diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs index 017fc4b7b63..d25147fcde1 100644 --- a/src/libcore/unstable/lang.rs +++ b/src/libcore/unstable/lang.rs @@ -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(tag: &'static str, p: *const T) { diff --git a/src/libcore/util.rs b/src/libcore/util.rs index a08e38c021f..43616ebfd30 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -26,19 +26,20 @@ pub fn ignore(_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( - ptr: &mut T, - new_value: T, +pub fn with( + 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; } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2e2c92abcdc..59a6e6469e2 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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() } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index ea21ab0527b..06eb2542235 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -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 => {} diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ff46abaf712..8e83ea7e32e 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -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 = &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 = &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, diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 44b62122612..c177d5ab0eb 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -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. diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 573e4bd5790..d779c20b3e8 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -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); diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 2bbcd24595c..b818f666444 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -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, diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 85914338017..34e006c9615 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -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)); diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 4491b04b382..899b8cfd7ed 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -574,7 +574,7 @@ pub impl InferCtxt { } /// Execute `f` and commit the bindings if successful - fn commit(&mut self, f: &fn() -> Result) -> Result { + fn commit(@mut self, f: &fn() -> Result) -> Result { assert!(!self.in_snapshot()); debug!("commit()"); @@ -589,7 +589,7 @@ pub impl InferCtxt { } /// Execute `f`, unroll bindings on failure - fn try(&mut self, f: &fn() -> Result) -> Result { + fn try(@mut self, f: &fn() -> Result) -> Result { 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(&mut self, f: &fn() -> Result) -> Result { + fn probe(@mut self, f: &fn() -> Result) -> Result { 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) + } +} \ No newline at end of file diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 9e34d5c6177..1ecb38854c8 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -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; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7facc181eff..1c822b520f6 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -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"; }