Skip to content

Commit 41023ee

Browse files
committed
---
yaml --- r: 13015 b: refs/heads/master c: 30b4764 h: refs/heads/master i: 13013: 3210963 13011: ccd14ea 13007: fdf8e9d v: v3
1 parent ec398a3 commit 41023ee

File tree

90 files changed

+2105
-163
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2105
-163
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: a3be0b105436118e187ea52deb89788afaf1edb5
2+
refs/heads/master: 30b47649ea37d211ee2dec4c541e6ba1e64c31a8
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/librustsyntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ enum expr_ {
351351
}
352352

353353
#[auto_serialize]
354-
type capture_item = {
354+
type capture_item = @{
355355
id: int,
356356
is_move: bool,
357357
name: ident, // Currently, can only capture a local var.

trunk/src/librustsyntax/parse/parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ class parser {
434434
fn parse_capture_item(p:parser, is_move: bool) -> capture_item {
435435
let sp = mk_sp(p.span.lo, p.span.hi);
436436
let ident = parse_ident(p);
437-
{id: p.get_id(), is_move: is_move, name: ident, span: sp}
437+
@{id: p.get_id(), is_move: is_move, name: ident, span: sp}
438438
}
439439

440440
if eat_keyword(self, "move") {
@@ -1710,7 +1710,7 @@ class parser {
17101710
let id = p.get_id();
17111711
let sp = mk_sp(p.span.lo, p.span.hi);
17121712
let ident = parse_ident(p);
1713-
res += [{id:id, is_move: is_move, name:ident, span:sp}];
1713+
res += [@{id:id, is_move: is_move, name:ident, span:sp}];
17141714
if !eat(p, token::COMMA) {
17151715
ret res;
17161716
}

trunk/src/rustc/driver/driver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
192192
bind middle::check_loop::check_crate(ty_cx, crate));
193193
time(time_passes, "alt checking",
194194
bind middle::check_alt::check_crate(ty_cx, crate));
195+
let _last_use_map =
196+
time(time_passes, "liveness checking",
197+
bind middle::liveness::check_crate(ty_cx, method_map, crate));
195198
time(time_passes, "typestate checking",
196199
bind middle::tstate::ck::check_crate(ty_cx, crate));
197200
let (root_map, mutbl_map) = time(

trunk/src/rustc/middle/borrowck.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,15 @@ enum assignment_type {
541541
}
542542

543543
impl methods for assignment_type {
544+
fn checked_by_liveness() -> bool {
545+
// the liveness pass guarantees that immutable local variables
546+
// are only assigned once; but it doesn't consider &mut
547+
alt self {
548+
at_straight_up {true}
549+
at_swap {true}
550+
at_mutbl_ref {false}
551+
}
552+
}
544553
fn ing_form(desc: str) -> str {
545554
alt self {
546555
at_straight_up { "assigning to " + desc }
@@ -717,6 +726,13 @@ impl methods for check_loan_ctxt {
717726
}
718727
}
719728

729+
fn is_local_variable(cmt: cmt) -> bool {
730+
alt cmt.cat {
731+
cat_local(_) {true}
732+
_ {false}
733+
}
734+
}
735+
720736
fn is_self_field(cmt: cmt) -> bool {
721737
alt cmt.cat {
722738
cat_comp(cmt_base, comp_field(_)) {
@@ -735,9 +751,13 @@ impl methods for check_loan_ctxt {
735751
#debug["check_assignment(cmt=%s)",
736752
self.bccx.cmt_to_repr(cmt)];
737753

738-
// check that the lvalue `ex` is assignable, but be careful
739-
// because assigning to self.foo in a ctor is always allowed.
740-
if !self.in_ctor || !self.is_self_field(cmt) {
754+
if self.in_ctor && self.is_self_field(cmt)
755+
&& at.checked_by_liveness() {
756+
// assigning to self.foo in a ctor is always allowed.
757+
} else if self.is_local_variable(cmt) && at.checked_by_liveness() {
758+
// liveness guarantees that immutable local variables
759+
// are only assigned once
760+
} else {
741761
alt cmt.mutbl {
742762
m_mutbl { /*ok*/ }
743763
m_const | m_imm {

trunk/src/rustc/middle/capture.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import syntax::{ast, ast_util};
22
import driver::session::session;
3+
import syntax::codemap::span;
34
import std::map;
45
import std::map::hashmap;
56

@@ -14,15 +15,17 @@ export cap_drop;
1415
export cap_ref;
1516

1617
enum capture_mode {
17-
cap_copy, //< Copy the value into the closure.
18-
cap_move, //< Move the value into the closure.
19-
cap_drop, //< Drop value after creating closure.
20-
cap_ref, //< Reference directly from parent stack frame (block fn).
18+
cap_copy, // Copy the value into the closure.
19+
cap_move, // Move the value into the closure.
20+
cap_drop, // Drop value after creating closure.
21+
cap_ref, // Reference directly from parent stack frame (block fn).
2122
}
2223

2324
type capture_var = {
24-
def: ast::def, //< The variable being accessed free.
25-
mode: capture_mode //< How is the variable being accessed.
25+
def: ast::def, // Variable being accessed free
26+
span: span, // Location of access or cap item
27+
cap_item: option<ast::capture_item>, // Capture item, if any
28+
mode: capture_mode // How variable is being accessed
2629
};
2730

2831
type capture_map = map::hashmap<ast::def_id, capture_var>;
@@ -70,15 +73,24 @@ fn compute_capture_vars(tcx: ty::ctxt,
7073
// if we are moving the value in, but it's not actually used,
7174
// must drop it.
7275
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
73-
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_move });
76+
cap_map.insert(cap_def_id, {def:cap_def,
77+
span: cap_item.span,
78+
cap_item: some(cap_item),
79+
mode:cap_move});
7480
} else {
75-
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_drop });
81+
cap_map.insert(cap_def_id, {def:cap_def,
82+
span: cap_item.span,
83+
cap_item: some(cap_item),
84+
mode:cap_drop});
7685
}
7786
} else {
7887
// if we are copying the value in, but it's not actually used,
7988
// just ignore it.
8089
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
81-
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_copy });
90+
cap_map.insert(cap_def_id, {def:cap_def,
91+
span: cap_item.span,
92+
cap_item: some(cap_item),
93+
mode:cap_copy});
8294
}
8395
}
8496
}
@@ -96,7 +108,10 @@ fn compute_capture_vars(tcx: ty::ctxt,
96108
alt cap_map.find(fvar_def_id) {
97109
option::some(_) { /* was explicitly named, do nothing */ }
98110
option::none {
99-
cap_map.insert(fvar_def_id, {def:fvar.def, mode:implicit_mode});
111+
cap_map.insert(fvar_def_id, {def:fvar.def,
112+
span: fvar.span,
113+
cap_item: none,
114+
mode:implicit_mode});
100115
}
101116
}
102117
}

0 commit comments

Comments
 (0)