diff options
author | Matthias Berndt <matthias_berndt@gmx.de> | 2016-08-08 19:41:33 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2016-09-19 21:45:30 +0200 |
commit | 3b08decd4b9175c4e9b967d01355263467e24aec (patch) | |
tree | 2aac9dff73eb4c17c486a83c8819fcde58a887da | |
parent | aca65c59769b080b1cfecf51266e32a4c16057e8 (diff) | |
download | vala-bug615830.tar.gz |
Fix type checking when using generics in combination with subtypingbug615830
Fixes bug 615830.
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/objects/bug615830.test | 12 | ||||
-rw-r--r-- | tests/objects/generics.vala | 7 | ||||
-rw-r--r-- | vala/valadatatype.vala | 19 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 2 |
5 files changed, 29 insertions, 13 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index b2caa7767..97e81c6ed 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,7 @@ TESTS = \ objects/bug751338.vala \ objects/bug767092.test \ objects/bug768823.test \ + objects/bug615830.test \ errors/errors.vala \ errors/bug567181.vala \ errors/bug579101.vala \ diff --git a/tests/objects/bug615830.test b/tests/objects/bug615830.test new file mode 100644 index 000000000..04742b3e1 --- /dev/null +++ b/tests/objects/bug615830.test @@ -0,0 +1,12 @@ +Invalid Code + +class Foo<T> { +} + +class Bar<T> : Foo<T> { +} + +int main (string[] args) { + Foo<int> f = new Bar<string> (); + return 0; +} 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..3b43d3652 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -735,7 +735,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) { |