mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: add err for unknown generic struct field (#16698)
This commit is contained in:
@ -1045,7 +1045,7 @@ pub mut:
|
|||||||
pub struct GenericInst {
|
pub struct GenericInst {
|
||||||
pub mut:
|
pub mut:
|
||||||
parent_idx int // idx of the base generic struct
|
parent_idx int // idx of the base generic struct
|
||||||
concrete_types []Type // concrete types, e.g. <int, string>
|
concrete_types []Type // concrete types, e.g. [int, string]
|
||||||
}
|
}
|
||||||
|
|
||||||
[minify]
|
[minify]
|
||||||
@ -1148,7 +1148,7 @@ pub fn (mytable &Table) type_to_code(t Type) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean type name from generics form. From Type<int> -> Type
|
// clean type name from generics form. From Type[int] -> Type
|
||||||
pub fn (t &Table) clean_generics_type_str(typ Type) string {
|
pub fn (t &Table) clean_generics_type_str(typ Type) string {
|
||||||
result := t.type_to_str(typ)
|
result := t.type_to_str(typ)
|
||||||
return result.all_before('[')
|
return result.all_before('[')
|
||||||
@ -1436,12 +1436,12 @@ pub fn (t &Table) fn_signature_using_aliases(func &Fn, import_aliases map[string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// symbol_name_except_generic return the name of the complete qualified name of the type,
|
// symbol_name_except_generic return the name of the complete qualified name of the type,
|
||||||
// but without the generic parts. For example, `main.Abc<int>` -> `main.Abc`
|
// but without the generic parts. For example, `main.Abc[int]` -> `main.Abc`
|
||||||
pub fn (t &TypeSymbol) symbol_name_except_generic() string {
|
pub fn (t &TypeSymbol) symbol_name_except_generic() string {
|
||||||
// main.Abc<int>
|
// main.Abc[int]
|
||||||
mut embed_name := t.name
|
mut embed_name := t.name
|
||||||
// remove generic part from name
|
// remove generic part from name
|
||||||
// main.Abc<int> => main.Abc
|
// main.Abc[int] => main.Abc
|
||||||
if embed_name.contains('[') {
|
if embed_name.contains('[') {
|
||||||
embed_name = embed_name.all_before('[')
|
embed_name = embed_name.all_before('[')
|
||||||
}
|
}
|
||||||
@ -1449,10 +1449,10 @@ pub fn (t &TypeSymbol) symbol_name_except_generic() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (t &TypeSymbol) embed_name() string {
|
pub fn (t &TypeSymbol) embed_name() string {
|
||||||
// main.Abc<int> => Abc<int>
|
// main.Abc[int] => Abc[int]
|
||||||
mut embed_name := t.name.split('.').last()
|
mut embed_name := t.name.split('.').last()
|
||||||
// remove generic part from name
|
// remove generic part from name
|
||||||
// Abc<int> => Abc
|
// Abc[int] => Abc
|
||||||
if embed_name.contains('[') {
|
if embed_name.contains('[') {
|
||||||
embed_name = embed_name.split('[')[0]
|
embed_name = embed_name.split('[')[0]
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,12 @@ 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
|
||||||
}
|
}
|
||||||
|
for ct in info.concrete_types {
|
||||||
|
ct_sym := c.table.sym(ct)
|
||||||
|
if ct_sym.kind == .placeholder {
|
||||||
|
c.error('unknown type `${ct_sym.name}`', 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/struct_field_generic_struct_unknown_type_err.vv:9:24: error: unknown type `UnknownType`
|
||||||
|
7 | }
|
||||||
|
8 | struct MyType {
|
||||||
|
9 | a Maybe[UnknownType]
|
||||||
|
| ^
|
||||||
|
10 | }
|
||||||
|
11 |
|
@ -0,0 +1,14 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Maybe[T] {
|
||||||
|
present bool
|
||||||
|
val T
|
||||||
|
}
|
||||||
|
struct MyType {
|
||||||
|
a Maybe[UnknownType]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = MyType {}
|
||||||
|
}
|
Reference in New Issue
Block a user