More complete fix to #3162 (borrowck bug related to access to rec fields)
This commit is contained in:
parent
83e7c869bd
commit
a08f3a7d4d
9 changed files with 51 additions and 39 deletions
|
|
@ -851,12 +851,10 @@ fn each_ancestor(list: &mut AncestorList,
|
|||
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
|
||||
// Decide whether this group is dead. Note that the
|
||||
// group being *dead* is disjoint from it *failing*.
|
||||
match *tg_opt {
|
||||
some(ref tg) => {
|
||||
nobe_is_dead = taskgroup_is_dead(tg);
|
||||
},
|
||||
none => { }
|
||||
}
|
||||
nobe_is_dead = match *tg_opt {
|
||||
some(ref tg) => taskgroup_is_dead(tg),
|
||||
none => nobe_is_dead
|
||||
};
|
||||
// Call iterator block. (If the group is dead, it's
|
||||
// safe to skip it. This will leave our *rust_task
|
||||
// hanging around in the group even after it's freed,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export swap;
|
|||
export reverse;
|
||||
export reversed;
|
||||
export iter, iter_between, each, eachi, reach, reachi;
|
||||
export each_mut, each_const;
|
||||
export iter2;
|
||||
export iteri;
|
||||
export riter;
|
||||
|
|
@ -1174,6 +1175,24 @@ pure fn each<T>(v: &[T], f: fn(T) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Like `each()`, but for the case where you have
|
||||
/// a vector with mutable contents and you would like
|
||||
/// to mutate the contents as you iterate.
|
||||
#[inline(always)]
|
||||
pure fn each_mut<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
|
||||
do vec::as_mut_buf(v) |p, n| {
|
||||
let mut n = n;
|
||||
let mut p = p;
|
||||
while n > 0u {
|
||||
unsafe {
|
||||
if !f(&mut *p) { break; }
|
||||
p = ptr::mut_offset(p, 1u);
|
||||
}
|
||||
n -= 1u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over a vector's elements and indices
|
||||
*
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ fn sha1() -> sha1 {
|
|||
fn mk_result(st: sha1state) -> ~[u8] {
|
||||
if !st.computed { pad_msg(st); st.computed = true; }
|
||||
let mut rs: ~[u8] = ~[];
|
||||
for vec::each(st.h) |hpart| {
|
||||
for vec::each_mut(st.h) |ptr_hpart| {
|
||||
let hpart = *ptr_hpart;
|
||||
let a = (hpart >> 24u32 & 0xFFu32) as u8;
|
||||
let b = (hpart >> 16u32 & 0xFFu32) as u8;
|
||||
let c = (hpart >> 8u32 & 0xFFu32) as u8;
|
||||
|
|
|
|||
|
|
@ -205,10 +205,10 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr {
|
|||
|
||||
|
||||
/* helper: descend into a matcher */
|
||||
fn follow(m: arb_depth<matchable>, idx_path: @mut ~[uint]) ->
|
||||
pure fn follow(m: arb_depth<matchable>, idx_path: &[uint]) ->
|
||||
arb_depth<matchable> {
|
||||
let mut res: arb_depth<matchable> = m;
|
||||
for vec::each(*idx_path) |idx| {
|
||||
for vec::each(idx_path) |idx| {
|
||||
res = match res {
|
||||
leaf(_) => return res,/* end of the line */
|
||||
seq(new_ms, _) => new_ms[idx]
|
||||
|
|
@ -222,7 +222,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option<arb_depth<matchable>>,
|
|||
match mmaybe {
|
||||
none => return none,
|
||||
some(m) => {
|
||||
return match follow(m, idx_path) {
|
||||
return match follow(m, *idx_path) {
|
||||
seq(_, sp) => {
|
||||
cx.span_fatal(sp,
|
||||
~"syntax matched under ... but not " +
|
||||
|
|
@ -274,7 +274,8 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint],
|
|||
/* we need to walk over all the free vars in lockstep, except for
|
||||
the leaves, which are just duplicated */
|
||||
do free_vars(b, repeat_me) |fv| {
|
||||
let cur_pos = follow(b.get(fv), idx_path);
|
||||
let fv_depth = b.get(fv);
|
||||
let cur_pos = follow(fv_depth, *idx_path);
|
||||
match cur_pos {
|
||||
leaf(_) => (),
|
||||
seq(ms, _) => {
|
||||
|
|
|
|||
|
|
@ -146,19 +146,12 @@ impl parser: parser_common {
|
|||
|
||||
fn eat_keyword(word: ~str) -> bool {
|
||||
self.require_keyword(word);
|
||||
|
||||
let mut bump = false;
|
||||
let val = match self.token {
|
||||
token::IDENT(sid, false) => {
|
||||
if word == *self.id_to_str(sid) {
|
||||
bump = true;
|
||||
true
|
||||
} else { false }
|
||||
}
|
||||
let is_kw = match self.token {
|
||||
token::IDENT(sid, false) => (word == *self.id_to_str(sid)),
|
||||
_ => false
|
||||
};
|
||||
if bump { self.bump() }
|
||||
val
|
||||
if is_kw { self.bump() }
|
||||
is_kw
|
||||
}
|
||||
|
||||
fn expect_keyword(word: ~str) {
|
||||
|
|
|
|||
|
|
@ -326,19 +326,8 @@ impl check_loan_ctxt {
|
|||
// even to data owned by the current stack frame. This is
|
||||
// because that aliasable data might have been located on
|
||||
// the current stack frame, we don't know.
|
||||
match cmt.lp {
|
||||
some(@lp_local(*)) | some(@lp_arg(*)) => {
|
||||
// it's ok to mutate a local variable, as it is either
|
||||
// lent our or not. The problem arises when you have
|
||||
// some subcomponent that might have been lent out
|
||||
// through an alias on the condition that you ensure
|
||||
// purity.
|
||||
}
|
||||
none | some(@lp_comp(*)) | some(@lp_deref(*)) => {
|
||||
self.report_purity_error(
|
||||
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
|
||||
}
|
||||
}
|
||||
self.report_purity_error(
|
||||
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
|
||||
}
|
||||
some(pc_pure_fn) => {
|
||||
if cmt.lp.is_none() {
|
||||
|
|
|
|||
|
|
@ -2065,7 +2065,7 @@ struct Resolver {
|
|||
str_of(name)));
|
||||
return Failed;
|
||||
}
|
||||
ModuleDef(module_) => {
|
||||
ModuleDef(copy module_) => {
|
||||
search_module = module_;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,10 +116,13 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
|||
}
|
||||
|
||||
fn type_needs(cx: ctx, use: uint, ty: ty::t) {
|
||||
let mut done = true;
|
||||
// Optimization -- don't descend type if all params already have this use
|
||||
for vec::each(cx.uses) |u| { if u & use != use { done = false } }
|
||||
if !done { type_needs_inner(cx, use, ty, @nil); }
|
||||
for vec::each_mut(cx.uses) |u| {
|
||||
if *u & use != use {
|
||||
type_needs_inner(cx, use, ty, @nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_needs_inner(cx: ctx, use: uint, ty: ty::t,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
fn main() {
|
||||
let mut _a = 3;
|
||||
let _b = &mut _a;
|
||||
{
|
||||
let _c = &*_b; //~ ERROR illegal borrow unless pure
|
||||
_a = 4; //~ NOTE impure due to assigning to mutable local variable
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue