Skip to content

Commit 7ebccbb

Browse files
committed
---
yaml --- r: 37821 b: refs/heads/try c: 33c1e47 h: refs/heads/master i: 37819: 5d52fef v: v3
1 parent f12c085 commit 7ebccbb

File tree

20 files changed

+364
-48
lines changed

20 files changed

+364
-48
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 09bb07bed9166105ea961a42b5fff7739ae0d2e9
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: eb8fd119c65c67f3b1b8268cc7341c22d39b7b61
5-
refs/heads/try: f02e9db212199e7d7e70b0330b8ea76caaaa0ea9
5+
refs/heads/try: 33c1e47c1b09216e100951ba9e95a3c0c61c0cc7
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278

branches/try/src/libcore/option.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
150150
/*!
151151
* Returns the leftmost some() value, or none if both are none.
152152
*/
153-
match opta {
154-
Some(_) => move opta,
153+
match move opta {
154+
Some(move opta) => Some(move opta),
155155
_ => move optb
156156
}
157157
}

branches/try/src/libcore/pipes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,9 +1029,9 @@ impl<T: Send> Port<T>: Recv<T> {
10291029
pure fn peek() -> bool unsafe {
10301030
let mut endp = None;
10311031
endp <-> self.endp;
1032-
let peek = match endp {
1033-
Some(ref endp) => pipes::peek(endp),
1034-
None => fail ~"peeking empty stream"
1032+
let peek = match &endp {
1033+
&Some(ref endp) => pipes::peek(endp),
1034+
&None => fail ~"peeking empty stream"
10351035
};
10361036
self.endp <-> endp;
10371037
peek

branches/try/src/librustc/driver/driver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
251251
time(time_passes, ~"alt checking", ||
252252
middle::check_alt::check_crate(ty_cx, crate));
253253

254+
time(time_passes, ~"mode computation", ||
255+
middle::mode::compute_modes(ty_cx, method_map, crate));
256+
254257
let last_use_map =
255258
time(time_passes, ~"liveness checking", ||
256259
middle::liveness::check_crate(ty_cx, method_map, crate));

branches/try/src/librustc/metadata/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
131131
tag_table_method_map = 0x60,
132132
tag_table_vtable_map = 0x61,
133133
tag_table_adjustments = 0x62,
134-
tag_table_legacy_boxed_trait = 0x63
134+
tag_table_legacy_boxed_trait = 0x63,
135+
tag_table_value_mode = 0x64
135136
}
136137

137138
const tag_item_trait_method_sort: uint = 0x70;

branches/try/src/librustc/middle/astencode.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,15 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
856856
ebml_w.id(id);
857857
}
858858
}
859+
860+
do option::iter(&tcx.value_modes.find(id)) |vm| {
861+
do ebml_w.tag(c::tag_table_value_mode) {
862+
ebml_w.id(id);
863+
do ebml_w.tag(c::tag_table_val) {
864+
(*vm).serialize(&ebml_w)
865+
}
866+
}
867+
}
859868
}
860869

861870
trait doc_decoder_helpers {
@@ -990,6 +999,9 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
990999
let adj: @ty::AutoAdjustment = @deserialize(val_dsr);
9911000
adj.tr(xcx);
9921001
dcx.tcx.adjustments.insert(id, adj);
1002+
} else if tag == (c::tag_table_value_mode as uint) {
1003+
let vm: ty::ValueMode = deserialize(val_dsr);
1004+
dcx.tcx.value_modes.insert(id, vm);
9931005
} else {
9941006
xcx.dcx.tcx.sess.bug(
9951007
fmt!("unknown tag found in side tables: %x", tag));

branches/try/src/librustc/middle/kind.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use syntax::{visit, ast_util};
1212
use syntax::ast::*;
1313
use syntax::codemap::span;
1414
use middle::ty::{Kind, kind_copyable, kind_noncopyable, kind_const};
15+
use middle::ty::{CopyValue, MoveValue, ReadValue};
1516
use std::map::HashMap;
1617
use util::ppaux::{ty_to_str, tys_to_str};
1718
use syntax::print::pprust::expr_to_str;
@@ -480,8 +481,16 @@ fn check_copy_ex(cx: ctx, ex: @expr, implicit_copy: bool,
480481
// borrowed unique value isn't really a copy
481482
!is_autorefd(cx, ex)
482483
{
483-
let ty = ty::expr_ty(cx.tcx, ex);
484-
check_copy(cx, ex.id, ty, ex.span, implicit_copy, why);
484+
match cx.tcx.value_modes.find(ex.id) {
485+
None => cx.tcx.sess.span_bug(ex.span, ~"no value mode for lval"),
486+
Some(MoveValue) | Some(ReadValue) => {} // Won't be a copy.
487+
Some(CopyValue) => {
488+
debug!("(kind checking) is a copy value: `%s`",
489+
expr_to_str(ex, cx.tcx.sess.intr()));
490+
let ty = ty::expr_ty(cx.tcx, ex);
491+
check_copy(cx, ex.id, ty, ex.span, implicit_copy, why);
492+
}
493+
}
485494
}
486495

487496
fn is_autorefd(cx: ctx, ex: @expr) -> bool {

branches/try/src/librustc/middle/liveness.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ use syntax::codemap::span;
111111
use syntax::ast::*;
112112
use io::WriterUtil;
113113
use capture::{cap_move, cap_drop, cap_copy, cap_ref};
114+
use middle::ty::MoveValue;
114115

115116
export check_crate;
116117
export last_use_map;
@@ -1533,6 +1534,22 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
15331534
for self.variable_from_def_map(expr.id, expr.span).each |var| {
15341535
let ln = self.live_node(expr.id, expr.span);
15351536
self.consider_last_use(expr, ln, *var);
1537+
1538+
match self.tcx.value_modes.find(expr.id) {
1539+
Some(MoveValue) => {
1540+
debug!("(checking expr) is a move: `%s`",
1541+
expr_to_str(expr, self.tcx.sess.intr()));
1542+
self.check_move_from_var(expr.span, ln, *var);
1543+
}
1544+
Some(v) => {
1545+
debug!("(checking expr) not a move (%?): `%s`",
1546+
v,
1547+
expr_to_str(expr, self.tcx.sess.intr()));
1548+
}
1549+
None => {
1550+
fail ~"no mode for lval";
1551+
}
1552+
}
15361553
}
15371554

15381555
visit::visit_expr(expr, self, vt);
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
use middle::ty;
2+
use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt};
3+
use middle::typeck::{method_map, method_map_entry};
4+
5+
use core::vec;
6+
use std::map::HashMap;
7+
use syntax::ast::{by_copy, by_move, by_ref, by_val, crate, expr, expr_assign};
8+
use syntax::ast::{expr_addr_of, expr_assign_op, expr_binary, expr_call};
9+
use syntax::ast::{expr_copy, expr_field, expr_index, expr_method_call};
10+
use syntax::ast::{expr_path, expr_swap, expr_unary, node_id, sty_uniq};
11+
use syntax::ast::{sty_value};
12+
use syntax::ast::{box, uniq, deref, not, neg, expr_paren};
13+
use syntax::visit;
14+
use syntax::visit::vt;
15+
16+
struct VisitContext {
17+
tcx: ctxt,
18+
method_map: HashMap<node_id,method_map_entry>,
19+
mode: ValueMode,
20+
}
21+
22+
fn compute_modes_for_fn_args(callee_id: node_id,
23+
args: &[@expr],
24+
&&cx: VisitContext,
25+
v: vt<VisitContext>) {
26+
let arg_tys = ty::ty_fn_args(ty::node_id_to_type(cx.tcx, callee_id));
27+
for vec::each2(args, arg_tys) |arg, arg_ty| {
28+
match ty::resolved_mode(cx.tcx, arg_ty.mode) {
29+
by_ref => {
30+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
31+
compute_modes_for_expr(*arg, arg_cx, v);
32+
}
33+
by_val | by_move | by_copy => compute_modes_for_expr(*arg, cx, v)
34+
}
35+
}
36+
}
37+
38+
fn record_mode_for_expr(expr: @expr, &&cx: VisitContext) {
39+
match cx.mode {
40+
ReadValue | CopyValue => {
41+
cx.tcx.value_modes.insert(expr.id, cx.mode);
42+
}
43+
MoveValue => {
44+
// This is, contextually, a move, but if this expression
45+
// is implicitly copyable it's cheaper to copy.
46+
let e_ty = ty::expr_ty(cx.tcx, expr);
47+
if ty::type_implicitly_moves(cx.tcx, e_ty) {
48+
cx.tcx.value_modes.insert(expr.id, MoveValue);
49+
} else {
50+
cx.tcx.value_modes.insert(expr.id, CopyValue);
51+
}
52+
}
53+
}
54+
}
55+
56+
fn compute_modes_for_expr(expr: @expr,
57+
&&cx: VisitContext,
58+
v: vt<VisitContext>) {
59+
// Adjust the mode if there was an implicit reference here.
60+
let cx = match cx.tcx.adjustments.find(expr.id) {
61+
None => cx,
62+
Some(adjustment) => {
63+
if adjustment.autoref.is_some() {
64+
VisitContext { mode: ReadValue, ..cx }
65+
} else {
66+
cx
67+
}
68+
}
69+
};
70+
71+
match expr.node {
72+
expr_call(callee, args, _) => {
73+
let callee_cx = VisitContext { mode: ReadValue, ..cx };
74+
compute_modes_for_expr(callee, callee_cx, v);
75+
compute_modes_for_fn_args(callee.id, args, cx, v);
76+
}
77+
expr_path(*) => {
78+
record_mode_for_expr(expr, cx);
79+
}
80+
expr_copy(expr) => {
81+
let callee_cx = VisitContext { mode: CopyValue, ..cx };
82+
compute_modes_for_expr(expr, callee_cx, v);
83+
}
84+
expr_method_call(callee, _, _, args, _) => {
85+
// The LHS of the dot may or may not result in a move, depending
86+
// on the method map entry.
87+
let callee_mode;
88+
match cx.method_map.find(expr.id) {
89+
Some(ref method_map_entry) => {
90+
match method_map_entry.explicit_self {
91+
sty_uniq(_) | sty_value => callee_mode = MoveValue,
92+
_ => callee_mode = ReadValue
93+
}
94+
}
95+
None => {
96+
cx.tcx.sess.span_bug(expr.span, ~"no method map entry");
97+
}
98+
}
99+
100+
let callee_cx = VisitContext { mode: callee_mode, ..cx };
101+
compute_modes_for_expr(callee, callee_cx, v);
102+
103+
compute_modes_for_fn_args(expr.callee_id, args, cx, v);
104+
}
105+
expr_binary(_, lhs, rhs) | expr_assign_op(_, lhs, rhs) => {
106+
// The signatures of these take their arguments by-ref, so they
107+
// don't copy or move.
108+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
109+
compute_modes_for_expr(lhs, arg_cx, v);
110+
compute_modes_for_expr(rhs, arg_cx, v);
111+
}
112+
expr_addr_of(_, arg) => {
113+
// Takes its argument by-ref, so it doesn't copy or move.
114+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
115+
compute_modes_for_expr(arg, arg_cx, v);
116+
}
117+
expr_unary(unop, arg) => {
118+
// Ditto.
119+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
120+
compute_modes_for_expr(arg, arg_cx, v);
121+
122+
match unop {
123+
deref => {
124+
// This is an lvalue, so it needs a value mode recorded
125+
// for it.
126+
record_mode_for_expr(expr, cx);
127+
}
128+
box(_) | uniq(_) | not | neg => {}
129+
}
130+
}
131+
expr_field(arg, _, _) => {
132+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
133+
compute_modes_for_expr(arg, arg_cx, v);
134+
135+
record_mode_for_expr(expr, cx);
136+
}
137+
expr_assign(lhs, rhs) => {
138+
// The signatures of these take their arguments by-ref, so they
139+
// don't copy or move.
140+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
141+
compute_modes_for_expr(lhs, arg_cx, v);
142+
compute_modes_for_expr(rhs, cx, v);
143+
}
144+
expr_swap(lhs, rhs) => {
145+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
146+
compute_modes_for_expr(lhs, arg_cx, v);
147+
compute_modes_for_expr(rhs, arg_cx, v);
148+
}
149+
expr_index(lhs, rhs) => {
150+
let lhs_cx = VisitContext { mode: ReadValue, ..cx };
151+
compute_modes_for_expr(lhs, lhs_cx, v);
152+
let rhs_cx = VisitContext { mode: MoveValue, ..cx };
153+
compute_modes_for_expr(rhs, rhs_cx, v);
154+
155+
record_mode_for_expr(expr, cx);
156+
}
157+
expr_paren(arg) => {
158+
compute_modes_for_expr(arg, cx, v);
159+
record_mode_for_expr(expr, cx);
160+
}
161+
_ => {
162+
// XXX: Spell out every expression above so when we add them we
163+
// don't forget to update this file.
164+
visit::visit_expr(expr, cx, v)
165+
}
166+
}
167+
}
168+
169+
pub fn compute_modes(tcx: ctxt, method_map: method_map, crate: @crate) {
170+
let visitor = visit::mk_vt(@{
171+
visit_expr: compute_modes_for_expr,
172+
.. *visit::default_visitor()
173+
});
174+
let callee_cx = VisitContext {
175+
tcx: tcx,
176+
method_map: method_map,
177+
mode: MoveValue
178+
};
179+
visit::visit_crate(*crate, callee_cx, visitor);
180+
}
181+

branches/try/src/librustc/middle/trans/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ fn build_closure(bcx0: block,
270270
let mut env_vals = ~[];
271271
for vec::each(cap_vars) |cap_var| {
272272
debug!("Building closure: captured variable %?", *cap_var);
273-
let datum = expr::trans_local_var(bcx, cap_var.def);
273+
let datum = expr::trans_local_var(bcx, cap_var.def, None);
274274
match cap_var.mode {
275275
capture::cap_ref => {
276276
assert proto == ast::ProtoBorrowed;

branches/try/src/librustc/middle/trans/datum.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,17 @@ impl Datum {
509509
}
510510
}
511511

512-
fn GEPi(bcx: block, ixs: &[uint], ty: ty::t) -> Datum {
512+
fn GEPi(bcx: block,
513+
ixs: &[uint],
514+
ty: ty::t,
515+
source: DatumSource)
516+
-> Datum {
513517
let base_val = self.to_ref_llval(bcx);
514518
Datum {
515519
val: GEPi(bcx, base_val, ixs),
516520
mode: ByRef,
517521
ty: ty,
518-
source: FromLvalue
522+
source: source
519523
}
520524
}
521525

0 commit comments

Comments
 (0)