rustc: Annotate vector and string literals in the AST with their uniqueness or lack thereof

This commit is contained in:
Patrick Walton 2011-06-09 17:11:21 -07:00
parent 1c48102838
commit 5318248f24
15 changed files with 111 additions and 45 deletions

View File

@ -247,9 +247,15 @@ fn unop_to_str(unop op) -> str {
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 @@ fn unop_to_str(unop op) -> str {
type lit = spanned[lit_];
tag lit_ {
lit_str(str);
lit_str(str, seq_kind);
lit_char(char);
lit_int(int);
lit_uint(uint);

View File

@ -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");
}

View File

@ -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));
}
//

View File

@ -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 make_new_lit(&ext_ctxt cx,
}
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 make_path_expr(&ext_ctxt cx, common::span sp, vec[ast::ident] idents)
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;
}

View File

@ -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_elt(&parser p) -> ast::elt {
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; }

View File

@ -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);
}

View File

@ -265,7 +265,7 @@ fn do_rand_(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)) {

View File

@ -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)) {

View File

@ -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 @@ fn unify_step(&@ctxt cx, &t expected, &t actual) -> result {
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 @@ fn unify_step(&@ctxt cx, &t expected, &t actual) -> result {
}
}
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)) {

View File

@ -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_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
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_for_or_for_each(&@fn_ctxt fcx, &@ast::decl decl,
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);
}

View File

@ -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, _)) {

View File

@ -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, _)) {

View File

@ -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]), '\'')
+ "'");

View File

@ -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");
}

View File

@ -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; }
}
}