@@ -56,7 +56,7 @@ use rustc_data_structures::steal::Steal;
5656use rustc_data_structures:: tagged_ptr:: TaggedRef ;
5757use rustc_errors:: codes:: * ;
5858use rustc_errors:: { DiagArgFromDisplay , DiagCtxtHandle , ErrorGuaranteed } ;
59- use rustc_hir:: def:: { DefKind , Namespace , PerNS , Res } ;
59+ use rustc_hir:: def:: { CtorKind , DefKind , Namespace , PerNS , Res } ;
6060use rustc_hir:: def_id:: { DefId , LOCAL_CRATE , LocalDefId , LocalDefIdMap } ;
6161use rustc_hir:: definitions:: PerParentDisambiguatorState ;
6262use rustc_hir:: lints:: DelayedLint ;
@@ -1420,10 +1420,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
14201420 let ct = self . arena . alloc ( ct) ;
14211421 return GenericArg :: Const ( ct. try_as_ambig_ct ( ) . unwrap ( ) ) ;
14221422 }
1423- TyKind :: GcaMacro ( expr) if self . tcx . features ( ) . gca_min_const_items ( ) => {
1423+ TyKind :: GcaMacro ( expr) if self . tcx . features ( ) . gca ( ) => {
14241424 let ct = match self . can_lower_expr_to_const_arg_direct (
14251425 expr,
1426- DirectConstArgContext :: MacrolessMinGenericConstArgs ,
1426+ self . direct_const_arg_context_enabled_by_gca_macro ( ) ,
14271427 ) {
14281428 Ok ( ( ) ) => self . lower_expr_to_const_arg_direct ( expr, None ) ,
14291429 Err ( e) => e. emit ( self ) ,
@@ -2628,18 +2628,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
26282628 span : Span ,
26292629 ) -> hir:: ConstItemRhs < ' hir > {
26302630 let is_direct = |body| {
2631- if self . tcx . features ( ) . gca_macroless_items ( ) {
2632- self . can_lower_expr_to_const_arg_direct (
2633- body,
2634- DirectConstArgContext :: MacrolessMinGenericConstArgs ,
2635- )
2636- . is_ok ( )
2631+ let context = if self . tcx . features ( ) . gca_macroless_items ( ) {
2632+ self . direct_const_arg_context_enabled_by_gca_macro ( )
26372633 } else {
2638- // do not check can_lower_expr_to_const_arg_direct, but rather just
2639- // ExprKind::GcaMacro, because we don't want e.g.
2640- // `impl<const N: u8> { const C: u8 = N; }` to be a direct-rhs const
2641- matches ! ( body, Expr { kind: ExprKind :: GcaMacro ( _) , .. } )
2642- }
2634+ DirectConstArgContext :: GCA_MACRO
2635+ } ;
2636+ self . can_lower_expr_to_const_arg_direct ( body, context) . is_ok ( )
26432637 } ;
26442638 if self . tcx . features ( ) . gca_min_const_items ( )
26452639 && let Some ( body) = body
@@ -2653,13 +2647,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
26532647 }
26542648 }
26552649
2650+ fn direct_const_arg_context_enabled_by_gca_macro ( & self ) -> DirectConstArgContext {
2651+ let mut result = DirectConstArgContext :: GCA_BASE_FEATURES ;
2652+ if self . tcx . features ( ) . gca_min_const_items ( ) {
2653+ result |= DirectConstArgContext :: GCA_MIN_CONST_ITEMS ;
2654+ }
2655+ if self . tcx . features ( ) . gca_adts ( ) {
2656+ result |= DirectConstArgContext :: GCA_ADTS ;
2657+ }
2658+ result
2659+ }
2660+
2661+ /// Only valid for const *arg* contexts, not const *item* contexts.
26562662 fn ambient_direct_const_arg_context ( & self ) -> DirectConstArgContext {
26572663 if self . tcx . features ( ) . gca_macroless_args ( ) {
2658- DirectConstArgContext :: MacrolessMinGenericConstArgs
2659- } else if self . tcx . features ( ) . gca_min_const_items ( ) {
2660- DirectConstArgContext :: MinGenericConstArgs
2664+ self . direct_const_arg_context_enabled_by_gca_macro ( )
2665+ } else if self . tcx . features ( ) . gca ( ) {
2666+ DirectConstArgContext :: GCA
26612667 } else {
2662- DirectConstArgContext :: Stable
2668+ DirectConstArgContext :: STABLE
26632669 }
26642670 }
26652671
@@ -2671,9 +2677,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
26712677 res : Option < Res < NodeId > > ,
26722678 context : DirectConstArgContext ,
26732679 ) -> Result < ( ) , UnrepresentableConstArgError > {
2674- if let DirectConstArgContext :: MacrolessMinGenericConstArgs = context {
2680+ if context. contains ( DirectConstArgContext :: PATH_ANY ) {
2681+ Ok ( ( ) )
2682+ } else if context. contains ( DirectConstArgContext :: PATH_CONST_CTOR )
2683+ && matches ! ( res, Some ( Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Const ) , _) ) )
2684+ {
2685+ // FIXME(gca_adts): This check is incomplete. Type-relative paths and other complicating
2686+ // factors make things very difficult - e.g. `<Option<T>>::None`
26752687 Ok ( ( ) )
2676- } else if qself. is_none ( )
2688+ } else if context. contains ( DirectConstArgContext :: PATH_PLAIN_PARAM )
2689+ && qself. is_none ( )
26772690 && path. is_single_argless_ident ( )
26782691 && matches ! ( res, Some ( Res :: Def ( DefKind :: ConstParam , _) ) )
26792692 {
@@ -2689,59 +2702,61 @@ impl<'hir> LoweringContext<'_, 'hir> {
26892702 expr : & Expr ,
26902703 context : DirectConstArgContext ,
26912704 ) -> Result < ( ) , UnrepresentableConstArgError > {
2692- use DirectConstArgContext :: * ;
26932705 // Note the only stable case is currently ExprKind::Path
2694- match ( & expr. kind , context) {
2695- (
2696- ExprKind :: Call ( Expr { kind : ExprKind :: Path ( _, _) , .. } , args) ,
2697- MacrolessMinGenericConstArgs ,
2698- ) => {
2706+ match & expr. kind {
2707+ ExprKind :: Call ( Expr { kind : ExprKind :: Path ( _, _) , .. } , args)
2708+ if context. contains ( DirectConstArgContext :: TUPLE_CALL ) =>
2709+ {
26992710 for arg in args {
27002711 self . can_lower_expr_to_const_arg_direct ( arg, context) ?;
27012712 }
27022713 Ok ( ( ) )
27032714 }
2704- ( ExprKind :: Tup ( exprs) , MacrolessMinGenericConstArgs ) => {
2715+ ExprKind :: Tup ( exprs) if context . contains ( DirectConstArgContext :: TUPLE ) => {
27052716 for expr in exprs {
27062717 self . can_lower_expr_to_const_arg_direct ( expr, context) ?;
27072718 }
27082719 Ok ( ( ) )
27092720 }
2710- ( ExprKind :: Path ( qself, path) , _ ) => {
2721+ ExprKind :: Path ( qself, path) => {
27112722 let res =
27122723 self . get_partial_res ( expr. id ) . and_then ( |partial_res| partial_res. full_res ( ) ) ;
27132724 self . can_lower_path_to_const_arg_direct ( qself, path, expr. span , res, context)
27142725 }
2715- ( ExprKind :: Struct ( se) , MacrolessMinGenericConstArgs ) => {
2726+ ExprKind :: Struct ( se) if context . contains ( DirectConstArgContext :: STRUCT ) => {
27162727 for f in & se. fields {
27172728 self . can_lower_expr_to_const_arg_direct ( & f. expr , context) ?;
27182729 }
27192730 Ok ( ( ) )
27202731 }
2721- ( ExprKind :: Array ( elements) , MacrolessMinGenericConstArgs ) => {
2732+ ExprKind :: Array ( elements) if context . contains ( DirectConstArgContext :: ARRAY ) => {
27222733 for element in elements {
27232734 self . can_lower_expr_to_const_arg_direct ( element, context) ?;
27242735 }
27252736 Ok ( ( ) )
27262737 }
2727- ( ExprKind :: Underscore , MacrolessMinGenericConstArgs ) => Ok ( ( ) ) ,
2728- ( ExprKind :: Paren ( expr) , MacrolessMinGenericConstArgs ) => {
2738+ ExprKind :: Underscore if context . contains ( DirectConstArgContext :: UNDERSCORE ) => Ok ( ( ) ) ,
2739+ ExprKind :: Paren ( expr) if context . contains ( DirectConstArgContext :: PAREN ) => {
27292740 self . can_lower_expr_to_const_arg_direct ( expr, context)
27302741 }
2731- ( ExprKind :: Block ( block, _) , MacrolessMinGenericConstArgs )
2732- if let [ stmt] = block. stmts . as_slice ( )
2742+ ExprKind :: Block ( block, _)
2743+ if context. contains ( DirectConstArgContext :: BLOCK )
2744+ && let [ stmt] = block. stmts . as_slice ( )
27332745 && let StmtKind :: Expr ( expr) = & stmt. kind =>
27342746 {
27352747 self . can_lower_expr_to_const_arg_direct ( expr, context)
27362748 }
2737- ( ExprKind :: Lit ( _) , MacrolessMinGenericConstArgs ) => Ok ( ( ) ) ,
2738- ( ExprKind :: Unary ( UnOp :: Neg , inner_expr) , MacrolessMinGenericConstArgs )
2739- if let ExprKind :: Lit ( _) = & inner_expr. kind =>
2749+ ExprKind :: Lit ( _) if context. contains ( DirectConstArgContext :: LIT ) => Ok ( ( ) ) ,
2750+ ExprKind :: Unary ( UnOp :: Neg , inner_expr)
2751+ if context. contains ( DirectConstArgContext :: LIT )
2752+ && let ExprKind :: Lit ( _) = & inner_expr. kind =>
27402753 {
27412754 Ok ( ( ) )
27422755 }
2743- ( ExprKind :: ConstBlock ( _) , MacrolessMinGenericConstArgs ) => Ok ( ( ) ) ,
2744- ( ExprKind :: GcaMacro ( _) , MacrolessMinGenericConstArgs | MinGenericConstArgs ) => {
2756+ ExprKind :: ConstBlock ( _) if context. contains ( DirectConstArgContext :: CONST_BLOCK ) => {
2757+ Ok ( ( ) )
2758+ }
2759+ ExprKind :: GcaMacro ( _) if context. contains ( DirectConstArgContext :: GCA_MACRO ) => {
27452760 // Always report this as able to be represented directly. If it turns out not to be,
27462761 // `lower_expr_to_const_arg_direct` will report an error.
27472762 Ok ( ( ) )
@@ -2927,11 +2942,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
29272942 // `can_lower_expr_to_const_arg_direct` always returns success upon encountering a
29282943 // ExprKind::GcaMacro, which effectively forces the expression to be lowered as a
29292944 // direct arg. If it actually turns out to not be possible, emit an error instead.
2930- // Always use MacrolessMinGenericConstArgs, even if we're under regular GCA, because
2931- // that's what the macro means: to enter a context that is like macroless GCA.
29322945 match self . can_lower_expr_to_const_arg_direct (
29332946 expr,
2934- DirectConstArgContext :: MacrolessMinGenericConstArgs ,
2947+ self . direct_const_arg_context_enabled_by_gca_macro ( ) ,
29352948 ) {
29362949 Ok ( ( ) ) => self . lower_expr_to_const_arg_direct ( expr, id_override) ,
29372950 Err ( err) => err. emit ( self ) ,
@@ -3273,19 +3286,53 @@ impl<'hir> GenericArgsCtor<'hir> {
32733286 }
32743287}
32753288
3276- #[ derive( Copy , Clone , Debug ) ]
3277- enum DirectConstArgContext {
3289+ bitflags:: bitflags! {
3290+ #[ derive( Copy , Clone , Debug ) ]
3291+ struct DirectConstArgContext : u16 {
3292+ const TUPLE_CALL = 1 << 0 ;
3293+ const TUPLE = 1 << 1 ;
3294+ const PATH_PLAIN_PARAM = 1 << 2 ;
3295+ const PATH_CONST_CTOR = 1 << 3 ;
3296+ const PATH_ANY = 1 << 4 ;
3297+ const STRUCT = 1 << 5 ;
3298+ const ARRAY = 1 << 6 ;
3299+ const UNDERSCORE = 1 << 7 ;
3300+ const PAREN = 1 << 8 ;
3301+ const BLOCK = 1 << 9 ;
3302+ const LIT = 1 << 10 ;
3303+ const CONST_BLOCK = 1 << 11 ;
3304+ const GCA_MACRO = 1 << 12 ;
3305+ }
3306+ }
3307+
3308+ impl DirectConstArgContext {
32783309 /// The only allowed direct const arg representation is simple paths that nameres to generic
32793310 /// const parameters.
3280- Stable ,
3311+ const STABLE : DirectConstArgContext = Self :: PATH_PLAIN_PARAM ;
3312+
32813313 /// The allowed representations are what is allowed on stable, plus the `gca!` macro.
3282- MinGenericConstArgs ,
3283- /// Expressions attempt to be lowered directly, and if that fails, the expression falls back to
3284- /// being represented as an anon const.
3314+ const GCA : DirectConstArgContext = Self :: STABLE . union ( Self :: GCA_MACRO ) ;
3315+
3316+ /// These expressions are allowed inside the `gca!` macro, regardless of what feature is
3317+ /// enabling the base `gca!` functionality.
32853318 ///
3286- /// This context is also used under MinGenericConstArgs inside a `gca!` macro, for
3287- /// simplicity, as they allow the same code.
3288- MacrolessMinGenericConstArgs ,
3319+ /// These are also allowed under macroless features without a `gca!` macro.
3320+ const GCA_BASE_FEATURES : DirectConstArgContext = Self :: GCA
3321+ . union ( DirectConstArgContext :: UNDERSCORE )
3322+ . union ( DirectConstArgContext :: PAREN )
3323+ . union ( DirectConstArgContext :: BLOCK )
3324+ . union ( DirectConstArgContext :: LIT )
3325+ . union ( DirectConstArgContext :: CONST_BLOCK ) ;
3326+
3327+ /// These are allowed under `#![feature(gca_min_const_items)]`
3328+ const GCA_MIN_CONST_ITEMS : DirectConstArgContext = DirectConstArgContext :: PATH_ANY ;
3329+
3330+ /// These are allowed under `#![feature(gca_adts)]`
3331+ const GCA_ADTS : DirectConstArgContext = DirectConstArgContext :: PATH_CONST_CTOR
3332+ . union ( DirectConstArgContext :: TUPLE_CALL )
3333+ . union ( DirectConstArgContext :: TUPLE )
3334+ . union ( DirectConstArgContext :: STRUCT )
3335+ . union ( DirectConstArgContext :: ARRAY ) ;
32893336}
32903337
32913338#[ derive( Debug ) ]
0 commit comments