checker: detect unknown type to iterate with $for (#8971)

pull/8980/head
Nick Treleaven 2021-02-26 06:28:19 +00:00 committed by GitHub
parent 3a082621c9
commit 59d4d0ef1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 2 deletions

View File

@ -723,6 +723,7 @@ pub:
stmts []Stmt
kind CompForKind
pos token.Position
typ_pos token.Position
pub mut:
// expr Expr
typ table.Type

View File

@ -3109,7 +3109,12 @@ fn (mut c Checker) stmt(node ast.Stmt) {
c.branch_stmt(node)
}
ast.CompFor {
// node.typ = c.expr(node.expr)
if node.typ > table.void_type {
sym := c.table.get_type_symbol(node.typ)
if sym.kind == .placeholder {
c.error('unknown type `$sym.name`', node.typ_pos)
}
}
c.stmts(node.stmts)
}
ast.ConstDecl {

View File

@ -0,0 +1,12 @@
vlib/v/checker/tests/comptime_for.vv:2:12: error: unknown type `Huh`
1 | fn unknown() {
2 | $for m in Huh.methods {}
| ~~~
3 | $for f in Huh.fields {}
4 | }
vlib/v/checker/tests/comptime_for.vv:3:12: error: unknown type `Huh`
1 | fn unknown() {
2 | $for m in Huh.methods {}
3 | $for f in Huh.fields {}
| ~~~
4 | }

View File

@ -0,0 +1,4 @@
fn unknown() {
$for m in Huh.methods {}
$for f in Huh.fields {}
}

View File

@ -217,10 +217,13 @@ fn (mut p Parser) comp_for() ast.CompFor {
// $for field in App(fields) {
p.next()
p.check(.key_for)
var_pos := p.tok.position()
val_var := p.check_name()
p.check(.key_in)
mut typ_pos := p.tok.position()
lang := p.parse_language()
typ := p.parse_any_type(lang, false, false)
typ_pos = typ_pos.extend(p.prev_tok.position())
p.check(.dot)
for_val := p.check_name()
mut kind := ast.CompForKind.methods
@ -228,15 +231,18 @@ fn (mut p Parser) comp_for() ast.CompFor {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FunctionData')
pos: var_pos
})
} else if for_val == 'fields' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FieldData')
pos: var_pos
})
kind = .fields
} else {
p.error('unknown kind `$for_val`, available are: `methods` or `fields`')
p.error_with_pos('unknown kind `$for_val`, available are: `methods` or `fields`',
p.prev_tok.position())
return ast.CompFor{}
}
spos := p.tok.position()
@ -246,6 +252,7 @@ fn (mut p Parser) comp_for() ast.CompFor {
stmts: stmts
kind: kind
typ: typ
typ_pos: typ_pos
pos: spos.extend(p.tok.position())
}
}