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