checker: check types with $for/$if introspection (#8984)
parent
1a8ff9d7dd
commit
4ad95cfeaf
|
@ -3109,11 +3109,10 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
c.branch_stmt(node)
|
||||
}
|
||||
ast.CompFor {
|
||||
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)
|
||||
}
|
||||
typ := c.unwrap_generic(node.typ)
|
||||
sym := c.table.get_type_symbol(typ)
|
||||
if sym.kind == .placeholder || typ.has_flag(.generic) {
|
||||
c.error('unknown type `$sym.name`', node.typ_pos)
|
||||
}
|
||||
c.stmts(node.stmts)
|
||||
}
|
||||
|
@ -4806,7 +4805,11 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
|
|||
if branch.cond is ast.InfixExpr {
|
||||
if branch.cond.op == .key_is {
|
||||
left := branch.cond.left
|
||||
got_type := (branch.cond.right as ast.Type).typ
|
||||
got_type := c.unwrap_generic((branch.cond.right as ast.Type).typ)
|
||||
sym := c.table.get_type_symbol(got_type)
|
||||
if sym.kind == .placeholder || got_type.has_flag(.generic) {
|
||||
c.error('unknown type `$sym.name`', branch.cond.right.position())
|
||||
}
|
||||
if left is ast.SelectorExpr {
|
||||
comptime_field_name = left.expr.str()
|
||||
c.comptime_fields_type[comptime_field_name] = got_type
|
||||
|
|
|
@ -12,7 +12,7 @@ vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:12:12: error: unkno
|
|||
| ~~
|
||||
13 | }
|
||||
14 | }
|
||||
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:15:10: error: compile time field access can only be used when iterating over `T.fields`
|
||||
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:15:10: error: undefined ident: `f`
|
||||
13 | }
|
||||
14 | }
|
||||
15 | _ = t.$(f.name)
|
||||
|
|
|
@ -3,10 +3,53 @@ vlib/v/checker/tests/comptime_for.vv:2:12: error: unknown type `Huh`
|
|||
2 | $for m in Huh.methods {}
|
||||
| ~~~
|
||||
3 | $for f in Huh.fields {}
|
||||
4 | }
|
||||
4 | $for f in T.fields {
|
||||
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 | }
|
||||
4 | $for f in T.fields {
|
||||
5 | $if f.typ is Huh {}
|
||||
vlib/v/checker/tests/comptime_for.vv:4:12: error: unknown type `T`
|
||||
2 | $for m in Huh.methods {}
|
||||
3 | $for f in Huh.fields {}
|
||||
4 | $for f in T.fields {
|
||||
| ^
|
||||
5 | $if f.typ is Huh {}
|
||||
6 | $if f.typ is T {}
|
||||
vlib/v/checker/tests/comptime_for.vv:5:16: error: unknown type `Huh`
|
||||
3 | $for f in Huh.fields {}
|
||||
4 | $for f in T.fields {
|
||||
5 | $if f.typ is Huh {}
|
||||
| ~~~
|
||||
6 | $if f.typ is T {}
|
||||
7 | }
|
||||
vlib/v/checker/tests/comptime_for.vv:6:16: error: unknown type `T`
|
||||
4 | $for f in T.fields {
|
||||
5 | $if f.typ is Huh {}
|
||||
6 | $if f.typ is T {}
|
||||
| ^
|
||||
7 | }
|
||||
8 | _ = m
|
||||
vlib/v/checker/tests/comptime_for.vv:8:6: error: undefined ident: `m`
|
||||
6 | $if f.typ is T {}
|
||||
7 | }
|
||||
8 | _ = m
|
||||
| ^
|
||||
9 | }
|
||||
10 |
|
||||
vlib/v/checker/tests/comptime_for.vv:14:16: error: unknown type `U`
|
||||
12 | $for f in T.fields {
|
||||
13 | $if f.typ is T {}
|
||||
14 | $if f.typ is U {}
|
||||
| ^
|
||||
15 | }
|
||||
16 | _ = f
|
||||
vlib/v/checker/tests/comptime_for.vv:16:6: error: undefined ident: `f`
|
||||
14 | $if f.typ is U {}
|
||||
15 | }
|
||||
16 | _ = f
|
||||
| ^
|
||||
17 | }
|
||||
18 |
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
fn unknown() {
|
||||
$for m in Huh.methods {}
|
||||
$for f in Huh.fields {}
|
||||
$for f in T.fields {
|
||||
$if f.typ is Huh {}
|
||||
$if f.typ is T {}
|
||||
}
|
||||
_ = m
|
||||
}
|
||||
|
||||
fn gf<T>() {
|
||||
$for f in T.fields {
|
||||
$if f.typ is T {}
|
||||
$if f.typ is U {}
|
||||
}
|
||||
_ = f
|
||||
}
|
||||
|
||||
struct S1 {
|
||||
i int
|
||||
}
|
||||
|
||||
gf<S1>()
|
||||
|
|
|
@ -227,6 +227,7 @@ fn (mut p Parser) comp_for() ast.CompFor {
|
|||
p.check(.dot)
|
||||
for_val := p.check_name()
|
||||
mut kind := ast.CompForKind.methods
|
||||
p.open_scope()
|
||||
if for_val == 'methods' {
|
||||
p.scope.register(ast.Var{
|
||||
name: val_var
|
||||
|
@ -247,6 +248,7 @@ fn (mut p Parser) comp_for() ast.CompFor {
|
|||
}
|
||||
spos := p.tok.position()
|
||||
stmts := p.parse_block()
|
||||
p.close_scope()
|
||||
return ast.CompFor{
|
||||
val_var: val_var
|
||||
stmts: stmts
|
||||
|
|
Loading…
Reference in New Issue