mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
349ce08a11
commit
59c979c8d2
@ -4120,6 +4120,58 @@ fn (mut c Checker) trace(fbase string, message string) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos token.Pos) ? {
|
||||
if typ == 0 {
|
||||
c.error('unknown type', pos)
|
||||
return
|
||||
}
|
||||
sym := c.table.final_sym(typ)
|
||||
match sym.kind {
|
||||
.function {
|
||||
fn_info := sym.info as ast.FnType
|
||||
c.ensure_generic_type_specify_type_names(fn_info.func.return_type, fn_info.func.return_type_pos)?
|
||||
for param in fn_info.func.params {
|
||||
c.ensure_generic_type_specify_type_names(param.typ, param.type_pos)?
|
||||
}
|
||||
}
|
||||
.array {
|
||||
c.ensure_generic_type_specify_type_names((sym.info as ast.Array).elem_type,
|
||||
pos)?
|
||||
}
|
||||
.array_fixed {
|
||||
c.ensure_generic_type_specify_type_names((sym.info as ast.ArrayFixed).elem_type,
|
||||
pos)?
|
||||
}
|
||||
.map {
|
||||
info := sym.info as ast.Map
|
||||
c.ensure_generic_type_specify_type_names(info.key_type, pos)?
|
||||
c.ensure_generic_type_specify_type_names(info.value_type, pos)?
|
||||
}
|
||||
.sum_type {
|
||||
info := sym.info as ast.SumType
|
||||
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
|
||||
c.error('`${sym.name}` type is generic sumtype, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
.struct_ {
|
||||
info := sym.info as ast.Struct
|
||||
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
|
||||
c.error('`${sym.name}` type is generic struct, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
.interface_ {
|
||||
info := sym.info as ast.Interface
|
||||
if info.generic_types.len > 0 && !typ.has_flag(.generic) && info.concrete_types.len == 0 {
|
||||
c.error('`${sym.name}` type is generic interface, must specify the generic type names, e.g. ${sym.name}[T], ${sym.name}[int]',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
|
||||
if typ == 0 {
|
||||
c.error('unknown type', pos)
|
||||
|
@ -52,6 +52,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
||||
c.error('struct field does not support storing result', field.optional_pos)
|
||||
}
|
||||
c.ensure_type_exists(field.typ, field.type_pos) or { return }
|
||||
c.ensure_generic_type_specify_type_names(field.typ, field.type_pos) or { return }
|
||||
if field.typ.has_flag(.generic) {
|
||||
has_generic_types = true
|
||||
}
|
||||
@ -77,11 +78,6 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
||||
if info.is_heap && !field.typ.is_ptr() {
|
||||
struct_sym.info.is_heap = true
|
||||
}
|
||||
if info.generic_types.len > 0 && !field.typ.has_flag(.generic)
|
||||
&& info.concrete_types.len == 0 {
|
||||
c.error('field `${field.name}` type is generic struct, must specify the generic type names, e.g. Foo[T], Foo[int]',
|
||||
field.type_pos)
|
||||
}
|
||||
}
|
||||
if sym.kind == .multi_return {
|
||||
c.error('cannot use multi return as field type', field.type_pos)
|
||||
|
@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/generics_interface_field_type_err.vv:34:18: error: `IComponentStore` type is generic interface, must specify the generic type names, e.g. IComponentStore[T], IComponentStore[int]
|
||||
32 | struct Registry {
|
||||
33 | pub mut:
|
||||
34 | data map[string]IComponentStore
|
||||
| ~~~~~~~~~~~~~~~
|
||||
35 | }
|
||||
36 |
|
45
vlib/v/checker/tests/generics_interface_field_type_err.vv
Normal file
45
vlib/v/checker/tests/generics_interface_field_type_err.vv
Normal file
@ -0,0 +1,45 @@
|
||||
module main
|
||||
|
||||
pub struct Entity {
|
||||
pub:
|
||||
id u16
|
||||
}
|
||||
|
||||
pub struct Position { // other components ie Velocity
|
||||
pub mut:
|
||||
x f64
|
||||
y f64
|
||||
z f64
|
||||
}
|
||||
|
||||
pub interface IComponentStore<T> {
|
||||
mut:
|
||||
add(Entity, T)
|
||||
}
|
||||
|
||||
pub struct ComponentStore<T> {
|
||||
pub mut:
|
||||
typ string
|
||||
// data etc
|
||||
}
|
||||
|
||||
pub fn (mut cs ComponentStore<T>) add(e Entity, value T) {
|
||||
// index := cs.set.add(e.id)
|
||||
// cs.instances[index] = value
|
||||
}
|
||||
|
||||
[heap]
|
||||
struct Registry {
|
||||
pub mut:
|
||||
data map[string]IComponentStore
|
||||
}
|
||||
|
||||
pub fn registry() &Registry {
|
||||
mut r := &Registry {
|
||||
data: map[string]IComponentStore{}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
vlib/v/checker/tests/generics_struct_field_type_err.vv:4:9: error: field `next` type is generic struct, must specify the generic type names, e.g. Foo[T], Foo[int]
|
||||
vlib/v/checker/tests/generics_struct_field_type_err.vv:4:9: error: `LL` type is generic struct, must specify the generic type names, e.g. LL[T], LL[int]
|
||||
2 | mut:
|
||||
3 | value T
|
||||
4 | next &LL = unsafe { 0 }
|
||||
|
Loading…
Reference in New Issue
Block a user