Rollup merge of #139364 - Kohei316:feat/doc-hidden-suggestion, r=nnethercote

Make the compiler suggest actual paths instead of visible paths if the visible paths are through any doc hidden path.

close #127011
Currently, when emitting a diagnostic about a valid trait, the compiler suggestes using visible paths of the trait even if they are through a doc hidden path. This PR updates the compiler to suggest actual paths in these cases.
This commit is contained in:
Matthias Krüger 2025-04-09 14:52:37 +02:00 committed by GitHub
commit 7494bd9a4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 59 additions and 2 deletions

View File

@ -25,6 +25,7 @@ use rustc_middle::bug;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
use rustc_middle::ty::print::{
PrintTraitRefExt as _, with_crate_prefix, with_forced_trimmed_paths,
with_no_visible_paths_if_doc_hidden,
};
use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;
@ -3328,7 +3329,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let path_strings = candidates.iter().map(|trait_did| {
format!(
"{prefix}{}{postfix}\n",
with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
self.tcx.def_path_str(*trait_did)
)),
)
});
@ -3336,7 +3339,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"{prefix}{}::*{postfix} // trait {}\n",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
self.tcx.def_path_str(*parent_did)
)),
self.tcx.item_name(*trait_did),
)
});

View File

@ -63,6 +63,7 @@ thread_local! {
static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
static REDUCED_QUERIES: Cell<bool> = const { Cell::new(false) };
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
static NO_VISIBLE_PATH_IF_DOC_HIDDEN: Cell<bool> = const { Cell::new(false) };
static RTN_MODE: Cell<RtnMode> = const { Cell::new(RtnMode::ForDiagnostic) };
}
@ -134,6 +135,8 @@ define_helper!(
/// Prevent selection of visible paths. `Display` impl of DefId will prefer
/// visible (public) reexports of types as paths.
fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
/// Prevent selection of visible paths if the paths are through a doc hidden path.
fn with_no_visible_paths_if_doc_hidden(NoVisibleIfDocHiddenGuard, NO_VISIBLE_PATH_IF_DOC_HIDDEN);
);
#[must_use]
@ -569,6 +572,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
return Ok(false);
};
if self.tcx().is_doc_hidden(visible_parent) && with_no_visible_paths_if_doc_hidden() {
return Ok(false);
}
let actual_parent = self.tcx().opt_parent(def_id);
debug!(
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",

View File

@ -0,0 +1,5 @@
//@ edition: 2021
pub trait Foo {
fn foo();
}

View File

@ -0,0 +1,14 @@
// ignore-tidy-linelength
//@ edition: 2021
//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_a=suggest-trait-reexported-as-not-doc-visible-a.rs
pub struct Bar;
impl __DocHidden::Foo for Bar {
fn foo() {}
}
#[doc(hidden)]
pub mod __DocHidden {
pub use suggest_trait_reexported_as_not_doc_visible_a::Foo;
}

View File

@ -0,0 +1,11 @@
// ignore-tidy-linelength
//@ edition: 2021
//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_a=suggest-trait-reexported-as-not-doc-visible-a.rs
//@ aux-crate:suggest_trait_reexported_as_not_doc_visible_b=suggest-trait-reexported-as-not-doc-visible-b.rs
use suggest_trait_reexported_as_not_doc_visible_b::Bar;
fn main() {
Bar::foo();
//~^ ERROR: no function or associated item named `foo` found for struct `Bar` in the current scope [E0599]
}

View File

@ -0,0 +1,15 @@
error[E0599]: no function or associated item named `foo` found for struct `Bar` in the current scope
--> $DIR/suggest-trait-reexported-as-not-doc-visible.rs:9:10
|
LL | Bar::foo();
| ^^^ function or associated item not found in `Bar`
|
= help: items from traits can only be used if the trait is in scope
help: trait `Foo` which provides `foo` is implemented but not in scope; perhaps you want to import it
|
LL + use suggest_trait_reexported_as_not_doc_visible_a::Foo;
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0599`.