@@ -54,7 +54,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
5454 owner : NodeId ,
5555 f : impl FnOnce ( & mut LoweringContext < ' _ , ' hir > ) -> hir:: OwnerNode < ' hir > ,
5656 ) {
57- let mut lctx = LoweringContext :: new ( self . tcx , self . resolver ) ;
57+ let mut lctx = LoweringContext :: new ( self . tcx , self . resolver , self . ast_index ) ;
5858 lctx. with_hir_id_owner ( owner, |lctx| f ( lctx) ) ;
5959
6060 for ( def_id, info) in lctx. children {
@@ -188,6 +188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
188188 let ( generics, ( ty, body_id) ) = self . lower_generics (
189189 generics,
190190 Const :: No ,
191+ false ,
191192 id,
192193 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
193194 |this| {
@@ -218,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
218219
219220 let itctx = ImplTraitContext :: Universal ;
220221 let ( generics, decl) =
221- this. lower_generics ( generics, header. constness , id, itctx, |this| {
222+ this. lower_generics ( generics, header. constness , false , id, itctx, |this| {
222223 this. lower_fn_decl (
223224 decl,
224225 id,
@@ -262,6 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
262263 let ( generics, ty) = self . lower_generics (
263264 & generics,
264265 Const :: No ,
266+ false ,
265267 id,
266268 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
267269 |this| match ty {
@@ -284,6 +286,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
284286 let ( generics, variants) = self . lower_generics (
285287 generics,
286288 Const :: No ,
289+ false ,
287290 id,
288291 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
289292 |this| {
@@ -298,6 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
298301 let ( generics, struct_def) = self . lower_generics (
299302 generics,
300303 Const :: No ,
304+ false ,
301305 id,
302306 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
303307 |this| this. lower_variant_data ( hir_id, struct_def) ,
@@ -308,6 +312,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
308312 let ( generics, vdata) = self . lower_generics (
309313 generics,
310314 Const :: No ,
315+ false ,
311316 id,
312317 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
313318 |this| this. lower_variant_data ( hir_id, vdata) ,
@@ -339,12 +344,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
339344 // parent lifetime.
340345 let itctx = ImplTraitContext :: Universal ;
341346 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| {
343348 let modifiers = TraitBoundModifiers {
344- constness : match * constness {
345- Const :: Yes ( span) => BoundConstness :: Maybe ( span) ,
346- Const :: No => BoundConstness :: Never ,
347- } ,
349+ constness : BoundConstness :: Never ,
348350 asyncness : BoundAsyncness :: Normal ,
349351 // we don't use this in bound lowering
350352 polarity : BoundPolarity :: Positive ,
@@ -379,6 +381,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
379381 ImplPolarity :: Negative ( s) => ImplPolarity :: Negative ( self . lower_span ( * s) ) ,
380382 } ;
381383 hir:: ItemKind :: Impl ( self . arena . alloc ( hir:: Impl {
384+ constness : self . lower_constness ( * constness) ,
382385 unsafety : self . lower_unsafety ( * unsafety) ,
383386 polarity,
384387 defaultness,
@@ -390,15 +393,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
390393 } ) )
391394 }
392395 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 ) ) ;
399396 let ( generics, ( unsafety, items, bounds) ) = self . lower_generics (
400397 generics,
401- constness,
398+ Const :: No ,
399+ false ,
402400 id,
403401 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
404402 |this| {
@@ -419,6 +417,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
419417 let ( generics, bounds) = self . lower_generics (
420418 generics,
421419 Const :: No ,
420+ false ,
422421 id,
423422 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
424423 |this| {
@@ -599,30 +598,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
599598 // This is used to track which lifetimes have already been defined,
600599 // and which need to be replicated when lowering an async fn.
601600
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 {
603603 hir:: ItemKind :: Impl ( impl_) => {
604604 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+ }
606625 }
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 ) ) ,
608632 kind => {
609633 span_bug ! ( item. span, "assoc item has unexpected kind of parent: {}" , kind. descr( ) )
610634 }
611635 } ;
612636
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-
623637 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 ) ) ,
626640 }
627641 }
628642
@@ -638,7 +652,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
638652 let fdec = & sig. decl ;
639653 let itctx = ImplTraitContext :: Universal ;
640654 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| {
642656 (
643657 // Disallow `impl Trait` in foreign items.
644658 this. lower_fn_decl (
@@ -752,7 +766,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
752766 }
753767 }
754768
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 > {
756774 let hir_id = self . lower_node_id ( i. id ) ;
757775 self . lower_attrs ( hir_id, & i. attrs ) ;
758776 let trait_item_def_id = hir_id. expect_owner ( ) ;
@@ -762,6 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
762780 let ( generics, kind) = self . lower_generics (
763781 generics,
764782 Const :: No ,
783+ false ,
765784 i. id ,
766785 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
767786 |this| {
@@ -782,6 +801,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
782801 i. id ,
783802 FnDeclKind :: Trait ,
784803 sig. header . coroutine_kind ,
804+ trait_constness,
785805 ) ;
786806 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
787807 }
@@ -799,6 +819,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
799819 i. id ,
800820 FnDeclKind :: Trait ,
801821 sig. header . coroutine_kind ,
822+ trait_constness,
802823 ) ;
803824 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
804825 }
@@ -808,6 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
808829 let ( generics, kind) = self . lower_generics (
809830 & generics,
810831 Const :: No ,
832+ false ,
811833 i. id ,
812834 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
813835 |this| {
@@ -876,7 +898,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
876898 self . expr ( span, hir:: ExprKind :: Err ( guar) )
877899 }
878900
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 > {
880906 // Since `default impl` is not yet implemented, this is always true in impls.
881907 let has_value = true ;
882908 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
@@ -887,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
887913 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
888914 generics,
889915 Const :: No ,
916+ false ,
890917 i. id ,
891918 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
892919 |this| {
@@ -911,6 +938,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911938 i. id ,
912939 if self . is_in_trait_impl { FnDeclKind :: Impl } else { FnDeclKind :: Inherent } ,
913940 sig. header . coroutine_kind ,
941+ constness_of_trait,
914942 ) ;
915943
916944 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
@@ -921,6 +949,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
921949 self . lower_generics (
922950 & generics,
923951 Const :: No ,
952+ false ,
924953 i. id ,
925954 ImplTraitContext :: Disallowed ( ImplTraitPosition :: Generic ) ,
926955 |this| match ty {
@@ -1323,15 +1352,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13231352 id : NodeId ,
13241353 kind : FnDeclKind ,
13251354 coroutine_kind : Option < CoroutineKind > ,
1355+ parent_constness : Const ,
13261356 ) -> ( & ' hir hir:: Generics < ' hir > , hir:: FnSig < ' hir > ) {
13271357 let header = self . lower_fn_header ( sig. header ) ;
13281358 // Don't pass along the user-provided constness of trait associated functions; we don't want to
13291359 // 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 } ;
13311362 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+ } ) ;
13351367 ( generics, hir:: FnSig { header, decl, span : self . lower_span ( sig. span ) } )
13361368 }
13371369
@@ -1406,6 +1438,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14061438 & mut self ,
14071439 generics : & Generics ,
14081440 constness : Const ,
1441+ force_append_constness : bool ,
14091442 parent_node_id : NodeId ,
14101443 itctx : ImplTraitContext ,
14111444 f : impl FnOnce ( & mut Self ) -> T ,
@@ -1466,7 +1499,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14661499 // if the effects feature is enabled. This needs to be done before we lower where
14671500 // clauses since where clauses need to bind to the DefId of the host param
14681501 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)
14701505 {
14711506 let span = self . lower_span ( span) ;
14721507 let param_node_id = self . next_node_id ( ) ;
@@ -1579,12 +1614,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
15791614 } ) ,
15801615 ) ) ,
15811616 ) ) ,
1617+ // FIXME(effects) we might not need a default.
15821618 default : Some ( hir:: AnonConst {
15831619 def_id : anon_const,
15841620 hir_id : const_id,
15851621 body : const_body,
15861622 } ) ,
15871623 is_host_effect : true ,
1624+ synthetic : true ,
15881625 } ,
15891626 colon_span : None ,
15901627 pure_wrt_drop : false ,
0 commit comments