1111
1212pub  mod  specialization_graph; 
1313
14- use  rustc_data_structures:: fx:: FxIndexSet ; 
14+ use  rustc_data_structures:: fx:: { FxHashSet ,   FxIndexSet } ; 
1515use  rustc_errors:: codes:: * ; 
1616use  rustc_errors:: { Diag ,  EmissionGuarantee } ; 
1717use  rustc_hir:: LangItem ; 
@@ -25,6 +25,8 @@ use rustc_middle::ty::{
2525} ; 
2626use  rustc_session:: lint:: builtin:: { COHERENCE_LEAK_CHECK ,  ORDER_DEPENDENT_TRAIT_OBJECTS } ; 
2727use  rustc_span:: { DUMMY_SP ,  ErrorGuaranteed ,  Span ,  sym} ; 
28+ use  rustc_type_ir:: elaborate; 
29+ use  rustc_type_ir:: fast_reject:: { SimplifiedType ,  TreatParams ,  simplify_type} ; 
2830use  specialization_graph:: GraphExt ; 
2931use  tracing:: { debug,  instrument} ; 
3032
@@ -484,20 +486,62 @@ fn report_conflicting_impls<'tcx>(
484486
485487pub ( super )  fn  trait_has_impl_which_may_shadow_dyn < ' tcx > ( 
486488    tcx :  TyCtxt < ' tcx > , 
487-     trait_def_id :   DefId , 
489+     ( target_trait_def_id ,  principal_def_id ) :   ( DefId ,   Option < DefId > ) , 
488490)  -> bool  { 
489491    // We only care about trait objects which have associated types. 
490492    if  !tcx
491-         . associated_items ( trait_def_id ) 
493+         . associated_items ( target_trait_def_id ) 
492494        . in_definition_order ( ) 
493495        . any ( |item| item. kind  == ty:: AssocKind :: Type ) 
494496    { 
495497        return  false ; 
496498    } 
497499
498-     let  mut  has_impl = false ; 
499-     tcx. for_each_impl ( trait_def_id,  |impl_def_id| { 
500-         if  has_impl { 
500+     let  target_self_ty =
501+         principal_def_id. map_or ( SimplifiedType :: MarkerTraitObject ,  SimplifiedType :: Trait ) ; 
502+ 
503+     let  elaborated_supertraits =
504+         principal_def_id. into_iter ( ) . flat_map ( |def_id| tcx. supertrait_def_ids ( def_id) ) . collect ( ) ; 
505+ 
506+     trait_has_impl_inner ( 
507+         tcx, 
508+         target_trait_def_id, 
509+         target_self_ty, 
510+         & elaborated_supertraits, 
511+         & mut  Default :: default ( ) , 
512+         true , 
513+     ) 
514+ } 
515+ 
516+ fn  trait_has_impl_inner < ' tcx > ( 
517+     tcx :  TyCtxt < ' tcx > , 
518+     target_trait_def_id :  DefId , 
519+     target_self_ty :  SimplifiedType < DefId > , 
520+     elaborated_supertraits :  & FxHashSet < DefId > , 
521+     seen_traits :  & mut  FxHashSet < DefId > , 
522+     first_generation :  bool , 
523+ )  -> bool  { 
524+     if  tcx. is_lang_item ( target_trait_def_id,  LangItem :: Sized )  { 
525+         return  false ; 
526+     } 
527+ 
528+     // If we've encountered a trait in a cycle, then let's just 
529+     // consider it to be implemented defensively. 
530+     if  !seen_traits. insert ( target_trait_def_id)  { 
531+         return  true ; 
532+     } 
533+     // Since we don't pass in the set of auto traits, and just the principal, 
534+     // consider all auto traits implemented. 
535+     if  tcx. trait_is_auto ( target_trait_def_id)  { 
536+         return  true ; 
537+     } 
538+     if  !first_generation && elaborated_supertraits. contains ( & target_trait_def_id)  { 
539+         return  true ; 
540+     } 
541+ 
542+     let  mut  has_offending_impl = false ; 
543+     tcx. for_each_impl ( target_trait_def_id,  |impl_def_id| { 
544+         if  has_offending_impl { 
501545            return ; 
502546        } 
503547
@@ -506,33 +550,51 @@ pub(super) fn trait_has_impl_which_may_shadow_dyn<'tcx>(
506550            . expect ( "impl must have trait ref" ) 
507551            . instantiate_identity ( ) 
508552            . self_ty ( ) ; 
509-         if  self_ty. is_known_rigid ( )  { 
510-             return ; 
511-         } 
512553
513-         let  sized_trait = tcx. require_lang_item ( LangItem :: Sized ,  None ) ; 
514-         if  tcx
515-             . param_env ( impl_def_id) 
516-             . caller_bounds ( ) 
517-             . iter ( ) 
518-             . filter_map ( |clause| clause. as_trait_clause ( ) ) 
519-             . any ( |bound| bound. def_id ( )  == sized_trait && bound. self_ty ( ) . skip_binder ( )  == self_ty) 
554+         if  simplify_type ( tcx,  self_ty,  TreatParams :: InstantiateWithInfer ) 
555+             . is_some_and ( |simp| simp != target_self_ty) 
520556        { 
521557            return ; 
522558        } 
523559
524-         if  let  ty:: Alias ( ty:: Projection ,  alias_ty)  = self_ty. kind ( ) 
525-             && tcx
526-                 . item_super_predicates ( alias_ty. def_id ) 
527-                 . iter_identity ( ) 
528-                 . filter_map ( |clause| clause. as_trait_clause ( ) ) 
529-                 . any ( |bound| bound. def_id ( )  == sized_trait) 
560+         for  ( pred,  _)  in 
561+             elaborate:: elaborate ( tcx,  tcx. predicates_of ( impl_def_id) . instantiate_identity ( tcx) ) 
530562        { 
531-             return ; 
563+             if  let  ty:: ClauseKind :: Trait ( trait_pred)  = pred. kind ( ) . skip_binder ( ) 
564+                 && trait_pred. self_ty ( )  == self_ty
565+                 && !trait_has_impl_inner ( 
566+                     tcx, 
567+                     trait_pred. def_id ( ) , 
568+                     target_self_ty, 
569+                     elaborated_supertraits, 
570+                     seen_traits, 
571+                     false , 
572+                 ) 
573+             { 
574+                 return ; 
575+             } 
576+         } 
577+ 
578+         if  let  ty:: Alias ( ty:: Projection ,  alias_ty)  = self_ty. kind ( )  { 
579+             for  pred in  tcx. item_super_predicates ( alias_ty. def_id ) . iter_identity ( )  { 
580+                 if  let  ty:: ClauseKind :: Trait ( trait_pred)  = pred. kind ( ) . skip_binder ( ) 
581+                     && trait_pred. self_ty ( )  == self_ty
582+                     && !trait_has_impl_inner ( 
583+                         tcx, 
584+                         trait_pred. def_id ( ) , 
585+                         target_self_ty, 
586+                         elaborated_supertraits, 
587+                         seen_traits, 
588+                         false , 
589+                     ) 
590+                 { 
591+                     return ; 
592+                 } 
593+             } 
532594        } 
533595
534-         has_impl  = true ; 
596+         has_offending_impl  = true ; 
535597    } ) ; 
536598
537-     has_impl 
599+     has_offending_impl 
538600} 
0 commit comments