From 8e0e925e2bd45806f88195a94e59246e2e5b6d5e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Aug 2020 20:45:24 -0400 Subject: [PATCH 01/13] Disallow linking to items with a mismatched disambiguator --- .../passes/collect_intra_doc_links.rs | 45 ++++++- .../intra-links-disambiguator-mismatch.rs | 53 ++++++++ .../intra-links-disambiguator-mismatch.stderr | 127 ++++++++++++++++++ 3 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs create mode 100644 src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index bf7a43236e061..3d8daf4e9a576 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -574,9 +574,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }; let resolved_self; let mut path_str; + let mut disambiguator = None; let (res, fragment) = { let mut kind = None; - let mut disambiguator = None; path_str = if let Some(prefix) = ["struct@", "enum@", "type@", "trait@", "union@", "module@", "mod@"] .iter() @@ -595,6 +595,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { link.trim_start_matches(prefix) } else if link.ends_with("!()") { kind = Some(MacroNS); + disambiguator = Some("bang"); link.trim_end_matches("!()") } else if link.ends_with("()") { kind = Some(ValueNS); @@ -610,7 +611,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { link.trim_start_matches("derive@") } else if link.ends_with('!') { kind = Some(MacroNS); - disambiguator = Some("macro"); + disambiguator = Some("bang"); link.trim_end_matches('!') } else { &link[..] @@ -789,6 +790,46 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { } else { debug!("intra-doc link to {} resolved to {:?}", path_str, res); + // Disallow e.g. linking to enums with `struct@` + if let Res::Def(kind, id) = res { + debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); + // NOTE: this relies on the fact that `''` is never parsed as a disambiguator + // NOTE: this needs to be kept in sync with the disambiguator parsing + match (kind, disambiguator.unwrap_or_default().trim_end_matches("@")) { + | (DefKind::Struct, "struct") + | (DefKind::Enum, "enum") + | (DefKind::Trait, "trait") + | (DefKind::Union, "union") + | (DefKind::Mod, "mod" | "module") + | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, "const") + | (DefKind::Static, "static") + // NOTE: this allows 'method' to mean both normal functions and associated functions + // This can't cause ambiguity because both are in the same namespace. + | (DefKind::Fn | DefKind::AssocFn, "fn" | "function" | "method") + | (DefKind::Macro(MacroKind::Bang), "bang") + | (DefKind::Macro(MacroKind::Derive), "derive") + // These are namespaces; allow anything in the namespace to match + | (_, "type" | "macro" | "value") + // If no disambiguator given, allow anything + | (_, "") + // All of these are valid, so do nothing + => {} + (_, disambiguator) => { + // The resolved item did not match the disambiguator; give a better error than 'not found' + let msg = format!("unresolved link to `{}`", path_str); + report_diagnostic(cx, &msg, &item, &dox, link_range, |diag, sp| { + let msg = format!("this item resolved to {} {}, which did not match the disambiguator '{}'", kind.article(), kind.descr(id), disambiguator); + if let Some(sp) = sp { + diag.span_note(sp, &msg); + } else { + diag.note(&msg); + } + }); + continue; + } + } + } + // item can be non-local e.g. when using #[doc(primitive = "pointer")] if let Some((src_id, dst_id)) = res .opt_def_id() diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs new file mode 100644 index 0000000000000..6ab815eab540e --- /dev/null +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -0,0 +1,53 @@ +#![deny(broken_intra_doc_links)] +//~^ NOTE lint level is defined +pub enum S {} + +macro_rules! m { + () => {}; +} + +static s: usize = 0; +const c: usize = 0; + +trait T {} + +/// Link to [struct@S] +//~^ ERROR unresolved link to `S` +//~| NOTE did not match + +/// Link to [mod@S] +//~^ ERROR unresolved link to `S` +//~| NOTE did not match + +/// Link to [union@S] +//~^ ERROR unresolved link to `S` +//~| NOTE did not match + +/// Link to [trait@S] +//~^ ERROR unresolved link to `S` +//~| NOTE did not match + +/// Link to [struct@T] +//~^ ERROR unresolved link to `T` +//~| NOTE did not match + +/// Link to [derive@m] +//~^ ERROR unresolved link to `m` +//~| NOTE did not match + +/// Link to [const@s] +//~^ ERROR unresolved link to `s` +//~| NOTE did not match + +/// Link to [static@c] +//~^ ERROR unresolved link to `c` +//~| NOTE did not match + +/// Link to [fn@c] +//~^ ERROR unresolved link to `c` +//~| NOTE did not match + +/// Link to [c()] +//~^ ERROR unresolved link to `c` +//~| NOTE did not match +pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr new file mode 100644 index 0000000000000..21276ecb20ae9 --- /dev/null +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -0,0 +1,127 @@ +error: unresolved link to `S` + --> $DIR/intra-links-disambiguator-mismatch.rs:16:14 + | +LL | /// Link to [struct@S] + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/intra-links-disambiguator-mismatch.rs:1:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ +note: this item resolved to an enum, which did not match the disambiguator 'struct' + --> $DIR/intra-links-disambiguator-mismatch.rs:16:14 + | +LL | /// Link to [struct@S] + | ^^^^^^^^ + +error: unresolved link to `S` + --> $DIR/intra-links-disambiguator-mismatch.rs:20:14 + | +LL | /// Link to [mod@S] + | ^^^^^ + | +note: this item resolved to an enum, which did not match the disambiguator 'mod' + --> $DIR/intra-links-disambiguator-mismatch.rs:20:14 + | +LL | /// Link to [mod@S] + | ^^^^^ + +error: unresolved link to `S` + --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 + | +LL | /// Link to [union@S] + | ^^^^^^^ + | +note: this item resolved to an enum, which did not match the disambiguator 'union' + --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 + | +LL | /// Link to [union@S] + | ^^^^^^^ + +error: unresolved link to `S` + --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 + | +LL | /// Link to [trait@S] + | ^^^^^^^ + | +note: this item resolved to an enum, which did not match the disambiguator 'trait' + --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 + | +LL | /// Link to [trait@S] + | ^^^^^^^ + +error: unresolved link to `T` + --> $DIR/intra-links-disambiguator-mismatch.rs:32:14 + | +LL | /// Link to [struct@T] + | ^^^^^^^^ + | +note: this item resolved to a trait, which did not match the disambiguator 'struct' + --> $DIR/intra-links-disambiguator-mismatch.rs:32:14 + | +LL | /// Link to [struct@T] + | ^^^^^^^^ + +error: unresolved link to `m` + --> $DIR/intra-links-disambiguator-mismatch.rs:36:14 + | +LL | /// Link to [derive@m] + | ^^^^^^^^ + | +note: this item resolved to a macro, which did not match the disambiguator 'derive' + --> $DIR/intra-links-disambiguator-mismatch.rs:36:14 + | +LL | /// Link to [derive@m] + | ^^^^^^^^ + +error: unresolved link to `s` + --> $DIR/intra-links-disambiguator-mismatch.rs:40:14 + | +LL | /// Link to [const@s] + | ^^^^^^^ + | +note: this item resolved to a static, which did not match the disambiguator 'const' + --> $DIR/intra-links-disambiguator-mismatch.rs:40:14 + | +LL | /// Link to [const@s] + | ^^^^^^^ + +error: unresolved link to `c` + --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 + | +LL | /// Link to [static@c] + | ^^^^^^^^ + | +note: this item resolved to a constant, which did not match the disambiguator 'static' + --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 + | +LL | /// Link to [static@c] + | ^^^^^^^^ + +error: unresolved link to `c` + --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 + | +LL | /// Link to [fn@c] + | ^^^^ + | +note: this item resolved to a constant, which did not match the disambiguator 'fn' + --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 + | +LL | /// Link to [fn@c] + | ^^^^ + +error: unresolved link to `c` + --> $DIR/intra-links-disambiguator-mismatch.rs:52:14 + | +LL | /// Link to [c()] + | ^^^ + | +note: this item resolved to a constant, which did not match the disambiguator 'fn' + --> $DIR/intra-links-disambiguator-mismatch.rs:52:14 + | +LL | /// Link to [c()] + | ^^^ + +error: aborting due to 10 previous errors + From 519c85439a39d85d0c4b08ff8622cad5bd707ada Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Aug 2020 22:37:21 -0400 Subject: [PATCH 02/13] Don't mark associated items as traits This caused the following false positive: ``` warning: unresolved link to `Default::default` --> /home/joshua/rustc2/default.rs:1:14 | 1 | /// Link to [Default::default()] | ^^^^^^^^^^^^^^^^^^ | = note: `#[warn(broken_intra_doc_links)]` on by default note: this item resolved to a trait, which did not match the disambiguator 'fn' --> /home/joshua/rustc2/default.rs:1:14 | 1 | /// Link to [Default::default()] | ^^^^^^^^^^^^^^^^^^ ``` --- src/librustdoc/passes/collect_intra_doc_links.rs | 3 ++- src/test/rustdoc/intra-link-trait-item.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/intra-link-trait-item.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3d8daf4e9a576..2323bf8e69e6c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -415,7 +415,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { AnchorFailure::Method })) } else { - Ok((ty_res, Some(format!("{}.{}", kind, item_name)))) + let res = Res::Def(item.kind.as_def_kind(), item.def_id); + Ok((res, Some(format!("{}.{}", kind, item_name)))) } } else { self.variant_field(path_str, current_item, module_id) diff --git a/src/test/rustdoc/intra-link-trait-item.rs b/src/test/rustdoc/intra-link-trait-item.rs new file mode 100644 index 0000000000000..70d36358fc249 --- /dev/null +++ b/src/test/rustdoc/intra-link-trait-item.rs @@ -0,0 +1,3 @@ +#![deny(broken_intra_doc_links_)] +/// Link to [Default::default()] +pub fn f() {} From 743f9327428801932bd70688b5c83f38bf61615a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Aug 2020 23:18:24 -0400 Subject: [PATCH 03/13] Keep the previous behavior of `register_res` Now that we're returning the `Res` of the associated item, not the trait itself, it got confused. --- src/librustdoc/clean/utils.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 52c306688268f..069d333de1834 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -607,6 +607,9 @@ pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId { Res::Def(DefKind::TyAlias, i) => (i, TypeKind::Typedef), Res::Def(DefKind::Enum, i) => (i, TypeKind::Enum), Res::Def(DefKind::Trait, i) => (i, TypeKind::Trait), + Res::Def(DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst, i) => { + (cx.tcx.parent(i).unwrap(), TypeKind::Trait) + } Res::Def(DefKind::Struct, i) => (i, TypeKind::Struct), Res::Def(DefKind::Union, i) => (i, TypeKind::Union), Res::Def(DefKind::Mod, i) => (i, TypeKind::Module), From 99354f552df332c669d6e621e68dda403ea135fd Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 3 Aug 2020 08:39:46 -0400 Subject: [PATCH 04/13] item -> link --- .../passes/collect_intra_doc_links.rs | 2 +- .../intra-links-disambiguator-mismatch.stderr | 60 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 2323bf8e69e6c..236dd79255938 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -819,7 +819,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // The resolved item did not match the disambiguator; give a better error than 'not found' let msg = format!("unresolved link to `{}`", path_str); report_diagnostic(cx, &msg, &item, &dox, link_range, |diag, sp| { - let msg = format!("this item resolved to {} {}, which did not match the disambiguator '{}'", kind.article(), kind.descr(id), disambiguator); + let msg = format!("this link resolved to {} {}, which did not match the disambiguator '{}'", kind.article(), kind.descr(id), disambiguator); if let Some(sp) = sp { diag.span_note(sp, &msg); } else { diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index 21276ecb20ae9..c40c720f879b5 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -1,5 +1,5 @@ error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:16:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 | LL | /// Link to [struct@S] | ^^^^^^^^ @@ -9,116 +9,116 @@ note: the lint level is defined here | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ -note: this item resolved to an enum, which did not match the disambiguator 'struct' - --> $DIR/intra-links-disambiguator-mismatch.rs:16:14 +note: this link resolved to an enum, which did not match the disambiguator 'struct' + --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 | LL | /// Link to [struct@S] | ^^^^^^^^ error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:20:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 | LL | /// Link to [mod@S] | ^^^^^ | -note: this item resolved to an enum, which did not match the disambiguator 'mod' - --> $DIR/intra-links-disambiguator-mismatch.rs:20:14 +note: this link resolved to an enum, which did not match the disambiguator 'mod' + --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 | LL | /// Link to [mod@S] | ^^^^^ error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:22:14 | LL | /// Link to [union@S] | ^^^^^^^ | -note: this item resolved to an enum, which did not match the disambiguator 'union' - --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 +note: this link resolved to an enum, which did not match the disambiguator 'union' + --> $DIR/intra-links-disambiguator-mismatch.rs:22:14 | LL | /// Link to [union@S] | ^^^^^^^ error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:26:14 | LL | /// Link to [trait@S] | ^^^^^^^ | -note: this item resolved to an enum, which did not match the disambiguator 'trait' - --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 +note: this link resolved to an enum, which did not match the disambiguator 'trait' + --> $DIR/intra-links-disambiguator-mismatch.rs:26:14 | LL | /// Link to [trait@S] | ^^^^^^^ error: unresolved link to `T` - --> $DIR/intra-links-disambiguator-mismatch.rs:32:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:30:14 | LL | /// Link to [struct@T] | ^^^^^^^^ | -note: this item resolved to a trait, which did not match the disambiguator 'struct' - --> $DIR/intra-links-disambiguator-mismatch.rs:32:14 +note: this link resolved to a trait, which did not match the disambiguator 'struct' + --> $DIR/intra-links-disambiguator-mismatch.rs:30:14 | LL | /// Link to [struct@T] | ^^^^^^^^ error: unresolved link to `m` - --> $DIR/intra-links-disambiguator-mismatch.rs:36:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 | LL | /// Link to [derive@m] | ^^^^^^^^ | -note: this item resolved to a macro, which did not match the disambiguator 'derive' - --> $DIR/intra-links-disambiguator-mismatch.rs:36:14 +note: this link resolved to a macro, which did not match the disambiguator 'derive' + --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 | LL | /// Link to [derive@m] | ^^^^^^^^ error: unresolved link to `s` - --> $DIR/intra-links-disambiguator-mismatch.rs:40:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 | LL | /// Link to [const@s] | ^^^^^^^ | -note: this item resolved to a static, which did not match the disambiguator 'const' - --> $DIR/intra-links-disambiguator-mismatch.rs:40:14 +note: this link resolved to a static, which did not match the disambiguator 'const' + --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 | LL | /// Link to [const@s] | ^^^^^^^ error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:42:14 | LL | /// Link to [static@c] | ^^^^^^^^ | -note: this item resolved to a constant, which did not match the disambiguator 'static' - --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 +note: this link resolved to a constant, which did not match the disambiguator 'static' + --> $DIR/intra-links-disambiguator-mismatch.rs:42:14 | LL | /// Link to [static@c] | ^^^^^^^^ error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:46:14 | LL | /// Link to [fn@c] | ^^^^ | -note: this item resolved to a constant, which did not match the disambiguator 'fn' - --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 +note: this link resolved to a constant, which did not match the disambiguator 'fn' + --> $DIR/intra-links-disambiguator-mismatch.rs:46:14 | LL | /// Link to [fn@c] | ^^^^ error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:52:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:50:14 | LL | /// Link to [c()] | ^^^ | -note: this item resolved to a constant, which did not match the disambiguator 'fn' - --> $DIR/intra-links-disambiguator-mismatch.rs:52:14 +note: this link resolved to a constant, which did not match the disambiguator 'fn' + --> $DIR/intra-links-disambiguator-mismatch.rs:50:14 | LL | /// Link to [c()] | ^^^ From 444f5a0556fc5779663e69ff1a3d5a7362ba9618 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 4 Aug 2020 23:31:36 -0400 Subject: [PATCH 05/13] Give a much better error message if the struct failed to resolve --- src/librustc_hir/def.rs | 12 +- .../passes/collect_intra_doc_links.rs | 187 ++++++++++++------ .../intra-links-disambiguator-mismatch.rs | 30 ++- .../intra-links-disambiguator-mismatch.stderr | 98 +++------ 4 files changed, 182 insertions(+), 145 deletions(-) diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs index af1860ca6bfea..618f3e99c3f04 100644 --- a/src/librustc_hir/def.rs +++ b/src/librustc_hir/def.rs @@ -150,7 +150,7 @@ impl DefKind { } } - pub fn matches_ns(&self, ns: Namespace) -> bool { + pub fn ns(&self) -> Option { match self { DefKind::Mod | DefKind::Struct @@ -163,7 +163,7 @@ impl DefKind { | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy - | DefKind::TyParam => ns == Namespace::TypeNS, + | DefKind::TyParam => Some(Namespace::TypeNS), DefKind::Fn | DefKind::Const @@ -171,9 +171,9 @@ impl DefKind { | DefKind::Static | DefKind::Ctor(..) | DefKind::AssocFn - | DefKind::AssocConst => ns == Namespace::ValueNS, + | DefKind::AssocConst => Some(Namespace::ValueNS), - DefKind::Macro(..) => ns == Namespace::MacroNS, + DefKind::Macro(..) => Some(Namespace::MacroNS), // Not namespaced. DefKind::AnonConst @@ -185,7 +185,7 @@ impl DefKind { | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm - | DefKind::Impl => false, + | DefKind::Impl => None, } } } @@ -453,7 +453,7 @@ impl Res { pub fn matches_ns(&self, ns: Namespace) -> bool { match self { - Res::Def(kind, ..) => kind.matches_ns(ns), + Res::Def(kind, ..) => kind.ns() == Some(ns), Res::PrimTy(..) | Res::SelfTy(..) | Res::ToolMod => ns == Namespace::TypeNS, Res::SelfCtor(..) | Res::Local(..) => ns == Namespace::ValueNS, Res::NonMacroAttr(..) => ns == Namespace::MacroNS, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 236dd79255938..03fabd3dc152c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -174,7 +174,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { fn resolve( &self, path_str: &str, - disambiguator: Option<&str>, + disambiguator: Option, ns: Namespace, current_item: &Option, parent_id: Option, @@ -214,7 +214,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { Res::Def(DefKind::Mod, _) => { // This resolved to a module, but if we were passed `type@`, // we want primitive types to take precedence instead. - if disambiguator == Some("type") { + if disambiguator == Some(Disambiguator::Namespace(Namespace::TypeNS)) { if let Some(prim) = is_primitive(path_str, ns) { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive)); @@ -575,47 +575,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }; let resolved_self; let mut path_str; - let mut disambiguator = None; + let disambiguator; let (res, fragment) = { - let mut kind = None; - path_str = if let Some(prefix) = - ["struct@", "enum@", "type@", "trait@", "union@", "module@", "mod@"] - .iter() - .find(|p| link.starts_with(**p)) - { - kind = Some(TypeNS); - disambiguator = Some(&prefix[..prefix.len() - 1]); - link.trim_start_matches(prefix) - } else if let Some(prefix) = - ["const@", "static@", "value@", "function@", "fn@", "method@"] - .iter() - .find(|p| link.starts_with(**p)) - { - kind = Some(ValueNS); - disambiguator = Some(&prefix[..prefix.len() - 1]); - link.trim_start_matches(prefix) - } else if link.ends_with("!()") { - kind = Some(MacroNS); - disambiguator = Some("bang"); - link.trim_end_matches("!()") - } else if link.ends_with("()") { - kind = Some(ValueNS); - disambiguator = Some("fn"); - link.trim_end_matches("()") - } else if link.starts_with("macro@") { - kind = Some(MacroNS); - disambiguator = Some("macro"); - link.trim_start_matches("macro@") - } else if link.starts_with("derive@") { - kind = Some(MacroNS); - disambiguator = Some("derive"); - link.trim_start_matches("derive@") - } else if link.ends_with('!') { - kind = Some(MacroNS); - disambiguator = Some("bang"); - link.trim_end_matches('!') + path_str = if let Ok((d, path)) = Disambiguator::from_str(&link) { + disambiguator = Some(d); + path } else { - &link[..] + disambiguator = None; + &link } .trim(); @@ -648,7 +615,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { } } - match kind { + match disambiguator.map(Disambiguator::ns) { Some(ns @ ValueNS) => { match self.resolve( path_str, @@ -796,34 +763,31 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); // NOTE: this relies on the fact that `''` is never parsed as a disambiguator // NOTE: this needs to be kept in sync with the disambiguator parsing - match (kind, disambiguator.unwrap_or_default().trim_end_matches("@")) { - | (DefKind::Struct, "struct") - | (DefKind::Enum, "enum") - | (DefKind::Trait, "trait") - | (DefKind::Union, "union") - | (DefKind::Mod, "mod" | "module") - | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, "const") - | (DefKind::Static, "static") + match (kind, disambiguator) { + | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) // NOTE: this allows 'method' to mean both normal functions and associated functions // This can't cause ambiguity because both are in the same namespace. - | (DefKind::Fn | DefKind::AssocFn, "fn" | "function" | "method") - | (DefKind::Macro(MacroKind::Bang), "bang") - | (DefKind::Macro(MacroKind::Derive), "derive") + | (DefKind::Fn | DefKind::AssocFn, Some(Disambiguator::Kind(DefKind::Fn))) // These are namespaces; allow anything in the namespace to match - | (_, "type" | "macro" | "value") + | (_, Some(Disambiguator::Namespace(_))) // If no disambiguator given, allow anything - | (_, "") + | (_, None) // All of these are valid, so do nothing => {} - (_, disambiguator) => { + (_, Some(Disambiguator::Kind(expected))) if kind == expected => {} + (_, Some(expected)) => { // The resolved item did not match the disambiguator; give a better error than 'not found' let msg = format!("unresolved link to `{}`", path_str); report_diagnostic(cx, &msg, &item, &dox, link_range, |diag, sp| { - let msg = format!("this link resolved to {} {}, which did not match the disambiguator '{}'", kind.article(), kind.descr(id), disambiguator); + // HACK(jynelson): by looking at the source I saw the DefId we pass + // for `expected.descr()` doesn't matter, since it's not a crate + let note = format!("this link resolved to {} {}, which is not {} {}", kind.article(), kind.descr(id), expected.article(), expected.descr(id)); + let suggestion = Disambiguator::display_for(kind, path_str); + let help_msg = format!("to link to the {}, use its disambiguator", kind.descr(id)); + diag.note(¬e); if let Some(sp) = sp { - diag.span_note(sp, &msg); - } else { - diag.note(&msg); + diag.span_suggestion(sp, &help_msg, suggestion, Applicability::MaybeIncorrect); + diag.set_sort_span(sp); } }); continue; @@ -879,6 +843,109 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum Disambiguator { + Kind(DefKind), + Namespace(Namespace), +} + +impl Disambiguator { + /// (disambiguator, path_str) + fn from_str(link: &str) -> Result<(Self, &str), ()> { + use Disambiguator::{Kind, Namespace as NS}; + + let find_suffix = || { + let suffixes = [ + ("!()", DefKind::Macro(MacroKind::Bang)), + ("()", DefKind::Fn), + ("!", DefKind::Macro(MacroKind::Bang)), + ]; + for &(suffix, kind) in &suffixes { + if link.ends_with(suffix) { + return Ok((Kind(kind), link.trim_end_matches(suffix))); + } + } + Err(()) + }; + + if let Some(idx) = link.find('@') { + let (prefix, rest) = link.split_at(idx); + let d = match prefix { + "struct" => Kind(DefKind::Struct), + "enum" => Kind(DefKind::Enum), + "trait" => Kind(DefKind::Trait), + "union" => Kind(DefKind::Union), + "module" | "mod" => Kind(DefKind::Mod), + "const" | "constant" => Kind(DefKind::Const), + "static" => Kind(DefKind::Static), + "function" | "fn" | "method" => Kind(DefKind::Fn), + "derive" => Kind(DefKind::Macro(MacroKind::Derive)), + "type" => NS(Namespace::TypeNS), + "value" => NS(Namespace::ValueNS), + "macro" => NS(Namespace::MacroNS), + _ => return find_suffix(), + }; + Ok((d, &rest[1..])) + } else { + find_suffix() + } + } + + fn display_for(kind: DefKind, path_str: &str) -> String { + if kind == DefKind::Macro(MacroKind::Bang) { + return format!("{}!", path_str); + } + let prefix = match kind { + DefKind::Struct => "struct", + DefKind::Enum => "enum", + DefKind::Trait => "trait", + DefKind::Union => "union", + DefKind::Mod => "mod", + DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst => { + "const" + } + DefKind::Static => "static", + DefKind::Fn | DefKind::AssocFn => "fn", + DefKind::Macro(MacroKind::Derive) => "derive", + // Now handle things that don't have a specific disambiguator + _ => match kind + .ns() + .expect("tried to calculate a disambiguator for a def without a namespace?") + { + Namespace::TypeNS => "type", + Namespace::ValueNS => "value", + Namespace::MacroNS => "macro", + }, + }; + format!("{}@{}", prefix, path_str) + } + + fn ns(self) -> Namespace { + match self { + Self::Namespace(n) => n, + Self::Kind(k) => { + k.ns().expect("only DefKinds with a valid namespace can be disambiguators") + } + } + } + + fn article(&self) -> &'static str { + match self { + Self::Namespace(_) => "a", + Self::Kind(kind) => kind.article(), + } + } + + fn descr(&self, def_id: DefId) -> &'static str { + match self { + Self::Namespace(Namespace::TypeNS) => "type", + Self::Namespace(Namespace::ValueNS) => "value", + Self::Namespace(Namespace::MacroNS) => "macro", + Self::Kind(kind) => kind.descr(def_id), + } + } +} + /// Reports a diagnostic for an intra-doc link. /// /// If no link range is provided, or the source span of the link cannot be determined, the span of diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 6ab815eab540e..9bf77a53fb58b 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -13,41 +13,51 @@ trait T {} /// Link to [struct@S] //~^ ERROR unresolved link to `S` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [mod@S] //~^ ERROR unresolved link to `S` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [union@S] //~^ ERROR unresolved link to `S` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [trait@S] //~^ ERROR unresolved link to `S` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [struct@T] //~^ ERROR unresolved link to `T` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [derive@m] //~^ ERROR unresolved link to `m` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [const@s] //~^ ERROR unresolved link to `s` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [static@c] //~^ ERROR unresolved link to `c` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [fn@c] //~^ ERROR unresolved link to `c` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator /// Link to [c()] //~^ ERROR unresolved link to `c` -//~| NOTE did not match +//~| NOTE this link resolved +//~| HELP use its disambiguator pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index c40c720f879b5..d0a3ebf2c6a2f 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -2,126 +2,86 @@ error: unresolved link to `S` --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 | LL | /// Link to [struct@S] - | ^^^^^^^^ + | ^^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` | note: the lint level is defined here --> $DIR/intra-links-disambiguator-mismatch.rs:1:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ -note: this link resolved to an enum, which did not match the disambiguator 'struct' - --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 - | -LL | /// Link to [struct@S] - | ^^^^^^^^ + = note: this link resolved to an enum, which is not a struct error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:19:14 | LL | /// Link to [mod@S] - | ^^^^^ + | ^^^^^ help: to link to the enum, use its disambiguator: `enum@S` | -note: this link resolved to an enum, which did not match the disambiguator 'mod' - --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 - | -LL | /// Link to [mod@S] - | ^^^^^ + = note: this link resolved to an enum, which is not a module error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:22:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 | LL | /// Link to [union@S] - | ^^^^^^^ - | -note: this link resolved to an enum, which did not match the disambiguator 'union' - --> $DIR/intra-links-disambiguator-mismatch.rs:22:14 + | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` | -LL | /// Link to [union@S] - | ^^^^^^^ + = note: this link resolved to an enum, which is not a union error: unresolved link to `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:26:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:29:14 | LL | /// Link to [trait@S] - | ^^^^^^^ - | -note: this link resolved to an enum, which did not match the disambiguator 'trait' - --> $DIR/intra-links-disambiguator-mismatch.rs:26:14 + | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` | -LL | /// Link to [trait@S] - | ^^^^^^^ + = note: this link resolved to an enum, which is not a trait error: unresolved link to `T` - --> $DIR/intra-links-disambiguator-mismatch.rs:30:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 | LL | /// Link to [struct@T] - | ^^^^^^^^ - | -note: this link resolved to a trait, which did not match the disambiguator 'struct' - --> $DIR/intra-links-disambiguator-mismatch.rs:30:14 + | ^^^^^^^^ help: to link to the trait, use its disambiguator: `trait@T` | -LL | /// Link to [struct@T] - | ^^^^^^^^ + = note: this link resolved to a trait, which is not a struct error: unresolved link to `m` - --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:39:14 | LL | /// Link to [derive@m] - | ^^^^^^^^ - | -note: this link resolved to a macro, which did not match the disambiguator 'derive' - --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 + | ^^^^^^^^ help: to link to the macro, use its disambiguator: `m!` | -LL | /// Link to [derive@m] - | ^^^^^^^^ + = note: this link resolved to a macro, which is not a derive macro error: unresolved link to `s` - --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 | LL | /// Link to [const@s] - | ^^^^^^^ - | -note: this link resolved to a static, which did not match the disambiguator 'const' - --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 + | ^^^^^^^ help: to link to the static, use its disambiguator: `static@s` | -LL | /// Link to [const@s] - | ^^^^^^^ + = note: this link resolved to a static, which is not a constant error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:42:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:49:14 | LL | /// Link to [static@c] - | ^^^^^^^^ + | ^^^^^^^^ help: to link to the constant, use its disambiguator: `const@c` | -note: this link resolved to a constant, which did not match the disambiguator 'static' - --> $DIR/intra-links-disambiguator-mismatch.rs:42:14 - | -LL | /// Link to [static@c] - | ^^^^^^^^ + = note: this link resolved to a constant, which is not a static error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:46:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:54:14 | LL | /// Link to [fn@c] - | ^^^^ - | -note: this link resolved to a constant, which did not match the disambiguator 'fn' - --> $DIR/intra-links-disambiguator-mismatch.rs:46:14 + | ^^^^ help: to link to the constant, use its disambiguator: `const@c` | -LL | /// Link to [fn@c] - | ^^^^ + = note: this link resolved to a constant, which is not a function error: unresolved link to `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:50:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:59:14 | LL | /// Link to [c()] - | ^^^ - | -note: this link resolved to a constant, which did not match the disambiguator 'fn' - --> $DIR/intra-links-disambiguator-mismatch.rs:50:14 + | ^^^ help: to link to the constant, use its disambiguator: `const@c` | -LL | /// Link to [c()] - | ^^^ + = note: this link resolved to a constant, which is not a function error: aborting due to 10 previous errors From fc273a035dfb352fd90246dd2560c807701eeea7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 4 Aug 2020 23:39:18 -0400 Subject: [PATCH 06/13] Unresolved link -> incompatible link kind Clearly it has been resolved, because we say on the next line what it resolved to. --- .../passes/collect_intra_doc_links.rs | 3 +-- .../intra-links-disambiguator-mismatch.rs | 20 +++++++++---------- .../intra-links-disambiguator-mismatch.stderr | 20 +++++++++---------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 03fabd3dc152c..8e485b9783094 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -777,7 +777,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { (_, Some(Disambiguator::Kind(expected))) if kind == expected => {} (_, Some(expected)) => { // The resolved item did not match the disambiguator; give a better error than 'not found' - let msg = format!("unresolved link to `{}`", path_str); + let msg = format!("incompatible link kind for `{}`", path_str); report_diagnostic(cx, &msg, &item, &dox, link_range, |diag, sp| { // HACK(jynelson): by looking at the source I saw the DefId we pass // for `expected.descr()` doesn't matter, since it's not a crate @@ -787,7 +787,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { diag.note(¬e); if let Some(sp) = sp { diag.span_suggestion(sp, &help_msg, suggestion, Applicability::MaybeIncorrect); - diag.set_sort_span(sp); } }); continue; diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 9bf77a53fb58b..3bc08b23341e5 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -12,52 +12,52 @@ const c: usize = 0; trait T {} /// Link to [struct@S] -//~^ ERROR unresolved link to `S` +//~^ ERROR incompatible link kind for `S` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [mod@S] -//~^ ERROR unresolved link to `S` +//~^ ERROR incompatible link kind for `S` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [union@S] -//~^ ERROR unresolved link to `S` +//~^ ERROR incompatible link kind for `S` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [trait@S] -//~^ ERROR unresolved link to `S` +//~^ ERROR incompatible link kind for `S` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [struct@T] -//~^ ERROR unresolved link to `T` +//~^ ERROR incompatible link kind for `T` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [derive@m] -//~^ ERROR unresolved link to `m` +//~^ ERROR incompatible link kind for `m` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [const@s] -//~^ ERROR unresolved link to `s` +//~^ ERROR incompatible link kind for `s` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [static@c] -//~^ ERROR unresolved link to `c` +//~^ ERROR incompatible link kind for `c` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [fn@c] -//~^ ERROR unresolved link to `c` +//~^ ERROR incompatible link kind for `c` //~| NOTE this link resolved //~| HELP use its disambiguator /// Link to [c()] -//~^ ERROR unresolved link to `c` +//~^ ERROR incompatible link kind for `c` //~| NOTE this link resolved //~| HELP use its disambiguator pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index d0a3ebf2c6a2f..8eb582512c03b 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -1,4 +1,4 @@ -error: unresolved link to `S` +error: incompatible link kind for `S` --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 | LL | /// Link to [struct@S] @@ -11,7 +11,7 @@ LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ = note: this link resolved to an enum, which is not a struct -error: unresolved link to `S` +error: incompatible link kind for `S` --> $DIR/intra-links-disambiguator-mismatch.rs:19:14 | LL | /// Link to [mod@S] @@ -19,7 +19,7 @@ LL | /// Link to [mod@S] | = note: this link resolved to an enum, which is not a module -error: unresolved link to `S` +error: incompatible link kind for `S` --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 | LL | /// Link to [union@S] @@ -27,7 +27,7 @@ LL | /// Link to [union@S] | = note: this link resolved to an enum, which is not a union -error: unresolved link to `S` +error: incompatible link kind for `S` --> $DIR/intra-links-disambiguator-mismatch.rs:29:14 | LL | /// Link to [trait@S] @@ -35,7 +35,7 @@ LL | /// Link to [trait@S] | = note: this link resolved to an enum, which is not a trait -error: unresolved link to `T` +error: incompatible link kind for `T` --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 | LL | /// Link to [struct@T] @@ -43,7 +43,7 @@ LL | /// Link to [struct@T] | = note: this link resolved to a trait, which is not a struct -error: unresolved link to `m` +error: incompatible link kind for `m` --> $DIR/intra-links-disambiguator-mismatch.rs:39:14 | LL | /// Link to [derive@m] @@ -51,7 +51,7 @@ LL | /// Link to [derive@m] | = note: this link resolved to a macro, which is not a derive macro -error: unresolved link to `s` +error: incompatible link kind for `s` --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 | LL | /// Link to [const@s] @@ -59,7 +59,7 @@ LL | /// Link to [const@s] | = note: this link resolved to a static, which is not a constant -error: unresolved link to `c` +error: incompatible link kind for `c` --> $DIR/intra-links-disambiguator-mismatch.rs:49:14 | LL | /// Link to [static@c] @@ -67,7 +67,7 @@ LL | /// Link to [static@c] | = note: this link resolved to a constant, which is not a static -error: unresolved link to `c` +error: incompatible link kind for `c` --> $DIR/intra-links-disambiguator-mismatch.rs:54:14 | LL | /// Link to [fn@c] @@ -75,7 +75,7 @@ LL | /// Link to [fn@c] | = note: this link resolved to a constant, which is not a function -error: unresolved link to `c` +error: incompatible link kind for `c` --> $DIR/intra-links-disambiguator-mismatch.rs:59:14 | LL | /// Link to [c()] From 2dad90d8b5c33c3aeef146d709b7f9ae66db49f4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 5 Aug 2020 20:46:02 -0400 Subject: [PATCH 07/13] Suggest f() for functions and add a test case --- src/librustdoc/passes/collect_intra_doc_links.rs | 3 ++- .../rustdoc-ui/intra-links-disambiguator-mismatch.rs | 5 +++++ .../intra-links-disambiguator-mismatch.stderr | 10 +++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8e485b9783094..ef44c9c937d85 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -893,6 +893,8 @@ impl Disambiguator { fn display_for(kind: DefKind, path_str: &str) -> String { if kind == DefKind::Macro(MacroKind::Bang) { return format!("{}!", path_str); + } else if kind == DefKind::Fn || kind == DefKind::AssocFn { + return format!("{}()", path_str); } let prefix = match kind { DefKind::Struct => "struct", @@ -904,7 +906,6 @@ impl Disambiguator { "const" } DefKind::Static => "static", - DefKind::Fn | DefKind::AssocFn => "fn", DefKind::Macro(MacroKind::Derive) => "derive", // Now handle things that don't have a specific disambiguator _ => match kind diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 3bc08b23341e5..1a7a2fce7a3f2 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -60,4 +60,9 @@ trait T {} //~^ ERROR incompatible link kind for `c` //~| NOTE this link resolved //~| HELP use its disambiguator + +/// Link to [const@f] +//~^ ERROR incompatible link kind for `f` +//~| NOTE this link resolved +//~| HELP use its disambiguator pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index 8eb582512c03b..9edf838f9d88b 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -83,5 +83,13 @@ LL | /// Link to [c()] | = note: this link resolved to a constant, which is not a function -error: aborting due to 10 previous errors +error: incompatible link kind for `f` + --> $DIR/intra-links-disambiguator-mismatch.rs:64:14 + | +LL | /// Link to [const@f] + | ^^^^^^^ help: to link to the function, use its disambiguator: `f()` + | + = note: this link resolved to a function, which is not a constant + +error: aborting due to 11 previous errors From f05e9da493a9e447dd2dafc271b06ad80358496f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 17:10:52 -0400 Subject: [PATCH 08/13] Still print help even if there's no span --- src/librustdoc/passes/collect_intra_doc_links.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ef44c9c937d85..a119e67ed7be0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -787,6 +787,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { diag.note(¬e); if let Some(sp) = sp { diag.span_suggestion(sp, &help_msg, suggestion, Applicability::MaybeIncorrect); + } else { + diag.help(&format!("{}: {}", help_msg, suggestion)); } }); continue; From 0c99d806eabd32a2ee2e6c71b400222b99c659e1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 18:11:47 -0400 Subject: [PATCH 09/13] Use the proper kind for associated items See comments in the diff; this is such a hack. The reason this can't be done properly in `register_res` is because there's no way to get back the parent type: calling `tcx.parent(assoc_item)` gets you the _impl_, not the type. You can call `tcx.impl_trait_ref(impl_).self_ty()`, but there's no way to go from that to a DefId without unwrapping. --- .../passes/collect_intra_doc_links.rs | 10 +++++++-- .../intra-links-disambiguator-mismatch.rs | 6 +++++ .../intra-links-disambiguator-mismatch.stderr | 22 +++++++++---------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a119e67ed7be0..7f3bb13edd7f2 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -17,6 +17,7 @@ use rustc_span::symbol::Ident; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; +use std::cell::Cell; use std::ops::Range; use crate::clean::*; @@ -62,11 +63,12 @@ struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, // NOTE: this may not necessarily be a module in the current crate mod_ids: Vec, + kind_side_channel: Cell>, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - LinkCollector { cx, mod_ids: Vec::new() } + LinkCollector { cx, mod_ids: Vec::new(), kind_side_channel: Cell::new(None) } } fn variant_field( @@ -347,6 +349,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { AnchorFailure::AssocConstant })) } else { + // HACK(jynelson): `clean` expects the type, not the associated item. + // but the disambiguator logic expects the associated item. + // Store the kind in a side channel so that only the disambiguator logic looks at it. + self.kind_side_channel.replace(Some(item.kind.as_def_kind())); Ok((ty_res, Some(format!("{}.{}", out, item_name)))) } } else { @@ -763,7 +769,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); // NOTE: this relies on the fact that `''` is never parsed as a disambiguator // NOTE: this needs to be kept in sync with the disambiguator parsing - match (kind, disambiguator) { + match (self.kind_side_channel.take().unwrap_or(kind), disambiguator) { | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) // NOTE: this allows 'method' to mean both normal functions and associated functions // This can't cause ambiguity because both are in the same namespace. diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 1a7a2fce7a3f2..5af2ff0699497 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -2,6 +2,10 @@ //~^ NOTE lint level is defined pub enum S {} +impl S { + fn assoc_fn() {} +} + macro_rules! m { () => {}; } @@ -65,4 +69,6 @@ trait T {} //~^ ERROR incompatible link kind for `f` //~| NOTE this link resolved //~| HELP use its disambiguator + +/// Link to [S::assoc_fn()] pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index 9edf838f9d88b..7cf15db6017cb 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -1,5 +1,5 @@ error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 | LL | /// Link to [struct@S] | ^^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -12,7 +12,7 @@ LL | #![deny(broken_intra_doc_links)] = note: this link resolved to an enum, which is not a struct error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:19:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:23:14 | LL | /// Link to [mod@S] | ^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -20,7 +20,7 @@ LL | /// Link to [mod@S] = note: this link resolved to an enum, which is not a module error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 | LL | /// Link to [union@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -28,7 +28,7 @@ LL | /// Link to [union@S] = note: this link resolved to an enum, which is not a union error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:29:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:33:14 | LL | /// Link to [trait@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -36,7 +36,7 @@ LL | /// Link to [trait@S] = note: this link resolved to an enum, which is not a trait error: incompatible link kind for `T` - --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 | LL | /// Link to [struct@T] | ^^^^^^^^ help: to link to the trait, use its disambiguator: `trait@T` @@ -44,7 +44,7 @@ LL | /// Link to [struct@T] = note: this link resolved to a trait, which is not a struct error: incompatible link kind for `m` - --> $DIR/intra-links-disambiguator-mismatch.rs:39:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:43:14 | LL | /// Link to [derive@m] | ^^^^^^^^ help: to link to the macro, use its disambiguator: `m!` @@ -52,7 +52,7 @@ LL | /// Link to [derive@m] = note: this link resolved to a macro, which is not a derive macro error: incompatible link kind for `s` - --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 | LL | /// Link to [const@s] | ^^^^^^^ help: to link to the static, use its disambiguator: `static@s` @@ -60,7 +60,7 @@ LL | /// Link to [const@s] = note: this link resolved to a static, which is not a constant error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:49:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:53:14 | LL | /// Link to [static@c] | ^^^^^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -68,7 +68,7 @@ LL | /// Link to [static@c] = note: this link resolved to a constant, which is not a static error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:54:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:58:14 | LL | /// Link to [fn@c] | ^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -76,7 +76,7 @@ LL | /// Link to [fn@c] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:59:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:63:14 | LL | /// Link to [c()] | ^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -84,7 +84,7 @@ LL | /// Link to [c()] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `f` - --> $DIR/intra-links-disambiguator-mismatch.rs:64:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:68:14 | LL | /// Link to [const@f] | ^^^^^^^ help: to link to the function, use its disambiguator: `f()` From ef54cde625966d4c103e067506ba31b3b79efec4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 18:33:29 -0400 Subject: [PATCH 10/13] Improve tests --- .../intra-links-disambiguator-mismatch.rs | 6 ----- .../intra-links-disambiguator-mismatch.stderr | 22 +++++++++---------- src/test/rustdoc/intra-link-trait-item.rs | 13 +++++++++-- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 5af2ff0699497..1a7a2fce7a3f2 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -2,10 +2,6 @@ //~^ NOTE lint level is defined pub enum S {} -impl S { - fn assoc_fn() {} -} - macro_rules! m { () => {}; } @@ -69,6 +65,4 @@ trait T {} //~^ ERROR incompatible link kind for `f` //~| NOTE this link resolved //~| HELP use its disambiguator - -/// Link to [S::assoc_fn()] pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index 7cf15db6017cb..9edf838f9d88b 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -1,5 +1,5 @@ error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 | LL | /// Link to [struct@S] | ^^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -12,7 +12,7 @@ LL | #![deny(broken_intra_doc_links)] = note: this link resolved to an enum, which is not a struct error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:23:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:19:14 | LL | /// Link to [mod@S] | ^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -20,7 +20,7 @@ LL | /// Link to [mod@S] = note: this link resolved to an enum, which is not a module error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 | LL | /// Link to [union@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -28,7 +28,7 @@ LL | /// Link to [union@S] = note: this link resolved to an enum, which is not a union error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:33:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:29:14 | LL | /// Link to [trait@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -36,7 +36,7 @@ LL | /// Link to [trait@S] = note: this link resolved to an enum, which is not a trait error: incompatible link kind for `T` - --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 | LL | /// Link to [struct@T] | ^^^^^^^^ help: to link to the trait, use its disambiguator: `trait@T` @@ -44,7 +44,7 @@ LL | /// Link to [struct@T] = note: this link resolved to a trait, which is not a struct error: incompatible link kind for `m` - --> $DIR/intra-links-disambiguator-mismatch.rs:43:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:39:14 | LL | /// Link to [derive@m] | ^^^^^^^^ help: to link to the macro, use its disambiguator: `m!` @@ -52,7 +52,7 @@ LL | /// Link to [derive@m] = note: this link resolved to a macro, which is not a derive macro error: incompatible link kind for `s` - --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 | LL | /// Link to [const@s] | ^^^^^^^ help: to link to the static, use its disambiguator: `static@s` @@ -60,7 +60,7 @@ LL | /// Link to [const@s] = note: this link resolved to a static, which is not a constant error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:53:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:49:14 | LL | /// Link to [static@c] | ^^^^^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -68,7 +68,7 @@ LL | /// Link to [static@c] = note: this link resolved to a constant, which is not a static error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:58:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:54:14 | LL | /// Link to [fn@c] | ^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -76,7 +76,7 @@ LL | /// Link to [fn@c] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:63:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:59:14 | LL | /// Link to [c()] | ^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -84,7 +84,7 @@ LL | /// Link to [c()] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `f` - --> $DIR/intra-links-disambiguator-mismatch.rs:68:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:64:14 | LL | /// Link to [const@f] | ^^^^^^^ help: to link to the function, use its disambiguator: `f()` diff --git a/src/test/rustdoc/intra-link-trait-item.rs b/src/test/rustdoc/intra-link-trait-item.rs index 70d36358fc249..80bafa1a270e1 100644 --- a/src/test/rustdoc/intra-link-trait-item.rs +++ b/src/test/rustdoc/intra-link-trait-item.rs @@ -1,3 +1,12 @@ -#![deny(broken_intra_doc_links_)] +// allow-tidy-line-length +#![deny(broken_intra_doc_links)] + +/// Link to [S::assoc_fn()] /// Link to [Default::default()] -pub fn f() {} +// @has intra_link_trait_item/struct.S.html '//*[@href="https://doc.rust-lang.org/nightly/core/default/trait.Default.html#tymethod.default"]' 'Default::default()' +// @has - '//*[@href="../intra_link_trait_item/struct.S.html#method.assoc_fn"]' 'S::assoc_fn()' +pub struct S; + +impl S { + pub fn assoc_fn() {} +} From d240490229b31e1ebd6871a08ee2cefeb580ba78 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 18:50:23 -0400 Subject: [PATCH 11/13] Fix outdated code --- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +--- src/test/rustdoc/intra-link-trait-item.rs | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7f3bb13edd7f2..00169530381cd 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -767,8 +767,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // Disallow e.g. linking to enums with `struct@` if let Res::Def(kind, id) = res { debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); - // NOTE: this relies on the fact that `''` is never parsed as a disambiguator - // NOTE: this needs to be kept in sync with the disambiguator parsing match (self.kind_side_channel.take().unwrap_or(kind), disambiguator) { | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) // NOTE: this allows 'method' to mean both normal functions and associated functions @@ -780,7 +778,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { | (_, None) // All of these are valid, so do nothing => {} - (_, Some(Disambiguator::Kind(expected))) if kind == expected => {} + (actual, Some(Disambiguator::Kind(expected))) if actual == expected => {} (_, Some(expected)) => { // The resolved item did not match the disambiguator; give a better error than 'not found' let msg = format!("incompatible link kind for `{}`", path_str); diff --git a/src/test/rustdoc/intra-link-trait-item.rs b/src/test/rustdoc/intra-link-trait-item.rs index 80bafa1a270e1..54270414c9dfe 100644 --- a/src/test/rustdoc/intra-link-trait-item.rs +++ b/src/test/rustdoc/intra-link-trait-item.rs @@ -1,10 +1,10 @@ -// allow-tidy-line-length +// ignore-tidy-linelength #![deny(broken_intra_doc_links)] /// Link to [S::assoc_fn()] /// Link to [Default::default()] -// @has intra_link_trait_item/struct.S.html '//*[@href="https://doc.rust-lang.org/nightly/core/default/trait.Default.html#tymethod.default"]' 'Default::default()' -// @has - '//*[@href="../intra_link_trait_item/struct.S.html#method.assoc_fn"]' 'S::assoc_fn()' +// @has intra_link_trait_item/struct.S.html '//*[@href="../intra_link_trait_item/struct.S.html#method.assoc_fn"]' 'S::assoc_fn()' +// @has - '//*[@href="https://doc.rust-lang.org/nightly/core/default/trait.Default.html#tymethod.default"]' 'Default::default()' pub struct S; impl S { From 17263bc2da9fe312556afe0812db82e9f41b9a6e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 18:57:56 -0400 Subject: [PATCH 12/13] Remove dead code --- .../passes/collect_intra_doc_links.rs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 00169530381cd..343a067508a97 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -779,7 +779,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // All of these are valid, so do nothing => {} (actual, Some(Disambiguator::Kind(expected))) if actual == expected => {} - (_, Some(expected)) => { + (_, Some(Disambiguator::Kind(expected))) => { // The resolved item did not match the disambiguator; give a better error than 'not found' let msg = format!("incompatible link kind for `{}`", path_str); report_diagnostic(cx, &msg, &item, &dox, link_range, |diag, sp| { @@ -934,22 +934,6 @@ impl Disambiguator { } } } - - fn article(&self) -> &'static str { - match self { - Self::Namespace(_) => "a", - Self::Kind(kind) => kind.article(), - } - } - - fn descr(&self, def_id: DefId) -> &'static str { - match self { - Self::Namespace(Namespace::TypeNS) => "type", - Self::Namespace(Namespace::ValueNS) => "value", - Self::Namespace(Namespace::MacroNS) => "macro", - Self::Kind(kind) => kind.descr(def_id), - } - } } /// Reports a diagnostic for an intra-doc link. From 9914f73f14fc4edbb7595078e97b3ee1f5d3bd4b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 6 Aug 2020 23:17:15 -0400 Subject: [PATCH 13/13] Add doc-comment for `kind_side_channel` --- src/librustdoc/passes/collect_intra_doc_links.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 343a067508a97..f84486347afcd 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -63,6 +63,9 @@ struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, // NOTE: this may not necessarily be a module in the current crate mod_ids: Vec, + /// This is used to store the kind of associated items, + /// because `clean` and the disambiguator code expect them to be different. + /// See the code for associated items on inherent impls for details. kind_side_channel: Cell>, }