Skip to content

Commit 2ef9c01

Browse files
committed
rustc: Implement "mutable?". Add a test case and XFAIL it in rustboot for now.
1 parent 4c2245d commit 2ef9c01

File tree

6 files changed

+87
-25
lines changed

6 files changed

+87
-25
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
456456
test/run-pass/iter-ret.rs \
457457
test/run-pass/leak-tag-copy.rs \
458458
test/run-pass/lib-io.rs \
459+
test/run-pass/maybe-mutable.rs \
459460
test/run-pass/mlist-cycle.rs \
460461
test/run-pass/obj-as.rs \
461462
test/run-pass/seq-compare.rs \

src/comp/front/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ tag pat_ {
9191
tag mutability {
9292
mut;
9393
imm;
94+
maybe_mut;
9495
}
9596

9697
tag opacity {

src/comp/front/parser.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,10 @@ impure fn parse_path(parser p, greed g) -> ast.path {
615615
impure fn parse_mutability(parser p) -> ast.mutability {
616616
if (p.peek() == token.MUTABLE) {
617617
p.bump();
618+
if (p.peek() == token.QUES) {
619+
p.bump();
620+
ret ast.maybe_mut;
621+
}
618622
ret ast.mut;
619623
}
620624
ret ast.imm;

src/comp/middle/ty.rs

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ fn ty_to_str(&@t typ) -> str {
148148
fn mt_to_str(&mt m) -> str {
149149
auto mstr;
150150
alt (m.mut) {
151-
case (ast.mut) { mstr = "mutable "; }
152-
case (ast.imm) { mstr = ""; }
151+
case (ast.mut) { mstr = "mutable "; }
152+
case (ast.imm) { mstr = ""; }
153+
case (ast.maybe_mut) { mstr = "mutable? "; }
153154
}
154155

155156
ret mstr + ty_to_str(m.ty);
@@ -858,6 +859,21 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
858859
ret ures_err(terr_mismatch, expected, actual);
859860
}
860861

862+
// Unifies two mutability flags.
863+
fn unify_mut(ast.mutability expected, ast.mutability actual)
864+
-> option.t[ast.mutability] {
865+
if (expected == actual) {
866+
ret some[ast.mutability](expected);
867+
}
868+
if (expected == ast.maybe_mut) {
869+
ret some[ast.mutability](actual);
870+
}
871+
if (actual == ast.maybe_mut) {
872+
ret some[ast.mutability](expected);
873+
}
874+
ret none[ast.mutability];
875+
}
876+
861877
tag fn_common_res {
862878
fn_common_res_err(unify_result);
863879
fn_common_res_ok(vec[arg], @t);
@@ -1158,9 +1174,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
11581174
case (ty.ty_box(?expected_mt)) {
11591175
alt (actual.struct) {
11601176
case (ty.ty_box(?actual_mt)) {
1161-
if (expected_mt.mut != actual_mt.mut) {
1162-
ret ures_err(terr_box_mutability, expected,
1163-
actual);
1177+
auto mut;
1178+
alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
1179+
case (none[ast.mutability]) {
1180+
ret ures_err(terr_box_mutability, expected,
1181+
actual);
1182+
}
1183+
case (some[ast.mutability](?m)) { mut = m; }
11641184
}
11651185

11661186
auto result = unify_step(bindings,
@@ -1169,8 +1189,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
11691189
handler);
11701190
alt (result) {
11711191
case (ures_ok(?result_sub)) {
1172-
auto mt = rec(ty=result_sub,
1173-
mut=expected_mt.mut);
1192+
auto mt = rec(ty=result_sub, mut=mut);
11741193
ret ures_ok(plain_ty(ty.ty_box(mt)));
11751194
}
11761195
case (_) {
@@ -1188,9 +1207,13 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
11881207
case (ty.ty_vec(?expected_mt)) {
11891208
alt (actual.struct) {
11901209
case (ty.ty_vec(?actual_mt)) {
1191-
if (expected_mt.mut != actual_mt.mut) {
1192-
ret ures_err(terr_vec_mutability, expected,
1193-
actual);
1210+
auto mut;
1211+
alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
1212+
case (none[ast.mutability]) {
1213+
ret ures_err(terr_vec_mutability, expected,
1214+
actual);
1215+
}
1216+
case (some[ast.mutability](?m)) { mut = m; }
11941217
}
11951218

11961219
auto result = unify_step(bindings,
@@ -1199,8 +1222,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
11991222
handler);
12001223
alt (result) {
12011224
case (ures_ok(?result_sub)) {
1202-
auto mt = rec(ty=result_sub,
1203-
mut=expected_mt.mut);
1225+
auto mt = rec(ty=result_sub, mut=mut);
12041226
ret ures_ok(plain_ty(ty.ty_vec(mt)));
12051227
}
12061228
case (_) {
@@ -1279,9 +1301,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
12791301
while (i < expected_len) {
12801302
auto expected_elem = expected_elems.(i);
12811303
auto actual_elem = actual_elems.(i);
1282-
if (expected_elem.mut != actual_elem.mut) {
1283-
auto err = terr_tuple_mutability;
1284-
ret ures_err(err, expected, actual);
1304+
1305+
auto mut;
1306+
alt (unify_mut(expected_elem.mut,
1307+
actual_elem.mut)) {
1308+
case (none[ast.mutability]) {
1309+
auto err = terr_tuple_mutability;
1310+
ret ures_err(err, expected, actual);
1311+
}
1312+
case (some[ast.mutability](?m)) { mut = m; }
12851313
}
12861314

12871315
auto result = unify_step(bindings,
@@ -1290,8 +1318,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
12901318
handler);
12911319
alt (result) {
12921320
case (ures_ok(?rty)) {
1293-
auto mt = rec(ty=rty,
1294-
mut=expected_elem.mut);
1321+
auto mt = rec(ty=rty, mut=mut);
12951322
result_elems += vec(mt);
12961323
}
12971324
case (_) {
@@ -1329,10 +1356,15 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
13291356
while (i < expected_len) {
13301357
auto expected_field = expected_fields.(i);
13311358
auto actual_field = actual_fields.(i);
1332-
if (expected_field.mt.mut
1333-
!= actual_field.mt.mut) {
1334-
auto err = terr_record_mutability;
1335-
ret ures_err(err, expected, actual);
1359+
1360+
auto mut;
1361+
alt (unify_mut(expected_field.mt.mut,
1362+
actual_field.mt.mut)) {
1363+
case (none[ast.mutability]) {
1364+
ret ures_err(terr_record_mutability,
1365+
expected, actual);
1366+
}
1367+
case (some[ast.mutability](?m)) { mut = m; }
13361368
}
13371369

13381370
if (!_str.eq(expected_field.ident,
@@ -1349,8 +1381,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
13491381
handler);
13501382
alt (result) {
13511383
case (ures_ok(?rty)) {
1352-
auto mt = rec(ty=rty,
1353-
mut=expected_field.mt.mut);
1384+
auto mt = rec(ty=rty, mut=mut);
13541385
_vec.push[field]
13551386
(result_fields,
13561387
rec(mt=mt with expected_field));
@@ -1490,6 +1521,12 @@ fn type_err_to_str(&ty.type_err err) -> str {
14901521
case (terr_mismatch) {
14911522
ret "types differ";
14921523
}
1524+
case (terr_box_mutability) {
1525+
ret "boxed values differ in mutability";
1526+
}
1527+
case (terr_vec_mutability) {
1528+
ret "vectors differ in mutability";
1529+
}
14931530
case (terr_tuple_size(?e_sz, ?a_sz)) {
14941531
ret "expected a tuple with " + _uint.to_str(e_sz, 10u) +
14951532
" elements but found one with " + _uint.to_str(a_sz, 10u) +

src/comp/pretty/pprust.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, &IN) op) {
5858
}
5959

6060
impure fn print_mt(ps s, &ast.mt mt) {
61-
if (mt.mut == ast.mut) {
62-
wrd1(s, "mutable");
61+
alt (mt.mut) {
62+
case (ast.mut) { wrd1(s, "mutable"); }
63+
case (ast.maybe_mut) { wrd1(s, "mutable?"); }
64+
case (ast.imm) { /* nothing */ }
6365
}
6466
print_type(s, mt.ty);
6567
}

src/test/run-pass/maybe-mutable.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// -*- rust -*-
2+
3+
fn len(vec[mutable? int] v) -> uint {
4+
auto i = 0u;
5+
for (int x in v) {
6+
i += 1u;
7+
}
8+
ret i;
9+
}
10+
11+
fn main() {
12+
auto v0 = vec(1, 2, 3, 4, 5);
13+
log len(v0);
14+
auto v1 = vec(mutable 1, 2, 3, 4, 5);
15+
log len(v1);
16+
}
17+

0 commit comments

Comments
 (0)