about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeremy Smart <jeremy3141592@gmail.com>2025-06-30 20:27:33 -0400
committerJeremy Smart <jeremy3141592@gmail.com>2025-07-02 22:04:51 -0400
commit6b824e8143c1dcacdbac3f14f01e2bbb85da8907 (patch)
treed6106610b090b5aeb3e8c28f0130dfbb1a791bf1
parent1e6e4bb95ab7879283e4274bd80c3e04b1ea3f7c (diff)
downloadrust-6b824e8143c1dcacdbac3f14f01e2bbb85da8907.tar.gz
rust-6b824e8143c1dcacdbac3f14f01e2bbb85da8907.zip
avoid suggesting traits from private dependencies
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs2
-rw-r--r--src/librustdoc/clean/blanket_impl.rs2
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--tests/ui/typeck/dont-suggest-private-dependencies.rs7
-rw-r--r--tests/ui/typeck/dont-suggest-private-dependencies.stderr30
9 files changed, 28 insertions, 32 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index baf3b9b5bc9..51cd1b7704d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -1588,7 +1588,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             &infcx_
         };
 
-        tcx.all_traits()
+        tcx.all_traits_including_private()
             .filter(|trait_def_id| {
                 // Consider only traits with the associated type
                 tcx.associated_items(*trait_def_id)
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index b35aef13c52..f446bc468e4 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1725,7 +1725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if unsatisfied_predicates.is_empty()
                 // ...or if we already suggested that name because of `rustc_confusable` annotation
                 && Some(similar_candidate.name()) != confusable_suggested
-                // and if the we aren't in an expansion.
+                // and if we aren't in an expansion.
                 && !span.from_expansion()
             {
                 self.find_likely_intended_associated_item(
@@ -3477,9 +3477,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diag<'_>,
         item_name: Ident,
-        valid_out_of_scope_traits: Vec<DefId>,
+        mut valid_out_of_scope_traits: Vec<DefId>,
         explain: bool,
     ) -> bool {
+        valid_out_of_scope_traits.retain(|id| self.tcx.is_user_visible_dep(id.krate));
         if !valid_out_of_scope_traits.is_empty() {
             let mut candidates = valid_out_of_scope_traits;
             candidates.sort_by_key(|id| self.tcx.def_path_str(id));
@@ -4384,7 +4385,7 @@ pub(crate) struct TraitInfo {
 /// Retrieves all traits in this crate and any dependent crates,
 /// and wraps them into `TraitInfo` for custom sorting.
 pub(crate) fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
-    tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
+    tcx.all_traits_including_private().map(|def_id| TraitInfo { def_id }).collect()
 }
 
 fn print_disambiguation_help<'tcx>(
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index aa5355551ce..f8b6a30682b 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2318,7 +2318,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// All traits in the crate graph, including those not visible to the user.
-    pub fn all_traits(self) -> impl Iterator<Item = DefId> {
+    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
         iter::once(LOCAL_CRATE)
             .chain(self.crates(()).iter().copied())
             .flat_map(move |cnum| self.traits(cnum).iter().copied())
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index baa4c0681e8..3fa83cfc6a0 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -130,7 +130,11 @@ impl<'tcx> SmirCtxt<'tcx> {
 
     pub fn all_trait_decls(&self) -> stable_mir::TraitDecls {
         let mut tables = self.0.borrow_mut();
-        tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
+        tables
+            .tcx
+            .all_traits_including_private()
+            .map(|trait_def_id| tables.trait_def(trait_def_id))
+            .collect()
     }
 
     pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 0c88bd3dcbc..db2517a8379 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1850,7 +1850,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let trait_def_id = trait_pred.def_id();
         let trait_name = self.tcx.item_name(trait_def_id);
         let crate_name = self.tcx.crate_name(trait_def_id.krate);
-        if let Some(other_trait_def_id) = self.tcx.all_traits().find(|def_id| {
+        if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| {
             trait_name == self.tcx.item_name(trait_def_id)
                 && trait_def_id.krate != def_id.krate
                 && crate_name == self.tcx.crate_name(def_id.krate)
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index c889f52b789..11d5b472d73 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -23,7 +23,7 @@ pub(crate) fn synthesize_blanket_impls(
     let ty = tcx.type_of(item_def_id);
 
     let mut blanket_impls = Vec::new();
-    for trait_def_id in tcx.all_traits() {
+    for trait_def_id in tcx.visible_traits() {
         if !cx.cache.effective_visibilities.is_reachable(tcx, trait_def_id)
             || cx.generated_synthetics.contains(&(ty.skip_binder(), trait_def_id))
         {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index cf3c4ac97af..bd57bb21e63 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -353,7 +353,7 @@ pub(crate) fn run_global_ctxt(
     rustc_passes::stability::check_unused_or_stable_features(tcx);
 
     let auto_traits =
-        tcx.all_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();
+        tcx.visible_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();
 
     let mut ctxt = DocContext {
         tcx,
diff --git a/tests/ui/typeck/dont-suggest-private-dependencies.rs b/tests/ui/typeck/dont-suggest-private-dependencies.rs
index afac00c5213..ee5224e2d82 100644
--- a/tests/ui/typeck/dont-suggest-private-dependencies.rs
+++ b/tests/ui/typeck/dont-suggest-private-dependencies.rs
@@ -10,6 +10,13 @@
 //@ compile-flags: -Zunstable-options
 //@ forbid-output: private_dep
 
+// By default, the `read` diagnostic suggests `std::os::unix::fs::FileExt::read_at`. Add
+// something more likely to be recommended to make the diagnostic cross-platform.
+trait DecoyRead {
+    fn read1(&self) {}
+}
+impl<T> DecoyRead for Vec<T> {}
+
 struct VecReader(Vec<u8>);
 
 impl std::io::Read for VecReader {
diff --git a/tests/ui/typeck/dont-suggest-private-dependencies.stderr b/tests/ui/typeck/dont-suggest-private-dependencies.stderr
index 18848a2c08d..b7b14ee6b9b 100644
--- a/tests/ui/typeck/dont-suggest-private-dependencies.stderr
+++ b/tests/ui/typeck/dont-suggest-private-dependencies.stderr
@@ -1,42 +1,26 @@
 error[E0599]: no method named `read` found for struct `Vec<u8>` in the current scope
-  --> $DIR/dont-suggest-private-dependencies.rs:17:16
+  --> $DIR/dont-suggest-private-dependencies.rs:24:16
    |
 LL |         self.0.read(buf)
    |                ^^^^
    |
-   = help: items from traits can only be used if the trait is in scope
-help: trait `ReadRef` which provides `read` is implemented but not in scope; perhaps you want to import it
+help: there is a method `read1` with a similar name, but with different arguments
+  --> $DIR/dont-suggest-private-dependencies.rs:16:5
    |
-LL + use object::read::read_ref::ReadRef;
-   |
-help: there is a method `read_at` with a similar name
-   |
-LL |         self.0.read_at(buf)
-   |                    +++
+LL |     fn read1(&self) {}
+   |     ^^^^^^^^^^^^^^^
 
 error[E0599]: no function or associated item named `cast_from_lossy` found for type `u8` in the current scope
-  --> $DIR/dont-suggest-private-dependencies.rs:26:17
+  --> $DIR/dont-suggest-private-dependencies.rs:33:17
    |
 LL |     let _ = u8::cast_from_lossy(9);
    |                 ^^^^^^^^^^^^^^^ function or associated item not found in `u8`
-   |
-   = help: items from traits can only be used if the trait is in scope
-help: trait `CastFrom` which provides `cast_from_lossy` is implemented but not in scope; perhaps you want to import it
-   |
-LL + use compiler_builtins::math::libm_math::support::int_traits::CastFrom;
-   |
 
 error[E0599]: no function or associated item named `foo` found for struct `B` in the current scope
-  --> $DIR/dont-suggest-private-dependencies.rs:28:16
+  --> $DIR/dont-suggest-private-dependencies.rs:35:16
    |
 LL |     let _ = B::foo();
    |                ^^^ function or associated item not found in `B`
-   |
-   = help: items from traits can only be used if the trait is in scope
-help: trait `A` which provides `foo` is implemented but not in scope; perhaps you want to import it
-   |
-LL + use private_dep::A;
-   |
 
 error: aborting due to 3 previous errors