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) ? {
|
fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
c.error('unknown type', pos)
|
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.error('struct field does not support storing result', field.optional_pos)
|
||||||
}
|
}
|
||||||
c.ensure_type_exists(field.typ, field.type_pos) or { return }
|
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) {
|
if field.typ.has_flag(.generic) {
|
||||||
has_generic_types = true
|
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() {
|
if info.is_heap && !field.typ.is_ptr() {
|
||||||
struct_sym.info.is_heap = true
|
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 {
|
if sym.kind == .multi_return {
|
||||||
c.error('cannot use multi return as field type', field.type_pos)
|
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:
|
2 | mut:
|
||||||
3 | value T
|
3 | value T
|
||||||
4 | next &LL = unsafe { 0 }
|
4 | next &LL = unsafe { 0 }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user