Skip to content

Commit 6740712

Browse files
committed
---
yaml --- r: 127675 b: refs/heads/snap-stage3 c: 5e720f0 h: refs/heads/master i: 127673: 4a36de2 127671: d4ab49e v: v3
1 parent a8ecf21 commit 6740712

37 files changed

+281
-53
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 49a970f2449a78f28b6c301e542d38593094ca77
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 07aadc2e8b1923b28595393922a816e46d3903f4
4+
refs/heads/snap-stage3: 5e720f0e5453e7b113f313df7827f3ad0a6dbe46
55
refs/heads/try: d9c23fcbaea89871667272a67ecb8d3a512162f3
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/doc/guide.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Sound good? Let's go!
2727
# Installing Rust
2828

2929
The first step to using Rust is to install it! There are a number of ways to
30-
install Rust, but the easiest is to use the the `rustup` script. If you're on
30+
install Rust, but the easiest is to use the `rustup` script. If you're on
3131
Linux or a Mac, all you need to do is this (note that you don't need to type
3232
in the `$`s, they just indicate the start of each command):
3333

@@ -120,7 +120,7 @@ to make a projects directory in my home directory, and keep all my projects
120120
there. Rust does not care where your code lives.
121121

122122
This actually leads to one other concern we should address: this tutorial will
123-
assume that you have basic familiarity with the command-line. Rust does not
123+
assume that you have basic familiarity with the command line. Rust does not
124124
require that you know a whole ton about the command line, but until the
125125
language is in a more finished state, IDE support is spotty. Rust makes no
126126
specific demands on your editing tooling, or where your code lives.
@@ -452,7 +452,7 @@ what you need, so it's not verboten.
452452

453453
Let's get back to bindings. Rust variable bindings have one more aspect that
454454
differs from other languages: bindings are required to be initialized with a
455-
value before you're allowed to use it. If we try...
455+
value before you're allowed to use them. If we try...
456456

457457
```{ignore}
458458
let x;
@@ -2090,7 +2090,7 @@ In this case, I happen to prefer the latter, and in the `random()` case, I prefe
20902090
the former. I think the nested `<>`s make the first option especially ugly and
20912091
a bit harder to read.
20922092

2093-
Anyway, with us now convering our input to a number, our code looks like this:
2093+
Anyway, with us now converting our input to a number, our code looks like this:
20942094

20952095
```{rust,ignore}
20962096
use std::io;
@@ -2281,7 +2281,7 @@ change that by adding loops!
22812281

22822282
## Looping
22832283

2284-
As we already discussed, the `loop` key word gives us an infinite loop. So
2284+
As we already discussed, the `loop` keyword gives us an infinite loop. So
22852285
let's add that in:
22862286

22872287
```{rust,no_run}
@@ -4099,7 +4099,7 @@ fn inverse(x: f64) -> Result<f64, String> {
40994099
```
41004100

41014101
We don't want to take the inverse of zero, so we check to make sure that we
4102-
weren't passed one. If we weren't, then we return an `Err`, with a message. If
4102+
weren't passed zero. If we were, then we return an `Err`, with a message. If
41034103
it's okay, we return an `Ok`, with the answer.
41044104

41054105
Why does this matter? Well, remember how `match` does exhaustive matches?

branches/snap-stage3/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.

branches/snap-stage3/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;

branches/snap-stage3/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 };

branches/snap-stage3/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

branches/snap-stage3/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() };

branches/snap-stage3/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

branches/snap-stage3/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,

branches/snap-stage3/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,

branches/snap-stage3/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) {

0 commit comments

Comments
 (0)