Preserve parenthesization in the AST
Maintain explicit "paren" nodes in the AST so we can pretty-print without having to guess where parens should go. We may revisit this in the future. r=graydon
This commit is contained in:
@@ -98,6 +98,8 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
|
||||
}
|
||||
}
|
||||
}
|
||||
expr_paren(e) => { check_expr(sess, def_map, method_map,
|
||||
tcx, e, is_const, v); }
|
||||
expr_vstore(_, expr_vstore_slice) |
|
||||
expr_vstore(_, expr_vstore_fixed(_)) |
|
||||
expr_vec(_, m_imm) |
|
||||
|
||||
@@ -72,7 +72,8 @@ fn classify(e: @expr,
|
||||
}
|
||||
|
||||
ast::expr_copy(inner) |
|
||||
ast::expr_unary(_, inner) => {
|
||||
ast::expr_unary(_, inner) |
|
||||
ast::expr_paren(inner) => {
|
||||
classify(inner, def_map, tcx)
|
||||
}
|
||||
|
||||
@@ -376,6 +377,7 @@ fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: @expr)
|
||||
expr_lit(lit) => Ok(lit_to_const(lit)),
|
||||
// If we have a vstore, just keep going; it has to be a string
|
||||
expr_vstore(e, _) => eval_const_expr_partial(tcx, e),
|
||||
expr_paren(e) => eval_const_expr_partial(tcx, e),
|
||||
_ => Err(~"Unsupported constant expr")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ fn visit_expr(expr: @expr, &&self: @IrMaps, vt: vt<@IrMaps>) {
|
||||
expr_break(_) | expr_again(_) | expr_lit(_) | expr_ret(*) |
|
||||
expr_block(*) | expr_unary_move(*) | expr_assign(*) |
|
||||
expr_swap(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) |
|
||||
expr_repeat(*) => {
|
||||
expr_repeat(*) | expr_paren(*) => {
|
||||
visit::visit_expr(expr, self, vt);
|
||||
}
|
||||
}
|
||||
@@ -1253,7 +1253,8 @@ impl Liveness {
|
||||
expr_loop_body(e) |
|
||||
expr_do_body(e) |
|
||||
expr_cast(e, _) |
|
||||
expr_unary(_, e) => {
|
||||
expr_unary(_, e) |
|
||||
expr_paren(e) => {
|
||||
self.propagate_through_expr(e, succ)
|
||||
}
|
||||
|
||||
@@ -1550,7 +1551,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
|
||||
expr_cast(*) | expr_unary(*) | expr_fail(*) |
|
||||
expr_ret(*) | expr_break(*) | expr_again(*) | expr_lit(_) |
|
||||
expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) |
|
||||
expr_struct(*) | expr_repeat(*) => {
|
||||
expr_struct(*) | expr_repeat(*) | expr_paren(*) => {
|
||||
visit::visit_expr(expr, self, vt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,6 +481,8 @@ impl &mem_categorization_ctxt {
|
||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||
}
|
||||
|
||||
ast::expr_paren(e) => self.cat_expr_unadjusted(e),
|
||||
|
||||
ast::expr_addr_of(*) | ast::expr_call(*) |
|
||||
ast::expr_swap(*) | ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) | ast::expr_fn(*) | ast::expr_fn_block(*) |
|
||||
|
||||
@@ -361,6 +361,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
||||
_ => cx.sess.span_bug(e.span, ~"expected to find a const def")
|
||||
}
|
||||
}
|
||||
ast::expr_paren(e) => { return const_expr(cx, e); }
|
||||
_ => cx.sess.span_bug(e.span,
|
||||
~"bad constant expression type in consts::const_expr")
|
||||
};
|
||||
|
||||
@@ -161,7 +161,6 @@ impl Dest : cmp::Eq {
|
||||
|
||||
fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
debug!("trans_to_datum(expr=%s)", bcx.expr_to_str(expr));
|
||||
|
||||
return match bcx.tcx().adjustments.find(expr.id) {
|
||||
None => {
|
||||
trans_to_datum_unadjusted(bcx, expr)
|
||||
@@ -392,6 +391,9 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
ast::expr_cast(val, _) => {
|
||||
return trans_imm_cast(bcx, val, expr.id);
|
||||
}
|
||||
ast::expr_paren(e) => {
|
||||
return trans_rvalue_datum_unadjusted(bcx, e);
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(
|
||||
expr.span,
|
||||
@@ -450,6 +452,9 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
|
||||
ast::expr_assign_op(op, dst, src) => {
|
||||
return trans_assign_op(bcx, expr, op, dst, src);
|
||||
}
|
||||
ast::expr_paren(a) => {
|
||||
return trans_rvalue_stmt_unadjusted(bcx, a);
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(
|
||||
expr.span,
|
||||
@@ -469,6 +474,9 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
|
||||
trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
|
||||
|
||||
match expr.node {
|
||||
ast::expr_paren(e) => {
|
||||
return trans_rvalue_dps_unadjusted(bcx, e, dest);
|
||||
}
|
||||
ast::expr_path(_) => {
|
||||
return trans_def_dps_unadjusted(bcx, expr,
|
||||
bcx.def(expr.id), dest);
|
||||
@@ -690,6 +698,9 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||
let mut bcx = bcx;
|
||||
|
||||
match expr.node {
|
||||
ast::expr_paren(e) => {
|
||||
return unrooted(bcx, e);
|
||||
}
|
||||
ast::expr_path(_) => {
|
||||
return trans_def_lvalue(bcx, expr, bcx.def(expr.id));
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
expr_paren(e) => mark_for_expr(cx, e),
|
||||
expr_match(*) | expr_block(_) | expr_if(*) |
|
||||
expr_while(*) | expr_fail(_) | expr_break(_) | expr_again(_) |
|
||||
expr_unary(_, _) | expr_lit(_) | expr_assert(_) |
|
||||
|
||||
@@ -2872,24 +2872,6 @@ fn is_pred_ty(fty: t) -> bool {
|
||||
is_fn_ty(fty) && type_is_bool(ty_fn_ret(fty))
|
||||
}
|
||||
|
||||
/*
|
||||
fn ty_var_id(typ: t) -> TyVid {
|
||||
match get(typ).sty {
|
||||
ty_infer(TyVar(vid)) => return vid,
|
||||
_ => { error!("ty_var_id called on non-var ty"); fail; }
|
||||
}
|
||||
}
|
||||
|
||||
fn int_var_id(typ: t) -> IntVid {
|
||||
match get(typ).sty {
|
||||
ty_infer(IntVar(vid)) => return vid,
|
||||
_ => { error!("ty_var_integral_id called on ty other than \
|
||||
ty_var_integral");
|
||||
fail; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Type accessors for AST nodes
|
||||
fn block_ty(cx: ctxt, b: &ast::blk) -> t {
|
||||
return node_id_to_type(cx, b.node.id);
|
||||
@@ -3094,6 +3076,8 @@ fn expr_kind(tcx: ctxt,
|
||||
RvalueDatumExpr
|
||||
}
|
||||
|
||||
ast::expr_paren(e) => expr_kind(tcx, method_map, e),
|
||||
|
||||
ast::expr_mac(*) => {
|
||||
tcx.sess.span_bug(
|
||||
expr.span,
|
||||
|
||||
@@ -990,11 +990,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
debug!("check_call_inner: after universal quant., fty=%s",
|
||||
fcx.infcx().ty_to_str(fty));
|
||||
|
||||
let supplied_arg_count = vec::len(args);
|
||||
let supplied_arg_count = args.len();
|
||||
|
||||
// Grab the argument types, supplying fresh type variables
|
||||
// if the wrong number of arguments were supplied
|
||||
let expected_arg_count = vec::len(fn_ty.sig.inputs);
|
||||
let expected_arg_count = fn_ty.sig.inputs.len();
|
||||
let formal_tys = if expected_arg_count == supplied_arg_count {
|
||||
fn_ty.sig.inputs.map(|a| a.ty)
|
||||
} else {
|
||||
@@ -1058,8 +1058,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
|
||||
bot |= check_expr_with_unifier(
|
||||
fcx, *arg, Some(formal_ty),
|
||||
|| demand::assign(fcx, arg.span, formal_ty, *arg)
|
||||
|| demand::assign(fcx, arg.span,
|
||||
formal_ty, *arg)
|
||||
);
|
||||
fcx.write_ty(arg.id, fcx.expr_ty(*arg));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1369,12 +1372,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
let expr_t = structurally_resolved_type(fcx, expr.span,
|
||||
fcx.expr_ty(base));
|
||||
let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t);
|
||||
let n_tys = vec::len(tys);
|
||||
let n_tys = tys.len();
|
||||
|
||||
match structure_of(fcx, expr.span, base_t) {
|
||||
ty::ty_rec(fields) => {
|
||||
match ty::field_idx(field, fields) {
|
||||
Some(ix) => {
|
||||
if n_tys > 0u {
|
||||
if n_tys > 0 {
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
~"can't provide type parameters \
|
||||
@@ -1680,7 +1684,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
ty::mk_estr(tcx, tt)
|
||||
}
|
||||
ast::expr_vec(args, mutbl) => {
|
||||
let tt = ast_expr_vstore_to_vstore(fcx, ev, vec::len(args), vst);
|
||||
let tt = ast_expr_vstore_to_vstore(fcx, ev, args.len(), vst);
|
||||
let t: ty::t = fcx.infcx().next_ty_var();
|
||||
for args.each |e| { bot |= check_expr_with(fcx, *e, t); }
|
||||
ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt)
|
||||
@@ -1871,6 +1875,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
bot = check_expr(fcx, a, expected);
|
||||
fcx.write_ty(id, fcx.expr_ty(a));
|
||||
}
|
||||
ast::expr_paren(a) => {
|
||||
bot = check_expr_with_unifier(fcx, a, expected, || ());
|
||||
fcx.write_ty(id, fcx.expr_ty(a));
|
||||
do expected.iter |i| {
|
||||
demand::assign(fcx, expr.span, *i, expr);
|
||||
demand::assign(fcx, a.span, *i, a);
|
||||
};
|
||||
}
|
||||
ast::expr_assign(lhs, rhs) => {
|
||||
bot = check_assignment(fcx, expr.span, lhs, rhs, id);
|
||||
}
|
||||
@@ -2583,9 +2595,9 @@ fn instantiate_path(fcx: @fn_ctxt,
|
||||
|
||||
// determine values for type parameters, using the values given by
|
||||
// the user (if any) and otherwise using fresh type variables
|
||||
let tps = if ty_substs_len == 0u {
|
||||
let tps = if ty_substs_len == 0 {
|
||||
fcx.infcx().next_ty_vars(ty_param_count)
|
||||
} else if ty_param_count == 0u {
|
||||
} else if ty_param_count == 0 {
|
||||
fcx.ccx.tcx.sess.span_err
|
||||
(span, ~"this item does not take type parameters");
|
||||
fcx.infcx().next_ty_vars(ty_param_count)
|
||||
|
||||
@@ -132,6 +132,10 @@ fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
|
||||
instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id,
|
||||
pcx.block_region);
|
||||
|
||||
// structure_of requires type variables to be resolved.
|
||||
// So when we pass in <expected>, it's an error if it
|
||||
// contains type variables.
|
||||
|
||||
// Take the enum type params out of `expected`.
|
||||
match structure_of(pcx.fcx, pat.span, expected) {
|
||||
ty::ty_enum(_, ref expected_substs) => {
|
||||
@@ -151,7 +155,7 @@ fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
|
||||
None => arg_len,
|
||||
Some(ps) => ps.len()
|
||||
};
|
||||
if arg_len > 0u {
|
||||
if arg_len > 0 {
|
||||
// N-ary variant.
|
||||
if arg_len != subpats_len {
|
||||
let s = fmt!("this pattern has %u field%s, but the \
|
||||
@@ -168,7 +172,7 @@ fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
|
||||
check_pat(pcx, *subpat, *arg_ty);
|
||||
}
|
||||
};
|
||||
} else if subpats_len > 0u {
|
||||
} else if subpats_len > 0 {
|
||||
tcx.sess.span_fatal
|
||||
(pat.span, fmt!("this pattern has %u field%s, \
|
||||
but the corresponding variant has no fields",
|
||||
|
||||
@@ -486,6 +486,11 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
ast::expr_paren(e) => {
|
||||
early_resolve_expr(e, fcx, is_early);
|
||||
}
|
||||
|
||||
// Must resolve bounds on methods with bounded params
|
||||
ast::expr_field(*) | ast::expr_binary(*) |
|
||||
ast::expr_unary(*) | ast::expr_assign_op(*) |
|
||||
|
||||
Reference in New Issue
Block a user