@@ -15,6 +15,7 @@ use rustc_infer::infer::outlives::obligations::TypeOutlives;
1515use rustc_infer:: infer:: { self , InferCtxt , TyCtxtInferExt } ;
1616use rustc_middle:: mir:: ConstraintCategory ;
1717use rustc_middle:: query:: Providers ;
18+ use rustc_middle:: ty:: print:: with_no_trimmed_paths;
1819use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
1920use rustc_middle:: ty:: {
2021 self , AdtKind , GenericParamDefKind , ToPredicate , Ty , TyCtxt , TypeFoldable , TypeSuperVisitable ,
@@ -112,8 +113,6 @@ where
112113
113114 let assumed_wf_types = wfcx. ocx . assumed_wf_types_and_report_errors ( param_env, body_def_id) ?;
114115
115- let implied_bounds = infcx. implied_bounds_tys ( param_env, body_def_id, assumed_wf_types) ;
116-
117116 let errors = wfcx. select_all_or_error ( ) ;
118117 if !errors. is_empty ( ) {
119118 let err = infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
@@ -128,10 +127,65 @@ where
128127 }
129128 }
130129
130+ debug ! ( ?assumed_wf_types) ;
131+
132+ let infcx_compat = infcx. fork ( ) ;
133+
134+ // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always.
135+ let implied_bounds =
136+ infcx. implied_bounds_tys_compat ( param_env, body_def_id, & assumed_wf_types, false ) ;
131137 let outlives_env = OutlivesEnvironment :: with_bounds ( param_env, implied_bounds) ;
132138
133- wfcx. ocx . resolve_regions_and_report_errors ( body_def_id, & outlives_env) ?;
134- infcx. tainted_by_errors ( ) . error_reported ( )
139+ let errors = infcx. resolve_regions ( & outlives_env) ;
140+ if errors. is_empty ( ) {
141+ return Ok ( ( ) ) ;
142+ }
143+
144+ let is_bevy = ' is_bevy: {
145+ // We don't want to emit this for dependents of Bevy, for now.
146+ // See #119956
147+ let is_bevy_paramset = |def : ty:: AdtDef < ' _ > | {
148+ let adt_did = with_no_trimmed_paths ! ( infcx. tcx. def_path_str( def. 0 . did) ) ;
149+ adt_did. contains ( "ParamSet" )
150+ } ;
151+ for ty in assumed_wf_types. iter ( ) {
152+ match ty. kind ( ) {
153+ ty:: Adt ( def, _) => {
154+ if is_bevy_paramset ( * def) {
155+ break ' is_bevy true ;
156+ }
157+ }
158+ ty:: Ref ( _, ty, _) => match ty. kind ( ) {
159+ ty:: Adt ( def, _) => {
160+ if is_bevy_paramset ( * def) {
161+ break ' is_bevy true ;
162+ }
163+ }
164+ _ => { }
165+ } ,
166+ _ => { }
167+ }
168+ }
169+ false
170+ } ;
171+
172+ // If we have set `no_implied_bounds_compat`, then do not attempt compatibility.
173+ // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`,
174+ // but that does result in slightly more work when this option is set and
175+ // just obscures what we mean here anyways. Let's just be explicit.
176+ if is_bevy && !infcx. tcx . sess . opts . unstable_opts . no_implied_bounds_compat {
177+ let implied_bounds =
178+ infcx_compat. implied_bounds_tys_compat ( param_env, body_def_id, & assumed_wf_types, true ) ;
179+ let outlives_env = OutlivesEnvironment :: with_bounds ( param_env, implied_bounds) ;
180+ let errors_compat = infcx_compat. resolve_regions ( & outlives_env) ;
181+ if errors_compat. is_empty ( ) {
182+ Ok ( ( ) )
183+ } else {
184+ Err ( infcx_compat. err_ctxt ( ) . report_region_errors ( body_def_id, & errors_compat) )
185+ }
186+ } else {
187+ Err ( infcx. err_ctxt ( ) . report_region_errors ( body_def_id, & errors) )
188+ }
135189}
136190
137191fn check_well_formed ( tcx : TyCtxt < ' _ > , def_id : hir:: OwnerId ) -> Result < ( ) , ErrorGuaranteed > {
@@ -723,7 +777,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
723777 let infcx = tcx. infer_ctxt ( ) . build ( ) ;
724778 let outlives_environment = OutlivesEnvironment :: with_bounds (
725779 param_env,
726- infcx. implied_bounds_tys ( param_env, id, wf_tys. clone ( ) ) ,
780+ infcx. implied_bounds_tys ( param_env, id, wf_tys) ,
727781 ) ;
728782 let region_bound_pairs = outlives_environment. region_bound_pairs ( ) ;
729783
0 commit comments