@@ -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 } )
0 commit comments