@@ -267,9 +267,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
267
267
this. lower_maybe_async_body ( span, & decl, asyncness, body. as_deref ( ) ) ;
268
268
269
269
let ( generics, decl) =
270
- this. add_implicit_generics ( generics, id, |this, idty| {
270
+ this. add_implicit_generics ( generics, id, |this, idty, idpb | {
271
271
let ret_id = asyncness. opt_return_id ( ) ;
272
- this. lower_fn_decl ( & decl, Some ( ( id, idty) ) , FnDeclKind :: Fn , ret_id)
272
+ this. lower_fn_decl (
273
+ & decl,
274
+ Some ( ( id, idty, idpb) ) ,
275
+ FnDeclKind :: Fn ,
276
+ ret_id,
277
+ )
273
278
} ) ;
274
279
let sig = hir:: FnSig {
275
280
decl,
@@ -384,7 +389,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
384
389
// lifetime to be added, but rather a reference to a
385
390
// parent lifetime.
386
391
let ( generics, ( trait_ref, lowered_ty) ) =
387
- self . add_implicit_generics ( ast_generics, id, |this, _| {
392
+ self . add_implicit_generics ( ast_generics, id, |this, _, _ | {
388
393
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
389
394
this. lower_trait_ref (
390
395
trait_ref,
@@ -410,7 +415,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
410
415
ImplPolarity :: Positive => ImplPolarity :: Positive ,
411
416
ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( s) ) ,
412
417
} ;
413
- hir:: ItemKind :: Impl ( hir:: Impl {
418
+ hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
414
419
unsafety : self . lower_unsafety ( unsafety) ,
415
420
polarity,
416
421
defaultness,
@@ -420,7 +425,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
420
425
of_trait : trait_ref,
421
426
self_ty : lowered_ty,
422
427
items : new_impl_items,
423
- } )
428
+ } ) )
424
429
}
425
430
ItemKind :: Trait ( box Trait {
426
431
is_auto,
@@ -649,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
649
654
ForeignItemKind :: Fn ( box Fn { ref sig, ref generics, .. } ) => {
650
655
let fdec = & sig. decl ;
651
656
let ( generics, ( fn_dec, fn_args) ) =
652
- self . add_implicit_generics ( generics, i. id , |this, _| {
657
+ self . add_implicit_generics ( generics, i. id , |this, _, _ | {
653
658
(
654
659
// Disallow `impl Trait` in foreign items.
655
660
this. lower_fn_decl ( fdec, None , FnDeclKind :: ExternFn , None ) ,
@@ -1226,10 +1231,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
1226
1231
id : NodeId ,
1227
1232
kind : FnDeclKind ,
1228
1233
is_async : Option < NodeId > ,
1229
- ) -> ( hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1234
+ ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1230
1235
let header = self . lower_fn_header ( sig. header ) ;
1231
- let ( generics, decl) = self . add_implicit_generics ( generics, id, |this, idty| {
1232
- this. lower_fn_decl ( & sig. decl , Some ( ( id, idty) ) , kind, is_async)
1236
+ let ( generics, decl) = self . add_implicit_generics ( generics, id, |this, idty, idpb | {
1237
+ this. lower_fn_decl ( & sig. decl , Some ( ( id, idty, idpb ) ) , kind, is_async)
1233
1238
} ) ;
1234
1239
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1235
1240
}
@@ -1289,7 +1294,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1289
1294
pub ( super ) fn lower_generics_mut (
1290
1295
& mut self ,
1291
1296
generics : & Generics ,
1292
- itctx : ImplTraitContext < ' _ , ' hir > ,
1297
+ mut itctx : ImplTraitContext < ' _ , ' hir > ,
1293
1298
) -> GenericsCtor < ' hir > {
1294
1299
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
1295
1300
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
@@ -1338,9 +1343,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
1338
1343
}
1339
1344
}
1340
1345
1346
+ let mut predicates = SmallVec :: new ( ) ;
1347
+ predicates. extend ( generics. params . iter ( ) . filter_map ( |param| {
1348
+ let bounds = self . lower_param_bounds ( & param. bounds , itctx. reborrow ( ) ) ;
1349
+ self . lower_generic_bound_predicate ( param. ident , param. id , & param. kind , bounds)
1350
+ } ) ) ;
1351
+ predicates. extend (
1352
+ generics
1353
+ . where_clause
1354
+ . predicates
1355
+ . iter ( )
1356
+ . map ( |predicate| self . lower_where_predicate ( predicate) ) ,
1357
+ ) ;
1358
+
1341
1359
GenericsCtor {
1342
- params : self . lower_generic_params_mut ( & generics. params , itctx) . collect ( ) ,
1343
- where_clause : self . lower_where_clause ( & generics. where_clause ) ,
1360
+ params : self . lower_generic_params_mut ( & generics. params ) . collect ( ) ,
1361
+ predicates,
1362
+ has_where_clause : !generics. where_clause . predicates . is_empty ( ) ,
1363
+ where_clause_span : self . lower_span ( generics. where_clause . span ) ,
1344
1364
span : self . lower_span ( generics. span ) ,
1345
1365
}
1346
1366
}
@@ -1349,17 +1369,74 @@ impl<'hir> LoweringContext<'_, 'hir> {
1349
1369
& mut self ,
1350
1370
generics : & Generics ,
1351
1371
itctx : ImplTraitContext < ' _ , ' hir > ,
1352
- ) -> hir:: Generics < ' hir > {
1372
+ ) -> & ' hir hir:: Generics < ' hir > {
1353
1373
let generics_ctor = self . lower_generics_mut ( generics, itctx) ;
1354
1374
generics_ctor. into_generics ( self . arena )
1355
1375
}
1356
1376
1357
- fn lower_where_clause ( & mut self , wc : & WhereClause ) -> hir:: WhereClause < ' hir > {
1358
- hir:: WhereClause {
1359
- predicates : self . arena . alloc_from_iter (
1360
- wc. predicates . iter ( ) . map ( |predicate| self . lower_where_predicate ( predicate) ) ,
1361
- ) ,
1362
- span : self . lower_span ( wc. span ) ,
1377
+ pub ( super ) fn lower_generic_bound_predicate (
1378
+ & mut self ,
1379
+ ident : Ident ,
1380
+ id : NodeId ,
1381
+ kind : & GenericParamKind ,
1382
+ bounds : & ' hir [ hir:: GenericBound < ' hir > ] ,
1383
+ ) -> Option < hir:: WherePredicate < ' hir > > {
1384
+ // Do not create a clause if we do not have anything inside it.
1385
+ if bounds. is_empty ( ) {
1386
+ return None ;
1387
+ }
1388
+ let ident = self . lower_ident ( ident) ;
1389
+ let param_span = ident. span ;
1390
+ let span = bounds
1391
+ . iter ( )
1392
+ . fold ( Some ( param_span. shrink_to_hi ( ) ) , |span : Option < Span > , bound| {
1393
+ let bound_span = bound. span ( ) ;
1394
+ // We include bounds that come from a `#[derive(_)]` but point at the user's code,
1395
+ // as we use this method to get a span appropriate for suggestions.
1396
+ if !bound_span. can_be_used_for_suggestions ( ) {
1397
+ None
1398
+ } else if let Some ( span) = span {
1399
+ Some ( span. to ( bound_span) )
1400
+ } else {
1401
+ Some ( bound_span)
1402
+ }
1403
+ } )
1404
+ . unwrap_or ( param_span. shrink_to_hi ( ) ) ;
1405
+ match kind {
1406
+ GenericParamKind :: Const { .. } => None ,
1407
+ GenericParamKind :: Type { .. } => {
1408
+ let def_id = self . resolver . local_def_id ( id) . to_def_id ( ) ;
1409
+ let ty_path = self . arena . alloc ( hir:: Path {
1410
+ span : param_span,
1411
+ res : Res :: Def ( DefKind :: TyParam , def_id) ,
1412
+ segments : self . arena . alloc_from_iter ( [ hir:: PathSegment :: from_ident ( ident) ] ) ,
1413
+ } ) ;
1414
+ let ty_id = self . next_id ( ) ;
1415
+ let bounded_ty =
1416
+ self . ty_path ( ty_id, param_span, hir:: QPath :: Resolved ( None , ty_path) ) ;
1417
+ Some ( hir:: WherePredicate :: BoundPredicate ( hir:: WhereBoundPredicate {
1418
+ bounded_ty : self . arena . alloc ( bounded_ty) ,
1419
+ bounds,
1420
+ span,
1421
+ bound_generic_params : & [ ] ,
1422
+ in_where_clause : false ,
1423
+ } ) )
1424
+ }
1425
+ GenericParamKind :: Lifetime => {
1426
+ let ident_span = self . lower_span ( ident. span ) ;
1427
+ let ident = self . lower_ident ( ident) ;
1428
+ let res = self . resolver . get_lifetime_res ( id) . unwrap_or_else ( || {
1429
+ panic ! ( "Missing resolution for lifetime {:?} at {:?}" , id, ident. span)
1430
+ } ) ;
1431
+ let lt_id = self . resolver . next_node_id ( ) ;
1432
+ let lifetime = self . new_named_lifetime_with_res ( lt_id, ident_span, ident, res) ;
1433
+ Some ( hir:: WherePredicate :: RegionPredicate ( hir:: WhereRegionPredicate {
1434
+ lifetime,
1435
+ span,
1436
+ bounds,
1437
+ in_where_clause : false ,
1438
+ } ) )
1439
+ }
1363
1440
}
1364
1441
}
1365
1442
@@ -1371,10 +1448,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1371
1448
ref bounds,
1372
1449
span,
1373
1450
} ) => hir:: WherePredicate :: BoundPredicate ( hir:: WhereBoundPredicate {
1374
- bound_generic_params : self . lower_generic_params (
1375
- bound_generic_params,
1376
- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
1377
- ) ,
1451
+ bound_generic_params : self . lower_generic_params ( bound_generic_params) ,
1378
1452
bounded_ty : self
1379
1453
. lower_ty ( bounded_ty, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Type ) ) ,
1380
1454
bounds : self . arena . alloc_from_iter ( bounds. iter ( ) . map ( |bound| {
@@ -1384,6 +1458,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1384
1458
)
1385
1459
} ) ) ,
1386
1460
span : self . lower_span ( span) ,
1461
+ in_where_clause : true ,
1387
1462
} ) ,
1388
1463
WherePredicate :: RegionPredicate ( WhereRegionPredicate {
1389
1464
ref lifetime,
@@ -1396,6 +1471,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1396
1471
bounds,
1397
1472
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
1398
1473
) ,
1474
+ in_where_clause : true ,
1399
1475
} ) ,
1400
1476
WherePredicate :: EqPredicate ( WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span } ) => {
1401
1477
hir:: WherePredicate :: EqPredicate ( hir:: WhereEqPredicate {
@@ -1414,16 +1490,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
1414
1490
/// Helper struct for delayed construction of Generics.
1415
1491
pub ( super ) struct GenericsCtor < ' hir > {
1416
1492
pub ( super ) params : SmallVec < [ hir:: GenericParam < ' hir > ; 4 ] > ,
1417
- where_clause : hir:: WhereClause < ' hir > ,
1493
+ pub ( super ) predicates : SmallVec < [ hir:: WherePredicate < ' hir > ; 4 ] > ,
1494
+ has_where_clause : bool ,
1495
+ where_clause_span : Span ,
1418
1496
span : Span ,
1419
1497
}
1420
1498
1421
1499
impl < ' hir > GenericsCtor < ' hir > {
1422
- pub ( super ) fn into_generics ( self , arena : & ' hir Arena < ' hir > ) -> hir:: Generics < ' hir > {
1423
- hir:: Generics {
1500
+ pub ( super ) fn into_generics ( self , arena : & ' hir Arena < ' hir > ) -> & ' hir hir:: Generics < ' hir > {
1501
+ arena . alloc ( hir:: Generics {
1424
1502
params : arena. alloc_from_iter ( self . params ) ,
1425
- where_clause : self . where_clause ,
1503
+ predicates : arena. alloc_from_iter ( self . predicates ) ,
1504
+ has_where_clause : self . has_where_clause ,
1505
+ where_clause_span : self . where_clause_span ,
1426
1506
span : self . span ,
1427
- }
1507
+ } )
1428
1508
}
1429
1509
}
0 commit comments