diff options
author | Matthias Berndt <matthias_berndt@gmx.de> | 2016-09-21 00:05:35 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2016-09-21 18:43:24 +0200 |
commit | 6054e9d6c68bd1696ceec44ffbc5ba7c3b5f2088 (patch) | |
tree | 43bcb67ddfbdbc9a18e80e9c3c40c88ea5e20020 | |
parent | 5c9b22e779122c2ce5598e0e11b6a9a34325910d (diff) | |
download | vala-wip/bug615830.tar.gz |
Fix type checking when using generics in combination with subtypingwip/bug615830
https://bugzilla.gnome.org/show_bug.cgi?id=615830
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/objects/bug615830-1.test | 11 | ||||
-rw-r--r-- | tests/objects/bug615830-2.test | 12 | ||||
-rw-r--r-- | tests/objects/generics.vala | 7 | ||||
-rw-r--r-- | vala/valadatatype.vala | 19 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 13 |
6 files changed, 48 insertions, 17 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index b2caa7767..4a29806be 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -128,6 +128,7 @@ TESTS = \ delegates/bug703804.vala \ objects/chainup.vala \ objects/classes.vala \ + objects/generics.vala \ objects/fields.vala \ objects/interfaces.vala \ objects/methods.vala \ @@ -171,6 +172,8 @@ TESTS = \ objects/bug751338.vala \ objects/bug767092.test \ objects/bug768823.test \ + objects/bug615830-1.test \ + objects/bug615830-2.test \ errors/errors.vala \ errors/bug567181.vala \ errors/bug579101.vala \ diff --git a/tests/objects/bug615830-1.test b/tests/objects/bug615830-1.test new file mode 100644 index 000000000..0283ce4b8 --- /dev/null +++ b/tests/objects/bug615830-1.test @@ -0,0 +1,11 @@ +Invalid Code + +class Foo<T> { +} + +class Bar<T> : Foo<T> { +} + +void main (string[] args) { + Foo<int> f = new Bar<string> (); +} diff --git a/tests/objects/bug615830-2.test b/tests/objects/bug615830-2.test new file mode 100644 index 000000000..88b2493b2 --- /dev/null +++ b/tests/objects/bug615830-2.test @@ -0,0 +1,12 @@ +Invalid Code + +struct Foo<T> { + int x; +} + +struct Bar<T> : Foo<T> { +} + +void main (string[] args) { + Foo<int> f = Bar<string> (); +} diff --git a/tests/objects/generics.vala b/tests/objects/generics.vala new file mode 100644 index 000000000..8b39db945 --- /dev/null +++ b/tests/objects/generics.vala @@ -0,0 +1,7 @@ +void main() { + // Support generic types without type arguments for non-generic + // functions that are agnostic with regard to the actual type arguments. + + GLib.HashTable<int, string> h = (GLib.HashTable) null; + (void) h; +} diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index 02b4cf13f..2e799b3b1 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -303,20 +303,19 @@ public abstract class Vala.DataType : CodeNode { return true; } - if (data_type == target_type.data_type) { + if (data_type != null && target_type.data_type != null && data_type.is_subtype_of (target_type.data_type)) { + var base_type = SemanticAnalyzer.get_instance_base_type_for_member(this, target_type.data_type, this); // check compatibility of generic type arguments - if (type_argument_list != null - && type_argument_list.size > 0 - && type_argument_list.size == target_type.get_type_arguments ().size) { - for (int i = 0; i < type_argument_list.size; i++) { - var type_arg = type_argument_list[i]; - var target_type_arg = target_type.get_type_arguments ()[i]; + var base_type_args = base_type.get_type_arguments(); + var target_type_args = target_type.get_type_arguments(); + if (base_type_args.size == target_type_args.size) { + for (int i = 0; i < base_type_args.size; i++) { // mutable generic types require type argument equality, // not just one way compatibility // as we do not currently have immutable generic container types, // the additional check would be very inconvenient, so we // skip the additional check for now - if (!type_arg.compatible (target_type_arg)) { + if (!base_type_args[i].compatible (target_type_args[i])) { return false; } } @@ -341,10 +340,6 @@ public abstract class Vala.DataType : CodeNode { } } - if (data_type != null && target_type.data_type != null && data_type.is_subtype_of (target_type.data_type)) { - return true; - } - return false; } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index cb1a575f5..cf04458be 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -721,11 +721,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor { private static DataType? get_instance_base_type (DataType instance_type, DataType base_type, CodeNode node_reference) { // construct a new type reference for the base type with correctly linked type arguments - ReferenceType instance_base_type; - if (base_type.data_type is Class) { - instance_base_type = new ObjectType ((Class) base_type.data_type); + DataType instance_base_type; + if (base_type.data_type is ObjectTypeSymbol) { + instance_base_type = new ObjectType ((ObjectTypeSymbol) base_type.data_type); + } else if (base_type.data_type is Struct){ + instance_base_type = new StructValueType ((Struct) base_type.data_type); } else { - instance_base_type = new ObjectType ((Interface) base_type.data_type); + instance_base_type = null; + assert(false); } foreach (DataType type_arg in base_type.get_type_arguments ()) { // resolve type argument specified in base type (possibly recursively for nested generic types) @@ -735,7 +738,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return instance_base_type; } - static DataType? get_instance_base_type_for_member (DataType derived_instance_type, TypeSymbol type_symbol, CodeNode node_reference) { + public static DataType? get_instance_base_type_for_member (DataType derived_instance_type, TypeSymbol type_symbol, CodeNode node_reference) { DataType instance_type = derived_instance_type; while (instance_type is PointerType) { |