Skip to content

Commit 9d05efb

Browse files
committed
Only look at trait impls in the current crate when looking for Drop impls
1 parent f98366d commit 9d05efb

File tree

3 files changed

+27
-18
lines changed

3 files changed

+27
-18
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/always_applicable.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ use crate::hir::def_id::{DefId, LocalDefId};
3636
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
3737
pub(crate) fn check_drop_impl(
3838
tcx: TyCtxt<'_>,
39-
drop_impl_did: DefId,
39+
drop_impl_did: LocalDefId,
4040
) -> Result<(), ErrorGuaranteed> {
41-
let drop_impl_did = drop_impl_did.expect_local();
42-
4341
match tcx.impl_polarity(drop_impl_did) {
4442
ty::ImplPolarity::Positive => {}
4543
ty::ImplPolarity::Negative => {

Diff for: compiler/rustc_middle/src/ty/util.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -390,23 +390,28 @@ impl<'tcx> TyCtxt<'tcx> {
390390
pub fn calculate_dtor(
391391
self,
392392
adt_did: LocalDefId,
393-
validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
393+
validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>,
394394
) -> Option<ty::Destructor> {
395395
let drop_trait = self.lang_items().drop_trait()?;
396396
self.ensure_ok().coherent_trait(drop_trait).ok()?;
397397

398-
let ty = self.type_of(adt_did).instantiate_identity();
399398
let mut dtor_candidate = None;
400-
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
399+
// `Drop` impls can only be written in the same crate as the adt, and cannot be blanket impls
400+
for &impl_did in self.local_trait_impls(drop_trait) {
401+
let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue };
402+
if adt_def.did() != adt_did.to_def_id() {
403+
continue;
404+
}
405+
401406
if validate(self, impl_did).is_err() {
402407
// Already `ErrorGuaranteed`, no need to delay a span bug here.
403-
return;
408+
continue;
404409
}
405410

406411
let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
407412
self.dcx()
408413
.span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function");
409-
return;
414+
continue;
410415
};
411416

412417
if let Some((old_item_id, _)) = dtor_candidate {
@@ -417,7 +422,7 @@ impl<'tcx> TyCtxt<'tcx> {
417422
}
418423

419424
dtor_candidate = Some((*item_id, self.impl_trait_header(impl_did).unwrap().constness));
420-
});
425+
}
421426

422427
let (did, constness) = dtor_candidate?;
423428
Some(ty::Destructor { did, constness })
@@ -427,25 +432,30 @@ impl<'tcx> TyCtxt<'tcx> {
427432
pub fn calculate_async_dtor(
428433
self,
429434
adt_did: LocalDefId,
430-
validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
435+
validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>,
431436
) -> Option<ty::AsyncDestructor> {
432437
let async_drop_trait = self.lang_items().async_drop_trait()?;
433438
self.ensure_ok().coherent_trait(async_drop_trait).ok()?;
434439

435-
let ty = self.type_of(adt_did).instantiate_identity();
436440
let mut dtor_candidate = None;
437-
self.for_each_relevant_impl(async_drop_trait, ty, |impl_did| {
441+
// `AsyncDrop` impls can only be written in the same crate as the adt, and cannot be blanket impls
442+
for &impl_did in self.local_trait_impls(async_drop_trait) {
443+
let Some(adt_def) = self.type_of(impl_did).skip_binder().ty_adt_def() else { continue };
444+
if adt_def.did() != adt_did.to_def_id() {
445+
continue;
446+
}
447+
438448
if validate(self, impl_did).is_err() {
439449
// Already `ErrorGuaranteed`, no need to delay a span bug here.
440-
return;
450+
continue;
441451
}
442452

443453
let [future, ctor] = self.associated_item_def_ids(impl_did) else {
444454
self.dcx().span_delayed_bug(
445455
self.def_span(impl_did),
446456
"AsyncDrop impl without async_drop function or Dropper type",
447457
);
448-
return;
458+
continue;
449459
};
450460

451461
if let Some((_, _, old_impl_did)) = dtor_candidate {
@@ -456,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> {
456466
}
457467

458468
dtor_candidate = Some((*future, *ctor, impl_did));
459-
});
469+
}
460470

461471
let (future, ctor, _) = dtor_candidate?;
462472
Some(ty::AsyncDestructor { future, ctor })

Diff for: compiler/rustc_mir_transform/src/check_const_item_mutation.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
5353
//
5454
// #[const_mutation_allowed]
5555
// pub const LOG: Log = Log { msg: "" };
56-
match self.tcx.adt_destructor(def_id) {
57-
Some(_) => None,
58-
None => Some(def_id),
56+
match self.tcx.type_of(def_id).skip_binder().ty_adt_def().map(|adt| adt.has_dtor(self.tcx))
57+
{
58+
Some(true) => None,
59+
Some(false) | None => Some(def_id),
5960
}
6061
}
6162

0 commit comments

Comments
 (0)