1
Fork 0

Type checking and trans for ranges

This commit is contained in:
Nick Cameron 2014-12-15 13:17:11 +13:00
parent 8a357e1d87
commit 17826e10a2
8 changed files with 102 additions and 29 deletions

View file

@ -439,8 +439,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
start.iter().chain(end.iter()).map(|x| &**x))
}
ast::ExprRange(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared range");
ast::ExprRange(ref start, ref end) => {
let fields = Some(&**start).into_iter()
.chain(end.as_ref().map(|e| &**e).into_iter());
self.straightline(expr, pred, fields)
}
ast::ExprUnary(_, ref e) if self.is_method_call(expr) => {

View file

@ -465,8 +465,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
assert!(overloaded);
}
ast::ExprRange(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared range");
ast::ExprRange(ref start, ref end) => {
self.consume_expr(&**start);
end.as_ref().map(|e| self.consume_expr(&**e));
}
ast::ExprCall(ref callee, ref args) => { // callee(args)

View file

@ -486,9 +486,6 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ast::ExprWhileLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
debug!("adding local variable {} from for loop with bm {}",
@ -517,7 +514,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
ast::ExprSlice(..) => {
ast::ExprSlice(..) | ast::ExprRange(..) => {
visit::walk_expr(ir, expr);
}
}
@ -1200,8 +1197,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**e1, succ)
}
ast::ExprRange(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
ast::ExprRange(ref e1, ref e2) => {
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
self.propagate_through_expr(&**e1, succ)
}
ast::ExprBox(None, ref e) |
@ -1496,7 +1494,8 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) |
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => {
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
ast::ExprSlice(..) | ast::ExprRange(..) => {
visit::walk_expr(this, expr);
}
ast::ExprIfLet(..) => {
@ -1505,9 +1504,6 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ast::ExprWhileLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
}
}
}

View file

@ -541,7 +541,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
ast::ExprAddrOf(..) | ast::ExprCall(..) |
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
ast::ExprClosure(..) | ast::ExprRet(..) |
ast::ExprUnary(..) | ast::ExprSlice(..) |
ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprRange(..) |
ast::ExprMethodCall(..) | ast::ExprCast(..) |
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
ast::ExprBinary(..) | ast::ExprWhile(..) |
@ -559,9 +559,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared range");
}
}
}

View file

@ -4257,6 +4257,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
ast::ExprCall(..) |
ast::ExprMethodCall(..) |
ast::ExprStruct(..) |
ast::ExprRange(..) |
ast::ExprTup(..) |
ast::ExprIf(..) |
ast::ExprMatch(..) |
@ -4273,9 +4274,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
ast::ExprWhileLet(..) => {
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprRange(..) => {
tcx.sess.span_bug(expr.span, "non-desugared range");
}
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
RvalueDpsExpr

View file

@ -3494,9 +3494,9 @@ fn populate_scope_map(cx: &CrateContext,
end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
}
ast::ExprRange(..) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
Found unexpanded range.");
ast::ExprRange(ref start, ref end) => {
walk_expr(cx, &**start, scope_stack, scope_map);
end.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map));
}
ast::ExprVec(ref init_expressions) |

View file

@ -39,7 +39,7 @@ use back::abi;
use llvm::{mod, ValueRef};
use middle::def;
use middle::mem_categorization::Typer;
use middle::subst::{mod, Subst};
use middle::subst::{mod, Subst, Substs};
use trans::{_match, adt, asm, base, callee, closure, consts, controlflow};
use trans::base::*;
use trans::build::*;
@ -66,6 +66,7 @@ use trans::type_::Type;
use syntax::{ast, ast_util, codemap};
use syntax::print::pprust::{expr_to_string};
use syntax::ptr::P;
use syntax::parse::token;
use std::rc::Rc;
// Destinations
@ -1048,8 +1049,49 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
base.as_ref().map(|e| &**e),
expr.span,
expr.id,
node_id_type(bcx, expr.id),
dest)
}
ast::ExprRange(ref start, ref end) => {
// FIXME it is just not right that we are synthesising ast nodes in
// trans. Shudder.
fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
ast::Field {
ident: codemap::dummy_spanned(token::str_to_ident(field_name)),
expr: expr,
span: codemap::DUMMY_SP,
}
}
// A range just desugars into a struct.
let (did, fields) = match end {
&Some(ref end) => {
// Desugar to Range
let fields = vec!(make_field("start", start.clone()),
make_field("end", end.clone()));
(tcx.lang_items.range_struct(), fields)
}
&None => {
// Desugar to RangeFrom
let fields = vec!(make_field("start", start.clone()));
(tcx.lang_items.range_from_struct(), fields)
}
};
if let Some(did) = did {
let substs = Substs::new_type(vec![node_id_type(bcx, start.id)], vec![]);
trans_struct(bcx,
fields.as_slice(),
None,
expr.span,
expr.id,
ty::mk_struct(tcx, did, substs),
dest)
} else {
tcx.sess.span_bug(expr.span,
"No lang item for ranges (how did we get this far?)")
}
}
ast::ExprTup(ref args) => {
let numbered_fields: Vec<(uint, &ast::Expr)> =
args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect();
@ -1347,10 +1389,10 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
base: Option<&ast::Expr>,
expr_span: codemap::Span,
expr_id: ast::NodeId,
ty: Ty<'tcx>,
dest: Dest) -> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_rec");
let ty = node_id_type(bcx, expr_id);
let tcx = bcx.tcx();
with_field_tys(tcx, ty, Some(expr_id), |discr, field_tys| {
let mut need_base = Vec::from_elem(field_tys.len(), true);

View file

@ -4238,7 +4238,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
check_expr(fcx, e);
let e_t = fcx.expr_ty(e);
if ty::type_is_error(e_t) {
fcx.write_ty(id, e_t);
fcx.write_ty(e.id, e_t);
some_err = true;
}
};
@ -4278,8 +4278,45 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
}
}
}
ast::ExprRange(..) => {
tcx.sess.span_bug(expr.span, "non-desugared range");
ast::ExprRange(ref start, ref end) => {
let mut some_err = false;
check_expr(fcx, &**start);
let t_start = fcx.expr_ty(&**start);
if ty::type_is_error(t_start) {
fcx.write_ty(start.id, t_start);
some_err = true;
}
if let &Some(ref e) = end {
check_expr_has_type(fcx, &**e, t_start);
let t_end = fcx.expr_ty(&**e);
if ty::type_is_error(t_end) {
fcx.write_ty(e.id, t_end);
some_err = true;
}
}
// Note that we don't check the type of the start/end satisfy any
// bounds because right the range structs do not have any. If we add
// some bounds, then we'll need to check `t_start` against them here.
if !some_err {
// Find the did from the appropriate lang item.
let did = if end.is_some() {
// Range
fcx.tcx().lang_items.range_struct()
} else {
// RangeFrom
fcx.tcx().lang_items.range_from_struct()
};
if let Some(did) = did {
let substs = Substs::new_type(vec![t_start], vec![]);
fcx.write_ty(id, ty::mk_struct(tcx, did, substs));
} else {
fcx.write_ty(id, ty::mk_err());
}
}
}
}