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:
parent
20aaf4de09
commit
5b4a16e864
@ -1045,7 +1045,7 @@ pub mut:
|
||||
pub struct GenericInst {
|
||||
pub mut:
|
||||
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]
|
||||
@ -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 {
|
||||
result := t.type_to_str(typ)
|
||||
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,
|
||||
// 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 {
|
||||
// main.Abc<int>
|
||||
// main.Abc[int]
|
||||
mut embed_name := t.name
|
||||
// remove generic part from name
|
||||
// main.Abc<int> => main.Abc
|
||||
// main.Abc[int] => main.Abc
|
||||
if embed_name.contains('[') {
|
||||
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 {
|
||||
// main.Abc<int> => Abc<int>
|
||||
// main.Abc[int] => Abc[int]
|
||||
mut embed_name := t.name.split('.').last()
|
||||
// remove generic part from name
|
||||
// Abc<int> => Abc
|
||||
// Abc[int] => Abc
|
||||
if embed_name.contains('[') {
|
||||
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() {
|
||||
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 {
|
||||
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 {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user