Skip to content

Commit 6aa81fa

Browse files
authored
parser: disallow untyped chan used as a fn parameter type (fix #25818) (#25854)
1 parent 8241859 commit 6aa81fa

15 files changed

+58
-0
lines changed

vlib/v/parser/fn.v

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,10 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool, bool) {
10471047
// error is added in parse_type
10481048
return []ast.Param{}, false, false, false
10491049
}
1050+
if param_type == ast.chan_type {
1051+
p.chan_type_error()
1052+
return []ast.Param{}, false, false, false
1053+
}
10501054
if is_mut {
10511055
if !param_type.has_flag(.generic) {
10521056
if is_variadic {
@@ -1177,6 +1181,10 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool, bool) {
11771181
// error is added in parse_type
11781182
return []ast.Param{}, false, false, false
11791183
}
1184+
if typ == ast.chan_type {
1185+
p.chan_type_error()
1186+
return []ast.Param{}, false, false, false
1187+
}
11801188
if is_mut {
11811189
if !typ.has_flag(.generic) {
11821190
if is_variadic {

vlib/v/parser/messages.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,8 @@ fn (mut p Parser) unexpected_with_pos(pos token.Pos, params ParamsForUnexpected)
220220
}
221221
return p.error_with_pos(msg, pos)
222222
}
223+
224+
fn (mut p Parser) chan_type_error() {
225+
p.error_with_pos('`chan` has no type specified. Use `chan Type` instead of `chan`',
226+
p.prev_tok.pos())
227+
}

vlib/v/parser/parse_type.v

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ fn (mut p Parser) parse_array_type(expecting token.Kind, is_option bool) ast.Typ
124124
// error is handled by parse_type
125125
return 0
126126
}
127+
if elem_type == ast.chan_type {
128+
p.chan_type_error()
129+
return 0
130+
}
127131
// has been explicitly resolved, but size is 0
128132
if fixed_size <= 0 && !size_unresolved {
129133
p.error_with_pos('fixed size cannot be zero or negative', size_expr.pos())
@@ -142,6 +146,10 @@ fn (mut p Parser) parse_array_type(expecting token.Kind, is_option bool) ast.Typ
142146
// error is set in parse_type
143147
return 0
144148
}
149+
if elem_type == ast.chan_type {
150+
p.chan_type_error()
151+
return 0
152+
}
145153
if elem_type.idx() == ast.thread_type_idx {
146154
p.register_auto_import('sync.threads')
147155
}
@@ -201,6 +209,10 @@ fn (mut p Parser) parse_map_type() ast.Type {
201209
// error is reported in parse_type
202210
return 0
203211
}
212+
if value_type == ast.chan_type {
213+
p.chan_type_error()
214+
return 0
215+
}
204216
if value_type.idx() == ast.void_type_idx {
205217
p.error_with_pos('map value type is missing: use `map[KeyType]ValueType`', p.tok.pos())
206218
return 0
@@ -293,6 +305,10 @@ fn (mut p Parser) parse_multi_return_type() ast.Type {
293305
if mr_type.idx() == 0 {
294306
break
295307
}
308+
if mr_type == ast.chan_type {
309+
p.chan_type_error()
310+
break
311+
}
296312
if mr_type.has_flag(.generic) {
297313
has_generic = true
298314
}
@@ -568,6 +584,11 @@ fn (mut p Parser) parse_type() ast.Type {
568584
// error is set in parse_type
569585
return 0
570586
}
587+
// !p.inside_receiver_param check can be removed once (ch chan) functions are removed
588+
if typ == ast.chan_type && !p.inside_receiver_param {
589+
p.chan_type_error()
590+
return 0
591+
}
571592
if typ == ast.void_type {
572593
p.error_with_pos('use `?` instead of `?void`', pos)
573594
return 0
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vlib/v/parser/tests/chan_no_type_array_fn_arg_err.vv:1:24: error: `chan` has no type specified. Use `chan Type` instead of `chan`
2+
1 | fn takes_array(chans []chan) {}
3+
| ~~~~
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn takes_array(chans []chan) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vlib/v/parser/tests/chan_no_type_err.vv:1:6: error: `chan` has no type specified. Use `chan Type{}` instead of `chan{}`
2+
1 | a := chan{}
3+
| ~~~~~~
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a := chan{}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vlib/v/parser/tests/chan_no_type_fn_arg_err.vv:1:12: error: `chan` has no type specified. Use `chan Type` instead of `chan`
2+
1 | fn takes(c chan) {}
3+
| ~~~~
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn takes(c chan) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vlib/v/parser/tests/chan_no_type_map_fn_arg_err.vv:1:31: error: `chan` has no type specified. Use `chan Type` instead of `chan`
2+
1 | fn takes_map(chans map[string]chan) {}
3+
| ~~~~

0 commit comments

Comments
 (0)