@@ -337,6 +337,7 @@ enum LifetimeBinderKind {
337337 PolyTrait ,
338338 WhereBound ,
339339 Item ,
340+ ConstItem ,
340341 Function ,
341342 Closure ,
342343 ImplBlock ,
@@ -349,7 +350,7 @@ impl LifetimeBinderKind {
349350 BareFnType => "type" ,
350351 PolyTrait => "bound" ,
351352 WhereBound => "bound" ,
352- Item => "item" ,
353+ Item | ConstItem => "item" ,
353354 ImplBlock => "impl block" ,
354355 Function => "function" ,
355356 Closure => "closure" ,
@@ -2404,30 +2405,44 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24042405 } ) ;
24052406 }
24062407
2407- ItemKind :: Static ( box ast:: StaticItem { ref ty, ref expr, .. } )
2408- | ItemKind :: Const ( box ast:: ConstItem { ref ty, ref expr, .. } ) => {
2408+ ItemKind :: Static ( box ast:: StaticItem { ref ty, ref expr, .. } ) => {
24092409 self . with_static_rib ( |this| {
24102410 this. with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Static ) , |this| {
24112411 this. visit_ty ( ty) ;
24122412 } ) ;
2413- this. with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
2413+ if let Some ( expr) = expr {
2414+ // We already forbid generic params because of the above item rib,
2415+ // so it doesn't matter whether this is a trivial constant.
2416+ this. resolve_const_body ( expr, Some ( ( item. ident , ConstantItemKind :: Static ) ) ) ;
2417+ }
2418+ } ) ;
2419+ }
2420+
2421+ ItemKind :: Const ( box ast:: ConstItem { ref generics, ref ty, ref expr, .. } ) => {
2422+ self . with_generic_param_rib (
2423+ & generics. params ,
2424+ RibKind :: Item ( HasGenericParams :: Yes ( generics. span ) ) ,
2425+ LifetimeRibKind :: Generics {
2426+ binder : item. id ,
2427+ kind : LifetimeBinderKind :: ConstItem ,
2428+ span : generics. span ,
2429+ } ,
2430+ |this| {
2431+ this. visit_generics ( generics) ;
2432+
2433+ this. with_lifetime_rib (
2434+ LifetimeRibKind :: Elided ( LifetimeRes :: Static ) ,
2435+ |this| this. visit_ty ( ty) ,
2436+ ) ;
2437+
24142438 if let Some ( expr) = expr {
2415- let constant_item_kind = match item. kind {
2416- ItemKind :: Const ( ..) => ConstantItemKind :: Const ,
2417- ItemKind :: Static ( ..) => ConstantItemKind :: Static ,
2418- _ => unreachable ! ( ) ,
2419- } ;
2420- // We already forbid generic params because of the above item rib,
2421- // so it doesn't matter whether this is a trivial constant.
2422- this. with_constant_rib (
2423- IsRepeatExpr :: No ,
2424- ConstantHasGenerics :: Yes ,
2425- Some ( ( item. ident , constant_item_kind) ) ,
2426- |this| this. visit_expr ( expr) ,
2439+ this. resolve_const_body (
2440+ expr,
2441+ Some ( ( item. ident , ConstantItemKind :: Const ) ) ,
24272442 ) ;
24282443 }
2429- } ) ;
2430- } ) ;
2444+ } ,
2445+ ) ;
24312446 }
24322447
24332448 ItemKind :: Use ( ref use_tree) => {
@@ -2700,28 +2715,31 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
27002715 for item in trait_items {
27012716 self . resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item. id ) ) ;
27022717 match & item. kind {
2703- AssocItemKind :: Const ( box ast:: ConstItem { ty, expr, .. } ) => {
2704- self . visit_ty ( ty) ;
2705- // Only impose the restrictions of `ConstRibKind` for an
2706- // actual constant expression in a provided default.
2707- if let Some ( expr) = expr {
2708- // We allow arbitrary const expressions inside of associated consts,
2709- // even if they are potentially not const evaluatable.
2710- //
2711- // Type parameters can already be used and as associated consts are
2712- // not used as part of the type system, this is far less surprising.
2713- self . with_lifetime_rib (
2714- LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) ,
2715- |this| {
2716- this. with_constant_rib (
2717- IsRepeatExpr :: No ,
2718- ConstantHasGenerics :: Yes ,
2719- None ,
2720- |this| this. visit_expr ( expr) ,
2721- )
2722- } ,
2723- ) ;
2724- }
2718+ AssocItemKind :: Const ( box ast:: ConstItem { generics, ty, expr, .. } ) => {
2719+ self . with_generic_param_rib (
2720+ & generics. params ,
2721+ RibKind :: AssocItem ,
2722+ LifetimeRibKind :: Generics {
2723+ binder : item. id ,
2724+ span : generics. span ,
2725+ kind : LifetimeBinderKind :: ConstItem ,
2726+ } ,
2727+ |this| {
2728+ this. visit_generics ( generics) ;
2729+ this. visit_ty ( ty) ;
2730+
2731+ // Only impose the restrictions of `ConstRibKind` for an
2732+ // actual constant expression in a provided default.
2733+ if let Some ( expr) = expr {
2734+ // We allow arbitrary const expressions inside of associated consts,
2735+ // even if they are potentially not const evaluatable.
2736+ //
2737+ // Type parameters can already be used and as associated consts are
2738+ // not used as part of the type system, this is far less surprising.
2739+ this. resolve_const_body ( expr, None ) ;
2740+ }
2741+ } ,
2742+ ) ;
27252743 }
27262744 AssocItemKind :: Fn ( box Fn { generics, .. } ) => {
27272745 walk_assoc_item ( self , generics, LifetimeBinderKind :: Function , item) ;
@@ -2876,36 +2894,42 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28762894 use crate :: ResolutionError :: * ;
28772895 self . resolve_doc_links ( & item. attrs , MaybeExported :: ImplItem ( trait_id. ok_or ( & item. vis ) ) ) ;
28782896 match & item. kind {
2879- AssocItemKind :: Const ( box ast:: ConstItem { ty, expr, .. } ) => {
2897+ AssocItemKind :: Const ( box ast:: ConstItem { generics , ty, expr, .. } ) => {
28802898 debug ! ( "resolve_implementation AssocItemKind::Const" ) ;
2881- // If this is a trait impl, ensure the const
2882- // exists in trait
2883- self . check_trait_item (
2884- item. id ,
2885- item. ident ,
2886- & item. kind ,
2887- ValueNS ,
2888- item. span ,
2889- seen_trait_items,
2890- |i, s, c| ConstNotMemberOfTrait ( i, s, c) ,
2891- ) ;
28922899
2893- self . visit_ty ( ty) ;
2894- if let Some ( expr) = expr {
2895- // We allow arbitrary const expressions inside of associated consts,
2896- // even if they are potentially not const evaluatable.
2897- //
2898- // Type parameters can already be used and as associated consts are
2899- // not used as part of the type system, this is far less surprising.
2900- self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
2901- this. with_constant_rib (
2902- IsRepeatExpr :: No ,
2903- ConstantHasGenerics :: Yes ,
2904- None ,
2905- |this| this. visit_expr ( expr) ,
2906- )
2907- } ) ;
2908- }
2900+ self . with_generic_param_rib (
2901+ & generics. params ,
2902+ RibKind :: AssocItem ,
2903+ LifetimeRibKind :: Generics {
2904+ binder : item. id ,
2905+ span : generics. span ,
2906+ kind : LifetimeBinderKind :: ConstItem ,
2907+ } ,
2908+ |this| {
2909+ // If this is a trait impl, ensure the const
2910+ // exists in trait
2911+ this. check_trait_item (
2912+ item. id ,
2913+ item. ident ,
2914+ & item. kind ,
2915+ ValueNS ,
2916+ item. span ,
2917+ seen_trait_items,
2918+ |i, s, c| ConstNotMemberOfTrait ( i, s, c) ,
2919+ ) ;
2920+
2921+ this. visit_generics ( generics) ;
2922+ this. visit_ty ( ty) ;
2923+ if let Some ( expr) = expr {
2924+ // We allow arbitrary const expressions inside of associated consts,
2925+ // even if they are potentially not const evaluatable.
2926+ //
2927+ // Type parameters can already be used and as associated consts are
2928+ // not used as part of the type system, this is far less surprising.
2929+ this. resolve_const_body ( expr, None ) ;
2930+ }
2931+ } ,
2932+ ) ;
29092933 }
29102934 AssocItemKind :: Fn ( box Fn { generics, .. } ) => {
29112935 debug ! ( "resolve_implementation AssocItemKind::Fn" ) ;
@@ -3063,6 +3087,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
30633087 ) ;
30643088 }
30653089
3090+ fn resolve_const_body ( & mut self , expr : & ' ast Expr , item : Option < ( Ident , ConstantItemKind ) > ) {
3091+ self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
3092+ this. with_constant_rib ( IsRepeatExpr :: No , ConstantHasGenerics :: Yes , item, |this| {
3093+ this. visit_expr ( expr)
3094+ } ) ;
3095+ } )
3096+ }
3097+
30663098 fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
30673099 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
30683100 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
@@ -4448,6 +4480,7 @@ impl<'ast> Visitor<'ast> for LifetimeCountVisitor<'_, '_, '_> {
44484480 fn visit_item ( & mut self , item : & ' ast Item ) {
44494481 match & item. kind {
44504482 ItemKind :: TyAlias ( box TyAlias { ref generics, .. } )
4483+ | ItemKind :: Const ( box ConstItem { ref generics, .. } )
44514484 | ItemKind :: Fn ( box Fn { ref generics, .. } )
44524485 | ItemKind :: Enum ( _, ref generics)
44534486 | ItemKind :: Struct ( _, ref generics)
@@ -4467,7 +4500,6 @@ impl<'ast> Visitor<'ast> for LifetimeCountVisitor<'_, '_, '_> {
44674500 ItemKind :: Mod ( ..)
44684501 | ItemKind :: ForeignMod ( ..)
44694502 | ItemKind :: Static ( ..)
4470- | ItemKind :: Const ( ..)
44714503 | ItemKind :: Use ( ..)
44724504 | ItemKind :: ExternCrate ( ..)
44734505 | ItemKind :: MacroDef ( ..)
0 commit comments