1
1
use rustc_data_structures:: frozen:: Frozen ;
2
2
use rustc_data_structures:: transitive_relation:: { TransitiveRelation , TransitiveRelationBuilder } ;
3
+ use rustc_hir:: def:: DefKind ;
3
4
use rustc_infer:: infer:: canonical:: QueryRegionConstraints ;
4
5
use rustc_infer:: infer:: outlives;
5
6
use rustc_infer:: infer:: outlives:: env:: RegionBoundPairs ;
6
7
use rustc_infer:: infer:: region_constraints:: GenericKind ;
7
8
use rustc_infer:: infer:: InferCtxt ;
8
9
use rustc_middle:: mir:: ConstraintCategory ;
9
10
use rustc_middle:: traits:: query:: OutlivesBound ;
10
- use rustc_middle:: ty:: { self , RegionVid , Ty } ;
11
+ use rustc_middle:: ty:: { self , DefIdTree as _ , RegionVid , Ty } ;
11
12
use rustc_trait_selection:: traits:: query:: type_op:: { self , TypeOp } ;
12
13
use std:: rc:: Rc ;
13
14
use type_op:: TypeOpOutput ;
@@ -218,7 +219,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
218
219
}
219
220
220
221
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
+
222
226
let unnormalized_input_output_tys = self
223
227
. universal_regions
224
228
. unnormalized_input_tys
@@ -236,7 +240,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
236
240
// the `relations` is built.
237
241
let mut normalized_inputs_and_output =
238
242
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
240
244
. flat_map ( |ty| {
241
245
debug ! ( "build: input_or_output={:?}" , ty) ;
242
246
// We add implied bounds from both the unnormalized and normalized ty.
@@ -247,10 +251,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
247
251
. and ( type_op:: normalize:: Normalize :: new ( ty) )
248
252
. fully_perform ( self . infcx )
249
253
. 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:?}" ) ) ;
254
255
TypeOpOutput {
255
256
output : self . infcx . tcx . ty_error ( ) ,
256
257
constraints : None ,
@@ -276,6 +277,25 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
276
277
} )
277
278
. collect ( ) ;
278
279
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
+
279
299
// Insert the facts we know from the predicates. Why? Why not.
280
300
let param_env = self . param_env ;
281
301
self . add_outlives_bounds ( outlives:: explicit_outlives_bounds ( param_env) ) ;
0 commit comments