Skip to content

Commit 8c20f21

Browse files
committed
---
yaml --- r: 6545 b: refs/heads/master c: 64ce092 h: refs/heads/master i: 6543: 50e7423 v: v3
1 parent 8dc0833 commit 8c20f21

File tree

11 files changed

+176
-129
lines changed

11 files changed

+176
-129
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 691b517fb9e18e190763a8ac83e09f1cffa6cf11
2+
refs/heads/master: 64ce092c273a20cc503697c3dfebb956c9025d46

trunk/src/comp/driver/rustc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
137137
let freevars =
138138
time(time_passes, "freevar finding",
139139
bind freevars::annotate_freevars(def_map, crate));
140+
time(time_passes, "const checking",
141+
bind middle::check_const::check_crate(sess, crate));
140142
let ty_cx = ty::mk_ctxt(sess, def_map, ext_map, ast_map, freevars);
141143
time(time_passes, "typechecking", bind typeck::check_crate(ty_cx, crate));
142144
time(time_passes, "block-use checking",
@@ -157,8 +159,6 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
157159
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
158160
time(time_passes, "kind checking",
159161
bind kind::check_crate(ty_cx, last_uses, crate));
160-
time(time_passes, "const checking",
161-
bind middle::check_const::check_crate(ty_cx, crate));
162162
if sess.get_opts().no_trans { ret; }
163163
let llmod =
164164
time(time_passes, "translation",

trunk/src/comp/middle/check_alt.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import syntax::ast::*;
2-
import syntax::ast_util::{variant_def_ids, dummy_sp, compare_lit, lit_eq};
2+
import syntax::ast_util::{variant_def_ids, dummy_sp, compare_lit_exprs,
3+
lit_expr_eq};
34
import syntax::visit;
45

56
fn check_crate(tcx: ty::ctxt, crate: @crate) {
@@ -66,7 +67,7 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
6667
pat_wild. | pat_bind(_) { ret true; }
6768
pat_lit(la) {
6869
alt b.node {
69-
pat_lit(lb) { ret lit_eq(la, lb); }
70+
pat_lit(lb) { ret lit_expr_eq(la, lb); }
7071
_ { ret false; }
7172
}
7273
}
@@ -106,11 +107,12 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
106107
pat_range(begina, enda) {
107108
alt b.node {
108109
pat_lit(lb) {
109-
ret compare_lit(begina, lb) <= 0 && compare_lit(enda, lb) >= 0;
110+
ret compare_lit_exprs(begina, lb) <= 0 &&
111+
compare_lit_exprs(enda, lb) >= 0;
110112
}
111113
pat_range(beginb, endb) {
112-
ret compare_lit(begina, beginb) <= 0 &&
113-
compare_lit(enda, endb) >= 0;
114+
ret compare_lit_exprs(begina, beginb) <= 0 &&
115+
compare_lit_exprs(enda, endb) >= 0;
114116
}
115117
_ { ret false; }
116118
}

trunk/src/comp/middle/check_const.rs

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,61 @@
11
import syntax::ast::*;
22
import syntax::visit;
3+
import driver::session::session;
34

4-
fn check_crate(tcx: ty::ctxt, crate: @crate) {
5-
let v =
6-
@{visit_item: bind check_item(tcx, _, _, _)
7-
with *visit::default_visitor::<()>()};
8-
visit::visit_crate(*crate, (), visit::mk_vt(v));
9-
tcx.sess.abort_if_errors();
5+
fn check_crate(sess: session, crate: @crate) {
6+
visit::visit_crate(*crate, false, visit::mk_vt(@{
7+
visit_item: check_item,
8+
visit_pat: check_pat,
9+
visit_expr: bind check_expr(sess, _, _, _)
10+
with *visit::default_visitor()
11+
}));
12+
sess.abort_if_errors();
1013
}
1114

12-
fn check_item(tcx: ty::ctxt, it: @item, &&s: (), v: visit::vt<()>) {
13-
visit::visit_item(it, s, v);
15+
fn check_item(it: @item, &&_is_const: bool, v: visit::vt<bool>) {
1416
alt it.node {
15-
item_const(_ /* ty */, ex) {
16-
let v =
17-
@{visit_expr: bind check_const_expr(tcx, _, _, _)
18-
with *visit::default_visitor::<()>()};
19-
check_const_expr(tcx, ex, (), visit::mk_vt(v));
20-
}
21-
_ { }
17+
item_const(_, ex) { v.visit_expr(ex, true, v); }
18+
_ { visit::visit_item(it, false, v); }
2219
}
2320
}
2421

25-
fn check_const_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
26-
visit::visit_expr(ex, s, v);
27-
alt ex.node {
28-
expr_lit(_) { }
29-
expr_binary(_, _, _) { /* subexps covered by visit */ }
30-
expr_unary(u, _) {
31-
alt u {
32-
box(_) |
33-
uniq(_) |
34-
deref. {
35-
tcx.sess.span_err(ex.span,
36-
"disallowed operator in constant expression");
22+
fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
23+
fn is_str(e: @expr) -> bool {
24+
alt e.node { expr_lit(@{node: lit_str(_), _}) { true } _ { false } }
25+
}
26+
alt p.node {
27+
// Let through plain string literals here
28+
pat_lit(a) { if !is_str(a) { v.visit_expr(a, true, v); } }
29+
pat_range(a, b) {
30+
if !is_str(a) { v.visit_expr(a, true, v); }
31+
if !is_str(b) { v.visit_expr(b, true, v); }
32+
}
33+
_ { visit::visit_pat(p, false, v); }
34+
}
35+
}
36+
37+
fn check_expr(sess: session, e: @expr, &&is_const: bool, v: visit::vt<bool>) {
38+
if is_const {
39+
alt e.node {
40+
expr_unary(box(_), _) | expr_unary(uniq(_), _) |
41+
expr_unary(deref., _){
42+
sess.span_err(e.span,
43+
"disallowed operator in constant expression");
44+
ret;
45+
}
46+
expr_lit(@{node: lit_str(_), _}) {
47+
sess.span_err(e.span,
48+
"string constants are not supported");
49+
}
50+
expr_lit(_) | expr_binary(_, _, _) | expr_unary(_, _) {}
51+
_ {
52+
sess.span_err(e.span,
53+
"constant contains unimplemented expression type");
54+
ret;
3755
}
38-
_ { }
3956
}
40-
}
41-
_ { tcx.sess.span_err(ex.span,
42-
"constant contains unimplemented expression type"); }
4357
}
58+
visit::visit_expr(e, is_const, v);
4459
}
4560

4661
// Local Variables:

trunk/src/comp/middle/trans_alt.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,27 @@ import trans_build::*;
77
import trans::{new_sub_block_ctxt, new_scope_block_ctxt, load_if_immediate};
88
import syntax::ast;
99
import syntax::ast_util;
10-
import syntax::ast_util::{dummy_sp, lit_eq};
10+
import syntax::ast_util::{dummy_sp};
1111
import syntax::ast::def_id;
1212
import syntax::codemap::span;
1313

1414
import trans_common::*;
1515

1616
// An option identifying a branch (either a literal, a tag variant or a range)
1717
tag opt {
18-
lit(@ast::lit);
18+
lit(@ast::expr);
1919
var(/* variant id */uint, /* variant dids */{tg: def_id, var: def_id});
20-
range(@ast::lit, @ast::lit);
20+
range(@ast::expr, @ast::expr);
2121
}
2222
fn opt_eq(a: opt, b: opt) -> bool {
23-
alt a {
24-
lit(la) {
25-
ret alt b { lit(lb) { lit_eq(la, lb) } _ { false } };
26-
}
27-
var(ida, _) {
28-
ret alt b { var(idb, _) { ida == idb } _ { false } };
29-
}
30-
range(la1, la2) {
31-
ret alt b {
32-
range(lb1, lb2) { lit_eq(la1, lb1) && lit_eq(la2, lb2) }
33-
_ { false }
34-
};
23+
alt (a, b) {
24+
(lit(a), lit(b)) { ast_util::compare_lit_exprs(a, b) == 0 }
25+
(range(a1, a2), range(b1, b2)) {
26+
ast_util::compare_lit_exprs(a1, b1) == 0 &&
27+
ast_util::compare_lit_exprs(a2, b2) == 0
3528
}
29+
(var(a, _), var(b, _)) { a == b }
30+
_ { false }
3631
}
3732
}
3833

@@ -45,7 +40,7 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
4540
alt o {
4641
lit(l) {
4742
alt l.node {
48-
ast::lit_str(s) {
43+
ast::expr_lit(@{node: ast::lit_str(s), _}) {
4944
let strty = ty::mk_str(bcx_tcx(bcx));
5045
let cell = trans::empty_dest_cell();
5146
bcx = trans_vec::trans_str(bcx, s, trans::by_val(cell));
@@ -54,17 +49,14 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
5449
}
5550
_ {
5651
ret single_result(
57-
rslt(bcx, trans::trans_crate_lit(ccx, *l)));
52+
rslt(bcx, trans::trans_const_expr(ccx, l)));
5853
}
5954
}
6055
}
6156
var(id, _) { ret single_result(rslt(bcx, C_int(ccx, id as int))); }
6257
range(l1, l2) {
63-
let cell1 = trans::empty_dest_cell();
64-
let cell2 = trans::empty_dest_cell();
65-
let bcx = trans::trans_lit(bcx, *l1, trans::by_val(cell1));
66-
let bcx = trans::trans_lit(bcx, *l2, trans::by_val(cell2));
67-
ret range_result(rslt(bcx, *cell1), rslt(bcx, *cell2));
58+
ret range_result(rslt(bcx, trans::trans_const_expr(ccx, l1)),
59+
rslt(bcx, trans::trans_const_expr(ccx, l2)));
6860
}
6961
}
7062
}
@@ -464,13 +456,9 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
464456
}
465457
}
466458
lit(l) {
467-
kind = alt l.node {
468-
ast::lit_str(_) | ast::lit_nil. | ast::lit_float(_) |
469-
ast::lit_mach_float(_, _) {
470-
test_val = Load(bcx, val); compare
471-
}
472-
_ { test_val = Load(bcx, val); switch }
473-
};
459+
test_val = Load(bcx, val);
460+
let pty = ty::node_id_to_monotype(ccx.tcx, pat_id);
461+
kind = ty::type_is_integral(ccx.tcx, pty) ? switch : compare;
474462
}
475463
range(_, _) {
476464
test_val = Load(bcx, val);

trunk/src/comp/middle/ty.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export type_is_vec;
155155
export type_is_fp;
156156
export type_allows_implicit_copy;
157157
export type_is_integral;
158+
export type_is_numeric;
158159
export type_is_native;
159160
export type_is_nil;
160161
export type_is_pod;
@@ -1173,6 +1174,10 @@ fn type_is_fp(cx: ctxt, ty: t) -> bool {
11731174
}
11741175
}
11751176

1177+
fn type_is_numeric(cx: ctxt, ty: t) -> bool {
1178+
ret type_is_integral(cx, ty) || type_is_fp(cx, ty);
1179+
}
1180+
11761181
fn type_is_signed(cx: ctxt, ty: t) -> bool {
11771182
alt struct(cx, ty) {
11781183
ty_int. { ret true; }

trunk/src/comp/middle/typeck.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import syntax::{ast, ast_util};
22
import ast::spanned;
3-
import syntax::ast_util::{local_def, respan, ty_param_kind, lit_is_numeric,
4-
lit_types_match};
3+
import syntax::ast_util::{local_def, respan, ty_param_kind};
54
import syntax::visit;
65
import metadata::csearch;
76
import driver::session;
@@ -1253,8 +1252,8 @@ fn lit_as_float(l: @ast::lit) -> str {
12531252
}
12541253
}
12551254

1256-
fn valid_range_bounds(l1: @ast::lit, l2: @ast::lit) -> bool {
1257-
ast_util::compare_lit(l1, l2) <= 0
1255+
fn valid_range_bounds(from: @ast::expr, to: @ast::expr) -> bool {
1256+
ast_util::compare_lit_exprs(from, to) <= 0
12581257
}
12591258

12601259
// Pattern checking is top-down rather than bottom-up so that bindings get
@@ -1264,27 +1263,26 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
12641263
alt pat.node {
12651264
ast::pat_wild. { write::ty_only_fixup(fcx, pat.id, expected); }
12661265
ast::pat_lit(lt) {
1267-
let typ = check_lit(fcx.ccx, lt);
1268-
typ = demand::simple(fcx, pat.span, expected, typ);
1269-
write::ty_only_fixup(fcx, pat.id, typ);
1266+
check_expr_with(fcx, lt, expected);
1267+
write::ty_only_fixup(fcx, pat.id, expr_ty(fcx.ccx.tcx, lt));
12701268
}
12711269
ast::pat_range(begin, end) {
1272-
if !lit_types_match(begin, end) {
1270+
check_expr_with(fcx, begin, expected);
1271+
check_expr_with(fcx, end, expected);
1272+
let b_ty = resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx,
1273+
begin));
1274+
if b_ty != resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx,
1275+
end)) {
12731276
fcx.ccx.tcx.sess.span_err(pat.span, "mismatched types in range");
1274-
} else if !lit_is_numeric(begin) || !lit_is_numeric(end) {
1277+
} else if !ty::type_is_numeric(fcx.ccx.tcx, b_ty) {
12751278
fcx.ccx.tcx.sess.span_err(pat.span,
12761279
"non-numeric type used in range");
12771280
} else if !valid_range_bounds(begin, end) {
12781281
fcx.ccx.tcx.sess.span_err(begin.span,
12791282
"lower range bound must be less \
12801283
than upper");
12811284
}
1282-
let typ1 = check_lit(fcx.ccx, begin);
1283-
typ1 = demand::simple(fcx, pat.span, expected, typ1);
1284-
write::ty_only_fixup(fcx, pat.id, typ1);
1285-
let typ2 = check_lit(fcx.ccx, end);
1286-
typ2 = demand::simple(fcx, pat.span, typ1, typ2);
1287-
write::ty_only_fixup(fcx, pat.id, typ2);
1285+
write::ty_only_fixup(fcx, pat.id, b_ty);
12881286
}
12891287
ast::pat_bind(name) {
12901288
let vid = lookup_local(fcx, pat.span, pat.id);

trunk/src/comp/syntax/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ type field_pat = {ident: ident, pat: @pat};
8686
tag pat_ {
8787
pat_wild;
8888
pat_bind(ident);
89-
pat_lit(@lit);
9089
pat_tag(@path, [@pat]);
9190
pat_rec([field_pat], bool);
9291
pat_tup([@pat]);
9392
pat_box(@pat);
9493
pat_uniq(@pat);
95-
pat_range(@lit, @lit);
94+
pat_lit(@expr);
95+
pat_range(@expr, @expr);
9696
}
9797

9898
tag mutability { mut; imm; maybe_mut; }

0 commit comments

Comments
 (0)