Skip to content

Commit 7902172

Browse files
committed
---
yaml --- r: 127487 b: refs/heads/master c: e7a5e8f h: refs/heads/master i: 127485: 164e970 127483: 8ef15ce 127479: ddd193a 127471: 223e8da 127455: 0a0607b 127423: d438295 127359: 2f4800f 127231: e4ec2d8 126975: 331ad03 v: v3
1 parent 5cde31f commit 7902172

37 files changed

+276
-48
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 954bae9df17681e611be4bf943c34b492db46dc8
2+
refs/heads/master: e7a5e8ff3bafa6d4d5a517e399597666947a5e07
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 12e0f72f517516ac4fce2aed85e6142e9b874bce
55
refs/heads/try: e9a2d9f337a45a2ddcd854d1039bbc9f907de41a

trunk/src/doc/guide-pointers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ This part is coming soon.
655655
# Returning Pointers
656656

657657
In many languages with pointers, you'd return a pointer from a function
658-
so as to avoid a copying a large data structure. For example:
658+
so as to avoid copying a large data structure. For example:
659659

660660
```{rust}
661661
struct BigStruct {

trunk/src/doc/tutorial.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,16 @@ let xs = Cons(1, box Cons(2, box Cons(3, box Nil)));
11331133
let ys = xs; // copies `Cons(u32, pointer)` shallowly
11341134
~~~
11351135

1136+
> *Note:* Names like `xs` and `ys` are a naming
1137+
> convention for collection-like data structures
1138+
> (like our `List`). These collections are given
1139+
> names appended with 's' to signify plurality,
1140+
> i.e. that the data structure stores multiple
1141+
> elements. For example, `xs` in this case can
1142+
> be read as "a list of ex-es", where "x" here
1143+
> are elements of type `u32`.
1144+
1145+
11361146
Rust will consider a shallow copy of a type with a destructor like `List` to
11371147
*move ownership* of the value. After a value has been moved, the source
11381148
location cannot be used unless it is reinitialized.

trunk/src/librustc/metadata/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
140140
tag_table_moves_map = 0x52,
141141
tag_table_capture_map = 0x53,
142142
tag_table_unboxed_closure_type = 0x54,
143+
tag_table_upvar_borrow_map = 0x55,
143144
}
144145
static first_astencode_tag: uint = tag_ast as uint;
145-
static last_astencode_tag: uint = tag_table_unboxed_closure_type as uint;
146+
static last_astencode_tag: uint = tag_table_upvar_borrow_map as uint;
146147
impl astencode_tag {
147148
pub fn from_uint(value : uint) -> Option<astencode_tag> {
148149
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;

trunk/src/librustc/middle/astencode.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use driver::session::Session;
1818
use metadata::decoder;
1919
use middle::def;
2020
use e = metadata::encoder;
21+
use middle::freevars;
2122
use middle::freevars::freevar_entry;
2223
use middle::region;
2324
use metadata::tydecode;
@@ -551,6 +552,15 @@ impl tr for freevar_entry {
551552
}
552553
}
553554

555+
impl tr for ty::UpvarBorrow {
556+
fn tr(&self, xcx: &ExtendedDecodeContext) -> ty::UpvarBorrow {
557+
ty::UpvarBorrow {
558+
kind: self.kind,
559+
region: self.region.tr(xcx)
560+
}
561+
}
562+
}
563+
554564
// ______________________________________________________________________
555565
// Encoding and decoding of MethodCallee
556566

@@ -1061,7 +1071,29 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10611071
Ok(encode_freevar_entry(rbml_w, fv_entry))
10621072
});
10631073
})
1064-
})
1074+
});
1075+
1076+
for freevar in fv.iter() {
1077+
match freevars::get_capture_mode(tcx, id) {
1078+
freevars::CaptureByRef => {
1079+
rbml_w.tag(c::tag_table_upvar_borrow_map, |rbml_w| {
1080+
rbml_w.id(id);
1081+
rbml_w.tag(c::tag_table_val, |rbml_w| {
1082+
let var_id = freevar.def.def_id().node;
1083+
let upvar_id = ty::UpvarId {
1084+
var_id: var_id,
1085+
closure_expr_id: id
1086+
};
1087+
let upvar_borrow = tcx.upvar_borrow_map.borrow()
1088+
.get_copy(&upvar_id);
1089+
var_id.encode(rbml_w);
1090+
upvar_borrow.encode(rbml_w);
1091+
})
1092+
})
1093+
}
1094+
_ => {}
1095+
}
1096+
}
10651097
}
10661098

10671099
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
@@ -1468,6 +1500,15 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
14681500
}).unwrap().move_iter().collect();
14691501
dcx.tcx.freevars.borrow_mut().insert(id, fv_info);
14701502
}
1503+
c::tag_table_upvar_borrow_map => {
1504+
let var_id: ast::NodeId = Decodable::decode(val_dsr).unwrap();
1505+
let upvar_id = ty::UpvarId {
1506+
var_id: xcx.tr_id(var_id),
1507+
closure_expr_id: id
1508+
};
1509+
let ub: ty::UpvarBorrow = Decodable::decode(val_dsr).unwrap();
1510+
dcx.tcx.upvar_borrow_map.borrow_mut().insert(upvar_id, ub.tr(xcx));
1511+
}
14711512
c::tag_table_tcache => {
14721513
let pty = val_dsr.read_polytype(xcx);
14731514
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };

trunk/src/librustc/middle/freevars.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![allow(non_camel_case_types)]
1515

1616
use middle::def;
17+
use middle::mem_categorization::Typer;
1718
use middle::resolve;
1819
use middle::ty;
1920
use util::nodemap::{DefIdSet, NodeMap, NodeSet};
@@ -147,11 +148,8 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]|
147148
}
148149
}
149150

150-
pub fn get_capture_mode(tcx: &ty::ctxt,
151-
closure_expr_id: ast::NodeId)
152-
-> CaptureMode
153-
{
154-
let fn_ty = ty::node_id_to_type(tcx, closure_expr_id);
151+
pub fn get_capture_mode<T: Typer>(tcx: &T, closure_expr_id: ast::NodeId) -> CaptureMode {
152+
let fn_ty = tcx.node_ty(closure_expr_id).ok().expect("couldn't find closure ty?");
155153
match ty::ty_closure_store(fn_ty) {
156154
ty::RegionTraitStore(..) => CaptureByRef,
157155
ty::UniqTraitStore => CaptureByValue

trunk/src/librustc/middle/trans/_match.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@
189189
#![allow(non_camel_case_types)]
190190

191191
use back::abi;
192+
use mc = middle::mem_categorization;
192193
use driver::config::FullDebugInfo;
194+
use euv = middle::expr_use_visitor;
193195
use llvm;
194196
use llvm::{ValueRef, BasicBlockRef};
195197
use middle::const_eval;
@@ -1292,13 +1294,58 @@ pub fn trans_match<'a>(
12921294
trans_match_inner(bcx, match_expr.id, discr_expr, arms, dest)
12931295
}
12941296

1295-
fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
1297+
/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
1298+
fn is_discr_reassigned(bcx: &Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
1299+
match discr.node {
1300+
ast::ExprPath(..) => match bcx.def(discr.id) {
1301+
def::DefArg(vid, _) | def::DefBinding(vid, _) |
1302+
def::DefLocal(vid, _) | def::DefUpvar(vid, _, _, _) => {
1303+
let mut rc = ReassignmentChecker {
1304+
node: vid,
1305+
reassigned: false
1306+
};
1307+
{
1308+
let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
1309+
visitor.walk_expr(body);
1310+
}
1311+
rc.reassigned
1312+
}
1313+
_ => false
1314+
},
1315+
_ => false
1316+
}
1317+
}
1318+
1319+
struct ReassignmentChecker {
1320+
node: ast::NodeId,
1321+
reassigned: bool
1322+
}
1323+
1324+
impl euv::Delegate for ReassignmentChecker {
1325+
fn consume(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: euv::ConsumeMode) {}
1326+
fn consume_pat(&mut self, _: &ast::Pat, _: mc::cmt, _: euv::ConsumeMode) {}
1327+
fn borrow(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: ty::Region,
1328+
_: ty::BorrowKind, _: euv::LoanCause) {}
1329+
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
1330+
1331+
fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
1332+
match cmt.cat {
1333+
mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: vid, .. }) |
1334+
mc::cat_arg(vid) | mc::cat_local(vid) => self.reassigned = self.node == vid,
1335+
_ => {}
1336+
}
1337+
}
1338+
}
1339+
1340+
fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>,
1341+
discr: &ast::Expr, body: &ast::Expr) -> BindingsMap {
12961342
// Create the bindings map, which is a mapping from each binding name
12971343
// to an alloca() that will be the value for that local variable.
12981344
// Note that we use the names because each binding will have many ids
12991345
// from the various alternatives.
13001346
let ccx = bcx.ccx();
13011347
let tcx = bcx.tcx();
1348+
let reassigned = is_discr_reassigned(bcx, discr, body);
13021349
let mut bindings_map = HashMap::new();
13031350
pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| {
13041351
let ident = path1.node;
@@ -1310,7 +1357,7 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
13101357
let trmode;
13111358
match bm {
13121359
ast::BindByValue(_)
1313-
if !ty::type_moves_by_default(tcx, variable_ty) => {
1360+
if !ty::type_moves_by_default(tcx, variable_ty) || reassigned => {
13141361
llmatch = alloca_no_lifetime(bcx,
13151362
llvariable_ty.ptr_to(),
13161363
"__llmatch");
@@ -1371,7 +1418,7 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
13711418
let arm_datas: Vec<ArmData> = arms.iter().map(|arm| ArmData {
13721419
bodycx: fcx.new_id_block("case_body", arm.body.id),
13731420
arm: arm,
1374-
bindings_map: create_bindings_map(bcx, *arm.pats.get(0))
1421+
bindings_map: create_bindings_map(bcx, *arm.pats.get(0), discr_expr, &*arm.body)
13751422
}).collect();
13761423

13771424
let mut static_inliner = StaticInliner { tcx: scope_cx.tcx() };

trunk/src/librustc/middle/trans/common.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use driver::session::Session;
1616
use llvm;
1717
use llvm::{ValueRef, BasicBlockRef, BuilderRef};
1818
use llvm::{True, False, Bool};
19+
use mc = middle::mem_categorization;
1920
use middle::def;
2021
use middle::lang_items::LangItem;
2122
use middle::subst;
@@ -481,6 +482,36 @@ impl<'a> Block<'a> {
481482
}
482483
}
483484

485+
impl<'a> mc::Typer for Block<'a> {
486+
fn tcx<'a>(&'a self) -> &'a ty::ctxt {
487+
self.tcx()
488+
}
489+
490+
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<ty::t> {
491+
Ok(node_id_type(self, id))
492+
}
493+
494+
fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option<ty::t> {
495+
self.tcx().method_map.borrow().find(&method_call).map(|method| method.ty)
496+
}
497+
498+
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment>> {
499+
&self.tcx().adjustments
500+
}
501+
502+
fn is_method_call(&self, id: ast::NodeId) -> bool {
503+
self.tcx().method_map.borrow().contains_key(&typeck::MethodCall::expr(id))
504+
}
505+
506+
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId> {
507+
self.tcx().region_maps.temporary_scope(rvalue_id)
508+
}
509+
510+
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
511+
self.tcx().upvar_borrow_map.borrow().get_copy(&upvar_id)
512+
}
513+
}
514+
484515
pub struct Result<'a> {
485516
pub bcx: &'a Block<'a>,
486517
pub val: ValueRef

trunk/src/librustc/middle/ty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ pub struct UpvarId {
539539
pub closure_expr_id: ast::NodeId,
540540
}
541541

542-
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
542+
#[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)]
543543
pub enum BorrowKind {
544544
/// Data must be immutable and is aliasable.
545545
ImmBorrow,
@@ -634,7 +634,7 @@ pub enum BorrowKind {
634634
* the closure, so sometimes it is necessary for them to be larger
635635
* than the closure lifetime itself.
636636
*/
637-
#[deriving(PartialEq, Clone)]
637+
#[deriving(PartialEq, Clone, Encodable, Decodable)]
638638
pub struct UpvarBorrow {
639639
pub kind: BorrowKind,
640640
pub region: ty::Region,

trunk/src/libserialize/serialize.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,6 @@ impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
571571

572572
// ___________________________________________________________________________
573573
// Helper routines
574-
//
575-
// In some cases, these should eventually be coded as traits.
576574

577575
pub trait EncoderHelpers<E> {
578576
fn emit_from_vec<T>(&mut self,

trunk/src/test/bench/rt-messaging-ping-pong.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::uint;
2222

2323
// This is a simple bench that creates M pairs of tasks. These
2424
// tasks ping-pong back and forth over a pair of streams. This is a
25-
// cannonical message-passing benchmark as it heavily strains message
25+
// canonical message-passing benchmark as it heavily strains message
2626
// passing and almost nothing else.
2727

2828
fn ping_pong_bench(n: uint, m: uint) {

trunk/src/test/bench/shootout-meteor.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<'a, T> Iterator<&'a T> for ListIterator<'a, T> {
101101
// every possible transformations (the 6 rotations with their
102102
// corresponding mirrored piece), with, as minimum coordinates, (0,
103103
// 0). If all is false, only generate half of the possibilities (used
104-
// to break the symetry of the board).
104+
// to break the symmetry of the board).
105105
fn transform(piece: Vec<(int, int)> , all: bool) -> Vec<Vec<(int, int)>> {
106106
let mut res: Vec<Vec<(int, int)>> =
107107
// rotations
@@ -124,9 +124,9 @@ fn transform(piece: Vec<(int, int)> , all: bool) -> Vec<Vec<(int, int)>> {
124124
res
125125
}
126126

127-
// A mask is a piece somewere on the board. It is represented as a
127+
// A mask is a piece somewhere on the board. It is represented as a
128128
// u64: for i in the first 50 bits, m[i] = 1 if the cell at (i/5, i%5)
129-
// is occuped. m[50 + id] = 1 if the identifier of the piece is id.
129+
// is occupied. m[50 + id] = 1 if the identifier of the piece is id.
130130

131131
// Takes a piece with minimum coordinate (0, 0) (as generated by
132132
// transform). Returns the corresponding mask if p translated by (dy,
@@ -159,7 +159,7 @@ fn make_masks() -> Vec<Vec<Vec<u64> > > {
159159
vec!((0i,0i),(0,1),(0,2),(1,2),(1,3)),
160160
vec!((0i,0i),(0,1),(0,2),(0,3),(1,2)));
161161

162-
// To break the central symetry of the problem, every
162+
// To break the central symmetry of the problem, every
163163
// transformation must be taken except for one piece (piece 3
164164
// here).
165165
let transforms: Vec<Vec<Vec<(int, int)>>> =
@@ -263,7 +263,7 @@ impl Data {
263263
// Records a new found solution. Returns false if the search must be
264264
// stopped.
265265
fn handle_sol(raw_sol: &List<u64>, data: &mut Data) {
266-
// because we break the symetry, 2 solutions correspond to a call
266+
// because we break the symmetry, 2 solutions correspond to a call
267267
// to this method: the normal solution, and the same solution in
268268
// reverse order, i.e. the board rotated by half a turn.
269269
data.nb += 2;
@@ -298,7 +298,7 @@ fn search(
298298
for id in range(0u, 10).filter(|id| board & (1 << (id + 50)) == 0) {
299299
// for each mask that fits on the board
300300
for m in masks_at.get(id).iter().filter(|&m| board & *m == 0) {
301-
// This check is too costy.
301+
// This check is too costly.
302302
//if is_board_unfeasible(board | m, masks) {continue;}
303303
search(masks, board | *m, i + 1, Cons(*m, &cur), data);
304304
}

trunk/src/test/bench/shootout-spectralnorm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
3636

3737
fn mult(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
3838
f: fn(&Vec<f64>, uint) -> f64) {
39-
// We lanch in different tasks the work to be done. To finish
40-
// this fuction, we need to wait for the completion of every
39+
// We launch in different tasks the work to be done. To finish
40+
// this function, we need to wait for the completion of every
4141
// tasks. To do that, we give to each tasks a wait_chan that we
4242
// drop at the end of the work. At the end of this function, we
4343
// wait until the channel hang up.

trunk/src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs

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

1111
// Verify that it is not possible to take the address of
12-
// static items with usnafe interior.
12+
// static items with unsafe interior.
1313

1414
use std::kinds::marker;
1515
use std::cell::UnsafeCell;

trunk/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs

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

11-
// Verify that managed pointers scope is treated like ownoed pointers.
12-
// regresion test for #11586
11+
// Verify that managed pointers scope is treated like owned pointers.
12+
// regression test for #11586
1313

1414

1515
use std::gc::{GC, Gc};

trunk/src/test/compile-fail/check-static-values-constraints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static STATIC7: SafeStruct = SafeStruct{field1: Variant1, field2: Variant3(WithD
7272
//~^ ERROR static items are not allowed to have destructors
7373

7474
// Test variadic constructor for structs. The base struct should be examined
75-
// as well as every field persent in the constructor.
75+
// as well as every field present in the constructor.
7676
// This example shouldn't fail because all the fields are safe.
7777
static STATIC8: SafeStruct = SafeStruct{field1: Variant1,
7878
..SafeStruct{field1: Variant1, field2: Variant1}};

0 commit comments

Comments
 (0)