Rollup merge of #151255 - fix-rustdoc-ice-reexported-deprecated-note, r=lolbinarycat

rustdoc: Fix ICE when deprecated note is not resolved on the correct `DefId`

Supersedes https://github.com/rust-lang/rust/pull/151237.
Follow-up of rust-lang/rust#151120.

The `span` overlapping approach wasn't good enough so instead we now check if the reexport itself has the `deprecated` attribute, and if so, we resolve the path to the reexport `DefId`, otherwise we resolve it on the reexported item's `DefId`.

cc @Zalathar
r? @lolbinarycat
This commit is contained in:
Stuart Cook 2026-01-20 18:00:10 +11:00 committed by GitHub
commit 0a5d1e8059
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 62 additions and 7 deletions

View file

@ -11,10 +11,11 @@ use rustc_ast::util::comments::may_have_doc_links;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::Interned;
use rustc_errors::{Applicability, Diag, DiagMessage};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, MacroKinds, Namespace, PerNS};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE};
use rustc_hir::{Mutability, Safety};
use rustc_hir::{Attribute, Mutability, Safety};
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::{bug, span_bug, ty};
use rustc_resolve::rustdoc::pulldown_cmark::LinkType;
@ -1108,10 +1109,8 @@ impl LinkCollector<'_, '_> {
// Also resolve links in the note text of `#[deprecated]`.
for attr in &item.attrs.other_attrs {
let rustc_hir::Attribute::Parsed(rustc_hir::attrs::AttributeKind::Deprecation {
span,
deprecation,
}) = attr
let Attribute::Parsed(AttributeKind::Deprecation { span: depr_span, deprecation }) =
attr
else {
continue;
};
@ -1128,8 +1127,14 @@ impl LinkCollector<'_, '_> {
// inlined item.
// <https://github.com/rust-lang/rust/pull/151120>
let item_id = if let Some(inline_stmt_id) = item.inline_stmt_id
&& item.span(tcx).is_none_or(|item_span| !item_span.inner().contains(*span))
{
&& tcx.get_all_attrs(inline_stmt_id).iter().any(|attr| {
matches!(
attr,
Attribute::Parsed(AttributeKind::Deprecation {
span: attr_span, ..
}) if attr_span == depr_span,
)
}) {
inline_stmt_id.to_def_id()
} else {
item.item_id.expect_def_id()

View file

@ -0,0 +1,16 @@
// This test ensures that the intra-doc link from reexported deprecated attribute note
// are resolved where they are declared.
#![deny(rustdoc::broken_intra_doc_links)]
#[doc(inline)]
pub use bar::sql_function_proc as sql_function;
pub fn define_sql_function() {}
pub mod bar {
#[deprecated(note = "Use [`define_sql_function`] instead")]
//~^ ERROR: unresolved link
//~| ERROR: unresolved link
pub fn sql_function_proc() {}
}

View file

@ -0,0 +1,34 @@
error: unresolved link to `define_sql_function`
--> $DIR/deprecated-note-from-reexported.rs:12:25
|
LL | #[deprecated(note = "Use [`define_sql_function`] instead")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the link appears in this line:
Use [`define_sql_function`] instead
^^^^^^^^^^^^^^^^^^^^^
= note: no item named `define_sql_function` in scope
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
note: the lint level is defined here
--> $DIR/deprecated-note-from-reexported.rs:4:9
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unresolved link to `define_sql_function`
--> $DIR/deprecated-note-from-reexported.rs:12:25
|
LL | #[deprecated(note = "Use [`define_sql_function`] instead")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the link appears in this line:
Use [`define_sql_function`] instead
^^^^^^^^^^^^^^^^^^^^^
= note: no item named `define_sql_function` in scope
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors