]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Accept "unowned var" as type for foreach variable declaration
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 9 Nov 2020 16:02:50 +0000 (17:02 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 10 Nov 2020 08:14:29 +0000 (09:14 +0100)
In addition to 39331e235f1183223c8ea685e3501ab4ca932c8f

See https://gitlab.gnome.org/GNOME/vala/issues/152

tests/Makefile.am
tests/parser/foreach.vala [new file with mode: 0644]
vala/valaforeachstatement.vala
vala/valaparser.vala

index 47e9a711b7485f5d03cce02f7be1b1a702ef0f89..0c5f059e6959aca4eb20c9ca4dc5e5f0b397f8be 100644 (file)
@@ -745,6 +745,7 @@ TESTS = \
        parser/field-no-override.test \
        parser/field-no-static-class.test \
        parser/field-no-virtual.test \
+       parser/foreach.vala \
        parser/foreach-no-type.test \
        parser/function-syntax-error.test \
        parser/inner-array-size.test \
diff --git a/tests/parser/foreach.vala b/tests/parser/foreach.vala
new file mode 100644 (file)
index 0000000..7879b67
--- /dev/null
@@ -0,0 +1,11 @@
+void main () {
+       string[] array = { "foo", "bar", "manam" };
+       foreach (string s in array) {
+       }
+       foreach (unowned string s in array) {
+       }
+       foreach (var s in array) {
+       }
+       foreach (unowned var s in array) {
+       }
+}
index 258a81dae1f87d6509ee71a0f49a8ad9702b84e1..2c81b202a55010b0f389a5d31594917080454697 100644 (file)
@@ -155,6 +155,10 @@ public class Vala.ForeachStatement : Block {
 
                checked = true;
 
+               if (type_reference == null) {
+                       type_reference = new VarType ();
+               }
+
                // analyze collection expression first, used for type inference
                if (!collection.check (context)) {
                        // ignore inner error
@@ -330,9 +334,13 @@ public class Vala.ForeachStatement : Block {
 
        bool analyze_element_type (DataType element_type) {
                // analyze element type
-               if (type_reference == null) {
+               if (type_reference is VarType) {
                        // var type
                        type_reference = element_type.copy ();
+                       // FIXME Only follows "unowned var" otherwise inherit ownership of element-type
+                       if (!type_reference.value_owned) {
+                               type_reference.value_owned = false;
+                       }
                } else if (!element_type.compatible (type_reference)) {
                        error = true;
                        Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", element_type.to_string (), type_reference.to_string ());
@@ -348,9 +356,13 @@ public class Vala.ForeachStatement : Block {
 
        bool check_without_iterator (CodeContext context, DataType collection_type, DataType element_type) {
                // analyze element type
-               if (type_reference == null) {
+               if (type_reference is VarType) {
                        // var type
                        type_reference = element_type.copy ();
+                       // FIXME Only follows "unowned var" otherwise inherit ownership of element-type
+                       if (!type_reference.value_owned) {
+                               type_reference.value_owned = false;
+                       }
                } else if (!element_type.compatible (type_reference)) {
                        error = true;
                        Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", element_type.to_string (), type_reference.to_string ());
index fc130c7cbad53f0c985acc4279e4ef0008767068..f54de7832c12ea5b5bad192b0fd58dca167bdea9 100644 (file)
@@ -2194,12 +2194,20 @@ public class Vala.Parser : CodeVisitor {
                var begin = get_location ();
                expect (TokenType.FOREACH);
                expect (TokenType.OPEN_PARENS);
-               DataType type = null;
-               if (!accept (TokenType.VAR)) {
-                       type = parse_type (true, true);
-                       if (accept (TokenType.IN)) {
-                               Report.error (type.source_reference, "syntax error, expected var or type");
-                               throw new ParseError.SYNTAX ("expected var or type");
+               var var_or_type = get_location ();
+               DataType type;
+               if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
+                       type = new VarType (false);
+               } else {
+                       rollback (var_or_type);
+                       if (accept (TokenType.VAR)) {
+                               type = new VarType ();
+                       } else {
+                               type = parse_type (true, true);
+                               if (accept (TokenType.IN)) {
+                                       Report.error (type.source_reference, "syntax error, expected `unowned var', `var' or type");
+                                       throw new ParseError.SYNTAX ("expected `unowned var', `var' or type");
+                               }
                        }
                }
                string id = parse_identifier ();