diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c54a6580b4..de5aed918d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -723,6 +723,7 @@ pub: stmts []Stmt kind CompForKind pos token.Position + typ_pos token.Position pub mut: // expr Expr typ table.Type diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d0c3a19a39..b26e9a5fef 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 { diff --git a/vlib/v/checker/tests/comptime_for.out b/vlib/v/checker/tests/comptime_for.out new file mode 100644 index 0000000000..29e3def2ac --- /dev/null +++ b/vlib/v/checker/tests/comptime_for.out @@ -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 | } diff --git a/vlib/v/checker/tests/comptime_for.vv b/vlib/v/checker/tests/comptime_for.vv new file mode 100644 index 0000000000..36ed340426 --- /dev/null +++ b/vlib/v/checker/tests/comptime_for.vv @@ -0,0 +1,4 @@ +fn unknown() { + $for m in Huh.methods {} + $for f in Huh.fields {} +} diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index cd0823a167..b28df5fee7 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -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()) } }