From 234927e098fc5e86ded3ac46b8cfaa522235dcf8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 23 May 2023 15:33:34 +0200 Subject: [PATCH 1/2] Ignore "non-real" type Res in rustdoc intra doc link resolution --- compiler/rustc_resolve/src/late.rs | 15 ++++++++------- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index a1077615d95..e0611907613 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -17,7 +17,7 @@ use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg}; use rustc_hir::def::Namespace::{self, *}; -use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; +use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1; @@ -4287,12 +4287,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } } - fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> bool { + fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option { // FIXME: This caching may be incorrect in case of multiple `macro_rules` // items with the same name in the same module. // Also hygiene is not considered. let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions); - let res = doc_link_resolutions + let res = *doc_link_resolutions .entry(self.parent_scope.module.nearest_parent_mod().expect_local()) .or_default() .entry((Symbol::intern(path_str), ns)) @@ -4307,8 +4307,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { return None; } res - }) - .is_some(); + }); self.r.doc_link_resolutions = doc_link_resolutions; res } @@ -4343,8 +4342,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let mut any_resolved = false; let mut need_assoc = false; for ns in [TypeNS, ValueNS, MacroNS] { - if self.resolve_and_cache_rustdoc_path(&path_str, ns) { - any_resolved = true; + if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) { + // Rustdoc ignores tool attribute resolutions and attempts + // to resolve their prefixes for diagnostics. + any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool)); } else if ns != MacroNS { need_assoc = true; } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 9381b3e0567..9e6894a77df 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -149,7 +149,7 @@ impl TryFrom for Res { Def(kind, id) => Ok(Res::Def(kind, id)), PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))), // e.g. `#[derive]` - NonMacroAttr(..) | Err => Result::Err(()), + ToolMod | NonMacroAttr(..) | Err => Result::Err(()), other => bug!("unrecognized res {:?}", other), } } From bcdfda1b6b1af042008feaf8f23bf90773b976f4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 May 2023 13:14:51 +0200 Subject: [PATCH 2/2] Add regression test for #111189 --- .../intra-doc/issue-111189-resolution-ice.rs | 10 +++++++++ .../issue-111189-resolution-ice.stderr | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs create mode 100644 tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs new file mode 100644 index 00000000000..4e74278dc7b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs @@ -0,0 +1,10 @@ +// Regression test for . +// This test ensures that it doesn't crash. + +#![deny(warnings)] + +/// #[rustfmt::skip] +//~^ ERROR unresolved link to `rustfmt::skip` +/// #[clippy::whatever] +//~^ ERROR unresolved link to `clippy::whatever` +pub fn foo() {} diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr new file mode 100644 index 00000000000..edd3dfa7d7e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr @@ -0,0 +1,21 @@ +error: unresolved link to `rustfmt::skip` + --> $DIR/issue-111189-resolution-ice.rs:6:7 + | +LL | /// #[rustfmt::skip] + | ^^^^^^^^^^^^^ no item named `rustfmt` in scope + | +note: the lint level is defined here + --> $DIR/issue-111189-resolution-ice.rs:4:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + +error: unresolved link to `clippy::whatever` + --> $DIR/issue-111189-resolution-ice.rs:8:7 + | +LL | /// #[clippy::whatever] + | ^^^^^^^^^^^^^^^^ no item named `clippy` in scope + +error: aborting due to 2 previous errors +