Skip to content

Commit 0b3412c

Browse files
authored
checker: check that type exists in TypeDecl
1 parent 541b058 commit 0b3412c

File tree

7 files changed

+90
-21
lines changed

7 files changed

+90
-21
lines changed

vlib/v/checker/checker.v

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,40 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
155155
return has_main_fn
156156
}
157157

158+
pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
159+
match node {
160+
ast.AliasTypeDecl {
161+
typ_sym := c.table.get_type_symbol(it.parent_type)
162+
if typ_sym.kind == .placeholder {
163+
c.error("type `$typ_sym.name` doesn't exist", it.pos)
164+
}
165+
}
166+
ast.FnTypeDecl {
167+
typ_sym := c.table.get_type_symbol(it.typ)
168+
fn_typ_info := typ_sym.info as table.FnType
169+
fn_info := fn_typ_info.func
170+
ret_sym := c.table.get_type_symbol(fn_info.return_type)
171+
if ret_sym.kind == .placeholder {
172+
c.error("type `$ret_sym.name` doesn't exist", it.pos)
173+
}
174+
for arg in fn_info.args {
175+
arg_sym := c.table.get_type_symbol(arg.typ)
176+
if arg_sym.kind == .placeholder {
177+
c.error("type `$arg_sym.name` doesn't exist", it.pos)
178+
}
179+
}
180+
}
181+
ast.SumTypeDecl {
182+
for typ in it.sub_types {
183+
typ_sym := c.table.get_type_symbol(typ)
184+
if typ_sym.kind == .placeholder {
185+
c.error("type `$typ_sym.name` doesn't exist", it.pos)
186+
}
187+
}
188+
}
189+
}
190+
}
191+
158192
pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
159193
splitted_full_name := decl.name.split('.')
160194
is_builtin := splitted_full_name[0] == 'builtin'
@@ -1088,6 +1122,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
10881122
it.pos)
10891123
}
10901124
}
1125+
// ast.Attr {}
10911126
ast.AssignStmt {
10921127
c.assign_stmt(mut it)
10931128
}
@@ -1099,7 +1134,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
10991134
c.error('$it.tok.lit statement not within a loop', it.tok.position())
11001135
}
11011136
}
1102-
// ast.Attr {}
11031137
ast.CompIf {
11041138
// c.expr(it.cond)
11051139
c.stmts(it.stmts)
@@ -1170,17 +1204,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
11701204
}
11711205
c.returns = false
11721206
}
1173-
ast.ForStmt {
1174-
c.in_for_count++
1175-
typ := c.expr(it.cond)
1176-
if !it.is_inf && typ.idx() != table.bool_type_idx {
1177-
c.error('non-bool used as for condition', it.pos)
1178-
}
1179-
// TODO: update loop var type
1180-
// how does this work currenly?
1181-
c.stmts(it.stmts)
1182-
c.in_for_count--
1183-
}
11841207
ast.ForCStmt {
11851208
c.in_for_count++
11861209
c.stmt(it.init)
@@ -1230,8 +1253,20 @@ fn (mut c Checker) stmt(node ast.Stmt) {
12301253
c.stmts(it.stmts)
12311254
c.in_for_count--
12321255
}
1256+
ast.ForStmt {
1257+
c.in_for_count++
1258+
typ := c.expr(it.cond)
1259+
if !it.is_inf && typ.idx() != table.bool_type_idx {
1260+
c.error('non-bool used as for condition', it.pos)
1261+
}
1262+
// TODO: update loop var type
1263+
// how does this work currenly?
1264+
c.stmts(it.stmts)
1265+
c.in_for_count--
1266+
}
1267+
// ast.GlobalDecl {}
12331268
ast.GoStmt {
1234-
if !is_call_expr(it.call_expr) {
1269+
if !(it.call_expr is ast.CallExpr) {
12351270
c.error('expression in `go` must be a function call', it.call_expr.position())
12361271
}
12371272
c.expr(it.call_expr)
@@ -1242,14 +1277,16 @@ fn (mut c Checker) stmt(node ast.Stmt) {
12421277
c.mod = it.name
12431278
c.is_builtin_mod = it.name == 'builtin'
12441279
}
1245-
// ast.GlobalDecl {}
12461280
ast.Return {
12471281
c.returns = true
12481282
c.return_stmt(mut it)
12491283
}
12501284
ast.StructDecl {
12511285
c.struct_decl(it)
12521286
}
1287+
ast.TypeDecl {
1288+
c.type_decl(it)
1289+
}
12531290
ast.UnsafeStmt {
12541291
c.stmts(it.stmts)
12551292
}
@@ -1260,13 +1297,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
12601297
}
12611298
}
12621299

1263-
fn is_call_expr(expr ast.Expr) bool {
1264-
return match expr {
1265-
ast.CallExpr { true }
1266-
else { false }
1267-
}
1268-
}
1269-
12701300
fn (mut c Checker) stmts(stmts []ast.Stmt) {
12711301
c.expected_type = table.void_type
12721302
for stmt in stmts {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
vlib/v/checker/tests/inout/alias_type_exists.v:1:1: error: type `Bird` doesn't exist
2+
1| type Pigeon = Bird
3+
~~~~~~~~~~~
4+
2|
5+
3| fn main() {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type Pigeon = Bird
2+
3+
fn main() {
4+
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
vlib/v/checker/tests/inout/fn_type_exists.v:1:1: error: type `Pants` doesn't exist
2+
1| type PantsCreator = fn (a Shirt) Pants
3+
~~~~~~~~~~~~~~~~~
4+
2|
5+
3| type PantsConsumer = fn (p Pants)
6+
vlib/v/checker/tests/inout/fn_type_exists.v:3:1: error: type `Pants` doesn't exist
7+
1| type PantsCreator = fn (a Shirt) Pants
8+
2|
9+
3| type PantsConsumer = fn (p Pants)
10+
~~~~~~~~~~~~~~~~~~
11+
4|
12+
5| fn main() {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type PantsCreator = fn (a Shirt) Pants
2+
3+
type PantsConsumer = fn (p Pants)
4+
5+
fn main() {
6+
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
vlib/v/checker/tests/inout/sum_type_exists.v:1:1: error: type `Nope` doesn't exist
2+
1| type Miscellaneous = Nope | Inexistant | int
3+
~~~~~~~~~~~~~~~~~~
4+
2|
5+
3| fn main() {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type Miscellaneous = Nope | Inexistant | int
2+
3+
fn main() {
4+
5+
}

0 commit comments

Comments
 (0)