From b620be9cd244368a3a0d354b0dec7e13b4b99527 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 23 May 2011 17:17:49 -0700 Subject: [PATCH] Typecheck @[] correctly Previously, if you wrote let @vec[int] foo = @[]; that would be a type error. That didn't seem right, so I changed pushdown to unify the inner type in an unop application with the argument type of the operator type. --- src/comp/middle/typeck.rs | 25 ++++++++++++++++++++++++ src/test/compile-fail/vector-no-ann-2.rs | 5 ----- src/test/run-pass/vector-no-ann-2.rs | 3 +++ 3 files changed, 28 insertions(+), 5 deletions(-) delete mode 100644 src/test/compile-fail/vector-no-ann-2.rs create mode 100644 src/test/run-pass/vector-no-ann-2.rs diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index aa636d9f2da0..41fe38403f01 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1317,6 +1317,31 @@ mod Pushdown { auto t = Demand::autoderef(scx, e.span, expected, ann_to_type(scx.fcx.ccx.tcx.node_types, ann), adk); write::ty_only_fixup(scx, ann.id, t); + + /* The following is a bit special-cased, but takes care of + the case where we say let @vec[whatever] v = @[]; */ + auto inner_ty = t; + alt (uop) { + case (ast::box(?mut)) { + alt (struct(scx.fcx.ccx.tcx, t)) { + case (ty::ty_box(?inner)) { inner_ty = inner.ty; } + case (_) { + scx.fcx.ccx.tcx.sess.span_err(e.span, + "Expecting an application of box" + + " to have a box type"); + } + } + } + case (ast::deref) { + inner_ty = ty::mk_box(scx.fcx.ccx.tcx, + // maybe_mut should work because it'll unify with + // the existing type? + rec(ty=t, mut=ast::maybe_mut)); + } + case (_) { inner_ty = strip_boxes(scx.fcx.ccx.tcx, t); } + } + + pushdown_expr(scx, inner_ty, sube); } case (ast::expr_lit(?lit, ?ann)) { auto t = Demand::simple(scx, e.span, expected, diff --git a/src/test/compile-fail/vector-no-ann-2.rs b/src/test/compile-fail/vector-no-ann-2.rs deleted file mode 100644 index c21d49e34dc4..000000000000 --- a/src/test/compile-fail/vector-no-ann-2.rs +++ /dev/null @@ -1,5 +0,0 @@ -// error-pattern:3:24:3:25 -fn main() -> () { - let @vec[uint] foo = @[]; -} -// this checks that span_err gets used diff --git a/src/test/run-pass/vector-no-ann-2.rs b/src/test/run-pass/vector-no-ann-2.rs new file mode 100644 index 000000000000..7302b8bdef1b --- /dev/null +++ b/src/test/run-pass/vector-no-ann-2.rs @@ -0,0 +1,3 @@ +fn main() -> () { + let @vec[uint] quux = @[]; +}