parser, checker: check undefined ident in if expr using generic type name (#14734)
parent
690a8422d1
commit
fcaf529228
|
@ -1,4 +1,4 @@
|
||||||
vlib/v/checker/tests/generic_type_name_in_non_generic_function.vv:3:10: error: unexpected generic variable in non-generic function `main`
|
vlib/v/checker/tests/generic_type_name_in_non_generic_function.vv:3:10: error: undefined ident: `A`
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | c := u8(`D`)
|
2 | c := u8(`D`)
|
||||||
3 | if c >= A && c <= Z {
|
3 | if c >= A && c <= Z {
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn (mut p Parser) check_expr(precedence int) ?ast.Expr {
|
||||||
p.error_with_pos("deprecated map syntax, use syntax like `{'age': 20}`",
|
p.error_with_pos("deprecated map syntax, use syntax like `{'age': 20}`",
|
||||||
p.tok.pos())
|
p.tok.pos())
|
||||||
} else {
|
} else {
|
||||||
if p.inside_if && p.is_generic_name() && p.peek_tok.kind != .dot {
|
if p.inside_comptime_if && p.is_generic_name() && p.peek_tok.kind != .dot {
|
||||||
// $if T is string {}
|
// $if T is string {}
|
||||||
p.expecting_type = true
|
p.expecting_type = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
||||||
mut prev_guard := false
|
mut prev_guard := false
|
||||||
for p.tok.kind in [.key_if, .key_else] {
|
for p.tok.kind in [.key_if, .key_else] {
|
||||||
p.inside_if = true
|
p.inside_if = true
|
||||||
|
if is_comptime {
|
||||||
|
p.inside_comptime_if = true
|
||||||
|
}
|
||||||
start_pos := if is_comptime { p.prev_tok.pos().extend(p.tok.pos()) } else { p.tok.pos() }
|
start_pos := if is_comptime { p.prev_tok.pos().extend(p.tok.pos()) } else { p.tok.pos() }
|
||||||
if p.tok.kind == .key_else {
|
if p.tok.kind == .key_else {
|
||||||
comments << p.eat_comments()
|
comments << p.eat_comments()
|
||||||
|
@ -40,6 +43,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
||||||
// else {
|
// else {
|
||||||
has_else = true
|
has_else = true
|
||||||
p.inside_if = false
|
p.inside_if = false
|
||||||
|
p.inside_comptime_if = false
|
||||||
end_pos := p.prev_tok.pos()
|
end_pos := p.prev_tok.pos()
|
||||||
body_pos := p.tok.pos()
|
body_pos := p.tok.pos()
|
||||||
p.open_scope()
|
p.open_scope()
|
||||||
|
@ -141,6 +145,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
||||||
end_pos := p.prev_tok.pos()
|
end_pos := p.prev_tok.pos()
|
||||||
body_pos := p.tok.pos()
|
body_pos := p.tok.pos()
|
||||||
p.inside_if = false
|
p.inside_if = false
|
||||||
|
p.inside_comptime_if = false
|
||||||
p.open_scope()
|
p.open_scope()
|
||||||
stmts := p.parse_block_no_scope(false)
|
stmts := p.parse_block_no_scope(false)
|
||||||
branches << ast.IfBranch{
|
branches << ast.IfBranch{
|
||||||
|
|
|
@ -35,6 +35,7 @@ mut:
|
||||||
inside_vlib_file bool // true for all vlib/ files
|
inside_vlib_file bool // true for all vlib/ files
|
||||||
inside_test_file bool // when inside _test.v or _test.vv file
|
inside_test_file bool // when inside _test.v or _test.vv file
|
||||||
inside_if bool
|
inside_if bool
|
||||||
|
inside_comptime_if bool
|
||||||
inside_if_expr bool
|
inside_if_expr bool
|
||||||
inside_if_cond bool
|
inside_if_cond bool
|
||||||
inside_ct_if_expr bool
|
inside_ct_if_expr bool
|
||||||
|
@ -2419,7 +2420,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
&& (!p.inside_for || p.inside_select) && !known_var {
|
&& (!p.inside_for || p.inside_select) && !known_var {
|
||||||
return p.struct_init(p.mod + '.' + p.tok.lit, false) // short_syntax: false
|
return p.struct_init(p.mod + '.' + p.tok.lit, false) // short_syntax: false
|
||||||
} else if p.peek_tok.kind == .lcbr
|
} else if p.peek_tok.kind == .lcbr
|
||||||
&& ((p.inside_if && lit0_is_capital && !known_var && language == .v)
|
&& ((p.inside_if && lit0_is_capital && p.tok.lit.len > 1 && !known_var && language == .v)
|
||||||
|| (p.inside_match_case && p.tok.kind == .name && p.peek_tok.pos - p.tok.pos == p.tok.len)) {
|
|| (p.inside_match_case && p.tok.kind == .name && p.peek_tok.pos - p.tok.pos == p.tok.len)) {
|
||||||
// `if a == Foo{} {...}` or `match foo { Foo{} {...} }`
|
// `if a == Foo{} {...}` or `match foo { Foo{} {...} }`
|
||||||
return p.struct_init(p.mod + '.' + p.tok.lit, false)
|
return p.struct_init(p.mod + '.' + p.tok.lit, false)
|
||||||
|
|
Loading…
Reference in New Issue