Skip to content

Commit 88ec89d

Browse files
committed
fix numerous dynamic borrow failures
1 parent 5f88634 commit 88ec89d

File tree

12 files changed

+77
-65
lines changed

12 files changed

+77
-65
lines changed

src/libcore/unstable/lang.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
133133

134134
/// Because this code is so perf. sensitive, use a static constant so that
135135
/// debug printouts are compiled out most of the time.
136-
static ENABLE_DEBUG_PTR: bool = false;
136+
static ENABLE_DEBUG_PTR: bool = true;
137137

138138
#[inline]
139139
pub fn debug_ptr<T>(tag: &'static str, p: *const T) {

src/libcore/util.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,20 @@ pub fn ignore<T>(_x: T) { }
2626

2727
/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
2828
/// original value of `*ptr`.
29+
///
30+
/// NB: This function accepts `@mut T` and not `&mut T` to avoid
31+
/// an obvious borrowck hazard. Typically passing in `&mut T` will
32+
/// cause borrow check errors because it freezes whatever location
33+
/// that `&mut T` is stored in (either statically or dynamically).
2934
#[inline(always)]
30-
pub fn with<T:Copy,R>(
31-
ptr: &mut T,
32-
new_value: T,
35+
pub fn with<T,R>(
36+
ptr: @mut T,
37+
mut value: T,
3338
op: &fn() -> R) -> R
3439
{
35-
// NDM: if swap operator were defined somewhat differently,
36-
// we wouldn't need to copy...
37-
38-
let old_value = *ptr;
39-
*ptr = new_value;
40+
value <-> *ptr;
4041
let result = op();
41-
*ptr = old_value;
42+
*ptr = value;
4243
return result;
4344
}
4445

src/librustc/middle/liveness.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ use util::ppaux::ty_to_str;
112112

113113
use core::cast::transmute;
114114
use core::hashmap::HashMap;
115-
use core::util::with;
116115
use syntax::ast::*;
117116
use syntax::codemap::span;
118117
use syntax::parse::token::special_idents;
@@ -343,9 +342,10 @@ pub impl IrMaps {
343342
}
344343

345344
fn visit_item(item: @item, self: @mut IrMaps, v: vt<@mut IrMaps>) {
346-
do with(&mut self.cur_item, item.id) {
347-
visit::visit_item(item, self, v)
348-
}
345+
let old_cur_item = self.cur_item;
346+
self.cur_item = item.id;
347+
visit::visit_item(item, self, v);
348+
self.cur_item = old_cur_item;
349349
}
350350

351351
fn visit_fn(fk: &visit::fn_kind,
@@ -762,11 +762,13 @@ pub impl Liveness {
762762
None => {
763763
// Vanilla 'break' or 'loop', so use the enclosing
764764
// loop scope
765-
let loop_scope = &mut *self.loop_scope;
766-
if loop_scope.len() == 0 {
765+
let len = { // FIXME(#5074) stage0
766+
let loop_scope = &mut *self.loop_scope;
767+
loop_scope.len()
768+
};
769+
if len == 0 {
767770
self.tcx.sess.span_bug(sp, ~"break outside loop");
768-
}
769-
else {
771+
} else {
770772
// FIXME(#5275): this shouldn't have to be a method...
771773
self.last_loop_scope()
772774
}

src/librustc/middle/region.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,8 @@ pub fn determine_rp_in_crate(sess: Session,
949949
let cx = &mut *cx;
950950
while cx.worklist.len() != 0 {
951951
let c_id = cx.worklist.pop();
952-
let c_variance = *cx.region_paramd_items.get(&c_id);
952+
let c_variance = { *cx.region_paramd_items.get(&c_id) };
953+
// NOTE cleanup scopes cause an exaggerated lock here
953954
debug!("popped %d from worklist", c_id);
954955
match cx.dep_map.find(&c_id) {
955956
None => {}

src/librustc/middle/resolve.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,9 @@ pub fn Resolver(session: Session,
779779
unresolved_imports: 0,
780780
781781
current_module: current_module,
782-
value_ribs: ~[],
783-
type_ribs: ~[],
784-
label_ribs: ~[],
782+
value_ribs: @mut ~[],
783+
type_ribs: @mut ~[],
784+
label_ribs: @mut ~[],
785785
786786
xray_context: NoXray,
787787
current_trait_refs: None,
@@ -830,13 +830,13 @@ pub struct Resolver {
830830
831831
// The current set of local scopes, for values.
832832
// FIXME #4948: Reuse ribs to avoid allocation.
833-
value_ribs: ~[@Rib],
833+
value_ribs: @mut ~[@Rib],
834834
835835
// The current set of local scopes, for types.
836-
type_ribs: ~[@Rib],
836+
type_ribs: @mut ~[@Rib],
837837
838838
// The current set of local scopes, for labels.
839-
label_ribs: ~[@Rib],
839+
label_ribs: @mut ~[@Rib],
840840
841841
// Whether the current context is an X-ray context. An X-ray context is
842842
// allowed to access private names of any module.
@@ -4313,19 +4313,18 @@ pub impl Resolver {
43134313
}
43144314

43154315
pat_struct(path, _, _) => {
4316-
let structs: &mut HashSet<def_id> = &mut self.structs;
43174316
match self.resolve_path(path, TypeNS, false, visitor) {
43184317
Some(def_ty(class_id))
4319-
if structs.contains(&class_id) => {
4318+
if self.structs.contains(&class_id) => {
43204319
let class_def = def_struct(class_id);
43214320
self.record_def(pattern.id, class_def);
43224321
}
4323-
Some(definition @ def_struct(class_id))
4324-
if structs.contains(&class_id) => {
4322+
Some(definition @ def_struct(class_id)) => {
4323+
assert!(self.structs.contains(&class_id));
43254324
self.record_def(pattern.id, definition);
43264325
}
43274326
Some(definition @ def_variant(_, variant_id))
4328-
if structs.contains(&variant_id) => {
4327+
if self.structs.contains(&variant_id) => {
43294328
self.record_def(pattern.id, definition);
43304329
}
43314330
result => {
@@ -4627,12 +4626,12 @@ pub impl Resolver {
46274626
let search_result;
46284627
match namespace {
46294628
ValueNS => {
4630-
search_result = self.search_ribs(&mut self.value_ribs, ident,
4629+
search_result = self.search_ribs(self.value_ribs, ident,
46314630
span,
46324631
DontAllowCapturingSelf);
46334632
}
46344633
TypeNS => {
4635-
search_result = self.search_ribs(&mut self.type_ribs, ident,
4634+
search_result = self.search_ribs(self.type_ribs, ident,
46364635
span, AllowCapturingSelf);
46374636
}
46384637
}
@@ -4822,15 +4821,14 @@ pub impl Resolver {
48224821

48234822
expr_struct(path, _, _) => {
48244823
// Resolve the path to the structure it goes to.
4825-
let structs: &mut HashSet<def_id> = &mut self.structs;
48264824
match self.resolve_path(path, TypeNS, false, visitor) {
48274825
Some(def_ty(class_id)) | Some(def_struct(class_id))
4828-
if structs.contains(&class_id) => {
4826+
if self.structs.contains(&class_id) => {
48294827
let class_def = def_struct(class_id);
48304828
self.record_def(expr.id, class_def);
48314829
}
48324830
Some(definition @ def_variant(_, class_id))
4833-
if structs.contains(&class_id) => {
4831+
if self.structs.contains(&class_id) => {
48344832
self.record_def(expr.id, definition);
48354833
}
48364834
_ => {
@@ -4856,7 +4854,7 @@ pub impl Resolver {
48564854
}
48574855

48584856
expr_break(Some(label)) | expr_again(Some(label)) => {
4859-
match self.search_ribs(&mut self.label_ribs, label, expr.span,
4857+
match self.search_ribs(self.label_ribs, label, expr.span,
48604858
DontAllowCapturingSelf) {
48614859
None =>
48624860
self.session.span_err(expr.span,

src/librustc/middle/typeck/check/vtable.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,14 @@ fn lookup_vtable(vcx: &VtableContext,
244244
// Nothing found. Continue.
245245
}
246246
Some(implementations) => {
247-
let implementations: &mut ~[@Impl] = *implementations;
247+
let len = { // FIXME(#5074): stage0 requires it
248+
let implementations: &mut ~[@Impl] = *implementations;
249+
implementations.len()
250+
};
248251
249252
// implementations is the list of all impls in scope for
250253
// trait_ref. (Usually, there's just one.)
251-
for uint::range(0, implementations.len()) |i| {
254+
for uint::range(0, len) |i| {
252255
let im = implementations[i];
253256
254257
// im is one specific impl of trait_ref.

src/librustc/middle/typeck/coherence.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ pub impl CoherenceChecker {
240240
241241
fn check_implementation(&self,
242242
item: @item, associated_traits: ~[@trait_ref]) {
243-
let self_type = self.crate_context.tcx.tcache.get(
244-
&local_def(item.id));
243+
let tcx = self.crate_context.tcx;
244+
let self_type = ty::lookup_item_type(tcx, local_def(item.id));
245245
246246
// If there are no traits, then this implementation must have a
247247
// base type.
@@ -452,10 +452,8 @@ pub impl CoherenceChecker {
452452
}
453453

454454
fn check_implementation_coherence(&self) {
455-
let coherence_info = &mut self.crate_context.coherence_info;
456-
let extension_methods = &coherence_info.extension_methods;
457-
458-
for extension_methods.each_key |&trait_id| {
455+
let coherence_info = self.crate_context.coherence_info;
456+
for coherence_info.extension_methods.each_key |&trait_id| {
459457
self.check_implementation_coherence_of(trait_id);
460458
}
461459
}
@@ -514,13 +512,16 @@ pub impl CoherenceChecker {
514512
}
515513

516514
fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) {
517-
let coherence_info = &mut self.crate_context.coherence_info;
518-
let extension_methods = &coherence_info.extension_methods;
515+
let coherence_info = self.crate_context.coherence_info;
516+
let extension_methods = &*coherence_info.extension_methods;
519517

520518
match extension_methods.find(&trait_def_id) {
521519
Some(impls) => {
522-
let impls: &mut ~[@Impl] = *impls;
523-
for uint::range(0, impls.len()) |i| {
520+
let len = { // FIXME(#5074) stage0 requires this
521+
let impls: &mut ~[@Impl] = *impls;
522+
impls.len()
523+
};
524+
for uint::range(0, len) |i| {
524525
f(impls[i]);
525526
}
526527
}
@@ -1014,7 +1015,7 @@ pub impl CoherenceChecker {
10141015
//
10151016

10161017
fn populate_destructor_table(&self) {
1017-
let coherence_info = &mut self.crate_context.coherence_info;
1018+
let coherence_info = self.crate_context.coherence_info;
10181019
let tcx = self.crate_context.tcx;
10191020
let drop_trait = tcx.lang_items.drop_trait();
10201021
let impls_opt = coherence_info.extension_methods.find(&drop_trait);

src/librustc/middle/typeck/infer/glb.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use middle::typeck::infer::lub::Lub;
1616
use middle::typeck::infer::sub::Sub;
1717
use middle::typeck::infer::to_str::InferStr;
1818
use middle::typeck::infer::{cres, InferCtxt};
19+
use middle::typeck::infer::fold_regions_in_sig;
1920
use middle::typeck::isr_alist;
2021
use syntax::ast;
2122
use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl};
@@ -188,7 +189,8 @@ impl Combine for Glb {
188189
let new_vars =
189190
self.infcx.region_vars.vars_created_since_snapshot(snapshot);
190191
let sig1 =
191-
self.infcx.fold_regions_in_sig(
192+
fold_regions_in_sig(
193+
self.infcx.tcx,
192194
&sig0,
193195
|r, _in_fn| generalize_region(self, snapshot,
194196
new_vars, a_isr, a_vars, b_vars,

src/librustc/middle/typeck/infer/lub.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use middle::typeck::infer::lattice::*;
1616
use middle::typeck::infer::sub::Sub;
1717
use middle::typeck::infer::to_str::InferStr;
1818
use middle::typeck::infer::{cres, InferCtxt};
19+
use middle::typeck::infer::fold_regions_in_sig;
1920
use middle::typeck::isr_alist;
2021
use util::common::indent;
2122
use util::ppaux::mt_to_str;
@@ -141,7 +142,8 @@ impl Combine for Lub {
141142
let new_vars =
142143
self.infcx.region_vars.vars_created_since_snapshot(snapshot);
143144
let sig1 =
144-
self.infcx.fold_regions_in_sig(
145+
fold_regions_in_sig(
146+
self.infcx.tcx,
145147
&sig0,
146148
|r, _in_fn| generalize_region(self, snapshot, new_vars,
147149
a_isr, r));

src/librustc/middle/typeck/infer/mod.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ pub impl InferCtxt {
574574
}
575575

576576
/// Execute `f` and commit the bindings if successful
577-
fn commit<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
577+
fn commit<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
578578
assert!(!self.in_snapshot());
579579

580580
debug!("commit()");
@@ -589,7 +589,7 @@ pub impl InferCtxt {
589589
}
590590

591591
/// Execute `f`, unroll bindings on failure
592-
fn try<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
592+
fn try<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
593593
debug!("try()");
594594
do indent {
595595
let snapshot = self.start_snapshot();
@@ -603,7 +603,7 @@ pub impl InferCtxt {
603603
}
604604

605605
/// Execute `f` then unroll any bindings it creates
606-
fn probe<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
606+
fn probe<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
607607
debug!("probe()");
608608
do indent {
609609
let snapshot = self.start_snapshot();
@@ -783,15 +783,14 @@ pub impl InferCtxt {
783783
});
784784
(fn_sig, isr)
785785
}
786+
}
786787

787-
fn fold_regions_in_sig(
788-
&mut self,
789-
fn_sig: &ty::FnSig,
790-
fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig
791-
{
792-
do ty::fold_sig(fn_sig) |t| {
793-
ty::fold_regions(self.tcx, t, fldr)
794-
}
788+
pub fn fold_regions_in_sig(
789+
tcx: ty::ctxt,
790+
fn_sig: &ty::FnSig,
791+
fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig
792+
{
793+
do ty::fold_sig(fn_sig) |t| {
794+
ty::fold_regions(tcx, t, fldr)
795795
}
796-
797-
}
796+
}

src/librustc/rustc.rc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ pub mod middle {
7676
}
7777
pub mod ty;
7878
pub mod subst;
79+
#[cfg(stage0)] #[path = "resolve_stage0.rs"]
80+
pub mod resolve;
81+
#[cfg(not(stage0))]
7982
pub mod resolve;
8083
#[path = "typeck/mod.rs"]
8184
pub mod typeck;

src/libsyntax/codemap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ pub impl CodeMap {
355355
}
356356

357357
pub fn span_to_str(&self, sp: span) -> ~str {
358-
let files = &mut *self.files;
358+
let files = &*self.files;
359359
if files.len() == 0 && sp == dummy_sp() {
360360
return ~"no-location";
361361
}

0 commit comments

Comments
 (0)