@@ -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| {
@@ -221,7 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
221
222
222
223
let itctx = ImplTraitContext :: Universal ;
223
224
let ( generics, decl) =
224
- this. lower_generics ( generics, header. constness , id, itctx, |this| {
225
+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
225
226
this. lower_fn_decl (
226
227
decl,
227
228
id,
@@ -265,6 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
265
266
let ( generics, ty) = self . lower_generics (
266
267
& generics,
267
268
Const :: No ,
269
+ false ,
268
270
id,
269
271
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
270
272
|this| match ty {
@@ -293,6 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
293
295
let ( generics, variants) = self . lower_generics (
294
296
generics,
295
297
Const :: No ,
298
+ false ,
296
299
id,
297
300
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
298
301
|this| {
@@ -307,6 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
307
310
let ( generics, struct_def) = self . lower_generics (
308
311
generics,
309
312
Const :: No ,
313
+ false ,
310
314
id,
311
315
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
312
316
|this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -317,6 +321,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
317
321
let ( generics, vdata) = self . lower_generics (
318
322
generics,
319
323
Const :: No ,
324
+ false ,
320
325
id,
321
326
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
322
327
|this| this. lower_variant_data ( hir_id, vdata) ,
@@ -348,12 +353,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
348
353
// parent lifetime.
349
354
let itctx = ImplTraitContext :: Universal ;
350
355
let ( generics, ( trait_ref, lowered_ty) ) =
351
- self . lower_generics ( ast_generics, * constness , id, itctx, |this| {
356
+ self . lower_generics ( ast_generics, Const :: No , false , id, itctx, |this| {
352
357
let modifiers = TraitBoundModifiers {
353
- constness : match * constness {
354
- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
355
- Const :: No => BoundConstness :: Never ,
356
- } ,
358
+ constness : BoundConstness :: Never ,
357
359
asyncness : BoundAsyncness :: Normal ,
358
360
// we don't use this in bound lowering
359
361
polarity : BoundPolarity :: Positive ,
@@ -389,6 +391,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
389
391
ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
390
392
} ;
391
393
hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
394
+ constness : self . lower_constness ( * constness) ,
392
395
safety : self . lower_safety ( * safety, hir:: Safety :: Safe ) ,
393
396
polarity,
394
397
defaultness,
@@ -400,15 +403,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
400
403
} ) )
401
404
}
402
405
ItemKind :: Trait ( box Trait { is_auto, safety, generics, bounds, items } ) => {
403
- // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible
404
- let constness = attrs
405
- . unwrap_or ( & [ ] )
406
- . iter ( )
407
- . find ( |x| x. has_name ( sym:: const_trait) )
408
- . map_or ( Const :: No , |x| Const :: Yes ( x. span ) ) ;
409
406
let ( generics, ( safety, items, bounds) ) = self . lower_generics (
410
407
generics,
411
- constness,
408
+ Const :: No ,
409
+ false ,
412
410
id,
413
411
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
414
412
|this| {
@@ -429,6 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
429
427
let ( generics, bounds) = self . lower_generics (
430
428
generics,
431
429
Const :: No ,
430
+ false ,
432
431
id,
433
432
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
434
433
|this| {
@@ -609,30 +608,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
609
608
// This is used to track which lifetimes have already been defined,
610
609
// and which need to be replicated when lowering an async fn.
611
610
612
- let generics = match parent_hir. node ( ) . expect_item ( ) . kind {
611
+ let parent_item = parent_hir. node ( ) . expect_item ( ) ;
612
+ let constness = match parent_item. kind {
613
613
hir:: ItemKind :: Impl ( impl_) => {
614
614
self . is_in_trait_impl = impl_. of_trait . is_some ( ) ;
615
- & impl_. generics
615
+ // N.B. the impl should always lower to methods that have `const host: bool` params if the trait
616
+ // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from
617
+ // calling non-const impls are done through associated types.
618
+ if let Some ( def_id) = impl_. of_trait . and_then ( |tr| tr. trait_def_id ( ) ) {
619
+ if let Some ( local_def) = def_id. as_local ( ) {
620
+ match & self . ast_index [ local_def] {
621
+ AstOwner :: Item ( ast:: Item { attrs, .. } ) => attrs
622
+ . iter ( )
623
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
624
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
625
+ _ => Const :: No ,
626
+ }
627
+ } else {
628
+ self . tcx
629
+ . get_attr ( def_id, sym:: const_trait)
630
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) )
631
+ }
632
+ } else {
633
+ Const :: No
634
+ }
616
635
}
617
- hir:: ItemKind :: Trait ( _, _, generics, _, _) => generics,
636
+ hir:: ItemKind :: Trait ( _, _, _, _, _) => parent_hir
637
+ . attrs
638
+ . get ( parent_item. hir_id ( ) . local_id )
639
+ . iter ( )
640
+ . find ( |attr| attr. has_name ( sym:: const_trait) )
641
+ . map_or ( Const :: No , |attr| Const :: Yes ( attr. span ) ) ,
618
642
kind => {
619
643
span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
620
644
}
621
645
} ;
622
646
623
- if self . tcx . features ( ) . effects {
624
- self . host_param_id = generics
625
- . params
626
- . iter ( )
627
- . find ( |param| {
628
- matches ! ( param. kind, hir:: GenericParamKind :: Const { is_host_effect: true , .. } )
629
- } )
630
- . map ( |param| param. def_id ) ;
631
- }
632
-
633
647
match ctxt {
634
- AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item) ) ,
635
- AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item) ) ,
648
+ AssocCtxt :: Trait => hir:: OwnerNode :: TraitItem ( self . lower_trait_item ( item, constness ) ) ,
649
+ AssocCtxt :: Impl => hir:: OwnerNode :: ImplItem ( self . lower_impl_item ( item, constness ) ) ,
636
650
}
637
651
}
638
652
@@ -648,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
648
662
let fdec = & sig. decl ;
649
663
let itctx = ImplTraitContext :: Universal ;
650
664
let ( generics, ( fn_dec, fn_args) ) =
651
- self . lower_generics ( generics, Const :: No , i. id , itctx, |this| {
665
+ self . lower_generics ( generics, Const :: No , false , i. id , itctx, |this| {
652
666
(
653
667
// Disallow `impl Trait` in foreign items.
654
668
this. lower_fn_decl (
@@ -765,7 +779,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
765
779
}
766
780
}
767
781
768
- fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
782
+ fn lower_trait_item (
783
+ & mut self ,
784
+ i : & AssocItem ,
785
+ trait_constness : Const ,
786
+ ) -> & ' hir hir:: TraitItem < ' hir > {
769
787
let hir_id = self . lower_node_id ( i. id ) ;
770
788
self . lower_attrs ( hir_id, & i. attrs ) ;
771
789
let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -775,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775
793
let ( generics, kind) = self . lower_generics (
776
794
generics,
777
795
Const :: No ,
796
+ false ,
778
797
i. id ,
779
798
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
780
799
|this| {
@@ -795,6 +814,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795
814
i. id ,
796
815
FnDeclKind :: Trait ,
797
816
sig. header . coroutine_kind ,
817
+ trait_constness,
798
818
) ;
799
819
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
800
820
}
@@ -813,6 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
813
833
i. id ,
814
834
FnDeclKind :: Trait ,
815
835
sig. header . coroutine_kind ,
836
+ trait_constness,
816
837
) ;
817
838
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
818
839
}
@@ -822,6 +843,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
822
843
let ( generics, kind) = self . lower_generics (
823
844
& generics,
824
845
Const :: No ,
846
+ false ,
825
847
i. id ,
826
848
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
827
849
|this| {
@@ -894,7 +916,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
894
916
self . expr ( span, hir:: ExprKind :: Err ( guar) )
895
917
}
896
918
897
- fn lower_impl_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: ImplItem < ' hir > {
919
+ fn lower_impl_item (
920
+ & mut self ,
921
+ i : & AssocItem ,
922
+ constness_of_trait : Const ,
923
+ ) -> & ' hir hir:: ImplItem < ' hir > {
898
924
// Since `default impl` is not yet implemented, this is always true in impls.
899
925
let has_value = true ;
900
926
let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -905,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
905
931
AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
906
932
generics,
907
933
Const :: No ,
934
+ false ,
908
935
i. id ,
909
936
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
910
937
|this| {
@@ -930,6 +957,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930
957
i. id ,
931
958
if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
932
959
sig. header . coroutine_kind ,
960
+ constness_of_trait,
933
961
) ;
934
962
935
963
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -940,6 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
940
968
self . lower_generics (
941
969
& generics,
942
970
Const :: No ,
971
+ false ,
943
972
i. id ,
944
973
ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
945
974
|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