Skip to content

Commit 7203be1

Browse files
committed
librustc: Fix handling of ~ and @ unary operators in mode computation. Closes #4114. rs=bugfix
1 parent b58e1f6 commit 7203be1

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

src/librustc/metadata/tydecode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
316316
match st.tcx.rcache.find({cnum: st.crate, pos: pos, len: len}) {
317317
Some(tt) => return tt,
318318
None => {
319-
let ps = @{pos: pos ,.. *st};
319+
let ps = @{pos: pos ,.. copy *st};
320320
let tt = parse_ty(ps, conv);
321321
st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt);
322322
return tt;

src/librustc/middle/mode.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ use middle::typeck::{method_map, method_map_entry};
44

55
use core::vec;
66
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_match, expr_paren};
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};
1312
use syntax::visit;
1413
use syntax::visit::vt;
1514

@@ -115,17 +114,25 @@ fn compute_modes_for_expr(expr: @expr,
115114
compute_modes_for_expr(arg, arg_cx, v);
116115
}
117116
expr_unary(unop, arg) => {
118-
// Ditto.
119-
let arg_cx = VisitContext { mode: ReadValue, ..cx };
120-
compute_modes_for_expr(arg, arg_cx, v);
121-
122117
match unop {
123118
deref => {
119+
// Derefs function as reads.
120+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
121+
compute_modes_for_expr(arg, arg_cx, v);
122+
124123
// This is an lvalue, so it needs a value mode recorded
125124
// for it.
126125
record_mode_for_expr(expr, cx);
127126
}
128-
box(_) | uniq(_) | not | neg => {}
127+
box(_) | uniq(_) => {
128+
let arg_cx = VisitContext { mode: MoveValue, ..cx };
129+
compute_modes_for_expr(arg, arg_cx, v);
130+
}
131+
not | neg => {
132+
// Takes its argument by ref.
133+
let arg_cx = VisitContext { mode: ReadValue, ..cx };
134+
compute_modes_for_expr(arg, arg_cx, v);
135+
}
129136
}
130137
}
131138
expr_field(arg, _, _) => {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2457,7 +2457,7 @@ fn check_block_no_value(fcx: @fn_ctxt, blk: ast::blk) -> bool {
24572457

24582458
fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
24592459
let fcx = match blk.node.rules {
2460-
ast::unsafe_blk => @fn_ctxt {purity: ast::unsafe_fn,.. *fcx0},
2460+
ast::unsafe_blk => @fn_ctxt {purity: ast::unsafe_fn,.. copy *fcx0},
24612461
ast::default_blk => fcx0
24622462
};
24632463
do fcx.with_region_lb(blk.node.id) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn dup(x: ~int) -> ~(~int,~int) { ~(x, x) } //~ ERROR use of moved variable
2+
fn main() {
3+
dup(~3);
4+
}

0 commit comments

Comments
 (0)