1
0
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:
Swastik Baranwal 2022-12-18 15:16:37 +05:30 committed by GitHub
parent 20aaf4de09
commit 5b4a16e864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 7 deletions

View File

@ -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]
}

View File

@ -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)

View File

@ -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 |

View File

@ -0,0 +1,14 @@
module main
pub struct Maybe[T] {
present bool
val T
}
struct MyType {
a Maybe[UnknownType]
}
fn main() {
_ = MyType {}
}