Skip to content

Commit 7249beb

Browse files
committed
---
yaml --- r: 40367 b: refs/heads/dist-snap c: bad62dc h: refs/heads/master i: 40365: 459b821 40363: 85a8821 40359: 2a495db 40351: 1e00ec0 v: v3
1 parent 4d4c756 commit 7249beb

File tree

11 files changed

+177
-55
lines changed

11 files changed

+177
-55
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278
99
refs/heads/incoming: e90142e536c150df0d9b4b2f11352152177509b5
10-
refs/heads/dist-snap: cf002e9d32a9b838f11933f3e1d38b6ffdbc0f98
10+
refs/heads/dist-snap: bad62dcb04d78c53911dc464663c04b47c5215ac
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1313
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/librustc/middle/borrowck/gather_loans.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,7 @@ impl gather_loan_ctxt {
447447
alt_id: ast::node_id) {
448448
do self.bccx.cat_pattern(discr_cmt, root_pat) |cmt, pat| {
449449
match pat.node {
450-
ast::pat_ident(bm, _, _)
451-
if !self.pat_is_variant_or_struct(pat) => {
450+
ast::pat_ident(bm, _, _) if self.pat_is_binding(pat) => {
452451
match bm {
453452
ast::bind_by_value | ast::bind_by_move => {
454453
// copying does not borrow anything, so no check
@@ -502,5 +501,9 @@ impl gather_loan_ctxt {
502501
fn pat_is_variant_or_struct(&self, pat: @ast::pat) -> bool {
503502
pat_util::pat_is_variant_or_struct(self.bccx.tcx.def_map, pat)
504503
}
504+
505+
fn pat_is_binding(&self, pat: @ast::pat) -> bool {
506+
pat_util::pat_is_binding(self.bccx.tcx.def_map, pat)
507+
}
505508
}
506509

branches/dist-snap/src/librustc/middle/check_alt.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use syntax::ast::*;
22
use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat};
33
use const_eval::{eval_const_expr, const_val, const_int, const_bool,
4-
compare_const_vals};
4+
compare_const_vals, lookup_const_by_id};
55
use syntax::codemap::span;
66
use syntax::print::pprust::pat_to_str;
77
use util::ppaux::ty_to_str;
@@ -229,6 +229,10 @@ fn pat_ctor_id(tcx: ty::ctxt, p: @pat) -> Option<ctor> {
229229
pat_ident(_, _, _) | pat_enum(_, _) => {
230230
match tcx.def_map.find(pat.id) {
231231
Some(def_variant(_, id)) => Some(variant(id)),
232+
Some(def_const(did)) => {
233+
let const_expr = lookup_const_by_id(tcx, did).get();
234+
Some(val(eval_const_expr(tcx, const_expr)))
235+
}
232236
_ => None
233237
}
234238
}
@@ -255,7 +259,7 @@ fn is_wild(tcx: ty::ctxt, p: @pat) -> bool {
255259
pat_wild => { true }
256260
pat_ident(_, _, _) => {
257261
match tcx.def_map.find(pat.id) {
258-
Some(def_variant(_, _)) => { false }
262+
Some(def_variant(_, _)) | Some(def_const(*)) => { false }
259263
_ => { true }
260264
}
261265
}
@@ -344,6 +348,20 @@ fn specialize(tcx: ty::ctxt, r: ~[@pat], ctor_id: ctor, arity: uint,
344348
if variant(id) == ctor_id { Some(vec::tail(r)) }
345349
else { None }
346350
}
351+
Some(def_const(did)) => {
352+
let const_expr = lookup_const_by_id(tcx, did).get();
353+
let e_v = eval_const_expr(tcx, const_expr);
354+
let match_ = match ctor_id {
355+
val(v) => compare_const_vals(e_v, v) == 0,
356+
range(c_lo, c_hi) => {
357+
compare_const_vals(c_lo, e_v) >= 0 &&
358+
compare_const_vals(c_hi, e_v) <= 0
359+
}
360+
single => true,
361+
_ => fail ~"type error"
362+
};
363+
if match_ { Some(vec::tail(r)) } else { None }
364+
}
347365
_ => Some(vec::append(vec::from_elem(arity, wild()), vec::tail(r)))
348366
}
349367
}
@@ -491,6 +509,7 @@ fn is_refutable(tcx: ty::ctxt, pat: &pat) -> bool {
491509
return true;
492510
}
493511
}
512+
Some(def_const(*)) => return true,
494513
_ => ()
495514
}
496515

branches/dist-snap/src/librustc/middle/const_eval.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,21 +149,23 @@ fn classify(e: @expr,
149149

150150
fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> {
151151
match tcx.def_map.find(e.id) {
152-
Some(ast::def_const(def_id)) => {
153-
if ast_util::is_local(def_id) {
154-
match tcx.items.find(def_id.node) {
155-
None => None,
156-
Some(ast_map::node_item(it, _)) => match it.node {
157-
item_const(_, const_expr) => Some(const_expr),
158-
_ => None
159-
},
160-
Some(_) => None
161-
}
162-
}
163-
else { None }
152+
Some(ast::def_const(def_id)) => lookup_const_by_id(tcx, def_id),
153+
_ => None
154+
}
155+
}
156+
157+
fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::def_id) -> Option<@expr> {
158+
if ast_util::is_local(def_id) {
159+
match tcx.items.find(def_id.node) {
160+
None => None,
161+
Some(ast_map::node_item(it, _)) => match it.node {
162+
item_const(_, const_expr) => Some(const_expr),
163+
_ => None
164+
},
165+
Some(_) => None
164166
}
165-
Some(_) => None,
166-
None => None
167+
} else {
168+
None
167169
}
168170
}
169171

branches/dist-snap/src/librustc/middle/pat_util.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use syntax::codemap::span;
77
use std::map::HashMap;
88

99
export pat_binding_ids, pat_bindings, pat_id_map, PatIdMap;
10-
export pat_is_variant_or_struct, pat_is_binding_or_wild;
10+
export pat_is_variant_or_struct, pat_is_binding, pat_is_binding_or_wild;
11+
export pat_is_const;
1112

1213
type PatIdMap = std::map::HashMap<ident, node_id>;
1314

@@ -33,9 +34,31 @@ fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool {
3334
}
3435
}
3536

37+
fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool {
38+
match pat.node {
39+
pat_ident(_, _, None) => {
40+
match dm.find(pat.id) {
41+
Some(def_const(*)) => true,
42+
_ => false
43+
}
44+
}
45+
_ => false
46+
}
47+
}
48+
49+
fn pat_is_binding(dm: resolve::DefMap, pat: @pat) -> bool {
50+
match pat.node {
51+
pat_ident(*) => {
52+
!pat_is_variant_or_struct(dm, pat) &&
53+
!pat_is_const(dm, pat)
54+
}
55+
_ => false
56+
}
57+
}
58+
3659
fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool {
3760
match pat.node {
38-
pat_ident(*) => !pat_is_variant_or_struct(dm, pat),
61+
pat_ident(*) => pat_is_binding(dm, pat),
3962
pat_wild => true,
4063
_ => false
4164
}
@@ -45,8 +68,7 @@ fn pat_bindings(dm: resolve::DefMap, pat: @pat,
4568
it: fn(binding_mode, node_id, span, @path)) {
4669
do walk_pat(pat) |p| {
4770
match p.node {
48-
pat_ident(binding_mode, pth, _)
49-
if !pat_is_variant_or_struct(dm, p) => {
71+
pat_ident(binding_mode, pth, _) if pat_is_binding(dm, p) => {
5072
it(binding_mode, p.id, p.span, pth);
5173
}
5274
_ => {}

branches/dist-snap/src/librustc/middle/resolve.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl AllowCapturingSelfFlag : cmp::Eq {
310310

311311
enum BareIdentifierPatternResolution {
312312
FoundStructOrEnumVariant(def),
313-
FoundConst,
313+
FoundConst(def),
314314
BareIdentifierPatternUnresolved
315315
}
316316

@@ -4308,11 +4308,17 @@ impl Resolver {
43084308
self.session
43094309
.str_of(ident)));
43104310
}
4311-
FoundConst => {
4311+
FoundConst(def) if mode == RefutableMode => {
4312+
debug!("(resolving pattern) resolving `%s` to \
4313+
constant",
4314+
self.session.str_of(ident));
4315+
4316+
self.record_def(pattern.id, def);
4317+
}
4318+
FoundConst(_) => {
43124319
self.session.span_err(pattern.span,
4313-
~"pattern variable \
4314-
conflicts with a constant \
4315-
in scope");
4320+
~"only refutable patterns \
4321+
allowed here");
43164322
}
43174323
BareIdentifierPatternUnresolved => {
43184324
debug!("(resolving pattern) binding `%s`",
@@ -4465,8 +4471,8 @@ impl Resolver {
44654471
def @ def_variant(*) | def @ def_class(*) => {
44664472
return FoundStructOrEnumVariant(def);
44674473
}
4468-
def_const(*) => {
4469-
return FoundConst;
4474+
def @ def_const(*) => {
4475+
return FoundConst(def);
44704476
}
44714477
_ => {
44724478
return BareIdentifierPatternUnresolved;

branches/dist-snap/src/librustc/middle/trans/alt.rs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
158158
// expression.
159159
enum Lit {
160160
UnitLikeStructLit(ast::node_id), // the node ID of the pattern
161-
ExprLit(@ast::expr)
161+
ExprLit(@ast::expr),
162+
ConstLit(ast::def_id), // the def ID of the constant
162163
}
163164

164165
// An option identifying a branch (either a literal, a enum variant or a
@@ -168,11 +169,43 @@ enum Opt {
168169
var(/* disr val */int, /* variant dids */{enm: def_id, var: def_id}),
169170
range(@ast::expr, @ast::expr)
170171
}
172+
171173
fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
172174
match (*a, *b) {
173-
(lit(ExprLit(a)), lit(ExprLit(b))) =>
174-
const_eval::compare_lit_exprs(tcx, a, b) == 0,
175-
(lit(UnitLikeStructLit(a)), lit(UnitLikeStructLit(b))) => a == b,
175+
(lit(a), lit(b)) => {
176+
match (a, b) {
177+
(UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b,
178+
_ => {
179+
let a_expr;
180+
match a {
181+
ExprLit(existing_a_expr) => a_expr = existing_a_expr,
182+
ConstLit(a_const) => {
183+
let e = const_eval::lookup_const_by_id(tcx, a_const);
184+
a_expr = e.get();
185+
}
186+
UnitLikeStructLit(_) => {
187+
fail ~"UnitLikeStructLit should have been handled \
188+
above"
189+
}
190+
}
191+
192+
let b_expr;
193+
match b {
194+
ExprLit(existing_b_expr) => b_expr = existing_b_expr,
195+
ConstLit(b_const) => {
196+
let e = const_eval::lookup_const_by_id(tcx, b_const);
197+
b_expr = e.get();
198+
}
199+
UnitLikeStructLit(_) => {
200+
fail ~"UnitLikeStructLit should have been handled \
201+
above"
202+
}
203+
}
204+
205+
const_eval::compare_lit_exprs(tcx, a_expr, b_expr) == 0
206+
}
207+
}
208+
}
176209
(range(a1, a2), range(b1, b2)) => {
177210
const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
178211
const_eval::compare_lit_exprs(tcx, a2, b2) == 0
@@ -200,6 +233,10 @@ fn trans_opt(bcx: block, o: &Opt) -> opt_result {
200233
let datumblock = datum::scratch_datum(bcx, struct_ty, true);
201234
return single_result(datumblock.to_result(bcx));
202235
}
236+
lit(ConstLit(lit_id)) => {
237+
let llval = consts::get_const_val(bcx.ccx(), lit_id);
238+
return single_result(rslt(bcx, llval));
239+
}
203240
var(disr_val, _) => {
204241
return single_result(rslt(bcx, C_int(ccx, disr_val)));
205242
}
@@ -353,7 +390,7 @@ fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r],
353390
let self = br.pats[col];
354391
match self.node {
355392
ast::pat_ident(_, path, None) => {
356-
if !pat_is_variant_or_struct(dm, self) {
393+
if pat_is_binding(dm, self) {
357394
let binding_info =
358395
br.data.bindings_map.get(path_to_ident(path));
359396
Store(bcx, val, binding_info.llmatch);
@@ -388,8 +425,7 @@ fn enter_default(bcx: block, dm: DefMap, m: &[@Match/&r],
388425
match p.node {
389426
ast::pat_wild | ast::pat_rec(_, _) | ast::pat_tup(_) |
390427
ast::pat_struct(*) => Some(~[]),
391-
ast::pat_ident(_, _, None)
392-
if !pat_is_variant_or_struct(dm, p) => Some(~[]),
428+
ast::pat_ident(_, _, None) if pat_is_binding(dm, p) => Some(~[]),
393429
_ => None
394430
}
395431
}
@@ -451,6 +487,15 @@ fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
451487
None
452488
}
453489
}
490+
ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
491+
let const_def = tcx.def_map.get(p.id);
492+
let const_def_id = ast_util::def_id_of_def(const_def);
493+
if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
494+
Some(~[])
495+
} else {
496+
None
497+
}
498+
}
454499
ast::pat_lit(l) => {
455500
if opt_eq(tcx, &lit(ExprLit(l)), opt) {Some(~[])} else {None}
456501
}
@@ -675,6 +720,10 @@ fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
675720
add_to_set(ccx.tcx, &found,
676721
lit(UnitLikeStructLit(cur.id)));
677722
}
723+
Some(ast::def_const(const_did)) => {
724+
add_to_set(ccx.tcx, &found,
725+
lit(ConstLit(const_did)));
726+
}
678727
_ => {}
679728
}
680729
}

branches/dist-snap/src/librustc/middle/trans/consts.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef)
9595
}
9696
}
9797

98+
fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef {
99+
if !ast_util::is_local(def_id) {
100+
cx.tcx.sess.bug(~"cross-crate constants");
101+
}
102+
if !cx.const_values.contains_key(def_id.node) {
103+
match cx.tcx.items.get(def_id.node) {
104+
ast_map::node_item(@{
105+
node: ast::item_const(_, subexpr), _
106+
}, _) => {
107+
trans_const(cx, subexpr, def_id.node);
108+
}
109+
_ => cx.tcx.sess.bug(~"expected a const to be an item")
110+
}
111+
}
112+
cx.const_values.get(def_id.node)
113+
}
98114

99115
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
100116
let _icx = cx.insn_ctxt("const_expr");
@@ -359,18 +375,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
359375
C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
360376
}
361377
Some(ast::def_const(def_id)) => {
362-
assert ast_util::is_local(def_id);
363-
if ! cx.const_values.contains_key(def_id.node) {
364-
match cx.tcx.items.get(def_id.node) {
365-
ast_map::node_item(@{
366-
node: ast::item_const(_, subexpr), _
367-
}, _) => {
368-
trans_const(cx, subexpr, def_id.node);
369-
}
370-
_ => cx.sess.span_bug(e.span, ~"expected item")
371-
}
372-
}
373-
cx.const_values.get(def_id.node)
378+
get_const_val(cx, def_id)
374379
}
375380
_ => cx.sess.span_bug(e.span, ~"expected a const or fn def")
376381
}

branches/dist-snap/src/librustc/middle/typeck/check.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,7 @@ fn check_fn(ccx: @crate_ctxt,
389389
let visit_pat = fn@(p: @ast::pat, &&e: (), v: visit::vt<()>) {
390390
match p.node {
391391
ast::pat_ident(_, path, _)
392-
if !pat_util::pat_is_variant_or_struct(fcx.ccx.tcx.def_map,
393-
p) => {
392+
if pat_util::pat_is_binding(fcx.ccx.tcx.def_map, p) => {
394393
assign(p.span, p.id, None);
395394
debug!("Pattern binding %s is assigned to %s",
396395
tcx.sess.str_of(path.idents[0]),

0 commit comments

Comments
 (0)