From f257a23313c69c2247097b55f884516da1b1a313 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 25 Aug 2021 19:40:40 +0800 Subject: [PATCH] checker: check non-generic struct init (#11300) --- vlib/v/checker/checker.v | 12 ++++++++++++ .../tests/generics_inst_non_generic_struct_err.out | 1 + .../tests/generics_inst_non_generic_struct_err.vv | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 vlib/v/checker/tests/generics_inst_non_generic_struct_err.out create mode 100644 vlib/v/checker/tests/generics_inst_non_generic_struct_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3476c0a693..467b00b4ad 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -818,6 +818,10 @@ pub fn (mut c Checker) generic_insts_to_concrete() { match parent.info { ast.Struct { mut parent_info := parent.info as ast.Struct + if !parent_info.is_generic { + util.verror('generic error', 'struct `$parent.name` is not a generic struct, cannot instantiate to the concrete types') + continue + } mut fields := parent_info.fields.clone() if parent_info.generic_types.len == info.concrete_types.len { generic_names := parent_info.generic_types.map(c.table.get_type_symbol(it).name) @@ -857,6 +861,10 @@ pub fn (mut c Checker) generic_insts_to_concrete() { } ast.Interface { mut parent_info := parent.info as ast.Interface + if !parent_info.is_generic { + util.verror('generic error', 'interface `$parent.name` is not a generic interface, cannot instantiate to the concrete types') + continue + } if parent_info.generic_types.len == info.concrete_types.len { mut fields := parent_info.fields.clone() generic_names := parent_info.generic_types.map(c.table.get_type_symbol(it).name) @@ -908,6 +916,10 @@ pub fn (mut c Checker) generic_insts_to_concrete() { } ast.SumType { mut parent_info := parent.info as ast.SumType + if !parent_info.is_generic { + util.verror('generic error', 'sumtype `$parent.name` is not a generic sumtype, cannot instantiate to the concrete types') + continue + } if parent_info.generic_types.len == info.concrete_types.len { mut fields := parent_info.fields.clone() mut variants := parent_info.variants.clone() diff --git a/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out new file mode 100644 index 0000000000..8d09c8f676 --- /dev/null +++ b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out @@ -0,0 +1 @@ +generic error: struct `main.Test` is not a generic struct, cannot instantiate to the concrete types diff --git a/vlib/v/checker/tests/generics_inst_non_generic_struct_err.vv b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.vv new file mode 100644 index 0000000000..6647877d21 --- /dev/null +++ b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.vv @@ -0,0 +1,6 @@ +struct Test { +} + +fn main() { + println(Test{}) +}