@@ -3,6 +3,7 @@ use super::ResolverAstLoweringExt;
3
3
use super :: { AstOwner , ImplTraitContext , ImplTraitPosition } ;
4
4
use super :: { FnDeclKind , LoweringContext , ParamMode } ;
5
5
6
+ use hir:: definitions:: DefPathData ;
6
7
use rustc_ast:: ptr:: P ;
7
8
use rustc_ast:: visit:: AssocCtxt ;
8
9
use rustc_ast:: * ;
@@ -257,10 +258,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
257
258
) ;
258
259
259
260
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
+ } ) ;
264
266
let sig = hir:: FnSig {
265
267
decl,
266
268
header : this. lower_fn_header ( * header) ,
@@ -295,6 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
295
297
add_ty_alias_where_clause ( & mut generics, * where_clauses, true ) ;
296
298
let ( generics, ty) = self . lower_generics (
297
299
& generics,
300
+ Const :: No ,
298
301
id,
299
302
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
300
303
|this| match ty {
@@ -316,6 +319,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
316
319
ItemKind :: Enum ( enum_definition, generics) => {
317
320
let ( generics, variants) = self . lower_generics (
318
321
generics,
322
+ Const :: No ,
319
323
id,
320
324
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
321
325
|this| {
@@ -329,6 +333,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
329
333
ItemKind :: Struct ( struct_def, generics) => {
330
334
let ( generics, struct_def) = self . lower_generics (
331
335
generics,
336
+ Const :: No ,
332
337
id,
333
338
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
334
339
|this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -338,6 +343,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
338
343
ItemKind :: Union ( vdata, generics) => {
339
344
let ( generics, vdata) = self . lower_generics (
340
345
generics,
346
+ Const :: No ,
341
347
id,
342
348
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
343
349
|this| this. lower_variant_data ( hir_id, vdata) ,
@@ -369,7 +375,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
369
375
// parent lifetime.
370
376
let itctx = ImplTraitContext :: Universal ;
371
377
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| {
373
379
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
374
380
this. lower_trait_ref (
375
381
trait_ref,
@@ -410,8 +416,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
410
416
} ) )
411
417
}
412
418
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
+ } ;
413
428
let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
414
429
generics,
430
+ constness,
415
431
id,
416
432
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
417
433
|this| {
@@ -431,6 +447,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
431
447
ItemKind :: TraitAlias ( generics, bounds) => {
432
448
let ( generics, bounds) = self . lower_generics (
433
449
generics,
450
+ Const :: No ,
434
451
id,
435
452
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
436
453
|this| {
@@ -593,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
593
610
let fdec = & sig. decl ;
594
611
let itctx = ImplTraitContext :: Universal ;
595
612
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| {
597
614
(
598
615
// Disallow `impl Trait` in foreign items.
599
616
this. lower_fn_decl (
@@ -745,6 +762,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
745
762
add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
746
763
let ( generics, kind) = self . lower_generics (
747
764
& generics,
765
+ Const :: No ,
748
766
i. id ,
749
767
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
750
768
|this| {
@@ -843,6 +861,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
843
861
add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
844
862
self . lower_generics (
845
863
& generics,
864
+ Const :: No ,
846
865
i. id ,
847
866
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
848
867
|this| match ty {
@@ -1201,9 +1220,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
1201
1220
) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1202
1221
let header = self . lower_fn_header ( sig. header ) ;
1203
1222
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
+ } ) ;
1207
1227
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1208
1228
}
1209
1229
@@ -1275,6 +1295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1275
1295
fn lower_generics < T > (
1276
1296
& mut self ,
1277
1297
generics : & Generics ,
1298
+ constness : Const ,
1278
1299
parent_node_id : NodeId ,
1279
1300
itctx : & ImplTraitContext ,
1280
1301
f : impl FnOnce ( & mut Self ) -> T ,
@@ -1372,6 +1393,87 @@ impl<'hir> LoweringContext<'_, 'hir> {
1372
1393
let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
1373
1394
predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
1374
1395
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
+
1375
1477
let lowered_generics = self . arena . alloc ( hir:: Generics {
1376
1478
params : self . arena . alloc_from_iter ( params) ,
1377
1479
predicates : self . arena . alloc_from_iter ( predicates) ,
0 commit comments