From ca32447c0ccd38367ad1ff98c784f17f21d0e80e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Mar 2025 14:11:44 +0000 Subject: Only look at trait impls in the current crate when looking for `Drop` impls --- compiler/rustc_middle/src/ty/util.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_middle') diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 61d8b5ce52e..45a7635087e 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -390,23 +390,28 @@ impl<'tcx> TyCtxt<'tcx> { pub fn calculate_dtor( self, adt_did: LocalDefId, - validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>, + validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>, ) -> Option { let drop_trait = self.lang_items().drop_trait()?; self.ensure_ok().coherent_trait(drop_trait).ok()?; - let ty = self.type_of(adt_did).instantiate_identity(); let mut dtor_candidate = None; - self.for_each_relevant_impl(drop_trait, ty, |impl_did| { + // `Drop` impls can only be written in the same crate as the adt, and cannot be blanket impls + for &impl_did in self.local_trait_impls(drop_trait) { + let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue }; + if adt_def.did() != adt_did.to_def_id() { + continue; + } + if validate(self, impl_did).is_err() { // Already `ErrorGuaranteed`, no need to delay a span bug here. - return; + continue; } let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { self.dcx() .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function"); - return; + continue; }; if let Some((old_item_id, _)) = dtor_candidate { @@ -417,7 +422,7 @@ impl<'tcx> TyCtxt<'tcx> { } dtor_candidate = Some((*item_id, self.impl_trait_header(impl_did).unwrap().constness)); - }); + } let (did, constness) = dtor_candidate?; Some(ty::Destructor { did, constness }) @@ -427,17 +432,22 @@ impl<'tcx> TyCtxt<'tcx> { pub fn calculate_async_dtor( self, adt_did: LocalDefId, - validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>, + validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>, ) -> Option { let async_drop_trait = self.lang_items().async_drop_trait()?; self.ensure_ok().coherent_trait(async_drop_trait).ok()?; - let ty = self.type_of(adt_did).instantiate_identity(); let mut dtor_candidate = None; - self.for_each_relevant_impl(async_drop_trait, ty, |impl_did| { + // `AsyncDrop` impls can only be written in the same crate as the adt, and cannot be blanket impls + for &impl_did in self.local_trait_impls(async_drop_trait) { + let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue }; + if adt_def.did() != adt_did.to_def_id() { + continue; + } + if validate(self, impl_did).is_err() { // Already `ErrorGuaranteed`, no need to delay a span bug here. - return; + continue; } let [future, ctor] = self.associated_item_def_ids(impl_did) else { @@ -445,7 +455,7 @@ impl<'tcx> TyCtxt<'tcx> { self.def_span(impl_did), "AsyncDrop impl without async_drop function or Dropper type", ); - return; + continue; }; if let Some((_, _, old_impl_did)) = dtor_candidate { @@ -456,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> { } dtor_candidate = Some((*future, *ctor, impl_did)); - }); + } let (future, ctor, _) = dtor_candidate?; Some(ty::AsyncDestructor { future, ctor }) -- cgit 1.4.1-3-g733a5