From c4016d083927d81d73dc8aba7d38ff631afa1ee8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 22 Oct 2026 10:44:47 +0200 Subject: [PATCH] Include `deprecated` attributes in `rustc_resolve` intra-doc link resolution --- compiler/rustc_resolve/src/late.rs | 7 ++++- .../intra-doc/link-in-deprecation-note-2.rs | 15 +++++++++ .../link-in-deprecation-note-2.stderr | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs create mode 100644 tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 315ace9c0d4cf..310211bffdeb6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2964,9 +2964,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut mod_inner_attrs_start = None; match item.kind { ItemKind::Mod(..) => { - // We only handle outer doc comments for modules here. + // We only handle outer attributes which can contain intra-doc links (doc comments + // and `deprecated`) for modules here. let attrs = if let Some(pos) = item.attrs.iter().position(|a| { a.doc_resolution_scope().is_some_and(|style| style == AttrStyle::Inner) + || matches!( + a.kind, + AttrKind::Normal(ref n) + if n.item.name() == Some(sym::deprecated) && a.style == AttrStyle::Inner) }) { mod_inner_attrs_start = Some(pos); &item.attrs[..pos] diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs new file mode 100644 index 0000000000000..e993b988b3fea --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs @@ -0,0 +1,15 @@ +// Because inner and outer attributes don't have the same scope for a module, we need +// to also apply the logic to the other module attributes which can contain intra-doc +// links. +// Regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod a { + #![deprecated = "[](TypeAlias::x)"] + //~^ ERROR broken_intra_doc_links +} + +#[deprecated = "[](TypeAlias::x)"] +//~^ ERROR broken_intra_doc_links +pub mod b {} diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr new file mode 100644 index 0000000000000..36c6ce48dd42a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr @@ -0,0 +1,31 @@ +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:9:21 + | +LL | #![deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope +note: the lint level is defined here + --> $DIR/link-in-deprecation-note-2.rs:6:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:13:16 + | +LL | #[deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: aborting due to 2 previous errors +