Skip to content

Commit f391497

Browse files
committed
Decouple trait impls of different traits wrt incremental
1 parent 6e8abb5 commit f391497

File tree

5 files changed

+14
-6
lines changed

5 files changed

+14
-6
lines changed

Diff for: compiler/rustc_hir_analysis/src/coherence/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,12 @@ pub(crate) fn provide(providers: &mut Providers) {
153153
}
154154

155155
fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> {
156+
let impls = tcx.local_trait_impls(def_id);
156157
// If there are no impls for the trait, then "all impls" are trivially coherent and we won't check anything
157158
// anyway. Thus we bail out even before the specialization graph, avoiding the dep_graph edge.
158-
let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) };
159+
if impls.is_empty() {
160+
return Ok(());
161+
}
159162
// Trigger building the specialization graph for the trait. This will detect and report any
160163
// overlap errors.
161164
let mut res = tcx.ensure_ok().specialization_graph_of(def_id);

Diff for: compiler/rustc_middle/src/hir/map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl<'tcx> TyCtxt<'tcx> {
368368
}
369369

370370
pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] {
371-
self.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..])
371+
self.local_trait_impls(trait_did)
372372
}
373373

374374
/// Gets the attributes on the crate. This is preferable to

Diff for: compiler/rustc_middle/src/hir/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ pub fn provide(providers: &mut Providers) {
233233
}
234234
};
235235
providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
236+
providers.local_trait_impls =
237+
|tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
236238
providers.expn_that_defined =
237239
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
238240
providers.in_scope_traits_map = |tcx, id| {

Diff for: compiler/rustc_middle/src/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,11 @@ rustc_queries! {
14841484
desc { "finding local trait impls" }
14851485
}
14861486

1487+
/// Return all `impl` blocks of the given trait in the current crate.
1488+
query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] {
1489+
desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) }
1490+
}
1491+
14871492
/// Given a trait `trait_id`, return all known `impl` blocks.
14881493
query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
14891494
arena_cache

Diff for: src/tools/clippy/clippy_lints/src/derive.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
324324
// there's a Copy impl for any instance of the adt.
325325
if !is_copy(cx, ty) {
326326
if ty_subs.non_erasable_generics().next().is_some() {
327-
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).is_some_and(|impls| {
328-
impls.iter().any(|&id| {
329-
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
327+
let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| {
328+
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
330329
if ty_adt.did() == adt.did())
331-
})
332330
});
333331
if !has_copy_impl {
334332
return;

0 commit comments

Comments
 (0)