@@ -3,6 +3,7 @@ use super::ResolverAstLoweringExt;
33use super :: { AstOwner , ImplTraitContext , ImplTraitPosition } ;
44use super :: { FnDeclKind , LoweringContext , ParamMode } ;
55
6+ use hir:: definitions:: DefPathData ;
67use rustc_ast:: ptr:: P ;
78use rustc_ast:: visit:: AssocCtxt ;
89use rustc_ast:: * ;
@@ -257,10 +258,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
257258 ) ;
258259
259260 let itctx = ImplTraitContext :: Universal ;
260- let ( generics, decl) = this. lower_generics ( generics, id, & itctx, |this| {
261- let ret_id = asyncness. opt_return_id ( ) ;
262- this. lower_fn_decl ( & decl, id, * fn_sig_span, FnDeclKind :: Fn , ret_id)
263- } ) ;
261+ let ( generics, decl) =
262+ this. lower_generics ( generics, header. constness , id, & itctx, |this| {
263+ let ret_id = asyncness. opt_return_id ( ) ;
264+ this. lower_fn_decl ( & decl, id, * fn_sig_span, FnDeclKind :: Fn , ret_id)
265+ } ) ;
264266 let sig = hir:: FnSig {
265267 decl,
266268 header : this. lower_fn_header ( * header) ,
@@ -295,6 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
295297 add_ty_alias_where_clause ( & mut generics, * where_clauses, true ) ;
296298 let ( generics, ty) = self . lower_generics (
297299 & generics,
300+ Const :: No ,
298301 id,
299302 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
300303 |this| match ty {
@@ -316,6 +319,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
316319 ItemKind :: Enum ( enum_definition, generics) => {
317320 let ( generics, variants) = self . lower_generics (
318321 generics,
322+ Const :: No ,
319323 id,
320324 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
321325 |this| {
@@ -329,6 +333,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
329333 ItemKind :: Struct ( struct_def, generics) => {
330334 let ( generics, struct_def) = self . lower_generics (
331335 generics,
336+ Const :: No ,
332337 id,
333338 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
334339 |this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -338,6 +343,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
338343 ItemKind :: Union ( vdata, generics) => {
339344 let ( generics, vdata) = self . lower_generics (
340345 generics,
346+ Const :: No ,
341347 id,
342348 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
343349 |this| this. lower_variant_data ( hir_id, vdata) ,
@@ -369,7 +375,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
369375 // parent lifetime.
370376 let itctx = ImplTraitContext :: Universal ;
371377 let ( generics, ( trait_ref, lowered_ty) ) =
372- self . lower_generics ( ast_generics, id, & itctx, |this| {
378+ self . lower_generics ( ast_generics, * constness , id, & itctx, |this| {
373379 let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
374380 this. lower_trait_ref (
375381 trait_ref,
@@ -410,8 +416,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
410416 } ) )
411417 }
412418 ItemKind :: Trait ( box Trait { is_auto, unsafety, generics, bounds, items } ) => {
419+ // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
420+ let constness = if let Some ( attrs) = attrs {
421+ attrs
422+ . iter ( )
423+ . find ( |x| x. has_name ( sym:: const_trait) )
424+ . map_or ( Const :: No , |x| Const :: Yes ( x. span ) )
425+ } else {
426+ Const :: No
427+ } ;
413428 let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
414429 generics,
430+ constness,
415431 id,
416432 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
417433 |this| {
@@ -431,6 +447,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
431447 ItemKind :: TraitAlias ( generics, bounds) => {
432448 let ( generics, bounds) = self . lower_generics (
433449 generics,
450+ Const :: No ,
434451 id,
435452 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
436453 |this| {
@@ -593,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
593610 let fdec = & sig. decl ;
594611 let itctx = ImplTraitContext :: Universal ;
595612 let ( generics, ( fn_dec, fn_args) ) =
596- self . lower_generics ( generics, i. id , & itctx, |this| {
613+ self . lower_generics ( generics, Const :: No , i. id , & itctx, |this| {
597614 (
598615 // Disallow `impl Trait` in foreign items.
599616 this. lower_fn_decl (
@@ -745,6 +762,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
745762 add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
746763 let ( generics, kind) = self . lower_generics (
747764 & generics,
765+ Const :: No ,
748766 i. id ,
749767 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
750768 |this| {
@@ -843,6 +861,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
843861 add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
844862 self . lower_generics (
845863 & generics,
864+ Const :: No ,
846865 i. id ,
847866 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
848867 |this| match ty {
@@ -1201,9 +1220,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
12011220 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
12021221 let header = self . lower_fn_header ( sig. header ) ;
12031222 let itctx = ImplTraitContext :: Universal ;
1204- let ( generics, decl) = self . lower_generics ( generics, id, & itctx, |this| {
1205- this. lower_fn_decl ( & sig. decl , id, sig. span , kind, is_async)
1206- } ) ;
1223+ let ( generics, decl) =
1224+ self . lower_generics ( generics, sig. header . constness , id, & itctx, |this| {
1225+ this. lower_fn_decl ( & sig. decl , id, sig. span , kind, is_async)
1226+ } ) ;
12071227 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
12081228 }
12091229
@@ -1275,6 +1295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12751295 fn lower_generics < T > (
12761296 & mut self ,
12771297 generics : & Generics ,
1298+ constness : Const ,
12781299 parent_node_id : NodeId ,
12791300 itctx : & ImplTraitContext ,
12801301 f : impl FnOnce ( & mut Self ) -> T ,
@@ -1372,6 +1393,87 @@ impl<'hir> LoweringContext<'_, 'hir> {
13721393 let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
13731394 predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
13741395
1396+ // Desugar `~const` bound in generics into an additional `const host: bool` param
1397+ // if the effects feature is enabled.
1398+ if let Const :: Yes ( span) = constness && self . tcx . features ( ) . effects
1399+ // Do not add host param if it already has it (manually specified)
1400+ && !params. iter ( ) . any ( |x| {
1401+ self . attrs . get ( & x. hir_id . local_id ) . map_or ( false , |attrs| {
1402+ attrs. iter ( ) . any ( |x| x. has_name ( sym:: rustc_host) )
1403+ } )
1404+ } )
1405+ {
1406+ let param_node_id = self . next_node_id ( ) ;
1407+ let const_node_id = self . next_node_id ( ) ;
1408+ let def_id = self . create_def ( self . local_def_id ( parent_node_id) , param_node_id, DefPathData :: TypeNs ( sym:: host) , span) ;
1409+ let anon_const: LocalDefId = self . create_def ( def_id, const_node_id, DefPathData :: AnonConst , span) ;
1410+
1411+ let hir_id = self . next_id ( ) ;
1412+ let const_id = self . next_id ( ) ;
1413+ let const_expr_id = self . next_id ( ) ;
1414+ let bool_id = self . next_id ( ) ;
1415+
1416+ self . children . push ( ( def_id, hir:: MaybeOwner :: NonOwner ( hir_id) ) ) ;
1417+ self . children . push ( ( anon_const, hir:: MaybeOwner :: NonOwner ( const_id) ) ) ;
1418+
1419+ let attr_id = self . tcx . sess . parse_sess . attr_id_generator . mk_attr_id ( ) ;
1420+
1421+ let attrs = self . arena . alloc_from_iter ( [
1422+ Attribute {
1423+ kind : AttrKind :: Normal ( P ( NormalAttr :: from_ident ( Ident :: new ( sym:: rustc_host, span) ) ) ) ,
1424+ span,
1425+ id : attr_id,
1426+ style : AttrStyle :: Outer ,
1427+ } ,
1428+ ] ) ;
1429+ self . attrs . insert ( hir_id. local_id , attrs) ;
1430+
1431+ let const_body = self . lower_body ( |this| {
1432+ (
1433+ & [ ] ,
1434+ hir:: Expr {
1435+ hir_id : const_expr_id,
1436+ kind : hir:: ExprKind :: Lit (
1437+ this. arena . alloc ( hir:: Lit { node : LitKind :: Bool ( true ) , span } ) ,
1438+ ) ,
1439+ span,
1440+ } ,
1441+ )
1442+ } ) ;
1443+
1444+ let param = hir:: GenericParam {
1445+ def_id,
1446+ hir_id,
1447+ name : hir:: ParamName :: Plain ( Ident { name : sym:: host, span } ) ,
1448+ span,
1449+ kind : hir:: GenericParamKind :: Const {
1450+ ty : self . arena . alloc ( self . ty (
1451+ span,
1452+ hir:: TyKind :: Path ( hir:: QPath :: Resolved (
1453+ None ,
1454+ self . arena . alloc ( hir:: Path {
1455+ res : Res :: PrimTy ( hir:: PrimTy :: Bool ) ,
1456+ span,
1457+ segments : self . arena . alloc_from_iter ( [ hir:: PathSegment {
1458+ ident : Ident { name : sym:: bool, span } ,
1459+ hir_id : bool_id,
1460+ res : Res :: PrimTy ( hir:: PrimTy :: Bool ) ,
1461+ args : None ,
1462+ infer_args : false ,
1463+ } ] ) ,
1464+ } ) ,
1465+ ) ) ,
1466+ ) ) ,
1467+ default : Some ( hir:: AnonConst { def_id : anon_const, hir_id : const_id, body : const_body } ) ,
1468+ } ,
1469+ colon_span : None ,
1470+ pure_wrt_drop : false ,
1471+ source : hir:: GenericParamSource :: Generics ,
1472+ } ;
1473+
1474+ params. push ( param) ;
1475+ }
1476+
13751477 let lowered_generics = self . arena . alloc ( hir:: Generics {
13761478 params : self . arena . alloc_from_iter ( params) ,
13771479 predicates : self . arena . alloc_from_iter ( predicates) ,
0 commit comments