]> git.lizzy.rs Git - rust.git/commitdiff
Permit standalone generic parameters as const generic arguments in macros
authorvarkor <github@varkor.com>
Wed, 18 Nov 2020 12:49:39 +0000 (12:49 +0000)
committervarkor <github@varkor.com>
Wed, 18 Nov 2020 13:16:35 +0000 (13:16 +0000)
compiler/rustc_parse/src/parser/diagnostics.rs
compiler/rustc_parse/src/parser/path.rs
src/test/ui/const-generics/macro_rules-braces.full.stderr
src/test/ui/const-generics/macro_rules-braces.min.stderr
src/test/ui/const-generics/macro_rules-braces.rs

index cd3b8db2303b366a65d5a99d5e38876ad33d255b..350a372a684cc5e7b6f829f1e13026c0f61a37c7 100644 (file)
@@ -1808,9 +1808,13 @@ pub fn handle_ambiguous_unbraced_const_arg(
         return Ok(false); // Don't continue.
     }
 
-    /// Handle a generic const argument that had not been enclosed in braces, and suggest enclosing
-    /// it braces. In this situation, unlike in `handle_ambiguous_unbraced_const_arg`, this is
-    /// almost certainly a const argument, so we always offer a suggestion.
+    /// Attempt to parse a generic const argument that has not been enclosed in braces.
+    /// There are a limited number of expressions that are permitted without being encoded
+    /// in braces:
+    /// - Literals.
+    /// - Single-segment paths (i.e. standalone generic const parameters).
+    /// All other expressions that can be parsed will emit an error suggesting the expression be
+    /// wrapped in braces.
     pub fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P<Expr>> {
         let start = self.token.span;
         let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
index 79e737490386c023eaa1d6842ffce0f4fafcca63..d64fd59b0a6574501dd7f79e81bb1a0339136f1f 100644 (file)
@@ -489,6 +489,7 @@ fn parse_assoc_equality_term(&mut self, ident: Ident, eq: Span) -> PResult<'a, P
     /// - An expression surrounded in `{}`.
     /// - A literal.
     /// - A numeric literal prefixed by `-`.
+    /// - A single-segment path.
     pub(super) fn expr_is_valid_const_arg(&self, expr: &P<rustc_ast::Expr>) -> bool {
         match &expr.kind {
             ast::ExprKind::Block(_, _) | ast::ExprKind::Lit(_) => true,
@@ -496,6 +497,13 @@ pub(super) fn expr_is_valid_const_arg(&self, expr: &P<rustc_ast::Expr>) -> bool
                 ast::ExprKind::Lit(_) => true,
                 _ => false,
             },
+            // We can only resolve single-segment paths at the moment, because multi-segment paths
+            // require type-checking: see `visit_generic_arg` in `src/librustc_resolve/late.rs`.
+            ast::ExprKind::Path(None, path)
+                if path.segments.len() == 1 && path.segments[0].args.is_none() =>
+            {
+                true
+            }
             _ => false,
         }
     }
index e5b67f61a25b7463c315ebb2fb29d51c003b9b83..273766b0b0e714b54217c45fe5fadc316e84c3fa 100644 (file)
@@ -1,14 +1,3 @@
-error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:34:17
-   |
-LL |     let _: baz!(N);
-   |                 ^
-   |
-help: enclose the `const` expression in braces
-   |
-LL |     let _: baz!({ N });
-   |                 ^   ^
-
 error: expressions must be enclosed in braces to be used as const generic arguments
   --> $DIR/macro_rules-braces.rs:54:17
    |
@@ -68,5 +57,5 @@ LL |     let _: biz!({ N });
    = note: this may fail depending on what value the parameter takes
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
index a4ef732017dd531448afbc3773fb60e830a01abd..10c2a596ca562b0299a980a20dc6543fa1595a4c 100644 (file)
@@ -1,14 +1,3 @@
-error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:34:17
-   |
-LL |     let _: baz!(N);
-   |                 ^
-   |
-help: enclose the `const` expression in braces
-   |
-LL |     let _: baz!({ N });
-   |                 ^   ^
-
 error: expressions must be enclosed in braces to be used as const generic arguments
   --> $DIR/macro_rules-braces.rs:54:17
    |
@@ -52,5 +41,5 @@ LL |     let _: biz!({ N });
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
index bc67d464f11bb0170c8cd045225e9b52bb6e75c2..bc2eca81b6182d5cb254c778e3364b72b4bfbd3d 100644 (file)
@@ -31,7 +31,7 @@ macro_rules! biz {
     let _: foo!({{ N }}); //[min]~ ERROR generic parameters may not
     let _: bar!(N);
     let _: bar!({ N }); //[min]~ ERROR generic parameters may not
-    let _: baz!(N); //~ ERROR expressions must be enclosed in braces
+    let _: baz!(N);
     let _: baz!({ N });
     let _: baz!({{ N }}); //[min]~ ERROR generic parameters may not
     let _: biz!(N);