Skip to content

[ICE]: rustdoc panics with "no resolutions for a doc link" when resolving intra-doc link in #[deprecated] note via glob re-export #151411

@leighmcculloch

Description

@leighmcculloch

Command

cargo +nightly doc

Code

pub use fuzz_test_helpers::*;

/// A type referenced in the deprecation note.
pub struct Env;

impl Env {
    /// Some function.
    pub fn try_invoke(&self) {}
}

mod fuzz_test_helpers {
    /// Deprecated function with intra-doc link in deprecation note.
    ///
    /// This function is deprecated.
    #[deprecated(note = "use [Env::try_invoke] instead")]
    pub fn fuzz_catch_panic() {}
}

Meta

rustc --version --verbose:

rustc 1.95.0-nightly (d940e5684 2026-01-19)
binary: rustc
commit-hash: d940e56841ddcc05671ead99290e35ff2e98369f
commit-date: 2026-01-19
host: aarch64-apple-darwin
release: 1.95.0-nightly
LLVM version: 21.1.8

Error output

 Documenting rustdoc-ice-repro v0.1.0 (/private/tmp/claude/rustdoc-ice-repro)
warning: unresolved link to `Env::try_invoke`
  --> src/lib.rs:14:5
   |
14 | /     /// Deprecated function with intra-doc link in deprecation note.
15 | |     ///
16 | |     /// This function is deprecated.
17 | |     #[deprecated(note = "use [Env::try_invoke] instead")]
   | |_______________________________________________________^
   |
   = note: the link appears in this line:

           use [Env::try_invoke] instead
                ^^^^^^^^^^^^^^^
   = note: no item named `Env` in scope
   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

error: internal compiler error: /rustc-dev/d940e56841ddcc05671ead99290e35ff2e98369f/compiler/rustc_metadata/src/rmeta/encoder.rs:2577:36: no resolutions for a doc link
  --> src/lib.rs:1:1
   |
 1 | / //! Test crate for rustdoc ICE reproduction.
 2 | |
 3 | | pub use fuzz_test_helpers::*;
...  |
18 | |     pub fn fuzz_catch_panic() {}
19 | | }
   | |_^

Note: In a larger codebase (the original context where this was discovered), the ICE was reported at a different location:

error: internal compiler error: src/librustdoc/passes/collect_intra_doc_links.rs:369:17: no resolution for "Env::try_invoke" MacroNS

Backtrace

Full backtrace
thread 'rustc' panicked at /rustc-dev/d940e56841ddcc05671ead99290e35ff2e98369f/compiler/rustc_metadata/src/rmeta/encoder.rs:2577:36:
Box<dyn Any>
stack backtrace:
   0:        0x1102a95c4 - <<std[261d5f6f38db11e0]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[833a3f1792d2e4c6]::fmt::Display>::fmt
   1:        0x10d506500 - core[833a3f1792d2e4c6]::fmt::write
   2:        0x1102c0dd0 - <std[261d5f6f38db11e0]::sys::stdio::unix::Stderr as std[261d5f6f38db11e0]::io::Write>::write_fmt
   3:        0x110280090 - std[261d5f6f38db11e0]::panicking::default_hook::{closure#0}
   4:        0x11029bd30 - std[261d5f6f38db11e0]::panicking::default_hook
   5:        0x10e1574a8 - std[261d5f6f38db11e0]::panicking::update_hook::<alloc[2fb6cc656c6c9c29]::boxed::Box<rustc_driver_impl[7b15139e55e44e2f]::install_ice_hook::{closure#1}>>::{closure#0}
   6:        0x11029c094 - std[261d5f6f38db11e0]::panicking::panic_with_hook
   7:        0x10e1dd70c - std[261d5f6f38db11e0]::panicking::begin_panic::<rustc_errors[6db60244e30f6bcb]::ExplicitBug>::{closure#0}
   8:        0x10e1c704c - std[261d5f6f38db11e0]::sys::backtrace::__rust_end_short_backtrace::<std[261d5f6f38db11e0]::panicking::begin_panic<rustc_errors[6db60244e30f6bcb]::ExplicitBug>::{closure#0}, !>
   9:        0x1130613ec - std[261d5f6f38db11e0]::panicking::begin_panic::<rustc_errors[6db60244e30f6bcb]::ExplicitBug>
  10:        0x113061fc8 - <rustc_errors[6db60244e30f6bcb]::diagnostic::BugAbort as rustc_errors[6db60244e30f6bcb]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
  11:        0x1130cff34 - <rustc_errors[6db60244e30f6bcb]::DiagCtxtHandle>::span_bug::<rustc_span[eeff11fcea3a431d]::span_encoding::Span, alloc[2fb6cc656c6c9c29]::string::String>
  12:        0x1130d0ea8 - rustc_middle[1c813a352572e2e0]::util::bug::opt_span_bug_fmt::<rustc_span[eeff11fcea3a431d]::span_encoding::Span>::{closure#0}
  13:        0x10ee38d3c - rustc_middle[1c813a352572e2e0]::ty::context::tls::with_opt::<rustc_middle[1c813a352572e2e0]::util::bug::opt_span_bug_fmt<rustc_span[eeff11fcea3a431d]::span_encoding::Span>::{closure#0}, !>::{closure#0}
  14:        0x10ee11dc4 - rustc_middle[1c813a352572e2e0]::ty::context::tls::with_context_opt::<rustc_middle[1c813a352572e2e0]::ty::context::tls::with_opt<rustc_middle[1c813a352572e2e0]::util::bug::opt_span_bug_fmt<rustc_span[eeff11fcea3a431d]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
  15:        0x1130d023c - rustc_middle[1c813a352572e2e0]::util::bug::span_bug_fmt::<rustc_span[eeff11fcea3a431d]::span_encoding::Span>
  16:        0x10ede4694 - <rustc_metadata[881736e06fa2cadd]::rmeta::encoder::provide::{closure#0} as core[833a3f1792d2e4c6]::ops::function::FnOnce<(rustc_middle[1c813a352572e2e0]::ty::context::TyCtxt, rustc_span[eeff11fcea3a431d]::def_id::LocalDefId)>>::call_once
  17:        0x10f6cc498 - rustc_query_impl[517e6d2b6cc5f52d]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[517e6d2b6cc5f52d]::query_impl::doc_link_resolutions::dynamic_query::{closure#2}::{closure#0}, rustc_middle[1c813a352572e2e0]::query::erase::Erased<[u8; 8usize]>>
  18:        0x10f70f18c - rustc_query_system[ac83779aa521246d]::query::plumbing::try_execute_query::<rustc_query_impl[517e6d2b6cc5f52d]::DynamicConfig<rustc_query_system[ac83779aa521246d]::query::caches::DefIdCache<rustc_middle[1c813a352572e2e0]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[517e6d2b6cc5f52d]::plumbing::QueryCtxt, false>
  19:        0x10f866bfc - rustc_query_impl[517e6d2b6cc5f52d]::query_impl::doc_link_resolutions::get_query_non_incr::__rust_end_short_backtrace
  20:        0x10120e340 - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector>::resolve_path
  21:        0x10120edec - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector>::resolve
  22:        0x10121f150 - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector>::resolve_link
  23:        0x101184364 - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector>::resolve_links::{closure#0}
  24:        0x1013297c4 - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector as rustdoc[86f01620660e41ec]::visit::DocVisitor>::visit_item
  25:        0x101329ce0 - <rustdoc[86f01620660e41ec]::passes::collect_intra_doc_links::LinkCollector as rustdoc[86f01620660e41ec]::visit::DocVisitor>::visit_item
  26:        0x101243cf8 - rustdoc[86f01620660e41ec]::core::run_global_ctxt
  27:        0x1011734a8 - rustdoc[86f01620660e41ec]::main_args::{closure#2}::{closure#0}
  28:        0x10116c0d0 - rustc_interface[e7f7fb8ea93efbab]::interface::run_compiler::<(), rustdoc[86f01620660e41ec]::main_args::{closure#2}>::{closure#1}
  29:        0x1010ccec4 - std[261d5f6f38db11e0]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[e7f7fb8ea93efbab]::util::run_in_thread_with_globals<rustc_interface[e7f7fb8ea93efbab]::util::run_in_thread_pool_with_globals<rustc_interface[e7f7fb8ea93efbab]::interface::run_compiler<(), rustdoc[86f01620660e41ec]::main_args::{closure#2}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  30:        0x101194a5c - <std[261d5f6f38db11e0]::thread::lifecycle::spawn_unchecked<rustc_interface[e7f7fb8ea93efbab]::util::run_in_thread_with_globals<rustc_interface[e7f7fb8ea93efbab]::util::run_in_thread_pool_with_globals<rustc_interface[e7f7fb8ea93efbab]::interface::run_compiler<(), rustdoc[86f01620660e41ec]::main_args::{closure#2}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[833a3f1792d2e4c6]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  31:        0x1102a6c14 - <std[261d5f6f38db11e0]::sys::thread::unix::Thread>::new::thread_start
  32:        0x1870c5c08 - __pthread_cond_wait

note: rustc 1.95.0-nightly (d940e5684 2026-01-19) running on aarch64-apple-darwin

note: compiler flags: --crate-type lib

query stack during panic:
#0 [doc_link_resolutions] resolutions for documentation links for a module
end of query stack

Additional context

The ICE occurs when:

  1. A function has a #[deprecated(note = "...")] attribute containing an intra-doc link (e.g., [Env::try_invoke])
  2. The function is in a private module
  3. The function is re-exported via a glob import (pub use module::*;)

The issue appears to be that rustdoc attempts to resolve the intra-doc link in the deprecation note but fails to properly handle the resolution when the item is accessed through a glob re-export. The warning "no item named Env in scope" suggests the link resolution is happening in the wrong scope (the private module's scope rather than the crate root where Env is defined).

Even though the link is unresolvable (which should just be a warning), rustdoc should not ICE. It should gracefully handle the unresolved link case.

Discovered in

This was discovered while running the following command on the stellar/rs-soroban-sdk repository:

cargo +nightly doc --no-deps --package soroban-sdk --package soroban-sdk-macros --package soroban-spec --package soroban-spec-rust --package soroban-ledger-snapshot --package soroban-meta --package soroban-token-sdk --package stellar-asset-spec --package proc_macros --all-features --open

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-intra-doc-linksArea: Intra-doc links, the ability to link to items in docs by nameC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions