Decouple trait impls of different traits wrt incremental
This commit is contained in:
parent
97ea17b71a
commit
a7b687c26e
5 changed files with 14 additions and 6 deletions
|
@ -153,9 +153,12 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
}
|
||||
|
||||
fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> {
|
||||
let impls = tcx.local_trait_impls(def_id);
|
||||
// If there are no impls for the trait, then "all impls" are trivially coherent and we won't check anything
|
||||
// anyway. Thus we bail out even before the specialization graph, avoiding the dep_graph edge.
|
||||
let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) };
|
||||
if impls.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
// Trigger building the specialization graph for the trait. This will detect and report any
|
||||
// overlap errors.
|
||||
let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
|
||||
|
|
|
@ -368,7 +368,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] {
|
||||
self.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..])
|
||||
self.local_trait_impls(trait_did)
|
||||
}
|
||||
|
||||
/// Gets the attributes on the crate. This is preferable to
|
||||
|
|
|
@ -238,6 +238,8 @@ pub fn provide(providers: &mut Providers) {
|
|||
}
|
||||
};
|
||||
providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
|
||||
providers.local_trait_impls =
|
||||
|tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
|
||||
providers.expn_that_defined =
|
||||
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
|
||||
providers.in_scope_traits_map = |tcx, id| {
|
||||
|
|
|
@ -1502,6 +1502,11 @@ rustc_queries! {
|
|||
desc { "finding local trait impls" }
|
||||
}
|
||||
|
||||
/// Return all `impl` blocks of the given trait in the current crate.
|
||||
query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] {
|
||||
desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) }
|
||||
}
|
||||
|
||||
/// Given a trait `trait_id`, return all known `impl` blocks.
|
||||
query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
|
||||
arena_cache
|
||||
|
|
|
@ -324,11 +324,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
|
|||
// there's a Copy impl for any instance of the adt.
|
||||
if !is_copy(cx, ty) {
|
||||
if ty_subs.non_erasable_generics().next().is_some() {
|
||||
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).is_some_and(|impls| {
|
||||
impls.iter().any(|&id| {
|
||||
let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| {
|
||||
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
||||
if ty_adt.did() == adt.did())
|
||||
})
|
||||
});
|
||||
if !has_copy_impl {
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue