@@ -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| {
@@ -220,7 +221,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
220221
221222 let itctx = ImplTraitContext :: Universal ;
222223 let ( generics, decl) =
223- this. lower_generics ( generics, header. constness , id, itctx, |this| {
224+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
224225 this. lower_fn_decl (
225226 decl,
226227 id,
@@ -264,6 +265,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
264265 let ( generics, ty) = self . lower_generics (
265266 & generics,
266267 Const :: No ,
268+ false ,
267269 id,
268270 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
269271 |this| match ty {
@@ -292,6 +294,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
292294 let ( generics, variants) = self . lower_generics (
293295 generics,
294296 Const :: No ,
297+ false ,
295298 id,
296299 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
297300 |this| {
@@ -306,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
306309 let ( generics, struct_def) = self . lower_generics (
307310 generics,
308311 Const :: No ,
312+ false ,
309313 id,
310314 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
311315 |this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -316,6 +320,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
316320 let ( generics, vdata) = self . lower_generics (
317321 generics,
318322 Const :: No ,
323+ false ,
319324 id,
320325 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
321326 |this| this. lower_variant_data ( hir_id, vdata) ,
@@ -347,12 +352,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
347352 // parent lifetime.
348353 let itctx = ImplTraitContext :: Universal ;
349354 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| {
351356 let modifiers = TraitBoundModifiers {
352- constness : match * constness {
353- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
354- Const :: No => BoundConstness :: Never ,
355- } ,
357+ constness : BoundConstness :: Never ,
356358 asyncness : BoundAsyncness :: Normal ,
357359 // we don't use this in bound lowering
358360 polarity : BoundPolarity :: Positive ,
@@ -388,6 +390,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
388390 ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
389391 } ;
390392 hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
393+ constness : self . lower_constness ( * constness) ,
391394 safety : self . lower_safety ( * safety, hir:: Safety :: Safe ) ,
392395 polarity,
393396 defaultness,
@@ -399,15 +402,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
399402 } ) )
400403 }
401404 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 ) ) ;
408405 let ( generics, ( safety, items, bounds) ) = self . lower_generics (
409406 generics,
410- constness,
407+ Const :: No ,
408+ false ,
411409 id,
412410 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
413411 |this| {
@@ -428,6 +426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
428426 let ( generics, bounds) = self . lower_generics (
429427 generics,
430428 Const :: No ,
429+ false ,
431430 id,
432431 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
433432 |this| {
@@ -608,30 +607,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
608607 // This is used to track which lifetimes have already been defined,
609608 // and which need to be replicated when lowering an async fn.
610609
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 {
612612 hir:: ItemKind :: Impl ( impl_) => {
613613 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+ }
615634 }
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 ) ) ,
617641 kind => {
618642 span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
619643 }
620644 } ;
621645
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-
632646 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 ) ) ,
635649 }
636650 }
637651
@@ -647,7 +661,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
647661 let fdec = & sig. decl ;
648662 let itctx = ImplTraitContext :: Universal ;
649663 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| {
651665 (
652666 // Disallow `impl Trait` in foreign items.
653667 this. lower_fn_decl (
@@ -764,7 +778,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
764778 }
765779 }
766780
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 > {
768786 let hir_id = self . lower_node_id ( i. id ) ;
769787 self . lower_attrs ( hir_id, & i. attrs ) ;
770788 let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -774,6 +792,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
774792 let ( generics, kind) = self . lower_generics (
775793 generics,
776794 Const :: No ,
795+ false ,
777796 i. id ,
778797 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
779798 |this| {
@@ -794,6 +813,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
794813 i. id ,
795814 FnDeclKind :: Trait ,
796815 sig. header . coroutine_kind ,
816+ trait_constness,
797817 ) ;
798818 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
799819 }
@@ -811,6 +831,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
811831 i. id ,
812832 FnDeclKind :: Trait ,
813833 sig. header . coroutine_kind ,
834+ trait_constness,
814835 ) ;
815836 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
816837 }
@@ -820,6 +841,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
820841 let ( generics, kind) = self . lower_generics (
821842 & generics,
822843 Const :: No ,
844+ false ,
823845 i. id ,
824846 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
825847 |this| {
@@ -892,7 +914,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
892914 self . expr ( span, hir:: ExprKind :: Err ( guar) )
893915 }
894916
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 > {
896922 // Since `default impl` is not yet implemented, this is always true in impls.
897923 let has_value = true ;
898924 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -903,6 +929,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
903929 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
904930 generics,
905931 Const :: No ,
932+ false ,
906933 i. id ,
907934 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
908935 |this| {
@@ -927,6 +954,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
927954 i. id ,
928955 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
929956 sig. header . coroutine_kind ,
957+ constness_of_trait,
930958 ) ;
931959
932960 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -937,6 +965,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
937965 self . lower_generics (
938966 & generics,
939967 Const :: No ,
968+ false ,
940969 i. id ,
941970 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
942971 |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