11use std:: iter;
22
3+ use rustc_data_structures:: fx:: FxHashSet ;
34use rustc_hir as hir;
45use rustc_hir:: lang_items:: LangItem ;
56use rustc_infer:: traits:: { ObligationCauseCode , PredicateObligations } ;
@@ -10,6 +11,7 @@ use rustc_middle::ty::{
1011} ;
1112use rustc_span:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId } ;
1213use rustc_span:: { DUMMY_SP , Span } ;
14+ use rustc_type_ir:: { Upcast , elaborate} ;
1315use tracing:: { debug, instrument, trace} ;
1416
1517use crate :: infer:: InferCtxt ;
@@ -632,7 +634,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
632634 // am looking forward to the future here.
633635 if !data. has_escaping_bound_vars ( ) && !region. has_escaping_bound_vars ( ) {
634636 let implicit_bounds = object_region_bounds ( self . tcx ( ) , data) ;
635-
636637 let explicit_bound = region;
637638
638639 self . out . reserve ( implicit_bounds. len ( ) ) ;
@@ -853,6 +854,39 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
853854 ) ) ;
854855 }
855856 }
857+
858+ // Finally, for backwards compatibility reasons, we imply the outlives bounds
859+ // that come from supertrait projections since we used to elaborate them into
860+ // the dyn trait itself.
861+ //
862+ // See <https://github.com/rust-lang/rust/pull/133397> when this was changed.
863+ let shadowed_projections: FxHashSet < _ > =
864+ data. projection_bounds ( ) . map ( |proj| proj. item_def_id ( ) ) . collect ( ) ;
865+ if let Some ( principal) = data. principal ( ) {
866+ let principal: ty:: Clause < ' tcx > = principal
867+ . with_self_ty ( self . tcx ( ) , self . tcx ( ) . types . trait_object_dummy_self )
868+ . upcast ( self . tcx ( ) ) ;
869+ for clause in elaborate:: elaborate ( self . tcx ( ) , [ principal] ) {
870+ if let Some ( proj) = clause. as_projection_clause ( )
871+ && !shadowed_projections. contains ( & proj. projection_def_id ( ) )
872+ {
873+ // A `Self` within the original bound will be instantiated with a
874+ // `trait_object_dummy_self`, so check for that.
875+ let references_self = match proj. skip_binder ( ) . term . unpack ( ) {
876+ ty:: TermKind :: Ty ( ty) => ty. walk ( ) . any ( |arg| {
877+ arg == self . tcx ( ) . types . trait_object_dummy_self . into ( )
878+ } ) ,
879+ // FIXME(associated_const_equality): We should walk the const instead of not doing anything
880+ ty:: TermKind :: Const ( _) => false ,
881+ } ;
882+ if !references_self {
883+ proj. map_bound ( |proj| & proj. projection_term . args [ 1 ..] )
884+ . visit_with ( self ) ;
885+ proj. term ( ) . visit_with ( self ) ;
886+ }
887+ }
888+ }
889+ }
856890 }
857891
858892 // Inference variables are the complicated case, since we don't
0 commit comments