@@ -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,15 @@ 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 = 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 ) ) ;
413
425
let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
414
426
generics,
427
+ constness,
415
428
id,
416
429
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
417
430
|this| {
@@ -431,6 +444,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
431
444
ItemKind :: TraitAlias ( generics, bounds) => {
432
445
let ( generics, bounds) = self . lower_generics (
433
446
generics,
447
+ Const :: No ,
434
448
id,
435
449
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
436
450
|this| {
@@ -593,7 +607,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
593
607
let fdec = & sig. decl ;
594
608
let itctx = ImplTraitContext :: Universal ;
595
609
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| {
597
611
(
598
612
// Disallow `impl Trait` in foreign items.
599
613
this. lower_fn_decl (
@@ -745,6 +759,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
745
759
add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
746
760
let ( generics, kind) = self . lower_generics (
747
761
& generics,
762
+ Const :: No ,
748
763
i. id ,
749
764
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
750
765
|this| {
@@ -843,6 +858,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
843
858
add_ty_alias_where_clause ( & mut generics, * where_clauses, false ) ;
844
859
self . lower_generics (
845
860
& generics,
861
+ Const :: No ,
846
862
i. id ,
847
863
& ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
848
864
|this| match ty {
@@ -1201,9 +1217,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
1201
1217
) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1202
1218
let header = self . lower_fn_header ( sig. header ) ;
1203
1219
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
+ } ) ;
1207
1224
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1208
1225
}
1209
1226
@@ -1275,6 +1292,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1275
1292
fn lower_generics < T > (
1276
1293
& mut self ,
1277
1294
generics : & Generics ,
1295
+ constness : Const ,
1278
1296
parent_node_id : NodeId ,
1279
1297
itctx : & ImplTraitContext ,
1280
1298
f : impl FnOnce ( & mut Self ) -> T ,
@@ -1372,6 +1390,87 @@ impl<'hir> LoweringContext<'_, 'hir> {
1372
1390
let impl_trait_bounds = std:: mem:: take ( & mut self . impl_trait_bounds ) ;
1373
1391
predicates. extend ( impl_trait_bounds. into_iter ( ) ) ;
1374
1392
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
+
1375
1474
let lowered_generics = self . arena . alloc ( hir:: Generics {
1376
1475
params : self . arena . alloc_from_iter ( params) ,
1377
1476
predicates : self . arena . alloc_from_iter ( predicates) ,
0 commit comments