fix numerous dynamic borrow failures
This commit is contained in:
parent
5f886342be
commit
88ec89d3fe
@ -133,7 +133,7 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
|
||||
|
||||
/// Because this code is so perf. sensitive, use a static constant so that
|
||||
/// debug printouts are compiled out most of the time.
|
||||
static ENABLE_DEBUG_PTR: bool = false;
|
||||
static ENABLE_DEBUG_PTR: bool = true;
|
||||
|
||||
#[inline]
|
||||
pub fn debug_ptr<T>(tag: &'static str, p: *const T) {
|
||||
|
@ -26,19 +26,20 @@ pub fn ignore<T>(_x: T) { }
|
||||
|
||||
/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
|
||||
/// original value of `*ptr`.
|
||||
///
|
||||
/// NB: This function accepts `@mut T` and not `&mut T` to avoid
|
||||
/// an obvious borrowck hazard. Typically passing in `&mut T` will
|
||||
/// cause borrow check errors because it freezes whatever location
|
||||
/// that `&mut T` is stored in (either statically or dynamically).
|
||||
#[inline(always)]
|
||||
pub fn with<T:Copy,R>(
|
||||
ptr: &mut T,
|
||||
new_value: T,
|
||||
pub fn with<T,R>(
|
||||
ptr: @mut T,
|
||||
mut value: T,
|
||||
op: &fn() -> R) -> R
|
||||
{
|
||||
// NDM: if swap operator were defined somewhat differently,
|
||||
// we wouldn't need to copy...
|
||||
|
||||
let old_value = *ptr;
|
||||
*ptr = new_value;
|
||||
value <-> *ptr;
|
||||
let result = op();
|
||||
*ptr = old_value;
|
||||
*ptr = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,6 @@ use util::ppaux::ty_to_str;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::hashmap::HashMap;
|
||||
use core::util::with;
|
||||
use syntax::ast::*;
|
||||
use syntax::codemap::span;
|
||||
use syntax::parse::token::special_idents;
|
||||
@ -343,9 +342,10 @@ pub impl IrMaps {
|
||||
}
|
||||
|
||||
fn visit_item(item: @item, self: @mut IrMaps, v: vt<@mut IrMaps>) {
|
||||
do with(&mut self.cur_item, item.id) {
|
||||
visit::visit_item(item, self, v)
|
||||
}
|
||||
let old_cur_item = self.cur_item;
|
||||
self.cur_item = item.id;
|
||||
visit::visit_item(item, self, v);
|
||||
self.cur_item = old_cur_item;
|
||||
}
|
||||
|
||||
fn visit_fn(fk: &visit::fn_kind,
|
||||
@ -762,11 +762,13 @@ pub impl Liveness {
|
||||
None => {
|
||||
// Vanilla 'break' or 'loop', so use the enclosing
|
||||
// loop scope
|
||||
let loop_scope = &mut *self.loop_scope;
|
||||
if loop_scope.len() == 0 {
|
||||
let len = { // FIXME(#5074) stage0
|
||||
let loop_scope = &mut *self.loop_scope;
|
||||
loop_scope.len()
|
||||
};
|
||||
if len == 0 {
|
||||
self.tcx.sess.span_bug(sp, ~"break outside loop");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// FIXME(#5275): this shouldn't have to be a method...
|
||||
self.last_loop_scope()
|
||||
}
|
||||
|
@ -949,7 +949,8 @@ pub fn determine_rp_in_crate(sess: Session,
|
||||
let cx = &mut *cx;
|
||||
while cx.worklist.len() != 0 {
|
||||
let c_id = cx.worklist.pop();
|
||||
let c_variance = *cx.region_paramd_items.get(&c_id);
|
||||
let c_variance = { *cx.region_paramd_items.get(&c_id) };
|
||||
// NOTE cleanup scopes cause an exaggerated lock here
|
||||
debug!("popped %d from worklist", c_id);
|
||||
match cx.dep_map.find(&c_id) {
|
||||
None => {}
|
||||
|
@ -779,9 +779,9 @@ pub fn Resolver(session: Session,
|
||||
unresolved_imports: 0,
|
||||
|
||||
current_module: current_module,
|
||||
value_ribs: ~[],
|
||||
type_ribs: ~[],
|
||||
label_ribs: ~[],
|
||||
value_ribs: @mut ~[],
|
||||
type_ribs: @mut ~[],
|
||||
label_ribs: @mut ~[],
|
||||
|
||||
xray_context: NoXray,
|
||||
current_trait_refs: None,
|
||||
@ -830,13 +830,13 @@ pub struct Resolver {
|
||||
|
||||
// The current set of local scopes, for values.
|
||||
// FIXME #4948: Reuse ribs to avoid allocation.
|
||||
value_ribs: ~[@Rib],
|
||||
value_ribs: @mut ~[@Rib],
|
||||
|
||||
// The current set of local scopes, for types.
|
||||
type_ribs: ~[@Rib],
|
||||
type_ribs: @mut ~[@Rib],
|
||||
|
||||
// The current set of local scopes, for labels.
|
||||
label_ribs: ~[@Rib],
|
||||
label_ribs: @mut ~[@Rib],
|
||||
|
||||
// Whether the current context is an X-ray context. An X-ray context is
|
||||
// allowed to access private names of any module.
|
||||
@ -4313,19 +4313,18 @@ pub impl Resolver {
|
||||
}
|
||||
|
||||
pat_struct(path, _, _) => {
|
||||
let structs: &mut HashSet<def_id> = &mut self.structs;
|
||||
match self.resolve_path(path, TypeNS, false, visitor) {
|
||||
Some(def_ty(class_id))
|
||||
if structs.contains(&class_id) => {
|
||||
if self.structs.contains(&class_id) => {
|
||||
let class_def = def_struct(class_id);
|
||||
self.record_def(pattern.id, class_def);
|
||||
}
|
||||
Some(definition @ def_struct(class_id))
|
||||
if structs.contains(&class_id) => {
|
||||
Some(definition @ def_struct(class_id)) => {
|
||||
assert!(self.structs.contains(&class_id));
|
||||
self.record_def(pattern.id, definition);
|
||||
}
|
||||
Some(definition @ def_variant(_, variant_id))
|
||||
if structs.contains(&variant_id) => {
|
||||
if self.structs.contains(&variant_id) => {
|
||||
self.record_def(pattern.id, definition);
|
||||
}
|
||||
result => {
|
||||
@ -4627,12 +4626,12 @@ pub impl Resolver {
|
||||
let search_result;
|
||||
match namespace {
|
||||
ValueNS => {
|
||||
search_result = self.search_ribs(&mut self.value_ribs, ident,
|
||||
search_result = self.search_ribs(self.value_ribs, ident,
|
||||
span,
|
||||
DontAllowCapturingSelf);
|
||||
}
|
||||
TypeNS => {
|
||||
search_result = self.search_ribs(&mut self.type_ribs, ident,
|
||||
search_result = self.search_ribs(self.type_ribs, ident,
|
||||
span, AllowCapturingSelf);
|
||||
}
|
||||
}
|
||||
@ -4822,15 +4821,14 @@ pub impl Resolver {
|
||||
|
||||
expr_struct(path, _, _) => {
|
||||
// Resolve the path to the structure it goes to.
|
||||
let structs: &mut HashSet<def_id> = &mut self.structs;
|
||||
match self.resolve_path(path, TypeNS, false, visitor) {
|
||||
Some(def_ty(class_id)) | Some(def_struct(class_id))
|
||||
if structs.contains(&class_id) => {
|
||||
if self.structs.contains(&class_id) => {
|
||||
let class_def = def_struct(class_id);
|
||||
self.record_def(expr.id, class_def);
|
||||
}
|
||||
Some(definition @ def_variant(_, class_id))
|
||||
if structs.contains(&class_id) => {
|
||||
if self.structs.contains(&class_id) => {
|
||||
self.record_def(expr.id, definition);
|
||||
}
|
||||
_ => {
|
||||
@ -4856,7 +4854,7 @@ pub impl Resolver {
|
||||
}
|
||||
|
||||
expr_break(Some(label)) | expr_again(Some(label)) => {
|
||||
match self.search_ribs(&mut self.label_ribs, label, expr.span,
|
||||
match self.search_ribs(self.label_ribs, label, expr.span,
|
||||
DontAllowCapturingSelf) {
|
||||
None =>
|
||||
self.session.span_err(expr.span,
|
||||
|
@ -244,11 +244,14 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||
// Nothing found. Continue.
|
||||
}
|
||||
Some(implementations) => {
|
||||
let implementations: &mut ~[@Impl] = *implementations;
|
||||
let len = { // FIXME(#5074): stage0 requires it
|
||||
let implementations: &mut ~[@Impl] = *implementations;
|
||||
implementations.len()
|
||||
};
|
||||
|
||||
// implementations is the list of all impls in scope for
|
||||
// trait_ref. (Usually, there's just one.)
|
||||
for uint::range(0, implementations.len()) |i| {
|
||||
for uint::range(0, len) |i| {
|
||||
let im = implementations[i];
|
||||
|
||||
// im is one specific impl of trait_ref.
|
||||
|
@ -240,8 +240,8 @@ pub impl CoherenceChecker {
|
||||
|
||||
fn check_implementation(&self,
|
||||
item: @item, associated_traits: ~[@trait_ref]) {
|
||||
let self_type = self.crate_context.tcx.tcache.get(
|
||||
&local_def(item.id));
|
||||
let tcx = self.crate_context.tcx;
|
||||
let self_type = ty::lookup_item_type(tcx, local_def(item.id));
|
||||
|
||||
// If there are no traits, then this implementation must have a
|
||||
// base type.
|
||||
@ -452,10 +452,8 @@ pub impl CoherenceChecker {
|
||||
}
|
||||
|
||||
fn check_implementation_coherence(&self) {
|
||||
let coherence_info = &mut self.crate_context.coherence_info;
|
||||
let extension_methods = &coherence_info.extension_methods;
|
||||
|
||||
for extension_methods.each_key |&trait_id| {
|
||||
let coherence_info = self.crate_context.coherence_info;
|
||||
for coherence_info.extension_methods.each_key |&trait_id| {
|
||||
self.check_implementation_coherence_of(trait_id);
|
||||
}
|
||||
}
|
||||
@ -514,13 +512,16 @@ pub impl CoherenceChecker {
|
||||
}
|
||||
|
||||
fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) {
|
||||
let coherence_info = &mut self.crate_context.coherence_info;
|
||||
let extension_methods = &coherence_info.extension_methods;
|
||||
let coherence_info = self.crate_context.coherence_info;
|
||||
let extension_methods = &*coherence_info.extension_methods;
|
||||
|
||||
match extension_methods.find(&trait_def_id) {
|
||||
Some(impls) => {
|
||||
let impls: &mut ~[@Impl] = *impls;
|
||||
for uint::range(0, impls.len()) |i| {
|
||||
let len = { // FIXME(#5074) stage0 requires this
|
||||
let impls: &mut ~[@Impl] = *impls;
|
||||
impls.len()
|
||||
};
|
||||
for uint::range(0, len) |i| {
|
||||
f(impls[i]);
|
||||
}
|
||||
}
|
||||
@ -1014,7 +1015,7 @@ pub impl CoherenceChecker {
|
||||
//
|
||||
|
||||
fn populate_destructor_table(&self) {
|
||||
let coherence_info = &mut self.crate_context.coherence_info;
|
||||
let coherence_info = self.crate_context.coherence_info;
|
||||
let tcx = self.crate_context.tcx;
|
||||
let drop_trait = tcx.lang_items.drop_trait();
|
||||
let impls_opt = coherence_info.extension_methods.find(&drop_trait);
|
||||
|
@ -16,6 +16,7 @@ use middle::typeck::infer::lub::Lub;
|
||||
use middle::typeck::infer::sub::Sub;
|
||||
use middle::typeck::infer::to_str::InferStr;
|
||||
use middle::typeck::infer::{cres, InferCtxt};
|
||||
use middle::typeck::infer::fold_regions_in_sig;
|
||||
use middle::typeck::isr_alist;
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl};
|
||||
@ -188,7 +189,8 @@ impl Combine for Glb {
|
||||
let new_vars =
|
||||
self.infcx.region_vars.vars_created_since_snapshot(snapshot);
|
||||
let sig1 =
|
||||
self.infcx.fold_regions_in_sig(
|
||||
fold_regions_in_sig(
|
||||
self.infcx.tcx,
|
||||
&sig0,
|
||||
|r, _in_fn| generalize_region(self, snapshot,
|
||||
new_vars, a_isr, a_vars, b_vars,
|
||||
|
@ -16,6 +16,7 @@ use middle::typeck::infer::lattice::*;
|
||||
use middle::typeck::infer::sub::Sub;
|
||||
use middle::typeck::infer::to_str::InferStr;
|
||||
use middle::typeck::infer::{cres, InferCtxt};
|
||||
use middle::typeck::infer::fold_regions_in_sig;
|
||||
use middle::typeck::isr_alist;
|
||||
use util::common::indent;
|
||||
use util::ppaux::mt_to_str;
|
||||
@ -141,7 +142,8 @@ impl Combine for Lub {
|
||||
let new_vars =
|
||||
self.infcx.region_vars.vars_created_since_snapshot(snapshot);
|
||||
let sig1 =
|
||||
self.infcx.fold_regions_in_sig(
|
||||
fold_regions_in_sig(
|
||||
self.infcx.tcx,
|
||||
&sig0,
|
||||
|r, _in_fn| generalize_region(self, snapshot, new_vars,
|
||||
a_isr, r));
|
||||
|
@ -574,7 +574,7 @@ pub impl InferCtxt {
|
||||
}
|
||||
|
||||
/// Execute `f` and commit the bindings if successful
|
||||
fn commit<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
fn commit<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
assert!(!self.in_snapshot());
|
||||
|
||||
debug!("commit()");
|
||||
@ -589,7 +589,7 @@ pub impl InferCtxt {
|
||||
}
|
||||
|
||||
/// Execute `f`, unroll bindings on failure
|
||||
fn try<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
fn try<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
debug!("try()");
|
||||
do indent {
|
||||
let snapshot = self.start_snapshot();
|
||||
@ -603,7 +603,7 @@ pub impl InferCtxt {
|
||||
}
|
||||
|
||||
/// Execute `f` then unroll any bindings it creates
|
||||
fn probe<T,E>(&mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
fn probe<T,E>(@mut self, f: &fn() -> Result<T,E>) -> Result<T,E> {
|
||||
debug!("probe()");
|
||||
do indent {
|
||||
let snapshot = self.start_snapshot();
|
||||
@ -783,15 +783,14 @@ pub impl InferCtxt {
|
||||
});
|
||||
(fn_sig, isr)
|
||||
}
|
||||
|
||||
fn fold_regions_in_sig(
|
||||
&mut self,
|
||||
fn_sig: &ty::FnSig,
|
||||
fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig
|
||||
{
|
||||
do ty::fold_sig(fn_sig) |t| {
|
||||
ty::fold_regions(self.tcx, t, fldr)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn fold_regions_in_sig(
|
||||
tcx: ty::ctxt,
|
||||
fn_sig: &ty::FnSig,
|
||||
fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig
|
||||
{
|
||||
do ty::fold_sig(fn_sig) |t| {
|
||||
ty::fold_regions(tcx, t, fldr)
|
||||
}
|
||||
}
|
@ -76,6 +76,9 @@ pub mod middle {
|
||||
}
|
||||
pub mod ty;
|
||||
pub mod subst;
|
||||
#[cfg(stage0)] #[path = "resolve_stage0.rs"]
|
||||
pub mod resolve;
|
||||
#[cfg(not(stage0))]
|
||||
pub mod resolve;
|
||||
#[path = "typeck/mod.rs"]
|
||||
pub mod typeck;
|
||||
|
@ -355,7 +355,7 @@ pub impl CodeMap {
|
||||
}
|
||||
|
||||
pub fn span_to_str(&self, sp: span) -> ~str {
|
||||
let files = &mut *self.files;
|
||||
let files = &*self.files;
|
||||
if files.len() == 0 && sp == dummy_sp() {
|
||||
return ~"no-location";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user