From: Rico Tzschichholz Date: Thu, 13 Apr 2023 15:19:04 +0000 (+0200) Subject: WIP vala: Check compatibility of generic type-arguments and type-constraints X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb5abe89419fc435a6f8b9c0178f6f3a917cfc7b;p=thirdparty%2Fvala.git WIP vala: Check compatibility of generic type-arguments and type-constraints --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 11a5469f4..a01040eae 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -808,6 +808,7 @@ TESTS = \ generics/arrays-not-supported-3.test \ generics/class-property-override.vala \ generics/constraints.vala \ + generics/constraints-incompatible.test \ generics/constructor-chain-up.vala \ generics/delegate-return-type-missing.test \ generics/floating-type-cast.vala \ diff --git a/tests/generics/constraints-incompatible.test b/tests/generics/constraints-incompatible.test new file mode 100644 index 000000000..1a9fec533 --- /dev/null +++ b/tests/generics/constraints-incompatible.test @@ -0,0 +1,16 @@ +Invalid Code + +class Bar { +} + +class SubBar : Bar { +} + +interface IFoo where G : SubBar { +} + +class Foo : IFoo where T : Bar { +} + +void main () { +} diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index a570f9d48..f947f7cdf 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -319,6 +319,10 @@ public abstract class Vala.DataType : CodeNode { /* temporarily ignore type parameters */ if (target_type is GenericType) { + unowned DataType? constraint_type = ((GenericType) target_type).type_parameter.type_constraint; + if (constraint_type != null) { + return compatible (constraint_type); + } return true; } @@ -721,10 +725,19 @@ public abstract class Vala.DataType : CodeNode { return false; } + var it = ((GenericSymbol) type_symbol).get_type_parameters ().iterator (); foreach (DataType type in get_type_arguments ()) { if (!type.check (context)) { return false; } + + it.next (); + unowned DataType? constraint_type = it.get ().type_constraint; + if (constraint_type != null && !type.compatible (constraint_type)) { + error = true; + Report.error (type.source_reference, "Cannot convert from `%s' to `%s'", type.to_string (), constraint_type.to_string ()); + return false; + } } return true; diff --git a/vala/valagenerictype.vala b/vala/valagenerictype.vala index 50c713bce..3a81449c1 100644 --- a/vala/valagenerictype.vala +++ b/vala/valagenerictype.vala @@ -52,6 +52,15 @@ public class Vala.GenericType : DataType { return result; } + public override bool compatible (DataType target_type) { + unowned DataType? constraint_type = type_parameter.type_constraint; + if (constraint_type != null) { + return constraint_type.compatible (target_type); + } + + return base.compatible (target_type); + } + public override DataType get_actual_type (DataType? derived_instance_type, List? method_type_arguments, CodeNode? node_reference) { var result = this.copy ();