@@ -390,23 +390,28 @@ impl<'tcx> TyCtxt<'tcx> {
390
390
pub fn calculate_dtor (
391
391
self ,
392
392
adt_did : LocalDefId ,
393
- validate : impl Fn ( Self , DefId ) -> Result < ( ) , ErrorGuaranteed > ,
393
+ validate : impl Fn ( Self , LocalDefId ) -> Result < ( ) , ErrorGuaranteed > ,
394
394
) -> Option < ty:: Destructor > {
395
395
let drop_trait = self . lang_items ( ) . drop_trait ( ) ?;
396
396
self . ensure_ok ( ) . coherent_trait ( drop_trait) . ok ( ) ?;
397
397
398
- let ty = self . type_of ( adt_did) . instantiate_identity ( ) ;
399
398
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
+
401
406
if validate ( self , impl_did) . is_err ( ) {
402
407
// Already `ErrorGuaranteed`, no need to delay a span bug here.
403
- return ;
408
+ continue ;
404
409
}
405
410
406
411
let Some ( item_id) = self . associated_item_def_ids ( impl_did) . first ( ) else {
407
412
self . dcx ( )
408
413
. span_delayed_bug ( self . def_span ( impl_did) , "Drop impl without drop function" ) ;
409
- return ;
414
+ continue ;
410
415
} ;
411
416
412
417
if let Some ( ( old_item_id, _) ) = dtor_candidate {
@@ -417,7 +422,7 @@ impl<'tcx> TyCtxt<'tcx> {
417
422
}
418
423
419
424
dtor_candidate = Some ( ( * item_id, self . impl_trait_header ( impl_did) . unwrap ( ) . constness ) ) ;
420
- } ) ;
425
+ }
421
426
422
427
let ( did, constness) = dtor_candidate?;
423
428
Some ( ty:: Destructor { did, constness } )
@@ -427,25 +432,30 @@ impl<'tcx> TyCtxt<'tcx> {
427
432
pub fn calculate_async_dtor (
428
433
self ,
429
434
adt_did : LocalDefId ,
430
- validate : impl Fn ( Self , DefId ) -> Result < ( ) , ErrorGuaranteed > ,
435
+ validate : impl Fn ( Self , LocalDefId ) -> Result < ( ) , ErrorGuaranteed > ,
431
436
) -> Option < ty:: AsyncDestructor > {
432
437
let async_drop_trait = self . lang_items ( ) . async_drop_trait ( ) ?;
433
438
self . ensure_ok ( ) . coherent_trait ( async_drop_trait) . ok ( ) ?;
434
439
435
- let ty = self . type_of ( adt_did) . instantiate_identity ( ) ;
436
440
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
+
438
448
if validate ( self , impl_did) . is_err ( ) {
439
449
// Already `ErrorGuaranteed`, no need to delay a span bug here.
440
- return ;
450
+ continue ;
441
451
}
442
452
443
453
let [ future, ctor] = self . associated_item_def_ids ( impl_did) else {
444
454
self . dcx ( ) . span_delayed_bug (
445
455
self . def_span ( impl_did) ,
446
456
"AsyncDrop impl without async_drop function or Dropper type" ,
447
457
) ;
448
- return ;
458
+ continue ;
449
459
} ;
450
460
451
461
if let Some ( ( _, _, old_impl_did) ) = dtor_candidate {
@@ -456,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> {
456
466
}
457
467
458
468
dtor_candidate = Some ( ( * future, * ctor, impl_did) ) ;
459
- } ) ;
469
+ }
460
470
461
471
let ( future, ctor, _) = dtor_candidate?;
462
472
Some ( ty:: AsyncDestructor { future, ctor } )
0 commit comments