Skip to content

Commit 98fdcb0

Browse files
committed
librustc: De-mode pattern bindings. r=nmatsakis
1 parent 184f510 commit 98fdcb0

File tree

16 files changed

+99
-108
lines changed

16 files changed

+99
-108
lines changed

src/librustc/driver/driver.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,12 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
248248
time(time_passes, ~"loop checking", ||
249249
middle::check_loop::check_crate(ty_cx, crate));
250250

251-
time(time_passes, ~"alt checking", ||
252-
middle::check_alt::check_crate(ty_cx, method_map, crate));
253-
254251
time(time_passes, ~"mode computation", ||
255252
middle::mode::compute_modes(ty_cx, method_map, crate));
256253

254+
time(time_passes, ~"alt checking", ||
255+
middle::check_alt::check_crate(ty_cx, method_map, crate));
256+
257257
let last_use_map =
258258
time(time_passes, ~"liveness checking", ||
259259
middle::liveness::check_crate(ty_cx, method_map, crate));

src/librustc/middle/borrowck/gather_loans.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -529,20 +529,9 @@ impl gather_loan_ctxt {
529529
self.guarantee_valid(cmt, mutbl, scope_r);
530530
}
531531
}
532-
ast::bind_by_implicit_ref => {
533-
// Note: there is a discussion of the function of
534-
// cat_discr in the method preserve():
535-
let cmt1 = self.bccx.cat_discr(cmt, alt_id);
536-
let arm_scope = ty::re_scope(arm_id);
537-
538-
// We used to remember the mutability of the location
539-
// that this binding refers to and use it later when
540-
// categorizing the binding. This hack is being
541-
// removed in favor of ref mode bindings.
542-
//
543-
// self.bccx.binding_map.insert(pat.id, cmt1.mutbl);
544-
545-
self.guarantee_valid(cmt1, m_const, arm_scope);
532+
ast::bind_infer => {
533+
// Nothing to do here; this is either a copy or a move;
534+
// thus either way there is nothing to check. Yay!
546535
}
547536
}
548537
}

src/librustc/middle/check_alt.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,15 +592,25 @@ fn check_legality_of_move_bindings(cx: @AltCheckCtxt,
592592
let mut by_ref_span = None;
593593
let mut any_by_move = false;
594594
for pats.each |pat| {
595-
do pat_bindings(def_map, *pat) |bm, _id, span, _path| {
595+
do pat_bindings(def_map, *pat) |bm, id, span, _path| {
596596
match bm {
597-
bind_by_ref(_) | bind_by_implicit_ref => {
597+
bind_by_ref(_) => {
598598
by_ref_span = Some(span);
599599
}
600600
bind_by_move => {
601601
any_by_move = true;
602602
}
603-
_ => { }
603+
bind_by_value => {}
604+
bind_infer => {
605+
match cx.tcx.value_modes.find(id) {
606+
Some(MoveValue) => any_by_move = true,
607+
Some(CopyValue) | Some(ReadValue) => {}
608+
None => {
609+
cx.tcx.sess.span_bug(span, ~"no mode for pat \
610+
binding");
611+
}
612+
}
613+
}
604614
}
605615
}
606616
}

src/librustc/middle/lint.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -767,27 +767,6 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) {
767767
}
768768
}
769769

770-
fn check_pat(tcx: ty::ctxt, pat: @ast::pat) {
771-
debug!("lint check_pat pat=%s", pat_to_str(pat, tcx.sess.intr()));
772-
773-
do pat_bindings(tcx.def_map, pat) |binding_mode, id, span, path| {
774-
match binding_mode {
775-
ast::bind_by_ref(_) | ast::bind_by_value | ast::bind_by_move => {}
776-
ast::bind_by_implicit_ref => {
777-
let pat_ty = ty::node_id_to_type(tcx, id);
778-
let kind = ty::type_kind(tcx, pat_ty);
779-
if !ty::kind_is_safe_for_default_mode(kind) {
780-
tcx.sess.span_lint(
781-
deprecated_pattern, id, id,
782-
span,
783-
fmt!("binding `%s` should use ref or copy mode",
784-
tcx.sess.str_of(path_to_ident(path))));
785-
}
786-
}
787-
}
788-
}
789-
}
790-
791770
fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl,
792771
_body: ast::blk, span: span, id: ast::node_id) {
793772
debug!("lint check_fn fk=%? id=%?", fk, id);
@@ -904,8 +883,6 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
904883
check_item(it, tcx),
905884
visit_fn: |fk, decl, body, span, id|
906885
check_fn(tcx, fk, decl, body, span, id),
907-
visit_pat: |pat|
908-
check_pat(tcx, pat),
909886
.. *visit::default_simple_visitor()
910887
});
911888
visit::visit_crate(*crate, (), v);

src/librustc/middle/liveness.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,7 @@ impl IrMaps {
390390
Arg(id, _, by_copy) |
391391
Local(LocalInfo {id: id, kind: FromLetNoInitializer, _}) |
392392
Local(LocalInfo {id: id, kind: FromLetWithInitializer, _}) |
393-
Local(LocalInfo {id: id, kind: FromMatch(bind_by_value), _}) |
394-
Local(LocalInfo {id: id, kind: FromMatch(bind_by_ref(_)), _}) |
395-
Local(LocalInfo {id: id, kind: FromMatch(bind_by_move), _}) => {
393+
Local(LocalInfo {id: id, kind: FromMatch(_), _}) => {
396394
let v = match self.last_use_map.find(expr_id) {
397395
Some(v) => v,
398396
None => {
@@ -405,8 +403,7 @@ impl IrMaps {
405403
(*v).push(id);
406404
}
407405
Arg(_, _, by_ref) |
408-
Arg(_, _, by_val) | Self | ImplicitRet |
409-
Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
406+
Arg(_, _, by_val) | Self | ImplicitRet => {
410407
debug!("--but it is not owned");
411408
}
412409
}

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -636,28 +636,12 @@ impl &mem_categorization_ctxt {
636636
mutbl:m, ty:expr_ty}
637637
}
638638

639-
ast::def_binding(vid, ast::bind_by_value) |
640-
ast::def_binding(vid, ast::bind_by_move) |
641-
ast::def_binding(vid, ast::bind_by_ref(_)) => {
639+
ast::def_binding(vid, _) => {
642640
// by-value/by-ref bindings are local variables
643641
@{id:id, span:span,
644642
cat:cat_local(vid), lp:Some(@lp_local(vid)),
645643
mutbl:m_imm, ty:expr_ty}
646644
}
647-
648-
ast::def_binding(pid, ast::bind_by_implicit_ref) => {
649-
// implicit-by-ref bindings are "special" since they are
650-
// implicit pointers.
651-
652-
// Technically, the mutability is not always imm, but we
653-
// (choose to be) unsound for the moment since these
654-
// implicit refs are going away and it reduces external
655-
// dependencies.
656-
657-
@{id:id, span:span,
658-
cat:cat_binding(pid), lp:None,
659-
mutbl:m_imm, ty:expr_ty}
660-
}
661645
}
662646
}
663647

src/librustc/middle/mode.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
use middle::pat_util;
12
use middle::ty;
23
use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt};
34
use middle::typeck::{method_map, method_map_entry};
45

56
use core::vec;
67
use std::map::HashMap;
7-
use syntax::ast::{box, by_copy, by_move, by_ref, by_val, crate, deref, expr};
8-
use syntax::ast::{expr_addr_of, expr_assign, expr_assign_op, expr_binary};
9-
use syntax::ast::{expr_call, expr_copy, expr_field, expr_index, expr_match};
10-
use syntax::ast::{expr_method_call, expr_paren, expr_path, expr_swap};
11-
use syntax::ast::{expr_unary, neg, node_id, not, sty_uniq, sty_value, uniq};
8+
use syntax::ast::{bind_infer, box, by_copy, by_move, by_ref, by_val, crate};
9+
use syntax::ast::{deref, expr, expr_addr_of, expr_assign, expr_assign_op};
10+
use syntax::ast::{expr_binary, expr_call, expr_copy, expr_field, expr_index};
11+
use syntax::ast::{expr_match, expr_method_call, expr_paren, expr_path};
12+
use syntax::ast::{expr_swap, expr_unary, neg, node_id, not, pat, pat_ident};
13+
use syntax::ast::{sty_uniq, sty_value, uniq};
1214
use syntax::visit;
1315
use syntax::visit::vt;
1416

@@ -166,18 +168,21 @@ fn compute_modes_for_expr(expr: @expr,
166168
record_mode_for_expr(expr, cx);
167169
}
168170
expr_match(head, ref arms) => {
171+
// We must do this first so that `arms_have_by_move_bindings`
172+
// below knows which bindings are moves.
173+
for arms.each |arm| {
174+
(v.visit_arm)(*arm, cx, v);
175+
}
176+
169177
let by_move_bindings_present =
170-
pat_util::arms_have_by_move_bindings(cx.tcx.def_map, *arms);
178+
pat_util::arms_have_by_move_bindings(cx.tcx, *arms);
171179
if by_move_bindings_present {
172180
// Propagate the current mode flag downward.
173181
visit::visit_expr(expr, cx, v);
174182
} else {
175183
// We aren't moving into any pattern, so this is just a read.
176184
let head_cx = VisitContext { mode: ReadValue, ..cx };
177185
compute_modes_for_expr(head, head_cx, v);
178-
for arms.each |arm| {
179-
(v.visit_arm)(*arm, cx, v);
180-
}
181186
}
182187
}
183188
_ => {
@@ -188,9 +193,28 @@ fn compute_modes_for_expr(expr: @expr,
188193
}
189194
}
190195

196+
fn compute_modes_for_pat(pat: @pat,
197+
&&cx: VisitContext,
198+
v: vt<VisitContext>) {
199+
match pat.node {
200+
pat_ident(bind_infer, _, _)
201+
if pat_util::pat_is_binding(cx.tcx.def_map, pat) => {
202+
if ty::type_implicitly_moves(cx.tcx, ty::pat_ty(cx.tcx, pat)) {
203+
cx.tcx.value_modes.insert(pat.id, MoveValue);
204+
} else {
205+
cx.tcx.value_modes.insert(pat.id, CopyValue);
206+
}
207+
}
208+
_ => {}
209+
}
210+
211+
visit::visit_pat(pat, cx, v);
212+
}
213+
191214
pub fn compute_modes(tcx: ctxt, method_map: method_map, crate: @crate) {
192215
let visitor = visit::mk_vt(@{
193216
visit_expr: compute_modes_for_expr,
217+
visit_pat: compute_modes_for_pat,
194218
.. *visit::default_visitor()
195219
});
196220
let callee_cx = VisitContext {

src/librustc/middle/pat_util.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use middle::ty::{CopyValue, MoveValue, ReadValue};
12+
1113
use syntax::ast::*;
1214
use syntax::ast_util;
1315
use syntax::ast_util::{path_to_ident, respan, walk_pat};
@@ -93,16 +95,25 @@ fn pat_binding_ids(dm: resolve::DefMap, pat: @pat) -> ~[node_id] {
9395
return found;
9496
}
9597

96-
fn arms_have_by_move_bindings(dm: resolve::DefMap, +arms: &[arm]) -> bool {
98+
fn arms_have_by_move_bindings(tcx: ty::ctxt, +arms: &[arm]) -> bool {
9799
for arms.each |arm| {
98100
for arm.pats.each |pat| {
99101
let mut found = false;
100-
do pat_bindings(dm, *pat) |binding_mode, _node_id, _span, _path| {
102+
do pat_bindings(tcx.def_map, *pat)
103+
|binding_mode, node_id, span, _path| {
101104
match binding_mode {
102105
bind_by_move => found = true,
103-
bind_by_implicit_ref |
104-
bind_by_ref(*) |
105-
bind_by_value => {}
106+
bind_infer => {
107+
match tcx.value_modes.find(node_id) {
108+
Some(MoveValue) => found = true,
109+
Some(CopyValue) | Some(ReadValue) => {}
110+
None => {
111+
tcx.sess.span_bug(span, ~"pat binding not in \
112+
value mode map");
113+
}
114+
}
115+
}
116+
bind_by_ref(*) | bind_by_value => {}
106117
}
107118
}
108119
if found { return true; }

src/librustc/middle/resolve.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use middle::lang_items::LanguageItems;
1717
use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
1818
use middle::pat_util::{pat_bindings};
1919
use syntax::ast::{_mod, add, arm};
20-
use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
2120
use syntax::ast::{bitand, bitor, bitxor};
2221
use syntax::ast::{binding_mode, blk, capture_clause, class_ctor, class_dtor};
2322
use syntax::ast::{crate, crate_num, decl_item};

src/librustc/middle/trans/alt.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ use syntax::ast::def_id;
154154
use syntax::codemap::span;
155155
use syntax::print::pprust::pat_to_str;
156156
use middle::resolve::DefMap;
157+
use middle::ty::{CopyValue, MoveValue, ReadValue};
157158
use back::abi;
158159
use std::map::HashMap;
159160
use dvec::DVec;
@@ -1394,7 +1395,7 @@ fn trans_alt_inner(scope_cx: block,
13941395
// Note that we use the names because each binding will have many ids
13951396
// from the various alternatives.
13961397
let bindings_map = std::map::HashMap();
1397-
do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, _s, path| {
1398+
do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, s, path| {
13981399
let ident = path_to_ident(path);
13991400
let variable_ty = node_id_type(bcx, p_id);
14001401
let llvariable_ty = type_of::type_of(bcx.ccx(), variable_ty);
@@ -1408,9 +1409,18 @@ fn trans_alt_inner(scope_cx: block,
14081409
llmatch = alloca(bcx, T_ptr(llvariable_ty));
14091410
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
14101411
}
1411-
ast::bind_by_implicit_ref => {
1412+
ast::bind_infer => {
1413+
// in this case also, the type of the variable will be T,
1414+
// but we need to store a *T
1415+
let is_move = match tcx.value_modes.find(p_id) {
1416+
None => {
1417+
tcx.sess.span_bug(s, ~"no value mode");
1418+
}
1419+
Some(MoveValue) => true,
1420+
Some(CopyValue) | Some(ReadValue) => false
1421+
};
14121422
llmatch = alloca(bcx, T_ptr(llvariable_ty));
1413-
trmode = TrByImplicitRef;
1423+
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
14141424
}
14151425
ast::bind_by_ref(_) => {
14161426
llmatch = alloca(bcx, llvariable_ty);

src/librustc/middle/typeck/check/alt.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
358358
demand::eqtype(fcx, pat.span, region_ty, typ);
359359
}
360360
// otherwise the type of x is the expected type T
361-
ast::bind_by_value => {
362-
demand::eqtype(fcx, pat.span, expected, typ);
363-
}
364-
ast::bind_by_move => {
365-
demand::eqtype(fcx, pat.span, expected, typ);
366-
}
367-
ast::bind_by_implicit_ref => {
361+
ast::bind_by_value | ast::bind_by_move | ast::bind_infer => {
368362
demand::eqtype(fcx, pat.span, expected, typ);
369363
}
370364
}

src/libstd/json.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pub impl<
291291
Number(v) => v.serialize(s),
292292
String(ref v) => v.serialize(s),
293293
Boolean(v) => v.serialize(s),
294-
List(v) => v.serialize(s),
294+
List(ref v) => v.serialize(s),
295295
Object(ref v) => {
296296
do s.emit_rec || {
297297
let mut idx = 0;
@@ -927,8 +927,8 @@ impl Json : Eq {
927927
match *other { Boolean(b1) => b0 == b1, _ => false },
928928
Null =>
929929
match *other { Null => true, _ => false },
930-
List(v0) =>
931-
match *other { List(v1) => v0 == v1, _ => false },
930+
List(ref v0) =>
931+
match *other { List(ref v1) => v0 == v1, _ => false },
932932
Object(ref d0) => {
933933
match *other {
934934
Object(ref d1) => {
@@ -981,10 +981,10 @@ impl Json : Ord {
981981
}
982982
}
983983

984-
List(l0) => {
984+
List(ref l0) => {
985985
match *other {
986986
Number(_) | String(_) | Boolean(_) => false,
987-
List(l1) => l0 < l1,
987+
List(ref l1) => (*l0) < (*l1),
988988
Object(_) | Null => true
989989
}
990990
}

src/libsyntax/ast.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ enum binding_mode {
309309
bind_by_value,
310310
bind_by_move,
311311
bind_by_ref(ast::mutability),
312-
bind_by_implicit_ref
312+
bind_infer
313313
}
314314

315315
impl binding_mode : to_bytes::IterBytes {
@@ -322,7 +322,7 @@ impl binding_mode : to_bytes::IterBytes {
322322
bind_by_ref(ref m) =>
323323
to_bytes::iter_bytes_2(&2u8, m, lsb0, f),
324324

325-
bind_by_implicit_ref =>
325+
bind_infer =>
326326
3u8.iter_bytes(lsb0, f),
327327
}
328328
}
@@ -349,9 +349,9 @@ impl binding_mode : cmp::Eq {
349349
_ => false
350350
}
351351
}
352-
bind_by_implicit_ref => {
352+
bind_infer => {
353353
match (*other) {
354-
bind_by_implicit_ref => true,
354+
bind_infer => true,
355355
_ => false
356356
}
357357
}

0 commit comments

Comments
 (0)