Skip to content

Commit a08f3a7

Browse files
committed
More complete fix to #3162 (borrowck bug related to access to rec fields)
1 parent 83e7c86 commit a08f3a7

File tree

9 files changed

+51
-39
lines changed

9 files changed

+51
-39
lines changed

Diff for: src/libcore/task.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -851,12 +851,10 @@ fn each_ancestor(list: &mut AncestorList,
851851
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
852852
// Decide whether this group is dead. Note that the
853853
// group being *dead* is disjoint from it *failing*.
854-
match *tg_opt {
855-
some(ref tg) => {
856-
nobe_is_dead = taskgroup_is_dead(tg);
857-
},
858-
none => { }
859-
}
854+
nobe_is_dead = match *tg_opt {
855+
some(ref tg) => taskgroup_is_dead(tg),
856+
none => nobe_is_dead
857+
};
860858
// Call iterator block. (If the group is dead, it's
861859
// safe to skip it. This will leave our *rust_task
862860
// hanging around in the group even after it's freed,

Diff for: src/libcore/vec.rs

+19
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export swap;
7575
export reverse;
7676
export reversed;
7777
export iter, iter_between, each, eachi, reach, reachi;
78+
export each_mut, each_const;
7879
export iter2;
7980
export iteri;
8081
export riter;
@@ -1174,6 +1175,24 @@ pure fn each<T>(v: &[T], f: fn(T) -> bool) {
11741175
}
11751176
}
11761177

1178+
/// Like `each()`, but for the case where you have
1179+
/// a vector with mutable contents and you would like
1180+
/// to mutate the contents as you iterate.
1181+
#[inline(always)]
1182+
pure fn each_mut<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
1183+
do vec::as_mut_buf(v) |p, n| {
1184+
let mut n = n;
1185+
let mut p = p;
1186+
while n > 0u {
1187+
unsafe {
1188+
if !f(&mut *p) { break; }
1189+
p = ptr::mut_offset(p, 1u);
1190+
}
1191+
n -= 1u;
1192+
}
1193+
}
1194+
}
1195+
11771196
/**
11781197
* Iterates over a vector's elements and indices
11791198
*

Diff for: src/libstd/sha1.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ fn sha1() -> sha1 {
158158
fn mk_result(st: sha1state) -> ~[u8] {
159159
if !st.computed { pad_msg(st); st.computed = true; }
160160
let mut rs: ~[u8] = ~[];
161-
for vec::each(st.h) |hpart| {
161+
for vec::each_mut(st.h) |ptr_hpart| {
162+
let hpart = *ptr_hpart;
162163
let a = (hpart >> 24u32 & 0xFFu32) as u8;
163164
let b = (hpart >> 16u32 & 0xFFu32) as u8;
164165
let c = (hpart >> 8u32 & 0xFFu32) as u8;

Diff for: src/libsyntax/ext/simplext.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr {
205205

206206

207207
/* helper: descend into a matcher */
208-
fn follow(m: arb_depth<matchable>, idx_path: @mut ~[uint]) ->
208+
pure fn follow(m: arb_depth<matchable>, idx_path: &[uint]) ->
209209
arb_depth<matchable> {
210210
let mut res: arb_depth<matchable> = m;
211-
for vec::each(*idx_path) |idx| {
211+
for vec::each(idx_path) |idx| {
212212
res = match res {
213213
leaf(_) => return res,/* end of the line */
214214
seq(new_ms, _) => new_ms[idx]
@@ -222,7 +222,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option<arb_depth<matchable>>,
222222
match mmaybe {
223223
none => return none,
224224
some(m) => {
225-
return match follow(m, idx_path) {
225+
return match follow(m, *idx_path) {
226226
seq(_, sp) => {
227227
cx.span_fatal(sp,
228228
~"syntax matched under ... but not " +
@@ -274,7 +274,8 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint],
274274
/* we need to walk over all the free vars in lockstep, except for
275275
the leaves, which are just duplicated */
276276
do free_vars(b, repeat_me) |fv| {
277-
let cur_pos = follow(b.get(fv), idx_path);
277+
let fv_depth = b.get(fv);
278+
let cur_pos = follow(fv_depth, *idx_path);
278279
match cur_pos {
279280
leaf(_) => (),
280281
seq(ms, _) => {

Diff for: src/libsyntax/parse/common.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -146,19 +146,12 @@ impl parser: parser_common {
146146

147147
fn eat_keyword(word: ~str) -> bool {
148148
self.require_keyword(word);
149-
150-
let mut bump = false;
151-
let val = match self.token {
152-
token::IDENT(sid, false) => {
153-
if word == *self.id_to_str(sid) {
154-
bump = true;
155-
true
156-
} else { false }
157-
}
149+
let is_kw = match self.token {
150+
token::IDENT(sid, false) => (word == *self.id_to_str(sid)),
158151
_ => false
159152
};
160-
if bump { self.bump() }
161-
val
153+
if is_kw { self.bump() }
154+
is_kw
162155
}
163156

164157
fn expect_keyword(word: ~str) {

Diff for: src/rustc/middle/borrowck/check_loans.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -326,19 +326,8 @@ impl check_loan_ctxt {
326326
// even to data owned by the current stack frame. This is
327327
// because that aliasable data might have been located on
328328
// the current stack frame, we don't know.
329-
match cmt.lp {
330-
some(@lp_local(*)) | some(@lp_arg(*)) => {
331-
// it's ok to mutate a local variable, as it is either
332-
// lent our or not. The problem arises when you have
333-
// some subcomponent that might have been lent out
334-
// through an alias on the condition that you ensure
335-
// purity.
336-
}
337-
none | some(@lp_comp(*)) | some(@lp_deref(*)) => {
338-
self.report_purity_error(
339-
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
340-
}
341-
}
329+
self.report_purity_error(
330+
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
342331
}
343332
some(pc_pure_fn) => {
344333
if cmt.lp.is_none() {

Diff for: src/rustc/middle/resolve3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,7 @@ struct Resolver {
20652065
str_of(name)));
20662066
return Failed;
20672067
}
2068-
ModuleDef(module_) => {
2068+
ModuleDef(copy module_) => {
20692069
search_module = module_;
20702070
}
20712071
}

Diff for: src/rustc/middle/trans/type_use.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
116116
}
117117

118118
fn type_needs(cx: ctx, use: uint, ty: ty::t) {
119-
let mut done = true;
120119
// Optimization -- don't descend type if all params already have this use
121-
for vec::each(cx.uses) |u| { if u & use != use { done = false } }
122-
if !done { type_needs_inner(cx, use, ty, @nil); }
120+
for vec::each_mut(cx.uses) |u| {
121+
if *u & use != use {
122+
type_needs_inner(cx, use, ty, @nil);
123+
return;
124+
}
125+
}
123126
}
124127

125128
fn type_needs_inner(cx: ctx, use: uint, ty: ty::t,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let mut _a = 3;
3+
let _b = &mut _a;
4+
{
5+
let _c = &*_b; //~ ERROR illegal borrow unless pure
6+
_a = 4; //~ NOTE impure due to assigning to mutable local variable
7+
}
8+
}

0 commit comments

Comments
 (0)