]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
WIP vala: Check compatibility of generic type-arguments and type-constraints
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 13 Apr 2023 15:19:04 +0000 (17:19 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sun, 21 Apr 2024 11:41:43 +0000 (13:41 +0200)
tests/Makefile.am
tests/generics/constraints-incompatible.test [new file with mode: 0644]
vala/valadatatype.vala
vala/valagenerictype.vala

index 207cdb6e5dabce654c285807756dbcf9dcb74133..a452b726ec1bc255bd62ba9d56774938cf8126b7 100644 (file)
@@ -811,6 +811,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 (file)
index 0000000..1a9fec5
--- /dev/null
@@ -0,0 +1,16 @@
+Invalid Code
+
+class Bar {
+}
+
+class SubBar : Bar {
+}
+
+interface IFoo<G> where G : SubBar {
+}
+
+class Foo<T> : IFoo<T> where T : Bar {
+}
+
+void main () {
+}
index a570f9d4803505b98d10669bdea8840b20d9cf8e..f947f7cdf483fddc07d3062a883db08aa9287801 100644 (file)
@@ -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;
index 50c713bced94934a2687c239b5ef5e5d53827516..3a81449c1ff6b82aec27382c2427bfee6584f3d8 100644 (file)
@@ -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<DataType>? method_type_arguments, CodeNode? node_reference) {
                var result = this.copy ();