From 5318248f24afbcc61cf948bbcacd61d8b157c24a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 9 Jun 2011 17:11:21 -0700 Subject: [PATCH] rustc: Annotate vector and string literals in the AST with their uniqueness or lack thereof --- src/comp/front/ast.rs | 10 +++++-- src/comp/front/eval.rs | 2 +- src/comp/front/extenv.rs | 18 ++++------- src/comp/front/extfmt.rs | 13 ++++---- src/comp/front/parser.rs | 29 ++++++++++++++++-- src/comp/middle/trans.rs | 4 +-- src/comp/middle/tstate/pre_post_conditions.rs | 2 +- src/comp/middle/tstate/states.rs | 2 +- src/comp/middle/ty.rs | 30 ++++++++++++++++++- src/comp/middle/typeck.rs | 22 ++++++++++---- src/comp/middle/visit.rs | 2 +- src/comp/middle/walk.rs | 2 +- src/comp/pretty/ppaux.rs | 5 +++- src/comp/pretty/pprust.rs | 9 ++++-- src/comp/util/common.rs | 6 ++-- 15 files changed, 111 insertions(+), 45 deletions(-) diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 49749fde64d..b36a956464c 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -247,9 +247,15 @@ tag spawn_dom { dom_thread; } +// FIXME: temporary +tag seq_kind { + sk_unique; + sk_rc; +} + type expr = spanned[expr_]; tag expr_ { - expr_vec(vec[@expr], mutability, ann); + expr_vec(vec[@expr], mutability, seq_kind, ann); expr_tup(vec[elt], ann); expr_rec(vec[field], option::t[@expr], ann); expr_call(@expr, vec[@expr], ann); @@ -294,7 +300,7 @@ tag expr_ { type lit = spanned[lit_]; tag lit_ { - lit_str(str); + lit_str(str, seq_kind); lit_char(char); lit_int(int); lit_uint(uint); diff --git a/src/comp/front/eval.rs b/src/comp/front/eval.rs index a8e881ee036..567066436e4 100644 --- a/src/comp/front/eval.rs +++ b/src/comp/front/eval.rs @@ -104,7 +104,7 @@ fn eval_lit(ctx cx, span sp, @ast::lit lit) -> val { alt (lit.node) { case (ast::lit_bool(?b)) { ret val_bool(b); } case (ast::lit_int(?i)) { ret val_int(i); } - case (ast::lit_str(?s)) { ret val_str(s); } + case (ast::lit_str(?s,_)) { ret val_str(s); } case (_) { cx.sess.span_err(sp, "evaluating unsupported literal"); } diff --git a/src/comp/front/extenv.rs b/src/comp/front/extenv.rs index 62e39c8488b..b3410545c57 100644 --- a/src/comp/front/extenv.rs +++ b/src/comp/front/extenv.rs @@ -40,22 +40,15 @@ fn expand_syntax_ext(&ext_ctxt cx, // FIXME: duplicate code copied from extfmt: -fn expr_to_str(&ext_ctxt cx, - @ast::expr expr) -> str { +fn expr_to_str(&ext_ctxt cx, @ast::expr expr) -> str { alt (expr.node) { case (ast::expr_lit(?l, _)) { alt (l.node) { - case (ast::lit_str(?s)) { - ret s; - } - case (_) { - cx.span_err(l.span, "malformed #env call"); - } + case (ast::lit_str(?s,_)) { ret s; } + case (_) { cx.span_err(l.span, "malformed #env call"); } } } - case (_) { - cx.span_err(expr.span, "malformed #env call"); - } + case (_) { cx.span_err(expr.span, "malformed #env call"); } } } @@ -67,8 +60,7 @@ fn make_new_lit(&ext_ctxt cx, common::span sp, ast::lit_ lit) } fn make_new_str(&ext_ctxt cx, common::span sp, str s) -> @ast::expr { - auto lit = ast::lit_str(s); - ret make_new_lit(cx, sp, lit); + ret make_new_lit(cx, sp, ast::lit_str(s, ast::sk_rc)); } // diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs index c3d4fffcbab..eca0ddc9ba4 100644 --- a/src/comp/front/extfmt.rs +++ b/src/comp/front/extfmt.rs @@ -49,12 +49,8 @@ fn expr_to_str(&ext_ctxt cx, @ast::expr expr) -> str { alt (expr.node) { case (ast::expr_lit(?l, _)) { alt (l.node) { - case (ast::lit_str(?s)) { - ret s; - } - case (_) { - cx.span_err(l.span, err_msg); - } + case (ast::lit_str(?s,_)) { ret s; } + case (_) { cx.span_err(l.span, err_msg); } } } case (_) { @@ -77,7 +73,7 @@ fn pieces_to_expr(&ext_ctxt cx, common::span sp, } fn make_new_str(&ext_ctxt cx, common::span sp, str s) -> @ast::expr { - auto lit = ast::lit_str(s); + auto lit = ast::lit_str(s, ast::sk_rc); ret make_new_lit(cx, sp, lit); } @@ -109,7 +105,8 @@ fn pieces_to_expr(&ext_ctxt cx, common::span sp, fn make_vec_expr(&ext_ctxt cx, common::span sp, vec[@ast::expr] exprs) -> @ast::expr { - auto vecexpr = ast::expr_vec(exprs, ast::imm, cx.next_ann()); + auto vecexpr = ast::expr_vec(exprs, ast::imm, ast::sk_rc, + cx.next_ann()); auto sp_vecexpr = @rec(node=vecexpr, span=sp); ret sp_vecexpr; } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 5635050e7da..d3a8fa9a329 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -682,7 +682,7 @@ fn parse_lit(&parser p) -> ast::lit { } case (token::LIT_STR(?s)) { p.bump(); - lit = ast::lit_str(p.get_str(s)); + lit = ast::lit_str(p.get_str(s), ast::sk_rc); } case (?t) { unexpected(p, t); @@ -826,7 +826,30 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { auto es = parse_seq_to_end[@ast::expr](token::RBRACKET, some(token::COMMA), pf, p); - ex = ast::expr_vec(es, mut, p.get_ann()); + ex = ast::expr_vec(es, mut, ast::sk_rc, p.get_ann()); + } else if (p.peek() == token::TILDE) { + p.bump(); + alt (p.peek()) { + case (token::LBRACKET) { // unique array (temporary) + p.bump(); + auto mut = parse_mutability(p); + auto es = parse_seq_to_end(token::RBRACKET, + some(token::COMMA), parse_expr, p); + ex = ast::expr_vec(es, mut, ast::sk_unique, p.get_ann()); + } + case (token::LIT_STR(?s)) { + p.bump(); + auto lit = @rec( + node=ast::lit_str(p.get_str(s), ast::sk_unique), + span=p.get_span() + ); + ex = ast::expr_lit(lit, p.get_ann()); + } + case (_) { + p.get_session().span_unimpl(p.get_span(), + "unique pointer creation"); + } + } } else if (eat_word(p, "obj")) { // Anonymous object @@ -1632,7 +1655,7 @@ fn stmt_ends_with_semi(&ast::stmt stmt) -> bool { } case (ast::stmt_expr(?e,_)) { alt (e.node) { - case (ast::expr_vec(_,_,_)) { ret true; } + case (ast::expr_vec(_,_,_,_)) { ret true; } case (ast::expr_tup(_,_)) { ret true; } case (ast::expr_rec(_,_,_)) { ret true; } case (ast::expr_call(_,_,_)) { ret true; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 72a382c1361..0846f597103 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3365,7 +3365,7 @@ fn trans_lit(&@crate_ctxt cx, &ast::lit lit, &ast::ann ann) -> ValueRef { case (ast::lit_nil) { ret C_nil(); } - case (ast::lit_str(?s)) { + case (ast::lit_str(?s, _)) { ret C_str(cx, s); } } @@ -5619,7 +5619,7 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ret trans_cast(cx, e, ann); } - case (ast::expr_vec(?args, _, ?ann)) { + case (ast::expr_vec(?args, _, _, ?ann)) { ret trans_vec(cx, args, ann); } diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index 80d548d4c8b..af64f01a13e 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -265,7 +265,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () { vec::push[@expr](args, operator); find_pre_post_exprs(fcx, args, a); } - case (expr_vec(?args, _, ?a)) { + case (expr_vec(?args, _, _, ?a)) { find_pre_post_exprs(fcx, args, a); } case (expr_tup(?elts, ?a)) { diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index f47076cc324..1669d4e6970 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -143,7 +143,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool { /* FIXME could get rid of some of the copy/paste */ alt (e.node) { - case (expr_vec(?elts, _, ?a)) { + case (expr_vec(?elts, _, _, ?a)) { ret find_pre_post_state_exprs(fcx, pres, a, elts); } case (expr_tup(?elts, ?a)) { diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index bd4944580a8..acfcb93cb2f 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1580,7 +1580,7 @@ fn item_ann(&@ast::item it) -> ast::ann { fn expr_ann(&@ast::expr e) -> ast::ann { alt (e.node) { - case (ast::expr_vec(_,_,?a)) { ret a; } + case (ast::expr_vec(_,_,_,?a)) { ret a; } case (ast::expr_tup(_,?a)) { ret a; } case (ast::expr_rec(_,_,?a)) { ret a; } case (ast::expr_call(_,_,?a)) { ret a; } @@ -2139,6 +2139,7 @@ mod unify { case (ty::ty_float) { ret struct_cmp(cx, expected, actual); } case (ty::ty_char) { ret struct_cmp(cx, expected, actual); } case (ty::ty_str) { ret struct_cmp(cx, expected, actual); } + case (ty::ty_istr) { ret struct_cmp(cx, expected, actual); } case (ty::ty_type) { ret struct_cmp(cx, expected, actual); } case (ty::ty_native) { ret struct_cmp(cx, expected, actual); } case (ty::ty_param(_)) { ret struct_cmp(cx, expected, actual); } @@ -2238,6 +2239,33 @@ mod unify { } } + case (ty::ty_ivec(?expected_mt)) { + alt (struct(cx.tcx, actual)) { + case (ty::ty_ivec(?actual_mt)) { + auto mut; + alt (unify_mut(expected_mt.mut, actual_mt.mut)) { + case (none) { ret ures_err(terr_vec_mutability); } + case (some(?m)) { mut = m; } + } + + auto result = unify_step(cx, + expected_mt.ty, + actual_mt.ty); + alt (result) { + case (ures_ok(?result_sub)) { + auto mt = rec(ty=result_sub, mut=mut); + ret ures_ok(mk_ivec(cx.tcx, mt)); + } + case (_) { + ret result; + } + } + } + + case (_) { ret ures_err(terr_mismatch); } + } + } + case (ty::ty_port(?expected_sub)) { alt (struct(cx.tcx, actual)) { case (ty::ty_port(?actual_sub)) { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index b6f5f71fbc8..637e4c05669 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1259,7 +1259,8 @@ fn replace_node_type_only(&ty::ctxt tcx, uint fixup, ty::t new_t) { fn check_lit(@crate_ctxt ccx, &@ast::lit lit) -> ty::t { alt (lit.node) { - case (ast::lit_str(_)) { ret ty::mk_str(ccx.tcx); } + case (ast::lit_str(_, ast::sk_rc)) { ret ty::mk_str(ccx.tcx); } + case (ast::lit_str(_, ast::sk_unique)) { ret ty::mk_istr(ccx.tcx); } case (ast::lit_char(_)) { ret ty::mk_char(ccx.tcx); } case (ast::lit_int(_)) { ret ty::mk_int(ccx.tcx); } case (ast::lit_float(_)) { ret ty::mk_float(ccx.tcx); } @@ -1334,9 +1335,9 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) { fcx.ccx.tcx.sess.span_err(pat.span, #fmt( "this pattern has %u field%s, but the corresponding variant has %u field%s", subpats_len, - if (subpats_len == 0u) { "" } else { "s" }, + if (subpats_len == 1u) { "" } else { "s" }, arg_len, - if (arg_len == 0u) { "" } else { "s" })); + if (arg_len == 1u) { "" } else { "s" })); } // TODO: vec::iter2 @@ -1352,7 +1353,7 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) { fcx.ccx.tcx.sess.span_err(pat.span, #fmt( "this pattern has %u field%s, but the corresponding variant has no fields", subpats_len, - if (subpats_len == 0u) { "" } else { "s" })); + if (subpats_len == 1u) { "" } else { "s" })); } write::ty_fixup(fcx, ann.id, path_tpot); @@ -2025,7 +2026,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) { write::ty_only_fixup(fcx, a.id, t_1); } - case (ast::expr_vec(?args, ?mut, ?a)) { + case (ast::expr_vec(?args, ?mut, ?kind, ?a)) { let ty::t t; if (vec::len[@ast::expr](args) == 0u) { t = next_ty_var(fcx); @@ -2040,7 +2041,16 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) { demand::simple(fcx, expr.span, t, expr_t); } - auto typ = ty::mk_vec(fcx.ccx.tcx, rec(ty=t, mut=mut)); + auto typ; + alt (kind) { + case (ast::sk_rc) { + typ = ty::mk_vec(fcx.ccx.tcx, rec(ty=t, mut=mut)); + } + case (ast::sk_unique) { + typ = ty::mk_ivec(fcx.ccx.tcx, rec(ty=t, mut=mut)); + } + } + write::ty_only_fixup(fcx, a.id, typ); } diff --git a/src/comp/middle/visit.rs b/src/comp/middle/visit.rs index 48901800e95..bc0740d9fb7 100644 --- a/src/comp/middle/visit.rs +++ b/src/comp/middle/visit.rs @@ -246,7 +246,7 @@ fn visit_exprs[E](vec[@expr] exprs, &E e, &vt[E] v) { fn visit_expr[E](&@expr ex, &E e, &vt[E] v) { alt (ex.node) { - case (expr_vec(?es, _, _)) { + case (expr_vec(?es, _, _, _)) { visit_exprs(es, e, v); } case (expr_tup(?elts, _)) { diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs index 11f0fd10c28..6b568ba0a5b 100644 --- a/src/comp/middle/walk.rs +++ b/src/comp/middle/walk.rs @@ -321,7 +321,7 @@ fn walk_expr(&ast_visitor v, @ast::expr e) { if (!v.keep_going()) { ret; } v.visit_expr_pre(e); alt (e.node) { - case (ast::expr_vec(?es, _, _)) { + case (ast::expr_vec(?es, _, _, _)) { walk_exprs(v, es); } case (ast::expr_tup(?elts, _)) { diff --git a/src/comp/pretty/ppaux.rs b/src/comp/pretty/ppaux.rs index 694291dcca9..3e9a3918e9a 100644 --- a/src/comp/pretty/ppaux.rs +++ b/src/comp/pretty/ppaux.rs @@ -225,7 +225,10 @@ fn print_literal(&ps s, &@ast::lit lit) { } alt (lit.node) { - case (ast::lit_str(?st)) {print_string(s, st);} + case (ast::lit_str(?st,?kind)) { + if (kind == ast::sk_unique) { word(s.s, "~"); } + print_string(s, st); + } case (ast::lit_char(?ch)) { word(s.s, "'" + escape_str(str::from_bytes([ch as u8]), '\'') + "'"); diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 2fd0356365b..20fe17c48c0 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -463,9 +463,14 @@ fn print_expr(&ps s, &@ast::expr expr) { } alt (expr.node) { - case (ast::expr_vec(?exprs,?mut,_)) { + case (ast::expr_vec(?exprs,?mut,?kind,_)) { ibox(s, indent_unit); - word(s.s, "["); + + alt (kind) { + case (ast::sk_rc) { word(s.s, "["); } + case (ast::sk_unique) { word(s.s, "~["); } + } + if (mut == ast::mut) { word_nbsp(s, "mutable"); } diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs index 443063c6f3f..5669aa5b2fa 100644 --- a/src/comp/util/common.rs +++ b/src/comp/util/common.rs @@ -233,9 +233,11 @@ fn local_rhs_span(&@ast::local l, &span def) -> span { fn lit_eq(&@ast::lit l, &@ast::lit m) -> bool { alt (l.node) { - case (ast::lit_str(?s)) { + case (ast::lit_str(?s,?kind_s)) { alt (m.node) { - case (ast::lit_str(?t)) { ret s == t; } + case (ast::lit_str(?t,?kind_t)) { + ret s == t && kind_s == kind_t; + } case (_) { ret false; } } }