authorgravatar for 94326797+riverbl@users.noreply.github.comriverbl <94326797+riverbl@users.noreply.github.com> 2021-12-30 22:54:11+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-02 21:17:25-07:00
log2ac7aefe2ff0d2f1a4d58a2baa49a40dfb670732
tree03933f9fb270ba76428c65d5fc2aaf59dea1a2ae
parentbb9399cc5d7a744f0212db56c0133526ab29ce88

stage2: do not interpret identifier containing underscores (eg: u3_2) as int primitive type


2 files changed, 40 insertions(+), 3 deletions(-)

src/AstGen.zig+24-3
......@@ -6017,6 +6017,27 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
60176017 }
60186018}
60196019
6020/// Parses the string `buf` as a base 10 integer of type `u16`.
6021///
6022/// Unlike std.fmt.parseInt, does not allow the '_' character in `buf`.
6023fn parseBitCount(buf: []const u8) std.fmt.ParseIntError!u16 {
6024 if (buf.len == 0) return error.InvalidCharacter;
6025
6026 var x: u16 = 0;
6027
6028 for (buf) |c| {
6029 const digit = switch (c) {
6030 '0'...'9' => c - '0',
6031 else => return error.InvalidCharacter,
6032 };
6033
6034 if (x != 0) x = try std.math.mul(u16, x, 10);
6035 x = try std.math.add(u16, x, @as(u16, digit));
6036 }
6037
6038 return x;
6039}
6040
60206041fn identifier(
60216042 gz: *GenZir,
60226043 scope: *Scope,
......@@ -6050,7 +6071,7 @@ fn identifier(
60506071 true => .signed,
60516072 false => .unsigned,
60526073 };
6053 const bit_count = std.fmt.parseInt(u16, ident_name_raw[1..], 10) catch |err| switch (err) {
6074 const bit_count = parseBitCount(ident_name_raw[1..]) catch |err| switch (err) {
60546075 error.Overflow => return astgen.failNode(
60556076 ident,
60566077 "primitive integer type '{s}' exceeds maximum bit width of 65535",
......@@ -8864,7 +8885,7 @@ const GenZir = struct {
88648885 parent: *Scope,
88658886 /// All `GenZir` scopes for the same ZIR share this.
88668887 astgen: *AstGen,
8867 /// Keeps track of the list of instructions in this scope. Possibly shared.
8888 /// Keeps track of the list of instructions in this scope. Possibly shared.
88688889 /// Indexes to instructions in `astgen`.
88698890 instructions: *ArrayListUnmanaged(Zir.Inst.Index),
88708891 /// A sub-block may share its instructions ArrayList with containing GenZir,
......@@ -10098,7 +10119,7 @@ pub fn isPrimitive(name: []const u8) bool {
1009810119 if (name.len < 2) return false;
1009910120 const first_c = name[0];
1010010121 if (first_c != 'i' and first_c != 'u') return false;
10101 if (std.fmt.parseInt(u16, name[1..], 10)) |_| {
10122 if (parseBitCount(name[1..])) |_| {
1010210123 return true;
1010310124 } else |err| switch (err) {
1010410125 error.Overflow => return true,
test/behavior/misc.zig+16
......@@ -186,3 +186,19 @@ test "lazy typeInfo value as generic parameter" {
186186 };
187187 S.foo(@typeInfo(@TypeOf(.{})));
188188}
189
190test "variable name containing underscores does not shadow int primitive" {
191 const _u0 = 0;
192 const i_8 = 0;
193 const u16_ = 0;
194 const i3_2 = 0;
195 const u6__4 = 0;
196 const i2_04_8 = 0;
197
198 _ = _u0;
199 _ = i_8;
200 _ = u16_;
201 _ = i3_2;
202 _ = u6__4;
203 _ = i2_04_8;
204}