Skip to content

Commit

Permalink
rustdoc: correctly resolve link disambiguators through ctors
Browse files Browse the repository at this point in the history
  • Loading branch information
notriddle committed Oct 4, 2024
1 parent 9ff5fc4 commit c52a0f8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
17 changes: 17 additions & 0 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ pub(crate) fn synthesize_auto_trait_and_blanket_impls(
/// [`href()`]: crate::html::format::href
pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
use DefKind::*;
use rustc_hir::def::CtorOf;
debug!("register_res({res:?})");

let (kind, did) = match res {
Expand All @@ -526,6 +527,22 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
did,
) => (kind.into(), did),

// Tuple and unit-like structs and enums exist in both type and
// value ns. The item that exists in value ns is the "constructor,"
// a special function or const that returns the constructed value.
//
// It's possible to make an intra-doc link that points at the
// constructor, but it's not actually documented separately from
// the type itself.
Res::Def(Ctor(ctor_of, _), did) => (
match ctor_of {
CtorOf::Struct => Struct,
CtorOf::Variant => Variant,
}
.into(),
cx.tcx.parent(did),
),

_ => panic!("register_res: unexpected {res:?}"),
};
if did.is_local() {
Expand Down
10 changes: 7 additions & 3 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_errors::{Applicability, Diag, DiagMessage};
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def::{CtorOf, DefKind, Namespace, PerNS};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::{Mutability, Safety};
use rustc_middle::ty::{Ty, TyCtxt};
Expand Down Expand Up @@ -212,7 +212,7 @@ impl UrlFragment {
}
DefKind::AssocConst => "associatedconstant.",
DefKind::AssocTy => "associatedtype.",
DefKind::Variant => "variant.",
DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => "variant.",
DefKind::Field => {
let parent_id = tcx.parent(def_id);
if tcx.def_kind(parent_id) == DefKind::Variant {
Expand Down Expand Up @@ -423,7 +423,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
if let Some(res) = self.resolve_path(path_str, ns, item_id, module_id) {
return Ok(match res {
Res::Def(
DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Variant,
DefKind::AssocFn
| DefKind::AssocConst
| DefKind::AssocTy
| DefKind::Variant
| DefKind::Ctor(CtorOf::Variant, _),
def_id,
) => {
vec![(Res::from_def_id(self.cx.tcx, self.cx.tcx.parent(def_id)), Some(def_id))]
Expand Down
37 changes: 37 additions & 0 deletions tests/rustdoc/intra-doc/value-ctor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// https://github.com/rust-lang/rust/issues/130591
#![deny(rustdoc::broken_intra_doc_links)]
#![crate_name = "foo"]

/// [value@Foo::X]
//@ has foo/enum.Foo.html '//a[@href="enum.Foo.html#variant.X"]' 'Foo::X'
pub enum Foo {
X,
}

/// [tst][value@MyStruct]
//@ has foo/struct.MyStruct.html '//a[@href="struct.MyStruct.html"]' 'tst'
pub struct MyStruct;

pub enum MyEnum {
Internals,
}

pub use MyEnum::*;

/// In this context, [a][type@Internals] is a struct, while [b][value@Internals] is an enum variant.
//@ has foo/struct.Internals.html '//a[@href="struct.Internals.html"]' 'a'
//@ has foo/struct.Internals.html '//a[@href="enum.MyEnum.html#variant.Internals"]' 'b'
pub struct Internals {
foo: (),
}

pub mod inside {
pub struct Internals2;
}

use inside::*;

/// In this context, [a][type@Internals2] is an enum, while [b][value@Internals2] is a struct.
//@ has foo/enum.Internals2.html '//a[@href="enum.Internals2.html"]' 'a'
//@ has foo/enum.Internals2.html '//a[@href="inside/struct.Internals2.html"]' 'b'
pub enum Internals2 {}

0 comments on commit c52a0f8

Please sign in to comment.