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> {
|
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
|
// 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.
|
// 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
|
// Trigger building the specialization graph for the trait. This will detect and report any
|
||||||
// overlap errors.
|
// overlap errors.
|
||||||
let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
|
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] {
|
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
|
/// 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.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 =
|
providers.expn_that_defined =
|
||||||
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
|
|tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
|
||||||
providers.in_scope_traits_map = |tcx, id| {
|
providers.in_scope_traits_map = |tcx, id| {
|
||||||
|
|
|
@ -1502,6 +1502,11 @@ rustc_queries! {
|
||||||
desc { "finding local trait impls" }
|
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.
|
/// Given a trait `trait_id`, return all known `impl` blocks.
|
||||||
query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
|
query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
|
||||||
arena_cache
|
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.
|
// there's a Copy impl for any instance of the adt.
|
||||||
if !is_copy(cx, ty) {
|
if !is_copy(cx, ty) {
|
||||||
if ty_subs.non_erasable_generics().next().is_some() {
|
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| {
|
let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| {
|
||||||
impls.iter().any(|&id| {
|
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
||||||
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
|
||||||
if ty_adt.did() == adt.did())
|
if ty_adt.did() == adt.did())
|
||||||
})
|
|
||||||
});
|
});
|
||||||
if !has_copy_impl {
|
if !has_copy_impl {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue