@@ -56,7 +56,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
5656 owner : NodeId ,
5757 f : impl FnOnce ( & mut LoweringContext < ' _ , ' hir > ) -> hir:: OwnerNode < ' hir > ,
5858 ) {
59- let mut lctx = LoweringContext :: new ( self . tcx , self . resolver ) ;
59+ let mut lctx = LoweringContext :: new ( self . tcx , self . resolver , self . ast_index ) ;
6060 lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
6161
6262 for ( def_id, info) in lctx. children {
@@ -190,6 +190,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
190190 let ( generics, ( ty, body_id) ) = self . lower_generics (
191191 generics,
192192 Const :: No ,
193+ false ,
193194 id,
194195 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
195196 |this| {
@@ -221,7 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
221222
222223 let itctx = ImplTraitContext :: Universal ;
223224 let ( generics, decl) =
224- this. lower_generics ( generics, header. constness , id, itctx, |this| {
225+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
225226 this. lower_fn_decl (
226227 decl,
227228 id,
@@ -265,6 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
265266 let ( generics, ty) = self . lower_generics (
266267 & generics,
267268 Const :: No ,
269+ false ,
268270 id,
269271 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
270272 |this| match ty {
@@ -293,6 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
293295 let ( generics, variants) = self . lower_generics (
294296 generics,
295297 Const :: No ,
298+ false ,
296299 id,
297300 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
298301 |this| {
@@ -307,6 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
307310 let ( generics, struct_def) = self . lower_generics (
308311 generics,
309312 Const :: No ,
313+ false ,
310314 id,
311315 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
312316 |this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -317,6 +321,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
317321 let ( generics, vdata) = self . lower_generics (
318322 generics,
319323 Const :: No ,
324+ false ,
320325 id,
321326 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
322327 |this| this. lower_variant_data ( hir_id, vdata) ,
@@ -348,12 +353,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
348353 // parent lifetime.
349354 let itctx = ImplTraitContext :: Universal ;
350355 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| {
352357 let modifiers = TraitBoundModifiers {
353- constness : match * constness {
354- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
355- Const :: No => BoundConstness :: Never ,
356- } ,
358+ constness : BoundConstness :: Never ,
357359 asyncness : BoundAsyncness :: Normal ,
358360 // we don't use this in bound lowering
359361 polarity : BoundPolarity :: Positive ,
@@ -389,6 +391,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
389391 ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
390392 } ;
391393 hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
394+ constness : self . lower_constness ( * constness) ,
392395 safety : self . lower_safety ( * safety, hir:: Safety :: Safe ) ,
393396 polarity,
394397 defaultness,
@@ -400,15 +403,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
400403 } ) )
401404 }
402405 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 ) ) ;
409406 let ( generics, ( safety, items, bounds) ) = self . lower_generics (
410407 generics,
411- constness,
408+ Const :: No ,
409+ false ,
412410 id,
413411 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
414412 |this| {
@@ -429,6 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
429427 let ( generics, bounds) = self . lower_generics (
430428 generics,
431429 Const :: No ,
430+ false ,
432431 id,
433432 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
434433 |this| {
@@ -609,30 +608,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
609608 // This is used to track which lifetimes have already been defined,
610609 // and which need to be replicated when lowering an async fn.
611610
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 {
613613 hir:: ItemKind :: Impl ( impl_) => {
614614 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+ }
616635 }
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 ) ) ,
618642 kind => {
619643 span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
620644 }
621645 } ;
622646
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-
633647 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 ) ) ,
636650 }
637651 }
638652
@@ -648,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
648662 let fdec = & sig. decl ;
649663 let itctx = ImplTraitContext :: Universal ;
650664 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| {
652666 (
653667 // Disallow `impl Trait` in foreign items.
654668 this. lower_fn_decl (
@@ -765,7 +779,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
765779 }
766780 }
767781
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 > {
769787 let hir_id = self . lower_node_id ( i. id ) ;
770788 self . lower_attrs ( hir_id, & i. attrs ) ;
771789 let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -775,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
775793 let ( generics, kind) = self . lower_generics (
776794 generics,
777795 Const :: No ,
796+ false ,
778797 i. id ,
779798 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
780799 |this| {
@@ -795,6 +814,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795814 i. id ,
796815 FnDeclKind :: Trait ,
797816 sig. header . coroutine_kind ,
817+ trait_constness,
798818 ) ;
799819 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
800820 }
@@ -813,6 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
813833 i. id ,
814834 FnDeclKind :: Trait ,
815835 sig. header . coroutine_kind ,
836+ trait_constness,
816837 ) ;
817838 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
818839 }
@@ -822,6 +843,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
822843 let ( generics, kind) = self . lower_generics (
823844 & generics,
824845 Const :: No ,
846+ false ,
825847 i. id ,
826848 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
827849 |this| {
@@ -894,7 +916,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
894916 self . expr ( span, hir:: ExprKind :: Err ( guar) )
895917 }
896918
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 > {
898924 // Since `default impl` is not yet implemented, this is always true in impls.
899925 let has_value = true ;
900926 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -905,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
905931 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
906932 generics,
907933 Const :: No ,
934+ false ,
908935 i. id ,
909936 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
910937 |this| {
@@ -930,6 +957,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930957 i. id ,
931958 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
932959 sig. header . coroutine_kind ,
960+ constness_of_trait,
933961 ) ;
934962
935963 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -940,6 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
940968 self . lower_generics (
941969 & generics,
942970 Const :: No ,
971+ false ,
943972 i. id ,
944973 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
945974 |this| match ty {
@@ -1352,15 +1381,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13521381 id : NodeId ,
13531382 kind : FnDeclKind ,
13541383 coroutine_kind : Option < CoroutineKind > ,
1384+ parent_constness : Const ,
13551385 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
13561386 let header = self . lower_fn_header ( sig. header ) ;
13571387 // Don't pass along the user-provided constness of trait associated functions; we don't want to
13581388 // 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 } ;
13601391 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+ } ) ;
13641396 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
13651397 }
13661398
@@ -1436,6 +1468,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14361468 & mut self ,
14371469 generics : & Generics ,
14381470 constness : Const ,
1471+ force_append_constness : bool ,
14391472 parent_node_id : NodeId ,
14401473 itctx : ImplTraitContext ,
14411474 f : impl FnOnce ( & mut Self ) -> T ,
@@ -1496,7 +1529,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14961529 // if the effects feature is enabled. This needs to be done before we lower where
14971530 // clauses since where clauses need to bind to the DefId of the host param
14981531 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)
15001535 {
15011536 let span = self . lower_span ( span) ;
15021537 let param_node_id = self . next_node_id ( ) ;
@@ -1609,13 +1644,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
16091644 } ) ,
16101645 ) ) ,
16111646 ) ) ,
1647+ // FIXME(effects) we might not need a default.
16121648 default : Some ( self . arena . alloc ( hir:: AnonConst {
16131649 def_id : anon_const,
16141650 hir_id : const_id,
16151651 body : const_body,
16161652 span,
16171653 } ) ) ,
16181654 is_host_effect : true ,
1655+ synthetic : true ,
16191656 } ,
16201657 colon_span : None ,
16211658 pure_wrt_drop : false ,
0 commit comments