@@ -54,7 +54,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
54
54
owner : NodeId ,
55
55
f : impl FnOnce ( & mut LoweringContext < ' _ , ' hir > ) -> hir:: OwnerNode < ' hir > ,
56
56
) {
57
- let mut lctx = LoweringContext :: new ( self . tcx , self . resolver ) ;
57
+ let mut lctx = LoweringContext :: new ( self . tcx , self . resolver , self . ast_index ) ;
58
58
lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
59
59
60
60
for ( def_id, info) in lctx. children {
@@ -188,6 +188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
188
188
let ( generics, ( ty, body_id) ) = self . lower_generics (
189
189
generics,
190
190
Const :: No ,
191
+ false ,
191
192
id,
192
193
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
193
194
|this| {
@@ -218,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
218
219
219
220
let itctx = ImplTraitContext :: Universal ;
220
221
let ( generics, decl) =
221
- this. lower_generics ( generics, header. constness , id, itctx, |this| {
222
+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
222
223
this. lower_fn_decl (
223
224
decl,
224
225
id,
@@ -262,6 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
262
263
let ( generics, ty) = self . lower_generics (
263
264
& generics,
264
265
Const :: No ,
266
+ false ,
265
267
id,
266
268
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
267
269
|this| match ty {
@@ -284,6 +286,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
284
286
let ( generics, variants) = self . lower_generics (
285
287
generics,
286
288
Const :: No ,
289
+ false ,
287
290
id,
288
291
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
289
292
|this| {
@@ -298,6 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
298
301
let ( generics, struct_def) = self . lower_generics (
299
302
generics,
300
303
Const :: No ,
304
+ false ,
301
305
id,
302
306
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
303
307
|this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -308,6 +312,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
308
312
let ( generics, vdata) = self . lower_generics (
309
313
generics,
310
314
Const :: No ,
315
+ false ,
311
316
id,
312
317
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
313
318
|this| this. lower_variant_data ( hir_id, vdata) ,
@@ -339,12 +344,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
339
344
// parent lifetime.
340
345
let itctx = ImplTraitContext :: Universal ;
341
346
let ( generics, ( trait_ref, lowered_ty) ) =
342
- self . lower_generics ( ast_generics, * constness , id, itctx, |this| {
347
+ self . lower_generics ( ast_generics, Const :: No , false , id, itctx, |this| {
343
348
let modifiers = TraitBoundModifiers {
344
- constness : match * constness {
345
- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
346
- Const :: No => BoundConstness :: Never ,
347
- } ,
349
+ constness : BoundConstness :: Never ,
348
350
asyncness : BoundAsyncness :: Normal ,
349
351
// we don't use this in bound lowering
350
352
polarity : BoundPolarity :: Positive ,
@@ -379,6 +381,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
379
381
ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
380
382
} ;
381
383
hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
384
+ constness : self . lower_constness ( * constness) ,
382
385
unsafety : self . lower_unsafety ( * unsafety) ,
383
386
polarity,
384
387
defaultness,
@@ -390,15 +393,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
390
393
} ) )
391
394
}
392
395
ItemKind :: Trait ( box Trait { is_auto, unsafety, generics, bounds, items } ) => {
393
- // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
394
- let constness = attrs
395
- . unwrap_or ( & [ ] )
396
- . iter ( )
397
- . find ( |x| x. has_name ( sym:: const_trait) )
398
- . map_or ( Const :: No , |x| Const :: Yes ( x. span ) ) ;
399
396
let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
400
397
generics,
401
- constness,
398
+ Const :: No ,
399
+ false ,
402
400
id,
403
401
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
404
402
|this| {
@@ -419,6 +417,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
419
417
let ( generics, bounds) = self . lower_generics (
420
418
generics,
421
419
Const :: No ,
420
+ false ,
422
421
id,
423
422
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
424
423
|this| {
@@ -599,30 +598,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
599
598
// This is used to track which lifetimes have already been defined,
600
599
// and which need to be replicated when lowering an async fn.
601
600
602
- let generics = match parent_hir. node ( ) . expect_item ( ) . kind {
601
+ let parent_item = parent_hir. node ( ) . expect_item ( ) ;
602
+ let constness = match parent_item. kind {
603
603
hir:: ItemKind :: Impl ( impl_) => {
604
604
self . is_in_trait_impl = impl_. of_trait . is_some ( ) ;
605
- & impl_. generics
605
+ // N.B. the impl should always lower to methods that have `const host: bool` params if the trait
606
+ // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
607
+ // calling non-const impls are done through associated types.
608
+ if let Some ( def_id) = impl_. of_trait . and_then ( |tr| tr. trait_def_id ( ) ) {
609
+ if let Some ( local_def) = def_id. as_local ( ) {
610
+ match & self . ast_index [ local_def] {
611
+ AstOwner :: Item ( ast:: Item { attrs, .. } ) => attrs
612
+ . iter ( )
613
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
614
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
615
+ _ => Const :: No ,
616
+ }
617
+ } else {
618
+ self . tcx
619
+ . get_attr ( def_id, sym:: const_trait)
620
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) )
621
+ }
622
+ } else {
623
+ Const :: No
624
+ }
606
625
}
607
- hir:: ItemKind :: Trait ( _, _, generics, _, _) => generics,
626
+ hir:: ItemKind :: Trait ( _, _, _, _, _) => parent_hir
627
+ . attrs
628
+ . get ( parent_item. hir_id ( ) . local_id )
629
+ . iter ( )
630
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
631
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
608
632
kind => {
609
633
span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
610
634
}
611
635
} ;
612
636
613
- if self . tcx . features ( ) . effects {
614
- self . host_param_id = generics
615
- . params
616
- . iter ( )
617
- . find ( |param| {
618
- matches ! ( param. kind, hir:: GenericParamKind :: Const { is_host_effect: true , .. } )
619
- } )
620
- . map ( |param| param. def_id ) ;
621
- }
622
-
623
637
match ctxt {
624
- AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item) ) ,
625
- AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item) ) ,
638
+ AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item, constness ) ) ,
639
+ AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item, constness ) ) ,
626
640
}
627
641
}
628
642
@@ -638,7 +652,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
638
652
let fdec = & sig. decl ;
639
653
let itctx = ImplTraitContext :: Universal ;
640
654
let ( generics, ( fn_dec, fn_args) ) =
641
- self . lower_generics ( generics, Const :: No , i. id , itctx, |this| {
655
+ self . lower_generics ( generics, Const :: No , false , i. id , itctx, |this| {
642
656
(
643
657
// Disallow `impl Trait` in foreign items.
644
658
this. lower_fn_decl (
@@ -752,7 +766,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
752
766
}
753
767
}
754
768
755
- fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
769
+ fn lower_trait_item (
770
+ & mut self ,
771
+ i : & AssocItem ,
772
+ trait_constness : Const ,
773
+ ) -> & ' hir hir:: TraitItem < ' hir > {
756
774
let hir_id = self . lower_node_id ( i. id ) ;
757
775
self . lower_attrs ( hir_id, & i. attrs ) ;
758
776
let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -762,6 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
762
780
let ( generics, kind) = self . lower_generics (
763
781
generics,
764
782
Const :: No ,
783
+ false ,
765
784
i. id ,
766
785
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
767
786
|this| {
@@ -782,6 +801,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
782
801
i. id ,
783
802
FnDeclKind :: Trait ,
784
803
sig. header . coroutine_kind ,
804
+ trait_constness,
785
805
) ;
786
806
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
787
807
}
@@ -799,6 +819,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
799
819
i. id ,
800
820
FnDeclKind :: Trait ,
801
821
sig. header . coroutine_kind ,
822
+ trait_constness,
802
823
) ;
803
824
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
804
825
}
@@ -808,6 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
808
829
let ( generics, kind) = self . lower_generics (
809
830
& generics,
810
831
Const :: No ,
832
+ false ,
811
833
i. id ,
812
834
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
813
835
|this| {
@@ -876,7 +898,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
876
898
self . expr ( span, hir:: ExprKind :: Err ( guar) )
877
899
}
878
900
879
- fn lower_impl_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: ImplItem < ' hir > {
901
+ fn lower_impl_item (
902
+ & mut self ,
903
+ i : & AssocItem ,
904
+ constness_of_trait : Const ,
905
+ ) -> & ' hir hir:: ImplItem < ' hir > {
880
906
// Since `default impl` is not yet implemented, this is always true in impls.
881
907
let has_value = true ;
882
908
let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -887,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
887
913
AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
888
914
generics,
889
915
Const :: No ,
916
+ false ,
890
917
i. id ,
891
918
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
892
919
|this| {
@@ -911,6 +938,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911
938
i. id ,
912
939
if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
913
940
sig. header . coroutine_kind ,
941
+ constness_of_trait,
914
942
) ;
915
943
916
944
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -921,6 +949,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
921
949
self . lower_generics (
922
950
& generics,
923
951
Const :: No ,
952
+ false ,
924
953
i. id ,
925
954
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
926
955
|this| match ty {
@@ -1323,15 +1352,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
1323
1352
id : NodeId ,
1324
1353
kind : FnDeclKind ,
1325
1354
coroutine_kind : Option < CoroutineKind > ,
1355
+ parent_constness : Const ,
1326
1356
) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1327
1357
let header = self . lower_fn_header ( sig. header ) ;
1328
1358
// Don't pass along the user-provided constness of trait associated functions; we don't want to
1329
1359
// synthesize a host effect param for them. We reject `const` on them during AST validation.
1330
- let constness = if kind == FnDeclKind :: Inherent { sig. header . constness } else { Const :: No } ;
1360
+ let constness =
1361
+ if kind == FnDeclKind :: Inherent { sig. header . constness } else { parent_constness } ;
1331
1362
let itctx = ImplTraitContext :: Universal ;
1332
- let ( generics, decl) = self . lower_generics ( generics, constness, id, itctx, |this| {
1333
- this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
1334
- } ) ;
1363
+ let ( generics, decl) =
1364
+ self . lower_generics ( generics, constness, kind == FnDeclKind :: Impl , id, itctx, |this| {
1365
+ this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
1366
+ } ) ;
1335
1367
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1336
1368
}
1337
1369
@@ -1406,6 +1438,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1406
1438
& mut self ,
1407
1439
generics : & Generics ,
1408
1440
constness : Const ,
1441
+ force_append_constness : bool ,
1409
1442
parent_node_id : NodeId ,
1410
1443
itctx : ImplTraitContext ,
1411
1444
f : impl FnOnce ( & mut Self ) -> T ,
@@ -1466,7 +1499,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1466
1499
// if the effects feature is enabled. This needs to be done before we lower where
1467
1500
// clauses since where clauses need to bind to the DefId of the host param
1468
1501
let host_param_parts = if let Const :: Yes ( span) = constness
1469
- && self . tcx . features ( ) . effects
1502
+ // if this comes from implementing a `const` trait, we must force constness to be appended
1503
+ // to the impl item, no matter whether effects is enabled.
1504
+ && ( self . tcx . features ( ) . effects || force_append_constness)
1470
1505
{
1471
1506
let span = self . lower_span ( span) ;
1472
1507
let param_node_id = self . next_node_id ( ) ;
@@ -1579,12 +1614,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
1579
1614
} ) ,
1580
1615
) ) ,
1581
1616
) ) ,
1617
+ // FIXME(effects) we might not need a default.
1582
1618
default : Some ( hir:: AnonConst {
1583
1619
def_id : anon_const,
1584
1620
hir_id : const_id,
1585
1621
body : const_body,
1586
1622
} ) ,
1587
1623
is_host_effect : true ,
1624
+ synthetic : true ,
1588
1625
} ,
1589
1626
colon_span : None ,
1590
1627
pure_wrt_drop : false ,
0 commit comments