From 7203be1109d6e29dce14a842d454922c665ade3f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 5 Dec 2012 22:57:58 -0800 Subject: [PATCH] librustc: Fix handling of `~` and `@` unary operators in mode computation. Closes #4114. rs=bugfix --- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/middle/mode.rs | 29 ++++++++++++------- src/librustc/middle/typeck/check/mod.rs | 2 +- .../compile-fail/move-based-on-type-tuple.rs | 4 +++ 4 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/test/compile-fail/move-based-on-type-tuple.rs diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index ab84ae6e0619..9cad123edc56 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -316,7 +316,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { match st.tcx.rcache.find({cnum: st.crate, pos: pos, len: len}) { Some(tt) => return tt, None => { - let ps = @{pos: pos ,.. *st}; + let ps = @{pos: pos ,.. copy *st}; let tt = parse_ty(ps, conv); st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt); return tt; diff --git a/src/librustc/middle/mode.rs b/src/librustc/middle/mode.rs index c763c9f74891..e1bea7714b3a 100644 --- a/src/librustc/middle/mode.rs +++ b/src/librustc/middle/mode.rs @@ -4,12 +4,11 @@ use middle::typeck::{method_map, method_map_entry}; use core::vec; use std::map::HashMap; -use syntax::ast::{by_copy, by_move, by_ref, by_val, crate, expr, expr_assign}; -use syntax::ast::{expr_addr_of, expr_assign_op, expr_binary, expr_call}; -use syntax::ast::{expr_copy, expr_field, expr_index, expr_method_call}; -use syntax::ast::{expr_path, expr_swap, expr_unary, node_id, sty_uniq}; -use syntax::ast::{sty_value}; -use syntax::ast::{box, uniq, deref, not, neg, expr_match, expr_paren}; +use syntax::ast::{box, by_copy, by_move, by_ref, by_val, crate, deref, expr}; +use syntax::ast::{expr_addr_of, expr_assign, expr_assign_op, expr_binary}; +use syntax::ast::{expr_call, expr_copy, expr_field, expr_index, expr_match}; +use syntax::ast::{expr_method_call, expr_paren, expr_path, expr_swap}; +use syntax::ast::{expr_unary, neg, node_id, not, sty_uniq, sty_value, uniq}; use syntax::visit; use syntax::visit::vt; @@ -115,17 +114,25 @@ fn compute_modes_for_expr(expr: @expr, compute_modes_for_expr(arg, arg_cx, v); } expr_unary(unop, arg) => { - // Ditto. - let arg_cx = VisitContext { mode: ReadValue, ..cx }; - compute_modes_for_expr(arg, arg_cx, v); - match unop { deref => { + // Derefs function as reads. + let arg_cx = VisitContext { mode: ReadValue, ..cx }; + compute_modes_for_expr(arg, arg_cx, v); + // This is an lvalue, so it needs a value mode recorded // for it. record_mode_for_expr(expr, cx); } - box(_) | uniq(_) | not | neg => {} + box(_) | uniq(_) => { + let arg_cx = VisitContext { mode: MoveValue, ..cx }; + compute_modes_for_expr(arg, arg_cx, v); + } + not | neg => { + // Takes its argument by ref. + let arg_cx = VisitContext { mode: ReadValue, ..cx }; + compute_modes_for_expr(arg, arg_cx, v); + } } } expr_field(arg, _, _) => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 3b9ad6e7184d..ecd29a6f6431 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2457,7 +2457,7 @@ fn check_block_no_value(fcx: @fn_ctxt, blk: ast::blk) -> bool { fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool { let fcx = match blk.node.rules { - ast::unsafe_blk => @fn_ctxt {purity: ast::unsafe_fn,.. *fcx0}, + ast::unsafe_blk => @fn_ctxt {purity: ast::unsafe_fn,.. copy *fcx0}, ast::default_blk => fcx0 }; do fcx.with_region_lb(blk.node.id) { diff --git a/src/test/compile-fail/move-based-on-type-tuple.rs b/src/test/compile-fail/move-based-on-type-tuple.rs new file mode 100644 index 000000000000..778bb8d557b9 --- /dev/null +++ b/src/test/compile-fail/move-based-on-type-tuple.rs @@ -0,0 +1,4 @@ +fn dup(x: ~int) -> ~(~int,~int) { ~(x, x) } //~ ERROR use of moved variable +fn main() { + dup(~3); +}