11use rustc_data_structures:: frozen:: Frozen ;
22use rustc_data_structures:: transitive_relation:: { TransitiveRelation , TransitiveRelationBuilder } ;
3+ use rustc_hir:: def:: DefKind ;
34use rustc_infer:: infer:: canonical:: QueryRegionConstraints ;
45use rustc_infer:: infer:: outlives;
56use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
67use rustc_infer:: infer:: region_constraints:: GenericKind ;
78use rustc_infer:: infer:: InferCtxt ;
89use rustc_middle:: mir:: ConstraintCategory ;
910use rustc_middle:: traits:: query:: OutlivesBound ;
10- use rustc_middle:: ty:: { self , RegionVid , Ty } ;
11+ use rustc_middle:: ty:: { self , DefIdTree as _ , RegionVid , Ty } ;
1112use rustc_trait_selection:: traits:: query:: type_op:: { self , TypeOp } ;
1213use std:: rc:: Rc ;
1314use type_op:: TypeOpOutput ;
@@ -218,7 +219,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
218219 }
219220
220221 pub ( crate ) fn create ( mut self ) -> CreateResult < ' tcx > {
221- let span = self . infcx . tcx . def_span ( self . universal_regions . defining_ty . def_id ( ) ) ;
222+ let tcx = self . infcx . tcx ;
223+ let defining_ty_def_id = self . universal_regions . defining_ty . def_id ( ) ;
224+ let span = self . infcx . tcx . def_span ( defining_ty_def_id) ;
225+
222226 let unnormalized_input_output_tys = self
223227 . universal_regions
224228 . unnormalized_input_tys
@@ -236,7 +240,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
236240 // the `relations` is built.
237241 let mut normalized_inputs_and_output =
238242 Vec :: with_capacity ( self . universal_regions . unnormalized_input_tys . len ( ) + 1 ) ;
239- let constraint_sets: Vec < _ > = unnormalized_input_output_tys
243+ let mut constraint_sets: Vec < _ > = unnormalized_input_output_tys
240244 . flat_map ( |ty| {
241245 debug ! ( "build: input_or_output={:?}" , ty) ;
242246 // We add implied bounds from both the unnormalized and normalized ty.
@@ -247,10 +251,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
247251 . and ( type_op:: normalize:: Normalize :: new ( ty) )
248252 . fully_perform ( self . infcx )
249253 . unwrap_or_else ( |_| {
250- self . infcx
251- . tcx
252- . sess
253- . delay_span_bug ( span, & format ! ( "failed to normalize {:?}" , ty) ) ;
254+ tcx. sess . delay_span_bug ( span, & format ! ( "failed to normalize {ty:?}" ) ) ;
254255 TypeOpOutput {
255256 output : self . infcx . tcx . ty_error ( ) ,
256257 constraints : None ,
@@ -276,6 +277,25 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
276277 } )
277278 . collect ( ) ;
278279
280+ // Add implied bounds from impl header.
281+ if let DefKind :: AssocFn = tcx. def_kind ( defining_ty_def_id) {
282+ for ty in tcx. assumed_wf_types ( tcx. parent ( defining_ty_def_id) ) {
283+ let Ok ( TypeOpOutput { output : norm_ty, constraints, .. } ) = self
284+ . param_env
285+ . and ( type_op:: normalize:: Normalize :: new ( ty) )
286+ . fully_perform ( self . infcx )
287+ else {
288+ tcx. sess . delay_span_bug ( span, & format ! ( "failed to normalize {ty:?}" ) ) ;
289+ continue ;
290+ } ;
291+
292+ // We currently add implied bounds from the normalized ty only.
293+ // This is more conservative and matches wfcheck behavior.
294+ self . add_implied_bounds ( norm_ty) ;
295+ constraint_sets. extend ( constraints) ;
296+ }
297+ }
298+
279299 // Insert the facts we know from the predicates. Why? Why not.
280300 let param_env = self . param_env ;
281301 self . add_outlives_bounds ( outlives:: explicit_outlives_bounds ( param_env) ) ;
0 commit comments