Commit a5cb4ab95e

Isaac Freund <ifreund@ifreund.xyz>
2021-03-07 19:20:41
parser: disallow ptr modifiers on array types
1 parent 482424e
Changed files (3)
lib/std/zig/ast.zig
@@ -275,8 +275,10 @@ pub const Tree = struct {
             .extra_volatile_qualifier => {
                 return stream.writeAll("extra volatile qualifier");
             },
-            .invalid_align => {
-                return stream.writeAll("alignment not allowed on arrays");
+            .ptr_mod_on_array_child_type => {
+                return stream.print("pointer modifier '{s}' not allowed on array child type", .{
+                    token_tags[parse_error.token].symbol(),
+                });
             },
             .invalid_and => {
                 return stream.writeAll("`&&` is invalid; note that `and` is boolean AND");
@@ -2388,7 +2390,7 @@ pub const Error = struct {
         extra_allowzero_qualifier,
         extra_const_qualifier,
         extra_volatile_qualifier,
-        invalid_align,
+        ptr_mod_on_array_child_type,
         invalid_and,
         invalid_bit_range,
         invalid_token,
lib/std/zig/parse.zig
@@ -1612,13 +1612,15 @@ const Parser = struct {
     /// PrefixTypeOp
     ///     <- QUESTIONMARK
     ///      / KEYWORD_anyframe MINUSRARROW
-    ///      / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
+    ///      / SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
     ///      / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
+    ///      / ArrayTypeStart
+    /// SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET
     /// PtrTypeStart
     ///     <- ASTERISK
     ///      / ASTERISK2
     ///      / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
-    /// ArrayTypeStart <- LBRACKET Expr? (COLON Expr)? RBRACKET
+    /// ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
     fn parseTypeExpr(p: *Parser) Error!Node.Index {
         switch (p.token_tags[p.tok_i]) {
             .question_mark => return p.addNode(.{
@@ -1785,15 +1787,15 @@ const Parser = struct {
                     else
                         0;
                     _ = try p.expectToken(.r_bracket);
-                    const mods = try p.parsePtrModifiers();
-                    const elem_type = try p.expectTypeExpr();
-                    if (mods.bit_range_start != 0) {
-                        try p.warnMsg(.{
-                            .tag = .invalid_bit_range,
-                            .token = p.nodes.items(.main_token)[mods.bit_range_start],
-                        });
-                    }
                     if (len_expr == 0) {
+                        const mods = try p.parsePtrModifiers();
+                        const elem_type = try p.expectTypeExpr();
+                        if (mods.bit_range_start != 0) {
+                            try p.warnMsg(.{
+                                .tag = .invalid_bit_range,
+                                .token = p.nodes.items(.main_token)[mods.bit_range_start],
+                            });
+                        }
                         if (sentinel == 0) {
                             return p.addNode(.{
                                 .tag = .ptr_type_aligned,
@@ -1826,12 +1828,15 @@ const Parser = struct {
                             });
                         }
                     } else {
-                        if (mods.align_node != 0) {
-                            try p.warnMsg(.{
-                                .tag = .invalid_align,
-                                .token = p.nodes.items(.main_token)[mods.align_node],
-                            });
+                        switch (p.token_tags[p.tok_i]) {
+                            .keyword_align,
+                            .keyword_const,
+                            .keyword_volatile,
+                            .keyword_allowzero,
+                            => return p.fail(.ptr_mod_on_array_child_type),
+                            else => {},
                         }
+                        const elem_type = try p.expectTypeExpr();
                         if (sentinel == 0) {
                             return p.addNode(.{
                                 .tag = .array_type,
lib/std/zig/parser_test.zig
@@ -4350,11 +4350,17 @@ test "zig fmt: error for invalid bit range" {
     });
 }
 
-test "zig fmt: error for invalid align" {
+test "zig fmt: error for ptr mod on array child type" {
     try testError(
-        \\var x: [10]align(10)u8 = bar;
+        \\var a: [10]align(10) u8 = e;
+        \\var b: [10]const u8 = f;
+        \\var c: [10]volatile u8 = g;
+        \\var d: [10]allowzero u8 = h;
     , &[_]Error{
-        .invalid_align,
+        .ptr_mod_on_array_child_type,
+        .ptr_mod_on_array_child_type,
+        .ptr_mod_on_array_child_type,
+        .ptr_mod_on_array_child_type,
     });
 }