]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Recursively infer generic type arguments
authorSimon Werbeck <simon.werbeck@gmail.com>
Thu, 14 Aug 2014 21:46:17 +0000 (23:46 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Sun, 16 Nov 2014 23:47:13 +0000 (00:47 +0100)
Slightly changed by Luca Bruno.

Fixes bug 626783

tests/Makefile.am
tests/methods/bug626783.vala [new file with mode: 0644]
vala/valaarraytype.vala
vala/valadatatype.vala
vala/valagenerictype.vala
vala/valamethodcall.vala
vala/valapointertype.vala

index 49357c5abc61680221b43b3bc3dbe363bffaeed0..0da5e3bfbcdbeb93845c573e3c3037a787fa605f 100644 (file)
@@ -50,6 +50,7 @@ TESTS = \
        methods/bug613483.vala \
        methods/bug620673.vala \
        methods/bug622570.vala \
+       methods/bug626783.vala \
        methods/bug639054.vala \
        methods/bug642885.vala \
        methods/bug642899.vala \
diff --git a/tests/methods/bug626783.vala b/tests/methods/bug626783.vala
new file mode 100644 (file)
index 0000000..d2b401b
--- /dev/null
@@ -0,0 +1,22 @@
+public class Test<G,H> {
+}
+
+public void foo<T> (Test<T,int> t) {
+}
+
+public void bar<A,B> (Test<Test<A,B>,int> t) {
+}
+
+public T* baz<T> () {
+       return null;
+}
+
+void main () {
+       var f = new Test<int,int> ();
+       foo (f);
+
+       var g = new Test<Test<char,uint>,int> ();
+       bar (g);
+
+       int* i = baz ();
+}
index 941485a1f0551602d40f9c53ba7ec112f5dc636f..d993e3c9372869a37b86315e6092d953da2e0b51 100644 (file)
@@ -272,6 +272,15 @@ public class Vala.ArrayType : ReferenceType {
                return result;
        }
 
+       public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+               var array_type = value_type as ArrayType;
+               if (array_type != null) {
+                       return element_type.infer_type_argument (type_param, array_type.element_type);
+               }
+
+               return null;
+       }
+
        public override bool is_disposable () {
                if (fixed_length) {
                        return element_type.is_disposable ();
index 352885bfd9cb518a30d218ab7fd1adcdd20838a8..02b4cf13f79587ef5a415efc965dc01fca65aedd 100644 (file)
@@ -462,6 +462,24 @@ public abstract class Vala.DataType : CodeNode {
                return result;
        }
 
+       /**
+        * Search for the type parameter in this formal type and match it in
+        * value_type.
+        */
+       public virtual DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+               var value_type_arg_it = value_type.get_type_arguments ().iterator ();
+               foreach (var formal_type_arg in this.get_type_arguments ()) {
+                       if (value_type_arg_it.next ()) {
+                               var inferred_type = formal_type_arg.infer_type_argument (type_param, value_type_arg_it.get ());
+                               if (inferred_type != null) {
+                                       return inferred_type;
+                               }
+                       }
+               }
+
+               return null;
+       }
+
        public bool is_weak () {
                if (this.value_owned) {
                        return false;
index 49a4c57234ff2cdb255db0a26dbff01b70cc7b81..66415e6f9e6609ce17c7f576ee993397fa222108 100644 (file)
@@ -42,6 +42,16 @@ public class Vala.GenericType : DataType {
                return result;
        }
 
+       public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+               if (type_parameter == type_param) {
+                       var ret = value_type.copy ();
+                       ret.value_owned = true;
+                       return ret;
+               }
+
+               return null;
+       }
+
        public override string to_qualified_string (Scope? scope = null) {
                return type_parameter.name;
        }
index efce5483a184af1a3dc1fb0fe597c9d989f6f2d8..0229e40b72c87b7b6e83fa2a4e08c7cd9811e176 100644 (file)
@@ -536,10 +536,8 @@ public class Vala.MethodCall : Expression {
                                                        if (arg_it.next ()) {
                                                                Expression arg = arg_it.get ();
 
-                                                               var generic_type = param.variable_type as GenericType;
-                                                               if (generic_type != null && generic_type.type_parameter == type_param) {
-                                                                       type_arg = arg.value_type.copy ();
-                                                                       type_arg.value_owned = true;
+                                                               type_arg = param.variable_type.infer_type_argument (type_param, arg.value_type);
+                                                               if (type_arg != null) {
                                                                        break;
                                                                }
 
@@ -549,11 +547,7 @@ public class Vala.MethodCall : Expression {
 
                                                // infer type arguments from expected return type
                                                if (type_arg == null && target_type != null) {
-                                                       var generic_type = m.return_type as GenericType;
-                                                       if (generic_type != null && generic_type.type_parameter == type_param) {
-                                                               type_arg = target_type.copy ();
-                                                               type_arg.value_owned = true;
-                                                       }
+                                                       type_arg = m.return_type.infer_type_argument (type_param, target_type);
                                                }
 
                                                if (type_arg == null) {
index 822123e91b5337cbcb865230147fd29e6579ba74..461983c302daf28321b9944ddb48cfaeb1439921 100644 (file)
@@ -137,6 +137,15 @@ public class Vala.PointerType : DataType {
                return result;
        }
 
+       public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+               var pointer_type = value_type as PointerType;
+               if (pointer_type != null) {
+                       return base_type.infer_type_argument (type_param, pointer_type.base_type);
+               }
+
+               return null;
+       }
+
        public override bool check (CodeContext context) {
                error = !base_type.check (context);
                return !error;