@@ -267,9 +267,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
267267 this. lower_maybe_async_body ( span, & decl, asyncness, body. as_deref ( ) ) ;
268268
269269 let ( generics, decl) =
270- this. add_implicit_generics ( generics, id, |this, idty| {
270+ this. add_implicit_generics ( generics, id, |this, idty, idpb | {
271271 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+ )
273278 } ) ;
274279 let sig = hir:: FnSig {
275280 decl,
@@ -384,7 +389,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
384389 // lifetime to be added, but rather a reference to a
385390 // parent lifetime.
386391 let ( generics, ( trait_ref, lowered_ty) ) =
387- self . add_implicit_generics ( ast_generics, id, |this, _| {
392+ self . add_implicit_generics ( ast_generics, id, |this, _, _ | {
388393 let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
389394 this. lower_trait_ref (
390395 trait_ref,
@@ -410,7 +415,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
410415 ImplPolarity :: Positive => ImplPolarity :: Positive ,
411416 ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( s) ) ,
412417 } ;
413- hir:: ItemKind :: Impl ( hir:: Impl {
418+ hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
414419 unsafety : self . lower_unsafety ( unsafety) ,
415420 polarity,
416421 defaultness,
@@ -420,7 +425,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
420425 of_trait : trait_ref,
421426 self_ty : lowered_ty,
422427 items : new_impl_items,
423- } )
428+ } ) )
424429 }
425430 ItemKind :: Trait ( box Trait {
426431 is_auto,
@@ -649,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
649654 ForeignItemKind :: Fn ( box Fn { ref sig, ref generics, .. } ) => {
650655 let fdec = & sig. decl ;
651656 let ( generics, ( fn_dec, fn_args) ) =
652- self . add_implicit_generics ( generics, i. id , |this, _| {
657+ self . add_implicit_generics ( generics, i. id , |this, _, _ | {
653658 (
654659 // Disallow `impl Trait` in foreign items.
655660 this. lower_fn_decl ( fdec, None , FnDeclKind :: ExternFn , None ) ,
@@ -1226,10 +1231,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
12261231 id : NodeId ,
12271232 kind : FnDeclKind ,
12281233 is_async : Option < NodeId > ,
1229- ) -> ( hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1234+ ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
12301235 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)
12331238 } ) ;
12341239 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
12351240 }
@@ -1289,7 +1294,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12891294 pub ( super ) fn lower_generics_mut (
12901295 & mut self ,
12911296 generics : & Generics ,
1292- itctx : ImplTraitContext < ' _ , ' hir > ,
1297+ mut itctx : ImplTraitContext < ' _ , ' hir > ,
12931298 ) -> GenericsCtor < ' hir > {
12941299 // Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
12951300 // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
@@ -1338,9 +1343,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
13381343 }
13391344 }
13401345
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+
13411359 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 ) ,
13441364 span : self . lower_span ( generics. span ) ,
13451365 }
13461366 }
@@ -1349,17 +1369,74 @@ impl<'hir> LoweringContext<'_, 'hir> {
13491369 & mut self ,
13501370 generics : & Generics ,
13511371 itctx : ImplTraitContext < ' _ , ' hir > ,
1352- ) -> hir:: Generics < ' hir > {
1372+ ) -> & ' hir hir:: Generics < ' hir > {
13531373 let generics_ctor = self . lower_generics_mut ( generics, itctx) ;
13541374 generics_ctor. into_generics ( self . arena )
13551375 }
13561376
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+ }
13631440 }
13641441 }
13651442
@@ -1371,10 +1448,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13711448 ref bounds,
13721449 span,
13731450 } ) => 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) ,
13781452 bounded_ty : self
13791453 . lower_ty ( bounded_ty, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Type ) ) ,
13801454 bounds : self . arena . alloc_from_iter ( bounds. iter ( ) . map ( |bound| {
@@ -1384,6 +1458,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13841458 )
13851459 } ) ) ,
13861460 span : self . lower_span ( span) ,
1461+ in_where_clause : true ,
13871462 } ) ,
13881463 WherePredicate :: RegionPredicate ( WhereRegionPredicate {
13891464 ref lifetime,
@@ -1396,6 +1471,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13961471 bounds,
13971472 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Bound ) ,
13981473 ) ,
1474+ in_where_clause : true ,
13991475 } ) ,
14001476 WherePredicate :: EqPredicate ( WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span } ) => {
14011477 hir:: WherePredicate :: EqPredicate ( hir:: WhereEqPredicate {
@@ -1414,16 +1490,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
14141490/// Helper struct for delayed construction of Generics.
14151491pub ( super ) struct GenericsCtor < ' hir > {
14161492 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 ,
14181496 span : Span ,
14191497}
14201498
14211499impl < ' 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 {
14241502 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 ,
14261506 span : self . span ,
1427- }
1507+ } )
14281508 }
14291509}
0 commit comments