about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-18 11:49:06 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-03-18 11:49:47 -0700
commit2ef9c01ffcd160937ddccc91a6f5e9fa24f22fd4 (patch)
tree2c558d866e94eb0ee42d9d4c608f75dc4e45a4c8 /src
parent4c2245d8421ff43832b005375025cd14f56c1ca9 (diff)
downloadrust-2ef9c01ffcd160937ddccc91a6f5e9fa24f22fd4.tar.gz
rust-2ef9c01ffcd160937ddccc91a6f5e9fa24f22fd4.zip
rustc: Implement "mutable?". Add a test case and XFAIL it in rustboot for now.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/comp/front/ast.rs1
-rw-r--r--src/comp/front/parser.rs4
-rw-r--r--src/comp/middle/ty.rs83
-rw-r--r--src/comp/pretty/pprust.rs6
-rw-r--r--src/test/run-pass/maybe-mutable.rs17
6 files changed, 87 insertions, 25 deletions
diff --git a/src/Makefile b/src/Makefile
index 16437310b76..630babf33c6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -456,6 +456,7 @@ TEST_XFAILS_BOOT :=  $(TASK_XFAILS) \
                     test/run-pass/iter-ret.rs \
                     test/run-pass/leak-tag-copy.rs \
                     test/run-pass/lib-io.rs \
+                    test/run-pass/maybe-mutable.rs \
                     test/run-pass/mlist-cycle.rs \
                     test/run-pass/obj-as.rs \
                     test/run-pass/seq-compare.rs \
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index e519d03bf2c..ec93db55c92 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -91,6 +91,7 @@ tag pat_ {
 tag mutability {
     mut;
     imm;
+    maybe_mut;
 }
 
 tag opacity {
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 71f0f2d891d..028b8a3132d 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -615,6 +615,10 @@ impure fn parse_path(parser p, greed g) -> ast.path {
 impure fn parse_mutability(parser p) -> ast.mutability {
     if (p.peek() == token.MUTABLE) {
         p.bump();
+        if (p.peek() == token.QUES) {
+            p.bump();
+            ret ast.maybe_mut;
+        }
         ret ast.mut;
     }
     ret ast.imm;
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 3d10462ad65..5fdb4dc2d2c 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -148,8 +148,9 @@ fn ty_to_str(&@t typ) -> str {
     fn mt_to_str(&mt m) -> str {
         auto mstr;
         alt (m.mut) {
-            case (ast.mut) { mstr = "mutable "; }
-            case (ast.imm) { mstr = "";         }
+            case (ast.mut)       { mstr = "mutable "; }
+            case (ast.imm)       { mstr = "";         }
+            case (ast.maybe_mut) { mstr = "mutable? "; }
         }
 
         ret mstr + ty_to_str(m.ty);
@@ -858,6 +859,21 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
         ret ures_err(terr_mismatch, expected, actual);
     }
 
+    // Unifies two mutability flags.
+    fn unify_mut(ast.mutability expected, ast.mutability actual)
+            -> option.t[ast.mutability] {
+        if (expected == actual) {
+            ret some[ast.mutability](expected);
+        }
+        if (expected == ast.maybe_mut) {
+            ret some[ast.mutability](actual);
+        }
+        if (actual == ast.maybe_mut) {
+            ret some[ast.mutability](expected);
+        }
+        ret none[ast.mutability];
+    }
+
     tag fn_common_res {
         fn_common_res_err(unify_result);
         fn_common_res_ok(vec[arg], @t);
@@ -1158,9 +1174,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
             case (ty.ty_box(?expected_mt)) {
                 alt (actual.struct) {
                     case (ty.ty_box(?actual_mt)) {
-                        if (expected_mt.mut != actual_mt.mut) {
-                            ret ures_err(terr_box_mutability, expected,
-                                         actual);
+                        auto mut;
+                        alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
+                            case (none[ast.mutability]) {
+                                ret ures_err(terr_box_mutability, expected,
+                                             actual);
+                            }
+                            case (some[ast.mutability](?m)) { mut = m; }
                         }
 
                         auto result = unify_step(bindings,
@@ -1169,8 +1189,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                                                  handler);
                         alt (result) {
                             case (ures_ok(?result_sub)) {
-                                auto mt = rec(ty=result_sub,
-                                              mut=expected_mt.mut);
+                                auto mt = rec(ty=result_sub, mut=mut);
                                 ret ures_ok(plain_ty(ty.ty_box(mt)));
                             }
                             case (_) {
@@ -1188,9 +1207,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
             case (ty.ty_vec(?expected_mt)) {
                 alt (actual.struct) {
                     case (ty.ty_vec(?actual_mt)) {
-                        if (expected_mt.mut != actual_mt.mut) {
-                            ret ures_err(terr_vec_mutability, expected,
-                                         actual);
+                        auto mut;
+                        alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
+                            case (none[ast.mutability]) {
+                                ret ures_err(terr_vec_mutability, expected,
+                                             actual);
+                            }
+                            case (some[ast.mutability](?m)) { mut = m; }
                         }
 
                         auto result = unify_step(bindings,
@@ -1199,8 +1222,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                                                  handler);
                         alt (result) {
                             case (ures_ok(?result_sub)) {
-                                auto mt = rec(ty=result_sub,
-                                              mut=expected_mt.mut);
+                                auto mt = rec(ty=result_sub, mut=mut);
                                 ret ures_ok(plain_ty(ty.ty_vec(mt)));
                             }
                             case (_) {
@@ -1279,9 +1301,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                         while (i < expected_len) {
                             auto expected_elem = expected_elems.(i);
                             auto actual_elem = actual_elems.(i);
-                            if (expected_elem.mut != actual_elem.mut) {
-                                auto err = terr_tuple_mutability;
-                                ret ures_err(err, expected, actual);
+
+                            auto mut;
+                            alt (unify_mut(expected_elem.mut,
+                                           actual_elem.mut)) {
+                                case (none[ast.mutability]) {
+                                    auto err = terr_tuple_mutability;
+                                    ret ures_err(err, expected, actual);
+                                }
+                                case (some[ast.mutability](?m)) { mut = m; }
                             }
 
                             auto result = unify_step(bindings,
@@ -1290,8 +1318,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                                                      handler);
                             alt (result) {
                                 case (ures_ok(?rty)) {
-                                    auto mt = rec(ty=rty,
-                                                  mut=expected_elem.mut);
+                                    auto mt = rec(ty=rty, mut=mut);
                                     result_elems += vec(mt);
                                 }
                                 case (_) {
@@ -1329,10 +1356,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                         while (i < expected_len) {
                             auto expected_field = expected_fields.(i);
                             auto actual_field = actual_fields.(i);
-                            if (expected_field.mt.mut
-                                    != actual_field.mt.mut) {
-                                auto err = terr_record_mutability;
-                                ret ures_err(err, expected, actual);
+
+                            auto mut;
+                            alt (unify_mut(expected_field.mt.mut,
+                                           actual_field.mt.mut)) {
+                                case (none[ast.mutability]) {
+                                    ret ures_err(terr_record_mutability,
+                                                 expected, actual);
+                                }
+                                case (some[ast.mutability](?m)) { mut = m; }
                             }
 
                             if (!_str.eq(expected_field.ident,
@@ -1349,8 +1381,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                                                      handler);
                             alt (result) {
                                 case (ures_ok(?rty)) {
-                                    auto mt = rec(ty=rty,
-                                                  mut=expected_field.mt.mut);
+                                    auto mt = rec(ty=rty, mut=mut);
                                     _vec.push[field]
                                         (result_fields,
                                          rec(mt=mt with expected_field));
@@ -1490,6 +1521,12 @@ fn type_err_to_str(&ty.type_err err) -> str {
         case (terr_mismatch) {
             ret "types differ";
         }
+        case (terr_box_mutability) {
+            ret "boxed values differ in mutability";
+        }
+        case (terr_vec_mutability) {
+            ret "vectors differ in mutability";
+        }
         case (terr_tuple_size(?e_sz, ?a_sz)) {
             ret "expected a tuple with " + _uint.to_str(e_sz, 10u) +
                 " elements but found one with " + _uint.to_str(a_sz, 10u) +
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index f2e52d72178..6f5ea096b05 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -58,8 +58,10 @@ impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, &IN) op) {
 }
 
 impure fn print_mt(ps s, &ast.mt mt) {
-    if (mt.mut == ast.mut) {
-        wrd1(s, "mutable");
+    alt (mt.mut) {
+        case (ast.mut)       { wrd1(s, "mutable");  }
+        case (ast.maybe_mut) { wrd1(s, "mutable?"); }
+        case (ast.imm)       { /* nothing */        }
     }
     print_type(s, mt.ty);
 }
diff --git a/src/test/run-pass/maybe-mutable.rs b/src/test/run-pass/maybe-mutable.rs
new file mode 100644
index 00000000000..c0af0867faa
--- /dev/null
+++ b/src/test/run-pass/maybe-mutable.rs
@@ -0,0 +1,17 @@
+// -*- rust -*-
+
+fn len(vec[mutable? int] v) -> uint {
+    auto i = 0u;
+    for (int x in v) {
+        i += 1u;
+    }
+    ret i;
+}
+
+fn main() {
+    auto v0 = vec(1, 2, 3, 4, 5);
+    log len(v0);
+    auto v1 = vec(mutable 1, 2, 3, 4, 5);
+    log len(v1);
+}
+