mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check generic method receiver type mismatch (#16739)
This commit is contained in:
@@ -215,30 +215,28 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||
c.error('optional or result type argument is not supported currently',
|
||||
param.type_pos)
|
||||
}
|
||||
if !param.typ.is_ptr() { // value parameter, i.e. on stack - check for `[heap]`
|
||||
arg_typ_sym := c.table.sym(param.typ)
|
||||
if arg_typ_sym.info is ast.Struct {
|
||||
if arg_typ_sym.info.is_heap { // set auto_heap to promote value parameter
|
||||
mut v := node.scope.find_var(param.name) or { continue }
|
||||
v.is_auto_heap = true
|
||||
}
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic struct `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
} else if arg_typ_sym.info is ast.Interface {
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic interface `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
} else if arg_typ_sym.info is ast.SumType {
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic sumtype `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
arg_typ_sym := c.table.sym(param.typ)
|
||||
if arg_typ_sym.info is ast.Struct {
|
||||
if !param.typ.is_ptr() && arg_typ_sym.info.is_heap { // set auto_heap to promote value parameter
|
||||
mut v := node.scope.find_var(param.name) or { continue }
|
||||
v.is_auto_heap = true
|
||||
}
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic struct `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
} else if arg_typ_sym.info is ast.Interface {
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic interface `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
} else if arg_typ_sym.info is ast.SumType {
|
||||
if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
|
||||
&& arg_typ_sym.info.concrete_types.len == 0 {
|
||||
c.error('generic sumtype `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]',
|
||||
param.type_pos)
|
||||
}
|
||||
}
|
||||
// Ensure each generic type of the parameter was declared in the function's definition
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
vlib/v/checker/tests/generics_method_receiver_type_err.vv:6:11: error: generic struct `Node` in fn declaration must specify the generic type names, e.g. Node[T]
|
||||
4 | }
|
||||
5 |
|
||||
6 | pub fn (x Node) str() string {
|
||||
| ~~~~
|
||||
7 | return 'Value is : ${u16(x.val)}\nName is : $x.name'
|
||||
8 | }
|
||||
@@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/generics_method_receiver_type_err_a.vv:6:11: error: generic struct `Node` in fn declaration must specify the generic type names, e.g. Node[T]
|
||||
4 | }
|
||||
5 |
|
||||
6 | pub fn (x Node) str() string {
|
||||
| ~~~~
|
||||
7 | return 'Value is : ${u16(x.val)}\nName is : $x.name'
|
||||
8 | }
|
||||
@@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/generics_method_receiver_type_err_b.vv:8:12: error: generic struct `ConsumableResources` in fn declaration must specify the generic type names, e.g. ConsumableResources[T]
|
||||
6 | used_resources map[T]Resources
|
||||
7 | }
|
||||
8 | pub fn (cr &ConsumableResources) get_total_resources() Resources {
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
9 | return cr.total_resources
|
||||
10 | }
|
||||
13
vlib/v/checker/tests/generics_method_receiver_type_err_b.vv
Normal file
13
vlib/v/checker/tests/generics_method_receiver_type_err_b.vv
Normal file
@@ -0,0 +1,13 @@
|
||||
pub struct Resources{}
|
||||
|
||||
pub struct ConsumableResources[T] {
|
||||
mut:
|
||||
total_resources Resources
|
||||
used_resources map[T]Resources
|
||||
}
|
||||
pub fn (cr &ConsumableResources) get_total_resources() Resources {
|
||||
return cr.total_resources
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
Reference in New Issue
Block a user