checker: check for reserved type names in `for in` (fix #14072) (#14212)

master
StunxFS 2022-04-29 18:25:29 -04:00 committed by GitHub
parent 48eb40cd2c
commit db185e6580
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 12 deletions

View File

@ -38,8 +38,9 @@ pub const (
valid_comptime_not_user_defined = all_valid_comptime_idents()
array_builtin_methods = ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice',
'sort', 'contains', 'index', 'wait', 'any', 'all', 'first', 'last', 'pop']
reserved_type_names = ['bool', 'char', 'i8', 'i16', 'int', 'i64', 'byte', 'u16',
'u32', 'u64', 'f32', 'f64', 'map', 'string', 'rune']
// TODO: remove `byte` from this list when it is no longer supported
reserved_type_names = ['byte', 'bool', 'char', 'i8', 'i16', 'int', 'i64', 'u8',
'u16', 'u32', 'u64', 'f32', 'f64', 'map', 'string', 'rune']
vroot_is_deprecated_message = '@VROOT is deprecated, use @VMODROOT or @VEXEROOT instead'
)

View File

@ -38,9 +38,15 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
typ_idx := typ.idx()
if node.key_var.len > 0 && node.key_var != '_' {
c.check_valid_snake_case(node.key_var, 'variable name', node.pos)
if node.key_var in reserved_type_names {
c.error('invalid use of reserved type `$node.key_var` as key name', node.pos)
}
}
if node.val_var.len > 0 && node.val_var != '_' {
c.check_valid_snake_case(node.val_var, 'variable name', node.pos)
if node.val_var in reserved_type_names {
c.error('invalid use of reserved type `$node.val_var` as value name', node.pos)
}
}
if node.is_range {
high_type := c.expr(node.high)

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/for_in_with_reserved_type_names.vv:2:6: error: invalid use of reserved type `rune` as value name
1 | fn main() {
2 | for rune in 'runes' {
| ~~~~
3 | println(rune)
4 | }
vlib/v/checker/tests/for_in_with_reserved_type_names.vv:6:6: error: invalid use of reserved type `char` as key name
4 | }
5 |
6 | for char, c in 'runes' {
| ~~~~
7 | println(c)
8 | println(char)

View File

@ -0,0 +1,10 @@
fn main() {
for rune in 'runes' {
println(rune)
}
for char, c in 'runes' {
println(c)
println(char)
}
}

View File

@ -85,9 +85,9 @@ pub fn merge_doc_comments(comments []DocComment) string {
mut is_horizontalrule := false
line_no_spaces := line_trimmed.replace(' ', '')
for char in ['-', '=', '*', '_', '~'] {
if line_no_spaces.starts_with(char.repeat(3))
&& line_no_spaces.count(char) == line_no_spaces.len {
for ch in ['-', '=', '*', '_', '~'] {
if line_no_spaces.starts_with(ch.repeat(3))
&& line_no_spaces.count(ch) == line_no_spaces.len {
is_horizontalrule = true
break
}

View File

@ -3376,11 +3376,11 @@ fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) {
g.writeln('return s; })()')
} else {
g.write('"')
for char in text {
if char == `\n` {
for ch in text {
if ch == `\n` {
g.write('\\n')
} else {
g.write('$char.ascii_str()')
g.write('$ch.ascii_str()')
}
}
g.write('"')

View File

@ -12,8 +12,8 @@ mut:
fn test_struct_init_with_fixed_array_field() {
s := 'xoxooxxxo'
mut board := [9]Piece{}
for i, char in s {
board[i] = match char {
for i, ch in s {
board[i] = match ch {
`x` { Piece.x }
`o` { Piece.o }
else { Piece.free }

View File

@ -40,9 +40,9 @@ fn test_str_invalid_escape() {
}
fn test_str_invalid_must_be_escape() {
for char in important_escapable_chars {
for ch in important_escapable_chars {
mut sc := Scanner{
text: [u8(`"`), `t`, char, `"`]
text: [u8(`"`), `t`, ch, `"`]
}
tok := sc.scan()
assert tok.kind == .error