@@ -56,7 +56,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
56
56
owner : NodeId ,
57
57
f : impl FnOnce ( & mut LoweringContext < ' _ , ' hir > ) -> hir:: OwnerNode < ' hir > ,
58
58
) {
59
- let mut lctx = LoweringContext :: new ( self . tcx , self . resolver ) ;
59
+ let mut lctx = LoweringContext :: new ( self . tcx , self . resolver , self . ast_index ) ;
60
60
lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
61
61
62
62
for ( def_id, info) in lctx. children {
@@ -190,6 +190,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
190
190
let ( generics, ( ty, body_id) ) = self . lower_generics (
191
191
generics,
192
192
Const :: No ,
193
+ false ,
193
194
id,
194
195
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
195
196
|this| {
@@ -220,7 +221,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
220
221
221
222
let itctx = ImplTraitContext :: Universal ;
222
223
let ( generics, decl) =
223
- this. lower_generics ( generics, header. constness , id, itctx, |this| {
224
+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
224
225
this. lower_fn_decl (
225
226
decl,
226
227
id,
@@ -264,6 +265,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
264
265
let ( generics, ty) = self . lower_generics (
265
266
& generics,
266
267
Const :: No ,
268
+ false ,
267
269
id,
268
270
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
269
271
|this| match ty {
@@ -292,6 +294,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
292
294
let ( generics, variants) = self . lower_generics (
293
295
generics,
294
296
Const :: No ,
297
+ false ,
295
298
id,
296
299
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
297
300
|this| {
@@ -306,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
306
309
let ( generics, struct_def) = self . lower_generics (
307
310
generics,
308
311
Const :: No ,
312
+ false ,
309
313
id,
310
314
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
311
315
|this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -316,6 +320,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
316
320
let ( generics, vdata) = self . lower_generics (
317
321
generics,
318
322
Const :: No ,
323
+ false ,
319
324
id,
320
325
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
321
326
|this| this. lower_variant_data ( hir_id, vdata) ,
@@ -347,12 +352,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
347
352
// parent lifetime.
348
353
let itctx = ImplTraitContext :: Universal ;
349
354
let ( generics, ( trait_ref, lowered_ty) ) =
350
- self . lower_generics ( ast_generics, * constness , id, itctx, |this| {
355
+ self . lower_generics ( ast_generics, Const :: No , false , id, itctx, |this| {
351
356
let modifiers = TraitBoundModifiers {
352
- constness : match * constness {
353
- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
354
- Const :: No => BoundConstness :: Never ,
355
- } ,
357
+ constness : BoundConstness :: Never ,
356
358
asyncness : BoundAsyncness :: Normal ,
357
359
// we don't use this in bound lowering
358
360
polarity : BoundPolarity :: Positive ,
@@ -388,6 +390,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
388
390
ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
389
391
} ;
390
392
hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
393
+ constness : self . lower_constness ( * constness) ,
391
394
safety : self . lower_safety ( * safety, hir:: Safety :: Safe ) ,
392
395
polarity,
393
396
defaultness,
@@ -399,15 +402,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
399
402
} ) )
400
403
}
401
404
ItemKind :: Trait ( box Trait { is_auto, safety, generics, bounds, items } ) => {
402
- // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
403
- let constness = attrs
404
- . unwrap_or ( & [ ] )
405
- . iter ( )
406
- . find ( |x| x. has_name ( sym:: const_trait) )
407
- . map_or ( Const :: No , |x| Const :: Yes ( x. span ) ) ;
408
405
let ( generics, ( safety, items, bounds) ) = self . lower_generics (
409
406
generics,
410
- constness,
407
+ Const :: No ,
408
+ false ,
411
409
id,
412
410
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
413
411
|this| {
@@ -428,6 +426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
428
426
let ( generics, bounds) = self . lower_generics (
429
427
generics,
430
428
Const :: No ,
429
+ false ,
431
430
id,
432
431
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
433
432
|this| {
@@ -608,30 +607,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
608
607
// This is used to track which lifetimes have already been defined,
609
608
// and which need to be replicated when lowering an async fn.
610
609
611
- let generics = match parent_hir. node ( ) . expect_item ( ) . kind {
610
+ let parent_item = parent_hir. node ( ) . expect_item ( ) ;
611
+ let constness = match parent_item. kind {
612
612
hir:: ItemKind :: Impl ( impl_) => {
613
613
self . is_in_trait_impl = impl_. of_trait . is_some ( ) ;
614
- & impl_. generics
614
+ // N.B. the impl should always lower to methods that have `const host: bool` params if the trait
615
+ // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
616
+ // calling non-const impls are done through associated types.
617
+ if let Some ( def_id) = impl_. of_trait . and_then ( |tr| tr. trait_def_id ( ) ) {
618
+ if let Some ( local_def) = def_id. as_local ( ) {
619
+ match & self . ast_index [ local_def] {
620
+ AstOwner :: Item ( ast:: Item { attrs, .. } ) => attrs
621
+ . iter ( )
622
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
623
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
624
+ _ => Const :: No ,
625
+ }
626
+ } else {
627
+ self . tcx
628
+ . get_attr ( def_id, sym:: const_trait)
629
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) )
630
+ }
631
+ } else {
632
+ Const :: No
633
+ }
615
634
}
616
- hir:: ItemKind :: Trait ( _, _, generics, _, _) => generics,
635
+ hir:: ItemKind :: Trait ( _, _, _, _, _) => parent_hir
636
+ . attrs
637
+ . get ( parent_item. hir_id ( ) . local_id )
638
+ . iter ( )
639
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
640
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
617
641
kind => {
618
642
span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
619
643
}
620
644
} ;
621
645
622
- if self . tcx . features ( ) . effects {
623
- self . host_param_id = generics
624
- . params
625
- . iter ( )
626
- . find ( |param| {
627
- matches ! ( param. kind, hir:: GenericParamKind :: Const { is_host_effect: true , .. } )
628
- } )
629
- . map ( |param| param. def_id ) ;
630
- }
631
-
632
646
match ctxt {
633
- AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item) ) ,
634
- AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item) ) ,
647
+ AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item, constness ) ) ,
648
+ AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item, constness ) ) ,
635
649
}
636
650
}
637
651
@@ -647,7 +661,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
647
661
let fdec = & sig. decl ;
648
662
let itctx = ImplTraitContext :: Universal ;
649
663
let ( generics, ( fn_dec, fn_args) ) =
650
- self . lower_generics ( generics, Const :: No , i. id , itctx, |this| {
664
+ self . lower_generics ( generics, Const :: No , false , i. id , itctx, |this| {
651
665
(
652
666
// Disallow `impl Trait` in foreign items.
653
667
this. lower_fn_decl (
@@ -764,7 +778,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
764
778
}
765
779
}
766
780
767
- fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
781
+ fn lower_trait_item (
782
+ & mut self ,
783
+ i : & AssocItem ,
784
+ trait_constness : Const ,
785
+ ) -> & ' hir hir:: TraitItem < ' hir > {
768
786
let hir_id = self . lower_node_id ( i. id ) ;
769
787
self . lower_attrs ( hir_id, & i. attrs ) ;
770
788
let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -774,6 +792,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
774
792
let ( generics, kind) = self . lower_generics (
775
793
generics,
776
794
Const :: No ,
795
+ false ,
777
796
i. id ,
778
797
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
779
798
|this| {
@@ -794,6 +813,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
794
813
i. id ,
795
814
FnDeclKind :: Trait ,
796
815
sig. header . coroutine_kind ,
816
+ trait_constness,
797
817
) ;
798
818
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
799
819
}
@@ -811,6 +831,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
811
831
i. id ,
812
832
FnDeclKind :: Trait ,
813
833
sig. header . coroutine_kind ,
834
+ trait_constness,
814
835
) ;
815
836
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
816
837
}
@@ -820,6 +841,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
820
841
let ( generics, kind) = self . lower_generics (
821
842
& generics,
822
843
Const :: No ,
844
+ false ,
823
845
i. id ,
824
846
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
825
847
|this| {
@@ -892,7 +914,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
892
914
self . expr ( span, hir:: ExprKind :: Err ( guar) )
893
915
}
894
916
895
- fn lower_impl_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: ImplItem < ' hir > {
917
+ fn lower_impl_item (
918
+ & mut self ,
919
+ i : & AssocItem ,
920
+ constness_of_trait : Const ,
921
+ ) -> & ' hir hir:: ImplItem < ' hir > {
896
922
// Since `default impl` is not yet implemented, this is always true in impls.
897
923
let has_value = true ;
898
924
let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -903,6 +929,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
903
929
AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
904
930
generics,
905
931
Const :: No ,
932
+ false ,
906
933
i. id ,
907
934
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
908
935
|this| {
@@ -927,6 +954,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
927
954
i. id ,
928
955
if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
929
956
sig. header . coroutine_kind ,
957
+ constness_of_trait,
930
958
) ;
931
959
932
960
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -937,6 +965,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
937
965
self . lower_generics (
938
966
& generics,
939
967
Const :: No ,
968
+ false ,
940
969
i. id ,
941
970
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
942
971
|this| match ty {
@@ -1352,15 +1381,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
1352
1381
id : NodeId ,
1353
1382
kind : FnDeclKind ,
1354
1383
coroutine_kind : Option < CoroutineKind > ,
1384
+ parent_constness : Const ,
1355
1385
) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
1356
1386
let header = self . lower_fn_header ( sig. header ) ;
1357
1387
// Don't pass along the user-provided constness of trait associated functions; we don't want to
1358
1388
// synthesize a host effect param for them. We reject `const` on them during AST validation.
1359
- let constness = if kind == FnDeclKind :: Inherent { sig. header . constness } else { Const :: No } ;
1389
+ let constness =
1390
+ if kind == FnDeclKind :: Inherent { sig. header . constness } else { parent_constness } ;
1360
1391
let itctx = ImplTraitContext :: Universal ;
1361
- let ( generics, decl) = self . lower_generics ( generics, constness, id, itctx, |this| {
1362
- this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
1363
- } ) ;
1392
+ let ( generics, decl) =
1393
+ self . lower_generics ( generics, constness, kind == FnDeclKind :: Impl , id, itctx, |this| {
1394
+ this. lower_fn_decl ( & sig. decl , id, sig. span , kind, coroutine_kind)
1395
+ } ) ;
1364
1396
( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
1365
1397
}
1366
1398
@@ -1436,6 +1468,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1436
1468
& mut self ,
1437
1469
generics : & Generics ,
1438
1470
constness : Const ,
1471
+ force_append_constness : bool ,
1439
1472
parent_node_id : NodeId ,
1440
1473
itctx : ImplTraitContext ,
1441
1474
f : impl FnOnce ( & mut Self ) -> T ,
@@ -1496,7 +1529,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
1496
1529
// if the effects feature is enabled. This needs to be done before we lower where
1497
1530
// clauses since where clauses need to bind to the DefId of the host param
1498
1531
let host_param_parts = if let Const :: Yes ( span) = constness
1499
- && self . tcx . features ( ) . effects
1532
+ // if this comes from implementing a `const` trait, we must force constness to be appended
1533
+ // to the impl item, no matter whether effects is enabled.
1534
+ && ( self . tcx . features ( ) . effects || force_append_constness)
1500
1535
{
1501
1536
let span = self . lower_span ( span) ;
1502
1537
let param_node_id = self . next_node_id ( ) ;
@@ -1609,13 +1644,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
1609
1644
} ) ,
1610
1645
) ) ,
1611
1646
) ) ,
1647
+ // FIXME(effects) we might not need a default.
1612
1648
default : Some ( self . arena . alloc ( hir:: AnonConst {
1613
1649
def_id : anon_const,
1614
1650
hir_id : const_id,
1615
1651
body : const_body,
1616
1652
span,
1617
1653
} ) ) ,
1618
1654
is_host_effect : true ,
1655
+ synthetic : true ,
1619
1656
} ,
1620
1657
colon_span : None ,
1621
1658
pure_wrt_drop : false ,
0 commit comments