Skip to content

Commit

Permalink
checker: disallow foo[T] as a value
Browse files Browse the repository at this point in the history
  • Loading branch information
Delta456 committed Nov 10, 2024
1 parent 422a841 commit 50d4a60
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
22 changes: 22 additions & 0 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -3834,6 +3834,17 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
c.error('`${node.name}` is a generic fn, you should pass its concrete types, e.g. ${node.name}[int]',
node.pos)
}
mut has_generic := false // foo[T] instead of foo[int]
for concrete_type in node.concrete_types {
if concrete_type.has_flag(.generic) {
has_generic = true
}
}
if c.table.cur_fn != unsafe { nil } && c.table.cur_concrete_types.len == 0
&& has_generic {
c.error('generic fn using generic types cannot be called outside of generic fn',
node.pos)
}
concrete_types := node.concrete_types.map(c.unwrap_generic(it))
if concrete_types.all(!it.has_flag(.generic)) {
c.table.register_fn_concrete_types(func.fkey(), concrete_types)
Expand Down Expand Up @@ -4012,6 +4023,17 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
c.error('`${node.name}` is a generic fn, you should pass its concrete types, e.g. ${node.name}[int]',
node.pos)
}
mut has_generic := false // foo[T] instead of foo[int]
for concrete_type in node.concrete_types {
if concrete_type.has_flag(.generic) {
has_generic = true
}
}
if c.table.cur_fn != unsafe { nil } && c.table.cur_concrete_types.len == 0
&& has_generic {
c.error('generic fn using generic types cannot be called outside of generic fn',
node.pos)
}
}
return c.resolve_var_fn(func, mut node, name)
}
Expand Down
21 changes: 21 additions & 0 deletions vlib/v/checker/tests/generic_fn_generic_name_unresolved_err.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
vlib/v/checker/tests/generic_fn_generic_name_unresolved_err.vv:8:7: error: generic fn using generic types cannot be called outside of generic fn
6 |
7 | fn main() {
8 | _ := func[T]
| ~~~~
9 | _ := {
10 | 'test': func[T]
vlib/v/checker/tests/generic_fn_generic_name_unresolved_err.vv:10:11: error: generic fn using generic types cannot be called outside of generic fn
8 | _ := func[T]
9 | _ := {
10 | 'test': func[T]
| ~~~~
11 | }
12 | _ := {
vlib/v/checker/tests/generic_fn_generic_name_unresolved_err.vv:13:3: error: generic fn using generic types cannot be called outside of generic fn
11 | }
12 | _ := {
13 | func[T]: 'test'
| ~~~~
14 | }
15 | }
15 changes: 15 additions & 0 deletions vlib/v/checker/tests/generic_fn_generic_name_unresolved_err.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module main

fn func[T](arg string, val T) int {
return 2
}

fn main() {
_ := func[T]
_ := {
'test': func[T]
}
_ := {
func[T]: 'test'
}
}

0 comments on commit 50d4a60

Please sign in to comment.