Skip to content

Commit 17826e1

Browse files
committed
Type checking and trans for ranges
1 parent 8a357e1 commit 17826e1

File tree

8 files changed

+102
-29
lines changed

8 files changed

+102
-29
lines changed

src/librustc/middle/cfg/construct.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
439439
start.iter().chain(end.iter()).map(|x| &**x))
440440
}
441441

442-
ast::ExprRange(..) => {
443-
self.tcx.sess.span_bug(expr.span, "non-desugared range");
442+
ast::ExprRange(ref start, ref end) => {
443+
let fields = Some(&**start).into_iter()
444+
.chain(end.as_ref().map(|e| &**e).into_iter());
445+
self.straightline(expr, pred, fields)
444446
}
445447

446448
ast::ExprUnary(_, ref e) if self.is_method_call(expr) => {

src/librustc/middle/expr_use_visitor.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
465465
assert!(overloaded);
466466
}
467467

468-
ast::ExprRange(..) => {
469-
self.tcx().sess.span_bug(expr.span, "non-desugared range");
468+
ast::ExprRange(ref start, ref end) => {
469+
self.consume_expr(&**start);
470+
end.as_ref().map(|e| self.consume_expr(&**e));
470471
}
471472

472473
ast::ExprCall(ref callee, ref args) => { // callee(args)

src/librustc/middle/liveness.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,6 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
486486
ast::ExprWhileLet(..) => {
487487
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
488488
}
489-
ast::ExprRange(..) => {
490-
ir.tcx.sess.span_bug(expr.span, "non-desugared range");
491-
}
492489
ast::ExprForLoop(ref pat, _, _, _) => {
493490
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
494491
debug!("adding local variable {} from for loop with bm {}",
@@ -517,7 +514,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
517514
ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
518515
ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
519516
ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
520-
ast::ExprSlice(..) => {
517+
ast::ExprSlice(..) | ast::ExprRange(..) => {
521518
visit::walk_expr(ir, expr);
522519
}
523520
}
@@ -1200,8 +1197,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
12001197
self.propagate_through_expr(&**e1, succ)
12011198
}
12021199

1203-
ast::ExprRange(..) => {
1204-
self.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
1200+
ast::ExprRange(ref e1, ref e2) => {
1201+
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
1202+
self.propagate_through_expr(&**e1, succ)
12051203
}
12061204

12071205
ast::ExprBox(None, ref e) |
@@ -1496,7 +1494,8 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
14961494
ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) |
14971495
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
14981496
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
1499-
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => {
1497+
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
1498+
ast::ExprSlice(..) | ast::ExprRange(..) => {
15001499
visit::walk_expr(this, expr);
15011500
}
15021501
ast::ExprIfLet(..) => {
@@ -1505,9 +1504,6 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
15051504
ast::ExprWhileLet(..) => {
15061505
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
15071506
}
1508-
ast::ExprRange(..) => {
1509-
this.ir.tcx.sess.span_bug(expr.span, "non-desugared range");
1510-
}
15111507
}
15121508
}
15131509

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
541541
ast::ExprAddrOf(..) | ast::ExprCall(..) |
542542
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
543543
ast::ExprClosure(..) | ast::ExprRet(..) |
544-
ast::ExprUnary(..) | ast::ExprSlice(..) |
544+
ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprRange(..) |
545545
ast::ExprMethodCall(..) | ast::ExprCast(..) |
546546
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
547547
ast::ExprBinary(..) | ast::ExprWhile(..) |
@@ -559,9 +559,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
559559
ast::ExprWhileLet(..) => {
560560
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
561561
}
562-
ast::ExprRange(..) => {
563-
self.tcx().sess.span_bug(expr.span, "non-desugared range");
564-
}
565562
}
566563
}
567564

src/librustc/middle/ty.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4257,6 +4257,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
42574257
ast::ExprCall(..) |
42584258
ast::ExprMethodCall(..) |
42594259
ast::ExprStruct(..) |
4260+
ast::ExprRange(..) |
42604261
ast::ExprTup(..) |
42614262
ast::ExprIf(..) |
42624263
ast::ExprMatch(..) |
@@ -4273,9 +4274,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
42734274
ast::ExprWhileLet(..) => {
42744275
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
42754276
}
4276-
ast::ExprRange(..) => {
4277-
tcx.sess.span_bug(expr.span, "non-desugared range");
4278-
}
42794277

42804278
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
42814279
RvalueDpsExpr

src/librustc_trans/trans/debuginfo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3494,9 +3494,9 @@ fn populate_scope_map(cx: &CrateContext,
34943494
end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
34953495
}
34963496

3497-
ast::ExprRange(..) => {
3498-
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3499-
Found unexpanded range.");
3497+
ast::ExprRange(ref start, ref end) => {
3498+
walk_expr(cx, &**start, scope_stack, scope_map);
3499+
end.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map));
35003500
}
35013501

35023502
ast::ExprVec(ref init_expressions) |

src/librustc_trans/trans/expr.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use back::abi;
3939
use llvm::{mod, ValueRef};
4040
use middle::def;
4141
use middle::mem_categorization::Typer;
42-
use middle::subst::{mod, Subst};
42+
use middle::subst::{mod, Subst, Substs};
4343
use trans::{_match, adt, asm, base, callee, closure, consts, controlflow};
4444
use trans::base::*;
4545
use trans::build::*;
@@ -66,6 +66,7 @@ use trans::type_::Type;
6666
use syntax::{ast, ast_util, codemap};
6767
use syntax::print::pprust::{expr_to_string};
6868
use syntax::ptr::P;
69+
use syntax::parse::token;
6970
use std::rc::Rc;
7071

7172
// Destinations
@@ -1048,8 +1049,49 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10481049
base.as_ref().map(|e| &**e),
10491050
expr.span,
10501051
expr.id,
1052+
node_id_type(bcx, expr.id),
10511053
dest)
10521054
}
1055+
ast::ExprRange(ref start, ref end) => {
1056+
// FIXME it is just not right that we are synthesising ast nodes in
1057+
// trans. Shudder.
1058+
fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
1059+
ast::Field {
1060+
ident: codemap::dummy_spanned(token::str_to_ident(field_name)),
1061+
expr: expr,
1062+
span: codemap::DUMMY_SP,
1063+
}
1064+
}
1065+
1066+
// A range just desugars into a struct.
1067+
let (did, fields) = match end {
1068+
&Some(ref end) => {
1069+
// Desugar to Range
1070+
let fields = vec!(make_field("start", start.clone()),
1071+
make_field("end", end.clone()));
1072+
(tcx.lang_items.range_struct(), fields)
1073+
}
1074+
&None => {
1075+
// Desugar to RangeFrom
1076+
let fields = vec!(make_field("start", start.clone()));
1077+
(tcx.lang_items.range_from_struct(), fields)
1078+
}
1079+
};
1080+
1081+
if let Some(did) = did {
1082+
let substs = Substs::new_type(vec![node_id_type(bcx, start.id)], vec![]);
1083+
trans_struct(bcx,
1084+
fields.as_slice(),
1085+
None,
1086+
expr.span,
1087+
expr.id,
1088+
ty::mk_struct(tcx, did, substs),
1089+
dest)
1090+
} else {
1091+
tcx.sess.span_bug(expr.span,
1092+
"No lang item for ranges (how did we get this far?)")
1093+
}
1094+
}
10531095
ast::ExprTup(ref args) => {
10541096
let numbered_fields: Vec<(uint, &ast::Expr)> =
10551097
args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect();
@@ -1347,10 +1389,10 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
13471389
base: Option<&ast::Expr>,
13481390
expr_span: codemap::Span,
13491391
expr_id: ast::NodeId,
1392+
ty: Ty<'tcx>,
13501393
dest: Dest) -> Block<'blk, 'tcx> {
13511394
let _icx = push_ctxt("trans_rec");
13521395

1353-
let ty = node_id_type(bcx, expr_id);
13541396
let tcx = bcx.tcx();
13551397
with_field_tys(tcx, ty, Some(expr_id), |discr, field_tys| {
13561398
let mut need_base = Vec::from_elem(field_tys.len(), true);

src/librustc_typeck/check/mod.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,7 +4238,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
42384238
check_expr(fcx, e);
42394239
let e_t = fcx.expr_ty(e);
42404240
if ty::type_is_error(e_t) {
4241-
fcx.write_ty(id, e_t);
4241+
fcx.write_ty(e.id, e_t);
42424242
some_err = true;
42434243
}
42444244
};
@@ -4278,8 +4278,45 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
42784278
}
42794279
}
42804280
}
4281-
ast::ExprRange(..) => {
4282-
tcx.sess.span_bug(expr.span, "non-desugared range");
4281+
ast::ExprRange(ref start, ref end) => {
4282+
let mut some_err = false;
4283+
4284+
check_expr(fcx, &**start);
4285+
let t_start = fcx.expr_ty(&**start);
4286+
if ty::type_is_error(t_start) {
4287+
fcx.write_ty(start.id, t_start);
4288+
some_err = true;
4289+
}
4290+
4291+
if let &Some(ref e) = end {
4292+
check_expr_has_type(fcx, &**e, t_start);
4293+
let t_end = fcx.expr_ty(&**e);
4294+
if ty::type_is_error(t_end) {
4295+
fcx.write_ty(e.id, t_end);
4296+
some_err = true;
4297+
}
4298+
}
4299+
4300+
// Note that we don't check the type of the start/end satisfy any
4301+
// bounds because right the range structs do not have any. If we add
4302+
// some bounds, then we'll need to check `t_start` against them here.
4303+
4304+
if !some_err {
4305+
// Find the did from the appropriate lang item.
4306+
let did = if end.is_some() {
4307+
// Range
4308+
fcx.tcx().lang_items.range_struct()
4309+
} else {
4310+
// RangeFrom
4311+
fcx.tcx().lang_items.range_from_struct()
4312+
};
4313+
if let Some(did) = did {
4314+
let substs = Substs::new_type(vec![t_start], vec![]);
4315+
fcx.write_ty(id, ty::mk_struct(tcx, did, substs));
4316+
} else {
4317+
fcx.write_ty(id, ty::mk_err());
4318+
}
4319+
}
42834320
}
42844321

42854322
}

0 commit comments

Comments
 (0)