Skip to content

Commit c55cef8

Browse files
committed
---
yaml --- r: 40651 b: refs/heads/dist-snap c: e23ea24 h: refs/heads/master i: 40649: ddd8974 40647: 78f0048 v: v3
1 parent 37d9851 commit c55cef8

File tree

4 files changed

+80
-78
lines changed

4 files changed

+80
-78
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: 16506c0250a35cc9cd330465cb2999c5f3ab6f0f
10+
refs/heads/dist-snap: e23ea24aed95885c8bc59de49c616f60fa5053d1
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/check_alt.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use syntax::ast::*;
12-
use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat};
12+
use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat, walk_pat};
1313
use const_eval::{eval_const_expr, const_val, const_int, const_bool,
1414
compare_const_vals, lookup_const_by_id};
1515
use syntax::codemap::span;
@@ -43,6 +43,15 @@ fn check_expr(cx: @AltCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) {
4343
visit::visit_expr(ex, s, v);
4444
match ex.node {
4545
expr_match(scrut, ref arms) => {
46+
// First, check legality of move bindings.
47+
let is_lvalue = ty::expr_is_lval(cx.tcx, cx.method_map, scrut);
48+
for arms.each |arm| {
49+
check_legality_of_move_bindings(cx,
50+
is_lvalue,
51+
arm.guard.is_some(),
52+
arm.pats);
53+
}
54+
4655
check_arms(cx, (*arms));
4756
/* Check for exhaustiveness */
4857
// Check for empty enum, because is_useful only works on inhabited
@@ -511,6 +520,13 @@ fn check_local(cx: @AltCheckCtxt, loc: @local, &&s: (), v: visit::vt<()>) {
511520
cx.tcx.sess.span_err(loc.node.pat.span,
512521
~"refutable pattern in local binding");
513522
}
523+
524+
// Check legality of move bindings.
525+
let is_lvalue = match loc.node.init {
526+
Some(init) => ty::expr_is_lval(cx.tcx, cx.method_map, init),
527+
None => true
528+
};
529+
check_legality_of_move_bindings(cx, is_lvalue, false, [ loc.node.pat ]);
514530
}
515531

516532
fn check_fn(cx: @AltCheckCtxt,
@@ -565,6 +581,67 @@ fn is_refutable(cx: @AltCheckCtxt, pat: &pat) -> bool {
565581
}
566582
}
567583

584+
// Legality of move bindings checking
585+
586+
fn check_legality_of_move_bindings(cx: @AltCheckCtxt,
587+
is_lvalue: bool,
588+
has_guard: bool,
589+
pats: &[@pat]) {
590+
let tcx = cx.tcx;
591+
let def_map = tcx.def_map;
592+
let mut by_ref_span = None;
593+
let mut any_by_move = false;
594+
for pats.each |pat| {
595+
do pat_bindings(def_map, *pat) |bm, _id, span, _path| {
596+
match bm {
597+
bind_by_ref(_) | bind_by_implicit_ref => {
598+
by_ref_span = Some(span);
599+
}
600+
bind_by_move => {
601+
any_by_move = true;
602+
}
603+
_ => { }
604+
}
605+
}
606+
}
607+
608+
if !any_by_move { return; } // pointless micro-optimization
609+
for pats.each |pat| {
610+
do walk_pat(*pat) |p| {
611+
if pat_is_binding(def_map, p) {
612+
match p.node {
613+
pat_ident(bind_by_move, _, sub) => {
614+
// check legality of moving out of the enum
615+
if sub.is_some() {
616+
tcx.sess.span_err(
617+
p.span,
618+
~"cannot bind by-move with sub-bindings");
619+
} else if has_guard {
620+
tcx.sess.span_err(
621+
p.span,
622+
~"cannot bind by-move into a pattern guard");
623+
} else if by_ref_span.is_some() {
624+
tcx.sess.span_err(
625+
p.span,
626+
~"cannot bind by-move and by-ref \
627+
in the same pattern");
628+
tcx.sess.span_note(
629+
by_ref_span.get(),
630+
~"by-ref binding occurs here");
631+
} else if is_lvalue {
632+
tcx.sess.span_err(
633+
p.span,
634+
~"cannot bind by-move when \
635+
matching an lvalue");
636+
}
637+
}
638+
_ => {}
639+
}
640+
}
641+
}
642+
}
643+
}
644+
568645
// Local Variables:
569646
// mode: rust
570647
// fill-column: 78;

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

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ fn check_alt(fcx: @fn_ctxt,
2121

2222
let pattern_ty = fcx.infcx().next_ty_var();
2323
bot = check_expr_with(fcx, discrim, pattern_ty);
24-
let is_lvalue = ty::expr_is_lval(tcx, fcx.ccx.method_map, discrim);
2524

2625
// Typecheck the patterns first, so that we get types for all the
2726
// bindings.
@@ -34,10 +33,6 @@ fn check_alt(fcx: @fn_ctxt,
3433
};
3534

3635
for arm.pats.each |p| { check_pat(pcx, *p, pattern_ty);}
37-
check_legality_of_move_bindings(fcx,
38-
is_lvalue,
39-
arm.guard.is_some(),
40-
arm.pats);
4136
}
4237

4338
// Now typecheck the blocks.
@@ -58,67 +53,6 @@ fn check_alt(fcx: @fn_ctxt,
5853
return bot;
5954
}
6055

61-
fn check_legality_of_move_bindings(fcx: @fn_ctxt,
62-
is_lvalue: bool,
63-
has_guard: bool,
64-
pats: &[@ast::pat])
65-
{
66-
let tcx = fcx.tcx();
67-
let def_map = tcx.def_map;
68-
let mut by_ref = None;
69-
let mut any_by_move = false;
70-
for pats.each |pat| {
71-
do pat_util::pat_bindings(def_map, *pat) |bm, _id, span, _path| {
72-
match bm {
73-
ast::bind_by_ref(_) | ast::bind_by_implicit_ref => {
74-
by_ref = Some(span);
75-
}
76-
ast::bind_by_move => {
77-
any_by_move = true;
78-
}
79-
_ => { }
80-
}
81-
}
82-
}
83-
84-
if !any_by_move { return; } // pointless micro-optimization
85-
for pats.each |pat| {
86-
do walk_pat(*pat) |p| {
87-
if pat_is_binding(def_map, p) {
88-
match p.node {
89-
ast::pat_ident(ast::bind_by_move, _, sub) => {
90-
// check legality of moving out of the enum
91-
if sub.is_some() {
92-
tcx.sess.span_err(
93-
p.span,
94-
~"cannot bind by-move with sub-bindings");
95-
} else if has_guard {
96-
tcx.sess.span_err(
97-
p.span,
98-
~"cannot bind by-move into a pattern guard");
99-
} else if by_ref.is_some() {
100-
tcx.sess.span_err(
101-
p.span,
102-
~"cannot bind by-move and by-ref \
103-
in the same pattern");
104-
tcx.sess.span_note(
105-
by_ref.get(),
106-
~"by-ref binding occurs here");
107-
} else if is_lvalue {
108-
tcx.sess.span_err(
109-
p.span,
110-
~"cannot bind by-move when \
111-
matching an lvalue");
112-
}
113-
}
114-
_ => {}
115-
}
116-
}
117-
}
118-
}
119-
}
120-
121-
12256
type pat_ctxt = {
12357
fcx: @fn_ctxt,
12458
map: PatIdMap,

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2399,15 +2399,11 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
23992399
let t = ty::mk_var(tcx, fcx.inh.locals.get(local.node.id));
24002400
fcx.write_ty(local.node.id, t);
24012401

2402-
let is_lvalue;
24032402
match local.node.init {
24042403
Some(init) => {
24052404
bot = check_decl_initializer(fcx, local.node.id, init);
2406-
is_lvalue = ty::expr_is_lval(tcx, fcx.ccx.method_map, init);
2407-
}
2408-
_ => {
2409-
is_lvalue = true;
24102405
}
2406+
_ => {}
24112407
}
24122408

24132409
let region =
@@ -2419,11 +2415,6 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
24192415
block_region: region,
24202416
};
24212417
alt::check_pat(pcx, local.node.pat, t);
2422-
let has_guard = false;
2423-
alt::check_legality_of_move_bindings(fcx,
2424-
is_lvalue,
2425-
has_guard,
2426-
[local.node.pat]);
24272418
return bot;
24282419
}
24292420

0 commit comments

Comments
 (0)