@@ -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,15 @@ 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 = attrs
421+ . unwrap_or ( & [ ] )
422+ . iter ( )
423+ . find ( |x| x. has_name ( sym:: const_trait) )
424+ . map_or ( Const :: No , |x| Const :: Yes ( x. span ) ) ;
413425 let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
414426 generics,
427+ constness,
415428 id,
416429 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
417430 |this| {
@@ -431,6 +444,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
431444 ItemKind :: TraitAlias ( generics, bounds) => {
432445 let ( generics, bounds) = self . lower_generics (
433446 generics,
447+ Const :: No ,
434448 id,
435449 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
436450 |this| {
@@ -593,7 +607,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
593607 let fdec = & sig. decl ;
594608 let itctx = ImplTraitContext :: Universal ;
595609 let ( generics, ( fn_dec, fn_args) ) =
596- self . lower_generics ( generics, i. id , & itctx, |this| {
610+ self . lower_generics ( generics, Const :: No , i. id , & itctx, |this| {
597611 (
598612 // Disallow `impl Trait` in foreign items.
599613 this. lower_fn_decl (
@@ -745,6 +759,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
745759 add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
746760 let ( generics, kind) = self . lower_generics (
747761 & generics,
762+ Const :: No ,
748763 i. id ,
749764 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
750765 |this| {
@@ -843,6 +858,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
843858 add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
844859 self . lower_generics (
845860 & generics,
861+ Const :: No ,
846862 i. id ,
847863 & ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
848864 |this| match ty {
@@ -1201,9 +1217,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
12011217 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
12021218 let header = self . lower_fn_header ( sig. header ) ;
12031219 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- } ) ;
1220+ let ( generics, decl) =
1221+ self . lower_generics ( generics, sig. header . constness , id, & itctx, |this| {
1222+ this. lower_fn_decl ( & sig. decl , id, sig. span , kind, is_async)
1223+ } ) ;
12071224 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
12081225 }
12091226
@@ -1275,6 +1292,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12751292 fn lower_generics < T > (
12761293 & mut self ,
12771294 generics : & Generics ,
1295+ constness : Const ,
12781296 parent_node_id : NodeId ,
12791297 itctx : & ImplTraitContext ,
12801298 f : impl FnOnce ( & mut Self ) -> T ,
@@ -1372,6 +1390,87 @@ impl<'hir> LoweringContext<'_, 'hir> {
13721390 let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
13731391 predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
13741392
1393+ // Desugar `~const` bound in generics into an additional `const host: bool` param
1394+ // if the effects feature is enabled.
1395+ if let Const :: Yes ( span) = constness && self . tcx . features ( ) . effects
1396+ // Do not add host param if it already has it (manually specified)
1397+ && !params. iter ( ) . any ( |x| {
1398+ self . attrs . get ( & x. hir_id . local_id ) . map_or ( false , |attrs| {
1399+ attrs. iter ( ) . any ( |x| x. has_name ( sym:: rustc_host) )
1400+ } )
1401+ } )
1402+ {
1403+ let param_node_id = self . next_node_id ( ) ;
1404+ let const_node_id = self . next_node_id ( ) ;
1405+ let def_id = self . create_def ( self . local_def_id ( parent_node_id) , param_node_id, DefPathData :: TypeNs ( sym:: host) , span) ;
1406+ let anon_const: LocalDefId = self . create_def ( def_id, const_node_id, DefPathData :: AnonConst , span) ;
1407+
1408+ let hir_id = self . next_id ( ) ;
1409+ let const_id = self . next_id ( ) ;
1410+ let const_expr_id = self . next_id ( ) ;
1411+ let bool_id = self . next_id ( ) ;
1412+
1413+ self . children . push ( ( def_id, hir:: MaybeOwner :: NonOwner ( hir_id) ) ) ;
1414+ self . children . push ( ( anon_const, hir:: MaybeOwner :: NonOwner ( const_id) ) ) ;
1415+
1416+ let attr_id = self . tcx . sess . parse_sess . attr_id_generator . mk_attr_id ( ) ;
1417+
1418+ let attrs = self . arena . alloc_from_iter ( [
1419+ Attribute {
1420+ kind : AttrKind :: Normal ( P ( NormalAttr :: from_ident ( Ident :: new ( sym:: rustc_host, span) ) ) ) ,
1421+ span,
1422+ id : attr_id,
1423+ style : AttrStyle :: Outer ,
1424+ } ,
1425+ ] ) ;
1426+ self . attrs . insert ( hir_id. local_id , attrs) ;
1427+
1428+ let const_body = self . lower_body ( |this| {
1429+ (
1430+ & [ ] ,
1431+ hir:: Expr {
1432+ hir_id : const_expr_id,
1433+ kind : hir:: ExprKind :: Lit (
1434+ this. arena . alloc ( hir:: Lit { node : LitKind :: Bool ( true ) , span } ) ,
1435+ ) ,
1436+ span,
1437+ } ,
1438+ )
1439+ } ) ;
1440+
1441+ let param = hir:: GenericParam {
1442+ def_id,
1443+ hir_id,
1444+ name : hir:: ParamName :: Plain ( Ident { name : sym:: host, span } ) ,
1445+ span,
1446+ kind : hir:: GenericParamKind :: Const {
1447+ ty : self . arena . alloc ( self . ty (
1448+ span,
1449+ hir:: TyKind :: Path ( hir:: QPath :: Resolved (
1450+ None ,
1451+ self . arena . alloc ( hir:: Path {
1452+ res : Res :: PrimTy ( hir:: PrimTy :: Bool ) ,
1453+ span,
1454+ segments : self . arena . alloc_from_iter ( [ hir:: PathSegment {
1455+ ident : Ident { name : sym:: bool, span } ,
1456+ hir_id : bool_id,
1457+ res : Res :: PrimTy ( hir:: PrimTy :: Bool ) ,
1458+ args : None ,
1459+ infer_args : false ,
1460+ } ] ) ,
1461+ } ) ,
1462+ ) ) ,
1463+ ) ) ,
1464+ default : Some ( hir:: AnonConst { def_id : anon_const, hir_id : const_id, body : const_body } ) ,
1465+ } ,
1466+ colon_span : None ,
1467+ pure_wrt_drop : false ,
1468+ source : hir:: GenericParamSource :: Generics ,
1469+ } ;
1470+
1471+ params. push ( param) ;
1472+ }
1473+
13751474 let lowered_generics = self . arena . alloc ( hir:: Generics {
13761475 params : self . arena . alloc_from_iter ( params) ,
13771476 predicates : self . arena . alloc_from_iter ( predicates) ,
0 commit comments