Skip to content

Commit c0eb4af

Browse files
committed
Add tcx.visible_traits() and use it for producing diagnostics
Add an alternative to `tcx.all_traits()` that only shows traits that the user might be able to use, for diagnostic purposes. With this available, make use of it for diagnostics including associated type errors which fixes [1]. Includes a few comment updates for related API. Fixes: #135232 [1]
1 parent 502915b commit c0eb4af

File tree

8 files changed

+34
-14
lines changed

8 files changed

+34
-14
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
179179
// all visible traits. If there's one clear winner, just suggest that.
180180

181181
let visible_traits: Vec<_> = tcx
182-
.all_traits()
182+
.visible_traits()
183183
.filter(|trait_def_id| {
184184
let viz = tcx.visibility(*trait_def_id);
185185
let def_id = self.item_def_id();

compiler/rustc_middle/src/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,8 @@ rustc_queries! {
21282128
eval_always
21292129
desc { "calculating the stability index for the local crate" }
21302130
}
2131+
/// All available crates in the graph, including those that should not be user-facing
2132+
/// (such as private crates).
21312133
query crates(_: ()) -> &'tcx [CrateNum] {
21322134
eval_always
21332135
desc { "fetching all foreign CrateNum instances" }

compiler/rustc_middle/src/ty/context.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2078,12 +2078,23 @@ impl<'tcx> TyCtxt<'tcx> {
20782078
self.limits(()).move_size_limit
20792079
}
20802080

2081+
/// All traits in the crate graph, including those not visible to the user.
20812082
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
20822083
iter::once(LOCAL_CRATE)
20832084
.chain(self.crates(()).iter().copied())
20842085
.flat_map(move |cnum| self.traits(cnum).iter().copied())
20852086
}
20862087

2088+
/// All traits that are visible within the crate graph (i.e. excluding private dependencies).
2089+
pub fn visible_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
2090+
let visible_crates =
2091+
self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2092+
2093+
iter::once(LOCAL_CRATE)
2094+
.chain(visible_crates)
2095+
.flat_map(move |cnum| self.traits(cnum).iter().copied())
2096+
}
2097+
20872098
#[inline]
20882099
pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
20892100
self.visibility(def_id).expect_local()

compiler/rustc_passes/src/diagnostic_items.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,14 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
7979
// Initialize the collector.
8080
let mut items = DiagnosticItems::default();
8181

82-
// Collect diagnostic items in other crates.
83-
for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
82+
// Collect diagnostic items in visible crates.
83+
for cnum in tcx
84+
.crates(())
85+
.iter()
86+
.copied()
87+
.filter(|cnum| tcx.is_user_visible_dep(*cnum))
88+
.chain(std::iter::once(LOCAL_CRATE))
89+
{
8490
for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
8591
collect_item(tcx, &mut items, name, def_id);
8692
}

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21892189
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
21902190
let traits_with_same_path: UnordSet<_> = self
21912191
.tcx
2192-
.all_traits()
2192+
.visible_traits()
21932193
.filter(|trait_def_id| *trait_def_id != trait_ref.def_id())
21942194
.map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id))
21952195
.filter(|(p, _)| *p == required_trait_path)

tests/ui/std/sysroot-private.default.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0405]: cannot find trait `Equivalent` in this scope
2-
--> $DIR/sysroot-private.rs:24:18
2+
--> $DIR/sysroot-private.rs:25:18
33
|
44
LL | trait Trait2<K>: Equivalent<K> {}
55
| ^^^^^^^^^^ not found in this scope
66

77
error[E0412]: cannot find type `K` in this scope
8-
--> $DIR/sysroot-private.rs:29:35
8+
--> $DIR/sysroot-private.rs:30:35
99
|
1010
LL | fn trait_member<T>(val: &T, key: &K) -> bool {
1111
| - ^
@@ -22,13 +22,13 @@ LL | fn trait_member<T, K>(val: &T, key: &K) -> bool {
2222
| +++
2323

2424
error[E0220]: associated type `Buf` not found for `Trait`
25-
--> $DIR/sysroot-private.rs:19:31
25+
--> $DIR/sysroot-private.rs:20:31
2626
|
2727
LL | type AssociatedTy = dyn Trait<Buf = i32, Bar = i32>;
28-
| ^^^ there is an associated type `Buf` in the trait `addr2line::lookup::LookupContinuation`
28+
| ^^^ help: `Trait` has the following associated type: `Bar`
2929

3030
error[E0425]: cannot find function `memchr2` in this scope
31-
--> $DIR/sysroot-private.rs:37:5
31+
--> $DIR/sysroot-private.rs:38:5
3232
|
3333
LL | memchr2(b'a', b'b', buf)
3434
| ^^^^^^^ not found in this scope

tests/ui/std/sysroot-private.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
trait Trait { type Bar; }
1717

1818
// Attempt to get a suggestion for `addr2line::LookupContinuation`, which has member `Buf`
19+
// Note that the suggestion only happens when `rustc_private` is enabled.
1920
type AssociatedTy = dyn Trait<Buf = i32, Bar = i32>;
2021
//~^ ERROR associated type `Buf` not found
21-
//~| NOTE there is an associated type `Buf` in the trait `addr2line::lookup::LookupContinuation`
22+
//[rustc_private_enabled]~| NOTE there is an associated type `Buf` in the trait `addr2line::lookup::LookupContinuation`
2223

2324
// Attempt to get a suggestion for `hashbrown::Equivalent`
2425
trait Trait2<K>: Equivalent<K> {}

tests/ui/std/sysroot-private.rustc_private_enabled.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0405]: cannot find trait `Equivalent` in this scope
2-
--> $DIR/sysroot-private.rs:24:18
2+
--> $DIR/sysroot-private.rs:25:18
33
|
44
LL | trait Trait2<K>: Equivalent<K> {}
55
| ^^^^^^^^^^ not found in this scope
66

77
error[E0412]: cannot find type `K` in this scope
8-
--> $DIR/sysroot-private.rs:29:35
8+
--> $DIR/sysroot-private.rs:30:35
99
|
1010
LL | fn trait_member<T>(val: &T, key: &K) -> bool {
1111
| - ^
@@ -22,13 +22,13 @@ LL | fn trait_member<T, K>(val: &T, key: &K) -> bool {
2222
| +++
2323

2424
error[E0220]: associated type `Buf` not found for `Trait`
25-
--> $DIR/sysroot-private.rs:19:31
25+
--> $DIR/sysroot-private.rs:20:31
2626
|
2727
LL | type AssociatedTy = dyn Trait<Buf = i32, Bar = i32>;
2828
| ^^^ there is an associated type `Buf` in the trait `addr2line::lookup::LookupContinuation`
2929

3030
error[E0425]: cannot find function `memchr2` in this scope
31-
--> $DIR/sysroot-private.rs:37:5
31+
--> $DIR/sysroot-private.rs:38:5
3232
|
3333
LL | memchr2(b'a', b'b', buf)
3434
| ^^^^^^^ not found in this scope

0 commit comments

Comments
 (0)