Skip to content

Commit

Permalink
Add tcx.visible_traits() and use it for producing diagnostics
Browse files Browse the repository at this point in the history
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
is part of the problem with [1].

Includes a few comment updates for related API.

[1]: rust-lang#135232
  • Loading branch information
tgross35 committed Jan 14, 2025
1 parent 0b126e5 commit 122a0d0
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// all visible traits. If there's one clear winner, just suggest that.

let visible_traits: Vec<_> = tcx
.all_traits()
.visible_traits()
.filter(|trait_def_id| {
let viz = tcx.visibility(*trait_def_id);
let def_id = self.item_def_id();
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,8 @@ rustc_queries! {
eval_always
desc { "calculating the stability index for the local crate" }
}
/// All available crates in the graph, including those that should not be user-facing
/// (such as private crates).
query crates(_: ()) -> &'tcx [CrateNum] {
eval_always
desc { "fetching all foreign CrateNum instances" }
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2078,12 +2078,23 @@ impl<'tcx> TyCtxt<'tcx> {
self.limits(()).move_size_limit
}

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

/// All traits that are visible within the crate graph (i.e. excluding private dependencies).
pub fn visible_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
let visible_crates =
self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));

iter::once(LOCAL_CRATE)
.chain(visible_crates)
.flat_map(move |cnum| self.traits(cnum).iter().copied())
}

#[inline]
pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
self.visibility(def_id).expect_local()
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_passes/src/diagnostic_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,14 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
// Initialize the collector.
let mut items = DiagnosticItems::default();

// Collect diagnostic items in other crates.
for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
// Collect diagnostic items in visible crates.
for cnum in tcx
.crates(())
.iter()
.copied()
.filter(|cnum| tcx.is_user_visible_dep(*cnum))
.chain(std::iter::once(LOCAL_CRATE))
{
for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
collect_item(tcx, &mut items, name, def_id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
let traits_with_same_path: UnordSet<_> = self
.tcx
.all_traits()
.visible_traits()
.filter(|trait_def_id| *trait_def_id != trait_ref.def_id())
.map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id))
.filter(|(p, _)| *p == required_trait_path)
Expand Down

0 comments on commit 122a0d0

Please sign in to comment.