Skip to content

Commit b06811c

Browse files
authored
checker: clean up ensure_type_exists() (#18860)
1 parent 4413808 commit b06811c

10 files changed

Lines changed: 115 additions & 92 deletions

File tree

vlib/v/checker/checker.v

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,9 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
459459
if c.file.mod.name != 'builtin' {
460460
c.check_valid_pascal_case(node.name, 'type alias', node.pos)
461461
}
462-
c.ensure_type_exists(node.parent_type, node.type_pos) or { return }
462+
if !c.ensure_type_exists(node.parent_type, node.type_pos) {
463+
return
464+
}
463465
mut parent_typ_sym := c.table.sym(node.parent_type)
464466
if node.parent_type.has_flag(.result) {
465467
c.add_error_detail('Result types cannot be stored and have to be unwrapped immediately')
@@ -551,13 +553,15 @@ fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) {
551553
typ_sym := c.table.sym(node.typ)
552554
fn_typ_info := typ_sym.info as ast.FnType
553555
fn_info := fn_typ_info.func
554-
c.ensure_type_exists(fn_info.return_type, fn_info.return_type_pos) or {}
556+
c.ensure_type_exists(fn_info.return_type, fn_info.return_type_pos)
555557
ret_sym := c.table.sym(fn_info.return_type)
556558
if ret_sym.kind == .placeholder {
557559
c.error('unknown type `${ret_sym.name}`', fn_info.return_type_pos)
558560
}
559561
for arg in fn_info.params {
560-
c.ensure_type_exists(arg.typ, arg.type_pos) or { return }
562+
if !c.ensure_type_exists(arg.typ, arg.type_pos) {
563+
return
564+
}
561565
arg_sym := c.table.sym(arg.typ)
562566
if arg_sym.kind == .placeholder {
563567
c.error('unknown type `${arg_sym.name}`', arg.type_pos)
@@ -569,7 +573,7 @@ fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
569573
c.check_valid_pascal_case(node.name, 'sum type', node.pos)
570574
mut names_used := []string{}
571575
for variant in node.variants {
572-
c.ensure_type_exists(variant.typ, variant.pos) or {}
576+
c.ensure_type_exists(variant.typ, variant.pos)
573577
sym := c.table.sym(variant.typ)
574578
if variant.typ.is_ptr() {
575579
variant_name := sym.name.all_after_last('.')
@@ -761,7 +765,9 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) {
761765
return '', expr.pos
762766
}
763767
// retrieve ast.Field
764-
c.ensure_type_exists(expr.expr_type, expr.pos) or { return '', expr.pos }
768+
if !c.ensure_type_exists(expr.expr_type, expr.pos) {
769+
return '', expr.pos
770+
}
765771
mut typ_sym := c.table.final_sym(c.unwrap_generic(expr.expr_type))
766772
match typ_sym.kind {
767773
.struct_ {
@@ -2492,14 +2498,14 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
24922498
expr_type_sym := c.table.sym(node.expr_type)
24932499
type_sym := c.table.sym(node.typ)
24942500
if expr_type_sym.kind == .sum_type {
2495-
c.ensure_type_exists(node.typ, node.pos) or {}
2501+
c.ensure_type_exists(node.typ, node.pos)
24962502
if !c.table.sumtype_has_variant(node.expr_type, node.typ, true) {
24972503
addr := '&'.repeat(node.typ.nr_muls())
24982504
c.error('cannot cast `${expr_type_sym.name}` to `${addr}${type_sym.name}`',
24992505
node.pos)
25002506
}
25012507
} else if expr_type_sym.kind == .interface_ && type_sym.kind == .interface_ {
2502-
c.ensure_type_exists(node.typ, node.pos) or {}
2508+
c.ensure_type_exists(node.typ, node.pos)
25032509
} else if node.expr_type.clear_flag(.option) != node.typ.clear_flag(.option) {
25042510
mut s := 'cannot cast non-sum type `${expr_type_sym.name}` using `as`'
25052511
if type_sym.kind == .sum_type {
@@ -2865,7 +2871,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
28652871
}
28662872

28672873
if to_sym.language != .c {
2868-
c.ensure_type_exists(to_type, node.pos) or {}
2874+
c.ensure_type_exists(to_type, node.pos)
28692875

28702876
if to_sym.info is ast.Alias && to_sym.info.parent_type.has_flag(.option)
28712877
&& !to_type.has_flag(.option) {
@@ -4548,10 +4554,10 @@ fn (mut c Checker) trace(fbase string, message string) {
45484554
}
45494555
}
45504556

4551-
fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos token.Pos) ? {
4557+
fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos token.Pos) bool {
45524558
if typ == 0 {
45534559
c.error('unknown type', pos)
4554-
return none
4560+
return false
45554561
}
45564562

45574563
c.ensure_generic_type_level++
@@ -4561,7 +4567,7 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke
45614567
if c.ensure_generic_type_level > checker.expr_level_cutoff_limit {
45624568
c.error('checker: too many levels of Checker.ensure_generic_type_specify_type_names calls: ${c.ensure_generic_type_level} ',
45634569
pos)
4564-
return none
4570+
return false
45654571
}
45664572

45674573
sym := c.table.final_sym(typ)
@@ -4574,66 +4580,82 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke
45744580
match sym.kind {
45754581
.function {
45764582
fn_info := sym.info as ast.FnType
4577-
c.ensure_generic_type_specify_type_names(fn_info.func.return_type, fn_info.func.return_type_pos)?
4583+
if !c.ensure_generic_type_specify_type_names(fn_info.func.return_type, fn_info.func.return_type_pos) {
4584+
return false
4585+
}
45784586
for param in fn_info.func.params {
4579-
c.ensure_generic_type_specify_type_names(param.typ, param.type_pos)?
4587+
if !c.ensure_generic_type_specify_type_names(param.typ, param.type_pos) {
4588+
return false
4589+
}
45804590
}
45814591
}
45824592
.array {
4583-
c.ensure_generic_type_specify_type_names((sym.info as ast.Array).elem_type,
4584-
pos)?
4593+
if !c.ensure_generic_type_specify_type_names((sym.info as ast.Array).elem_type,
4594+
pos) {
4595+
return false
4596+
}
45854597
}
45864598
.array_fixed {
4587-
c.ensure_generic_type_specify_type_names((sym.info as ast.ArrayFixed).elem_type,
4588-
pos)?
4599+
if !c.ensure_generic_type_specify_type_names((sym.info as ast.ArrayFixed).elem_type,
4600+
pos) {
4601+
return false
4602+
}
45894603
}
45904604
.map {
45914605
info := sym.info as ast.Map
4592-
c.ensure_generic_type_specify_type_names(info.key_type, pos)?
4593-
c.ensure_generic_type_specify_type_names(info.value_type, pos)?
4606+
if !c.ensure_generic_type_specify_type_names(info.key_type, pos) {
4607+
return false
4608+
}
4609+
if !c.ensure_generic_type_specify_type_names(info.value_type, pos) {
4610+
return false
4611+
}
45944612
}
45954613
.sum_type {
45964614
info := sym.info as ast.SumType
45974615
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
45984616
c.error('`${sym.name}` type is generic sumtype, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
45994617
pos)
4618+
return false
46004619
}
46014620
}
46024621
.struct_ {
46034622
info := sym.info as ast.Struct
46044623
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
46054624
c.error('`${sym.name}` type is generic struct, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
46064625
pos)
4626+
return false
46074627
}
46084628
}
46094629
.interface_ {
46104630
info := sym.info as ast.Interface
46114631
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
46124632
c.error('`${sym.name}` type is generic interface, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
46134633
pos)
4634+
return false
46144635
}
46154636
}
46164637
else {}
46174638
}
4639+
return true
46184640
}
46194641

4620-
fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
4642+
fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) bool {
46214643
if typ == 0 {
46224644
c.error('unknown type', pos)
4623-
return
4645+
return false
46244646
}
46254647
sym := c.table.sym(typ)
46264648
if !c.is_builtin_mod && sym.kind == .struct_ && !sym.is_pub && sym.mod != c.mod {
46274649
c.error('struct `${sym.name}` was declared as private to module `${sym.mod}`, so it can not be used inside module `${c.mod}`',
46284650
pos)
4629-
return
4651+
return false
46304652
}
46314653
match sym.kind {
46324654
.placeholder {
46334655
if sym.language == .v && !sym.name.starts_with('C.') {
46344656
c.error(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `${sym.name}`'),
46354657
pos)
4636-
return
4658+
return false
46374659
}
46384660
}
46394661
.int_literal, .float_literal {
@@ -4646,35 +4668,50 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
46464668
'unknown type `${sym.name}`.\nDid you mean `f64`?'
46474669
}
46484670
c.error(msg, pos)
4649-
return
4671+
return false
46504672
}
46514673
}
46524674
.function {
46534675
fn_info := sym.info as ast.FnType
4654-
c.ensure_type_exists(fn_info.func.return_type, fn_info.func.return_type_pos)?
4676+
if !c.ensure_type_exists(fn_info.func.return_type, fn_info.func.return_type_pos) {
4677+
return false
4678+
}
46554679
for param in fn_info.func.params {
4656-
c.ensure_type_exists(param.typ, param.type_pos)?
4680+
if !c.ensure_type_exists(param.typ, param.type_pos) {
4681+
return false
4682+
}
46574683
}
46584684
}
46594685
.array {
4660-
c.ensure_type_exists((sym.info as ast.Array).elem_type, pos)?
4686+
if !c.ensure_type_exists((sym.info as ast.Array).elem_type, pos) {
4687+
return false
4688+
}
46614689
}
46624690
.array_fixed {
4663-
c.ensure_type_exists((sym.info as ast.ArrayFixed).elem_type, pos)?
4691+
if !c.ensure_type_exists((sym.info as ast.ArrayFixed).elem_type, pos) {
4692+
return false
4693+
}
46644694
}
46654695
.map {
46664696
info := sym.info as ast.Map
4667-
c.ensure_type_exists(info.key_type, pos)?
4668-
c.ensure_type_exists(info.value_type, pos)?
4697+
if !c.ensure_type_exists(info.key_type, pos) {
4698+
return false
4699+
}
4700+
if !c.ensure_type_exists(info.value_type, pos) {
4701+
return false
4702+
}
46694703
}
46704704
.sum_type {
46714705
info := sym.info as ast.SumType
46724706
for concrete_typ in info.concrete_types {
4673-
c.ensure_type_exists(concrete_typ, pos)?
4707+
if !c.ensure_type_exists(concrete_typ, pos) {
4708+
return false
4709+
}
46744710
}
46754711
}
46764712
else {}
46774713
}
4714+
return true
46784715
}
46794716

46804717
// return true if a violation of a shared variable access rule is detected

vlib/v/checker/containers.v

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
9292
c.error('cannot use unwrapped Option as capacity', node.cap_expr.pos())
9393
}
9494
}
95-
c.ensure_type_exists(node.elem_type, node.elem_type_pos) or {}
95+
c.ensure_type_exists(node.elem_type, node.elem_type_pos)
9696
if node.typ.has_flag(.generic) && c.table.cur_fn != unsafe { nil }
9797
&& c.table.cur_fn.generic_names.len == 0 {
9898
c.error('generic struct cannot be used in non-generic function', node.pos)
@@ -108,7 +108,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
108108

109109
if node.is_fixed {
110110
c.ensure_sumtype_array_has_default_value(node)
111-
c.ensure_type_exists(node.elem_type, node.elem_type_pos) or {}
111+
c.ensure_type_exists(node.elem_type, node.elem_type_pos)
112112
if node.elem_type.is_any_kind_of_pointer() && !c.inside_unsafe && !c.is_builtin_mod {
113113
c.warn('fixed arrays of references need to be initialized right away (unless inside `unsafe`)',
114114
node.pos)
@@ -367,8 +367,8 @@ fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
367367
}
368368
}
369369
}
370-
c.ensure_type_exists(info.key_type, node.pos) or {}
371-
c.ensure_type_exists(info.value_type, node.pos) or {}
370+
c.ensure_type_exists(info.key_type, node.pos)
371+
c.ensure_type_exists(info.value_type, node.pos)
372372
node.key_type = info.key_type
373373
node.value_type = info.value_type
374374
return node.typ

vlib/v/checker/fn.v

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,9 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
209209
if node.language == .v {
210210
// Make sure all types are valid
211211
for mut param in node.params {
212-
c.ensure_type_exists(param.typ, param.type_pos) or { return }
212+
if !c.ensure_type_exists(param.typ, param.type_pos) {
213+
return
214+
}
213215
if reserved_type_names_chk.matches(param.name) {
214216
c.error('invalid use of reserved type `${param.name}` as a parameter name',
215217
param.pos)
@@ -277,7 +279,9 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
277279
c.error('top level declaration cannot shadow builtin type', node.pos)
278280
}
279281
if node.return_type != ast.Type(0) {
280-
c.ensure_type_exists(node.return_type, node.return_type_pos) or { return }
282+
if !c.ensure_type_exists(node.return_type, node.return_type_pos) {
283+
return
284+
}
281285
if node.language == .v && node.is_method && node.name == 'str' {
282286
if node.return_type != ast.string_type {
283287
c.error('.str() methods should return `string`', node.pos)
@@ -981,7 +985,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
981985
node.concrete_list_pos)
982986
}
983987
for concrete_type in node.concrete_types {
984-
c.ensure_type_exists(concrete_type, node.concrete_list_pos) or {}
988+
c.ensure_type_exists(concrete_type, node.concrete_list_pos)
985989
}
986990
if func.generic_names.len > 0 && node.args.len == 0 && node.concrete_types.len == 0 {
987991
c.error('no argument generic function must add concrete types, e.g. foo[int]()',
@@ -1877,7 +1881,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
18771881
node.concrete_list_pos)
18781882
}
18791883
for concrete_type in node.concrete_types {
1880-
c.ensure_type_exists(concrete_type, node.concrete_list_pos) or {}
1884+
c.ensure_type_exists(concrete_type, node.concrete_list_pos)
18811885
}
18821886
if method.return_type == ast.void_type && method.is_conditional
18831887
&& method.ctdefine_idx != ast.invalid_type_idx {

vlib/v/checker/infix.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
195195
} else {
196196
if mut node.right is ast.ArrayInit {
197197
for i, typ in node.right.expr_types {
198-
c.ensure_type_exists(typ, node.right.exprs[i].pos()) or {}
198+
c.ensure_type_exists(typ, node.right.exprs[i].pos())
199199
}
200200
}
201201
}

vlib/v/checker/interface.v

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
118118
if node.language == .v {
119119
c.check_valid_snake_case(method.name, 'method name', method.pos)
120120
}
121-
c.ensure_type_exists(method.return_type, method.return_type_pos) or { return }
121+
if !c.ensure_type_exists(method.return_type, method.return_type_pos) {
122+
continue
123+
}
122124
if is_js {
123125
mtyp := c.table.sym(method.return_type)
124126
if !mtyp.is_js_compatible() {
@@ -147,7 +149,9 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
147149
if param.typ.has_flag(.generic) {
148150
has_generic_types = true
149151
}
150-
c.ensure_type_exists(param.typ, param.pos) or { return }
152+
if !c.ensure_type_exists(param.typ, param.pos) {
153+
continue
154+
}
151155
if reserved_type_names_chk.matches(param.name) {
152156
c.error('invalid use of reserved type `${param.name}` as a parameter name',
153157
param.pos)
@@ -190,7 +194,9 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
190194
if node.language == .v {
191195
c.check_valid_snake_case(field.name, 'field name', field.pos)
192196
}
193-
c.ensure_type_exists(field.typ, field.pos) or { return }
197+
if !c.ensure_type_exists(field.typ, field.pos) {
198+
continue
199+
}
194200
if field.typ.has_flag(.generic) {
195201
has_generic_types = true
196202
}

vlib/v/checker/match.v

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
2626
|| (node.cond is ast.SelectorExpr && node.cond.is_mut) {
2727
c.fail_if_immutable(mut node.cond)
2828
}
29-
c.ensure_type_exists(node.cond_type, node.pos) or { return ast.void_type }
29+
if !c.ensure_type_exists(node.cond_type, node.pos) {
30+
return ast.void_type
31+
}
3032
c.check_expr_opt_call(node.cond, cond_type)
3133
cond_type_sym := c.table.sym(cond_type)
3234
cond_is_option := cond_type.has_flag(.option)

vlib/v/checker/orm.v

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
2626

2727
// To avoid panics while working with `table_expr`,
2828
// it is necessary to check if its type exists.
29-
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
29+
if !c.ensure_type_exists(node.table_expr.typ, node.pos) {
30+
return ast.void_type
31+
}
3032
table_sym := c.table.sym(node.table_expr.typ)
3133

3234
if !c.check_orm_table_expr_type(node.table_expr) {
@@ -175,7 +177,9 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
175177

176178
// To avoid panics while working with `table_expr`,
177179
// it is necessary to check if its type exists.
178-
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
180+
if !c.ensure_type_exists(node.table_expr.typ, node.pos) {
181+
return ast.void_type
182+
}
179183
table_sym := c.table.sym(node.table_expr.typ)
180184

181185
if !c.check_orm_table_expr_type(node.table_expr) {

0 commit comments

Comments
 (0)