diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 7da9d6f82bc..cf0e7e161c1 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -299,7 +299,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, last_private_map: last_private_map } = time(time_passes, "resolution", (), |_| - middle::resolve::resolve_crate(&sess, lang_items, krate)); + middle::resolve::resolve_crate(&sess, &lang_items, krate)); // Discard MTWT tables that aren't required past resolution. syntax::ext::mtwt::clear_tables(); @@ -316,7 +316,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, sess.diagnostic(), krate))); let freevars = time(time_passes, "freevar finding", (), |_| - freevars::annotate_freevars(def_map, krate)); + freevars::annotate_freevars(&def_map, krate)); let region_map = time(time_passes, "region resolution", (), |_| middle::region::resolve_crate(&sess, krate)); @@ -328,7 +328,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, freevars, region_map, lang_items); // passes are timed inside typeck - let (method_map, vtable_map) = typeck::check_crate(&ty_cx, trait_map, krate); + typeck::check_crate(&ty_cx, trait_map, krate); time(time_passes, "check static items", (), |_| middle::check_static::check_crate(&ty_cx, krate)); @@ -338,56 +338,52 @@ pub fn phase_3_run_analysis_passes(sess: Session, middle::const_eval::process_crate(krate, &ty_cx)); time(time_passes, "const checking", (), |_| - middle::check_const::check_crate(krate, def_map, method_map, &ty_cx)); + middle::check_const::check_crate(krate, &ty_cx)); let maps = (external_exports, last_private_map); let (exported_items, public_items) = time(time_passes, "privacy checking", maps, |(a, b)| - middle::privacy::check_crate(&ty_cx, &method_map, &exp_map2, - a, b, krate)); + middle::privacy::check_crate(&ty_cx, &exp_map2, a, b, krate)); time(time_passes, "effect checking", (), |_| - middle::effect::check_crate(&ty_cx, method_map, krate)); + middle::effect::check_crate(&ty_cx, krate)); let middle::moves::MoveMaps {moves_map, moved_variables_set, capture_map} = time(time_passes, "compute moves", (), |_| - middle::moves::compute_moves(&ty_cx, method_map, krate)); + middle::moves::compute_moves(&ty_cx, krate)); time(time_passes, "match checking", (), |_| - middle::check_match::check_crate(&ty_cx, method_map, - &moves_map, krate)); + middle::check_match::check_crate(&ty_cx, &moves_map, krate)); time(time_passes, "liveness checking", (), |_| - middle::liveness::check_crate(&ty_cx, method_map, - &capture_map, krate)); + middle::liveness::check_crate(&ty_cx, &capture_map, krate)); let root_map = time(time_passes, "borrow checking", (), |_| - middle::borrowck::check_crate(&ty_cx, method_map, - &moves_map, &moved_variables_set, + middle::borrowck::check_crate(&ty_cx, &moves_map, + &moved_variables_set, &capture_map, krate)); drop(moves_map); drop(moved_variables_set); time(time_passes, "kind checking", (), |_| - kind::check_crate(&ty_cx, method_map, krate)); + kind::check_crate(&ty_cx, krate)); let reachable_map = time(time_passes, "reachability checking", (), |_| - reachable::find_reachable(&ty_cx, method_map, &exported_items)); + reachable::find_reachable(&ty_cx, &exported_items)); time(time_passes, "death checking", (), |_| { middle::dead::check_crate(&ty_cx, - method_map, &exported_items, &reachable_map, krate) }); time(time_passes, "lint checking", (), |_| - lint::check_crate(&ty_cx, method_map, &exported_items, krate)); + lint::check_crate(&ty_cx, &exported_items, krate)); CrateAnalysis { exp_map2: exp_map2, @@ -396,8 +392,6 @@ pub fn phase_3_run_analysis_passes(sess: Session, public_items: public_items, maps: astencode::Maps { root_map: root_map, - method_map: method_map, - vtable_map: vtable_map, capture_map: RefCell::new(capture_map) }, reachable: reachable_map diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 9e652536f6d..ba7c5054794 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1882,37 +1882,23 @@ impl TypeNames { /* Memory-managed interface to target data. */ -pub struct target_data_res { - pub td: TargetDataRef, +pub struct TargetData { + pub lltd: TargetDataRef } -impl Drop for target_data_res { +impl Drop for TargetData { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeTargetData(self.td); + llvm::LLVMDisposeTargetData(self.lltd); } } } -pub fn target_data_res(td: TargetDataRef) -> target_data_res { - target_data_res { - td: td - } -} - -pub struct TargetData { - pub lltd: TargetDataRef, - dtor: @target_data_res -} - pub fn mk_target_data(string_rep: &str) -> TargetData { - let lltd = string_rep.with_c_str(|buf| { - unsafe { llvm::LLVMCreateTargetData(buf) } - }); - TargetData { - lltd: lltd, - dtor: @target_data_res(lltd) + lltd: string_rep.with_c_str(|buf| { + unsafe { llvm::LLVMCreateTargetData(buf) } + }) } } @@ -1949,35 +1935,22 @@ impl Drop for ObjectFile { /* Memory-managed interface to section iterators. */ -pub struct section_iter_res { - pub si: SectionIteratorRef, +pub struct SectionIter { + pub llsi: SectionIteratorRef } -impl Drop for section_iter_res { +impl Drop for SectionIter { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeSectionIterator(self.si); + llvm::LLVMDisposeSectionIterator(self.llsi); } } } -pub fn section_iter_res(si: SectionIteratorRef) -> section_iter_res { - section_iter_res { - si: si - } -} - -pub struct SectionIter { - pub llsi: SectionIteratorRef, - dtor: @section_iter_res -} - pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { unsafe { - let llsi = llvm::LLVMGetSections(llof); SectionIter { - llsi: llsi, - dtor: @section_iter_res(llsi) + llsi: llvm::LLVMGetSections(llof) } } } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 799da4150c5..efbfce1b2bb 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -23,7 +23,6 @@ use metadata::loader; use metadata::loader::Os; use metadata::loader::CratePaths; -use std::cell::RefCell; use std::rc::Rc; use collections::HashMap; use syntax::ast; @@ -280,7 +279,7 @@ fn resolve_crate<'a>(e: &mut Env, hash: Option<&Svh>, should_link: bool, span: Span) - -> (ast::CrateNum, @cstore::crate_metadata, + -> (ast::CrateNum, Rc, cstore::CrateSource) { match existing_match(e, crate_id, hash) { None => { @@ -317,7 +316,7 @@ fn resolve_crate<'a>(e: &mut Env, let cnum_map = if should_link { resolve_crate_deps(e, root, metadata.as_slice(), span) } else { - @RefCell::new(HashMap::new()) + HashMap::new() }; // Claim this crate number and cache it if we're linking to the @@ -331,13 +330,13 @@ fn resolve_crate<'a>(e: &mut Env, -1 }; - let cmeta = @cstore::crate_metadata { + let cmeta = Rc::new(cstore::crate_metadata { name: load_ctxt.crate_id.name.to_owned(), data: metadata, cnum_map: cnum_map, cnum: cnum, span: span, - }; + }); let source = cstore::CrateSource { dylib: dylib, @@ -346,7 +345,7 @@ fn resolve_crate<'a>(e: &mut Env, }; if should_link { - e.sess.cstore.set_crate_data(cnum, cmeta); + e.sess.cstore.set_crate_data(cnum, cmeta.clone()); e.sess.cstore.add_used_crate_source(source.clone()); } (cnum, cmeta, source) @@ -365,10 +364,7 @@ fn resolve_crate_deps(e: &mut Env, debug!("resolving deps of external crate"); // The map from crate numbers in the crate we're resolving to local crate // numbers - let mut cnum_map = HashMap::new(); - let r = decoder::get_crate_deps(cdata); - for dep in r.iter() { - let extrn_cnum = dep.cnum; + decoder::get_crate_deps(cdata).iter().map(|dep| { debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash); let (local_cnum, _, _) = resolve_crate(e, root, dep.crate_id.name.as_slice(), @@ -376,9 +372,8 @@ fn resolve_crate_deps(e: &mut Env, Some(&dep.hash), true, span); - cnum_map.insert(extrn_cnum, local_cnum); - } - return @RefCell::new(cnum_map); + (dep.cnum, local_cnum) + }).collect() } pub struct Loader<'a> { @@ -407,8 +402,8 @@ impl<'a> CrateLoader for Loader<'a> { info.ident, &info.crate_id, None, info.should_link, krate.span); - let macros = decoder::get_exported_macros(data); - let registrar = decoder::get_macro_registrar_fn(data).map(|id| { + let macros = decoder::get_exported_macros(&*data); + let registrar = decoder::get_macro_registrar_fn(&*data).map(|id| { decoder::get_symbol(data.data.as_slice(), id) }); MacroCrate { diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index f02f9c61582..4ebf4a52e41 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -33,8 +33,8 @@ pub struct StaticMethodInfo { } pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> ~str { - let cdata = cstore.get_crate_data(def.krate).data(); - return decoder::get_symbol(cdata, def.node); + let cdata = cstore.get_crate_data(def.krate); + decoder::get_symbol(cdata.data(), def.node) } /// Iterates over all the language items in the given crate. @@ -43,7 +43,7 @@ pub fn each_lang_item(cstore: &cstore::CStore, f: |ast::NodeId, uint| -> bool) -> bool { let crate_data = cstore.get_crate_data(cnum); - decoder::each_lang_item(crate_data, f) + decoder::each_lang_item(&*crate_data, f) } /// Iterates over each child of the given item. @@ -57,7 +57,7 @@ pub fn each_child_of_item(cstore: &cstore::CStore, cstore.get_crate_data(cnum) }; decoder::each_child_of_item(cstore.intr.clone(), - crate_data, + &*crate_data, def_id.node, get_crate_data, callback) @@ -74,7 +74,7 @@ pub fn each_top_level_item_of_crate(cstore: &cstore::CStore, cstore.get_crate_data(cnum) }; decoder::each_top_level_item_of_crate(cstore.intr.clone(), - crate_data, + &*crate_data, get_crate_data, callback) } @@ -82,7 +82,7 @@ pub fn each_top_level_item_of_crate(cstore: &cstore::CStore, pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - let path = decoder::get_item_path(cdata, def.node); + let path = decoder::get_item_path(&*cdata, def.node); // FIXME #1920: This path is not always correct if the crate is not linked // into the root namespace. @@ -103,26 +103,26 @@ pub fn maybe_get_item_ast(tcx: &ty::ctxt, def: ast::DefId, -> found_ast { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::maybe_get_item_ast(cdata, tcx, def.node, decode_inlined_item) + decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item) } pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId) - -> Vec<@ty::VariantInfo> { + -> Vec> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - return decoder::get_enum_variants(cstore.intr.clone(), cdata, def.node, tcx) + decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx) } /// Returns information about the given implementation. -pub fn get_impl(tcx: &ty::ctxt, impl_def_id: ast::DefId) - -> ty::Impl { - let cdata = tcx.sess.cstore.get_crate_data(impl_def_id.krate); - decoder::get_impl(tcx.sess.cstore.intr.clone(), cdata, impl_def_id.node, tcx) +pub fn get_impl_methods(cstore: &cstore::CStore, impl_def_id: ast::DefId) + -> Vec { + let cdata = cstore.get_crate_data(impl_def_id.krate); + decoder::get_impl_methods(&*cdata, impl_def_id.node) } pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method { let cdata = tcx.sess.cstore.get_crate_data(def.krate); - decoder::get_method(tcx.sess.cstore.intr.clone(), cdata, def.node, tcx) + decoder::get_method(tcx.sess.cstore.intr.clone(), &*cdata, def.node, tcx) } pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore, @@ -130,60 +130,60 @@ pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore, -> (ast::Ident, ast::ExplicitSelf_) { let cdata = cstore.get_crate_data(def.krate); - decoder::get_method_name_and_explicit_self(cstore.intr.clone(), cdata, def.node) + decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node) } pub fn get_trait_method_def_ids(cstore: &cstore::CStore, def: ast::DefId) -> Vec { let cdata = cstore.get_crate_data(def.krate); - decoder::get_trait_method_def_ids(cdata, def.node) + decoder::get_trait_method_def_ids(&*cdata, def.node) } pub fn get_item_variances(cstore: &cstore::CStore, def: ast::DefId) -> ty::ItemVariances { let cdata = cstore.get_crate_data(def.krate); - decoder::get_item_variances(cdata, def.node) + decoder::get_item_variances(&*cdata, def.node) } pub fn get_provided_trait_methods(tcx: &ty::ctxt, def: ast::DefId) - -> Vec<@ty::Method> { + -> Vec> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_provided_trait_methods(cstore.intr.clone(), cdata, def.node, tcx) + decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx) } -pub fn get_supertraits(tcx: &ty::ctxt, def: ast::DefId) -> Vec<@ty::TraitRef> { +pub fn get_supertraits(tcx: &ty::ctxt, def: ast::DefId) -> Vec> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_supertraits(cdata, def.node, tcx) + decoder::get_supertraits(&*cdata, def.node, tcx) } pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId) -> Option { let cdata = cstore.get_crate_data(def.krate); - decoder::get_type_name_if_impl(cdata, def.node) + decoder::get_type_name_if_impl(&*cdata, def.node) } pub fn get_static_methods_if_impl(cstore: &cstore::CStore, def: ast::DefId) -> Option > { let cdata = cstore.get_crate_data(def.krate); - decoder::get_static_methods_if_impl(cstore.intr.clone(), cdata, def.node) + decoder::get_static_methods_if_impl(cstore.intr.clone(), &*cdata, def.node) } pub fn get_item_attrs(cstore: &cstore::CStore, def_id: ast::DefId, f: |Vec<@ast::MetaItem> |) { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_item_attrs(cdata, def_id.node, f) + decoder::get_item_attrs(&*cdata, def_id.node, f) } pub fn get_struct_fields(cstore: &cstore::CStore, def: ast::DefId) -> Vec { let cdata = cstore.get_crate_data(def.krate); - decoder::get_struct_fields(cstore.intr.clone(), cdata, def.node) + decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node) } pub fn get_type(tcx: &ty::ctxt, @@ -191,13 +191,13 @@ pub fn get_type(tcx: &ty::ctxt, -> ty::ty_param_bounds_and_ty { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_type(cdata, def.node, tcx) + decoder::get_type(&*cdata, def.node, tcx) } pub fn get_trait_def(tcx: &ty::ctxt, def: ast::DefId) -> ty::TraitDef { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_trait_def(cdata, def.node, tcx) + decoder::get_trait_def(&*cdata, def.node, tcx) } pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId, @@ -213,7 +213,7 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId, decoder::maybe_find_item(def.node, class_doc), || format!("get_field_type: in class {:?}, field ID {:?} not found", class_id, def) ); - let ty = decoder::item_type(def, the_field, tcx, cdata); + let ty = decoder::item_type(def, the_field, tcx, &*cdata); ty::ty_param_bounds_and_ty { generics: ty::Generics {type_param_defs: Rc::new(Vec::new()), region_param_defs: Rc::new(Vec::new())}, @@ -224,10 +224,10 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId, // Given a def_id for an impl, return the trait it implements, // if there is one. pub fn get_impl_trait(tcx: &ty::ctxt, - def: ast::DefId) -> Option<@ty::TraitRef> { + def: ast::DefId) -> Option> { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_impl_trait(cdata, def.node, tcx) + decoder::get_impl_trait(&*cdata, def.node, tcx) } // Given a def_id for an impl, return information about its vtables @@ -235,35 +235,35 @@ pub fn get_impl_vtables(tcx: &ty::ctxt, def: ast::DefId) -> typeck::impl_res { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(def.krate); - decoder::get_impl_vtables(cdata, def.node, tcx) + decoder::get_impl_vtables(&*cdata, def.node, tcx) } pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) -> Vec<(cstore::NativeLibaryKind, ~str)> { let cdata = cstore.get_crate_data(crate_num); - decoder::get_native_libraries(cdata) + decoder::get_native_libraries(&*cdata) } pub fn each_impl(cstore: &cstore::CStore, crate_num: ast::CrateNum, callback: |ast::DefId|) { let cdata = cstore.get_crate_data(crate_num); - decoder::each_impl(cdata, callback) + decoder::each_impl(&*cdata, callback) } pub fn each_implementation_for_type(cstore: &cstore::CStore, def_id: ast::DefId, callback: |ast::DefId|) { let cdata = cstore.get_crate_data(def_id.krate); - decoder::each_implementation_for_type(cdata, def_id.node, callback) + decoder::each_implementation_for_type(&*cdata, def_id.node, callback) } pub fn each_implementation_for_trait(cstore: &cstore::CStore, def_id: ast::DefId, callback: |ast::DefId|) { let cdata = cstore.get_crate_data(def_id.krate); - decoder::each_implementation_for_trait(cdata, def_id.node, callback) + decoder::each_implementation_for_trait(&*cdata, def_id.node, callback) } /// If the given def ID describes a method belonging to a trait (either a @@ -274,21 +274,21 @@ pub fn get_trait_of_method(cstore: &cstore::CStore, tcx: &ty::ctxt) -> Option { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_trait_of_method(cdata, def_id.node, tcx) + decoder::get_trait_of_method(&*cdata, def_id.node, tcx) } pub fn get_macro_registrar_fn(cstore: &cstore::CStore, crate_num: ast::CrateNum) -> Option { let cdata = cstore.get_crate_data(crate_num); - decoder::get_macro_registrar_fn(cdata) + decoder::get_macro_registrar_fn(&*cdata) } pub fn get_exported_macros(cstore: &cstore::CStore, crate_num: ast::CrateNum) -> Vec<~str> { let cdata = cstore.get_crate_data(crate_num); - decoder::get_exported_macros(cdata) + decoder::get_exported_macros(&*cdata) } pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore, @@ -296,5 +296,5 @@ pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore, -> Option { let cdata = cstore.get_crate_data(def_id.krate); - decoder::get_tuple_struct_definition_if_ctor(cdata, def_id.node) + decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.node) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 2d46f92e88f..8e731a98dd7 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -30,7 +30,7 @@ use syntax::parse::token::IdentInterner; // local crate numbers (as generated during this session). Each external // crate may refer to types in other external crates, and each has their // own crate numbers. -pub type cnum_map = @RefCell>; +pub type cnum_map = HashMap; pub enum MetadataBlob { MetadataVec(CVec), @@ -68,7 +68,7 @@ pub struct CrateSource { } pub struct CStore { - metas: RefCell>, + metas: RefCell>>, extern_mod_crate_map: RefCell, used_crate_sources: RefCell>, used_libraries: RefCell>, @@ -95,8 +95,8 @@ impl CStore { self.metas.borrow().len() as ast::CrateNum + 1 } - pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata { - *self.metas.borrow().get(&cnum) + pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc { + self.metas.borrow().get(&cnum).clone() } pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh { @@ -104,13 +104,13 @@ impl CStore { decoder::get_crate_hash(cdata.data()) } - pub fn set_crate_data(&self, cnum: ast::CrateNum, data: @crate_metadata) { + pub fn set_crate_data(&self, cnum: ast::CrateNum, data: Rc) { self.metas.borrow_mut().insert(cnum, data); } - pub fn iter_crate_data(&self, i: |ast::CrateNum, @crate_metadata|) { - for (&k, &v) in self.metas.borrow().iter() { - i(k, v); + pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) { + for (&k, v) in self.metas.borrow().iter() { + i(k, &**v); } } @@ -155,7 +155,7 @@ impl CStore { ordering: &mut Vec) { if ordering.as_slice().contains(&cnum) { return } let meta = cstore.get_crate_data(cnum); - for (_, &dep) in meta.cnum_map.borrow().iter() { + for (_, &dep) in meta.cnum_map.iter() { visit(cstore, dep, ordering); } ordering.push(cnum); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b1cede8e410..37d9d3417c9 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -45,7 +45,7 @@ use syntax::ast; use syntax::codemap; use syntax::crateid::CrateId; -pub type Cmd = @crate_metadata; +pub type Cmd<'a> = &'a crate_metadata; // A function that takes a def_id relative to the crate being searched and // returns a def_id relative to the compilation environment, i.e. if we hit a @@ -76,8 +76,6 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool, ret } -pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Cmd; - pub fn maybe_find_item<'a>(item_id: ast::NodeId, items: ebml::Doc<'a>) -> Option> { fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool { @@ -388,7 +386,7 @@ pub fn get_trait_def(cdata: Cmd, generics: ty::Generics {type_param_defs: tp_defs, region_param_defs: rp_defs}, bounds: bounds, - trait_ref: @item_trait_ref(item_doc, tcx, cdata) + trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata)) } } @@ -412,11 +410,11 @@ pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) pub fn get_impl_trait(cdata: Cmd, id: ast::NodeId, - tcx: &ty::ctxt) -> Option<@ty::TraitRef> + tcx: &ty::ctxt) -> Option> { let item_doc = lookup_item(id, cdata.data()); reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { - @doc_trait_ref(tp, tcx, cdata) + Rc::new(doc_trait_ref(tp, tcx, cdata)) }) } @@ -462,6 +460,8 @@ pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool { }) } +pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc; + fn each_child_of_item_or_crate(intr: Rc, cdata: Cmd, item_doc: ebml::Doc, @@ -477,12 +477,17 @@ fn each_child_of_item_or_crate(intr: Rc, // This item may be in yet another crate if it was the child of a // reexport. - let other_crates_items = if child_def_id.krate == cdata.cnum { - reader::get_doc(reader::Doc(cdata.data()), tag_items) + let crate_data = if child_def_id.krate == cdata.cnum { + None } else { - let crate_data = get_crate_data(child_def_id.krate); - reader::get_doc(reader::Doc(crate_data.data()), tag_items) + Some(get_crate_data(child_def_id.krate)) }; + let crate_data = match crate_data { + Some(ref cdata) => &**cdata, + None => cdata + }; + + let other_crates_items = reader::get_doc(reader::Doc(crate_data.data()), tag_items); // Get the item. match maybe_find_item(child_def_id.node, other_crates_items) { @@ -565,12 +570,17 @@ fn each_child_of_item_or_crate(intr: Rc, let name = name_doc.as_str_slice(); // This reexport may be in yet another crate. - let other_crates_items = if child_def_id.krate == cdata.cnum { - reader::get_doc(reader::Doc(cdata.data()), tag_items) + let crate_data = if child_def_id.krate == cdata.cnum { + None } else { - let crate_data = get_crate_data(child_def_id.krate); - reader::get_doc(reader::Doc(crate_data.data()), tag_items) + Some(get_crate_data(child_def_id.krate)) }; + let crate_data = match crate_data { + Some(ref cdata) => &**cdata, + None => cdata + }; + + let other_crates_items = reader::get_doc(reader::Doc(crate_data.data()), tag_items); // Get the item. match maybe_find_item(child_def_id.node, other_crates_items) { @@ -634,7 +644,7 @@ pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec { item_path(lookup_item(id, cdata.data())) } -pub type DecodeInlinedItem<'a> = |cdata: @cstore::crate_metadata, +pub type DecodeInlinedItem<'a> = |cdata: Cmd, tcx: &ty::ctxt, path: Vec, par_doc: ebml::Doc|: 'a @@ -665,27 +675,27 @@ pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId, } pub fn get_enum_variants(intr: Rc, cdata: Cmd, id: ast::NodeId, - tcx: &ty::ctxt) -> Vec<@ty::VariantInfo> { + tcx: &ty::ctxt) -> Vec> { let data = cdata.data(); let items = reader::get_doc(reader::Doc(data), tag_items); let item = find_item(id, items); - let mut infos: Vec<@ty::VariantInfo> = Vec::new(); - let variant_ids = enum_variant_ids(item, cdata); let mut disr_val = 0; - for did in variant_ids.iter() { + enum_variant_ids(item, cdata).iter().map(|did| { let item = find_item(did.node, items); let ctor_ty = item_type(ast::DefId { krate: cdata.cnum, node: id}, item, tcx, cdata); let name = item_name(&*intr, item); let arg_tys = match ty::get(ctor_ty).sty { - ty::ty_bare_fn(ref f) => f.sig.inputs.clone(), - _ => Vec::new(), // Nullary enum variant. + ty::ty_bare_fn(ref f) => f.sig.inputs.clone(), + _ => Vec::new(), // Nullary enum variant. }; match variant_disr_val(item) { - Some(val) => { disr_val = val; } - _ => { /* empty */ } + Some(val) => { disr_val = val; } + _ => { /* empty */ } } - infos.push(@ty::VariantInfo{ + let old_disr_val = disr_val; + disr_val += 1; + Rc::new(ty::VariantInfo { args: arg_tys, arg_names: None, ctor_ty: ctor_ty, @@ -693,11 +703,10 @@ pub fn get_enum_variants(intr: Rc, cdata: Cmd, id: ast::NodeId, // I'm not even sure if we encode visibility // for variants -- TEST -- tjc id: *did, - disr_val: disr_val, - vis: ast::Inherited}); - disr_val += 1; - } - return infos; + disr_val: old_disr_val, + vis: ast::Inherited + }) + }).collect() } fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ { @@ -723,32 +732,17 @@ fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ { } } -fn item_impl_methods(intr: Rc, cdata: Cmd, item: ebml::Doc, - tcx: &ty::ctxt) -> Vec<@ty::Method> { - let mut rslt = Vec::new(); - reader::tagged_docs(item, tag_item_impl_method, |doc| { +/// Returns information about the given implementation. +pub fn get_impl_methods(cdata: Cmd, impl_id: ast::NodeId) -> Vec { + let mut methods = Vec::new(); + reader::tagged_docs(lookup_item(impl_id, cdata.data()), + tag_item_impl_method, |doc| { let m_did = reader::with_doc_data(doc, parse_def_id); - rslt.push(@get_method(intr.clone(), cdata, m_did.node, tcx)); + methods.push(translate_def_id(cdata, m_did)); true }); - rslt -} - -/// Returns information about the given implementation. -pub fn get_impl(intr: Rc, cdata: Cmd, impl_id: ast::NodeId, - tcx: &ty::ctxt) - -> ty::Impl { - let data = cdata.data(); - let impl_item = lookup_item(impl_id, data); - ty::Impl { - did: ast::DefId { - krate: cdata.cnum, - node: impl_id, - }, - ident: item_name(&*intr, impl_item), - methods: item_impl_methods(intr, cdata, impl_item, tcx), - } + methods } pub fn get_method_name_and_explicit_self( @@ -821,8 +815,8 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { } pub fn get_provided_trait_methods(intr: Rc, cdata: Cmd, - id: ast::NodeId, tcx: &ty::ctxt) -> - Vec<@ty::Method> { + id: ast::NodeId, tcx: &ty::ctxt) + -> Vec> { let data = cdata.data(); let item = lookup_item(id, data); let mut result = Vec::new(); @@ -832,7 +826,7 @@ pub fn get_provided_trait_methods(intr: Rc, cdata: Cmd, let mth = lookup_item(did.node, data); if item_method_sort(mth) == 'p' { - result.push(@get_method(intr.clone(), cdata, did.node, tcx)); + result.push(Rc::new(get_method(intr.clone(), cdata, did.node, tcx))); } true }); @@ -842,7 +836,7 @@ pub fn get_provided_trait_methods(intr: Rc, cdata: Cmd, /// Returns the supertraits of the given trait. pub fn get_supertraits(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) - -> Vec<@ty::TraitRef> { + -> Vec> { let mut results = Vec::new(); let item_doc = lookup_item(id, cdata.data()); reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| { @@ -851,7 +845,7 @@ pub fn get_supertraits(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place. let trait_ref = doc_trait_ref(trait_doc, tcx, cdata); if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() { - results.push(@trait_ref); + results.push(Rc::new(trait_ref)); } true }); @@ -1155,7 +1149,7 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { return ast::DefId { krate: cdata.cnum, node: did.node }; } - match cdata.cnum_map.borrow().find(&did.krate) { + match cdata.cnum_map.find(&did.krate) { Some(&n) => { ast::DefId { krate: n, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index f4c3f564068..848fd8d362e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -27,7 +27,7 @@ use util::nodemap::{NodeMap, NodeSet}; use serialize::Encodable; use std::cast; -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::hash; use std::hash::Hash; use std::io::MemWriter; @@ -52,9 +52,6 @@ use syntax::visit; use syntax; use writer = serialize::ebml::writer; -// used by astencode: -pub type abbrev_map = @RefCell>; - /// A borrowed version of ast::InlinedItem. pub enum InlinedItemRef<'a> { IIItemRef(&'a ast::Item), @@ -71,7 +68,7 @@ pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext, pub struct EncodeParams<'a> { pub diag: &'a SpanHandler, pub tcx: &'a ty::ctxt, - pub reexports2: middle::resolve::ExportMap2, + pub reexports2: &'a middle::resolve::ExportMap2, pub item_symbols: &'a RefCell>, pub non_inlineable_statics: &'a RefCell, pub link_meta: &'a LinkMeta, @@ -79,33 +76,16 @@ pub struct EncodeParams<'a> { pub encode_inlined_item: EncodeInlinedItem<'a>, } -pub struct Stats { - inline_bytes: Cell, - attr_bytes: Cell, - dep_bytes: Cell, - lang_item_bytes: Cell, - native_lib_bytes: Cell, - macro_registrar_fn_bytes: Cell, - macro_defs_bytes: Cell, - impl_bytes: Cell, - misc_bytes: Cell, - item_bytes: Cell, - index_bytes: Cell, - zero_bytes: Cell, - total_bytes: Cell, -} - pub struct EncodeContext<'a> { pub diag: &'a SpanHandler, pub tcx: &'a ty::ctxt, - pub stats: @Stats, - pub reexports2: middle::resolve::ExportMap2, + pub reexports2: &'a middle::resolve::ExportMap2, pub item_symbols: &'a RefCell>, pub non_inlineable_statics: &'a RefCell, pub link_meta: &'a LinkMeta, pub cstore: &'a cstore::CStore, pub encode_inlined_item: EncodeInlinedItem<'a>, - pub type_abbrevs: abbrev_map, + pub type_abbrevs: tyencode::abbrev_map, } fn encode_name(ebml_w: &mut Encoder, name: Name) { @@ -134,7 +114,7 @@ fn encode_trait_ref(ebml_w: &mut Encoder, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + abbrevs: &ecx.type_abbrevs }; ebml_w.start_tag(tag); @@ -146,8 +126,8 @@ fn encode_impl_vtables(ebml_w: &mut Encoder, ecx: &EncodeContext, vtables: &typeck::impl_res) { ebml_w.start_tag(tag_item_impl_vtables); - astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_vtables); - astencode::encode_vtable_param_res(ecx, ebml_w, vtables.self_vtables); + astencode::encode_vtable_res(ecx, ebml_w, &vtables.trait_vtables); + astencode::encode_vtable_param_res(ecx, ebml_w, &vtables.self_vtables); ebml_w.end_tag(); } @@ -170,7 +150,7 @@ fn encode_ty_type_param_defs(ebml_w: &mut Encoder, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + abbrevs: &ecx.type_abbrevs }; for param in params.iter() { ebml_w.start_tag(tag); @@ -227,7 +207,7 @@ pub fn write_type(ecx: &EncodeContext, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + abbrevs: &ecx.type_abbrevs }; tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ); } @@ -249,7 +229,7 @@ fn encode_method_fty(ecx: &EncodeContext, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + abbrevs: &ecx.type_abbrevs }; tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ); @@ -290,7 +270,7 @@ fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) { } fn encode_struct_fields(ebml_w: &mut Encoder, - fields: &Vec, + fields: &[ty::field_ty], origin: DefId) { for f in fields.iter() { if f.name == special_idents::unnamed_field.name { @@ -313,7 +293,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, ebml_w: &mut Encoder, id: NodeId, variants: &[P], - index: @RefCell> >, + index: &mut Vec>, generics: &ast::Generics) { debug!("encode_enum_variant_info(id={:?})", id); @@ -323,7 +303,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, ast::DefId { krate: LOCAL_CRATE, node: id }); for variant in variants.iter() { let def_id = local_def(variant.node.id); - index.borrow_mut().push(entry { + index.push(entry { val: variant.node.id as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -347,11 +327,10 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let fields = ty::lookup_struct_fields(ecx.tcx, def_id); let idx = encode_info_for_struct(ecx, ebml_w, - &fields, + fields.as_slice(), index); - encode_struct_fields(ebml_w, &fields, def_id); - let bkts = create_index(idx); - encode_index(ebml_w, bkts, write_i64); + encode_struct_fields(ebml_w, fields.as_slice(), def_id); + encode_index(ebml_w, idx, write_i64); } } if vi.get(i).disr_val != disr_val { @@ -402,10 +381,12 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext, ebml_w: &mut Encoder, exp: &middle::resolve::Export2) -> bool { + let impl_methods = ecx.tcx.impl_methods.borrow(); match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) { Some(implementations) => { - for &base_impl in implementations.borrow().iter() { - for &m in base_impl.methods.iter() { + for base_impl_did in implementations.borrow().iter() { + for &method_did in impl_methods.get(base_impl_did).iter() { + let m = ty::method(ecx.tcx, method_did); if m.explicit_self == ast::SelfStatic { encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident); } @@ -424,7 +405,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext, -> bool { match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) { Some(methods) => { - for &m in methods.iter() { + for m in methods.iter() { if m.explicit_self == ast::SelfStatic { encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident); } @@ -666,8 +647,8 @@ fn encode_provided_source(ebml_w: &mut Encoder, /* Returns an index of items in this class */ fn encode_info_for_struct(ecx: &EncodeContext, ebml_w: &mut Encoder, - fields: &Vec, - global_index: @RefCell> >) + fields: &[ty::field_ty], + global_index: &mut Vec>) -> Vec> { /* Each class has its own index, since different classes may have fields with the same name */ @@ -680,7 +661,7 @@ fn encode_info_for_struct(ecx: &EncodeContext, let id = field.id.node; index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()}); - global_index.borrow_mut().push(entry { + global_index.push(entry { val: id as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -700,9 +681,9 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, ebml_w: &mut Encoder, name: ast::Ident, ctor_id: NodeId, - index: @RefCell> >, + index: &mut Vec>, struct_id: NodeId) { - index.borrow_mut().push(entry { + index.push(entry { val: ctor_id as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -825,10 +806,10 @@ fn encode_inherent_implementations(ecx: &EncodeContext, def_id: DefId) { match ecx.tcx.inherent_impls.borrow().find(&def_id) { None => {} - Some(&implementations) => { - for implementation in implementations.borrow().iter() { + Some(implementations) => { + for &impl_def_id in implementations.borrow().iter() { ebml_w.start_tag(tag_items_data_item_inherent_impl); - encode_def_id(ebml_w, implementation.did); + encode_def_id(ebml_w, impl_def_id); ebml_w.end_tag(); } } @@ -841,10 +822,10 @@ fn encode_extension_implementations(ecx: &EncodeContext, trait_def_id: DefId) { match ecx.tcx.trait_impls.borrow().find(&trait_def_id) { None => {} - Some(&implementations) => { - for implementation in implementations.borrow().iter() { + Some(implementations) => { + for &impl_def_id in implementations.borrow().iter() { ebml_w.start_tag(tag_items_data_item_extension_impl); - encode_def_id(ebml_w, implementation.did); + encode_def_id(ebml_w, impl_def_id); ebml_w.end_tag(); } } @@ -854,14 +835,14 @@ fn encode_extension_implementations(ecx: &EncodeContext, fn encode_info_for_item(ecx: &EncodeContext, ebml_w: &mut Encoder, item: &Item, - index: @RefCell> >, + index: &mut Vec>, path: PathElems, vis: ast::Visibility) { let tcx = ecx.tcx; fn add_to_index(item: &Item, ebml_w: &Encoder, - index: @RefCell> >) { - index.borrow_mut().push(entry { + index: &mut Vec>) { + index.push(entry { val: item.id as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -988,7 +969,7 @@ fn encode_info_for_item(ecx: &EncodeContext, class itself */ let idx = encode_info_for_struct(ecx, ebml_w, - &fields, + fields.as_slice(), index); /* Index the class*/ @@ -1009,7 +990,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - encode_struct_fields(ebml_w, &fields, def_id); + encode_struct_fields(ebml_w, fields.as_slice(), def_id); (ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item)); @@ -1017,8 +998,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_inherent_implementations(ecx, ebml_w, def_id); /* Each class has its own index -- encode it */ - let bkts = create_index(idx); - encode_index(ebml_w, bkts, write_i64); + encode_index(ebml_w, idx, write_i64); ebml_w.end_tag(); // If this is a tuple-like struct, encode the type of the constructor. @@ -1033,8 +1013,8 @@ fn encode_info_for_item(ecx: &EncodeContext, ItemImpl(_, ref opt_trait, ty, ref ast_methods) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. - let impls = tcx.impls.borrow(); - let imp = impls.get(&def_id); + let impl_methods = tcx.impl_methods.borrow(); + let methods = impl_methods.get(&def_id); add_to_index(item, ebml_w, index); ebml_w.start_tag(tag_items_data_item); @@ -1051,16 +1031,16 @@ fn encode_info_for_item(ecx: &EncodeContext, } _ => {} } - for method in imp.methods.iter() { + for &method_def_id in methods.iter() { ebml_w.start_tag(tag_item_impl_method); - let s = def_to_str(method.def_id); + let s = def_to_str(method_def_id); ebml_w.writer.write(s.as_bytes()); ebml_w.end_tag(); } for ast_trait_ref in opt_trait.iter() { let trait_ref = ty::node_id_to_trait_ref( tcx, ast_trait_ref.ref_id); - encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref); + encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_trait_ref); let impl_vtables = ty::lookup_impl_vtables(tcx, def_id); encode_impl_vtables(ebml_w, ecx, &impl_vtables); } @@ -1072,18 +1052,18 @@ fn encode_info_for_item(ecx: &EncodeContext, // appear first in the impl structure, in the same order they do // in the ast. This is a little sketchy. let num_implemented_methods = ast_methods.len(); - for (i, m) in imp.methods.iter().enumerate() { + for (i, &method_def_id) in methods.iter().enumerate() { let ast_method = if i < num_implemented_methods { Some(*ast_methods.get(i)) } else { None }; - index.borrow_mut().push(entry { - val: m.def_id.node as i64, + index.push(entry { + val: method_def_id.node as i64, pos: ebml_w.writer.tell().unwrap(), }); encode_info_for_method(ecx, ebml_w, - *m, + &*ty::method(tcx, method_def_id), path.clone(), false, item.id, @@ -1101,7 +1081,7 @@ fn encode_info_for_item(ecx: &EncodeContext, trait_def.generics.type_param_defs(), tag_items_data_item_ty_param_bounds); encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs()); - encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); + encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref); encode_name(ebml_w, item.ident.name); encode_attributes(ebml_w, item.attrs.as_slice()); encode_visibility(ebml_w, vis); @@ -1120,7 +1100,7 @@ fn encode_info_for_item(ecx: &EncodeContext, // the builtin-kinds-as-supertraits. See corresponding fixme in decoder. for ast_trait_ref in super_traits.iter() { let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id); - encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref); + encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_super_trait_ref); } // Encode the implementations of this trait. @@ -1135,14 +1115,14 @@ fn encode_info_for_item(ecx: &EncodeContext, let method_ty = ty::method(tcx, method_def_id); - index.borrow_mut().push(entry { + index.push(entry { val: method_def_id.node as i64, pos: ebml_w.writer.tell().unwrap(), }); ebml_w.start_tag(tag_items_data_item); - encode_method_ty_fields(ecx, ebml_w, method_ty); + encode_method_ty_fields(ecx, ebml_w, &*method_ty); encode_parent_item(ebml_w, def_id); @@ -1202,10 +1182,10 @@ fn encode_info_for_item(ecx: &EncodeContext, fn encode_info_for_foreign_item(ecx: &EncodeContext, ebml_w: &mut Encoder, nitem: &ForeignItem, - index: @RefCell> >, + index: &mut Vec>, path: PathElems, abi: abi::Abi) { - index.borrow_mut().push(entry { + index.push(entry { val: nitem.id as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -1244,7 +1224,7 @@ fn my_visit_expr(_e: &Expr) { } fn my_visit_item(i: &Item, ebml_w: &mut Encoder, ecx_ptr: *int, - index: @RefCell> >) { + index: &mut Vec>) { let mut ebml_w = unsafe { ebml_w.unsafe_clone() }; // See above let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) }; @@ -1256,7 +1236,7 @@ fn my_visit_item(i: &Item, fn my_visit_foreign_item(ni: &ForeignItem, ebml_w: &mut Encoder, ecx_ptr:*int, - index: @RefCell> >) { + index: &mut Vec>) { // See above let ecx: &EncodeContext = unsafe { cast::transmute(ecx_ptr) }; debug!("writing foreign item {}::{}", @@ -1277,7 +1257,7 @@ fn my_visit_foreign_item(ni: &ForeignItem, struct EncodeVisitor<'a,'b> { ebml_w_for_visit_item: &'a mut Encoder<'b>, ecx_ptr:*int, - index: @RefCell> >, + index: &'a mut Vec>, } impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> { @@ -1305,9 +1285,9 @@ fn encode_info_for_items(ecx: &EncodeContext, ebml_w: &mut Encoder, krate: &Crate) -> Vec> { - let index = @RefCell::new(Vec::new()); + let mut index = Vec::new(); ebml_w.start_tag(tag_items_data); - index.borrow_mut().push(entry { + index.push(entry { val: CRATE_NODE_ID as i64, pos: ebml_w.writer.tell().unwrap(), }); @@ -1321,53 +1301,34 @@ fn encode_info_for_items(ecx: &EncodeContext, // See comment in `encode_side_tables_for_ii` in astencode let ecx_ptr: *int = unsafe { cast::transmute(ecx) }; - { - let mut visitor = EncodeVisitor { - index: index, - ecx_ptr: ecx_ptr, - ebml_w_for_visit_item: &mut *ebml_w, - }; - - visit::walk_crate(&mut visitor, krate, ()); - } + visit::walk_crate(&mut EncodeVisitor { + index: &mut index, + ecx_ptr: ecx_ptr, + ebml_w_for_visit_item: &mut *ebml_w, + }, krate, ()); ebml_w.end_tag(); - return /*bad*/index.borrow().clone(); + index } // Path and definition ID indexing -fn create_index( - index: Vec> ) - -> Vec<@Vec> > { - let mut buckets: Vec<@RefCell> >> = Vec::new(); - for _ in range(0u, 256u) { - buckets.push(@RefCell::new(Vec::new())); - } - for elt in index.iter() { +fn encode_index(ebml_w: &mut Encoder, index: Vec>, + write_fn: |&mut MemWriter, &T|) { + let mut buckets: Vec>> = Vec::from_fn(256, |_| Vec::new()); + for elt in index.move_iter() { let h = hash::hash(&elt.val) as uint; - buckets.get_mut(h % 256).borrow_mut().push((*elt).clone()); + buckets.get_mut(h % 256).push(elt); } - let mut buckets_frozen = Vec::new(); - for bucket in buckets.iter() { - buckets_frozen.push(@/*bad*/bucket.borrow().clone()); - } - return buckets_frozen; -} - -fn encode_index( - ebml_w: &mut Encoder, - buckets: Vec<@Vec> > , - write_fn: |&mut MemWriter, &T|) { ebml_w.start_tag(tag_index); let mut bucket_locs = Vec::new(); ebml_w.start_tag(tag_index_buckets); for bucket in buckets.iter() { bucket_locs.push(ebml_w.writer.tell().unwrap()); ebml_w.start_tag(tag_index_buckets_bucket); - for elt in (**bucket).iter() { + for elt in bucket.iter() { ebml_w.start_tag(tag_index_buckets_bucket_elt); assert!(elt.pos < 0xffff_ffff); { @@ -1614,7 +1575,7 @@ impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> { fn visit_item(&mut self, item: &Item, _: ()) { match item.node { ItemImpl(_, Some(ref trait_ref), _, _) => { - let def_map = self.ecx.tcx.def_map; + let def_map = &self.ecx.tcx.def_map; let trait_def = def_map.borrow().get_copy(&trait_ref.ref_id); let def_id = ast_util::def_id_of_def(trait_def); @@ -1723,20 +1684,33 @@ pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec { } fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) { - let stats = Stats { - inline_bytes: Cell::new(0), - attr_bytes: Cell::new(0), - dep_bytes: Cell::new(0), - lang_item_bytes: Cell::new(0), - native_lib_bytes: Cell::new(0), - macro_registrar_fn_bytes: Cell::new(0), - macro_defs_bytes: Cell::new(0), - impl_bytes: Cell::new(0), - misc_bytes: Cell::new(0), - item_bytes: Cell::new(0), - index_bytes: Cell::new(0), - zero_bytes: Cell::new(0), - total_bytes: Cell::new(0), + struct Stats { + attr_bytes: u64, + dep_bytes: u64, + lang_item_bytes: u64, + native_lib_bytes: u64, + macro_registrar_fn_bytes: u64, + macro_defs_bytes: u64, + impl_bytes: u64, + misc_bytes: u64, + item_bytes: u64, + index_bytes: u64, + zero_bytes: u64, + total_bytes: u64, + } + let mut stats = Stats { + attr_bytes: 0, + dep_bytes: 0, + lang_item_bytes: 0, + native_lib_bytes: 0, + macro_registrar_fn_bytes: 0, + macro_defs_bytes: 0, + impl_bytes: 0, + misc_bytes: 0, + item_bytes: 0, + index_bytes: 0, + zero_bytes: 0, + total_bytes: 0, }; let EncodeParams { item_symbols, @@ -1749,19 +1723,16 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) non_inlineable_statics, .. } = parms; - let type_abbrevs = @RefCell::new(HashMap::new()); - let stats = @stats; let ecx = EncodeContext { diag: diag, tcx: tcx, - stats: stats, reexports2: reexports2, item_symbols: item_symbols, non_inlineable_statics: non_inlineable_statics, link_meta: link_meta, cstore: cstore, encode_inlined_item: encode_inlined_item, - type_abbrevs: type_abbrevs, + type_abbrevs: RefCell::new(HashMap::new()), }; let mut ebml_w = writer::Encoder(wr); @@ -1772,88 +1743,86 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) let mut i = ebml_w.writer.tell().unwrap(); let crate_attrs = synthesize_crate_attrs(&ecx, krate); encode_attributes(&mut ebml_w, crate_attrs.as_slice()); - ecx.stats.attr_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.attr_bytes = ebml_w.writer.tell().unwrap() - i; i = ebml_w.writer.tell().unwrap(); encode_crate_deps(&mut ebml_w, ecx.cstore); - ecx.stats.dep_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.dep_bytes = ebml_w.writer.tell().unwrap() - i; // Encode the language items. i = ebml_w.writer.tell().unwrap(); encode_lang_items(&ecx, &mut ebml_w); - ecx.stats.lang_item_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.lang_item_bytes = ebml_w.writer.tell().unwrap() - i; // Encode the native libraries used i = ebml_w.writer.tell().unwrap(); encode_native_libraries(&ecx, &mut ebml_w); - ecx.stats.native_lib_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i; // Encode the macro registrar function i = ebml_w.writer.tell().unwrap(); encode_macro_registrar_fn(&ecx, &mut ebml_w); - ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i; // Encode macro definitions i = ebml_w.writer.tell().unwrap(); encode_macro_defs(&ecx, krate, &mut ebml_w); - ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.macro_defs_bytes = ebml_w.writer.tell().unwrap() - i; // Encode the def IDs of impls, for coherence checking. i = ebml_w.writer.tell().unwrap(); encode_impls(&ecx, krate, &mut ebml_w); - ecx.stats.impl_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.impl_bytes = ebml_w.writer.tell().unwrap() - i; // Encode miscellaneous info. i = ebml_w.writer.tell().unwrap(); encode_misc_info(&ecx, krate, &mut ebml_w); - ecx.stats.misc_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.misc_bytes = ebml_w.writer.tell().unwrap() - i; // Encode and index the items. ebml_w.start_tag(tag_items); i = ebml_w.writer.tell().unwrap(); let items_index = encode_info_for_items(&ecx, &mut ebml_w, krate); - ecx.stats.item_bytes.set(ebml_w.writer.tell().unwrap() - i); + stats.item_bytes = ebml_w.writer.tell().unwrap() - i; i = ebml_w.writer.tell().unwrap(); - let items_buckets = create_index(items_index); - encode_index(&mut ebml_w, items_buckets, write_i64); - ecx.stats.index_bytes.set(ebml_w.writer.tell().unwrap() - i); + encode_index(&mut ebml_w, items_index, write_i64); + stats.index_bytes = ebml_w.writer.tell().unwrap() - i; ebml_w.end_tag(); - ecx.stats.total_bytes.set(ebml_w.writer.tell().unwrap()); + stats.total_bytes = ebml_w.writer.tell().unwrap(); if tcx.sess.meta_stats() { for e in ebml_w.writer.get_ref().iter() { if *e == 0 { - ecx.stats.zero_bytes.set(ecx.stats.zero_bytes.get() + 1); + stats.zero_bytes += 1; } } println!("metadata stats:"); - println!(" inline bytes: {}", ecx.stats.inline_bytes.get()); - println!(" attribute bytes: {}", ecx.stats.attr_bytes.get()); - println!(" dep bytes: {}", ecx.stats.dep_bytes.get()); - println!(" lang item bytes: {}", ecx.stats.lang_item_bytes.get()); - println!(" native bytes: {}", ecx.stats.native_lib_bytes.get()); - println!("macro registrar bytes: {}", ecx.stats.macro_registrar_fn_bytes.get()); - println!(" macro def bytes: {}", ecx.stats.macro_defs_bytes.get()); - println!(" impl bytes: {}", ecx.stats.impl_bytes.get()); - println!(" misc bytes: {}", ecx.stats.misc_bytes.get()); - println!(" item bytes: {}", ecx.stats.item_bytes.get()); - println!(" index bytes: {}", ecx.stats.index_bytes.get()); - println!(" zero bytes: {}", ecx.stats.zero_bytes.get()); - println!(" total bytes: {}", ecx.stats.total_bytes.get()); + println!(" attribute bytes: {}", stats.attr_bytes); + println!(" dep bytes: {}", stats.dep_bytes); + println!(" lang item bytes: {}", stats.lang_item_bytes); + println!(" native bytes: {}", stats.native_lib_bytes); + println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes); + println!(" macro def bytes: {}", stats.macro_defs_bytes); + println!(" impl bytes: {}", stats.impl_bytes); + println!(" misc bytes: {}", stats.misc_bytes); + println!(" item bytes: {}", stats.item_bytes); + println!(" index bytes: {}", stats.index_bytes); + println!(" zero bytes: {}", stats.zero_bytes); + println!(" total bytes: {}", stats.total_bytes); } } // Get the encoded string for a type pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> ~str { - let cx = &tyencode::ctxt { + let mut wr = MemWriter::new(); + tyencode::enc_ty(&mut wr, &tyencode::ctxt { diag: tcx.sess.diagnostic(), ds: def_to_str, tcx: tcx, - abbrevs: tyencode::ac_no_abbrevs}; - let mut wr = MemWriter::new(); - tyencode::enc_ty(&mut wr, cx, t); + abbrevs: &RefCell::new(HashMap::new()) + }, t); str::from_utf8_owned(wr.get_ref().to_owned()).unwrap() } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index cfa2d647ec9..3ba8dd3b30f 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -18,6 +18,7 @@ use middle::ty; +use std::rc::Rc; use std::str; use std::strbuf::StrBuf; use std::uint; @@ -563,7 +564,7 @@ fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef ty::TypeParameterDef { ident: parse_ident(st, ':'), def_id: parse_def(st, NominalType, |x,y| conv(x,y)), - bounds: @parse_bounds(st, |x,y| conv(x,y)), + bounds: Rc::new(parse_bounds(st, |x,y| conv(x,y))), default: parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y))) } } @@ -591,7 +592,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { param_bounds.builtin_bounds.add(ty::BoundShare); } 'I' => { - param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y))); + param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y)))); } '.' => { return param_bounds; diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 1d7d43f895e..13d24e7a1d0 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -17,7 +17,6 @@ use std::cell::RefCell; use collections::HashMap; use std::io; use std::io::MemWriter; -use std::str; use std::fmt; use middle::ty::param_ty; @@ -39,7 +38,7 @@ pub struct ctxt<'a> { pub ds: fn(DefId) -> ~str, // The type context. pub tcx: &'a ty::ctxt, - pub abbrevs: abbrev_ctxt + pub abbrevs: &'a abbrev_map } // Compact string representation for ty.t values. API ty_str & parse_from_str. @@ -51,61 +50,35 @@ pub struct ty_abbrev { s: ~str } -pub enum abbrev_ctxt { - ac_no_abbrevs, - ac_use_abbrevs(@RefCell>), -} +pub type abbrev_map = RefCell>; fn mywrite(w: &mut MemWriter, fmt: &fmt::Arguments) { fmt::write(&mut *w as &mut io::Writer, fmt); } pub fn enc_ty(w: &mut MemWriter, cx: &ctxt, t: ty::t) { - match cx.abbrevs { - ac_no_abbrevs => { - let result_str_opt = cx.tcx.short_names_cache.borrow() - .find(&t) - .map(|result| { - (*result).clone() - }); - let result_str = match result_str_opt { - Some(s) => s, - None => { - let wr = &mut MemWriter::new(); - enc_sty(wr, cx, &ty::get(t).sty); - let s = str::from_utf8(wr.get_ref()).unwrap(); - cx.tcx.short_names_cache.borrow_mut().insert(t, s.to_str()); - s.to_str() - } - }; - w.write(result_str.as_bytes()); - } - ac_use_abbrevs(abbrevs) => { - match abbrevs.borrow_mut().find(&t) { - Some(a) => { w.write(a.s.as_bytes()); return; } - None => {} - } - let pos = w.tell().unwrap(); - enc_sty(w, cx, &ty::get(t).sty); - let end = w.tell().unwrap(); - let len = end - pos; - fn estimate_sz(u: u64) -> u64 { - let mut n = u; - let mut len = 0; - while n != 0 { len += 1; n = n >> 4; } - return len; - } - let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len); - if abbrev_len < len { - // I.e. it's actually an abbreviation. - let s = format!("\\#{:x}:{:x}\\#", pos, len); - let a = ty_abbrev { pos: pos as uint, - len: len as uint, - s: s }; - abbrevs.borrow_mut().insert(t, a); - } - return; - } + match cx.abbrevs.borrow_mut().find(&t) { + Some(a) => { w.write(a.s.as_bytes()); return; } + None => {} + } + let pos = w.tell().unwrap(); + enc_sty(w, cx, &ty::get(t).sty); + let end = w.tell().unwrap(); + let len = end - pos; + fn estimate_sz(u: u64) -> u64 { + let mut n = u; + let mut len = 0; + while n != 0 { len += 1; n = n >> 4; } + return len; + } + let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len); + if abbrev_len < len { + // I.e. it's actually an abbreviation. + cx.abbrevs.borrow_mut().insert(t, ty_abbrev { + pos: pos as uint, + len: len as uint, + s: format!("\\#{:x}:{:x}\\#", pos, len) + }); } } @@ -393,9 +366,9 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) { } } - for &tp in bs.trait_bounds.iter() { + for tp in bs.trait_bounds.iter() { mywrite!(w, "I"); - enc_trait_ref(w, cx, tp); + enc_trait_ref(w, cx, &**tp); } mywrite!(w, "."); @@ -403,6 +376,6 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) { pub fn enc_type_param_def(w: &mut MemWriter, cx: &ctxt, v: &ty::TypeParameterDef) { mywrite!(w, "{}:{}|", token::get_ident(v.ident), (cx.ds)(v.def_id)); - enc_bounds(w, cx, v.bounds); + enc_bounds(w, cx, &*v.bounds); enc_opt(w, v.default, |w, t| enc_ty(w, cx, t)); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 49a2b6326c8..08133a8b69e 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -55,13 +55,11 @@ use writer = serialize::ebml::writer; // Auxiliary maps of things to be encoded pub struct Maps { pub root_map: middle::borrowck::root_map, - pub method_map: middle::typeck::MethodMap, - pub vtable_map: middle::typeck::vtable_map, pub capture_map: RefCell, } struct DecodeContext<'a> { - cdata: @cstore::crate_metadata, + cdata: &'a cstore::crate_metadata, tcx: &'a ty::ctxt, maps: &'a Maps } @@ -112,7 +110,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, ebml_w.writer.tell()); } -pub fn decode_inlined_item(cdata: @cstore::crate_metadata, +pub fn decode_inlined_item(cdata: &cstore::crate_metadata, tcx: &ty::ctxt, maps: &Maps, path: Vec, @@ -273,7 +271,7 @@ impl, E> def_id_encoder_helpers for S { trait def_id_decoder_helpers { fn read_def_id(&mut self, xcx: &ExtendedDecodeContext) -> ast::DefId; fn read_def_id_noxcx(&mut self, - cdata: @cstore::crate_metadata) -> ast::DefId; + cdata: &cstore::crate_metadata) -> ast::DefId; } impl, E> def_id_decoder_helpers for D { @@ -283,7 +281,7 @@ impl, E> def_id_decoder_helpers for D { } fn read_def_id_noxcx(&mut self, - cdata: @cstore::crate_metadata) -> ast::DefId { + cdata: &cstore::crate_metadata) -> ast::DefId { let did: ast::DefId = Decodable::decode(self).ok().unwrap(); decoder::translate_def_id(cdata, did) } @@ -528,7 +526,7 @@ impl tr for ty::TraitStore { // ______________________________________________________________________ // Encoding and decoding of freevar information -fn encode_freevar_entry(ebml_w: &mut Encoder, fv: @freevar_entry) { +fn encode_freevar_entry(ebml_w: &mut Encoder, fv: &freevar_entry) { (*fv).encode(ebml_w).unwrap(); } @@ -660,7 +658,7 @@ impl tr for MethodOrigin { fn encode_vtable_res_with_key(ecx: &e::EncodeContext, ebml_w: &mut Encoder, autoderef: u32, - dr: typeck::vtable_res) { + dr: &typeck::vtable_res) { ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| { ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| { autoderef.encode(ebml_w) @@ -673,19 +671,19 @@ fn encode_vtable_res_with_key(ecx: &e::EncodeContext, pub fn encode_vtable_res(ecx: &e::EncodeContext, ebml_w: &mut Encoder, - dr: typeck::vtable_res) { + dr: &typeck::vtable_res) { // can't autogenerate this code because automatic code of // ty::t doesn't work, and there is no way (atm) to have // hand-written encoding routines combine with auto-generated // ones. perhaps we should fix this. ebml_w.emit_from_vec(dr.as_slice(), |ebml_w, param_tables| { - Ok(encode_vtable_param_res(ecx, ebml_w, *param_tables)) + Ok(encode_vtable_param_res(ecx, ebml_w, param_tables)) }).unwrap() } pub fn encode_vtable_param_res(ecx: &e::EncodeContext, ebml_w: &mut Encoder, - param_tables: typeck::vtable_param_res) { + param_tables: &typeck::vtable_param_res) { ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| { Ok(encode_vtable_origin(ecx, ebml_w, vtable_origin)) }).unwrap() @@ -697,7 +695,7 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext, vtable_origin: &typeck::vtable_origin) { ebml_w.emit_enum("vtable_origin", |ebml_w| { match *vtable_origin { - typeck::vtable_static(def_id, ref tys, vtable_res) => { + typeck::vtable_static(def_id, ref tys, ref vtable_res) => { ebml_w.emit_enum_variant("vtable_static", 0u, 3u, |ebml_w| { ebml_w.emit_enum_variant_arg(0u, |ebml_w| { Ok(ebml_w.emit_def_id(def_id)) @@ -727,23 +725,23 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext, pub trait vtable_decoder_helpers { fn read_vtable_res_with_key(&mut self, tcx: &ty::ctxt, - cdata: @cstore::crate_metadata) + cdata: &cstore::crate_metadata) -> (u32, typeck::vtable_res); fn read_vtable_res(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_res; fn read_vtable_param_res(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_param_res; fn read_vtable_origin(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_origin; } impl<'a> vtable_decoder_helpers for reader::Decoder<'a> { fn read_vtable_res_with_key(&mut self, tcx: &ty::ctxt, - cdata: @cstore::crate_metadata) + cdata: &cstore::crate_metadata) -> (u32, typeck::vtable_res) { self.read_struct("VtableWithKey", 2, |this| { let autoderef = this.read_struct_field("autoderef", 0, |this| { @@ -756,27 +754,21 @@ impl<'a> vtable_decoder_helpers for reader::Decoder<'a> { } fn read_vtable_res(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_res { - @self.read_to_vec(|this| - Ok(this.read_vtable_param_res(tcx, cdata))) - .unwrap() - .move_iter() - .collect() + self.read_to_vec(|this| Ok(this.read_vtable_param_res(tcx, cdata))) + .unwrap().move_iter().collect() } fn read_vtable_param_res(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_param_res { - @self.read_to_vec(|this| - Ok(this.read_vtable_origin(tcx, cdata))) - .unwrap() - .move_iter() - .collect() + self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata))) + .unwrap().move_iter().collect() } fn read_vtable_origin(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> typeck::vtable_origin { self.read_enum("vtable_origin", |this| { this.read_enum_variant(["vtable_static", @@ -828,7 +820,7 @@ impl<'a> get_ty_str_ctxt for e::EncodeContext<'a> { diag: self.tcx.sess.diagnostic(), ds: e::def_to_str, tcx: self.tcx, - abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs) + abbrevs: &self.type_abbrevs } } } @@ -1026,7 +1018,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { ebml_w.emit_from_vec(fv.as_slice(), |ebml_w, fv_entry| { - Ok(encode_freevar_entry(ebml_w, *fv_entry)) + Ok(encode_freevar_entry(ebml_w, fv_entry)) }); }) }) @@ -1052,7 +1044,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } let method_call = MethodCall::expr(id); - for &method in maps.method_map.borrow().find(&method_call).iter() { + for &method in tcx.method_map.borrow().find(&method_call).iter() { ebml_w.tag(c::tag_table_method_map, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { @@ -1061,21 +1053,21 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &dr in maps.vtable_map.borrow().find(&method_call).iter() { + for &dr in tcx.vtable_map.borrow().find(&method_call).iter() { ebml_w.tag(c::tag_table_vtable_map, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { - encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, *dr); + encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, dr); }) }) } - for adj in tcx.adjustments.borrow().find(&id).iter() { - match ***adj { + for &adj in tcx.adjustments.borrow().find(&id).iter() { + match *adj { ty::AutoDerefRef(adj) => { for autoderef in range(0, adj.autoderefs) { let method_call = MethodCall::autoderef(id, autoderef as u32); - for &method in maps.method_map.borrow().find(&method_call).iter() { + for &method in tcx.method_map.borrow().find(&method_call).iter() { ebml_w.tag(c::tag_table_method_map, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { @@ -1084,12 +1076,12 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &dr in maps.vtable_map.borrow().find(&method_call).iter() { + for &dr in tcx.vtable_map.borrow().find(&method_call).iter() { ebml_w.tag(c::tag_table_vtable_map, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { encode_vtable_res_with_key(ecx, ebml_w, - method_call.autoderef, *dr); + method_call.autoderef, dr); }) }) } @@ -1101,7 +1093,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, ebml_w.tag(c::tag_table_adjustments, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { - ebml_w.emit_auto_adjustment(ecx, **adj); + ebml_w.emit_auto_adjustment(ecx, adj); }) }) } @@ -1148,15 +1140,15 @@ trait ebml_decoder_decoder_helpers { // Versions of the type reading functions that don't need the full // ExtendedDecodeContext. fn read_ty_noxcx(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t; + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> ty::t; fn read_tys_noxcx(&mut self, tcx: &ty::ctxt, - cdata: @cstore::crate_metadata) -> Vec; + cdata: &cstore::crate_metadata) -> Vec; } impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> { fn read_ty_noxcx(&mut self, - tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t { + tcx: &ty::ctxt, cdata: &cstore::crate_metadata) -> ty::t { self.read_opaque(|_, doc| { Ok(tydecode::parse_ty_data( doc.data, @@ -1169,7 +1161,7 @@ impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> { fn read_tys_noxcx(&mut self, tcx: &ty::ctxt, - cdata: @cstore::crate_metadata) -> Vec { + cdata: &cstore::crate_metadata) -> Vec { self.read_to_vec(|this| Ok(this.read_ty_noxcx(tcx, cdata)) ) .unwrap() .move_iter() @@ -1378,8 +1370,8 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, dcx.tcx.node_type_substs.borrow_mut().insert(id, tys); } c::tag_table_freevars => { - let fv_info = @val_dsr.read_to_vec(|val_dsr| { - Ok(@val_dsr.read_freevar_entry(xcx)) + let fv_info = val_dsr.read_to_vec(|val_dsr| { + Ok(val_dsr.read_freevar_entry(xcx)) }).unwrap().move_iter().collect(); dcx.tcx.freevars.borrow_mut().insert(id, fv_info); } @@ -1398,7 +1390,7 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, expr_id: id, autoderef: autoderef }; - dcx.maps.method_map.borrow_mut().insert(method_call, method); + dcx.tcx.method_map.borrow_mut().insert(method_call, method); } c::tag_table_vtable_map => { let (autoderef, vtable_res) = @@ -1408,10 +1400,10 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, expr_id: id, autoderef: autoderef }; - dcx.maps.vtable_map.borrow_mut().insert(vtable_key, vtable_res); + dcx.tcx.vtable_map.borrow_mut().insert(vtable_key, vtable_res); } c::tag_table_adjustments => { - let adj: @ty::AutoAdjustment = @val_dsr.read_auto_adjustment(xcx); + let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(xcx); dcx.tcx.adjustments.borrow_mut().insert(id, adj); } c::tag_table_capture_map => { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 5e0425141ac..e09507f5d5f 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -30,6 +30,8 @@ use syntax::visit::Visitor; use syntax::visit; use util::ppaux::Repr; +use std::rc::Rc; + struct CheckLoanCtxt<'a> { bccx: &'a BorrowckCtxt<'a>, dfcx_loans: &'a LoanDataFlow<'a>, @@ -82,7 +84,7 @@ pub fn check_loans(bccx: &BorrowckCtxt, #[deriving(Eq)] enum MoveError { MoveOk, - MoveWhileBorrowed(/*loan*/@LoanPath, /*loan*/Span) + MoveWhileBorrowed(/*loan*/Rc, /*loan*/Span) } impl<'a> CheckLoanCtxt<'a> { @@ -121,7 +123,7 @@ impl<'a> CheckLoanCtxt<'a> { pub fn each_in_scope_restriction(&self, scope_id: ast::NodeId, - loan_path: @LoanPath, + loan_path: &LoanPath, op: |&Loan, &Restriction| -> bool) -> bool { //! Iterates through all the in-scope restrictions for the @@ -133,7 +135,7 @@ impl<'a> CheckLoanCtxt<'a> { let mut ret = true; for restr in loan.restrictions.iter() { - if restr.loan_path == loan_path { + if *restr.loan_path == *loan_path { if !op(loan, restr) { ret = false; break; @@ -243,7 +245,7 @@ impl<'a> CheckLoanCtxt<'a> { "it".to_owned() } else { format!("`{}`", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) }; match (new_loan.kind, old_loan.kind) { @@ -252,7 +254,7 @@ impl<'a> CheckLoanCtxt<'a> { new_loan.span, format!("cannot borrow `{}` as mutable \ more than once at a time", - self.bccx.loan_path_to_str(new_loan.loan_path))); + self.bccx.loan_path_to_str(&*new_loan.loan_path))); } (ty::UniqueImmBorrow, _) => { @@ -260,7 +262,7 @@ impl<'a> CheckLoanCtxt<'a> { new_loan.span, format!("closure requires unique access to `{}` \ but {} is already borrowed", - self.bccx.loan_path_to_str(new_loan.loan_path), + self.bccx.loan_path_to_str(&*new_loan.loan_path), old_pronoun)); } @@ -269,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> { new_loan.span, format!("cannot borrow `{}` as {} because \ previous closure requires unique access", - self.bccx.loan_path_to_str(new_loan.loan_path), + self.bccx.loan_path_to_str(&*new_loan.loan_path), new_loan.kind.to_user_str())); } @@ -278,7 +280,7 @@ impl<'a> CheckLoanCtxt<'a> { new_loan.span, format!("cannot borrow `{}` as {} because \ {} is also borrowed as {}", - self.bccx.loan_path_to_str(new_loan.loan_path), + self.bccx.loan_path_to_str(&*new_loan.loan_path), new_loan.kind.to_user_str(), old_pronoun, old_loan.kind.to_user_str())); @@ -290,7 +292,7 @@ impl<'a> CheckLoanCtxt<'a> { self.bccx.span_note( span, format!("borrow occurs due to use of `{}` in closure", - self.bccx.loan_path_to_str(new_loan.loan_path))); + self.bccx.loan_path_to_str(&*new_loan.loan_path))); } _ => { } } @@ -300,21 +302,21 @@ impl<'a> CheckLoanCtxt<'a> { format!("the mutable borrow prevents subsequent \ moves, borrows, or modification of `{0}` \ until the borrow ends", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) } ty::ImmBorrow => { format!("the immutable borrow prevents subsequent \ moves or mutable borrows of `{0}` \ until the borrow ends", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) } ty::UniqueImmBorrow => { format!("the unique capture prevents subsequent \ moves or borrows of `{0}` \ until the borrow ends", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) } }; @@ -322,12 +324,12 @@ impl<'a> CheckLoanCtxt<'a> { ClosureCapture(_) => { format!("previous borrow of `{}` occurs here due to \ use in closure", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) } AddrOf | AutoRef | RefBinding => { format!("previous borrow of `{}` occurs here", - self.bccx.loan_path_to_str(old_loan.loan_path)) + self.bccx.loan_path_to_str(&*old_loan.loan_path)) } }; @@ -356,7 +358,7 @@ impl<'a> CheckLoanCtxt<'a> { id: ast::NodeId, span: Span, use_kind: MovedValueUseKind, - lp: @LoanPath) { + lp: &Rc) { /*! * Reports an error if `expr` (which should be a path) * is using a moved/uninitialized value @@ -368,7 +370,7 @@ impl<'a> CheckLoanCtxt<'a> { self.bccx.report_use_of_moved_value( span, use_kind, - lp, + &**lp, move, moved_lp); false @@ -378,7 +380,7 @@ impl<'a> CheckLoanCtxt<'a> { pub fn check_assignment(&self, expr: &ast::Expr) { // We don't use cat_expr() here because we don't want to treat // auto-ref'd parameters in overloaded operators as rvalues. - let cmt = match self.bccx.tcx.adjustments.borrow().find_copy(&expr.id) { + let cmt = match self.bccx.tcx.adjustments.borrow().find(&expr.id) { None => self.bccx.cat_expr_unadjusted(expr), Some(adj) => self.bccx.cat_expr_autoderefd(expr, adj) }; @@ -388,10 +390,9 @@ impl<'a> CheckLoanCtxt<'a> { // Mutable values can be assigned, as long as they obey loans // and aliasing restrictions: if cmt.mutbl.is_mutable() { - if check_for_aliasable_mutable_writes(self, expr, cmt) { + if check_for_aliasable_mutable_writes(self, expr, cmt.clone()) { if check_for_assignment_to_restricted_or_frozen_location( - self, expr, cmt) - { + self, expr, cmt.clone()) { // Safe, but record for lint pass later: mark_variable_as_used_mut(self, cmt); } @@ -401,13 +402,13 @@ impl<'a> CheckLoanCtxt<'a> { // For immutable local variables, assignments are legal // if they cannot already have been assigned - if self.is_local_variable(cmt) { + if self.is_local_variable(cmt.clone()) { assert!(cmt.mutbl.is_immutable()); // no "const" locals - let lp = opt_loan_path(cmt).unwrap(); - self.move_data.each_assignment_of(expr.id, lp, |assign| { + let lp = opt_loan_path(&cmt).unwrap(); + self.move_data.each_assignment_of(expr.id, &lp, |assign| { self.bccx.report_reassigned_immutable_variable( expr.span, - lp, + &*lp, assign); false }); @@ -415,21 +416,21 @@ impl<'a> CheckLoanCtxt<'a> { } // Otherwise, just a plain error. - match opt_loan_path(cmt) { + match opt_loan_path(&cmt) { Some(lp) => { self.bccx.span_err( expr.span, format!("cannot assign to {} {} `{}`", cmt.mutbl.to_user_str(), - self.bccx.cmt_to_str(cmt), - self.bccx.loan_path_to_str(lp))); + self.bccx.cmt_to_str(&*cmt), + self.bccx.loan_path_to_str(&*lp))); } None => { self.bccx.span_err( expr.span, format!("cannot assign to {} {}", cmt.mutbl.to_user_str(), - self.bccx.cmt_to_str(cmt))); + self.bccx.cmt_to_str(&*cmt))); } } return; @@ -446,7 +447,7 @@ impl<'a> CheckLoanCtxt<'a> { loop { debug!("mark_writes_through_upvars_as_used_mut(cmt={})", cmt.repr(this.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_local(id) | mc::cat_arg(id) => { this.tcx().used_mut_nodes.borrow_mut().insert(id); return; @@ -494,10 +495,10 @@ impl<'a> CheckLoanCtxt<'a> { debug!("check_for_aliasable_mutable_writes(cmt={}, guarantor={})", cmt.repr(this.tcx()), guarantor.repr(this.tcx())); match guarantor.cat { - mc::cat_deref(b, _, mc::BorrowedPtr(ty::MutBorrow, _)) => { + mc::cat_deref(ref b, _, mc::BorrowedPtr(ty::MutBorrow, _)) => { // Statically prohibit writes to `&mut` when aliasable - check_for_aliasability_violation(this, expr, b); + check_for_aliasability_violation(this, expr, b.clone()); } _ => {} @@ -535,7 +536,7 @@ impl<'a> CheckLoanCtxt<'a> { //! Check for assignments that violate the terms of an //! outstanding loan. - let loan_path = match opt_loan_path(cmt) { + let loan_path = match opt_loan_path(&cmt) { Some(lp) => lp, None => { return true; /* no loan path, can't be any loans */ } }; @@ -571,10 +572,10 @@ impl<'a> CheckLoanCtxt<'a> { // owned pointer are borrowed, and hence while `v[*]` is not // restricted from being written, `v` is. let cont = this.each_in_scope_restriction(expr.id, - loan_path, + &*loan_path, |loan, restr| { if restr.set.intersects(RESTR_MUTATE) { - this.report_illegal_mutation(expr, loan_path, loan); + this.report_illegal_mutation(expr, &*loan_path, loan); false } else { true @@ -623,17 +624,17 @@ impl<'a> CheckLoanCtxt<'a> { // // Here the restriction that `v` not be mutated would be misapplied // to block the subpath `v[1]`. - let full_loan_path = loan_path; + let full_loan_path = loan_path.clone(); let mut loan_path = loan_path; loop { - match *loan_path { + loan_path = match *loan_path { // Peel back one layer if, for `loan_path` to be // mutable, `lp_base` must be mutable. This occurs // with inherited mutability and with `&mut` // pointers. - LpExtend(lp_base, mc::McInherited, _) | - LpExtend(lp_base, _, LpDeref(mc::BorrowedPtr(ty::MutBorrow, _))) => { - loan_path = lp_base; + LpExtend(ref lp_base, mc::McInherited, _) | + LpExtend(ref lp_base, _, LpDeref(mc::BorrowedPtr(ty::MutBorrow, _))) => { + lp_base.clone() } // Otherwise stop iterating @@ -642,12 +643,12 @@ impl<'a> CheckLoanCtxt<'a> { LpVar(_) => { return true; } - } + }; // Check for a non-const loan of `loan_path` let cont = this.each_in_scope_loan(expr.id, |loan| { if loan.loan_path == loan_path { - this.report_illegal_mutation(expr, full_loan_path, loan); + this.report_illegal_mutation(expr, &*full_loan_path, loan); false } else { true @@ -700,7 +701,7 @@ impl<'a> CheckLoanCtxt<'a> { self.bccx.span_note( loan_span, format!("borrow of `{}` occurs here", - self.bccx.loan_path_to_str(loan_path))); + self.bccx.loan_path_to_str(&*loan_path))); } } true @@ -712,13 +713,12 @@ impl<'a> CheckLoanCtxt<'a> { span: Span) { for cap_var in self.bccx.capture_map.get(&closure_id).iter() { let var_id = ast_util::def_id_of_def(cap_var.def).node; - let var_path = @LpVar(var_id); self.check_if_path_is_moved(closure_id, span, - MovedInCapture, var_path); + MovedInCapture, &Rc::new(LpVar(var_id))); match cap_var.mode { moves::CapRef | moves::CapCopy => {} moves::CapMove => { - check_by_move_capture(self, closure_id, cap_var, var_path); + check_by_move_capture(self, closure_id, cap_var, &LpVar(var_id)); } } } @@ -727,7 +727,7 @@ impl<'a> CheckLoanCtxt<'a> { fn check_by_move_capture(this: &CheckLoanCtxt, closure_id: ast::NodeId, cap_var: &moves::CaptureVar, - move_path: @LoanPath) { + move_path: &LoanPath) { let move_err = this.analyze_move_out_from(closure_id, move_path); match move_err { MoveOk => {} @@ -740,7 +740,7 @@ impl<'a> CheckLoanCtxt<'a> { this.bccx.span_note( loan_span, format!("borrow of `{}` occurs here", - this.bccx.loan_path_to_str(loan_path))); + this.bccx.loan_path_to_str(&*loan_path))); } } } @@ -748,7 +748,7 @@ impl<'a> CheckLoanCtxt<'a> { pub fn analyze_move_out_from(&self, expr_id: ast::NodeId, - mut move_path: @LoanPath) + move_path: &LoanPath) -> MoveError { debug!("analyze_move_out_from(expr_id={:?}, move_path={})", self.tcx().map.node_to_str(expr_id), @@ -756,22 +756,23 @@ impl<'a> CheckLoanCtxt<'a> { // We must check every element of a move path. See // `borrowck-move-subcomponent.rs` for a test case. - loop { - // check for a conflicting loan: - let mut ret = MoveOk; - self.each_in_scope_restriction(expr_id, move_path, |loan, _| { - // Any restriction prevents moves. - ret = MoveWhileBorrowed(loan.loan_path, loan.span); - false - }); - if ret != MoveOk { - return ret - } + // check for a conflicting loan: + let mut ret = MoveOk; + self.each_in_scope_restriction(expr_id, move_path, |loan, _| { + // Any restriction prevents moves. + ret = MoveWhileBorrowed(loan.loan_path.clone(), loan.span); + false + }); - match *move_path { - LpVar(_) => return MoveOk, - LpExtend(subpath, _, _) => move_path = subpath, + if ret != MoveOk { + return ret + } + + match *move_path { + LpVar(_) => MoveOk, + LpExtend(ref subpath, _, _) => { + self.analyze_move_out_from(expr_id, &**subpath) } } } @@ -806,14 +807,13 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>, this.check_for_conflicting_loans(expr.id); this.check_move_out_from_expr(expr); - let method_map = this.bccx.method_map.borrow(); + let method_map = this.bccx.tcx.method_map.borrow(); match expr.node { ast::ExprPath(..) => { if !this.move_data.is_assignee(expr.id) { let cmt = this.bccx.cat_expr_unadjusted(expr); debug!("path cmt={}", cmt.repr(this.tcx())); - let r = opt_loan_path(cmt); - for &lp in r.iter() { + for lp in opt_loan_path(&cmt).iter() { this.check_if_path_is_moved(expr.id, expr.span, MovedInUse, lp); } } diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index f250b105d0b..f4eee0526dd 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -23,6 +23,8 @@ use syntax::ast; use syntax::codemap::Span; use util::ppaux::Repr; +use std::rc::Rc; + struct GatherMoveInfo { id: ast::NodeId, kind: MoveKind, @@ -35,7 +37,7 @@ pub fn gather_decl(bccx: &BorrowckCtxt, decl_id: ast::NodeId, _decl_span: Span, var_id: ast::NodeId) { - let loan_path = @LpVar(var_id); + let loan_path = Rc::new(LpVar(var_id)); move_data.add_move(bccx.tcx, loan_path, decl_id, Declared); } @@ -105,7 +107,7 @@ fn gather_move(bccx: &BorrowckCtxt, move_info.id, move_info.cmt.repr(bccx.tcx)); let potentially_illegal_move = - check_and_get_illegal_move_origin(bccx, move_info.cmt); + check_and_get_illegal_move_origin(bccx, &move_info.cmt); match potentially_illegal_move { Some(illegal_move_origin) => { let error = MoveError::with_move_info(illegal_move_origin, @@ -116,7 +118,7 @@ fn gather_move(bccx: &BorrowckCtxt, None => () } - match opt_loan_path(move_info.cmt) { + match opt_loan_path(&move_info.cmt) { Some(loan_path) => { move_data.add_move(bccx.tcx, loan_path, move_info.id, move_info.kind); @@ -131,7 +133,7 @@ pub fn gather_assignment(bccx: &BorrowckCtxt, move_data: &MoveData, assignment_id: ast::NodeId, assignment_span: Span, - assignee_loan_path: @LoanPath, + assignee_loan_path: Rc, assignee_id: ast::NodeId) { move_data.add_assignment(bccx.tcx, assignee_loan_path, @@ -145,7 +147,7 @@ pub fn gather_move_and_assignment(bccx: &BorrowckCtxt, move_data: &MoveData, assignment_id: ast::NodeId, assignment_span: Span, - assignee_loan_path: @LoanPath, + assignee_loan_path: Rc, assignee_id: ast::NodeId) { move_data.add_assignment(bccx.tcx, assignee_loan_path, @@ -156,14 +158,14 @@ pub fn gather_move_and_assignment(bccx: &BorrowckCtxt, } fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, - cmt: mc::cmt) -> Option { + cmt: &mc::cmt) -> Option { match cmt.cat { mc::cat_deref(_, _, mc::BorrowedPtr(..)) | mc::cat_deref(_, _, mc::GcPtr) | mc::cat_deref(_, _, mc::UnsafePtr(..)) | mc::cat_upvar(..) | mc::cat_static_item | mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => { - Some(cmt) + Some(cmt.clone()) } // Can move out of captured upvars only if the destination closure @@ -179,12 +181,12 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, None } - mc::cat_downcast(b) | - mc::cat_interior(b, _) => { + mc::cat_downcast(ref b) | + mc::cat_interior(ref b, _) => { match ty::get(b.ty).sty { ty::ty_struct(did, _) | ty::ty_enum(did, _) => { if ty::has_dtor(bccx.tcx, did) { - Some(cmt) + Some(cmt.clone()) } else { check_and_get_illegal_move_origin(bccx, b) } @@ -195,8 +197,8 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, } } - mc::cat_deref(b, _, mc::OwnedPtr) | - mc::cat_discr(b, _) => { + mc::cat_deref(ref b, _, mc::OwnedPtr) | + mc::cat_discr(ref b, _) => { check_and_get_illegal_move_origin(bccx, b) } } diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index a04afd6d5f3..a27fe5cec22 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -39,9 +39,9 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt, cause: cause, loan_region: loan_region, loan_kind: loan_kind, - cmt_original: cmt, + cmt_original: cmt.clone(), root_scope_id: root_scope_id}; - ctxt.check(cmt, None) + ctxt.check(&cmt, None) } /////////////////////////////////////////////////////////////////////////// @@ -69,7 +69,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { self.bccx.tcx } - fn check(&self, cmt: mc::cmt, discr_scope: Option) -> R { + fn check(&self, cmt: &mc::cmt, discr_scope: Option) -> R { //! Main routine. Walks down `cmt` until we find the "guarantor". debug!("guarantee_lifetime.check(cmt={}, loan_region={})", cmt.repr(self.bccx.tcx), @@ -83,15 +83,14 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_upvar(..) | mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed mc::cat_deref(_, _, mc::UnsafePtr(..)) => { - let scope = self.scope(cmt); - self.check_scope(scope) + self.check_scope(self.scope(cmt)) } mc::cat_static_item => { Ok(()) } - mc::cat_deref(base, derefs, mc::GcPtr) => { + mc::cat_deref(ref base, derefs, mc::GcPtr) => { let base_scope = self.scope(base); // L-Deref-Managed-Imm-User-Root @@ -111,13 +110,13 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - mc::cat_downcast(base) | - mc::cat_deref(base, _, mc::OwnedPtr) | // L-Deref-Send - mc::cat_interior(base, _) => { // L-Field + mc::cat_downcast(ref base) | + mc::cat_deref(ref base, _, mc::OwnedPtr) | // L-Deref-Send + mc::cat_interior(ref base, _) => { // L-Field self.check(base, discr_scope) } - mc::cat_discr(base, new_discr_scope) => { + mc::cat_discr(ref base, new_discr_scope) => { // Subtle: in a match, we must ensure that each binding // variable remains valid for the duration of the arm in // which it appears, presuming that this arm is taken. @@ -176,7 +175,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } fn is_rvalue_or_immutable(&self, - cmt: mc::cmt) -> bool { + cmt: &mc::cmt) -> bool { //! We can omit the root on an `@T` value if the location //! that holds the box is either (1) an rvalue, in which case //! it is in a non-user-accessible temporary, or (2) an immutable @@ -189,8 +188,8 @@ impl<'a> GuaranteeLifetimeContext<'a> { } fn check_root(&self, - cmt_deref: mc::cmt, - cmt_base: mc::cmt, + cmt_deref: &mc::cmt, + cmt_base: &mc::cmt, derefs: uint, discr_scope: Option) -> R { debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, \ @@ -253,7 +252,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - fn is_moved(&self, cmt: mc::cmt) -> bool { + fn is_moved(&self, cmt: &mc::cmt) -> bool { //! True if `cmt` is something that is potentially moved //! out of the current stack frame. @@ -269,9 +268,9 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_upvar(..) => { false } - r @ mc::cat_downcast(..) | - r @ mc::cat_interior(..) | - r @ mc::cat_discr(..) => { + ref r @ mc::cat_downcast(..) | + ref r @ mc::cat_interior(..) | + ref r @ mc::cat_discr(..) => { self.tcx().sess.span_bug( cmt.span, format!("illegal guarantor category: {:?}", r)); @@ -279,7 +278,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - fn scope(&self, cmt: mc::cmt) -> ty::Region { + fn scope(&self, cmt: &mc::cmt) -> ty::Region { //! Returns the maximal region scope for the which the //! lvalue `cmt` is guaranteed to be valid without any //! rooting etc, and presuming `cmt` is not mutated. @@ -307,18 +306,18 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) => { r } - mc::cat_downcast(cmt) | - mc::cat_deref(cmt, _, mc::OwnedPtr) | - mc::cat_deref(cmt, _, mc::GcPtr) | - mc::cat_interior(cmt, _) | - mc::cat_discr(cmt, _) => { + mc::cat_downcast(ref cmt) | + mc::cat_deref(ref cmt, _, mc::OwnedPtr) | + mc::cat_deref(ref cmt, _, mc::GcPtr) | + mc::cat_interior(ref cmt, _) | + mc::cat_discr(ref cmt, _) => { self.scope(cmt) } } } fn report_error(&self, code: bckerr_code) { - self.bccx.report(BckError { cmt: self.cmt_original, + self.bccx.report(BckError { cmt: self.cmt_original.clone(), span: self.span, cause: self.cause, code: code }); diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index dd9f2eb970b..7f748dffd70 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -36,6 +36,8 @@ use syntax::visit; use syntax::visit::{Visitor, FnKind}; use syntax::ast::{Expr, FnDecl, Block, NodeId, Stmt, Pat, Local}; +use std::rc::Rc; + mod lifetime; mod restrictions; mod gather_moves; @@ -146,7 +148,7 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt, None => { // Variable declarations without initializers are considered "moves": let tcx = this.bccx.tcx; - pat_util::pat_bindings(tcx.def_map, local.pat, |_, id, span, _| { + pat_util::pat_bindings(&tcx.def_map, local.pat, |_, id, span, _| { gather_moves::gather_decl(this.bccx, &this.move_data, id, @@ -177,7 +179,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, // If this expression is borrowed, have to ensure it remains valid: for &adjustments in tcx.adjustments.borrow().find(&ex.id).iter() { - this.guarantee_adjustments(ex, *adjustments); + this.guarantee_adjustments(ex, adjustments); } // If this expression is a move, gather it: @@ -188,7 +190,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, } // Special checks for various kinds of expressions: - let method_map = this.bccx.method_map.borrow(); + let method_map = this.bccx.tcx.method_map.borrow(); match ex.node { ast::ExprAddrOf(mutbl, base) => { let base_cmt = this.bccx.cat_expr(base); @@ -228,7 +230,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, let cmt = this.bccx.cat_expr(ex_v); for arm in arms.iter() { for pat in arm.pats.iter() { - this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id))); + this.gather_pat(cmt.clone(), *pat, Some((arm.body.id, ex.id))); } } visit::walk_expr(this, ex, ()); @@ -296,9 +298,9 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, } } -fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |@LoanPath|) { +fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |Rc|) { let cmt = bccx.cat_expr(expr); - match opt_loan_path(cmt) { + match opt_loan_path(&cmt) { Some(lp) => op(lp), None => { // This can occur with e.g. `*foo() = 5`. In such @@ -375,14 +377,13 @@ impl<'a> GatherLoanCtxt<'a> { pub fn guarantee_autoderefs(&mut self, expr: &ast::Expr, autoderefs: uint) { - let method_map = self.bccx.method_map.borrow(); + let method_map = self.bccx.tcx.method_map.borrow(); for i in range(0, autoderefs) { match method_map.find(&MethodCall::autoderef(expr.id, i as u32)) { Some(method) => { // Treat overloaded autoderefs as if an AutoRef adjustment // was applied on the base type, as that is always the case. - let mut mc = self.bccx.mc(); - let cmt = match mc.cat_expr_autoderefd(expr, i) { + let cmt = match self.bccx.mc().cat_expr_autoderefd(expr, i) { Ok(v) => v, Err(()) => self.tcx().sess.span_bug(expr.span, "Err from mc") }; @@ -431,7 +432,7 @@ impl<'a> GatherLoanCtxt<'a> { autoref: Some(ref autoref), autoderefs}) => { self.guarantee_autoderefs(expr, autoderefs); - let mut mc = self.bccx.mc(); + let mc = self.bccx.mc(); let cmt = match mc.cat_expr_autoderefd(expr, autoderefs) { Ok(v) => v, Err(()) => self.tcx().sess.span_bug(expr.span, "Err from mc") @@ -551,20 +552,20 @@ impl<'a> GatherLoanCtxt<'a> { // Check that the lifetime of the borrow does not exceed // the lifetime of the data being borrowed. if lifetime::guarantee_lifetime(self.bccx, self.item_ub, root_ub, - borrow_span, cause, cmt, loan_region, + borrow_span, cause, cmt.clone(), loan_region, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of non-mutable data. if check_mutability(self.bccx, borrow_span, cause, - cmt, req_kind).is_err() { + cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of aliasable data. if check_aliasability(self.bccx, borrow_span, cause, - cmt, req_kind).is_err() { + cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } @@ -572,7 +573,7 @@ impl<'a> GatherLoanCtxt<'a> { // loan is safe. let restr = restrictions::compute_restrictions( self.bccx, borrow_span, cause, - cmt, loan_region, self.restriction_set(req_kind)); + cmt.clone(), loan_region, self.restriction_set(req_kind)); // Create the loan record (if needed). let loan = match restr { @@ -612,11 +613,11 @@ impl<'a> GatherLoanCtxt<'a> { let gen_scope = self.compute_gen_scope(borrow_id, loan_scope); debug!("gen_scope = {:?}", gen_scope); - let kill_scope = self.compute_kill_scope(loan_scope, loan_path); + let kill_scope = self.compute_kill_scope(loan_scope, &*loan_path); debug!("kill_scope = {:?}", kill_scope); if req_kind == ty::MutBorrow { - self.mark_loan_path_as_mutated(loan_path); + self.mark_loan_path_as_mutated(&*loan_path); } Loan { @@ -718,7 +719,7 @@ impl<'a> GatherLoanCtxt<'a> { } } - pub fn mark_loan_path_as_mutated(&self, loan_path: @LoanPath) { + pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) { //! For mutable loans of content whose mutability derives //! from a local variable, mark the mutability decl as necessary. @@ -726,8 +727,8 @@ impl<'a> GatherLoanCtxt<'a> { LpVar(local_id) => { self.tcx().used_mut_nodes.borrow_mut().insert(local_id); } - LpExtend(base, mc::McInherited, _) => { - self.mark_loan_path_as_mutated(base); + LpExtend(ref base, mc::McInherited, _) => { + self.mark_loan_path_as_mutated(&**base); } LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McImmutable, _) => { @@ -752,7 +753,7 @@ impl<'a> GatherLoanCtxt<'a> { } } - pub fn compute_kill_scope(&self, loan_scope: ast::NodeId, lp: @LoanPath) + pub fn compute_kill_scope(&self, loan_scope: ast::NodeId, lp: &LoanPath) -> ast::NodeId { //! Determine when the loan restrictions go out of scope. //! This is either when the lifetime expires or when the @@ -793,7 +794,7 @@ impl<'a> GatherLoanCtxt<'a> { * `gather_pat()`. */ - let mut mc = self.bccx.mc(); + let mc = self.bccx.mc(); for arg in decl.inputs.iter() { let arg_ty = ty::node_id_to_type(self.tcx(), arg.pat.id); @@ -822,12 +823,12 @@ impl<'a> GatherLoanCtxt<'a> { ast::PatIdent(bm, _, _) if self.pat_is_binding(pat) => { // Each match binding is effectively an assignment. let tcx = self.bccx.tcx; - pat_util::pat_bindings(tcx.def_map, pat, |_, id, span, _| { + pat_util::pat_bindings(&tcx.def_map, pat, |_, id, span, _| { gather_moves::gather_assignment(self.bccx, &self.move_data, id, span, - @LpVar(id), + Rc::new(LpVar(id)), id); }); @@ -920,7 +921,7 @@ impl<'a> GatherLoanCtxt<'a> { } pub fn pat_is_binding(&self, pat: &ast::Pat) -> bool { - pat_util::pat_is_binding(self.bccx.tcx.def_map, pat) + pat_util::pat_is_binding(&self.bccx.tcx.def_map, pat) } pub fn report_potential_errors(&self) { diff --git a/src/librustc/middle/borrowck/gather_loans/move_error.rs b/src/librustc/middle/borrowck/gather_loans/move_error.rs index c9a8df0f535..24d873e0ff7 100644 --- a/src/librustc/middle/borrowck/gather_loans/move_error.rs +++ b/src/librustc/middle/borrowck/gather_loans/move_error.rs @@ -79,7 +79,7 @@ pub struct GroupedMoveErrors { fn report_move_errors(bccx: &BorrowckCtxt, errors: &Vec) { let grouped_errors = group_errors_with_same_origin(errors); for error in grouped_errors.iter() { - report_cannot_move_out_of(bccx, error.move_from); + report_cannot_move_out_of(bccx, error.move_from.clone()); let mut is_first_note = true; for move_to in error.move_to_places.iter() { note_move_destination(bccx, move_to.span, @@ -112,7 +112,7 @@ fn group_errors_with_same_origin(errors: &Vec) } } grouped_errors.push(GroupedMoveErrors { - move_from: error.move_from, + move_from: error.move_from.clone(), move_to_places: move_to }) } @@ -128,11 +128,11 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) { bccx.span_err( move_from.span, format!("cannot move out of {}", - bccx.cmt_to_str(move_from))); + bccx.cmt_to_str(&*move_from))); } - mc::cat_downcast(b) | - mc::cat_interior(b, _) => { + mc::cat_downcast(ref b) | + mc::cat_interior(ref b, _) => { match ty::get(b.ty).sty { ty::ty_struct(did, _) | ty::ty_enum(did, _) if ty::has_dtor(bccx.tcx, did) => { diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index 39ea9e17b26..de4ce84fb0a 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -18,9 +18,11 @@ use middle::ty; use syntax::codemap::Span; use util::ppaux::Repr; +use std::rc::Rc; + pub enum RestrictionResult { Safe, - SafeIf(@LoanPath, Vec ) + SafeIf(Rc, Vec) } pub fn compute_restrictions(bccx: &BorrowckCtxt, @@ -33,7 +35,7 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt, bccx: bccx, span: span, cause: cause, - cmt_original: cmt, + cmt_original: cmt.clone(), loan_region: loan_region, }; @@ -59,7 +61,7 @@ impl<'a> RestrictionsContext<'a> { cmt.repr(self.bccx.tcx), restrictions.repr(self.bccx.tcx)); - match cmt.cat { + match cmt.cat.clone() { mc::cat_rvalue(..) => { // Effectively, rvalues are stored into a // non-aliasable temporary on the stack. Since they @@ -73,9 +75,11 @@ impl<'a> RestrictionsContext<'a> { mc::cat_arg(local_id) | mc::cat_upvar(ty::UpvarId {var_id: local_id, ..}, _) => { // R-Variable - let lp = @LpVar(local_id); - SafeIf(lp, vec!(Restriction {loan_path: lp, - set: restrictions})) + let lp = Rc::new(LpVar(local_id)); + SafeIf(lp.clone(), vec!(Restriction { + loan_path: lp, + set: restrictions + })) } mc::cat_downcast(cmt_base) => { @@ -170,9 +174,13 @@ impl<'a> RestrictionsContext<'a> { restrictions: RestrictionSet) -> RestrictionResult { match result { Safe => Safe, - SafeIf(base_lp, base_vec) => { - let lp = @LpExtend(base_lp, mc, elem); - SafeIf(lp, base_vec.append_one(Restriction { loan_path: lp, set: restrictions })) + SafeIf(base_lp, mut base_vec) => { + let lp = Rc::new(LpExtend(base_lp, mc, elem)); + base_vec.push(Restriction { + loan_path: lp.clone(), + set: restrictions + }); + SafeIf(lp, base_vec) } } } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 21e68e2724f..06491d36b02 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -18,14 +18,14 @@ use middle::typeck; use middle::moves; use middle::dataflow::DataFlowContext; use middle::dataflow::DataFlowOperator; -use util::nodemap::NodeSet; +use util::nodemap::{NodeMap, NodeSet}; use util::ppaux::{note_and_explain_region, Repr, UserString}; -use std::cell::{Cell, RefCell}; -use collections::HashMap; +use std::cell::RefCell; use std::ops::{BitOr, BitAnd}; -use std::result::Result; +use std::rc::Rc; use std::strbuf::StrBuf; +use collections::HashMap; use syntax::ast; use syntax::ast_map; use syntax::ast_util; @@ -76,7 +76,6 @@ impl<'a> Visitor<()> for BorrowckCtxt<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: typeck::MethodMap, moves_map: &NodeSet, moved_variables_set: &NodeSet, capture_map: &moves::CaptureMap, @@ -84,41 +83,15 @@ pub fn check_crate(tcx: &ty::ctxt, -> root_map { let mut bccx = BorrowckCtxt { tcx: tcx, - method_map: method_map, moves_map: moves_map, moved_variables_set: moved_variables_set, capture_map: capture_map, - root_map: root_map(), - stats: @BorrowStats { - loaned_paths_same: Cell::new(0), - loaned_paths_imm: Cell::new(0), - stable_paths: Cell::new(0), - guaranteed_paths: Cell::new(0), - } + root_map: RefCell::new(HashMap::new()) }; - let bccx = &mut bccx; - visit::walk_crate(bccx, krate, ()); + visit::walk_crate(&mut bccx, krate, ()); - if tcx.sess.borrowck_stats() { - println!("--- borrowck stats ---"); - println!("paths requiring guarantees: {}", - bccx.stats.guaranteed_paths.get()); - println!("paths requiring loans : {}", - make_stat(bccx, bccx.stats.loaned_paths_same.get())); - println!("paths requiring imm loans : {}", - make_stat(bccx, bccx.stats.loaned_paths_imm.get())); - println!("stable paths : {}", - make_stat(bccx, bccx.stats.stable_paths.get())); - } - - return bccx.root_map; - - fn make_stat(bccx: &mut BorrowckCtxt, stat: uint) -> ~str { - let stat_f = stat as f64; - let total = bccx.stats.guaranteed_paths.get() as f64; - format!("{} ({:.0f}%)", stat , stat_f * 100.0 / total) - } + return bccx.root_map.unwrap(); } fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) { @@ -149,7 +122,6 @@ fn borrowck_fn(this: &mut BorrowckCtxt, gather_loans::gather_loans_in_fn(this, decl, body); let mut loan_dfcx = DataFlowContext::new(this.tcx, - this.method_map, LoanDataFlowOperator, id_range, all_loans.len()); @@ -161,7 +133,6 @@ fn borrowck_fn(this: &mut BorrowckCtxt, let flowed_moves = move_data::FlowedMoveData::new(move_data, this.tcx, - this.method_map, id_range, body); @@ -176,21 +147,10 @@ fn borrowck_fn(this: &mut BorrowckCtxt, pub struct BorrowckCtxt<'a> { tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, moves_map: &'a NodeSet, moved_variables_set: &'a NodeSet, capture_map: &'a moves::CaptureMap, - root_map: root_map, - - // Statistics: - stats: @BorrowStats -} - -pub struct BorrowStats { - loaned_paths_same: Cell, - loaned_paths_imm: Cell, - stable_paths: Cell, - guaranteed_paths: Cell, + root_map: RefCell, } // The keys to the root map combine the `id` of the deref expression @@ -226,10 +186,10 @@ pub enum PartialTotal { /// Record of a loan that was issued. pub struct Loan { index: uint, - loan_path: @LoanPath, + loan_path: Rc, cmt: mc::cmt, kind: ty::BorrowKind, - restrictions: Vec , + restrictions: Vec, gen_scope: ast::NodeId, kill_scope: ast::NodeId, span: Span, @@ -247,7 +207,7 @@ pub enum LoanCause { #[deriving(Eq, TotalEq, Hash)] pub enum LoanPath { LpVar(ast::NodeId), // `x` in doc.rs - LpExtend(@LoanPath, mc::MutabilityCategory, LoanPathElem) + LpExtend(Rc, mc::MutabilityCategory, LoanPathElem) } #[deriving(Eq, TotalEq, Hash)] @@ -260,12 +220,12 @@ impl LoanPath { pub fn node_id(&self) -> ast::NodeId { match *self { LpVar(local_id) => local_id, - LpExtend(base, _, _) => base.node_id() + LpExtend(ref base, _, _) => base.node_id() } } } -pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> { +pub fn opt_loan_path(cmt: &mc::cmt) -> Option> { //! Computes the `LoanPath` (if any) for a `cmt`. //! Note that this logic is somewhat duplicated in //! the method `compute()` found in `gather_loans::restrictions`, @@ -283,23 +243,23 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> { mc::cat_arg(id) | mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) | mc::cat_upvar(ty::UpvarId {var_id: id, ..}, _) => { - Some(@LpVar(id)) + Some(Rc::new(LpVar(id))) } - mc::cat_deref(cmt_base, _, pk) => { + mc::cat_deref(ref cmt_base, _, pk) => { opt_loan_path(cmt_base).map(|lp| { - @LpExtend(lp, cmt.mutbl, LpDeref(pk)) + Rc::new(LpExtend(lp, cmt.mutbl, LpDeref(pk))) }) } - mc::cat_interior(cmt_base, ik) => { + mc::cat_interior(ref cmt_base, ik) => { opt_loan_path(cmt_base).map(|lp| { - @LpExtend(lp, cmt.mutbl, LpInterior(ik)) + Rc::new(LpExtend(lp, cmt.mutbl, LpInterior(ik))) }) } - mc::cat_downcast(cmt_base) | - mc::cat_discr(cmt_base, _) => { + mc::cat_downcast(ref cmt_base) | + mc::cat_discr(ref cmt_base, _) => { opt_loan_path(cmt_base) } } @@ -319,7 +279,7 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> { // because the restriction against moves is implied. pub struct Restriction { - loan_path: @LoanPath, + loan_path: Rc, set: RestrictionSet } @@ -380,11 +340,7 @@ pub struct RootInfo { pub scope: ast::NodeId, } -pub type root_map = @RefCell>; - -pub fn root_map() -> root_map { - return @RefCell::new(HashMap::new()); -} +pub type root_map = HashMap; /////////////////////////////////////////////////////////////////////////// // Errors @@ -437,12 +393,9 @@ impl<'a> BorrowckCtxt<'a> { self.moves_map.contains(&id) } - pub fn mc(&self) -> mc::MemCategorizationContext> { + pub fn mc(&self) -> mc::MemCategorizationContext<&'a ty::ctxt> { mc::MemCategorizationContext { - typer: TcxTyper { - tcx: self.tcx, - method_map: self.method_map - } + typer: self.tcx, } } @@ -516,14 +469,16 @@ impl<'a> BorrowckCtxt<'a> { } pub fn cat_discr(&self, cmt: mc::cmt, match_id: ast::NodeId) -> mc::cmt { - @mc::cmt_ {cat:mc::cat_discr(cmt, match_id), - mutbl:cmt.mutbl.inherit(), - ..*cmt} + Rc::new(mc::cmt_ { + cat: mc::cat_discr(cmt.clone(), match_id), + mutbl: cmt.mutbl.inherit(), + ..*cmt + }) } pub fn cat_pattern(&self, cmt: mc::cmt, - pat: @ast::Pat, + pat: &ast::Pat, op: |mc::cmt, &ast::Pat|) { let r = self.mc().cat_pattern(cmt, pat, |_,x,y| op(x,y)); assert!(r.is_ok()); @@ -532,7 +487,7 @@ impl<'a> BorrowckCtxt<'a> { pub fn report(&self, err: BckError) { self.span_err( err.span, - self.bckerr_to_str(err)); + self.bckerr_to_str(&err)); self.note_and_explain_bckerr(err); } @@ -541,7 +496,7 @@ impl<'a> BorrowckCtxt<'a> { use_kind: MovedValueUseKind, lp: &LoanPath, move: &move_data::Move, - moved_lp: @LoanPath) { + moved_lp: &LoanPath) { let verb = match use_kind { MovedInUse => "use", MovedInCapture => "capture", @@ -572,8 +527,7 @@ impl<'a> BorrowckCtxt<'a> { move_data::MoveExpr => { let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { Some(ast_map::NodeExpr(expr)) => { - (ty::expr_ty_adjusted(self.tcx, expr, - &*self.method_map.borrow()), expr.span) + (ty::expr_ty_adjusted(self.tcx, expr), expr.span) } r => self.tcx.sess.bug(format!("MoveExpr({:?}) maps to {:?}, not Expr", move.id, r)) @@ -599,8 +553,7 @@ impl<'a> BorrowckCtxt<'a> { move_data::Captured => { let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { Some(ast_map::NodeExpr(expr)) => { - (ty::expr_ty_adjusted(self.tcx, expr, - &*self.method_map.borrow()), expr.span) + (ty::expr_ty_adjusted(self.tcx, expr), expr.span) } r => self.tcx.sess.bug(format!("Captured({:?}) maps to {:?}, not Expr", move.id, r)) @@ -656,17 +609,17 @@ impl<'a> BorrowckCtxt<'a> { self.tcx.sess.span_end_note(s, m); } - pub fn bckerr_to_str(&self, err: BckError) -> ~str { + pub fn bckerr_to_str(&self, err: &BckError) -> ~str { match err.code { err_mutbl => { - let descr = match opt_loan_path(err.cmt) { + let descr = match opt_loan_path(&err.cmt) { None => format!("{} {}", err.cmt.mutbl.to_user_str(), - self.cmt_to_str(err.cmt)), + self.cmt_to_str(&*err.cmt)), Some(lp) => format!("{} {} `{}`", err.cmt.mutbl.to_user_str(), - self.cmt_to_str(err.cmt), - self.loan_path_to_str(lp)), + self.cmt_to_str(&*err.cmt), + self.loan_path_to_str(&*lp)), }; match err.cause { @@ -682,16 +635,16 @@ impl<'a> BorrowckCtxt<'a> { format!("cannot root managed value long enough") } err_out_of_scope(..) => { - let msg = match opt_loan_path(err.cmt) { + let msg = match opt_loan_path(&err.cmt) { None => format!("borrowed value"), - Some(lp) => format!("`{}`", self.loan_path_to_str(lp)), + Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), }; format!("{} does not live long enough", msg) } err_borrowed_pointer_too_short(..) => { - let descr = match opt_loan_path(err.cmt) { - Some(lp) => format!("`{}`", self.loan_path_to_str(lp)), - None => self.cmt_to_str(err.cmt), + let descr = match opt_loan_path(&err.cmt) { + Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), + None => self.cmt_to_str(&*err.cmt), }; format!("lifetime of {} is too short to guarantee \ @@ -783,9 +736,9 @@ impl<'a> BorrowckCtxt<'a> { } err_borrowed_pointer_too_short(loan_scope, ptr_scope, _) => { - let descr = match opt_loan_path(err.cmt) { - Some(lp) => format!("`{}`", self.loan_path_to_str(lp)), - None => self.cmt_to_str(err.cmt), + let descr = match opt_loan_path(&err.cmt) { + Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), + None => self.cmt_to_str(&*err.cmt), }; note_and_explain_region( self.tcx, @@ -809,8 +762,8 @@ impl<'a> BorrowckCtxt<'a> { out.push_str(ty::local_var_name_str(self.tcx, id).get()); } - LpExtend(lp_base, _, LpInterior(mc::InteriorField(fname))) => { - self.append_autoderefd_loan_path_to_str(lp_base, out); + LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => { + self.append_autoderefd_loan_path_to_str(&**lp_base, out); match fname { mc::NamedField(fname) => { out.push_char('.'); @@ -823,14 +776,14 @@ impl<'a> BorrowckCtxt<'a> { } } - LpExtend(lp_base, _, LpInterior(mc::InteriorElement(_))) => { - self.append_autoderefd_loan_path_to_str(lp_base, out); + LpExtend(ref lp_base, _, LpInterior(mc::InteriorElement(_))) => { + self.append_autoderefd_loan_path_to_str(&**lp_base, out); out.push_str("[..]"); } - LpExtend(lp_base, _, LpDeref(_)) => { + LpExtend(ref lp_base, _, LpDeref(_)) => { out.push_char('*'); - self.append_loan_path_to_str(lp_base, out); + self.append_loan_path_to_str(&**lp_base, out); } } } @@ -839,11 +792,11 @@ impl<'a> BorrowckCtxt<'a> { loan_path: &LoanPath, out: &mut StrBuf) { match *loan_path { - LpExtend(lp_base, _, LpDeref(_)) => { + LpExtend(ref lp_base, _, LpDeref(_)) => { // For a path like `(*x).f` or `(*x)[3]`, autoderef // rules would normally allow users to omit the `*x`. // So just serialize such paths to `x.f` or x[3]` respectively. - self.append_autoderefd_loan_path_to_str(lp_base, out) + self.append_autoderefd_loan_path_to_str(&**lp_base, out) } LpVar(..) | LpExtend(_, _, LpInterior(..)) => { @@ -858,7 +811,7 @@ impl<'a> BorrowckCtxt<'a> { result.into_owned() } - pub fn cmt_to_str(&self, cmt: mc::cmt) -> ~str { + pub fn cmt_to_str(&self, cmt: &mc::cmt_) -> ~str { self.mc().cmt_to_str(cmt) } } @@ -902,11 +855,11 @@ impl Repr for LoanPath { format!("$({})", tcx.map.node_to_str(id)) } - &LpExtend(lp, _, LpDeref(_)) => { + &LpExtend(ref lp, _, LpDeref(_)) => { format!("{}.*", lp.repr(tcx)) } - &LpExtend(lp, _, LpInterior(ref interior)) => { + &LpExtend(ref lp, _, LpInterior(ref interior)) => { format!("{}.{}", lp.repr(tcx), interior.repr(tcx)) } } @@ -915,37 +868,32 @@ impl Repr for LoanPath { /////////////////////////////////////////////////////////////////////////// -pub struct TcxTyper<'a> { - tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, -} - -impl<'a> mc::Typer for TcxTyper<'a> { +impl<'a> mc::Typer for &'a ty::ctxt { fn tcx<'a>(&'a self) -> &'a ty::ctxt { - self.tcx + *self } - fn node_ty(&mut self, id: ast::NodeId) -> mc::McResult { - Ok(ty::node_id_to_type(self.tcx, id)) + fn node_ty(&self, id: ast::NodeId) -> mc::McResult { + Ok(ty::node_id_to_type(*self, id)) } fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option { self.method_map.borrow().find(&method_call).map(|method| method.ty) } - fn adjustment(&mut self, id: ast::NodeId) -> Option<@ty::AutoAdjustment> { - self.tcx.adjustments.borrow().find_copy(&id) + fn adjustments<'a>(&'a self) -> &'a RefCell> { + &self.adjustments } - fn is_method_call(&mut self, id: ast::NodeId) -> bool { + fn is_method_call(&self, id: ast::NodeId) -> bool { self.method_map.borrow().contains_key(&typeck::MethodCall::expr(id)) } - fn temporary_scope(&mut self, id: ast::NodeId) -> Option { - self.tcx.region_maps.temporary_scope(id) + fn temporary_scope(&self, id: ast::NodeId) -> Option { + self.region_maps.temporary_scope(id) } - fn upvar_borrow(&mut self, id: ty::UpvarId) -> ty::UpvarBorrow { - self.tcx.upvar_borrow_map.borrow().get_copy(&id) + fn upvar_borrow(&self, id: ty::UpvarId) -> ty::UpvarBorrow { + self.upvar_borrow_map.borrow().get_copy(&id) } } diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 0e18946a3a1..efdc103d14d 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -16,13 +16,13 @@ comments in the section "Moves and initialization" and in `doc.rs`. */ use std::cell::RefCell; +use std::rc::Rc; use std::uint; use collections::{HashMap, HashSet}; use middle::borrowck::*; use middle::dataflow::DataFlowContext; use middle::dataflow::DataFlowOperator; use middle::ty; -use middle::typeck; use syntax::ast; use syntax::ast_util; use syntax::codemap::Span; @@ -33,7 +33,7 @@ pub struct MoveData { pub paths: RefCell>, /// Cache of loan path to move path index, for easy lookup. - pub path_map: RefCell>, + pub path_map: RefCell, MovePathIndex>>, /// Each move or uninitialized variable gets an entry here. pub moves: RefCell>, @@ -97,7 +97,7 @@ static InvalidMoveIndex: MoveIndex = pub struct MovePath { /// Loan path corresponding to this move path - pub loan_path: @LoanPath, + pub loan_path: Rc, /// Parent pointer, `InvalidMovePathIndex` if root pub parent: MovePathIndex, @@ -182,8 +182,8 @@ impl MoveData { } } - fn path_loan_path(&self, index: MovePathIndex) -> @LoanPath { - self.paths.borrow().get(index.get()).loan_path + fn path_loan_path(&self, index: MovePathIndex) -> Rc { + self.paths.borrow().get(index.get()).loan_path.clone() } fn path_parent(&self, index: MovePathIndex) -> MovePathIndex { @@ -226,7 +226,7 @@ impl MoveData { pub fn move_path(&self, tcx: &ty::ctxt, - lp: @LoanPath) -> MovePathIndex { + lp: Rc) -> MovePathIndex { /*! * Returns the existing move path index for `lp`, if any, * and otherwise adds a new index for `lp` and any of its @@ -245,7 +245,7 @@ impl MoveData { let index = MovePathIndex(self.paths.borrow().len()); self.paths.borrow_mut().push(MovePath { - loan_path: lp, + loan_path: lp.clone(), parent: InvalidMovePathIndex, first_move: InvalidMoveIndex, first_child: InvalidMovePathIndex, @@ -255,8 +255,8 @@ impl MoveData { index } - LpExtend(base, _, _) => { - let parent_index = self.move_path(tcx, base); + LpExtend(ref base, _, _) => { + let parent_index = self.move_path(tcx, base.clone()); let index = MovePathIndex(self.paths.borrow().len()); @@ -264,7 +264,7 @@ impl MoveData { self.set_path_first_child(parent_index, index); self.paths.borrow_mut().push(MovePath { - loan_path: lp, + loan_path: lp.clone(), parent: parent_index, first_move: InvalidMoveIndex, first_child: InvalidMovePathIndex, @@ -284,29 +284,26 @@ impl MoveData { return index; } - fn existing_move_path(&self, - lp: @LoanPath) + fn existing_move_path(&self, lp: &Rc) -> Option { - self.path_map.borrow().find_copy(&lp) + self.path_map.borrow().find_copy(lp) } - fn existing_base_paths(&self, - lp: @LoanPath) + fn existing_base_paths(&self, lp: &Rc) -> Vec { let mut result = vec!(); self.add_existing_base_paths(lp, &mut result); result } - fn add_existing_base_paths(&self, - lp: @LoanPath, + fn add_existing_base_paths(&self, lp: &Rc, result: &mut Vec) { /*! * Adds any existing move path indices for `lp` and any base * paths of `lp` to `result`, but does not add new move paths */ - match self.path_map.borrow().find_copy(&lp) { + match self.path_map.borrow().find_copy(lp) { Some(index) => { self.each_base_path(index, |p| { result.push(p); @@ -314,9 +311,9 @@ impl MoveData { }); } None => { - match *lp { + match **lp { LpVar(..) => { } - LpExtend(b, _, _) => { + LpExtend(ref b, _, _) => { self.add_existing_base_paths(b, result); } } @@ -327,7 +324,7 @@ impl MoveData { pub fn add_move(&self, tcx: &ty::ctxt, - lp: @LoanPath, + lp: Rc, id: ast::NodeId, kind: MoveKind) { /*! @@ -356,7 +353,7 @@ impl MoveData { pub fn add_assignment(&self, tcx: &ty::ctxt, - lp: @LoanPath, + lp: Rc, assign_id: ast::NodeId, span: Span, assignee_id: ast::NodeId, @@ -369,7 +366,7 @@ impl MoveData { debug!("add_assignment(lp={}, assign_id={:?}, assignee_id={:?}", lp.repr(tcx), assign_id, assignee_id); - let path_index = self.move_path(tcx, lp); + let path_index = self.move_path(tcx, lp.clone()); if !is_also_move { self.assignee_ids.borrow_mut().insert(assignee_id); @@ -511,19 +508,16 @@ impl MoveData { impl<'a> FlowedMoveData<'a> { pub fn new(move_data: MoveData, tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, id_range: ast_util::IdRange, body: &ast::Block) -> FlowedMoveData<'a> { let mut dfcx_moves = DataFlowContext::new(tcx, - method_map, MoveDataFlowOperator, id_range, move_data.moves.borrow().len()); let mut dfcx_assign = DataFlowContext::new(tcx, - method_map, AssignDataFlowOperator, id_range, move_data.var_assignments.borrow().len()); @@ -539,7 +533,7 @@ impl<'a> FlowedMoveData<'a> { pub fn each_path_moved_by(&self, id: ast::NodeId, - f: |&Move, @LoanPath| -> bool) + f: |&Move, &LoanPath| -> bool) -> bool { /*! * Iterates through each path moved by `id` @@ -549,14 +543,14 @@ impl<'a> FlowedMoveData<'a> { let move = self.move_data.moves.borrow(); let move = move.get(index); let moved_path = move.path; - f(move, self.move_data.path_loan_path(moved_path)) + f(move, &*self.move_data.path_loan_path(moved_path)) }) } pub fn each_move_of(&self, id: ast::NodeId, - loan_path: @LoanPath, - f: |&Move, @LoanPath| -> bool) + loan_path: &Rc, + f: |&Move, &LoanPath| -> bool) -> bool { /*! * Iterates through each move of `loan_path` (or some base path @@ -591,7 +585,7 @@ impl<'a> FlowedMoveData<'a> { if base_indices.iter().any(|x| x == &moved_path) { // Scenario 1 or 2: `loan_path` or some base path of // `loan_path` was moved. - if !f(move, self.move_data.path_loan_path(moved_path)) { + if !f(move, &*self.move_data.path_loan_path(moved_path)) { ret = false; } } else { @@ -600,7 +594,7 @@ impl<'a> FlowedMoveData<'a> { if p == loan_path_index { // Scenario 3: some extension of `loan_path` // was moved - f(move, self.move_data.path_loan_path(moved_path)) + f(move, &*self.move_data.path_loan_path(moved_path)) } else { true } @@ -621,7 +615,7 @@ impl<'a> FlowedMoveData<'a> { pub fn each_assignment_of(&self, id: ast::NodeId, - loan_path: @LoanPath, + loan_path: &Rc, f: |&Assignment| -> bool) -> bool { /*! diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 67f3b8fe906..eb52aa18de8 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -21,8 +21,6 @@ use syntax::visit::Visitor; use syntax::visit; pub struct CheckCrateVisitor<'a> { - def_map: resolve::DefMap, - method_map: typeck::MethodMap, tcx: &'a ty::ctxt, } @@ -38,16 +36,8 @@ impl<'a> Visitor for CheckCrateVisitor<'a> { } } -pub fn check_crate(krate: &Crate, - def_map: resolve::DefMap, - method_map: typeck::MethodMap, - tcx: &ty::ctxt) { - let mut v = CheckCrateVisitor { - def_map: def_map, - method_map: method_map, - tcx: tcx, - }; - visit::walk_crate(&mut v, krate, false); +pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) { + visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx }, krate, false); tcx.sess.abort_if_errors(); } @@ -55,7 +45,7 @@ fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) { match it.node { ItemStatic(_, _, ex) => { v.visit_expr(ex, true); - check_item_recursion(&v.tcx.sess, &v.tcx.map, v.def_map, it); + check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it); } ItemEnum(ref enum_definition, _) => { for var in (*enum_definition).variants.iter() { @@ -103,7 +93,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) { ExprLit(lit) if ast_util::lit_is_str(lit) => {} ExprBinary(..) | ExprUnary(..) => { let method_call = typeck::MethodCall::expr(e.id); - if v.method_map.borrow().contains_key(&method_call) { + if v.tcx.method_map.borrow().contains_key(&method_call) { v.tcx.sess.span_err(e.span, "user-defined operators are not \ allowed in constant expressions"); } @@ -127,7 +117,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) { "paths in constants may only refer to \ items without type parameters"); } - match v.def_map.borrow().find(&e.id) { + match v.tcx.def_map.borrow().find(&e.id) { Some(&DefStatic(..)) | Some(&DefFn(_, _)) | Some(&DefVariant(_, _, _)) | @@ -145,7 +135,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) { } } ExprCall(callee, _) => { - match v.def_map.borrow().find(&callee.id) { + match v.tcx.def_map.borrow().find(&callee.id) { Some(&DefStruct(..)) => {} // OK. Some(&DefVariant(..)) => {} // OK. _ => { @@ -188,14 +178,14 @@ struct CheckItemRecursionVisitor<'a> { root_it: &'a Item, sess: &'a Session, ast_map: &'a ast_map::Map, - def_map: resolve::DefMap, + def_map: &'a resolve::DefMap, idstack: Vec } // Make sure a const item doesn't recursively refer to itself // FIXME: Should use the dependency graph when it's available (#1356) pub fn check_item_recursion<'a>(sess: &'a Session, ast_map: &'a ast_map::Map, - def_map: resolve::DefMap, + def_map: &'a resolve::DefMap, it: &'a Item) { let mut visitor = CheckItemRecursionVisitor { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index db1badb7d59..2ef009e36e4 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -15,7 +15,6 @@ use middle::const_eval::{eval_const_expr, const_val, const_bool, const_float}; use middle::pat_util::*; use middle::ty::*; use middle::ty; -use middle::typeck::MethodMap; use util::nodemap::NodeSet; use util::ppaux::ty_to_str; @@ -30,7 +29,6 @@ use syntax::visit::{Visitor, FnKind}; struct MatchCheckCtxt<'a> { tcx: &'a ty::ctxt, - method_map: MethodMap, moves_map: &'a NodeSet } @@ -47,12 +45,10 @@ impl<'a> Visitor<()> for MatchCheckCtxt<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: MethodMap, moves_map: &NodeSet, krate: &Crate) { let mut cx = MatchCheckCtxt { tcx: tcx, - method_map: method_map, moves_map: moves_map }; @@ -938,7 +934,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, has_guard: bool, pats: &[@Pat]) { let tcx = cx.tcx; - let def_map = tcx.def_map; + let def_map = &tcx.def_map; let mut by_ref_span = None; let mut any_by_move = false; for pat in pats.iter() { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index d39f0721b42..cd3ab100e55 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -15,7 +15,7 @@ use middle::astencode; use middle::ty; use middle::typeck::astconv; -use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; +use util::nodemap::{DefIdMap, NodeMap}; use syntax::ast::*; use syntax::parse::token::InternedString; @@ -127,9 +127,7 @@ pub fn lookup_variant_by_id(tcx: &ty::ctxt, None => {} } let maps = astencode::Maps { - root_map: @RefCell::new(HashMap::new()), - method_map: @RefCell::new(FnvHashMap::new()), - vtable_map: @RefCell::new(FnvHashMap::new()), + root_map: HashMap::new(), capture_map: RefCell::new(NodeMap::new()) }; let e = match csearch::maybe_get_item_ast(tcx, enum_def, @@ -168,9 +166,7 @@ pub fn lookup_const_by_id(tcx: &ty::ctxt, def_id: ast::DefId) None => {} } let maps = astencode::Maps { - root_map: @RefCell::new(HashMap::new()), - method_map: @RefCell::new(FnvHashMap::new()), - vtable_map: @RefCell::new(FnvHashMap::new()), + root_map: HashMap::new(), capture_map: RefCell::new(NodeMap::new()) }; let e = match csearch::maybe_get_item_ast(tcx, def_id, diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 2b79917f9d5..742daa82ecd 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -32,7 +32,6 @@ use util::nodemap::NodeMap; #[deriving(Clone)] pub struct DataFlowContext<'a, O> { tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, /// the data flow operator oper: O, @@ -123,7 +122,6 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> { impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> { pub fn new(tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, oper: O, id_range: IdRange, bits_per_id: uint) -> DataFlowContext<'a, O> { @@ -138,7 +136,6 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> { DataFlowContext { tcx: tcx, - method_map: method_map, words_per_id: words_per_id, nodeid_to_bitset: NodeMap::new(), bits_per_id: bits_per_id, @@ -784,7 +781,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> { fn is_method_call(&self, expr: &ast::Expr) -> bool { let method_call = typeck::MethodCall::expr(expr.id); - self.dfcx.method_map.borrow().contains_key(&method_call) + self.dfcx.tcx.method_map.borrow().contains_key(&method_call) } fn reset(&mut self, bits: &mut [uint]) { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 413c6a4de1d..74355357fe7 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -50,18 +50,15 @@ fn should_explore(tcx: &ty::ctxt, def_id: ast::DefId) -> bool { struct MarkSymbolVisitor<'a> { worklist: Vec, - method_map: typeck::MethodMap, tcx: &'a ty::ctxt, live_symbols: ~HashSet, } impl<'a> MarkSymbolVisitor<'a> { fn new(tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, worklist: Vec) -> MarkSymbolVisitor<'a> { MarkSymbolVisitor { worklist: worklist, - method_map: method_map, tcx: tcx, live_symbols: ~HashSet::new(), } @@ -93,7 +90,7 @@ impl<'a> MarkSymbolVisitor<'a> { fn lookup_and_handle_method(&mut self, id: ast::NodeId, span: codemap::Span) { let method_call = typeck::MethodCall::expr(id); - match self.method_map.borrow().find(&method_call) { + match self.tcx.method_map.borrow().find(&method_call) { Some(method) => { match method.origin { typeck::MethodStatic(def_id) => { @@ -285,14 +282,13 @@ fn create_and_seed_worklist(tcx: &ty::ctxt, } fn find_live(tcx: &ty::ctxt, - method_map: typeck::MethodMap, exported_items: &privacy::ExportedItems, reachable_symbols: &NodeSet, krate: &ast::Crate) -> ~HashSet { let worklist = create_and_seed_worklist(tcx, exported_items, reachable_symbols, krate); - let mut symbol_visitor = MarkSymbolVisitor::new(tcx, method_map, worklist); + let mut symbol_visitor = MarkSymbolVisitor::new(tcx, worklist); symbol_visitor.mark_live_symbols(); symbol_visitor.live_symbols } @@ -340,13 +336,13 @@ impl<'a> DeadVisitor<'a> { // This is done to handle the case where, for example, the static // method of a private type is used, but the type itself is never // called directly. - let def_id = local_def(id); - match self.tcx.inherent_impls.borrow().find(&def_id) { + let impl_methods = self.tcx.impl_methods.borrow(); + match self.tcx.inherent_impls.borrow().find(&local_def(id)) { None => (), - Some(ref impl_list) => { - for impl_ in impl_list.borrow().iter() { - for method in impl_.methods.iter() { - if self.live_symbols.contains(&method.def_id.node) { + Some(impl_list) => { + for impl_did in impl_list.borrow().iter() { + for method_did in impl_methods.get(impl_did).iter() { + if self.live_symbols.contains(&method_did.node) { return true; } } @@ -406,11 +402,10 @@ impl<'a> Visitor<()> for DeadVisitor<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: typeck::MethodMap, exported_items: &privacy::ExportedItems, reachable_symbols: &NodeSet, krate: &ast::Crate) { - let live_symbols = find_live(tcx, method_map, exported_items, + let live_symbols = find_live(tcx, exported_items, reachable_symbols, krate); let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; visit::walk_crate(&mut visitor, krate, ()); diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 827d07484b7..ef7c5924844 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -12,7 +12,7 @@ /// `unsafe`. use middle::ty; -use middle::typeck::{MethodCall, MethodMap}; +use middle::typeck::MethodCall; use util::ppaux; use syntax::ast; @@ -38,8 +38,6 @@ fn type_is_unsafe_function(ty: ty::t) -> bool { struct EffectCheckVisitor<'a> { tcx: &'a ty::ctxt, - /// The method map. - method_map: MethodMap, /// Whether we're in an unsafe context. unsafe_context: UnsafeContext, } @@ -138,7 +136,7 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> { match expr.node { ast::ExprMethodCall(_, _, _) => { let method_call = MethodCall::expr(expr.id); - let base_type = self.method_map.borrow().get(&method_call).ty; + let base_type = self.tcx.method_map.borrow().get(&method_call).ty; debug!("effect: method call case, base type is {}", ppaux::ty_to_str(self.tcx, base_type)); if type_is_unsafe_function(base_type) { @@ -190,10 +188,9 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> { } } -pub fn check_crate(tcx: &ty::ctxt, method_map: MethodMap, krate: &ast::Crate) { +pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) { let mut visitor = EffectCheckVisitor { tcx: tcx, - method_map: method_map, unsafe_context: SafeContext, }; diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index d6adb19419b..83f6d5abfa4 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -29,16 +29,15 @@ pub struct freevar_entry { pub def: ast::Def, //< The variable being accessed free. pub span: Span //< First span where it is accessed (there can be multiple) } -pub type freevar_info = @Vec<@freevar_entry> ; -pub type freevar_map = NodeMap; +pub type freevar_map = NodeMap>; -struct CollectFreevarsVisitor { +struct CollectFreevarsVisitor<'a> { seen: NodeSet, - refs: Vec<@freevar_entry> , - def_map: resolve::DefMap, + refs: Vec, + def_map: &'a resolve::DefMap, } -impl Visitor for CollectFreevarsVisitor { +impl<'a> Visitor for CollectFreevarsVisitor<'a> { fn visit_item(&mut self, _: &ast::Item, _: int) { // ignore_item @@ -65,7 +64,7 @@ impl Visitor for CollectFreevarsVisitor { if i == depth { // Made it to end of loop let dnum = ast_util::def_id_of_def(def).node; if !self.seen.contains(&dnum) { - self.refs.push(@freevar_entry { + self.refs.push(freevar_entry { def: def, span: expr.span, }); @@ -87,30 +86,23 @@ impl Visitor for CollectFreevarsVisitor { // Since we want to be able to collect upvars in some arbitrary piece // of the AST, we take a walker function that we invoke with a visitor // in order to start the search. -fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) -> freevar_info { - let seen = NodeSet::new(); - let refs = Vec::new(); - +fn collect_freevars(def_map: &resolve::DefMap, blk: &ast::Block) -> Vec { let mut v = CollectFreevarsVisitor { - seen: seen, - refs: refs, + seen: NodeSet::new(), + refs: Vec::new(), def_map: def_map, }; v.visit_block(blk, 1); - let CollectFreevarsVisitor { - refs, - .. - } = v; - return @refs; + v.refs } -struct AnnotateFreevarsVisitor { - def_map: resolve::DefMap, +struct AnnotateFreevarsVisitor<'a> { + def_map: &'a resolve::DefMap, freevars: freevar_map, } -impl Visitor<()> for AnnotateFreevarsVisitor { +impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> { fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl, blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) { let vars = collect_freevars(self.def_map, blk); @@ -124,7 +116,7 @@ impl Visitor<()> for AnnotateFreevarsVisitor { // efficient as it fully recomputes the free variables at every // node of interest rather than building up the free variables in // one pass. This could be improved upon if it turns out to matter. -pub fn annotate_freevars(def_map: resolve::DefMap, krate: &ast::Crate) -> +pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate) -> freevar_map { let mut visitor = AnnotateFreevarsVisitor { def_map: def_map, @@ -132,16 +124,12 @@ pub fn annotate_freevars(def_map: resolve::DefMap, krate: &ast::Crate) -> }; visit::walk_crate(&mut visitor, krate, ()); - let AnnotateFreevarsVisitor { - freevars, - .. - } = visitor; - freevars + visitor.freevars } -pub fn get_freevars(tcx: &ty::ctxt, fid: ast::NodeId) -> freevar_info { +pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T { match tcx.freevars.borrow().find(&fid) { - None => fail!("get_freevars: {} has no freevars", fid), - Some(&d) => return d + None => fail!("with_freevars: {} has no freevars", fid), + Some(d) => f(d.as_slice()) } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a152e06eb06..e6c885e56f1 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -47,7 +47,6 @@ use syntax::visit::Visitor; #[deriving(Clone)] pub struct Context<'a> { tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, } impl<'a> Visitor<()> for Context<'a> { @@ -70,11 +69,9 @@ impl<'a> Visitor<()> for Context<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: typeck::MethodMap, krate: &Crate) { let mut ctx = Context { tcx: tcx, - method_map: method_map, }; visit::walk_crate(&mut ctx, krate, ()); tcx.sess.abort_if_errors(); @@ -115,9 +112,9 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t .find(&trait_ref.ref_id) .expect("trait ref not in def map!"); let trait_def_id = ast_util::def_id_of_def(ast_trait_def); - let trait_def = *cx.tcx.trait_defs.borrow() - .find(&trait_def_id) - .expect("trait def not in trait-defs map!"); + let trait_def = cx.tcx.trait_defs.borrow() + .find_copy(&trait_def_id) + .expect("trait def not in trait-defs map!"); // If this trait has builtin-kind supertraits, meet them. let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id); @@ -166,7 +163,7 @@ fn check_item(cx: &mut Context, item: &Item) { // closure. fn with_appropriate_checker(cx: &Context, id: NodeId, - b: |checker: |&Context, @freevar_entry||) { + b: |checker: |&Context, &freevar_entry||) { fn check_for_uniq(cx: &Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned, regardless of whether it is // moved in or copied in. @@ -187,7 +184,7 @@ fn with_appropriate_checker(cx: &Context, bounds, Some(var_t)); } - fn check_for_bare(cx: &Context, fv: @freevar_entry) { + fn check_for_bare(cx: &Context, fv: &freevar_entry) { cx.tcx.sess.span_err( fv.span, "can't capture dynamic environment in a fn item; \ @@ -226,10 +223,11 @@ fn check_fn( // Check kinds on free variables: with_appropriate_checker(cx, fn_id, |chk| { - let r = freevars::get_freevars(cx.tcx, fn_id); - for fv in r.iter() { - chk(cx, *fv); - } + freevars::with_freevars(cx.tcx, fn_id, |r| { + for fv in r.iter() { + chk(cx, fv); + } + }) }); visit::walk_fn(cx, fk, decl, body, sp, fn_id, ()); @@ -240,7 +238,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) { // Handle any kind bounds on type parameters { - let method_map = cx.method_map.borrow(); + let method_map = cx.tcx.method_map.borrow(); let method = method_map.find(&typeck::MethodCall::expr(e.id)); let node_type_substs = cx.tcx.node_type_substs.borrow(); let r = match method { @@ -309,11 +307,10 @@ pub fn check_expr(cx: &mut Context, e: &Expr) { // Search for auto-adjustments to find trait coercions. match cx.tcx.adjustments.borrow().find(&e.id) { Some(adjustment) => { - match **adjustment { + match *adjustment { ty::AutoObject(..) => { let source_ty = ty::expr_ty(cx.tcx, e); - let target_ty = ty::expr_ty_adjusted(cx.tcx, e, - &*cx.method_map.borrow()); + let target_ty = ty::expr_ty_adjusted(cx.tcx, e); check_trait_cast(cx, source_ty, target_ty, e.span); } ty::AutoAddEnv(..) | diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 7fca0e56aa2..42ef8b9d51b 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -195,12 +195,12 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option { } pub fn collect_language_items(krate: &ast::Crate, - session: &Session) -> @LanguageItems { + session: &Session) -> LanguageItems { let mut collector = LanguageItemCollector::new(session); collector.collect(krate); let LanguageItemCollector { items, .. } = collector; session.abort_if_errors(); - @items + items } // End of the macro diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6ce815d9bc4..d1cc7d7bc40 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -53,6 +53,7 @@ use std::i16; use std::i32; use std::i64; use std::i8; +use std::rc::Rc; use std::to_str::ToStr; use std::u16; use std::u32; @@ -423,23 +424,16 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ '-' to '_' in command-line flags */ pub fn get_lint_dict() -> LintDict { - let mut map = HashMap::new(); - for &(k, v) in lint_table.iter() { - map.insert(k, v); - } - return map; + lint_table.iter().map(|&(k, v)| (k, v)).collect() } struct Context<'a> { // All known lint modes (string versions) - dict: @LintDict, + dict: LintDict, // Current levels of each lint warning cur: SmallIntMap<(level, LintSource)>, // context we're checking in (used to access fields like sess) tcx: &'a ty::ctxt, - // maps from an expression id that corresponds to a method call to the - // details of the method to be invoked - method_map: typeck::MethodMap, // Items exported by the crate; used by the missing_doc lint. exported_items: &'a privacy::ExportedItems, // The id of the current `ast::StructDef` being walked. @@ -685,7 +679,7 @@ impl<'a> AstConv for Context<'a>{ ty::lookup_item_type(self.tcx, id) } - fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef { + fn get_trait_def(&self, id: ast::DefId) -> Rc { ty::lookup_trait_def(self.tcx, id) } @@ -1340,7 +1334,7 @@ fn check_unsafe_block(cx: &Context, e: &ast::Expr) { fn check_unused_mut_pat(cx: &Context, p: &ast::Pat) { match p.node { ast::PatIdent(ast::BindByValue(ast::MutMutable), - ref path, _) if pat_util::pat_is_binding(cx.tcx.def_map, p)=> { + ref path, _) if pat_util::pat_is_binding(&cx.tcx.def_map, p) => { // `let mut _a = 1;` doesn't need a warning. let initial_underscore = if path.segments.len() == 1 { token::get_ident(path.segments @@ -1390,7 +1384,7 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) { cx.span_lint(UnnecessaryAllocation, e.span, msg); }; - match cx.tcx.adjustments.borrow().find_copy(&e.id) { + match cx.tcx.adjustments.borrow().find(&e.id) { Some(adjustment) => { match *adjustment { ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. }) => { @@ -1472,7 +1466,7 @@ fn check_missing_doc_method(cx: &Context, m: &ast::Method) { node: m.id }; - match cx.tcx.methods.borrow().find(&did).map(|method| *method) { + match cx.tcx.methods.borrow().find_copy(&did) { None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"), Some(md) => { match md.container { @@ -1537,7 +1531,7 @@ fn check_stability(cx: &Context, e: &ast::Expr) { } ast::ExprMethodCall(..) => { let method_call = typeck::MethodCall::expr(e.id); - match cx.method_map.borrow().find(&method_call) { + match cx.tcx.method_map.borrow().find(&method_call) { Some(method) => { match method.origin { typeck::MethodStatic(def_id) => { @@ -1775,14 +1769,12 @@ impl<'a> IdVisitingOperation for Context<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: typeck::MethodMap, exported_items: &privacy::ExportedItems, krate: &ast::Crate) { let mut cx = Context { - dict: @get_lint_dict(), + dict: get_lint_dict(), cur: SmallIntMap::new(), tcx: tcx, - method_map: method_map, exported_items: exported_items, cur_struct_def_id: -1, is_doc_hidden: false, @@ -1793,7 +1785,9 @@ pub fn check_crate(tcx: &ty::ctxt, // Install default lint levels, followed by the command line levels, and // then actually visit the whole crate. for (_, spec) in cx.dict.iter() { - cx.set_level(spec.lint, spec.default, Default); + if spec.default != allow { + cx.cur.insert(spec.lint as uint, (spec.default, Default)); + } } for &(lint, level) in tcx.sess.opts.lint_opts.iter() { cx.set_level(lint, level, CommandLine); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a189b977635..4be9992367d 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -106,7 +106,6 @@ use middle::lint::{UnusedVariable, DeadAssignment}; use middle::pat_util; use middle::ty; -use middle::typeck; use middle::moves; use util::nodemap::NodeMap; @@ -171,10 +170,9 @@ impl<'a> Visitor<()> for IrMaps<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: typeck::MethodMap, capture_map: &moves::CaptureMap, krate: &Crate) { - visit::walk_crate(&mut IrMaps(tcx, method_map, capture_map), krate, ()); + visit::walk_crate(&mut IrMaps(tcx, capture_map), krate, ()); tcx.sess.abort_if_errors(); } @@ -247,7 +245,6 @@ enum VarKind { struct IrMaps<'a> { tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, capture_map: &'a moves::CaptureMap, num_live_nodes: uint, @@ -260,12 +257,10 @@ struct IrMaps<'a> { } fn IrMaps<'a>(tcx: &'a ty::ctxt, - method_map: typeck::MethodMap, capture_map: &'a moves::CaptureMap) -> IrMaps<'a> { IrMaps { tcx: tcx, - method_map: method_map, capture_map: capture_map, num_live_nodes: 0, num_vars: 0, @@ -366,14 +361,14 @@ fn visit_fn(ir: &mut IrMaps, let _i = ::util::common::indenter(); // swap in a new set of IR maps for this function body: - let mut fn_maps = IrMaps(ir.tcx, ir.method_map, ir.capture_map); + let mut fn_maps = IrMaps(ir.tcx, ir.capture_map); unsafe { debug!("creating fn_maps: {}", transmute::<&IrMaps, *IrMaps>(&fn_maps)); } for arg in decl.inputs.iter() { - pat_util::pat_bindings(ir.tcx.def_map, + pat_util::pat_bindings(&ir.tcx.def_map, arg.pat, |_bm, arg_id, _x, path| { debug!("adding argument {}", arg_id); @@ -407,7 +402,7 @@ fn visit_fn(ir: &mut IrMaps, } fn visit_local(ir: &mut IrMaps, local: &Local) { - pat_util::pat_bindings(ir.tcx.def_map, local.pat, |bm, p_id, sp, path| { + pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |bm, p_id, sp, path| { debug!("adding local variable {}", p_id); let name = ast_util::path_to_ident(path); ir.add_live_node_for_node(p_id, VarDefNode(sp)); @@ -431,7 +426,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) { fn visit_arm(ir: &mut IrMaps, arm: &Arm) { for pat in arm.pats.iter() { - pat_util::pat_bindings(ir.tcx.def_map, *pat, |bm, p_id, sp, path| { + pat_util::pat_bindings(&ir.tcx.def_map, *pat, |bm, p_id, sp, path| { debug!("adding local variable {} from match with bm {:?}", p_id, bm); let name = ast_util::path_to_ident(path); @@ -601,7 +596,7 @@ impl<'a> Liveness<'a> { fn pat_bindings(&mut self, pat: &Pat, f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) { - pat_util::pat_bindings(self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| { + pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); let var = self.variable(p_id, sp); f(self, ln, var, sp, p_id); @@ -1529,7 +1524,7 @@ impl<'a> Liveness<'a> { fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) { for arg in decl.inputs.iter() { - pat_util::pat_bindings(self.ir.tcx.def_map, + pat_util::pat_bindings(&self.ir.tcx.def_map, arg.pat, |_bm, p_id, sp, path| { let var = self.variable(p_id, sp); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 84e9151c11c..35124aa9916 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -64,6 +64,7 @@ use middle::ty; use middle::typeck; +use util::nodemap::NodeMap; use util::ppaux::{ty_to_str, Repr}; use syntax::ast::{MutImmutable, MutMutable}; @@ -72,7 +73,10 @@ use syntax::codemap::Span; use syntax::print::pprust; use syntax::parse::token; -#[deriving(Eq)] +use std::cell::RefCell; +use std::rc::Rc; + +#[deriving(Clone, Eq)] pub enum categorization { cat_rvalue(ty::Region), // temporary val, argument is its scope cat_static_item, @@ -88,14 +92,14 @@ pub enum categorization { // (*1) downcast is only required if the enum has more than one variant } -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct CopiedUpvar { pub upvar_id: ast::NodeId, pub onceness: ast::Onceness, } // different kinds of pointers: -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum PointerKind { OwnedPtr, GcPtr, @@ -105,26 +109,26 @@ pub enum PointerKind { // We use the term "interior" to mean "something reachable from the // base without a pointer dereference", e.g. a field -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum InteriorKind { InteriorField(FieldName), InteriorElement(ElementKind), } -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum FieldName { NamedField(ast::Name), PositionalField(uint) } -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum ElementKind { VecElement, StrElement, OtherElement, } -#[deriving(Eq, TotalEq, Hash, Show)] +#[deriving(Clone, Eq, TotalEq, Hash, Show)] pub enum MutabilityCategory { McImmutable, // Immutable. McDeclared, // Directly declared as mutable. @@ -145,7 +149,7 @@ pub enum MutabilityCategory { // dereference, but its type is the type *before* the dereference // (`@T`). So use `cmt.type` to find the type of the value in a consistent // fashion. For more details, see the method `cat_pattern` -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct cmt_ { pub id: ast::NodeId, // id of expr/pat producing this value pub span: Span, // span of same expr/pat @@ -154,7 +158,7 @@ pub struct cmt_ { pub ty: ty::t // type of the expr (*see WARNING above*) } -pub type cmt = @cmt_; +pub type cmt = Rc; // We pun on *T to mean both actual deref of a ptr as well // as accessing of components: @@ -263,12 +267,12 @@ pub type McResult = Result; */ pub trait Typer { fn tcx<'a>(&'a self) -> &'a ty::ctxt; - fn node_ty(&mut self, id: ast::NodeId) -> McResult; + fn node_ty(&self, id: ast::NodeId) -> McResult; fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option; - fn adjustment(&mut self, node_id: ast::NodeId) -> Option<@ty::AutoAdjustment>; - fn is_method_call(&mut self, id: ast::NodeId) -> bool; - fn temporary_scope(&mut self, rvalue_id: ast::NodeId) -> Option; - fn upvar_borrow(&mut self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow; + fn adjustments<'a>(&'a self) -> &'a RefCell>; + fn is_method_call(&self, id: ast::NodeId) -> bool; + fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option; + fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow; } impl MutabilityCategory { @@ -350,31 +354,27 @@ impl MemCategorizationContext { self.typer.tcx() } - fn adjustment(&mut self, id: ast::NodeId) -> Option<@ty::AutoAdjustment> { - self.typer.adjustment(id) - } - - fn expr_ty(&mut self, expr: &ast::Expr) -> McResult { + fn expr_ty(&self, expr: &ast::Expr) -> McResult { self.typer.node_ty(expr.id) } - fn expr_ty_adjusted(&mut self, expr: &ast::Expr) -> McResult { + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult { let unadjusted_ty = if_ok!(self.expr_ty(expr)); - let adjustment = self.adjustment(expr.id); - Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty, adjustment, + Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty, + self.typer.adjustments().borrow().find(&expr.id), |method_call| self.typer.node_method_ty(method_call))) } - fn node_ty(&mut self, id: ast::NodeId) -> McResult { + fn node_ty(&self, id: ast::NodeId) -> McResult { self.typer.node_ty(id) } - fn pat_ty(&mut self, pat: @ast::Pat) -> McResult { + fn pat_ty(&self, pat: &ast::Pat) -> McResult { self.typer.node_ty(pat.id) } - pub fn cat_expr(&mut self, expr: &ast::Expr) -> McResult { - match self.adjustment(expr.id) { + pub fn cat_expr(&self, expr: &ast::Expr) -> McResult { + match self.typer.adjustments().borrow().find(&expr.id) { None => { // No adjustments. self.cat_expr_unadjusted(expr) @@ -386,8 +386,9 @@ impl MemCategorizationContext { // Implicity casts a concrete object to trait object // so just patch up the type let expr_ty = if_ok!(self.expr_ty_adjusted(expr)); - let expr_cmt = if_ok!(self.cat_expr_unadjusted(expr)); - Ok(@cmt_ {ty: expr_ty, ..*expr_cmt}) + let mut expr_cmt = (*if_ok!(self.cat_expr_unadjusted(expr))).clone(); + expr_cmt.ty = expr_ty; + Ok(Rc::new(expr_cmt)) } ty::AutoAddEnv(..) => { @@ -417,7 +418,7 @@ impl MemCategorizationContext { } } - pub fn cat_expr_autoderefd(&mut self, expr: &ast::Expr, autoderefs: uint) + pub fn cat_expr_autoderefd(&self, expr: &ast::Expr, autoderefs: uint) -> McResult { let mut cmt = if_ok!(self.cat_expr_unadjusted(expr)); for deref in range(1u, autoderefs + 1) { @@ -426,7 +427,7 @@ impl MemCategorizationContext { return Ok(cmt); } - pub fn cat_expr_unadjusted(&mut self, expr: &ast::Expr) -> McResult { + pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult { debug!("cat_expr: id={} expr={}", expr.id, expr.repr(self.tcx())); let expr_ty = if_ok!(self.expr_ty(expr)); @@ -475,7 +476,7 @@ impl MemCategorizationContext { } } - pub fn cat_def(&mut self, + pub fn cat_def(&self, id: ast::NodeId, span: Span, expr_ty: ty::t, @@ -493,23 +494,23 @@ impl MemCategorizationContext { ast::DefUse(_) | ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) | ast::DefTyParam(..) | ast::DefTyParamBinder(..) | ast::DefRegion(_) | ast::DefLabel(_) | ast::DefSelfTy(..) | ast::DefMethod(..) => { - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_static_item, mutbl: McImmutable, ty:expr_ty - }) + })) } ast::DefStatic(_, true) => { - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_static_item, mutbl: McDeclared, ty:expr_ty - }) + })) } ast::DefArg(vid, binding_mode) => { @@ -521,13 +522,13 @@ impl MemCategorizationContext { ast::BindByValue(ast::MutMutable) => McDeclared, _ => McImmutable }; - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id: id, span: span, cat: cat_arg(vid), mutbl: m, ty:expr_ty - }) + })) } ast::DefUpvar(var_id, _, fn_node_id, _) => { @@ -551,7 +552,7 @@ impl MemCategorizationContext { self.cat_upvar(id, span, var_id, fn_node_id) } else { // FIXME #2152 allow mutation of moved upvars - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_copied_upvar(CopiedUpvar { @@ -559,7 +560,7 @@ impl MemCategorizationContext { onceness: closure_ty.onceness}), mutbl:McImmutable, ty:expr_ty - }) + })) } } _ => { @@ -579,18 +580,18 @@ impl MemCategorizationContext { _ => McImmutable }; - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id: id, span: span, cat: cat_local(vid), mutbl: m, ty: expr_ty - }) + })) } } } - fn cat_upvar(&mut self, + fn cat_upvar(&self, id: ast::NodeId, span: Span, var_id: ast::NodeId, @@ -619,28 +620,28 @@ impl MemCategorizationContext { // give err type. Nobody should be inspecting this type anyhow. let upvar_ty = ty::mk_err(); - let base_cmt = @cmt_ { + let base_cmt = Rc::new(cmt_ { id:id, span:span, cat:cat_upvar(upvar_id, upvar_borrow), mutbl:McImmutable, ty:upvar_ty, - }; + }); let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region); - let deref_cmt = @cmt_ { + let deref_cmt = Rc::new(cmt_ { id:id, span:span, cat:cat_deref(base_cmt, 0, ptr), mutbl:MutabilityCategory::from_borrow_kind(upvar_borrow.kind), ty:var_ty, - }; + }); Ok(deref_cmt) } - pub fn cat_rvalue_node(&mut self, + pub fn cat_rvalue_node(&self, id: ast::NodeId, span: Span, expr_ty: ty::t) @@ -655,40 +656,40 @@ impl MemCategorizationContext { } } - pub fn cat_rvalue(&mut self, + pub fn cat_rvalue(&self, cmt_id: ast::NodeId, span: Span, temp_scope: ty::Region, expr_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id:cmt_id, span:span, cat:cat_rvalue(temp_scope), mutbl:McDeclared, ty:expr_ty - } + }) } - pub fn cat_field(&mut self, + pub fn cat_field(&self, node: &N, base_cmt: cmt, f_name: ast::Ident, f_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_interior(base_cmt, InteriorField(NamedField(f_name.name))), mutbl: base_cmt.mutbl.inherit(), + cat: cat_interior(base_cmt, InteriorField(NamedField(f_name.name))), ty: f_ty - } + }) } - pub fn cat_deref_obj(&mut self, node: &N, base_cmt: cmt) -> cmt { + pub fn cat_deref_obj(&self, node: &N, base_cmt: cmt) -> cmt { self.cat_deref_common(node, base_cmt, 0, ty::mk_nil()) } - fn cat_deref(&mut self, + fn cat_deref(&self, node: &N, base_cmt: cmt, deref_cnt: uint) @@ -720,7 +721,7 @@ impl MemCategorizationContext { } } - fn cat_deref_common(&mut self, + fn cat_deref_common(&self, node: &N, base_cmt: cmt, deref_cnt: uint, @@ -737,16 +738,16 @@ impl MemCategorizationContext { (base_cmt.mutbl.inherit(), cat_interior(base_cmt, interior)) } }; - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), cat: cat, mutbl: m, ty: deref_ty - } + }) } - pub fn cat_index(&mut self, + pub fn cat_index(&self, elt: &N, base_cmt: cmt, derefs: uint) @@ -799,13 +800,13 @@ impl MemCategorizationContext { let m = MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr); // the deref is explicit in the resulting cmt - let deref_cmt = @cmt_ { + let deref_cmt = Rc::new(cmt_ { id:elt.id(), span:elt.span(), - cat:cat_deref(base_cmt, derefs, ptr), + cat:cat_deref(base_cmt.clone(), derefs, ptr), mutbl:m, ty:element_ty - }; + }); interior(elt, deref_cmt, base_cmt.ty, m.inherit(), element_ty) } @@ -813,7 +814,7 @@ impl MemCategorizationContext { deref_interior(_) => { // fixed-length vectors have no deref let m = base_cmt.mutbl.inherit(); - interior(elt, base_cmt, base_cmt.ty, m, element_ty) + interior(elt, base_cmt.clone(), base_cmt.ty, m, element_ty) } }; @@ -823,19 +824,19 @@ impl MemCategorizationContext { mutbl: MutabilityCategory, element_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id:elt.id(), span:elt.span(), cat:cat_interior(of_cmt, InteriorElement(element_kind(vec_ty))), mutbl:mutbl, ty:element_ty - } + }) } } - pub fn cat_slice_pattern(&mut self, + pub fn cat_slice_pattern(&self, vec_cmt: cmt, - slice_pat: @ast::Pat) + slice_pat: &ast::Pat) -> McResult<(cmt, ast::Mutability, ty::Region)> { /*! * Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is @@ -855,7 +856,7 @@ impl MemCategorizationContext { return Ok((cmt_slice, slice_mutbl, slice_r)); fn vec_slice_info(tcx: &ty::ctxt, - pat: @ast::Pat, + pat: &ast::Pat, slice_ty: ty::t) -> (ast::Mutability, ty::Region) { /*! @@ -880,41 +881,41 @@ impl MemCategorizationContext { } } - pub fn cat_imm_interior(&mut self, + pub fn cat_imm_interior(&self, node: &N, base_cmt: cmt, interior_ty: ty::t, interior: InteriorKind) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_interior(base_cmt, interior), mutbl: base_cmt.mutbl.inherit(), + cat: cat_interior(base_cmt, interior), ty: interior_ty - } + }) } - pub fn cat_downcast(&mut self, + pub fn cat_downcast(&self, node: &N, base_cmt: cmt, downcast_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_downcast(base_cmt), mutbl: base_cmt.mutbl.inherit(), + cat: cat_downcast(base_cmt), ty: downcast_ty - } + }) } - pub fn cat_pattern(&mut self, + pub fn cat_pattern(&self, cmt: cmt, - pat: @ast::Pat, - op: |&mut MemCategorizationContext, + pat: &ast::Pat, + op: |&MemCategorizationContext, cmt, - @ast::Pat|) + &ast::Pat|) -> McResult<()> { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. @@ -965,7 +966,7 @@ impl MemCategorizationContext { pat.id, pprust::pat_to_str(pat), cmt.repr(self.tcx())); - op(self, cmt, pat); + op(self, cmt.clone(), pat); match pat.node { ast::PatWild | ast::PatWildMulti => { @@ -984,7 +985,7 @@ impl MemCategorizationContext { if ty::enum_is_univariant(self.tcx(), enum_did) { cmt // univariant, no downcast needed } else { - self.cat_downcast(pat, cmt, cmt.ty) + self.cat_downcast(pat, cmt.clone(), cmt.ty) } }; @@ -993,7 +994,7 @@ impl MemCategorizationContext { let subcmt = self.cat_imm_interior( - pat, downcast_cmt, subpat_ty, + pat, downcast_cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); @@ -1005,14 +1006,14 @@ impl MemCategorizationContext { let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let cmt_field = self.cat_imm_interior( - pat, cmt, subpat_ty, + pat, cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(cmt_field, subpat, |x,y,z| op(x,y,z))); } } Some(&ast::DefStatic(..)) => { for &subpat in subpats.iter() { - if_ok!(self.cat_pattern(cmt, subpat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(cmt.clone(), subpat, |x,y,z| op(x,y,z))); } } _ => { @@ -1035,7 +1036,7 @@ impl MemCategorizationContext { // {f1: p1, ..., fN: pN} for fp in field_pats.iter() { let field_ty = if_ok!(self.pat_ty(fp.pat)); // see (*2) - let cmt_field = self.cat_field(pat, cmt, fp.ident, field_ty); + let cmt_field = self.cat_field(pat, cmt.clone(), fp.ident, field_ty); if_ok!(self.cat_pattern(cmt_field, fp.pat, |x,y,z| op(x,y,z))); } } @@ -1046,7 +1047,7 @@ impl MemCategorizationContext { let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let subcmt = self.cat_imm_interior( - pat, cmt, subpat_ty, + pat, cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); } @@ -1061,7 +1062,7 @@ impl MemCategorizationContext { ast::PatVec(ref before, slice, ref after) => { let elt_cmt = self.cat_index(pat, cmt, 0); for &before_pat in before.iter() { - if_ok!(self.cat_pattern(elt_cmt, before_pat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(elt_cmt.clone(), before_pat, |x,y,z| op(x,y,z))); } for &slice_pat in slice.iter() { let slice_ty = if_ok!(self.pat_ty(slice_pat)); @@ -1069,7 +1070,7 @@ impl MemCategorizationContext { if_ok!(self.cat_pattern(slice_cmt, slice_pat, |x,y,z| op(x,y,z))); } for &after_pat in after.iter() { - if_ok!(self.cat_pattern(elt_cmt, after_pat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(elt_cmt.clone(), after_pat, |x,y,z| op(x,y,z))); } } @@ -1081,7 +1082,7 @@ impl MemCategorizationContext { Ok(()) } - pub fn cmt_to_str(&self, cmt: cmt) -> ~str { + pub fn cmt_to_str(&self, cmt: &cmt_) -> ~str { match cmt.cat { cat_static_item => { "static item".to_owned() @@ -1098,7 +1099,7 @@ impl MemCategorizationContext { cat_arg(..) => { "argument".to_owned() } - cat_deref(base, _, pk) => { + cat_deref(ref base, _, pk) => { match base.cat { cat_upvar(..) => { format!("captured outer variable") @@ -1126,11 +1127,11 @@ impl MemCategorizationContext { cat_upvar(..) => { "captured outer variable".to_owned() } - cat_discr(cmt, _) => { - self.cmt_to_str(cmt) + cat_discr(ref cmt, _) => { + self.cmt_to_str(&**cmt) } - cat_downcast(cmt) => { - self.cmt_to_str(cmt) + cat_downcast(ref cmt) => { + self.cmt_to_str(&**cmt) } } } @@ -1150,7 +1151,7 @@ pub enum AliasableReason { } impl cmt_ { - pub fn guarantor(self) -> cmt { + pub fn guarantor(&self) -> cmt { //! Returns `self` after stripping away any owned pointer derefs or //! interior content. The return value is basically the `cmt` which //! determines how long the value in `self` remains live. @@ -1165,12 +1166,12 @@ impl cmt_ { cat_deref(_, _, GcPtr(..)) | cat_deref(_, _, BorrowedPtr(..)) | cat_upvar(..) => { - @self + Rc::new((*self).clone()) } - cat_downcast(b) | - cat_discr(b, _) | - cat_interior(b, _) | - cat_deref(b, _, OwnedPtr) => { + cat_downcast(ref b) | + cat_discr(ref b, _) | + cat_interior(ref b, _) | + cat_deref(ref b, _, OwnedPtr) => { b.guarantor() } } @@ -1187,12 +1188,12 @@ impl cmt_ { // aliased and eventually recused. match self.cat { - cat_deref(b, _, BorrowedPtr(ty::MutBorrow, _)) | - cat_deref(b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | - cat_downcast(b) | - cat_deref(b, _, OwnedPtr) | - cat_interior(b, _) | - cat_discr(b, _) => { + cat_deref(ref b, _, BorrowedPtr(ty::MutBorrow, _)) | + cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | + cat_downcast(ref b) | + cat_deref(ref b, _, OwnedPtr) | + cat_interior(ref b, _) | + cat_discr(ref b, _) => { // Aliasability depends on base cmt b.freely_aliasable(ctxt) } @@ -1256,21 +1257,21 @@ impl Repr for categorization { cat_arg(..) => { format!("{:?}", *self) } - cat_deref(cmt, derefs, ptr) => { + cat_deref(ref cmt, derefs, ptr) => { format!("{}-{}{}->", cmt.cat.repr(tcx), ptr_sigil(ptr), derefs) } - cat_interior(cmt, interior) => { + cat_interior(ref cmt, interior) => { format!("{}.{}", cmt.cat.repr(tcx), interior.repr(tcx)) } - cat_downcast(cmt) => { + cat_downcast(ref cmt) => { format!("{}->(enum)", cmt.cat.repr(tcx)) } - cat_discr(cmt, _) => { + cat_discr(ref cmt, _) => { cmt.cat.repr(tcx) } } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 2029df38b10..53d3dec6713 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -130,7 +130,7 @@ and so on. use middle::pat_util::{pat_bindings}; use middle::freevars; use middle::ty; -use middle::typeck::{MethodCall, MethodMap}; +use middle::typeck::MethodCall; use util::ppaux; use util::ppaux::Repr; use util::common::indenter; @@ -177,7 +177,6 @@ pub struct MoveMaps { #[deriving(Clone)] struct VisitContext<'a> { tcx: &'a ty::ctxt, - method_map: MethodMap, move_maps: MoveMaps } @@ -202,13 +201,9 @@ impl<'a> visit::Visitor<()> for VisitContext<'a> { fn visit_ty(&mut self, _t: &Ty, _: ()) {} } -pub fn compute_moves(tcx: &ty::ctxt, - method_map: MethodMap, - krate: &Crate) -> MoveMaps -{ +pub fn compute_moves(tcx: &ty::ctxt, krate: &Crate) -> MoveMaps { let mut visit_cx = VisitContext { tcx: tcx, - method_map: method_map, move_maps: MoveMaps { moves_map: NodeSet::new(), moved_variables_set: NodeSet::new(), @@ -274,8 +269,7 @@ impl<'a> VisitContext<'a> { debug!("consume_expr(expr={})", expr.repr(self.tcx)); - let expr_ty = ty::expr_ty_adjusted(self.tcx, expr, - &*self.method_map.borrow()); + let expr_ty = ty::expr_ty_adjusted(self.tcx, expr); if ty::type_moves_by_default(self.tcx, expr_ty) { self.move_maps.moves_map.insert(expr.id); self.use_expr(expr, Move); @@ -318,7 +312,7 @@ impl<'a> VisitContext<'a> { // reading the underlying expression, not moving it. let comp_mode = match self.tcx.adjustments.borrow().find(&expr.id) { Some(adjustment) => { - match **adjustment { + match *adjustment { ty::AutoDerefRef(ty::AutoDerefRef { autoref: Some(_), .. @@ -550,7 +544,7 @@ impl<'a> VisitContext<'a> { self.use_pat(a.pat); } let cap_vars = self.compute_captures(expr.id); - self.move_maps.capture_map.insert(expr.id, cap_vars); + self.move_maps.capture_map.insert(expr.id, Rc::new(cap_vars)); self.consume_block(body); } @@ -577,7 +571,7 @@ impl<'a> VisitContext<'a> { arg_exprs: &[@Expr]) -> bool { let method_call = MethodCall::expr(expr.id); - if !self.method_map.borrow().contains_key(&method_call) { + if !self.tcx.method_map.borrow().contains_key(&method_call) { return false; } @@ -611,7 +605,7 @@ impl<'a> VisitContext<'a> { * into itself or not based on its type and annotation. */ - pat_bindings(self.tcx.def_map, pat, |bm, id, _span, path| { + pat_bindings(&self.tcx.def_map, pat, |bm, id, _span, path| { let binding_moves = match bm { BindByRef(_) => false, BindByValue(_) => { @@ -645,34 +639,35 @@ impl<'a> VisitContext<'a> { self.consume_expr(arg_expr) } - pub fn compute_captures(&mut self, fn_expr_id: NodeId) -> Rc > { + fn compute_captures(&mut self, fn_expr_id: NodeId) -> Vec { debug!("compute_capture_vars(fn_expr_id={:?})", fn_expr_id); let _indenter = indenter(); let fn_ty = ty::node_id_to_type(self.tcx, fn_expr_id); - let freevars = freevars::get_freevars(self.tcx, fn_expr_id); - Rc::new(match ty::ty_closure_store(fn_ty) { - ty::RegionTraitStore(..) => { - // || captures everything by ref - freevars.iter() - .map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef}) - .collect() - } - ty::UniqTraitStore => { - // proc captures by copy or by move depending on type - freevars.iter() - .map(|fvar| { - let fvar_def_id = ast_util::def_id_of_def(fvar.def).node; - let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id); - debug!("fvar_def_id={:?} fvar_ty={}", - fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty)); - let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) { - CapMove - } else { - CapCopy - }; - CaptureVar {def: fvar.def, span: fvar.span, mode:mode} - }).collect() + freevars::with_freevars(self.tcx, fn_expr_id, |freevars| { + match ty::ty_closure_store(fn_ty) { + ty::RegionTraitStore(..) => { + // || captures everything by ref + freevars.iter() + .map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef}) + .collect() + } + ty::UniqTraitStore => { + // proc captures by copy or by move depending on type + freevars.iter() + .map(|fvar| { + let fvar_def_id = ast_util::def_id_of_def(fvar.def).node; + let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id); + debug!("fvar_def_id={:?} fvar_ty={}", + fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty)); + let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) { + CapMove + } else { + CapCopy + }; + CaptureVar {def: fvar.def, span: fvar.span, mode:mode} + }).collect() + } } }) } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 2d50d2e0f77..842d3bae6a7 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -20,7 +20,7 @@ pub type PatIdMap = HashMap; // This is used because same-named variables in alternative patterns need to // use the NodeId of their namesake in the first pattern. -pub fn pat_id_map(dm: resolve::DefMap, pat: &Pat) -> PatIdMap { +pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap { let mut map = HashMap::new(); pat_bindings(dm, pat, |_bm, p_id, _s, n| { map.insert(path_to_ident(n), p_id); @@ -28,7 +28,7 @@ pub fn pat_id_map(dm: resolve::DefMap, pat: &Pat) -> PatIdMap { map } -pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: &Pat) -> bool { +pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => { match dm.borrow().find(&pat.id) { @@ -40,7 +40,7 @@ pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: &Pat) -> bool { } } -pub fn pat_is_const(dm: resolve::DefMap, pat: &Pat) -> bool { +pub fn pat_is_const(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatIdent(_, _, None) | PatEnum(..) => { match dm.borrow().find(&pat.id) { @@ -52,7 +52,7 @@ pub fn pat_is_const(dm: resolve::DefMap, pat: &Pat) -> bool { } } -pub fn pat_is_binding(dm: resolve::DefMap, pat: &Pat) -> bool { +pub fn pat_is_binding(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatIdent(..) => { !pat_is_variant_or_struct(dm, pat) && @@ -62,7 +62,7 @@ pub fn pat_is_binding(dm: resolve::DefMap, pat: &Pat) -> bool { } } -pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: &Pat) -> bool { +pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatIdent(..) => pat_is_binding(dm, pat), PatWild | PatWildMulti => true, @@ -72,7 +72,7 @@ pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: &Pat) -> bool { /// Call `it` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` -pub fn pat_bindings(dm: resolve::DefMap, +pub fn pat_bindings(dm: &resolve::DefMap, pat: &Pat, it: |BindingMode, NodeId, Span, &Path|) { walk_pat(pat, |p| { @@ -88,7 +88,7 @@ pub fn pat_bindings(dm: resolve::DefMap, /// Checks if the pattern contains any patterns that bind something to /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. -pub fn pat_contains_bindings(dm: resolve::DefMap, pat: &Pat) -> bool { +pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &Pat) -> bool { let mut contains_bindings = false; walk_pat(pat, |p| { if pat_is_binding(dm, p) { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 1e160df1061..427a7f406b0 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -254,7 +254,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> { _ => true, }; let tr = ty::impl_trait_ref(self.tcx, local_def(item.id)); - let public_trait = tr.map_or(false, |tr| { + let public_trait = tr.clone().map_or(false, |tr| { !is_local(tr.def_id) || self.exported_items.contains(&tr.def_id.node) }); @@ -337,7 +337,6 @@ struct PrivacyVisitor<'a> { curitem: ast::NodeId, in_fn: bool, in_foreign: bool, - method_map: &'a MethodMap, parents: NodeMap, external_exports: resolve::ExternalExports, last_private_map: resolve::LastPrivateMap, @@ -775,8 +774,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> { fn visit_expr(&mut self, expr: &ast::Expr, _: ()) { match expr.node { ast::ExprField(base, ident, _) => { - match ty::get(ty::expr_ty_adjusted(self.tcx, base, - &*self.method_map.borrow())).sty { + match ty::get(ty::expr_ty_adjusted(self.tcx, base)).sty { ty::ty_struct(id, _) => { self.check_field(expr.span, id, NamedField(ident)); } @@ -785,7 +783,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> { } ast::ExprMethodCall(ident, _, _) => { let method_call = MethodCall::expr(expr.id); - match self.method_map.borrow().find(&method_call) { + match self.tcx.method_map.borrow().find(&method_call) { None => { self.tcx.sess.span_bug(expr.span, "method call not in \ @@ -1404,7 +1402,6 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> { } pub fn check_crate(tcx: &ty::ctxt, - method_map: &MethodMap, exp_map2: &resolve::ExportMap2, external_exports: resolve::ExternalExports, last_private_map: resolve::LastPrivateMap, @@ -1423,7 +1420,6 @@ pub fn check_crate(tcx: &ty::ctxt, in_foreign: false, tcx: tcx, parents: visitor.parents, - method_map: method_map, external_exports: external_exports, last_private_map: last_private_map, }; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 839f1d6039c..6e2edb4e8b2 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -84,9 +84,6 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, struct ReachableContext<'a> { // The type context. tcx: &'a ty::ctxt, - // The method map, which links node IDs of method call expressions to the - // methods they've been resolved to. - method_map: typeck::MethodMap, // The set of items which must be exported in the linkage sense. reachable_symbols: NodeSet, // A worklist of item IDs. Each item ID in this worklist will be inlined @@ -133,7 +130,7 @@ impl<'a> Visitor<()> for ReachableContext<'a> { } ast::ExprMethodCall(..) => { let method_call = typeck::MethodCall::expr(expr.id); - match self.method_map.borrow().get(&method_call).origin { + match self.tcx.method_map.borrow().get(&method_call).origin { typeck::MethodStatic(def_id) => { if is_local(def_id) { if self.def_id_represents_local_inlined_item(def_id) { @@ -159,10 +156,9 @@ impl<'a> Visitor<()> for ReachableContext<'a> { impl<'a> ReachableContext<'a> { // Creates a new reachability computation context. - fn new(tcx: &'a ty::ctxt, method_map: typeck::MethodMap) -> ReachableContext<'a> { + fn new(tcx: &'a ty::ctxt) -> ReachableContext<'a> { ReachableContext { tcx: tcx, - method_map: method_map, reachable_symbols: NodeSet::new(), worklist: Vec::new(), } @@ -339,10 +335,9 @@ impl<'a> ReachableContext<'a> { } pub fn find_reachable(tcx: &ty::ctxt, - method_map: typeck::MethodMap, exported_items: &privacy::ExportedItems) -> NodeSet { - let mut reachable_context = ReachableContext::new(tcx, method_map); + let mut reachable_context = ReachableContext::new(tcx); // Step 1: Seed the worklist with all nodes which were found to be public as // a result of the privacy pass along with all local lang items. If diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index cd9d88537b4..d645b628aff 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -16,7 +16,7 @@ use metadata::decoder::{DefLike, DlDef, DlField, DlImpl}; use middle::lang_items::LanguageItems; use middle::lint::{UnnecessaryQualification, UnusedImports}; use middle::pat_util::pat_bindings; -use util::nodemap::{NodeMap, DefIdSet}; +use util::nodemap::{NodeMap, DefIdSet, FnvHashSet}; use syntax::ast::*; use syntax::ast; @@ -34,11 +34,12 @@ use syntax::visit::Visitor; use collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; use std::mem::replace; +use std::rc::{Rc, Weak}; use std::strbuf::StrBuf; use std::uint; // Definition mapping -pub type DefMap = @RefCell>; +pub type DefMap = RefCell>; struct binding_info { span: Span, @@ -53,7 +54,7 @@ pub type TraitMap = NodeMap >; // This is the replacement export map. It maps a module to all of the exports // within. -pub type ExportMap2 = @RefCell >>; +pub type ExportMap2 = RefCell >>; pub struct Export2 { pub name: ~str, // The name of the target. @@ -125,6 +126,7 @@ enum NamespaceError { /// A NamespaceResult represents the result of resolving an import in /// a particular namespace. The result is either definitely-resolved, /// definitely- unresolved, or unknown. +#[deriving(Clone)] enum NamespaceResult { /// Means that resolve hasn't gathered enough information yet to determine /// whether the name is bound in this namespace. (That is, it hasn't @@ -135,7 +137,7 @@ enum NamespaceResult { UnboundResult, /// Means that resolve has determined that the name is bound in the Module /// argument, and specified by the NameBindings argument. - BoundResult(@Module, @NameBindings) + BoundResult(Rc, Rc) } impl NamespaceResult { @@ -189,14 +191,14 @@ enum ImportDirectiveSubclass { /// The context that we thread through while building the reduced graph. #[deriving(Clone)] enum ReducedGraphParent { - ModuleReducedGraphParent(@Module) + ModuleReducedGraphParent(Rc) } impl ReducedGraphParent { - fn module(&self) -> @Module { + fn module(&self) -> Rc { match *self { - ModuleReducedGraphParent(m) => { - m + ModuleReducedGraphParent(ref m) => { + m.clone() } } } @@ -279,7 +281,7 @@ enum SearchThroughModulesFlag { enum ModulePrefixResult { NoPrefixFound, - PrefixFound(@Module, uint) + PrefixFound(Rc, uint) } #[deriving(Eq)] @@ -326,8 +328,8 @@ impl Rib { /// One import directive. struct ImportDirective { - module_path: Vec , - subclass: @ImportDirectiveSubclass, + module_path: Vec, + subclass: ImportDirectiveSubclass, span: Span, id: NodeId, is_public: bool, // see note in ImportResolution about how to use this @@ -335,7 +337,7 @@ struct ImportDirective { impl ImportDirective { fn new(module_path: Vec , - subclass: @ImportDirectiveSubclass, + subclass: ImportDirectiveSubclass, span: Span, id: NodeId, is_public: bool) @@ -353,12 +355,12 @@ impl ImportDirective { /// The item that an import resolves to. #[deriving(Clone)] struct Target { - target_module: @Module, - bindings: @NameBindings, + target_module: Rc, + bindings: Rc, } impl Target { - fn new(target_module: @Module, bindings: @NameBindings) -> Target { + fn new(target_module: Rc, bindings: Rc) -> Target { Target { target_module: target_module, bindings: bindings @@ -372,63 +374,60 @@ struct ImportResolution { /// should *not* be used whenever resolution is being performed, this is /// only looked at for glob imports statements currently. Privacy testing /// occurs during a later phase of compilation. - is_public: Cell, + is_public: bool, // The number of outstanding references to this name. When this reaches // zero, outside modules can count on the targets being correct. Before // then, all bets are off; future imports could override this name. - outstanding_references: Cell, + outstanding_references: uint, /// The value that this `use` directive names, if there is one. - value_target: RefCell>, + value_target: Option, /// The source node of the `use` directive leading to the value target /// being non-none - value_id: Cell, + value_id: NodeId, /// The type that this `use` directive names, if there is one. - type_target: RefCell>, + type_target: Option, /// The source node of the `use` directive leading to the type target /// being non-none - type_id: Cell, -} - -fn get(cell: &RefCell) -> T { - cell.borrow().clone() + type_id: NodeId, } impl ImportResolution { fn new(id: NodeId, is_public: bool) -> ImportResolution { ImportResolution { - type_id: Cell::new(id), - value_id: Cell::new(id), - outstanding_references: Cell::new(0), - value_target: RefCell::new(None), - type_target: RefCell::new(None), - is_public: Cell::new(is_public), + type_id: id, + value_id: id, + outstanding_references: 0, + value_target: None, + type_target: None, + is_public: is_public, } } fn target_for_namespace(&self, namespace: Namespace) -> Option { match namespace { - TypeNS => return self.type_target.borrow().clone(), - ValueNS => return self.value_target.borrow().clone(), + TypeNS => self.type_target.clone(), + ValueNS => self.value_target.clone(), } } fn id(&self, namespace: Namespace) -> NodeId { match namespace { - TypeNS => self.type_id.get(), - ValueNS => self.value_id.get(), + TypeNS => self.type_id, + ValueNS => self.value_id, } } } /// The link from a module up to its nearest parent node. +#[deriving(Clone)] enum ParentLink { NoParentLink, - ModuleParentLink(@Module, Ident), - BlockParentLink(@Module, NodeId) + ModuleParentLink(Weak, Ident), + BlockParentLink(Weak, NodeId) } /// The type of module this is. @@ -448,12 +447,12 @@ struct Module { kind: Cell, is_public: bool, - children: RefCell>, - imports: RefCell >, + children: RefCell>>, + imports: RefCell>, // The external module children of this node that were declared with // `extern crate`. - external_module_children: RefCell>, + external_module_children: RefCell>>, // The anonymous children of this node. Anonymous children are pseudo- // modules that are implicitly created around items contained within @@ -469,10 +468,10 @@ struct Module { // // There will be an anonymous module created around `g` with the ID of the // entry block for `f`. - anonymous_children: RefCell>, + anonymous_children: RefCell>>, // The status of resolving each import in this module. - import_resolutions: RefCell>, + import_resolutions: RefCell>, // The number of unresolved globs that this module exports. glob_count: Cell, @@ -518,7 +517,7 @@ impl Module { #[deriving(Clone)] struct TypeNsDef { is_public: bool, // see note in ImportResolution about how to use this - module_def: Option<@Module>, + module_def: Option>, type_def: Option, type_span: Option } @@ -555,8 +554,8 @@ impl NameBindings { is_public: bool, sp: Span) { // Merges the module with the existing type def or creates a new one. - let module_ = @Module::new(parent_link, def_id, kind, external, - is_public); + let module_ = Rc::new(Module::new(parent_link, def_id, kind, external, + is_public)); let type_def = self.type_def.borrow().clone(); match type_def { None => { @@ -589,11 +588,11 @@ impl NameBindings { let type_def = self.type_def.borrow().clone(); match type_def { None => { - let module = @Module::new(parent_link, def_id, kind, - external, is_public); + let module = Module::new(parent_link, def_id, kind, + external, is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { is_public: is_public, - module_def: Some(module), + module_def: Some(Rc::new(module)), type_def: None, type_span: None, }); @@ -601,14 +600,14 @@ impl NameBindings { Some(type_def) => { match type_def.module_def { None => { - let module = @Module::new(parent_link, - def_id, - kind, - external, - is_public); + let module = Module::new(parent_link, + def_id, + kind, + external, + is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { is_public: is_public, - module_def: Some(module), + module_def: Some(Rc::new(module)), type_def: type_def.type_def, type_span: None, }); @@ -653,9 +652,9 @@ impl NameBindings { } /// Returns the module node if applicable. - fn get_module_if_available(&self) -> Option<@Module> { + fn get_module_if_available(&self) -> Option> { match *self.type_def.borrow() { - Some(ref type_def) => (*type_def).module_def, + Some(ref type_def) => type_def.module_def.clone(), None => None } } @@ -664,7 +663,7 @@ impl NameBindings { * Returns the module node. Fails if this node does not have a module * definition. */ - fn get_module(&self) -> @Module { + fn get_module(&self) -> Rc { match self.get_module_if_available() { None => { fail!("get_module called on a node with no module \ @@ -684,10 +683,10 @@ impl NameBindings { fn defined_in_public_namespace(&self, namespace: Namespace) -> bool { match namespace { TypeNS => match *self.type_def.borrow() { - Some(def) => def.is_public, None => false + Some(ref def) => def.is_public, None => false }, ValueNS => match *self.value_def.borrow() { - Some(def) => def.is_public, None => false + Some(ref def) => def.is_public, None => false } } } @@ -697,12 +696,12 @@ impl NameBindings { TypeNS => { match *self.type_def.borrow() { None => None, - Some(type_def) => { + Some(ref type_def) => { match type_def.type_def { Some(type_def) => Some(type_def), None => { match type_def.module_def { - Some(module) => { + Some(ref module) => { match module.def_id.get() { Some(did) => Some(DefMod(did)), None => None, @@ -730,13 +729,13 @@ impl NameBindings { TypeNS => { match *self.type_def.borrow() { None => None, - Some(type_def) => type_def.type_span + Some(ref type_def) => type_def.type_span } } ValueNS => { match *self.value_def.borrow() { None => None, - Some(value_def) => value_def.value_span + Some(ref value_def) => value_def.value_span } } } @@ -799,9 +798,9 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str { } fn Resolver<'a>(session: &'a Session, - lang_items: @LanguageItems, + lang_items: &'a LanguageItems, crate_span: Span) -> Resolver<'a> { - let graph_root = @NameBindings(); + let graph_root = NameBindings(); graph_root.define_module(NoParentLink, Some(DefId { krate: 0, node: 0 }), @@ -821,27 +820,27 @@ fn Resolver<'a>(session: &'a Session, graph_root: graph_root, - method_map: @RefCell::new(HashMap::new()), + method_set: RefCell::new(FnvHashSet::new()), structs: HashSet::new(), unresolved_imports: 0, current_module: current_module, - value_ribs: @RefCell::new(Vec::new()), - type_ribs: @RefCell::new(Vec::new()), - label_ribs: @RefCell::new(Vec::new()), + value_ribs: RefCell::new(Vec::new()), + type_ribs: RefCell::new(Vec::new()), + label_ribs: RefCell::new(Vec::new()), current_trait_refs: None, self_ident: special_idents::self_, type_self_ident: special_idents::type_self, - primitive_type_table: @PrimitiveTypeTable(), + primitive_type_table: PrimitiveTypeTable(), namespaces: vec!(TypeNS, ValueNS), - def_map: @RefCell::new(NodeMap::new()), - export_map2: @RefCell::new(NodeMap::new()), + def_map: RefCell::new(NodeMap::new()), + export_map2: RefCell::new(NodeMap::new()), trait_map: NodeMap::new(), used_imports: HashSet::new(), external_exports: DefIdSet::new(), @@ -856,28 +855,28 @@ fn Resolver<'a>(session: &'a Session, /// The main resolver class. struct Resolver<'a> { session: &'a Session, - lang_items: @LanguageItems, + lang_items: &'a LanguageItems, - graph_root: @NameBindings, + graph_root: NameBindings, - method_map: @RefCell>>, + method_set: RefCell>, structs: HashSet, // The number of imports that are currently unresolved. unresolved_imports: uint, // The module that represents the current item scope. - current_module: @Module, + current_module: Rc, // The current set of local scopes, for values. // FIXME #4948: Reuse ribs to avoid allocation. - value_ribs: @RefCell >, + value_ribs: RefCell>, // The current set of local scopes, for types. - type_ribs: @RefCell >, + type_ribs: RefCell>, // The current set of local scopes, for labels. - label_ribs: @RefCell >, + label_ribs: RefCell>, // The trait that the current context can refer to. current_trait_refs: Option >, @@ -888,7 +887,7 @@ struct Resolver<'a> { type_self_ident: Ident, // The idents for the primitive types. - primitive_type_table: @PrimitiveTypeTable, + primitive_type_table: PrimitiveTypeTable, // The four namespaces. namespaces: Vec , @@ -921,10 +920,10 @@ impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> { fn visit_foreign_item(&mut self, foreign_item: &ForeignItem, context: ReducedGraphParent) { self.resolver.build_reduced_graph_for_foreign_item(foreign_item, - context, - |r, c| { + context.clone(), + |r| { let mut v = BuildReducedGraphVisitor{ resolver: r }; - visit::walk_foreign_item(&mut v, foreign_item, c); + visit::walk_foreign_item(&mut v, foreign_item, context.clone()); }) } @@ -982,17 +981,6 @@ impl<'a> Resolver<'a> { visit::walk_crate(&mut visitor, krate, initial_parent); } - /// Returns the current module tracked by the reduced graph parent. - fn get_module_from_parent(&mut self, - reduced_graph_parent: ReducedGraphParent) - -> @Module { - match reduced_graph_parent { - ModuleReducedGraphParent(module_) => { - return module_; - } - } - } - /** * Adds a new child item to the module definition of the parent node and * returns its corresponding name bindings as well as the current parent. @@ -1003,32 +991,26 @@ impl<'a> Resolver<'a> { * If this node does not have a module definition and we are not inside * a block, fails. */ - fn add_child(&mut self, - name: Ident, - reduced_graph_parent: ReducedGraphParent, - duplicate_checking_mode: DuplicateCheckingMode, - // For printing errors - sp: Span) - -> (@NameBindings, ReducedGraphParent) { + fn add_child(&self, + name: Ident, + reduced_graph_parent: ReducedGraphParent, + duplicate_checking_mode: DuplicateCheckingMode, + // For printing errors + sp: Span) + -> Rc { // If this is the immediate descendant of a module, then we add the // child name directly. Otherwise, we create or reuse an anonymous // module and add the child to that. - let module_; - match reduced_graph_parent { - ModuleReducedGraphParent(parent_module) => { - module_ = parent_module; - } - } + let module_ = reduced_graph_parent.module(); // Add or reuse the child. - let new_parent = ModuleReducedGraphParent(module_); - let child_opt = module_.children.borrow().find_copy(&name.name); - match child_opt { + let child = module_.children.borrow().find_copy(&name.name); + match child { None => { - let child = @NameBindings(); - module_.children.borrow_mut().insert(name.name, child); - return (child, new_parent); + let child = Rc::new(NameBindings()); + module_.children.borrow_mut().insert(name.name, child.clone()); + child } Some(child) => { // Enforce the duplicate checking mode: @@ -1105,7 +1087,7 @@ impl<'a> Resolver<'a> { } } } - return (child, new_parent); + child } } } @@ -1145,7 +1127,7 @@ impl<'a> Resolver<'a> { -> ParentLink { match parent { ModuleReducedGraphParent(module_) => { - return ModuleParentLink(module_, name); + return ModuleParentLink(module_.downgrade(), name); } } } @@ -1162,10 +1144,10 @@ impl<'a> Resolver<'a> { match item.node { ItemMod(..) => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ForbidDuplicateModules, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp); - let parent_link = self.get_parent_link(new_parent, ident); + let parent_link = self.get_parent_link(parent, ident); let def_id = DefId { krate: 0, node: item.id }; name_bindings.define_module(parent_link, Some(def_id), @@ -1181,8 +1163,8 @@ impl<'a> Resolver<'a> { // These items live in the value namespace. ItemStatic(_, m, _) => { - let (name_bindings, _) = - self.add_child(ident, parent, ForbidDuplicateValues, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp); let mutbl = m == ast::MutMutable; name_bindings.define_value @@ -1190,18 +1172,18 @@ impl<'a> Resolver<'a> { parent } ItemFn(_, fn_style, _, _, _) => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ForbidDuplicateValues, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp); let def = DefFn(local_def(item.id), fn_style); name_bindings.define_value(def, sp, is_public); - new_parent + parent } // These items live in the type namespace. ItemTy(..) => { - let (name_bindings, _) = - self.add_child(ident, parent, ForbidDuplicateTypes, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); name_bindings.define_type (DefTy(local_def(item.id)), sp, is_public); @@ -1209,8 +1191,8 @@ impl<'a> Resolver<'a> { } ItemEnum(ref enum_definition, _) => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ForbidDuplicateTypes, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); name_bindings.define_type (DefTy(local_def(item.id)), sp, is_public); @@ -1219,7 +1201,7 @@ impl<'a> Resolver<'a> { self.build_reduced_graph_for_variant( variant, local_def(item.id), - new_parent, + parent.clone(), is_public); } parent @@ -1233,7 +1215,7 @@ impl<'a> Resolver<'a> { None => (ForbidDuplicateTypes, None) }; - let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp); + let name_bindings = self.add_child(ident, parent.clone(), forbid, sp); // Define a name in the type namespace. name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public); @@ -1249,7 +1231,7 @@ impl<'a> Resolver<'a> { // Record the def ID of this struct. self.structs.insert(local_def(item.id)); - new_parent + parent } ItemImpl(_, None, ty, ref methods) => { @@ -1270,7 +1252,7 @@ impl<'a> Resolver<'a> { .find_copy(&name.name); let new_parent = match parent_opt { // It already exists - Some(child) if child.get_module_if_available() + Some(ref child) if child.get_module_if_available() .is_some() && child.get_module().kind.get() == ImplModuleKind => { @@ -1278,14 +1260,14 @@ impl<'a> Resolver<'a> { } // Create the module _ => { - let (name_bindings, new_parent) = + let name_bindings = self.add_child(name, - parent, + parent.clone(), ForbidDuplicateModules, sp); let parent_link = - self.get_parent_link(new_parent, ident); + self.get_parent_link(parent.clone(), ident); let def_id = local_def(item.id); let ns = TypeNS; let is_public = @@ -1308,9 +1290,9 @@ impl<'a> Resolver<'a> { for method in methods.iter() { // Add the method to the module. let ident = method.ident; - let (method_name_bindings, _) = + let method_name_bindings = self.add_child(ident, - new_parent, + new_parent.clone(), ForbidDuplicateValues, method.span); let def = match method.explicit_self.node { @@ -1344,11 +1326,11 @@ impl<'a> Resolver<'a> { ItemImpl(_, Some(_), _, _) => parent, ItemTrait(_, _, ref methods) => { - let (name_bindings, new_parent) = - self.add_child(ident, parent, ForbidDuplicateTypes, sp); + let name_bindings = + self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp); // Add all the methods within to a new module. - let parent_link = self.get_parent_link(parent, ident); + let parent_link = self.get_parent_link(parent.clone(), ident); name_bindings.define_module(parent_link, Some(local_def(item.id)), TraitModuleKind, @@ -1358,8 +1340,9 @@ impl<'a> Resolver<'a> { let module_parent = ModuleReducedGraphParent(name_bindings. get_module()); + let def_id = local_def(item.id); + // Add the names of all the methods to the trait info. - let mut method_names = HashMap::new(); for method in methods.iter() { let ty_m = trait_method_to_ty_method(method); @@ -1380,36 +1363,21 @@ impl<'a> Resolver<'a> { } }; - let (method_name_bindings, _) = + let method_name_bindings = self.add_child(ident, - module_parent, + module_parent.clone(), ForbidDuplicateValues, ty_m.span); method_name_bindings.define_value(def, ty_m.span, true); // Add it to the trait info if not static. - match ty_m.explicit_self.node { - SelfStatic => {} - _ => { - method_names.insert(ident.name, ()); - } - } - } - - let def_id = local_def(item.id); - for (name, _) in method_names.iter() { - let mut method_map = self.method_map.borrow_mut(); - if !method_map.contains_key(name) { - method_map.insert(*name, HashSet::new()); - } - match method_map.find_mut(name) { - Some(s) => { s.insert(def_id); }, - _ => fail!("can't happen"), + if ty_m.explicit_self.node != SelfStatic { + self.method_set.borrow_mut().insert((ident.name, def_id)); } } name_bindings.define_type(DefTrait(def_id), sp, is_public); - new_parent + parent } ItemMac(..) => parent } @@ -1426,15 +1394,15 @@ impl<'a> Resolver<'a> { match variant.node.kind { TupleVariantKind(_) => { - let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues, - variant.span); + let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span); child.define_value(DefVariant(item_id, local_def(variant.node.id), false), variant.span, is_public); } StructVariantKind(_) => { - let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues, - variant.span); + let child = self.add_child(ident, parent, + ForbidDuplicateTypesAndValues, + variant.span); child.define_type(DefVariant(item_id, local_def(variant.node.id), true), variant.span, is_public); @@ -1478,15 +1446,15 @@ impl<'a> Resolver<'a> { } // Build up the import directives. - let module_ = self.get_module_from_parent(parent); + let module_ = parent.module(); let is_public = view_item.vis == ast::Public; match view_path.node { ViewPathSimple(binding, ref full_path, id) => { let source_ident = full_path.segments.last().unwrap().identifier; - let subclass = @SingleImport(binding, - source_ident); - self.build_import_directive(module_, + let subclass = SingleImport(binding, + source_ident); + self.build_import_directive(&*module_, module_path, subclass, view_path.span, @@ -1496,20 +1464,19 @@ impl<'a> Resolver<'a> { ViewPathList(_, ref source_idents, _) => { for source_ident in source_idents.iter() { let name = source_ident.node.name; - let subclass = @SingleImport(name, name); self.build_import_directive( - module_, + &*module_, module_path.clone(), - subclass, + SingleImport(name, name), source_ident.span, source_ident.node.id, is_public); } } ViewPathGlob(_, id) => { - self.build_import_directive(module_, + self.build_import_directive(&*module_, module_path, - @GlobImport, + GlobImport, view_path.span, id, is_public); @@ -1525,16 +1492,16 @@ impl<'a> Resolver<'a> { let def_id = DefId { krate: crate_id, node: 0 }; self.external_exports.insert(def_id); let parent_link = ModuleParentLink - (self.get_module_from_parent(parent), name); - let external_module = @Module::new(parent_link, - Some(def_id), - NormalModuleKind, - false, - true); + (parent.module().downgrade(), name); + let external_module = Rc::new(Module::new(parent_link, + Some(def_id), + NormalModuleKind, + false, + true)); parent.module().external_module_children .borrow_mut().insert(name.name, - external_module); + external_module.clone()); self.build_reduced_graph_for_external_crate( external_module); @@ -1549,11 +1516,10 @@ impl<'a> Resolver<'a> { fn build_reduced_graph_for_foreign_item(&mut self, foreign_item: &ForeignItem, parent: ReducedGraphParent, - f: |&mut Resolver, - ReducedGraphParent|) { + f: |&mut Resolver|) { let name = foreign_item.ident; let is_public = foreign_item.vis == ast::Public; - let (name_bindings, new_parent) = + let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, foreign_item.span); @@ -1567,13 +1533,13 @@ impl<'a> Resolver<'a> { foreign_item.id, 0, NormalRibKind), - |this| f(this, new_parent)); + f); } ForeignItemStatic(_, m) => { let def = DefStatic(local_def(foreign_item.id), m); name_bindings.define_value(def, foreign_item.span, is_public); - f(self, new_parent) + f(self) } } } @@ -1590,15 +1556,15 @@ impl<'a> Resolver<'a> { anonymous module for block {}", block_id); - let parent_module = self.get_module_from_parent(parent); - let new_module = @Module::new( - BlockParentLink(parent_module, block_id), + let parent_module = parent.module(); + let new_module = Rc::new(Module::new( + BlockParentLink(parent_module.downgrade(), block_id), None, AnonymousModuleKind, false, - false); + false)); parent_module.anonymous_children.borrow_mut() - .insert(block_id, new_module); + .insert(block_id, new_module.clone()); ModuleReducedGraphParent(new_module) } else { parent @@ -1608,7 +1574,7 @@ impl<'a> Resolver<'a> { fn handle_external_def(&mut self, def: Def, vis: Visibility, - child_name_bindings: @NameBindings, + child_name_bindings: &NameBindings, final_ident: &str, ident: Ident, new_parent: ReducedGraphParent) { @@ -1617,7 +1583,7 @@ impl<'a> Resolver<'a> { vis); let is_public = vis == ast::Public; let is_exported = is_public && match new_parent { - ModuleReducedGraphParent(module) => { + ModuleReducedGraphParent(ref module) => { match module.def_id.get() { None => true, Some(did) => self.external_exports.contains(&did) @@ -1641,7 +1607,7 @@ impl<'a> Resolver<'a> { debug!("(building reduced graph for \ external crate) building module \ {}", final_ident); - let parent_link = self.get_parent_link(new_parent, ident); + let parent_link = self.get_parent_link(new_parent.clone(), ident); child_name_bindings.define_module(parent_link, Some(def_id), @@ -1685,7 +1651,6 @@ impl<'a> Resolver<'a> { let method_def_ids = csearch::get_trait_method_def_ids(&self.session.cstore, def_id); - let mut interned_method_names = HashSet::new(); for &method_def_id in method_def_ids.iter() { let (method_name, explicit_self) = csearch::get_method_name_and_explicit_self(&self.session.cstore, @@ -1698,22 +1663,12 @@ impl<'a> Resolver<'a> { // Add it to the trait info if not static. if explicit_self != SelfStatic { - interned_method_names.insert(method_name.name); + self.method_set.borrow_mut().insert((method_name.name, def_id)); } if is_exported { self.external_exports.insert(method_def_id); } } - for name in interned_method_names.iter() { - let mut method_map = self.method_map.borrow_mut(); - if !method_map.contains_key(name) { - method_map.insert(*name, HashSet::new()); - } - match method_map.find_mut(name) { - Some(s) => { s.insert(def_id); }, - _ => fail!("can't happen"), - } - } child_name_bindings.define_type(def, DUMMY_SP, is_public); @@ -1758,7 +1713,7 @@ impl<'a> Resolver<'a> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_def(&mut self, - root: @Module, + root: Rc, def_like: DefLike, ident: Ident, visibility: Visibility) { @@ -1775,25 +1730,25 @@ impl<'a> Resolver<'a> { child_ident, vis| { self.build_reduced_graph_for_external_crate_def( - root, + root.clone(), def_like, child_ident, vis) }); } _ => { - let (child_name_bindings, new_parent) = + let child_name_bindings = self.add_child(ident, - ModuleReducedGraphParent(root), + ModuleReducedGraphParent(root.clone()), OverwriteDuplicates, DUMMY_SP); self.handle_external_def(def, visibility, - child_name_bindings, + &*child_name_bindings, token::get_ident(ident).get(), ident, - new_parent); + ModuleReducedGraphParent(root)); } } } @@ -1812,10 +1767,10 @@ impl<'a> Resolver<'a> { static methods for type name {}", token::get_ident(final_ident)); - let (child_name_bindings, new_parent) = + let child_name_bindings = self.add_child( final_ident, - ModuleReducedGraphParent(root), + ModuleReducedGraphParent(root.clone()), OverwriteDuplicates, DUMMY_SP); @@ -1838,7 +1793,7 @@ impl<'a> Resolver<'a> { } Some(_) | None => { let parent_link = - self.get_parent_link(new_parent, + self.get_parent_link(ModuleReducedGraphParent(root), final_ident); child_name_bindings.define_module( parent_link, @@ -1864,9 +1819,9 @@ impl<'a> Resolver<'a> { static method '{}'", token::get_ident(ident)); - let (method_name_bindings, _) = + let method_name_bindings = self.add_child(ident, - new_parent, + new_parent.clone(), OverwriteDuplicates, DUMMY_SP); let def = DefFn( @@ -1893,9 +1848,9 @@ impl<'a> Resolver<'a> { } /// Builds the reduced graph rooted at the given external module. - fn populate_external_module(&mut self, module: @Module) { + fn populate_external_module(&mut self, module: Rc) { debug!("(populating external module) attempting to populate {}", - self.module_to_str(module)); + self.module_to_str(&*module)); let def_id = match module.def_id.get() { None => { @@ -1910,7 +1865,7 @@ impl<'a> Resolver<'a> { |def_like, child_ident, visibility| { debug!("(populating external module) ... found ident: {}", token::get_ident(child_ident)); - self.build_reduced_graph_for_external_crate_def(module, + self.build_reduced_graph_for_external_crate_def(module.clone(), def_like, child_ident, visibility) @@ -1920,24 +1875,23 @@ impl<'a> Resolver<'a> { /// Ensures that the reduced graph rooted at the given external module /// is built, building it if it is not. - fn populate_module_if_necessary(&mut self, module: @Module) { + fn populate_module_if_necessary(&mut self, module: &Rc) { if !module.populated.get() { - self.populate_external_module(module) + self.populate_external_module(module.clone()) } assert!(module.populated.get()) } /// Builds the reduced graph rooted at the 'use' directive for an external /// crate. - fn build_reduced_graph_for_external_crate(&mut self, - root: @Module) { + fn build_reduced_graph_for_external_crate(&mut self, root: Rc) { csearch::each_top_level_item_of_crate(&self.session.cstore, root.def_id .get() .unwrap() .krate, |def_like, ident, visibility| { - self.build_reduced_graph_for_external_crate_def(root, + self.build_reduced_graph_for_external_crate_def(root.clone(), def_like, ident, visibility) @@ -1946,47 +1900,48 @@ impl<'a> Resolver<'a> { /// Creates and adds an import directive to the given module. fn build_import_directive(&mut self, - module_: @Module, + module_: &Module, module_path: Vec , - subclass: @ImportDirectiveSubclass, + subclass: ImportDirectiveSubclass, span: Span, id: NodeId, is_public: bool) { - let directive = @ImportDirective::new(module_path, - subclass, span, id, - is_public); - module_.imports.borrow_mut().push(directive); + module_.imports.borrow_mut().push(ImportDirective::new(module_path, + subclass, + span, id, + is_public)); + self.unresolved_imports += 1; // Bump the reference count on the name. Or, if this is a glob, set // the appropriate flag. - match *subclass { + match subclass { SingleImport(target, _) => { debug!("(building import directive) building import \ directive: {}::{}", - self.idents_to_str(directive.module_path.as_slice()), + self.idents_to_str(module_.imports.borrow().last().unwrap() + .module_path.as_slice()), token::get_ident(target)); let mut import_resolutions = module_.import_resolutions .borrow_mut(); - match import_resolutions.find(&target.name) { - Some(&resolution) => { + match import_resolutions.find_mut(&target.name) { + Some(resolution) => { debug!("(building import directive) bumping \ reference"); - resolution.outstanding_references.set( - resolution.outstanding_references.get() + 1); + resolution.outstanding_references += 1; // the source of this name is different now - resolution.type_id.set(id); - resolution.value_id.set(id); - resolution.is_public.set(is_public); - } - None => { - debug!("(building import directive) creating new"); - let resolution = @ImportResolution::new(id, is_public); - resolution.outstanding_references.set(1); - import_resolutions.insert(target.name, resolution); + resolution.type_id = id; + resolution.value_id = id; + resolution.is_public = is_public; + return; } + None => {} } + debug!("(building import directive) creating new"); + let mut resolution = ImportResolution::new(id, is_public); + resolution.outstanding_references = 1; + import_resolutions.insert(target.name, resolution); } GlobImport => { // Set the glob flag. This tells us that we don't know the @@ -1995,8 +1950,6 @@ impl<'a> Resolver<'a> { module_.glob_count.set(module_.glob_count.get() + 1); } } - - self.unresolved_imports += 1; } // Import resolution @@ -2017,7 +1970,7 @@ impl<'a> Resolver<'a> { i, self.unresolved_imports); let module_root = self.graph_root.get_module(); - self.resolve_imports_for_module_subtree(module_root); + self.resolve_imports_for_module_subtree(module_root.clone()); if self.unresolved_imports == 0 { debug!("(resolving imports) success"); @@ -2036,14 +1989,13 @@ impl<'a> Resolver<'a> { /// Attempts to resolve imports for the given module and all of its /// submodules. - fn resolve_imports_for_module_subtree(&mut self, - module_: @Module) { + fn resolve_imports_for_module_subtree(&mut self, module_: Rc) { debug!("(resolving imports for module subtree) resolving {}", - self.module_to_str(module_)); - self.resolve_imports_for_module(module_); + self.module_to_str(&*module_)); + self.resolve_imports_for_module(module_.clone()); - self.populate_module_if_necessary(module_); - for (_, &child_node) in module_.children.borrow().iter() { + self.populate_module_if_necessary(&module_); + for (_, child_node) in module_.children.borrow().iter() { match child_node.get_module_if_available() { None => { // Nothing to do. @@ -2054,17 +2006,17 @@ impl<'a> Resolver<'a> { } } - for (_, &child_module) in module_.anonymous_children.borrow().iter() { - self.resolve_imports_for_module_subtree(child_module); + for (_, child_module) in module_.anonymous_children.borrow().iter() { + self.resolve_imports_for_module_subtree(child_module.clone()); } } /// Attempts to resolve imports for the given module only. - fn resolve_imports_for_module(&mut self, module: @Module) { + fn resolve_imports_for_module(&mut self, module: Rc) { if module.all_imports_resolved() { debug!("(resolving imports for module) all imports resolved for \ {}", - self.module_to_str(module)); + self.module_to_str(&*module)); return; } @@ -2072,15 +2024,15 @@ impl<'a> Resolver<'a> { let import_count = imports.len(); while module.resolved_import_count.get() < import_count { let import_index = module.resolved_import_count.get(); - let import_directive = *imports.get(import_index); - match self.resolve_import_for_module(module, import_directive) { + let import_directive = imports.get(import_index); + match self.resolve_import_for_module(module.clone(), import_directive) { Failed => { // We presumably emitted an error. Continue. let msg = format!("failed to resolve import `{}`", self.import_path_to_str( import_directive.module_path .as_slice(), - *import_directive.subclass)); + import_directive.subclass)); self.resolve_error(import_directive.span, msg); } Indeterminate => { @@ -2149,8 +2101,8 @@ impl<'a> Resolver<'a> { /// currently-unresolved imports, or success if we know the name exists. /// If successful, the resolved bindings are written into the module. fn resolve_import_for_module(&mut self, - module_: @Module, - import_directive: @ImportDirective) + module_: Rc, + import_directive: &ImportDirective) -> ResolveResult<()> { let mut resolution_result = Failed; let module_path = &import_directive.module_path; @@ -2158,14 +2110,14 @@ impl<'a> Resolver<'a> { debug!("(resolving import for module) resolving import `{}::...` in \ `{}`", self.idents_to_str(module_path.as_slice()), - self.module_to_str(module_)); + self.module_to_str(&*module_)); // First, resolve the module path for the directive, if necessary. let container = if module_path.len() == 0 { // Use the crate root. Some((self.graph_root.get_module(), LastMod(AllPublic))) } else { - match self.resolve_module_path(module_, + match self.resolve_module_path(module_.clone(), module_path.as_slice(), DontUseLexicalScope, import_directive.span, @@ -2186,10 +2138,10 @@ impl<'a> Resolver<'a> { // We found the module that the target is contained // within. Attempt to resolve the import within it. - match *import_directive.subclass { + match import_directive.subclass { SingleImport(target, source) => { resolution_result = - self.resolve_single_import(module_, + self.resolve_single_import(&*module_, containing_module, target, source, @@ -2198,7 +2150,7 @@ impl<'a> Resolver<'a> { } GlobImport => { resolution_result = - self.resolve_glob_import(module_, + self.resolve_glob_import(&*module_, containing_module, import_directive.id, import_directive.is_public, @@ -2225,7 +2177,7 @@ impl<'a> Resolver<'a> { // resolve_imports_for_module.) if !resolution_result.indeterminate() { - match *import_directive.subclass { + match import_directive.subclass { GlobImport => { assert!(module_.glob_count.get() >= 1); module_.glob_count.set(module_.glob_count.get() - 1); @@ -2239,7 +2191,7 @@ impl<'a> Resolver<'a> { return resolution_result; } - fn create_name_bindings_from_module(module: @Module) -> NameBindings { + fn create_name_bindings_from_module(module: Rc) -> NameBindings { NameBindings { type_def: RefCell::new(Some(TypeNsDef { is_public: false, @@ -2252,8 +2204,8 @@ impl<'a> Resolver<'a> { } fn resolve_single_import(&mut self, - module_: @Module, - containing_module: @Module, + module_: &Module, + containing_module: Rc, target: Ident, source: Ident, directive: &ImportDirective, @@ -2262,7 +2214,7 @@ impl<'a> Resolver<'a> { debug!("(resolving single import) resolving `{}` = `{}::{}` from \ `{}` id {}, last private {:?}", token::get_ident(target), - self.module_to_str(containing_module), + self.module_to_str(&*containing_module), token::get_ident(source), self.module_to_str(module_), directive.id, @@ -2281,22 +2233,22 @@ impl<'a> Resolver<'a> { let mut type_result = UnknownResult; // Search for direct children of the containing module. - self.populate_module_if_necessary(containing_module); + self.populate_module_if_necessary(&containing_module); match containing_module.children.borrow().find(&source.name) { None => { // Continue. } - Some(child_name_bindings) => { + Some(ref child_name_bindings) => { if child_name_bindings.defined_in_namespace(ValueNS) { debug!("(resolving single import) found value binding"); - value_result = BoundResult(containing_module, - *child_name_bindings); + value_result = BoundResult(containing_module.clone(), + (*child_name_bindings).clone()); } if child_name_bindings.defined_in_namespace(TypeNS) { debug!("(resolving single import) found type binding"); - type_result = BoundResult(containing_module, - *child_name_bindings); + type_result = BoundResult(containing_module.clone(), + (*child_name_bindings).clone()); } } } @@ -2305,7 +2257,7 @@ impl<'a> Resolver<'a> { // search imports as well. let mut value_used_reexport = false; let mut type_used_reexport = false; - match (value_result, type_result) { + match (value_result.clone(), type_result.clone()) { (BoundResult(..), BoundResult(..)) => {} // Continue. _ => { // If there is an unresolved glob at this point in the @@ -2318,12 +2270,8 @@ impl<'a> Resolver<'a> { return Indeterminate; } - // Now search the exported imports within the containing - // module. - - let import_resolutions = containing_module.import_resolutions - .borrow(); - match import_resolutions.find(&source.name) { + // Now search the exported imports within the containing module. + match containing_module.import_resolutions.borrow().find(&source.name) { None => { debug!("(resolving single import) no import"); // The containing module definitely doesn't have an @@ -2339,32 +2287,30 @@ impl<'a> Resolver<'a> { } } Some(import_resolution) - if import_resolution.outstanding_references.get() - == 0 => { + if import_resolution.outstanding_references == 0 => { fn get_binding(this: &mut Resolver, - import_resolution: @ImportResolution, + import_resolution: &ImportResolution, namespace: Namespace) -> NamespaceResult { // Import resolutions must be declared with "pub" // in order to be exported. - if !import_resolution.is_public.get() { + if !import_resolution.is_public { return UnboundResult; } - match (*import_resolution). + match import_resolution. target_for_namespace(namespace) { None => { return UnboundResult; } - Some(target) => { + Some(Target {target_module, bindings}) => { debug!("(resolving single import) found \ import in ns {:?}", namespace); let id = import_resolution.id(namespace); this.used_imports.insert((id, namespace)); - return BoundResult(target.target_module, - target.bindings); + return BoundResult(target_module, bindings); } } } @@ -2372,14 +2318,14 @@ impl<'a> Resolver<'a> { // The name is an import which has been fully // resolved. We can, therefore, just follow it. if value_result.is_unknown() { - value_result = get_binding(self, *import_resolution, + value_result = get_binding(self, import_resolution, ValueNS); - value_used_reexport = import_resolution.is_public.get(); + value_used_reexport = import_resolution.is_public; } if type_result.is_unknown() { - type_result = get_binding(self, *import_resolution, + type_result = get_binding(self, import_resolution, TypeNS); - type_used_reexport = import_resolution.is_public.get(); + type_used_reexport = import_resolution.is_public; } } @@ -2407,9 +2353,9 @@ impl<'a> Resolver<'a> { debug!("(resolving single import) found external \ module"); let name_bindings = - @Resolver::create_name_bindings_from_module( - module); - type_result = BoundResult(containing_module, + Rc::new(Resolver::create_name_bindings_from_module( + module)); + type_result = BoundResult(containing_module.clone(), name_bindings); type_used_public = true; } @@ -2418,18 +2364,15 @@ impl<'a> Resolver<'a> { } // We've successfully resolved the import. Write the results in. - let import_resolution = { - let import_resolutions = module_.import_resolutions.borrow(); - assert!(import_resolutions.contains_key(&target.name)); - import_resolutions.get_copy(&target.name) - }; + let mut import_resolutions = module_.import_resolutions.borrow_mut(); + let import_resolution = import_resolutions.get_mut(&target.name); match value_result { - BoundResult(target_module, name_bindings) => { + BoundResult(ref target_module, ref name_bindings) => { debug!("(resolving single import) found value target"); - *import_resolution.value_target.borrow_mut() = - Some(Target::new(target_module, name_bindings)); - import_resolution.value_id.set(directive.id); + import_resolution.value_target = Some(Target::new(target_module.clone(), + name_bindings.clone())); + import_resolution.value_id = directive.id; value_used_public = name_bindings.defined_in_public_namespace(ValueNS); } UnboundResult => { /* Continue. */ } @@ -2438,12 +2381,12 @@ impl<'a> Resolver<'a> { } } match type_result { - BoundResult(target_module, name_bindings) => { + BoundResult(ref target_module, ref name_bindings) => { debug!("(resolving single import) found type target: {:?}", { name_bindings.type_def.borrow().clone().unwrap().type_def }); - *import_resolution.type_target.borrow_mut() = - Some(Target::new(target_module, name_bindings)); - import_resolution.type_id.set(directive.id); + import_resolution.type_target = + Some(Target::new(target_module.clone(), name_bindings.clone())); + import_resolution.type_id = directive.id; type_used_public = name_bindings.defined_in_public_namespace(TypeNS); } UnboundResult => { /* Continue. */ } @@ -2456,22 +2399,21 @@ impl<'a> Resolver<'a> { let msg = format!("unresolved import: there is no \ `{}` in `{}`", token::get_ident(source), - self.module_to_str(containing_module)); + self.module_to_str(&*containing_module)); self.resolve_error(directive.span, msg); return Failed; } let value_used_public = value_used_reexport || value_used_public; let type_used_public = type_used_reexport || type_used_public; - assert!(import_resolution.outstanding_references.get() >= 1); - import_resolution.outstanding_references.set( - import_resolution.outstanding_references.get() - 1); + assert!(import_resolution.outstanding_references >= 1); + import_resolution.outstanding_references -= 1; // record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. - let value_private = match *import_resolution.value_target.borrow() { - Some(target) => { + let value_private = match import_resolution.value_target { + Some(ref target) => { let def = target.bindings.def_for_namespace(ValueNS).unwrap(); self.def_map.borrow_mut().insert(directive.id, def); let did = def_id_of_def(def); @@ -2481,8 +2423,8 @@ impl<'a> Resolver<'a> { // _exists is false. None => None, }; - let type_private = match *import_resolution.type_target.borrow() { - Some(target) => { + let type_private = match import_resolution.type_target { + Some(ref target) => { let def = target.bindings.def_for_namespace(TypeNS).unwrap(); self.def_map.borrow_mut().insert(directive.id, def); let did = def_id_of_def(def); @@ -2504,8 +2446,8 @@ impl<'a> Resolver<'a> { // succeeds or bails out (as importing * from an empty module or a module // that exports nothing is valid). fn resolve_glob_import(&mut self, - module_: @Module, - containing_module: @Module, + module_: &Module, + containing_module: Rc, id: NodeId, is_public: bool, lp: LastPrivate) @@ -2531,70 +2473,71 @@ impl<'a> Resolver<'a> { for (ident, target_import_resolution) in import_resolutions.iter() { debug!("(resolving glob import) writing module resolution \ {:?} into `{}`", - target_import_resolution.type_target.borrow().is_none(), + target_import_resolution.type_target.is_none(), self.module_to_str(module_)); - if !target_import_resolution.is_public.get() { + if !target_import_resolution.is_public { debug!("(resolving glob import) nevermind, just kidding"); continue } // Here we merge two import resolutions. let mut import_resolutions = module_.import_resolutions.borrow_mut(); - match import_resolutions.find(ident) { - None => { - // Simple: just copy the old import resolution. - let new_import_resolution = - @ImportResolution::new(id, is_public); - *new_import_resolution.value_target.borrow_mut() = - get(&target_import_resolution.value_target); - *new_import_resolution.type_target.borrow_mut() = - get(&target_import_resolution.type_target); - - import_resolutions.insert - (*ident, new_import_resolution); - } - Some(&dest_import_resolution) => { + match import_resolutions.find_mut(ident) { + Some(dest_import_resolution) => { // Merge the two import resolutions at a finer-grained // level. - match *target_import_resolution.value_target.borrow() { + match target_import_resolution.value_target { None => { // Continue. } - Some(value_target) => { - *dest_import_resolution.value_target.borrow_mut() = Some(value_target); + Some(ref value_target) => { + dest_import_resolution.value_target = + Some(value_target.clone()); } } - match *target_import_resolution.type_target.borrow() { + match target_import_resolution.type_target { None => { // Continue. } - Some(type_target) => { - *dest_import_resolution.type_target.borrow_mut() = Some(type_target); + Some(ref type_target) => { + dest_import_resolution.type_target = + Some(type_target.clone()); } } - dest_import_resolution.is_public.set(is_public); + dest_import_resolution.is_public = is_public; + continue; } + None => {} } + + // Simple: just copy the old import resolution. + let mut new_import_resolution = ImportResolution::new(id, is_public); + new_import_resolution.value_target = + target_import_resolution.value_target.clone(); + new_import_resolution.type_target = + target_import_resolution.type_target.clone(); + + import_resolutions.insert(*ident, new_import_resolution); } // Add all children from the containing module. - self.populate_module_if_necessary(containing_module); + self.populate_module_if_necessary(&containing_module); for (&name, name_bindings) in containing_module.children .borrow().iter() { - self.merge_import_resolution(module_, containing_module, + self.merge_import_resolution(module_, containing_module.clone(), id, is_public, - name, *name_bindings); + name, name_bindings.clone()); } // Add external module children from the containing module. for (&name, module) in containing_module.external_module_children .borrow().iter() { let name_bindings = - @Resolver::create_name_bindings_from_module(*module); - self.merge_import_resolution(module_, containing_module, + Rc::new(Resolver::create_name_bindings_from_module(module.clone())); + self.merge_import_resolution(module_, containing_module.clone(), id, is_public, name, name_bindings); } @@ -2613,58 +2556,49 @@ impl<'a> Resolver<'a> { } fn merge_import_resolution(&mut self, - module_: @Module, - containing_module: @Module, + module_: &Module, + containing_module: Rc, id: NodeId, is_public: bool, name: Name, - name_bindings: @NameBindings) { - let dest_import_resolution; + name_bindings: Rc) { let mut import_resolutions = module_.import_resolutions.borrow_mut(); - match import_resolutions.find(&name) { - None => { - // Create a new import resolution from this child. - dest_import_resolution = - @ImportResolution::new(id, is_public); - import_resolutions.insert(name, - dest_import_resolution); - } - Some(&existing_import_resolution) => { - dest_import_resolution = existing_import_resolution; - } - } + let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| { + // Create a new import resolution from this child. + ImportResolution::new(id, is_public) + }); debug!("(resolving glob import) writing resolution `{}` in `{}` \ to `{}`", token::get_name(name).get().to_str(), - self.module_to_str(containing_module), + self.module_to_str(&*containing_module), self.module_to_str(module_)); // Merge the child item into the import resolution. if name_bindings.defined_in_public_namespace(ValueNS) { debug!("(resolving glob import) ... for value target"); - *dest_import_resolution.value_target.borrow_mut() = - Some(Target::new(containing_module, name_bindings)); - dest_import_resolution.value_id.set(id); + dest_import_resolution.value_target = + Some(Target::new(containing_module.clone(), name_bindings.clone())); + dest_import_resolution.value_id = id; } if name_bindings.defined_in_public_namespace(TypeNS) { debug!("(resolving glob import) ... for type target"); - *dest_import_resolution.type_target.borrow_mut() = - Some(Target::new(containing_module, name_bindings)); - dest_import_resolution.type_id.set(id); + dest_import_resolution.type_target = + Some(Target::new(containing_module, name_bindings.clone())); + dest_import_resolution.type_id = id; } - dest_import_resolution.is_public.set(is_public); + dest_import_resolution.is_public = is_public; } /// Resolves the given module path from the given root `module_`. fn resolve_module_path_from_root(&mut self, - module_: @Module, + module_: Rc, module_path: &[Ident], index: uint, span: Span, name_search_type: NameSearchType, lp: LastPrivate) - -> ResolveResult<(@Module, LastPrivate)> { + -> ResolveResult<(Rc, LastPrivate)> { let mut search_module = module_; let mut index = index; let module_path_len = module_path.len(); @@ -2675,14 +2609,14 @@ impl<'a> Resolver<'a> { // modules as we go. while index < module_path_len { let name = module_path[index]; - match self.resolve_name_in_module(search_module, + match self.resolve_name_in_module(search_module.clone(), name, TypeNS, name_search_type, false) { Failed => { let segment_name = token::get_ident(name); - let module_name = self.module_to_str(search_module); + let module_name = self.module_to_str(&*search_module); if "???" == module_name { let span = Span { lo: span.lo, @@ -2710,7 +2644,7 @@ impl<'a> Resolver<'a> { // Check to see whether there are type bindings, and, if // so, whether there is a module within. match *target.bindings.type_def.borrow() { - Some(type_def) => { + Some(ref type_def) => { match type_def.module_def { None => { // Not a module. @@ -2718,7 +2652,7 @@ impl<'a> Resolver<'a> { token::get_ident(name))); return Failed; } - Some(module_def) => { + Some(ref module_def) => { // If we're doing the search for an // import, do not allow traits and impls // to be selected. @@ -2733,7 +2667,7 @@ impl<'a> Resolver<'a> { return Failed; } (_, _) => { - search_module = module_def; + search_module = module_def.clone(); // Keep track of the closest // private module used when @@ -2777,22 +2711,22 @@ impl<'a> Resolver<'a> { /// On success, returns the resolved module, and the closest *private* /// module found to the destination when resolving this path. fn resolve_module_path(&mut self, - module_: @Module, + module_: Rc, module_path: &[Ident], use_lexical_scope: UseLexicalScopeFlag, span: Span, name_search_type: NameSearchType) - -> ResolveResult<(@Module, LastPrivate)> { + -> ResolveResult<(Rc, LastPrivate)> { let module_path_len = module_path.len(); assert!(module_path_len > 0); debug!("(resolving module path for import) processing `{}` rooted at \ `{}`", self.idents_to_str(module_path), - self.module_to_str(module_)); + self.module_to_str(&*module_)); // Resolve the module prefix, if any. - let module_prefix_result = self.resolve_module_prefix(module_, + let module_prefix_result = self.resolve_module_prefix(module_.clone(), module_path); let search_module; @@ -2857,8 +2791,8 @@ impl<'a> Resolver<'a> { } } } - Success(PrefixFound(containing_module, index)) => { - search_module = containing_module; + Success(PrefixFound(ref containing_module, index)) => { + search_module = containing_module.clone(); start_index = index; last_private = LastMod(DependsOn(containing_module.def_id .get() @@ -2877,7 +2811,7 @@ impl<'a> Resolver<'a> { /// Invariant: This must only be called during main resolution, not during /// import resolution. fn resolve_item_in_lexical_scope(&mut self, - module_: @Module, + module_: Rc, name: Ident, namespace: Namespace, search_through_modules: @@ -2887,17 +2821,17 @@ impl<'a> Resolver<'a> { namespace {:?} in `{}`", token::get_ident(name), namespace, - self.module_to_str(module_)); + self.module_to_str(&*module_)); // The current module node is handled specially. First, check for // its immediate children. - self.populate_module_if_necessary(module_); + self.populate_module_if_necessary(&module_); match module_.children.borrow().find(&name.name) { Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("top name bindings succeeded"); - return Success((Target::new(module_, *name_bindings), + return Success((Target::new(module_.clone(), name_bindings.clone()), false)); } Some(_) | None => { /* Not found; continue. */ } @@ -2935,7 +2869,7 @@ impl<'a> Resolver<'a> { None => {} Some(module) => { let name_bindings = - @Resolver::create_name_bindings_from_module(module); + Rc::new(Resolver::create_name_bindings_from_module(module)); debug!("lower name bindings succeeded"); return Success((Target::new(module_, name_bindings), false)); } @@ -2946,7 +2880,7 @@ impl<'a> Resolver<'a> { let mut search_module = module_; loop { // Go to the next parent. - match search_module.parent_link { + match search_module.parent_link.clone() { NoParentLink => { // No more parents. This module was unresolved. debug!("(resolving item in lexical scope) unresolved \ @@ -2969,22 +2903,22 @@ impl<'a> Resolver<'a> { TraitModuleKind | ImplModuleKind | AnonymousModuleKind => { - search_module = parent_module_node; + search_module = parent_module_node.upgrade().unwrap(); } } } SearchThroughModules => { - search_module = parent_module_node; + search_module = parent_module_node.upgrade().unwrap(); } } } - BlockParentLink(parent_module_node, _) => { - search_module = parent_module_node; + BlockParentLink(ref parent_module_node, _) => { + search_module = parent_module_node.upgrade().unwrap(); } } // Resolve the name in the parent module. - match self.resolve_name_in_module(search_module, + match self.resolve_name_in_module(search_module.clone(), name, namespace, PathSearch, @@ -3012,9 +2946,9 @@ impl<'a> Resolver<'a> { /// Resolves a module name in the current lexical scope. fn resolve_module_in_lexical_scope(&mut self, - module_: @Module, + module_: Rc, name: Ident) - -> ResolveResult<@Module> { + -> ResolveResult> { // If this module is an anonymous module, resolve the item in the // lexical scope. Otherwise, resolve the item from the crate root. let resolve_result = self.resolve_item_in_lexical_scope( @@ -3023,7 +2957,7 @@ impl<'a> Resolver<'a> { Success((target, _)) => { let bindings = &*target.bindings; match *bindings.type_def.borrow() { - Some(type_def) => { + Some(ref type_def) => { match type_def.module_def { None => { error!("!!! (resolving module in lexical \ @@ -3031,8 +2965,8 @@ impl<'a> Resolver<'a> { module!"); return Failed; } - Some(module_def) => { - return Success(module_def); + Some(ref module_def) => { + return Success(module_def.clone()); } } } @@ -3057,14 +2991,15 @@ impl<'a> Resolver<'a> { } /// Returns the nearest normal module parent of the given module. - fn get_nearest_normal_module_parent(&mut self, module_: @Module) - -> Option<@Module> { + fn get_nearest_normal_module_parent(&mut self, module_: Rc) + -> Option> { let mut module_ = module_; loop { - match module_.parent_link { + match module_.parent_link.clone() { NoParentLink => return None, ModuleParentLink(new_module, _) | BlockParentLink(new_module, _) => { + let new_module = new_module.upgrade().unwrap(); match new_module.kind.get() { NormalModuleKind => return Some(new_module), ExternModuleKind | @@ -3079,15 +3014,15 @@ impl<'a> Resolver<'a> { /// Returns the nearest normal module parent of the given module, or the /// module itself if it is a normal module. - fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module) - -> @Module { + fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc) + -> Rc { match module_.kind.get() { NormalModuleKind => return module_, ExternModuleKind | TraitModuleKind | ImplModuleKind | AnonymousModuleKind => { - match self.get_nearest_normal_module_parent(module_) { + match self.get_nearest_normal_module_parent(module_.clone()) { None => module_, Some(new_module) => new_module } @@ -3099,7 +3034,7 @@ impl<'a> Resolver<'a> { /// (b) some chain of `super::`. /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) * fn resolve_module_prefix(&mut self, - module_: @Module, + module_: Rc, module_path: &[Ident]) -> ResolveResult { // Start at the current module if we see `self` or `super`, or at the @@ -3126,7 +3061,7 @@ impl<'a> Resolver<'a> { break } debug!("(resolving module prefix) resolving `super` at {}", - self.module_to_str(containing_module)); + self.module_to_str(&*containing_module)); match self.get_nearest_normal_module_parent(containing_module) { None => return Failed, Some(new_module) => { @@ -3137,7 +3072,7 @@ impl<'a> Resolver<'a> { } debug!("(resolving module prefix) finished resolving prefix at {}", - self.module_to_str(containing_module)); + self.module_to_str(&*containing_module)); return Success(PrefixFound(containing_module, i)); } @@ -3149,7 +3084,7 @@ impl<'a> Resolver<'a> { /// The boolean returned on success is an indicator of whether this lookup /// passed through a public re-export proxy. fn resolve_name_in_module(&mut self, - module_: @Module, + module_: Rc, name: Ident, namespace: Namespace, name_search_type: NameSearchType, @@ -3157,16 +3092,16 @@ impl<'a> Resolver<'a> { -> ResolveResult<(Target, bool)> { debug!("(resolving name in module) resolving `{}` in `{}`", token::get_ident(name), - self.module_to_str(module_)); + self.module_to_str(&*module_)); // First, check the direct children of the module. - self.populate_module_if_necessary(module_); + self.populate_module_if_necessary(&module_); match module_.children.borrow().find(&name.name) { Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("(resolving name in module) found node as child"); - return Success((Target::new(module_, *name_bindings), + return Success((Target::new(module_.clone(), name_bindings.clone()), false)); } Some(_) | None => { @@ -3185,10 +3120,10 @@ impl<'a> Resolver<'a> { // Check the list of resolved imports. match module_.import_resolutions.borrow().find(&name.name) { Some(import_resolution) if allow_private_imports || - import_resolution.is_public.get() => { + import_resolution.is_public => { - if import_resolution.is_public.get() && - import_resolution.outstanding_references.get() != 0 { + if import_resolution.is_public && + import_resolution.outstanding_references != 0 { debug!("(resolving name in module) import \ unresolved; bailing out"); return Indeterminate; @@ -3216,7 +3151,7 @@ impl<'a> Resolver<'a> { None => {} Some(module) => { let name_bindings = - @Resolver::create_name_bindings_from_module(module); + Rc::new(Resolver::create_name_bindings_from_module(module)); return Success((Target::new(module_, name_bindings), false)); } } @@ -3228,7 +3163,7 @@ impl<'a> Resolver<'a> { return Failed; } - fn report_unresolved_imports(&mut self, module_: @Module) { + fn report_unresolved_imports(&mut self, module_: Rc) { let index = module_.resolved_import_count.get(); let imports = module_.imports.borrow(); let import_count = imports.len(); @@ -3248,9 +3183,9 @@ impl<'a> Resolver<'a> { } // Descend into children and anonymous children. - self.populate_module_if_necessary(module_); + self.populate_module_if_necessary(&module_); - for (_, &child_node) in module_.children.borrow().iter() { + for (_, child_node) in module_.children.borrow().iter() { match child_node.get_module_if_available() { None => { // Continue. @@ -3261,8 +3196,8 @@ impl<'a> Resolver<'a> { } } - for (_, &module_) in module_.anonymous_children.borrow().iter() { - self.report_unresolved_imports(module_); + for (_, module_) in module_.anonymous_children.borrow().iter() { + self.report_unresolved_imports(module_.clone()); } } @@ -3281,7 +3216,7 @@ impl<'a> Resolver<'a> { } fn record_exports_for_module_subtree(&mut self, - module_: @Module) { + module_: Rc) { // If this isn't a local krate, then bail out. We don't need to record // exports for nonlocal crates. @@ -3290,27 +3225,27 @@ impl<'a> Resolver<'a> { // OK. Continue. debug!("(recording exports for module subtree) recording \ exports for local module `{}`", - self.module_to_str(module_)); + self.module_to_str(&*module_)); } None => { // Record exports for the root module. debug!("(recording exports for module subtree) recording \ exports for root module `{}`", - self.module_to_str(module_)); + self.module_to_str(&*module_)); } Some(_) => { // Bail out. debug!("(recording exports for module subtree) not recording \ exports for `{}`", - self.module_to_str(module_)); + self.module_to_str(&*module_)); return; } } - self.record_exports_for_module(module_); - self.populate_module_if_necessary(module_); + self.record_exports_for_module(&*module_); + self.populate_module_if_necessary(&module_); - for (_, &child_name_bindings) in module_.children.borrow().iter() { + for (_, child_name_bindings) in module_.children.borrow().iter() { match child_name_bindings.get_module_if_available() { None => { // Nothing to do. @@ -3321,12 +3256,12 @@ impl<'a> Resolver<'a> { } } - for (_, &child_module) in module_.anonymous_children.borrow().iter() { - self.record_exports_for_module_subtree(child_module); + for (_, child_module) in module_.anonymous_children.borrow().iter() { + self.record_exports_for_module_subtree(child_module.clone()); } } - fn record_exports_for_module(&mut self, module_: @Module) { + fn record_exports_for_module(&mut self, module_: &Module) { let mut exports2 = Vec::new(); self.add_exports_for_module(&mut exports2, module_); @@ -3343,7 +3278,7 @@ impl<'a> Resolver<'a> { fn add_exports_of_namebindings(&mut self, exports2: &mut Vec , name: Name, - namebindings: @NameBindings, + namebindings: &NameBindings, ns: Namespace) { match namebindings.def_for_namespace(ns) { Some(d) => { @@ -3363,9 +3298,9 @@ impl<'a> Resolver<'a> { fn add_exports_for_module(&mut self, exports2: &mut Vec , - module_: @Module) { + module_: &Module) { for (name, importresolution) in module_.import_resolutions.borrow().iter() { - if !importresolution.is_public.get() { + if !importresolution.is_public { continue } let xs = [TypeNS, ValueNS]; @@ -3376,7 +3311,7 @@ impl<'a> Resolver<'a> { token::get_name(*name)); self.add_exports_of_namebindings(exports2, *name, - target.bindings, + &*target.bindings, ns) } _ => () @@ -3404,7 +3339,7 @@ impl<'a> Resolver<'a> { // implementations thus found, for compatibility with old resolve pass. fn with_scope(&mut self, name: Option, f: |&mut Resolver|) { - let orig_module = self.current_module; + let orig_module = self.current_module.clone(); // Move down in the graph. match name { @@ -3412,13 +3347,13 @@ impl<'a> Resolver<'a> { // Nothing to do. } Some(name) => { - self.populate_module_if_necessary(orig_module); + self.populate_module_if_necessary(&orig_module); match orig_module.children.borrow().find(&name.name) { None => { debug!("!!! (with scope) didn't find `{}` in `{}`", token::get_ident(name), - self.module_to_str(orig_module)); + self.module_to_str(&*orig_module)); } Some(name_bindings) => { match (*name_bindings).get_module_if_available() { @@ -3426,7 +3361,7 @@ impl<'a> Resolver<'a> { debug!("!!! (with scope) didn't find module \ for `{}` in `{}`", token::get_ident(name), - self.module_to_str(orig_module)); + self.module_to_str(&*orig_module)); } Some(module_) => { self.current_module = module_; @@ -3444,12 +3379,12 @@ impl<'a> Resolver<'a> { /// Wraps the given definition in the appropriate number of `def_upvar` /// wrappers. - fn upvarify(&mut self, - ribs: &mut Vec<@Rib> , - rib_index: uint, - def_like: DefLike, - span: Span) - -> Option { + fn upvarify(&self, + ribs: &[Rib], + rib_index: uint, + def_like: DefLike, + span: Span) + -> Option { let mut def; let is_ty_param; @@ -3470,7 +3405,7 @@ impl<'a> Resolver<'a> { let mut rib_index = rib_index + 1; while rib_index < ribs.len() { - match ribs.get(rib_index).kind { + match ribs[rib_index].kind { NormalRibKind => { // Nothing to do. Continue. } @@ -3560,18 +3495,18 @@ impl<'a> Resolver<'a> { return Some(DlDef(def)); } - fn search_ribs(&mut self, - ribs: &mut Vec<@Rib> , - name: Name, - span: Span) - -> Option { + fn search_ribs(&self, + ribs: &[Rib], + name: Name, + span: Span) + -> Option { // FIXME #4950: This should not use a while loop. // FIXME #4950: Try caching? let mut i = ribs.len(); while i != 0 { i -= 1; - let binding_opt = ribs.get(i).bindings.borrow().find_copy(&name); + let binding_opt = ribs[i].bindings.borrow().find_copy(&name); match binding_opt { Some(def_like) => { return self.upvarify(ribs, i, def_like, span); @@ -3645,12 +3580,12 @@ impl<'a> Resolver<'a> { ItemTrait(ref generics, ref traits, ref methods) => { // Create a new rib for the self type. - let self_type_rib = @Rib::new(NormalRibKind); - self.type_ribs.borrow_mut().push(self_type_rib); + let self_type_rib = Rib::new(NormalRibKind); // plain insert (no renaming) let name = self.type_self_ident.name; self_type_rib.bindings.borrow_mut() .insert(name, DlDef(DefSelfTy(item.id))); + self.type_ribs.borrow_mut().push(self_type_rib); // Create a new rib for the trait-wide type parameters. self.with_type_parameter_rib(HasTypeParameters(generics, @@ -3772,8 +3707,7 @@ impl<'a> Resolver<'a> { HasTypeParameters(generics, node_id, initial_index, rib_kind) => { - let function_type_rib = @Rib::new(rib_kind); - self.type_ribs.borrow_mut().push(function_type_rib); + let function_type_rib = Rib::new(rib_kind); for (index, type_parameter) in generics.ty_params.iter().enumerate() { let ident = type_parameter.ident; @@ -3790,6 +3724,7 @@ impl<'a> Resolver<'a> { function_type_rib.bindings.borrow_mut() .insert(ident.name, def_like); } + self.type_ribs.borrow_mut().push(function_type_rib); } NoTypeParameters => { @@ -3806,14 +3741,14 @@ impl<'a> Resolver<'a> { } fn with_label_rib(&mut self, f: |&mut Resolver|) { - self.label_ribs.borrow_mut().push(@Rib::new(NormalRibKind)); + self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind)); f(self); self.label_ribs.borrow_mut().pop(); } fn with_constant_rib(&mut self, f: |&mut Resolver|) { - self.value_ribs.borrow_mut().push(@Rib::new(ConstantItemRibKind)); - self.type_ribs.borrow_mut().push(@Rib::new(ConstantItemRibKind)); + self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind)); + self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind)); f(self); self.type_ribs.borrow_mut().pop(); self.value_ribs.borrow_mut().pop(); @@ -3825,11 +3760,11 @@ impl<'a> Resolver<'a> { type_parameters: TypeParameters, block: P) { // Create a value rib for the function. - let function_value_rib = @Rib::new(rib_kind); + let function_value_rib = Rib::new(rib_kind); self.value_ribs.borrow_mut().push(function_value_rib); // Create a label rib for the function. - let function_label_rib = @Rib::new(rib_kind); + let function_label_rib = Rib::new(rib_kind); self.label_ribs.borrow_mut().push(function_label_rib); // If this function has type parameters, add them now. @@ -3980,7 +3915,7 @@ impl<'a> Resolver<'a> { // to be NormalRibKind? fn resolve_method(&mut self, rib_kind: RibKind, - method: @Method, + method: &Method, outer_type_parameter_count: uint) { let method_generics = &method.generics; let type_parameters = @@ -4093,9 +4028,9 @@ impl<'a> Resolver<'a> { // this is done hygienically. This could arise for a macro // that expands into an or-pattern where one 'x' was from the // user and one 'x' came from the macro. - fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap { + fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { let mut result = HashMap::new(); - pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| { + pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path| { let name = mtwt::resolve(path_to_ident(path)); result.insert(name, binding_info {span: sp, @@ -4151,7 +4086,7 @@ impl<'a> Resolver<'a> { } fn resolve_arm(&mut self, arm: &Arm) { - self.value_ribs.borrow_mut().push(@Rib::new(NormalRibKind)); + self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind)); let mut bindings_list = HashMap::new(); for pattern in arm.pats.iter() { @@ -4172,19 +4107,16 @@ impl<'a> Resolver<'a> { fn resolve_block(&mut self, block: &Block) { debug!("(resolving block) entering block"); - self.value_ribs.borrow_mut().push(@Rib::new(NormalRibKind)); + self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind)); // Move down in the graph, if there's an anonymous module rooted here. - let orig_module = self.current_module; - let anonymous_children = self.current_module - .anonymous_children - .borrow(); - match anonymous_children.find(&block.id) { + let orig_module = self.current_module.clone(); + match orig_module.anonymous_children.borrow().find(&block.id) { None => { /* Nothing to do. */ } - Some(&anonymous_module) => { + Some(anonymous_module) => { debug!("(resolving block) found anonymous module, moving \ down"); - self.current_module = anonymous_module; + self.current_module = anonymous_module.clone(); } } @@ -4302,7 +4234,7 @@ impl<'a> Resolver<'a> { } fn resolve_pattern(&mut self, - pattern: @Pat, + pattern: &Pat, mode: PatternBindingMode, // Maps idents to the node ID for the (outermost) // pattern that binds them @@ -4553,9 +4485,9 @@ impl<'a> Resolver<'a> { } fn resolve_bare_identifier_pattern(&mut self, name: Ident) - -> - BareIdentifierPatternResolution { - match self.resolve_item_in_lexical_scope(self.current_module, + -> BareIdentifierPatternResolution { + let module = self.current_module.clone(); + match self.resolve_item_in_lexical_scope(module, name, ValueNS, SearchThroughModules) { @@ -4668,12 +4600,12 @@ impl<'a> Resolver<'a> { // FIXME #4952: Merge me with resolve_name_in_module? fn resolve_definition_of_name_in_module(&mut self, - containing_module: @Module, + containing_module: Rc, name: Ident, namespace: Namespace) -> NameDefinition { // First, search children. - self.populate_module_if_necessary(containing_module); + self.populate_module_if_necessary(&containing_module); match containing_module.children.borrow().find(&name.name) { Some(child_name_bindings) => { @@ -4695,7 +4627,7 @@ impl<'a> Resolver<'a> { // Next, search import resolutions. match containing_module.import_resolutions.borrow().find(&name.name) { - Some(import_resolution) if import_resolution.is_public.get() => { + Some(import_resolution) if import_resolution.is_public => { match (*import_resolution).target_for_namespace(namespace) { Some(target) => { match target.bindings.def_for_namespace(namespace) { @@ -4750,7 +4682,8 @@ impl<'a> Resolver<'a> { let containing_module; let last_private; - match self.resolve_module_path(self.current_module, + let module = self.current_module.clone(); + match self.resolve_module_path(module, module_path_idents.as_slice(), UseLexicalScope, path.span, @@ -4773,7 +4706,7 @@ impl<'a> Resolver<'a> { } let ident = path.segments.last().unwrap().identifier; - let def = match self.resolve_definition_of_name_in_module(containing_module, + let def = match self.resolve_definition_of_name_in_module(containing_module.clone(), ident, namespace) { NoNameDefinition => { @@ -4786,22 +4719,17 @@ impl<'a> Resolver<'a> { }; match containing_module.kind.get() { TraitModuleKind | ImplModuleKind => { - match self.method_map.borrow().find(&ident.name) { - Some(s) => { - match containing_module.def_id.get() { - Some(def_id) if s.contains(&def_id) => { - debug!("containing module was a trait or impl \ - and name was a method -> not resolved"); - return None; - }, - _ => (), - } + match containing_module.def_id.get() { + Some(def_id) if self.method_set.borrow().contains(&(ident.name, def_id)) => { + debug!("containing module was a trait or impl \ + and name was a method -> not resolved"); + return None; }, - None => (), + _ => (), } }, _ => (), - }; + } return Some(def); } @@ -4865,12 +4793,12 @@ impl<'a> Resolver<'a> { let search_result = match namespace { ValueNS => { let renamed = mtwt::resolve(ident); - self.search_ribs(&mut *self.value_ribs.borrow_mut(), + self.search_ribs(self.value_ribs.borrow().as_slice(), renamed, span) } TypeNS => { let name = ident.name; - self.search_ribs(&mut *self.type_ribs.borrow_mut(), name, span) + self.search_ribs(self.type_ribs.borrow().as_slice(), name, span) } }; @@ -4893,7 +4821,8 @@ impl<'a> Resolver<'a> { namespace: Namespace) -> Option<(Def, LastPrivate)> { // Check the items. - match self.resolve_item_in_lexical_scope(self.current_module, + let module = self.current_module.clone(); + match self.resolve_item_in_lexical_scope(module, ident, namespace, DontSearchThroughModules) { @@ -4936,7 +4865,7 @@ impl<'a> Resolver<'a> { rs } - fn resolve_error(&mut self, span: Span, s: &str) { + fn resolve_error(&self, span: Span, s: &str) { if self.emit_errors { self.session.span_err(span, s); } @@ -5115,9 +5044,9 @@ impl<'a> Resolver<'a> { ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ExprBreak(Some(label)) | ExprAgain(Some(label)) => { - let mut label_ribs = self.label_ribs.borrow_mut(); let renamed = mtwt::resolve(label); - match self.search_ribs(&mut *label_ribs, renamed, expr.span) { + match self.search_ribs(self.label_ribs.borrow().as_slice(), + renamed, expr.span) { None => self.resolve_error(expr.span, format!("use of undeclared label `{}`", @@ -5147,14 +5076,14 @@ impl<'a> Resolver<'a> { // field, we need to add any trait methods we find that match // the field name so that we can do some nice error reporting // later on in typeck. - let traits = self.search_for_traits_containing_method(ident); + let traits = self.search_for_traits_containing_method(ident.name); self.trait_map.insert(expr.id, traits); } ExprMethodCall(ident, _, _) => { debug!("(recording candidate traits for expr) recording \ traits for {}", expr.id); - let traits = self.search_for_traits_containing_method(ident); + let traits = self.search_for_traits_containing_method(ident.name); self.trait_map.insert(expr.id, traits); } _ => { @@ -5163,34 +5092,44 @@ impl<'a> Resolver<'a> { } } - fn search_for_traits_containing_method(&mut self, name: Ident) -> Vec { + fn search_for_traits_containing_method(&mut self, name: Name) -> Vec { debug!("(searching for traits containing method) looking for '{}'", - token::get_ident(name)); + token::get_name(name)); + + fn add_trait_info(found_traits: &mut Vec, + trait_def_id: DefId, + name: Name) { + debug!("(adding trait info) found trait {}:{} for method '{}'", + trait_def_id.krate, + trait_def_id.node, + token::get_name(name)); + found_traits.push(trait_def_id); + } let mut found_traits = Vec::new(); - let mut search_module = self.current_module; - match self.method_map.borrow().find(&name.name) { - Some(candidate_traits) => loop { - // Look for the current trait. - match self.current_trait_refs { - Some(ref trait_def_ids) => { - for trait_def_id in trait_def_ids.iter() { - if candidate_traits.contains(trait_def_id) { - self.add_trait_info(&mut found_traits, - *trait_def_id, - name); - } + let mut search_module = self.current_module.clone(); + loop { + // Look for the current trait. + match self.current_trait_refs { + Some(ref trait_def_ids) => { + let method_set = self.method_set.borrow(); + for &trait_def_id in trait_def_ids.iter() { + if method_set.contains(&(name, trait_def_id)) { + add_trait_info(&mut found_traits, trait_def_id, name); } } - None => { - // Nothing to do. - } } + None => { + // Nothing to do. + } + } - // Look for trait children. - self.populate_module_if_necessary(search_module); + // Look for trait children. + self.populate_module_if_necessary(&search_module); - for (_, &child_names) in search_module.children.borrow().iter() { + { + let method_set = self.method_set.borrow(); + for (_, child_names) in search_module.children.borrow().iter() { let def = match child_names.def_for_namespace(TypeNS) { Some(def) => def, None => continue @@ -5199,52 +5138,37 @@ impl<'a> Resolver<'a> { DefTrait(trait_def_id) => trait_def_id, _ => continue, }; - if candidate_traits.contains(&trait_def_id) { - self.add_trait_info(&mut found_traits, trait_def_id, - name); + if method_set.contains(&(name, trait_def_id)) { + add_trait_info(&mut found_traits, trait_def_id, name); } } + } - // Look for imports. - let import_resolutions = search_module.import_resolutions - .borrow(); - for (_, &import) in import_resolutions.iter() { - let target = match import.target_for_namespace(TypeNS) { - None => continue, - Some(target) => target, - }; - let did = match target.bindings.def_for_namespace(TypeNS) { - Some(DefTrait(trait_def_id)) => trait_def_id, - Some(..) | None => continue, - }; - if candidate_traits.contains(&did) { - self.add_trait_info(&mut found_traits, did, name); - self.used_imports.insert((import.type_id.get(), TypeNS)); - } + // Look for imports. + for (_, import) in search_module.import_resolutions.borrow().iter() { + let target = match import.target_for_namespace(TypeNS) { + None => continue, + Some(target) => target, + }; + let did = match target.bindings.def_for_namespace(TypeNS) { + Some(DefTrait(trait_def_id)) => trait_def_id, + Some(..) | None => continue, + }; + if self.method_set.borrow().contains(&(name, did)) { + add_trait_info(&mut found_traits, did, name); + self.used_imports.insert((import.type_id, TypeNS)); } + } - match search_module.parent_link { - NoParentLink | ModuleParentLink(..) => break, - BlockParentLink(parent_module, _) => { - search_module = parent_module; - } + match search_module.parent_link.clone() { + NoParentLink | ModuleParentLink(..) => break, + BlockParentLink(parent_module, _) => { + search_module = parent_module.upgrade().unwrap(); } - }, - _ => () + } } - return found_traits; - } - - fn add_trait_info(&self, - found_traits: &mut Vec , - trait_def_id: DefId, - name: Ident) { - debug!("(adding trait info) found trait {}:{} for method '{}'", - trait_def_id.krate, - trait_def_id.node, - token::get_ident(name)); - found_traits.push(trait_def_id); + found_traits } fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) { @@ -5381,40 +5305,38 @@ impl<'a> Resolver<'a> { // /// A somewhat inefficient routine to obtain the name of a module. - fn module_to_str(&mut self, module_: @Module) -> ~str { + fn module_to_str(&mut self, module: &Module) -> ~str { let mut idents = Vec::new(); - let mut current_module = module_; - loop { - match current_module.parent_link { - NoParentLink => { - break; - } - ModuleParentLink(module_, name) => { + + fn collect_mod(idents: &mut Vec, module: &Module) { + match module.parent_link { + NoParentLink => {} + ModuleParentLink(ref module, name) => { idents.push(name); - current_module = module_; + collect_mod(idents, &*module.upgrade().unwrap()); } - BlockParentLink(module_, _) => { + BlockParentLink(ref module, _) => { idents.push(special_idents::opaque); - current_module = module_; + collect_mod(idents, &*module.upgrade().unwrap()); } } } + collect_mod(&mut idents, module); if idents.len() == 0 { return "???".to_owned(); } - return self.idents_to_str(idents.move_iter() - .rev() - .collect::>() - .as_slice()); + self.idents_to_str(idents.move_iter().rev() + .collect::>() + .as_slice()) } #[allow(dead_code)] // useful for debugging - fn dump_module(&mut self, module_: @Module) { - debug!("Dump of module `{}`:", self.module_to_str(module_)); + fn dump_module(&mut self, module_: Rc) { + debug!("Dump of module `{}`:", self.module_to_str(&*module_)); debug!("Children:"); - self.populate_module_if_necessary(module_); + self.populate_module_if_necessary(&module_); for (&name, _) in module_.children.borrow().iter() { debug!("* {}", token::get_name(name)); } @@ -5455,7 +5377,7 @@ pub struct CrateMap { /// Entry point to crate resolution. pub fn resolve_crate(session: &Session, - lang_items: @LanguageItems, + lang_items: &LanguageItems, krate: &Crate) -> CrateMap { let mut resolver = Resolver(session, lang_items, krate.span); diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index bab7a227572..55f8b3d1fd2 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -225,6 +225,7 @@ use util::ppaux::{Repr, vec_map_to_str}; use collections::HashMap; use std::cell::Cell; +use std::rc::Rc; use syntax::ast; use syntax::ast::Ident; use syntax::ast_util::path_to_ident; @@ -250,7 +251,7 @@ pub enum VecLenOpt { // range) enum Opt { lit(Lit), - var(ty::Disr, @adt::Repr), + var(ty::Disr, Rc), range(@ast::Expr, @ast::Expr), vec_len(/* length */ uint, VecLenOpt, /*range of matches*/(uint, uint)) } @@ -351,8 +352,8 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> { let (llval, _) = consts::get_const_val(bcx.ccx(), lit_id); return single_result(rslt(bcx, llval)); } - var(disr_val, repr) => { - return adt::trans_case(bcx, repr, disr_val); + var(disr_val, ref repr) => { + return adt::trans_case(bcx, &**repr, disr_val); } range(l1, l2) => { let (l1, _) = consts::const_expr(ccx, l1, true); @@ -417,15 +418,10 @@ struct BindingInfo { type BindingsMap = HashMap; -struct ArmData<'a,'b> { +struct ArmData<'a, 'b> { bodycx: &'b Block<'b>, arm: &'a ast::Arm, - bindings_map: @BindingsMap -} - -// FIXME #11820: method resolution is unreliable with & -impl<'a,'b> Clone for ArmData<'a, 'b> { - fn clone(&self) -> ArmData<'a, 'b> { *self } + bindings_map: BindingsMap } /** @@ -434,14 +430,13 @@ impl<'a,'b> Clone for ArmData<'a, 'b> { * As we proceed `bound_ptrs` are filled with pointers to values to be bound, * these pointers are stored in llmatch variables just before executing `data` arm. */ -#[deriving(Clone)] -struct Match<'a,'b> { - pats: Vec<@ast::Pat> , - data: ArmData<'a,'b>, +struct Match<'a, 'b> { + pats: Vec<@ast::Pat>, + data: &'a ArmData<'a, 'b>, bound_ptrs: Vec<(Ident, ValueRef)> } -impl<'a,'b> Repr for Match<'a,'b> { +impl<'a, 'b> Repr for Match<'a, 'b> { fn repr(&self, tcx: &ty::ctxt) -> ~str { if tcx.sess.verbose() { // for many programs, this just take too long to serialize @@ -462,12 +457,12 @@ fn has_nested_bindings(m: &[Match], col: uint) -> bool { return false; } -fn expand_nested_bindings<'r,'b>( +fn expand_nested_bindings<'a, 'b>( bcx: &'b Block<'b>, - m: &[Match<'r,'b>], + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef) - -> Vec> { + -> Vec> { debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -482,21 +477,25 @@ fn expand_nested_bindings<'r,'b>( .append((vec!(inner)) .append(br.pats.slice(col + 1u, br.pats.len())).as_slice()); - let mut res = Match { + let mut bound_ptrs = br.bound_ptrs.clone(); + bound_ptrs.push((path_to_ident(path), val)); + Match { pats: pats, - data: br.data.clone(), - bound_ptrs: br.bound_ptrs.clone() - }; - res.bound_ptrs.push((path_to_ident(path), val)); - res + data: &*br.data, + bound_ptrs: bound_ptrs + } + } + _ => Match { + pats: br.pats.clone(), + data: &*br.data, + bound_ptrs: br.bound_ptrs.clone() } - _ => (*br).clone(), } }).collect() } fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) { - if !pat_is_binding_or_wild(bcx.tcx().def_map, p) { + if !pat_is_binding_or_wild(&bcx.tcx().def_map, p) { bcx.sess().span_bug( p.span, format!("expected an identifier pattern but found p: {}", @@ -506,14 +505,14 @@ fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) { type enter_pat<'a> = |@ast::Pat|: 'a -> Option>; -fn enter_match<'r,'b>( +fn enter_match<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef, e: enter_pat) - -> Vec> { + -> Vec> { debug!("enter_match(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -521,47 +520,39 @@ fn enter_match<'r,'b>( bcx.val_to_str(val)); let _indenter = indenter(); - let mut result = Vec::new(); - for br in m.iter() { - match e(*br.pats.get(col)) { - Some(sub) => { - let pats = sub.append(br.pats.slice(0u, col)) - .append(br.pats.slice(col + 1u, br.pats.len())); + m.iter().filter_map(|br| { + e(*br.pats.get(col)).map(|sub| { + let pats = sub.append(br.pats.slice(0u, col)) + .append(br.pats.slice(col + 1u, br.pats.len())); - let this = *br.pats.get(col); - let mut bound_ptrs = br.bound_ptrs.clone(); - match this.node { - ast::PatIdent(_, ref path, None) => { - if pat_is_binding(dm, this) { - bound_ptrs.push((path_to_ident(path), val)); - } + let this = *br.pats.get(col); + let mut bound_ptrs = br.bound_ptrs.clone(); + match this.node { + ast::PatIdent(_, ref path, None) => { + if pat_is_binding(dm, this) { + bound_ptrs.push((path_to_ident(path), val)); } - _ => {} } - - result.push(Match { - pats: pats, - data: br.data.clone(), - bound_ptrs: bound_ptrs - }); + _ => {} } - None => () - } - } - debug!("result={}", result.repr(bcx.tcx())); - - return result; + Match { + pats: pats, + data: br.data, + bound_ptrs: bound_ptrs + } + }) + }).collect() } -fn enter_default<'r,'b>( +fn enter_default<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef, chk: &FailureHandler) - -> Vec> { + -> Vec> { debug!("enter_default(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -625,14 +616,14 @@ fn enter_default<'r,'b>( // so all patterns must either be records (resp. tuples) or // wildcards -fn enter_opt<'r,'b>( +fn enter_opt<'a, 'b>( bcx: &'b Block<'b>, - m: &[Match<'r,'b>], + m: &'a [Match<'a, 'b>], opt: &Opt, col: uint, variant_size: uint, val: ValueRef) - -> Vec> { + -> Vec> { debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -657,10 +648,10 @@ fn enter_opt<'r,'b>( // "column" of arm patterns and the algorithm will converge. let guarded = m.iter().any(|x| x.data.arm.guard.is_some()); let multi_pats = m.len() > 0 && m[0].pats.len() > 1; - enter_match(bcx, tcx.def_map, m, col, val, |p| { + enter_match(bcx, &tcx.def_map, m, col, val, |p| { let answer = match p.node { ast::PatEnum(..) | - ast::PatIdent(_, _, None) if pat_is_const(tcx.def_map, p) => { + ast::PatIdent(_, _, None) if pat_is_const(&tcx.def_map, p) => { let const_def = tcx.def_map.borrow().get_copy(&p.id); let const_def_id = ast_util::def_id_of_def(const_def); let konst = lit(ConstLit(const_def_id)); @@ -684,7 +675,7 @@ fn enter_opt<'r,'b>( } } ast::PatIdent(_, _, None) - if pat_is_variant_or_struct(tcx.def_map, p) => { + if pat_is_variant_or_struct(&tcx.def_map, p) => { if opt_eq(tcx, &variant_opt(bcx, p.id), opt) { Some(Vec::new()) } else { @@ -799,14 +790,14 @@ fn enter_opt<'r,'b>( }) } -fn enter_rec_or_struct<'r,'b>( +fn enter_rec_or_struct<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, fields: &[ast::Ident], val: ValueRef) - -> Vec> { + -> Vec> { debug!("enter_rec_or_struct(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -835,14 +826,14 @@ fn enter_rec_or_struct<'r,'b>( }) } -fn enter_tup<'r,'b>( +fn enter_tup<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef, n_elts: uint) - -> Vec> { + -> Vec> { debug!("enter_tup(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -868,14 +859,14 @@ fn enter_tup<'r,'b>( }) } -fn enter_tuple_struct<'r,'b>( +fn enter_tuple_struct<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef, n_elts: uint) - -> Vec> { + -> Vec> { debug!("enter_tuple_struct(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -897,13 +888,13 @@ fn enter_tuple_struct<'r,'b>( }) } -fn enter_uniq<'r,'b>( +fn enter_uniq<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef) - -> Vec> { + -> Vec> { debug!("enter_uniq(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -925,14 +916,13 @@ fn enter_uniq<'r,'b>( }) } -fn enter_region<'r, - 'b>( +fn enter_region<'a, 'b>( bcx: &'b Block<'b>, - dm: DefMap, - m: &[Match<'r,'b>], + dm: &DefMap, + m: &'a [Match<'a, 'b>], col: uint, val: ValueRef) - -> Vec> { + -> Vec> { debug!("enter_region(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -1170,7 +1160,7 @@ fn pats_require_rooting(bcx: &Block, m: &[Match], col: uint) -> bool { m.iter().any(|br| { let pat_id = br.pats.get(col).id; let key = root_map_key {id: pat_id, derefs: 0u }; - bcx.ccx().maps.root_map.borrow().contains_key(&key) + bcx.ccx().maps.root_map.contains_key(&key) }) } @@ -1424,12 +1414,11 @@ fn insert_lllocals<'a>(bcx: &'a Block<'a>, bcx } -fn compile_guard<'r, - 'b>( +fn compile_guard<'a, 'b>( bcx: &'b Block<'b>, guard_expr: &ast::Expr, data: &ArmData, - m: &[Match<'r,'b>], + m: &'a [Match<'a, 'b>], vals: &[ValueRef], chk: &FailureHandler) -> &'b Block<'b> { @@ -1445,9 +1434,9 @@ fn compile_guard<'r, let temp_scope = bcx.fcx.push_custom_cleanup_scope(); let mut bcx = bcx; - bcx = store_non_ref_bindings(bcx, data.bindings_map, + bcx = store_non_ref_bindings(bcx, &data.bindings_map, Some(cleanup::CustomScope(temp_scope))); - bcx = insert_lllocals(bcx, data.bindings_map, + bcx = insert_lllocals(bcx, &data.bindings_map, cleanup::CustomScope(temp_scope)); let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr)); @@ -1482,10 +1471,9 @@ fn compile_guard<'r, } } -fn compile_submatch<'r, - 'b>( +fn compile_submatch<'a, 'b>( bcx: &'b Block<'b>, - m: &[Match<'r,'b>], + m: &'a [Match<'a, 'b>], vals: &[ValueRef], chk: &FailureHandler) { debug!("compile_submatch(bcx={}, m={}, vals={})", @@ -1514,7 +1502,7 @@ fn compile_submatch<'r, Some(guard_expr) => { bcx = compile_guard(bcx, guard_expr, - &m[0].data, + m[0].data, m.slice(1, m.len()), vals, chk); @@ -1541,17 +1529,16 @@ fn compile_submatch<'r, } } -fn compile_submatch_continue<'r, - 'b>( +fn compile_submatch_continue<'a, 'b>( mut bcx: &'b Block<'b>, - m: &[Match<'r,'b>], + m: &'a [Match<'a, 'b>], vals: &[ValueRef], chk: &FailureHandler, col: uint, val: ValueRef) { let fcx = bcx.fcx; let tcx = bcx.tcx(); - let dm = tcx.def_map; + let dm = &tcx.def_map; let vals_left = Vec::from_slice(vals.slice(0u, col)).append(vals.slice(col + 1u, vals.len())); let ccx = bcx.fcx.ccx; @@ -1575,7 +1562,7 @@ fn compile_submatch_continue<'r, expr::with_field_tys(tcx, pat_ty, Some(pat_id), |discr, field_tys| { let rec_vals = rec_fields.iter().map(|field_name| { let ix = ty::field_idx_strict(tcx, field_name.name, field_tys); - adt::trans_field_ptr(bcx, pat_repr, val, discr, ix) + adt::trans_field_ptr(bcx, &*pat_repr, val, discr, ix) }).collect::>(); compile_submatch( bcx, @@ -1601,7 +1588,7 @@ fn compile_submatch_continue<'r, _ => ccx.sess().bug("non-tuple type in tuple pattern") }; let tup_vals = Vec::from_fn(n_tup_elts, |i| { - adt::trans_field_ptr(bcx, tup_repr, val, 0, i) + adt::trans_field_ptr(bcx, &*tup_repr, val, 0, i) }); compile_submatch(bcx, enter_tup(bcx, @@ -1630,7 +1617,7 @@ fn compile_submatch_continue<'r, let struct_repr = adt::represent_type(bcx.ccx(), struct_ty); let llstructvals = Vec::from_fn(struct_element_count, |i| { - adt::trans_field_ptr(bcx, struct_repr, val, 0, i) + adt::trans_field_ptr(bcx, &*struct_repr, val, 0, i) }); compile_submatch(bcx, enter_tuple_struct(bcx, dm, m, col, val, @@ -1666,8 +1653,8 @@ fn compile_submatch_continue<'r, debug!("test_val={}", bcx.val_to_str(test_val)); if opts.len() > 0u { match *opts.get(0) { - var(_, repr) => { - let (the_kind, val_opt) = adt::trans_switch(bcx, repr, val); + var(_, ref repr) => { + let (the_kind, val_opt) = adt::trans_switch(bcx, &**repr, val); kind = the_kind; for &tval in val_opt.iter() { test_val = tval; } } @@ -1813,9 +1800,9 @@ fn compile_submatch_continue<'r, let mut size = 0u; let mut unpacked = Vec::new(); match *opt { - var(disr_val, repr) => { + var(disr_val, ref repr) => { let ExtractedBlock {vals: argvals, bcx: new_bcx} = - extract_variant_args(opt_cx, repr, disr_val, val); + extract_variant_args(opt_cx, &**repr, disr_val, val); size = argvals.len(); unpacked = argvals; opt_cx = new_bcx; @@ -1885,7 +1872,7 @@ fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap { let ccx = bcx.ccx(); let tcx = bcx.tcx(); let mut bindings_map = HashMap::new(); - pat_bindings(tcx.def_map, pat, |bm, p_id, span, path| { + pat_bindings(&tcx.def_map, pat, |bm, p_id, span, path| { let ident = path_to_ident(path); let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); @@ -1933,26 +1920,6 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>, return bcx; } - let mut arm_datas = Vec::new(); - let mut matches = Vec::new(); - for arm in arms.iter() { - let body = fcx.new_id_block("case_body", arm.body.id); - let bindings_map = create_bindings_map(bcx, *arm.pats.get(0)); - let arm_data = ArmData { - bodycx: body, - arm: arm, - bindings_map: @bindings_map - }; - arm_datas.push(arm_data.clone()); - for p in arm.pats.iter() { - matches.push(Match { - pats: vec!(*p), - data: arm_data.clone(), - bound_ptrs: Vec::new(), - }); - } - } - let t = node_id_type(bcx, discr_expr.id); let chk = { if ty::type_is_empty(tcx, t) { @@ -1970,8 +1937,23 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>, Infallible } }; - let lldiscr = discr_datum.val; - compile_submatch(bcx, matches.as_slice(), [lldiscr], &chk); + + let arm_datas: Vec = arms.iter().map(|arm| ArmData { + bodycx: fcx.new_id_block("case_body", arm.body.id), + arm: arm, + bindings_map: create_bindings_map(bcx, *arm.pats.get(0)) + }).collect(); + + let mut matches = Vec::new(); + for arm_data in arm_datas.iter() { + matches.extend(arm_data.arm.pats.iter().map(|p| Match { + pats: vec!(*p), + data: arm_data, + bound_ptrs: Vec::new(), + })); + } + + compile_submatch(bcx, matches.as_slice(), [discr_datum.val], &chk); let mut arm_cxs = Vec::new(); for arm_data in arm_datas.iter() { @@ -1982,12 +1964,12 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>, // is just to reduce code space. See extensive comment at the start // of the file for more details. if arm_data.arm.guard.is_none() { - bcx = store_non_ref_bindings(bcx, arm_data.bindings_map, None); + bcx = store_non_ref_bindings(bcx, &arm_data.bindings_map, None); } // insert bindings into the lllocals map and add cleanups let cleanup_scope = fcx.push_custom_cleanup_scope(); - bcx = insert_lllocals(bcx, arm_data.bindings_map, + bcx = insert_lllocals(bcx, &arm_data.bindings_map, cleanup::CustomScope(cleanup_scope)); bcx = expr::trans_into(bcx, arm_data.arm.body, dest); bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); @@ -2066,7 +2048,7 @@ pub fn store_local<'a>(bcx: &'a Block<'a>, // create dummy memory for the variables if we have no // value to store into them immediately let tcx = bcx.tcx(); - pat_bindings(tcx.def_map, pat, |_, p_id, _, path| { + pat_bindings(&tcx.def_map, pat, |_, p_id, _, path| { let scope = cleanup::var_scope(tcx, p_id); bcx = mk_binding_alloca( bcx, p_id, path, BindLocal, scope, (), @@ -2199,7 +2181,7 @@ fn bind_irrefutable_pat<'a>( let ccx = bcx.ccx(); match pat.node { ast::PatIdent(pat_binding_mode, ref path, inner) => { - if pat_is_binding(tcx.def_map, pat) { + if pat_is_binding(&tcx.def_map, pat) { // Allocate the stack slot where the value of this // binding will live and place it into the appropriate // map. @@ -2238,7 +2220,7 @@ fn bind_irrefutable_pat<'a>( enum_id, var_id); let args = extract_variant_args(bcx, - repr, + &*repr, vinfo.disr_val, val); for sub_pat in sub_pats.iter() { @@ -2259,7 +2241,7 @@ fn bind_irrefutable_pat<'a>( // This is the tuple struct case. let repr = adt::represent_node(bcx, pat.id); for (i, elem) in elems.iter().enumerate() { - let fldptr = adt::trans_field_ptr(bcx, repr, + let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i); bcx = bind_irrefutable_pat(bcx, *elem, fldptr, binding_mode, @@ -2282,7 +2264,7 @@ fn bind_irrefutable_pat<'a>( expr::with_field_tys(tcx, pat_ty, Some(pat.id), |discr, field_tys| { for f in fields.iter() { let ix = ty::field_idx_strict(tcx, f.ident.name, field_tys); - let fldptr = adt::trans_field_ptr(bcx, pat_repr, val, + let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val, discr, ix); bcx = bind_irrefutable_pat(bcx, f.pat, fldptr, binding_mode, cleanup_scope); @@ -2292,7 +2274,7 @@ fn bind_irrefutable_pat<'a>( ast::PatTup(ref elems) => { let repr = adt::represent_node(bcx, pat.id); for (i, elem) in elems.iter().enumerate() { - let fldptr = adt::trans_field_ptr(bcx, repr, val, 0, i); + let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i); bcx = bind_irrefutable_pat(bcx, *elem, fldptr, binding_mode, cleanup_scope); } diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index da78b650852..fbd638b6191 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -45,8 +45,8 @@ use std::container::Map; use libc::c_ulonglong; -use std::option::{Option, Some, None}; use std::num::{Bitwise}; +use std::rc::Rc; use lib::llvm::{ValueRef, True, IntEQ, IntNE}; use middle::trans::_match; @@ -115,22 +115,22 @@ pub struct Struct { * these, for places in trans where the `ty::t` isn't directly * available. */ -pub fn represent_node(bcx: &Block, node: ast::NodeId) -> @Repr { +pub fn represent_node(bcx: &Block, node: ast::NodeId) -> Rc { represent_type(bcx.ccx(), node_id_type(bcx, node)) } /// Decides how to represent a given type. -pub fn represent_type(cx: &CrateContext, t: ty::t) -> @Repr { +pub fn represent_type(cx: &CrateContext, t: ty::t) -> Rc { debug!("Representing: {}", ty_to_str(cx.tcx(), t)); match cx.adt_reprs.borrow().find(&t) { - Some(repr) => return *repr, + Some(repr) => return repr.clone(), None => {} } - let repr = @represent_type_uncached(cx, t); + let repr = Rc::new(represent_type_uncached(cx, t)); debug!("Represented as: {:?}", repr) - cx.adt_reprs.borrow_mut().insert(t, repr); - return repr; + cx.adt_reprs.borrow_mut().insert(t, repr.clone()); + repr } fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr { @@ -267,7 +267,19 @@ impl Case { mk_struct(cx, self.tys.as_slice(), false).size == 0 } fn find_ptr(&self) -> Option { - self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull) + self.tys.iter().position(|&ty| { + match ty::get(ty).sty { + ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty { + ty::ty_vec(_, None) => false, + _ => true, + }, + ty::ty_uniq(..) | ty::ty_box(..) | + ty::ty_str(ty::VstoreUniq) | + ty::ty_bare_fn(..) => true, + // Is that everything? Would closures or slices qualify? + _ => false + } + }) } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 92a6bb73c8e..fda51e744ce 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -75,6 +75,7 @@ use libc::c_uint; use std::c_str::ToCStr; use std::cell::{Cell, RefCell}; use std::local_data; +use std::rc::Rc; use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic}; use syntax::ast_util::{local_def, is_local}; use syntax::attr::AttrMetaMethods; @@ -398,17 +399,17 @@ pub fn malloc_raw_dyn_managed<'a>( // Type descriptor and type glue stuff -pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { +pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> Rc { match ccx.tydescs.borrow().find(&t) { - Some(&inf) => return inf, + Some(inf) => return inf.clone(), _ => { } } ccx.stats.n_static_tydescs.set(ccx.stats.n_static_tydescs.get() + 1u); - let inf = glue::declare_tydesc(ccx, t); + let inf = Rc::new(glue::declare_tydesc(ccx, t)); - ccx.tydescs.borrow_mut().insert(t, inf); - return inf; + ccx.tydescs.borrow_mut().insert(t, inf.clone()); + inf } #[allow(dead_code)] // useful @@ -637,7 +638,7 @@ pub fn iter_structural_ty<'r, cx: &'b Block<'b>, repr: &adt::Repr, av: ValueRef, - variant: @ty::VariantInfo, + variant: &ty::VariantInfo, tps: &[ty::t], f: val_and_ty_fn<'r,'b>) -> &'b Block<'b> { @@ -659,7 +660,7 @@ pub fn iter_structural_ty<'r, let repr = adt::represent_type(cx.ccx(), t); expr::with_field_tys(cx.tcx(), t, None, |discr, field_tys| { for (i, field_ty) in field_tys.iter().enumerate() { - let llfld_a = adt::trans_field_ptr(cx, repr, av, discr, i); + let llfld_a = adt::trans_field_ptr(cx, &*repr, av, discr, i); cx = f(cx, llfld_a, field_ty.mt.ty); } }) @@ -677,7 +678,7 @@ pub fn iter_structural_ty<'r, ty::ty_tup(ref args) => { let repr = adt::represent_type(cx.ccx(), t); for (i, arg) in args.iter().enumerate() { - let llfld_a = adt::trans_field_ptr(cx, repr, av, 0, i); + let llfld_a = adt::trans_field_ptr(cx, &*repr, av, 0, i); cx = f(cx, llfld_a, *arg); } } @@ -692,9 +693,9 @@ pub fn iter_structural_ty<'r, // NB: we must hit the discriminant first so that structural // comparison know not to proceed when the discriminants differ. - match adt::trans_switch(cx, repr, av) { + match adt::trans_switch(cx, &*repr, av) { (_match::single, None) => { - cx = iter_variant(cx, repr, av, *variants.get(0), + cx = iter_variant(cx, &*repr, av, &**variants.get(0), substs.tps.as_slice(), f); } (_match::switch, Some(lldiscrim_a)) => { @@ -709,7 +710,7 @@ pub fn iter_structural_ty<'r, let variant_cx = fcx.new_temp_block("enum-iter-variant-".to_owned() + variant.disr_val.to_str()); - match adt::trans_case(cx, repr, variant.disr_val) { + match adt::trans_case(cx, &*repr, variant.disr_val) { _match::single_result(r) => { AddCase(llswitch, r.val, variant_cx.llbb) } @@ -718,9 +719,9 @@ pub fn iter_structural_ty<'r, } let variant_cx = iter_variant(variant_cx, - repr, + &*repr, av, - *variant, + &**variant, substs.tps.as_slice(), |x,y,z| f(x,y,z)); Br(variant_cx, next_cx.llbb); @@ -1112,7 +1113,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, id: ast::NodeId, has_env: bool, output_type: ty::t, - param_substs: Option<@param_substs>, + param_substs: Option<&'a param_substs>, sp: Option, block_arena: &'a TypedArena>) -> FunctionContext<'a> { @@ -1120,7 +1121,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, debug!("new_fn_ctxt(path={}, id={}, param_substs={})", if id == -1 { "".to_owned() } else { ccx.tcx.map.path_to_str(id) }, - id, param_substs.repr(ccx.tcx())); + id, param_substs.map(|s| s.repr(ccx.tcx()))); let substd_output_type = match param_substs { None => output_type, @@ -1166,11 +1167,9 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, /// Performs setup on a newly created function, creating the entry scope block /// and allocating space for the return pointer. -pub fn init_function<'a>( - fcx: &'a FunctionContext<'a>, - skip_retptr: bool, - output_type: ty::t, - param_substs: Option<@param_substs>) { +pub fn init_function<'a>(fcx: &'a FunctionContext<'a>, + skip_retptr: bool, + output_type: ty::t) { let entry_bcx = fcx.new_temp_block("entry-block"); *fcx.entry_bcx.borrow_mut() = Some(entry_bcx); @@ -1182,7 +1181,9 @@ pub fn init_function<'a>( llvm::LLVMGetFirstInstruction(entry_bcx.llbb) })); - let substd_output_type = match param_substs { + // This shouldn't need to recompute the return type, + // as new_fn_ctxt did it already. + let substd_output_type = match fcx.param_substs { None => output_type, Some(substs) => { ty::subst_tps(fcx.ccx.tcx(), @@ -1329,7 +1330,7 @@ pub fn trans_closure(ccx: &CrateContext, decl: &ast::FnDecl, body: &ast::Block, llfndecl: ValueRef, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, id: ast::NodeId, _attributes: &[ast::Attribute], output_type: ty::t, @@ -1340,7 +1341,7 @@ pub fn trans_closure(ccx: &CrateContext, set_uwtable(llfndecl); debug!("trans_closure(..., param_substs={})", - param_substs.repr(ccx.tcx())); + param_substs.map(|s| s.repr(ccx.tcx()))); let has_env = match ty::get(ty::node_id_to_type(ccx.tcx(), id)).sty { ty::ty_closure(_) => true, @@ -1353,10 +1354,10 @@ pub fn trans_closure(ccx: &CrateContext, id, has_env, output_type, - param_substs, + param_substs.map(|s| &*s), Some(body.span), &arena); - init_function(&fcx, false, output_type, param_substs); + init_function(&fcx, false, output_type); // cleanup scope for the incoming arguments let arg_scope = fcx.push_custom_cleanup_scope(); @@ -1429,11 +1430,11 @@ pub fn trans_fn(ccx: &CrateContext, decl: &ast::FnDecl, body: &ast::Block, llfndecl: ValueRef, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, id: ast::NodeId, attrs: &[ast::Attribute]) { let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id)); - debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx())); + debug!("trans_fn(param_substs={})", param_substs.map(|s| s.repr(ccx.tcx()))); let _icx = push_ctxt("trans_fn"); let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), id)); trans_closure(ccx, decl, body, llfndecl, @@ -1445,7 +1446,7 @@ pub fn trans_enum_variant(ccx: &CrateContext, variant: &ast::Variant, _args: &[ast::VariantArg], disr: ty::Disr, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, llfndecl: ValueRef) { let _icx = push_ctxt("trans_enum_variant"); @@ -1460,7 +1461,7 @@ pub fn trans_enum_variant(ccx: &CrateContext, pub fn trans_tuple_struct(ccx: &CrateContext, _fields: &[ast::StructField], ctor_id: ast::NodeId, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, llfndecl: ValueRef) { let _icx = push_ctxt("trans_tuple_struct"); @@ -1475,24 +1476,20 @@ pub fn trans_tuple_struct(ccx: &CrateContext, fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, ctor_id: ast::NodeId, disr: ty::Disr, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, llfndecl: ValueRef) { - let no_substs: &[ty::t] = []; - let ty_param_substs = match param_substs { - Some(ref substs) => { - let v: &[ty::t] = substs.tys.as_slice(); - v - } - None => { - let v: &[ty::t] = no_substs; - v - } - }; + let ctor_ty = { + let no_substs: &[ty::t] = []; + let ty_param_substs: &[ty::t] = match param_substs { + Some(substs) => substs.tys.as_slice(), + None => no_substs + }; - let ctor_ty = ty::subst_tps(ccx.tcx(), - ty_param_substs, - None, - ty::node_id_to_type(ccx.tcx(), ctor_id)); + ty::subst_tps(ccx.tcx(), + ty_param_substs, + None, + ty::node_id_to_type(ccx.tcx(), ctor_id)) + }; let result_ty = match ty::get(ctor_ty).sty { ty::ty_bare_fn(ref bft) => bft.sig.output, @@ -1504,8 +1501,8 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty, - param_substs, None, &arena); - init_function(&fcx, false, result_ty, param_substs); + param_substs.map(|s| &*s), None, &arena); + init_function(&fcx, false, result_ty); let arg_tys = ty::ty_fn_args(ctor_ty); @@ -1515,10 +1512,10 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, if !type_is_zero_size(fcx.ccx, result_ty) { let repr = adt::represent_type(ccx, result_ty); - adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr); + adt::trans_start_init(bcx, &*repr, fcx.llretptr.get().unwrap(), disr); for (i, arg_datum) in arg_datums.move_iter().enumerate() { let lldestptr = adt::trans_field_ptr(bcx, - repr, + &*repr, fcx.llretptr.get().unwrap(), disr, i); @@ -1529,11 +1526,11 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, finish_fn(&fcx, bcx); } -pub fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef, - id: ast::NodeId, vi: @Vec<@ty::VariantInfo>, - i: &mut uint) { +fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef, + id: ast::NodeId, vi: &[Rc], + i: &mut uint) { for &variant in enum_definition.variants.iter() { - let disr_val = vi.get(*i).disr_val; + let disr_val = vi[*i].disr_val; *i += 1; match variant.node.kind { @@ -1596,7 +1593,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { if !generics.is_type_parameterized() { let vi = ty::enum_variants(ccx.tcx(), local_def(item.id)); let mut i = 0; - trans_enum_def(ccx, enum_definition, item.id, vi, &mut i); + trans_enum_def(ccx, enum_definition, item.id, vi.as_slice(), &mut i); } } ast::ItemStatic(_, m, expr) => { @@ -2056,17 +2053,13 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef { pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>) -> encoder::EncodeParams<'r> { - - let diag = cx.sess().diagnostic(); - let item_symbols = &cx.item_symbols; - let link_meta = &cx.link_meta; encoder::EncodeParams { - diag: diag, + diag: cx.sess().diagnostic(), tcx: cx.tcx(), - reexports2: cx.exp_map2, - item_symbols: item_symbols, + reexports2: &cx.exp_map2, + item_symbols: &cx.item_symbols, non_inlineable_statics: &cx.non_inlineable_statics, - link_meta: link_meta, + link_meta: &cx.link_meta, cstore: &cx.sess().cstore, encode_inlined_item: ie, } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 7002d09beca..642ae86a979 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -176,14 +176,14 @@ pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, node: ExprOrMethodCall) -> def_id.repr(bcx.tcx()), node, type_params.repr(bcx.tcx()), vtables.repr(bcx.tcx())); trans_fn_ref_with_vtables(bcx, def_id, node, - type_params.as_slice(), + type_params, vtables) } fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>, def_id: ast::DefId, ref_id: ast::NodeId, - type_params: &[ty::t], + type_params: Vec, vtables: Option) -> Callee<'a> { Callee {bcx: bcx, @@ -203,32 +203,35 @@ fn resolve_default_method_vtables(bcx: &Block, // Build up a param_substs that we are going to resolve the // trait_vtables under. - let param_substs = Some(@param_substs { + let param_substs = param_substs { tys: substs.tps.clone(), self_ty: substs.self_ty, - vtables: impl_vtables, + vtables: impl_vtables.clone(), self_vtables: None - }); + }; - let trait_vtables_fixed = resolve_vtables_under_param_substs( - bcx.tcx(), param_substs, impl_res.trait_vtables); + let mut param_vtables = resolve_vtables_under_param_substs( + bcx.tcx(), Some(¶m_substs), impl_res.trait_vtables.as_slice()); // Now we pull any vtables for parameters on the actual method. let num_method_vtables = method.generics.type_param_defs().len(); - let method_vtables = match impl_vtables { - Some(vtables) => { + match impl_vtables { + Some(ref vtables) => { let num_impl_type_parameters = vtables.len() - num_method_vtables; - Vec::from_slice(vtables.tailn(num_impl_type_parameters)) + param_vtables.push_all(vtables.tailn(num_impl_type_parameters)) }, - None => Vec::from_elem(num_method_vtables, @Vec::new()) - }; - - let method_vtables = method_vtables.as_slice(); - let param_vtables = @((*trait_vtables_fixed).clone().append(method_vtables)); + None => { + param_vtables.extend(range(0, num_method_vtables).map( + |_| -> typeck::vtable_param_res { + Vec::new() + } + )) + } + } let self_vtables = resolve_param_vtables_under_param_substs( - bcx.tcx(), param_substs, impl_res.self_vtables); + bcx.tcx(), Some(¶m_substs), impl_res.self_vtables.as_slice()); (param_vtables, self_vtables) } @@ -238,7 +241,7 @@ pub fn trans_fn_ref_with_vtables( bcx: &Block, // def_id: ast::DefId, // def id of fn node: ExprOrMethodCall, // node id of use of fn; may be zero if N/A - type_params: &[ty::t], // values for fn's ty params + type_params: Vec, // values for fn's ty params vtables: Option) // vtables for the call -> ValueRef { /*! @@ -273,9 +276,11 @@ pub fn trans_fn_ref_with_vtables( // Polytype of the function item (may have type params) let fn_tpt = ty::lookup_item_type(tcx, def_id); - let substs = ty::substs { regions: ty::ErasedRegions, - self_ty: None, - tps: /*bad*/ Vec::from_slice(type_params) }; + let substs = ty::substs { + regions: ty::ErasedRegions, + self_ty: None, + tps: type_params + }; // Load the info for the appropriate trait if necessary. match ty::trait_of_method(tcx, def_id) { @@ -313,24 +318,25 @@ pub fn trans_fn_ref_with_vtables( // Compute the first substitution let first_subst = make_substs_for_receiver_types( - tcx, impl_id, trait_ref, method); + tcx, impl_id, &*trait_ref, &*method); // And compose them let new_substs = first_subst.subst(tcx, &substs); - - let (param_vtables, self_vtables) = - resolve_default_method_vtables(bcx, impl_id, - method, &substs, vtables); - debug!("trans_fn_with_vtables - default method: \ substs = {}, trait_subst = {}, \ first_subst = {}, new_subst = {}, \ - vtables = {}, \ - self_vtable = {}, param_vtables = {}", + vtables = {}", substs.repr(tcx), trait_ref.substs.repr(tcx), first_subst.repr(tcx), new_substs.repr(tcx), - vtables.repr(tcx), + vtables.repr(tcx)); + + let (param_vtables, self_vtables) = + resolve_default_method_vtables(bcx, impl_id, + &*method, &substs, vtables); + + debug!("trans_fn_with_vtables - default method: \ + self_vtable = {}, param_vtables = {}", self_vtables.repr(tcx), param_vtables.repr(tcx)); (true, source_id, @@ -352,7 +358,7 @@ pub fn trans_fn_ref_with_vtables( // intrinsic, or is a default method. In particular, if we see an // intrinsic that is inlined from a different crate, we want to reemit the // intrinsic instead of trying to call it in the other crate. - let must_monomorphise = if type_params.len() > 0 || is_default { + let must_monomorphise = if substs.tps.len() > 0 || is_default { true } else if def_id.krate == ast::LOCAL_CRATE { let map_node = session::expect( @@ -391,7 +397,7 @@ pub fn trans_fn_ref_with_vtables( let ref_ty = match node { ExprId(id) => node_id_type(bcx, id), MethodCall(method_call) => { - let t = bcx.ccx().maps.method_map.borrow().get(&method_call).ty; + let t = bcx.tcx().method_map.borrow().get(&method_call).ty; monomorphize_type(bcx, t) } }; @@ -474,7 +480,7 @@ pub fn trans_method_call<'a>( let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_ex={})", call_ex.repr(bcx.tcx())); let method_call = MethodCall::expr(call_ex.id); - let method_ty = bcx.ccx().maps.method_map.borrow().get(&method_call).ty; + let method_ty = bcx.tcx().method_map.borrow().get(&method_call).ty; trans_call_inner( bcx, Some(common::expr_info(call_ex)), @@ -504,7 +510,7 @@ pub fn trans_lang_call<'a>( trans_fn_ref_with_vtables_to_callee(bcx, did, 0, - [], + vec!(), None) }, ArgVals(args), diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 68744643ca6..df17fb516a7 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -466,7 +466,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext, let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, llfn, -1, true, f.sig.output, None, None, &arena); - init_function(&fcx, true, f.sig.output, None); + init_function(&fcx, true, f.sig.output); let bcx = fcx.entry_bcx.borrow().clone().unwrap(); let args = create_datums_for_fn_args(&fcx, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 72e716d0c3c..edb98db416a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -154,21 +154,6 @@ pub fn expr_info(expr: &ast::Expr) -> NodeInfo { NodeInfo { id: expr.id, span: expr.span } } -pub struct Stats { - pub n_static_tydescs: Cell, - pub n_glues_created: Cell, - pub n_null_glues: Cell, - pub n_real_glues: Cell, - pub n_fns: Cell, - pub n_monos: Cell, - pub n_inlines: Cell, - pub n_closures: Cell, - pub n_llvm_insns: Cell, - pub llvm_insns: RefCell>, - // (ident, time-in-ms, llvm-instructions) - pub fn_stats: RefCell >, -} - pub struct BuilderRef_res { pub b: BuilderRef, } @@ -274,7 +259,7 @@ pub struct FunctionContext<'a> { // If this function is being monomorphized, this contains the type // substitutions used. - pub param_substs: Option<@param_substs>, + pub param_substs: Option<&'a param_substs>, // The source span and nesting context where this function comes from, for // error reporting and symbol generation. @@ -686,53 +671,9 @@ pub fn is_null(val: ValueRef) -> bool { } } -// Used to identify cached monomorphized functions and vtables -#[deriving(Eq, TotalEq, Hash)] -pub enum mono_param_id { - mono_precise(ty::t, Option<@Vec >), - mono_any, - mono_repr(uint /* size */, - uint /* align */, - MonoDataClass, - datum::RvalueMode), -} - -#[deriving(Eq, TotalEq, Hash)] -pub enum MonoDataClass { - MonoBits, // Anything not treated differently from arbitrary integer data - MonoNonNull, // Non-null pointers (used for optional-pointer optimization) - // FIXME(#3547)---scalars and floats are - // treated differently in most ABIs. But we - // should be doing something more detailed - // here. - MonoFloat -} - -pub fn mono_data_classify(t: ty::t) -> MonoDataClass { - match ty::get(t).sty { - ty::ty_float(_) => MonoFloat, - ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty { - ty::ty_vec(_, None) => MonoBits, - _ => MonoNonNull, - }, - ty::ty_uniq(..) | ty::ty_box(..) | - ty::ty_str(ty::VstoreUniq) | - ty::ty_bare_fn(..) => MonoNonNull, - // Is that everything? Would closures or slices qualify? - _ => MonoBits - } -} - -#[deriving(Eq, TotalEq, Hash)] -pub struct mono_id_ { - pub def: ast::DefId, - pub params: Vec } - -pub type mono_id = @mono_id_; - pub fn monomorphize_type(bcx: &Block, t: ty::t) -> ty::t { match bcx.fcx.param_substs { - Some(substs) => { + Some(ref substs) => { ty::subst_tps(bcx.tcx(), substs.tys.as_slice(), substs.self_ty, t) } _ => { @@ -754,9 +695,7 @@ pub fn expr_ty(bcx: &Block, ex: &ast::Expr) -> ty::t { } pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t { - let tcx = bcx.tcx(); - let t = ty::expr_ty_adjusted(tcx, ex, &*bcx.ccx().maps.method_map.borrow()); - monomorphize_type(bcx, t) + monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex)) } // Key used to lookup values supplied for type parameters in an expr. @@ -774,7 +713,7 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec { let params = match node { ExprId(id) => ty::node_id_to_type_params(tcx, id), MethodCall(method_call) => { - bcx.ccx().maps.method_map.borrow().get(&method_call).substs.tps.clone() + tcx.method_map.borrow().get(&method_call).substs.tps.clone() } }; @@ -788,62 +727,63 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec { } match bcx.fcx.param_substs { - Some(substs) => { - params.iter().map(|t| { - ty::subst_tps(tcx, substs.tys.as_slice(), substs.self_ty, *t) - }).collect() - } - _ => params + Some(ref substs) => { + params.iter().map(|t| { + ty::subst_tps(tcx, substs.tys.as_slice(), substs.self_ty, *t) + }).collect() + } + _ => params } } pub fn node_vtables(bcx: &Block, id: typeck::MethodCall) -> Option { - let vtable_map = bcx.ccx().maps.vtable_map.borrow(); - let raw_vtables = vtable_map.find(&id); - raw_vtables.map(|vts| resolve_vtables_in_fn_ctxt(bcx.fcx, *vts)) + bcx.tcx().vtable_map.borrow().find(&id).map(|vts| { + resolve_vtables_in_fn_ctxt(bcx.fcx, vts.as_slice()) + }) } // Apply the typaram substitutions in the FunctionContext to some // vtables. This should eliminate any vtable_params. -pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res) - -> typeck::vtable_res { +pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, + vts: &[typeck::vtable_param_res]) + -> typeck::vtable_res { resolve_vtables_under_param_substs(fcx.ccx.tcx(), fcx.param_substs, vts) } pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt, - param_substs: Option<@param_substs>, - vts: typeck::vtable_res) - -> typeck::vtable_res { - @vts.iter().map(|ds| + param_substs: Option<¶m_substs>, + vts: &[typeck::vtable_param_res]) + -> typeck::vtable_res { + vts.iter().map(|ds| { resolve_param_vtables_under_param_substs(tcx, param_substs, - *ds)) - .collect() + ds.as_slice()) + }).collect() } pub fn resolve_param_vtables_under_param_substs( tcx: &ty::ctxt, - param_substs: Option<@param_substs>, - ds: typeck::vtable_param_res) + param_substs: Option<¶m_substs>, + ds: &[typeck::vtable_origin]) -> typeck::vtable_param_res { - @ds.iter().map( - |d| resolve_vtable_under_param_substs(tcx, - param_substs, - d)) - .collect() + ds.iter().map(|d| { + resolve_vtable_under_param_substs(tcx, + param_substs, + d) + }).collect() } pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, vt: &typeck::vtable_origin) -> typeck::vtable_origin { match *vt { - typeck::vtable_static(trait_id, ref tys, sub) => { + typeck::vtable_static(trait_id, ref tys, ref sub) => { let tys = match param_substs { Some(substs) => { tys.iter().map(|t| { @@ -857,7 +797,7 @@ pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt, }; typeck::vtable_static( trait_id, tys, - resolve_vtables_under_param_substs(tcx, param_substs, sub)) + resolve_vtables_under_param_substs(tcx, param_substs, sub.as_slice())) } typeck::vtable_param(n_param, n_bound) => { match param_substs { @@ -883,11 +823,11 @@ pub fn find_vtable(tcx: &ty::ctxt, n_param, n_bound, ps.repr(tcx)); let param_bounds = match n_param { - typeck::param_self => ps.self_vtables.expect("self vtables missing"), + typeck::param_self => ps.self_vtables.as_ref().expect("self vtables missing"), typeck::param_numbered(n) => { - let tables = ps.vtables + let tables = ps.vtables.as_ref() .expect("vtables missing where they are needed"); - *tables.get(n) + tables.get(n) } }; param_bounds.get(n_bound).clone() diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 8848feb8889..759e48e633f 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -130,7 +130,7 @@ fn const_deref_ptr(cx: &CrateContext, v: ValueRef) -> ValueRef { fn const_deref_newtype(cx: &CrateContext, v: ValueRef, t: ty::t) -> ValueRef { let repr = adt::represent_type(cx, t); - adt::const_get_field(cx, repr, v, 0, 0) + adt::const_get_field(cx, &*repr, v, 0, 0) } fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool) @@ -187,13 +187,12 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef let mut llconst = llconst; let mut inlineable = inlineable; let ety = ty::expr_ty(cx.tcx(), e); - let ety_adjusted = ty::expr_ty_adjusted(cx.tcx(), e, - &*cx.maps.method_map.borrow()); + let ety_adjusted = ty::expr_ty_adjusted(cx.tcx(), e); let opt_adj = cx.tcx.adjustments.borrow().find_copy(&e.id); match opt_adj { None => { } Some(adj) => { - match *adj { + match adj { ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => { let def = ty::resolve_expr(cx.tcx(), e); let wrapper = closure::get_wrapper_for_bare_fn(cx, @@ -414,19 +413,17 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, }, true) } ast::ExprField(base, field, _) => { - let bt = ty::expr_ty_adjusted(cx.tcx(), base, - &*cx.maps.method_map.borrow()); + let bt = ty::expr_ty_adjusted(cx.tcx(), base); let brepr = adt::represent_type(cx, bt); let (bv, inlineable) = const_expr(cx, base, is_local); expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys); - (adt::const_get_field(cx, brepr, bv, discr, ix), inlineable) + (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable) }) } ast::ExprIndex(base, index) => { - let bt = ty::expr_ty_adjusted(cx.tcx(), base, - &*cx.maps.method_map.borrow()); + let bt = ty::expr_ty_adjusted(cx.tcx(), base); let (bv, inlineable) = const_expr(cx, base, is_local); let iv = match const_eval::eval_const_expr(cx.tcx(), index) { const_eval::const_int(i) => i as u64, @@ -494,7 +491,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, (expr::cast_enum, expr::cast_integral) | (expr::cast_enum, expr::cast_float) => { let repr = adt::represent_type(cx, basety); - let discr = adt::const_get_discrim(cx, repr, v); + let discr = adt::const_get_discrim(cx, &*repr, v); let iv = C_integral(cx.int_type, discr, false); let ety_cast = expr::cast_type_kind(ety); match ety_cast { @@ -527,7 +524,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, let ety = ty::expr_ty(cx.tcx(), e); let repr = adt::represent_type(cx, ety); let (vals, inlineable) = map_list(es.as_slice()); - (adt::trans_const(cx, repr, 0, vals.as_slice()), inlineable) + (adt::trans_const(cx, &*repr, 0, vals.as_slice()), inlineable) } ast::ExprStruct(_, ref fs, ref base_opt) => { let ety = ty::expr_ty(cx.tcx(), e); @@ -547,7 +544,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, None => { match base_val { Some((bv, inlineable)) => { - (adt::const_get_field(cx, repr, bv, discr, ix), + (adt::const_get_field(cx, &*repr, bv, discr, ix), inlineable) } None => cx.sess().span_bug(e.span, "missing struct field") @@ -555,7 +552,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, } } })); - (adt::trans_const(cx, repr, discr, cs), + (adt::trans_const(cx, &*repr, discr, cs), inlineable.iter().fold(true, |a, &b| a && b)) }) } @@ -635,7 +632,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, let vinfo = ty::enum_variant_with_id(cx.tcx(), enum_did, variant_did); - (adt::trans_const(cx, repr, vinfo.disr_val, []), true) + (adt::trans_const(cx, &*repr, vinfo.disr_val, []), true) } Some(ast::DefStruct(_)) => { let ety = ty::expr_ty(cx.tcx(), e); @@ -654,7 +651,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, let ety = ty::expr_ty(cx.tcx(), e); let repr = adt::represent_type(cx, ety); let (arg_vals, inlineable) = map_list(args.as_slice()); - (adt::trans_const(cx, repr, 0, arg_vals.as_slice()), + (adt::trans_const(cx, &*repr, 0, arg_vals.as_slice()), inlineable) } Some(ast::DefVariant(enum_did, variant_did, _)) => { @@ -665,7 +662,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, variant_did); let (arg_vals, inlineable) = map_list(args.as_slice()); (adt::trans_const(cx, - repr, + &*repr, vinfo.disr_val, arg_vals.as_slice()), inlineable) } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 4aad1cded1e..119750cd9ce 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -20,8 +20,9 @@ use middle::resolve; use middle::trans::adt; use middle::trans::base; use middle::trans::builder::Builder; -use middle::trans::common::{mono_id,ExternMap,tydesc_info,BuilderRef_res,Stats}; +use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res}; use middle::trans::debuginfo; +use middle::trans::monomorphize::MonoId; use middle::trans::type_::Type; use middle::ty; use util::sha2::Sha256; @@ -30,10 +31,26 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap}; use std::cell::{Cell, RefCell}; use std::c_str::ToCStr; use std::ptr; +use std::rc::Rc; use collections::{HashMap, HashSet}; use syntax::ast; use syntax::parse::token::InternedString; +pub struct Stats { + pub n_static_tydescs: Cell, + pub n_glues_created: Cell, + pub n_null_glues: Cell, + pub n_real_glues: Cell, + pub n_fns: Cell, + pub n_monos: Cell, + pub n_inlines: Cell, + pub n_closures: Cell, + pub n_llvm_insns: Cell, + pub llvm_insns: RefCell>, + // (ident, time-in-ms, llvm-instructions) + pub fn_stats: RefCell >, +} + pub struct CrateContext { pub llmod: ModuleRef, pub llcx: ContextRef, @@ -47,7 +64,7 @@ pub struct CrateContext { pub item_symbols: RefCell>, pub link_meta: LinkMeta, pub drop_glues: RefCell>, - pub tydescs: RefCell>, + pub tydescs: RefCell>>, /// Set when running emit_tydescs to enforce that no more tydescs are /// created. pub finished_tydescs: Cell, @@ -61,10 +78,10 @@ pub struct CrateContext { /// that is generated pub non_inlineable_statics: RefCell, /// Cache instances of monomorphized functions - pub monomorphized: RefCell>, + pub monomorphized: RefCell>, pub monomorphizing: RefCell>, /// Cache generated vtables - pub vtables: RefCell>, + pub vtables: RefCell>, /// Cache of constant strings, pub const_cstr_cache: RefCell>, @@ -91,13 +108,13 @@ pub struct CrateContext { pub lltypes: RefCell>, pub llsizingtypes: RefCell>, - pub adt_reprs: RefCell>, + pub adt_reprs: RefCell>>, pub symbol_hasher: RefCell, pub type_hashcodes: RefCell>, pub all_llvm_symbols: RefCell>, pub tcx: ty::ctxt, pub maps: astencode::Maps, - pub stats: @Stats, + pub stats: Stats, pub int_type: Type, pub opaque_vec_type: Type, pub builder: BuilderRef_res, @@ -179,7 +196,7 @@ impl CrateContext { all_llvm_symbols: RefCell::new(HashSet::new()), tcx: tcx, maps: maps, - stats: @Stats { + stats: Stats { n_static_tydescs: Cell::new(0u), n_glues_created: Cell::new(0u), n_null_glues: Cell::new(0u), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index c5739960a19..4dd929e16f7 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -57,7 +57,7 @@ For example, the following simple type for a singly-linked list... ``` struct List { value: int, - tail: Option<@List>, + tail: Option<~List>, } ``` @@ -66,8 +66,8 @@ will generate the following callstack with a naive DFS algorithm: ``` describe(t = List) describe(t = int) - describe(t = Option<@List>) - describe(t = @List) + describe(t = Option<~List>) + describe(t = ~List) describe(t = List) // at the beginning again... ... ``` @@ -144,6 +144,7 @@ use util::ppaux; use std::c_str::{CString, ToCStr}; use std::cell::{Cell, RefCell}; +use std::rc::{Rc, Weak}; use collections::HashMap; use collections::HashSet; use libc::{c_uint, c_ulonglong, c_longlong}; @@ -180,7 +181,7 @@ pub struct CrateDebugContext { created_files: RefCell>, created_types: RefCell>, created_enum_disr_types: RefCell>, - namespace_map: RefCell , @NamespaceTreeNode>>, + namespace_map: RefCell, Rc>>, // This collection is used to assert that composite types (structs, enums, ...) have their // members only set once: composite_types_completed: RefCell>, @@ -369,7 +370,7 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) { } let cx = bcx.ccx(); - let def_map = cx.tcx.def_map; + let def_map = &cx.tcx.def_map; pat_util::pat_bindings(def_map, local.pat, |_, node_id, span, path_ref| { let var_ident = ast_util::path_to_ident(path_ref); @@ -509,7 +510,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { let fcx = bcx.fcx; let cx = fcx.ccx; - let def_map = cx.tcx.def_map; + let def_map = &cx.tcx.def_map; let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; pat_util::pat_bindings(def_map, arg.pat, |_, node_id, span, path_ref| { @@ -609,7 +610,7 @@ pub fn start_emitting_source_locations(fcx: &FunctionContext) { /// indicates why no debuginfo should be created for the function. pub fn create_function_debug_context(cx: &CrateContext, fn_ast_id: ast::NodeId, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, llfn: ValueRef) -> FunctionDebugContext { if cx.sess().opts.debuginfo == NoDebugInfo { return FunctionDebugContext { repr: DebugInfoDisabled }; @@ -775,7 +776,7 @@ pub fn create_function_debug_context(cx: &CrateContext, fn get_function_signature(cx: &CrateContext, fn_ast_id: ast::NodeId, fn_decl: &ast::FnDecl, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, error_span: Span) -> DIArray { if cx.sess().opts.debuginfo == LimitedDebugInfo { return create_DIArray(DIB(cx), []); @@ -828,7 +829,7 @@ pub fn create_function_debug_context(cx: &CrateContext, fn get_template_parameters(cx: &CrateContext, generics: &ast::Generics, - param_substs: Option<@param_substs>, + param_substs: Option<¶m_substs>, file_metadata: DIFile, name_to_append_suffix_to: &mut StrBuf) -> DIArray { @@ -1388,8 +1389,8 @@ fn prepare_tuple_metadata(cx: &CrateContext, } struct GeneralMemberDescriptionFactory { - type_rep: @adt::Repr, - variants: @Vec<@ty::VariantInfo> , + type_rep: Rc, + variants: Rc>>, discriminant_type_metadata: ValueRef, containing_scope: DIScope, file_metadata: DIFile, @@ -1412,7 +1413,7 @@ impl GeneralMemberDescriptionFactory { let (variant_type_metadata, variant_llvm_type, member_desc_factory) = describe_enum_variant(cx, struct_def, - *self.variants.get(i), + &**self.variants.get(i), Some(self.discriminant_type_metadata), self.containing_scope, self.file_metadata, @@ -1617,7 +1618,7 @@ fn prepare_enum_metadata(cx: &CrateContext, member_description_factory) = describe_enum_variant(cx, struct_def, - *variants.get(0), + &**variants.get(0), None, containing_scope, file_metadata, @@ -1661,7 +1662,7 @@ fn prepare_enum_metadata(cx: &CrateContext, llvm_type: enum_llvm_type, file_metadata: file_metadata, member_description_factory: GeneralMD(GeneralMemberDescriptionFactory { - type_rep: type_rep, + type_rep: type_rep.clone(), variants: variants, discriminant_type_metadata: discriminant_type_metadata, containing_scope: containing_scope, @@ -1676,7 +1677,7 @@ fn prepare_enum_metadata(cx: &CrateContext, member_description_factory) = describe_enum_variant(cx, struct_def, - *variants.get(nndiscr as uint), + &**variants.get(nndiscr as uint), None, containing_scope, file_metadata, @@ -2381,7 +2382,7 @@ fn populate_scope_map(cx: &CrateContext, fn_entry_block: &ast::Block, fn_metadata: DISubprogram, scope_map: &mut HashMap) { - let def_map = cx.tcx.def_map; + let def_map = &cx.tcx.def_map; struct ScopeStackEntry { scope_metadata: DIScope, @@ -2494,7 +2495,7 @@ fn populate_scope_map(cx: &CrateContext, scope_stack: &mut Vec , scope_map: &mut HashMap) { - let def_map = cx.tcx.def_map; + let def_map = &cx.tcx.def_map; // Unfortunately, we cannot just use pat_util::pat_bindings() or ast_util::walk_pat() here // because we have to visit *all* nodes in order to put them into the scope map. The above @@ -2830,14 +2831,14 @@ fn populate_scope_map(cx: &CrateContext, struct NamespaceTreeNode { name: ast::Name, scope: DIScope, - parent: Option<@NamespaceTreeNode>, + parent: Option>, } impl NamespaceTreeNode { fn mangled_name_of_contained_item(&self, item_name: &str) -> ~str { fn fill_nested(node: &NamespaceTreeNode, output: &mut StrBuf) { match node.parent { - Some(parent) => fill_nested(parent, output), + Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output), None => {} } let string = token::get_name(node.name); @@ -2854,7 +2855,7 @@ impl NamespaceTreeNode { } } -fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> @NamespaceTreeNode { +fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc { ty::with_path(cx.tcx(), def_id, |path| { // prepend crate name if not already present let krate = if def_id.krate == ast::LOCAL_CRATE { @@ -2866,7 +2867,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> @NamespaceTreeNo let mut path = krate.move_iter().chain(path).peekable(); let mut current_key = Vec::new(); - let mut parent_node: Option<@NamespaceTreeNode> = None; + let mut parent_node: Option> = None; // Create/Lookup namespace for each element of the path. loop { @@ -2890,7 +2891,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> @NamespaceTreeNo None => { // create and insert let parent_scope = match parent_node { - Some(node) => node.scope, + Some(ref node) => node.scope, None => ptr::null() }; let namespace_name = token::get_name(name); @@ -2907,14 +2908,14 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> @NamespaceTreeNo } }); - let node = @NamespaceTreeNode { + let node = Rc::new(NamespaceTreeNode { name: name, scope: scope, - parent: parent_node, - }; + parent: parent_node.map(|parent| parent.downgrade()), + }); debug_context(cx).namespace_map.borrow_mut() - .insert(current_key.clone(), node); + .insert(current_key.clone(), node.clone()); node } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 4e850b8990a..3c1dfedcac6 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -118,7 +118,7 @@ pub fn trans_into<'a>(bcx: &'a Block<'a>, bcx.fcx.push_ast_cleanup_scope(expr.id); - let kind = ty::expr_kind(bcx.tcx(), bcx.ccx().maps.method_map, expr); + let kind = ty::expr_kind(bcx.tcx(), expr); bcx = match kind { ty::LvalueExpr | ty::RvalueDatumExpr => { trans_unadjusted(bcx, expr).store_to_dest(dest, expr.id) @@ -175,7 +175,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, }; debug!("unadjusted datum for expr {}: {}", expr.id, datum.to_str(bcx.ccx())); - match *adjustment { + match adjustment { AutoAddEnv(..) => { datum = unpack_datum!(bcx, add_env(bcx, expr, datum)); } @@ -205,8 +205,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, }; } AutoObject(..) => { - let adjusted_ty = ty::expr_ty_adjusted(bcx.tcx(), expr, - &*bcx.ccx().maps.method_map.borrow()); + let adjusted_ty = ty::expr_ty_adjusted(bcx.tcx(), expr); let scratch = rvalue_scratch_datum(bcx, adjusted_ty, "__adjust"); bcx = meth::trans_trait_cast( bcx, datum, expr.id, SaveIn(scratch.val)); @@ -323,7 +322,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>, debuginfo::set_source_location(bcx.fcx, expr.id, expr.span); - return match ty::expr_kind(bcx.tcx(), bcx.ccx().maps.method_map, expr) { + return match ty::expr_kind(bcx.tcx(), expr) { ty::LvalueExpr | ty::RvalueDatumExpr => { let datum = unpack_datum!(bcx, { trans_datum_unadjusted(bcx, expr) @@ -444,7 +443,7 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>, let ix = ty::field_idx_strict(bcx.tcx(), field.name, field_tys); let d = base_datum.get_element( field_tys[ix].mt.ty, - |srcval| adt::trans_field_ptr(bcx, repr, srcval, discr, ix)); + |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, ix)); DatumBlock { datum: d.to_expr_datum(), bcx: bcx } }) } @@ -680,7 +679,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>, let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr)); let numbered_fields: Vec<(uint, @ast::Expr)> = args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect(); - trans_adt(bcx, repr, 0, numbered_fields.as_slice(), None, dest) + trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest) } ast::ExprLit(lit) => { match lit.node { @@ -798,7 +797,7 @@ fn trans_def_dps_unadjusted<'a>( // Nullary variant. let ty = expr_ty(bcx, ref_expr); let repr = adt::represent_type(bcx.ccx(), ty); - adt::trans_start_init(bcx, repr, lldest, + adt::trans_start_init(bcx, &*repr, lldest, variant_info.disr_val); return bcx; } @@ -808,7 +807,7 @@ fn trans_def_dps_unadjusted<'a>( match ty::get(ty).sty { ty::ty_struct(did, _) if ty::has_dtor(bcx.tcx(), did) => { let repr = adt::represent_type(bcx.ccx(), ty); - adt::trans_start_init(bcx, repr, lldest, 0); + adt::trans_start_init(bcx, &*repr, lldest, 0); } _ => {} } @@ -1005,7 +1004,7 @@ fn trans_rec_or_struct<'a>( }; let repr = adt::represent_type(bcx.ccx(), ty); - trans_adt(bcx, repr, discr, numbered_fields.as_slice(), optbase, dest) + trans_adt(bcx, &*repr, discr, numbered_fields.as_slice(), optbase, dest) }) } @@ -1118,7 +1117,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>, // Otherwise, we should be in the RvalueDpsExpr path. assert!( op == ast::UnDeref || - !ccx.maps.method_map.borrow().contains_key(&method_call)); + !ccx.tcx.method_map.borrow().contains_key(&method_call)); let un_ty = expr_ty(bcx, expr); @@ -1240,8 +1239,8 @@ fn trans_gc<'a>(mut bcx: &'a Block<'a>, SaveIn(addr) => { let expr_ty = expr_ty(bcx, expr); let repr = adt::represent_type(bcx.ccx(), expr_ty); - adt::trans_start_init(bcx, repr, addr, 0); - let field_dest = adt::trans_field_ptr(bcx, repr, addr, 0, 0); + adt::trans_start_init(bcx, &*repr, addr, 0); + let field_dest = adt::trans_field_ptr(bcx, &*repr, addr, 0, 0); contents_datum.store_to(bcx, field_dest) } } @@ -1403,7 +1402,7 @@ fn trans_binary<'a>(bcx: &'a Block<'a>, let ccx = bcx.ccx(); // if overloaded, would be RvalueDpsExpr - assert!(!ccx.maps.method_map.borrow().contains_key(&MethodCall::expr(expr.id))); + assert!(!ccx.tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id))); match op { ast::BiAnd => { @@ -1443,7 +1442,7 @@ fn trans_overloaded_op<'a, 'b>( rhs: Option<(Datum, ast::NodeId)>, dest: Option) -> Result<'a> { - let method_ty = bcx.ccx().maps.method_map.borrow().get(&method_call).ty; + let method_ty = bcx.tcx().method_map.borrow().get(&method_call).ty; callee::trans_call_inner(bcx, Some(expr_info(expr)), monomorphize_type(bcx, method_ty), @@ -1581,7 +1580,7 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>, bcx, datum.to_lvalue_datum(bcx, "trans_imm_cast", expr.id)); let llexpr_ptr = datum.to_llref(); let lldiscrim_a = - adt::trans_get_discr(bcx, repr, llexpr_ptr, Some(Type::i64(ccx))); + adt::trans_get_discr(bcx, &*repr, llexpr_ptr, Some(Type::i64(ccx))); match k_out { cast_integral => int_cast(bcx, ll_t_out, val_ty(lldiscrim_a), @@ -1614,7 +1613,7 @@ fn trans_assign_op<'a>( debug!("trans_assign_op(expr={})", bcx.expr_to_str(expr)); // User-defined operator methods cannot be used with `+=` etc right now - assert!(!bcx.ccx().maps.method_map.borrow().contains_key(&MethodCall::expr(expr.id))); + assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id))); // Evaluate LHS (destination), which should be an lvalue let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op")); @@ -1692,7 +1691,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>, expr_id: expr.id, autoderef: derefs as u32 }; - let method_ty = ccx.maps.method_map.borrow() + let method_ty = ccx.tcx.method_map.borrow() .find(&method_call).map(|method| method.ty); let datum = match method_ty { Some(method_ty) => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 98e09b2fd31..8488261db9c 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -145,39 +145,34 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef { glue } -pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: @tydesc_info) { +pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef { let _icx = push_ctxt("lazily_emit_visit_glue"); let llfnty = Type::glue_fn(ccx, type_of(ccx, ti.ty).ptr_to()); match ti.visit_glue.get() { - Some(_) => (), + Some(visit_glue) => visit_glue, None => { debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty)); let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit"); ti.visit_glue.set(Some(glue_fn)); make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit"); debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty)); + glue_fn } } } // See [Note-arg-mode] pub fn call_visit_glue(bcx: &Block, v: ValueRef, tydesc: ValueRef, - static_ti: Option<@tydesc_info>) { + static_ti: Option<&tydesc_info>) { let _icx = push_ctxt("call_tydesc_glue_full"); let ccx = bcx.ccx(); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. if bcx.unreachable.get() && !ccx.sess().no_landing_pads() { return; } - let static_glue_fn = match static_ti { - None => None, - Some(sti) => { - lazily_emit_visit_glue(ccx, sti); - sti.visit_glue.get() - } - }; + let static_glue_fn = static_ti.map(|sti| lazily_emit_visit_glue(ccx, sti)); // When static type info is available, avoid casting to a generic pointer. let llrawptr = if static_glue_fn.is_none() { @@ -224,7 +219,7 @@ fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>, substs: &ty::substs) -> &'a Block<'a> { let repr = adt::represent_type(bcx.ccx(), t); - let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0); + let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0); with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| { trans_struct_drop(cx, t, v0, dtor_did, class_did, substs) }) @@ -265,7 +260,7 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>, // this scope. let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs); for (i, fld) in field_tys.iter().enumerate() { - let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i); + let llfld_a = adt::trans_field_ptr(bcx, &*repr, v0, 0, i); bcx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope), llfld_a, fld.mt.ty); @@ -404,7 +399,7 @@ fn incr_refcnt_of_boxed<'a>(bcx: &'a Block<'a>, // Generates the declaration for (but doesn't emit) a type descriptor. -pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { +pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info { // If emit_tydescs already ran, then we shouldn't be creating any new // tydescs. assert!(!ccx.finished_tydescs.get()); @@ -430,16 +425,15 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { let ty_name = token::intern_and_get_ident(ppaux::ty_to_str(ccx.tcx(), t)); let ty_name = C_str_slice(ccx, ty_name); - let inf = @tydesc_info { + debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t)); + tydesc_info { ty: t, tydesc: gvar, size: llsize, align: llalign, name: ty_name, visit_glue: Cell::new(None), - }; - debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t)); - return inf; + } } fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, @@ -466,7 +460,7 @@ fn make_generic_glue(ccx: &CrateContext, let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(), None, None, &arena); - init_function(&fcx, false, ty::mk_nil(), None); + init_function(&fcx, false, ty::mk_nil()); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u); @@ -491,9 +485,7 @@ pub fn emit_tydescs(ccx: &CrateContext) { // As of this point, allow no more tydescs to be created. ccx.finished_tydescs.set(true); let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to(); - for (_, &val) in ccx.tydescs.borrow().iter() { - let ti = val; - + for (_, ti) in ccx.tydescs.borrow().iter() { // Each of the glue functions needs to be cast to a generic type // before being put into the tydesc because we only have a singleton // tydesc type. Then we'll recast each function to its real type when diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index 9e5213e6a99..3a0083ba5c6 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -85,7 +85,7 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Opti pub fn trans_intrinsic(ccx: &CrateContext, decl: ValueRef, item: &ast::ForeignItem, - substs: @param_substs, + substs: ¶m_substs, ref_id: Option) { debug!("trans_intrinsic(item.ident={})", token::get_ident(item.ident)); @@ -194,8 +194,8 @@ pub fn trans_intrinsic(ccx: &CrateContext, let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, decl, item.id, false, output_type, - Some(substs), Some(item.span), &arena); - init_function(&fcx, true, output_type, Some(substs)); + Some(&*substs), Some(item.span), &arena); + init_function(&fcx, true, output_type); set_always_inline(fcx.llfn); @@ -328,7 +328,7 @@ pub fn trans_intrinsic(ccx: &CrateContext, "get_tydesc" => { let tp_ty = *substs.tys.get(0); let static_ti = get_tydesc(ccx, tp_ty); - glue::lazily_emit_visit_glue(ccx, static_ti); + glue::lazily_emit_visit_glue(ccx, &*static_ti); // FIXME (#3730): ideally this shouldn't need a cast, // but there's a circularity between translating rust types to llvm diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 851f8207cb6..d122edb7678 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -83,7 +83,7 @@ pub fn trans_method_callee<'a>( -> Callee<'a> { let _icx = push_ctxt("meth::trans_method_callee"); - let (origin, method_ty) = match bcx.ccx().maps.method_map + let (origin, method_ty) = match bcx.tcx().method_map .borrow().find(&method_call) { Some(method) => { debug!("trans_method_callee({:?}, method={})", @@ -193,21 +193,21 @@ pub fn trans_static_method_callee(bcx: &Block, name={}", method_id, expr_id, token::get_name(mname)); let vtable_key = MethodCall::expr(expr_id); - let vtbls = ccx.maps.vtable_map.borrow().get_copy(&vtable_key); - let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls); + let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, ccx.tcx.vtable_map.borrow() + .get(&vtable_key).as_slice()); - match vtbls.get(bound_index).get(0) { - &typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { + match vtbls.move_iter().nth(bound_index).unwrap().move_iter().nth(0).unwrap() { + typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => { assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t))); let mth_id = method_with_name(ccx, impl_did, mname); let (callee_substs, callee_origins) = combine_impl_and_methods_tps( bcx, mth_id, ExprId(expr_id), - rcvr_substs.as_slice(), rcvr_origins); + rcvr_substs, rcvr_origins); let llfn = trans_fn_ref_with_vtables(bcx, mth_id, ExprId(expr_id), - callee_substs.as_slice(), + callee_substs, Some(callee_origins)); let callee_ty = node_id_type(bcx, expr_id); @@ -221,22 +221,22 @@ pub fn trans_static_method_callee(bcx: &Block, } } -pub fn method_with_name(ccx: &CrateContext, - impl_id: ast::DefId, - name: ast::Name) -> ast::DefId { +fn method_with_name(ccx: &CrateContext, + impl_id: ast::DefId, + name: ast::Name) -> ast::DefId { match ccx.impl_method_cache.borrow().find_copy(&(impl_id, name)) { Some(m) => return m, None => {} } - let imp = ccx.tcx.impls.borrow(); - let imp = imp.find(&impl_id) - .expect("could not find impl while translating"); - let meth = imp.methods.iter().find(|m| m.ident.name == name) - .expect("could not find method while translating"); + let methods = ccx.tcx.impl_methods.borrow(); + let methods = methods.find(&impl_id) + .expect("could not find impl while translating"); + let meth_did = methods.iter().find(|&did| ty::method(&ccx.tcx, *did).ident.name == name) + .expect("could not find method while translating"); - ccx.impl_method_cache.borrow_mut().insert((impl_id, name), meth.def_id); - meth.def_id + ccx.impl_method_cache.borrow_mut().insert((impl_id, name), *meth_did); + *meth_did } fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>, @@ -247,7 +247,7 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>, -> Callee<'a> { let _icx = push_ctxt("meth::trans_monomorphized_callee"); match vtbl { - typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { + typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => { let ccx = bcx.ccx(); let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident; let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name); @@ -257,13 +257,13 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>, let (callee_substs, callee_origins) = combine_impl_and_methods_tps( bcx, mth_id, MethodCall(method_call), - rcvr_substs.as_slice(), rcvr_origins); + rcvr_substs, rcvr_origins); // translate the function let llfn = trans_fn_ref_with_vtables(bcx, mth_id, MethodCall(method_call), - callee_substs.as_slice(), + callee_substs, Some(callee_origins)); Callee { bcx: bcx, data: Fn(llfn) } @@ -277,9 +277,9 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>, fn combine_impl_and_methods_tps(bcx: &Block, mth_did: ast::DefId, node: ExprOrMethodCall, - rcvr_substs: &[ty::t], + rcvr_substs: Vec, rcvr_origins: typeck::vtable_res) - -> (Vec , typeck::vtable_res) { + -> (Vec, typeck::vtable_res) { /*! * * Creates a concatenated set of substitutions which includes @@ -302,10 +302,13 @@ fn combine_impl_and_methods_tps(bcx: &Block, let n_m_tps = method.generics.type_param_defs().len(); let node_substs = node_id_type_params(bcx, node); debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx())); - let ty_substs - = Vec::from_slice(rcvr_substs).append(node_substs.tailn(node_substs.len() - n_m_tps)); - debug!("n_m_tps={:?}", n_m_tps); debug!("node_substs={:?}", node_substs.repr(ccx.tcx())); + let mut ty_substs = rcvr_substs; + { + let start = node_substs.len() - n_m_tps; + ty_substs.extend(node_substs.move_iter().skip(start)); + } + debug!("n_m_tps={:?}", n_m_tps); debug!("ty_substs={:?}", ty_substs.repr(ccx.tcx())); @@ -315,14 +318,20 @@ fn combine_impl_and_methods_tps(bcx: &Block, ExprId(id) => MethodCall::expr(id), MethodCall(method_call) => method_call }; - let vtables = node_vtables(bcx, vtable_key); - let r_m_origins = match vtables { - Some(vt) => vt, - None => @Vec::from_elem(node_substs.len(), @Vec::new()) - }; - let vtables - = @Vec::from_slice(rcvr_origins.as_slice()) - .append(r_m_origins.tailn(r_m_origins.len() - n_m_tps)); + let mut vtables = rcvr_origins; + match node_vtables(bcx, vtable_key) { + Some(vt) => { + let start = vt.len() - n_m_tps; + vtables.extend(vt.move_iter().skip(start)); + } + None => { + vtables.extend(range(0, n_m_tps).map( + |_| -> typeck::vtable_param_res { + Vec::new() + } + )); + } + } (ty_substs, vtables) } @@ -418,83 +427,50 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>, }; } -pub fn vtable_id(ccx: &CrateContext, - origin: &typeck::vtable_origin) - -> mono_id { - match origin { - &typeck::vtable_static(impl_id, ref substs, sub_vtables) => { - let psubsts = param_substs { - tys: (*substs).clone(), - vtables: Some(sub_vtables), - self_ty: None, - self_vtables: None - }; - - monomorphize::make_mono_id( - ccx, - impl_id, - &psubsts) - } - - // can't this be checked at the callee? - _ => fail!("vtable_id") - } -} - /// Creates a returns a dynamic vtable for the given type and vtable origin. /// This is used only for objects. -pub fn get_vtable(bcx: &Block, - self_ty: ty::t, - origins: typeck::vtable_param_res) - -> ValueRef { +fn get_vtable(bcx: &Block, + self_ty: ty::t, + origins: typeck::vtable_param_res) + -> ValueRef { let ccx = bcx.ccx(); let _icx = push_ctxt("meth::get_vtable"); // Check the cache. - let hash_id = (self_ty, vtable_id(ccx, origins.get(0))); + let hash_id = (self_ty, monomorphize::make_vtable_id(ccx, origins.get(0))); match ccx.vtables.borrow().find(&hash_id) { Some(&val) => { return val } None => { } } // Not in the cache. Actually build it. - let mut methods = Vec::new(); - for origin in origins.iter() { - match *origin { - typeck::vtable_static(id, ref substs, sub_vtables) => { - let vtable_methods = emit_vtable_methods(bcx, - id, - substs.as_slice(), - sub_vtables); - for vtable_method in vtable_methods.move_iter() { - methods.push(vtable_method) - } + let methods = origins.move_iter().flat_map(|origin| { + match origin { + typeck::vtable_static(id, substs, sub_vtables) => { + emit_vtable_methods(bcx, id, substs, sub_vtables).move_iter() } _ => ccx.sess().bug("get_vtable: expected a static origin"), } - } + }); // Generate a destructor for the vtable. let drop_glue = glue::get_drop_glue(ccx, self_ty); - let vtable = make_vtable(ccx, drop_glue, methods.as_slice()); + let vtable = make_vtable(ccx, drop_glue, methods); ccx.vtables.borrow_mut().insert(hash_id, vtable); - return vtable; + vtable } /// Helper function to declare and initialize the vtable. -pub fn make_vtable(ccx: &CrateContext, - drop_glue: ValueRef, - ptrs: &[ValueRef]) - -> ValueRef { +pub fn make_vtable>(ccx: &CrateContext, + drop_glue: ValueRef, + ptrs: I) + -> ValueRef { + let _icx = push_ctxt("meth::make_vtable"); + + let components: Vec<_> = Some(drop_glue).move_iter().chain(ptrs).collect(); + unsafe { - let _icx = push_ctxt("meth::make_vtable"); - - let mut components = vec!(drop_glue); - for &ptr in ptrs.iter() { - components.push(ptr) - } - let tbl = C_struct(ccx, components.as_slice(), false); let sym = token::gensym("vtable"); let vt_gvar = format!("vtable{}", sym).with_c_str(|buf| { @@ -509,7 +485,7 @@ pub fn make_vtable(ccx: &CrateContext, fn emit_vtable_methods(bcx: &Block, impl_id: ast::DefId, - substs: &[ty::t], + substs: Vec, vtables: typeck::vtable_res) -> Vec { let ccx = bcx.ccx(); @@ -539,7 +515,8 @@ fn emit_vtable_methods(bcx: &Block, token::get_ident(ident)); C_null(Type::nil(ccx).ptr_to()) } else { - trans_fn_ref_with_vtables(bcx, m_id, ExprId(0), substs, Some(vtables)) + trans_fn_ref_with_vtables(bcx, m_id, ExprId(0), + substs.clone(), Some(vtables.clone())) } }).collect() } @@ -576,8 +553,12 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>, bcx = datum.store_to(bcx, llboxdest); // Store the vtable into the second half of pair. - let res = *ccx.maps.vtable_map.borrow().get(&MethodCall::expr(id)); - let origins = *resolve_vtables_in_fn_ctxt(bcx.fcx, res).get(0); + let origins = { + let vtable_map = ccx.tcx.vtable_map.borrow(); + resolve_param_vtables_under_param_substs(ccx.tcx(), + bcx.fcx.param_substs, + vtable_map.get(&MethodCall::expr(id)).get(0).as_slice()) + }; let vtable = get_vtable(bcx, v_ty, origins); let llvtabledest = GEPi(bcx, lldest, [0u, abi::trt_field_vtable]); let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to()); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 7d7ea5a2211..aa6e2dafd83 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -16,7 +16,6 @@ use middle::trans::base::{trans_enum_variant, push_ctxt, get_item_val}; use middle::trans::base::{trans_fn, decl_internal_rust_fn}; use middle::trans::base; use middle::trans::common::*; -use middle::trans::meth; use middle::trans::intrinsic; use middle::ty; use middle::typeck; @@ -26,7 +25,7 @@ use syntax::abi; use syntax::ast; use syntax::ast_map; use syntax::ast_util::local_def; -use std::hash::sip; +use std::hash::{sip, Hash}; pub fn monomorphic_fn(ccx: &CrateContext, fn_id: ast::DefId, @@ -47,26 +46,51 @@ pub fn monomorphic_fn(ccx: &CrateContext, self_vtables.repr(ccx.tcx()), ref_id); - assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); - let _icx = push_ctxt("monomorphic_fn"); - let mut must_cast = false; + assert!(real_substs.tps.iter().all(|t| { + !ty::type_needs_infer(*t) && !ty::type_has_params(*t) + })); - let psubsts = @param_substs { + let _icx = push_ctxt("monomorphic_fn"); + + let substs_iter = real_substs.self_ty.iter().chain(real_substs.tps.iter()); + let param_ids: Vec = match vtables { + Some(ref vts) => { + debug!("make_mono_id vtables={} psubsts={}", + vts.repr(ccx.tcx()), real_substs.tps.repr(ccx.tcx())); + let vts_iter = self_vtables.iter().chain(vts.iter()); + vts_iter.zip(substs_iter).map(|(vtable, subst)| MonoParamId { + subst: *subst, + // Do we really need the vtables to be hashed? Isn't the type enough? + vtables: vtable.iter().map(|vt| make_vtable_id(ccx, vt)).collect() + }).collect() + } + None => substs_iter.map(|subst| MonoParamId { + subst: *subst, + vtables: Vec::new() + }).collect() + }; + + let hash_id = MonoId { + def: fn_id, + params: param_ids + }; + + match ccx.monomorphized.borrow().find(&hash_id) { + Some(&val) => { + debug!("leaving monomorphic fn {}", + ty::item_path_str(ccx.tcx(), fn_id)); + return (val, false); + } + None => () + } + + let psubsts = param_substs { tys: real_substs.tps.clone(), vtables: vtables, self_ty: real_substs.self_ty.clone(), self_vtables: self_vtables }; - for s in real_substs.tps.iter() { assert!(!ty::type_has_params(*s)); } - for s in psubsts.tys.iter() { assert!(!ty::type_has_params(*s)); } - - let hash_id = make_mono_id(ccx, fn_id, &*psubsts); - if hash_id.params.iter().any( - |p| match *p { mono_precise(_, _) => false, _ => true }) { - must_cast = true; - } - debug!("monomorphic_fn(\ fn_id={}, \ psubsts={}, \ @@ -75,15 +99,6 @@ pub fn monomorphic_fn(ccx: &CrateContext, psubsts.repr(ccx.tcx()), hash_id); - match ccx.monomorphized.borrow().find(&hash_id) { - Some(&val) => { - debug!("leaving monomorphic fn {}", - ty::item_path_str(ccx.tcx(), fn_id)); - return (val, must_cast); - } - None => () - } - let tpt = ty::lookup_item_type(ccx.tcx(), fn_id); let llitem_ty = tpt.ty; @@ -122,8 +137,8 @@ pub fn monomorphic_fn(ccx: &CrateContext, debug!("monomorphic_fn about to subst into {}", llitem_ty.repr(ccx.tcx())); let mono_ty = match is_static_provided { - None => ty::subst_tps(ccx.tcx(), psubsts.tys.as_slice(), - psubsts.self_ty, llitem_ty), + None => ty::subst_tps(ccx.tcx(), real_substs.tps.as_slice(), + real_substs.self_ty, llitem_ty), Some(num_method_ty_params) => { // Static default methods are a little unfortunate, in // that the "internal" and "external" type of them differ. @@ -139,9 +154,9 @@ pub fn monomorphic_fn(ccx: &CrateContext, // stick a substitution for the self type in. // This is a bit unfortunate. - let idx = psubsts.tys.len() - num_method_ty_params; - let substs = psubsts.tys.slice(0, idx) + - &[psubsts.self_ty.unwrap()] + psubsts.tys.tailn(idx); + let idx = real_substs.tps.len() - num_method_ty_params; + let substs = real_substs.tps.slice(0, idx) + + &[real_substs.self_ty.unwrap()] + real_substs.tps.tailn(idx); debug!("static default: changed substitution to {}", substs.repr(ccx.tcx())); @@ -178,16 +193,22 @@ pub fn monomorphic_fn(ccx: &CrateContext, } let s = ccx.tcx.map.with_path(fn_id.node, |path| { - exported_name(path, format!("h{}", sip::hash(&(hash_id, mono_ty))), + let mut state = sip::SipState::new(); + hash_id.hash(&mut state); + mono_ty.hash(&mut state); + + exported_name(path, format!("h{}", state.result()), ccx.link_meta.crateid.version_or_default()) }); debug!("monomorphize_fn mangled to {}", s); + // This shouldn't need to option dance. + let mut hash_id = Some(hash_id); let mk_lldecl = || { let lldecl = decl_internal_rust_fn(ccx, false, f.sig.inputs.as_slice(), f.sig.output, s); - ccx.monomorphized.borrow_mut().insert(hash_id, lldecl); + ccx.monomorphized.borrow_mut().insert(hash_id.take_unwrap(), lldecl); lldecl }; @@ -200,7 +221,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, } => { let d = mk_lldecl(); set_llvm_fn_attrs(i.attrs.as_slice(), d); - trans_fn(ccx, decl, body, d, Some(psubsts), fn_id.node, []); + trans_fn(ccx, decl, body, d, Some(&psubsts), fn_id.node, []); d } _ => { @@ -214,7 +235,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, Some(decl) => decl, None => { let d = mk_lldecl(); - intrinsic::trans_intrinsic(ccx, d, i, psubsts, ref_id); + intrinsic::trans_intrinsic(ccx, d, i, &psubsts, ref_id); d } } @@ -222,7 +243,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, ast_map::NodeVariant(v) => { let parent = ccx.tcx.map.get_parent(fn_id.node); let tvs = ty::enum_variants(ccx.tcx(), local_def(parent)); - let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); + let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); let d = mk_lldecl(); set_inline_hint(d); match v.node.kind { @@ -232,7 +253,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, v, args.as_slice(), this_tv.disr_val, - Some(psubsts), + Some(&psubsts), d); } ast::StructVariantKind(_) => @@ -243,7 +264,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, ast_map::NodeMethod(mth) => { let d = mk_lldecl(); set_llvm_fn_attrs(mth.attrs.as_slice(), d); - trans_fn(ccx, mth.decl, mth.body, d, Some(psubsts), mth.id, []); + trans_fn(ccx, mth.decl, mth.body, d, Some(&psubsts), mth.id, []); d } ast_map::NodeTraitMethod(method) => { @@ -251,7 +272,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, ast::Provided(mth) => { let d = mk_lldecl(); set_llvm_fn_attrs(mth.attrs.as_slice(), d); - trans_fn(ccx, mth.decl, mth.body, d, Some(psubsts), mth.id, []); + trans_fn(ccx, mth.decl, mth.body, d, Some(&psubsts), mth.id, []); d } _ => { @@ -267,7 +288,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, struct_def.fields.as_slice(), struct_def.ctor_id.expect("ast-mapped tuple struct \ didn't have a ctor id"), - Some(psubsts), + Some(&psubsts), d); d } @@ -286,32 +307,41 @@ pub fn monomorphic_fn(ccx: &CrateContext, ccx.monomorphizing.borrow_mut().insert(fn_id, depth); debug!("leaving monomorphic fn {}", ty::item_path_str(ccx.tcx(), fn_id)); - (lldecl, must_cast) + (lldecl, false) } -pub fn make_mono_id(ccx: &CrateContext, - item: ast::DefId, - substs: ¶m_substs) -> mono_id { - // FIXME (possibly #5801): Need a lot of type hints to get - // .collect() to work. - let substs_iter = substs.self_ty.iter().chain(substs.tys.iter()); - let precise_param_ids: Vec<(ty::t, Option<@Vec >)> = match substs.vtables { - Some(vts) => { - debug!("make_mono_id vtables={} substs={}", - vts.repr(ccx.tcx()), substs.tys.repr(ccx.tcx())); - let vts_iter = substs.self_vtables.iter().chain(vts.iter()); - vts_iter.zip(substs_iter).map(|(vtable, subst)| { - let v = vtable.iter().map(|vt| meth::vtable_id(ccx, vt)).collect::>(); - (*subst, if !v.is_empty() { Some(@v) } else { None }) - }).collect() - } - None => substs_iter.map(|subst| (*subst, None::<@Vec >)).collect() - }; - - - let param_ids = precise_param_ids.iter().map(|x| { - let (a, b) = *x; - mono_precise(a, b) - }).collect(); - @mono_id_ {def: item, params: param_ids} +// Used to identify cached monomorphized functions and vtables +#[deriving(Eq, TotalEq, Hash)] +pub struct MonoParamId { + pub subst: ty::t, + // Do we really need the vtables to be hashed? Isn't the type enough? + pub vtables: Vec +} + +#[deriving(Eq, TotalEq, Hash)] +pub struct MonoId { + pub def: ast::DefId, + pub params: Vec +} + +pub fn make_vtable_id(ccx: &CrateContext, + origin: &typeck::vtable_origin) + -> MonoId { + match origin { + &typeck::vtable_static(impl_id, ref substs, ref sub_vtables) => { + MonoId { + def: impl_id, + params: sub_vtables.iter().zip(substs.iter()).map(|(vtable, subst)| { + MonoParamId { + subst: *subst, + // Do we really need the vtables to be hashed? Isn't the type enough? + vtables: vtable.iter().map(|vt| make_vtable_id(ccx, vt)).collect() + } + }).collect() + } + } + + // can't this be checked at the callee? + _ => fail!("make_vtable_id needs vtable_static") + } } diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 7dc4641e97f..a1752862715 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -25,6 +25,7 @@ use middle::trans::type_of::*; use middle::ty; use util::ppaux::ty_to_str; +use std::rc::Rc; use arena::TypedArena; use libc::c_uint; use syntax::ast::DefId; @@ -33,15 +34,15 @@ use syntax::ast_map; use syntax::parse::token::{InternedString, special_idents}; use syntax::parse::token; -pub struct Reflector<'a> { +pub struct Reflector<'a, 'b> { visitor_val: ValueRef, - visitor_methods: @Vec<@ty::Method> , - final_bcx: &'a Block<'a>, + visitor_methods: &'a [Rc], + final_bcx: &'b Block<'b>, tydesc_ty: Type, - bcx: &'a Block<'a> + bcx: &'b Block<'b> } -impl<'a> Reflector<'a> { +impl<'a, 'b> Reflector<'a, 'b> { pub fn c_uint(&mut self, u: uint) -> ValueRef { C_uint(self.bcx.ccx(), u) } @@ -75,7 +76,7 @@ impl<'a> Reflector<'a> { pub fn c_tydesc(&mut self, t: ty::t) -> ValueRef { let bcx = self.bcx; let static_ti = get_tydesc(bcx.ccx(), t); - glue::lazily_emit_visit_glue(bcx.ccx(), static_ti); + glue::lazily_emit_visit_glue(bcx.ccx(), &*static_ti); PointerCast(bcx, static_ti.tydesc, self.tydesc_ty.ptr_to()) } @@ -92,7 +93,7 @@ impl<'a> Reflector<'a> { format!("couldn't find visit method for {}", ty_name)); let mth_ty = ty::mk_bare_fn(tcx, - self.visitor_methods.get(mth_idx).fty.clone()); + self.visitor_methods[mth_idx].fty.clone()); let v = self.visitor_val; debug!("passing {} args:", args.len()); let mut bcx = self.bcx; @@ -307,7 +308,7 @@ impl<'a> Reflector<'a> { let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, llfdecl, -1, false, ty::mk_u64(), None, None, &arena); - init_function(&fcx, false, ty::mk_u64(), None); + init_function(&fcx, false, ty::mk_u64()); let arg = unsafe { // @@ -319,7 +320,7 @@ impl<'a> Reflector<'a> { }; let bcx = fcx.entry_bcx.borrow().clone().unwrap(); let arg = BitCast(bcx, arg, llptrty); - let ret = adt::trans_get_discr(bcx, repr, arg, Some(Type::i64(ccx))); + let ret = adt::trans_get_discr(bcx, &*repr, arg, Some(Type::i64(ccx))); Store(bcx, ret, fcx.llretptr.get().unwrap()); match fcx.llreturn.get() { Some(llreturn) => Br(bcx, llreturn), @@ -344,7 +345,7 @@ impl<'a> Reflector<'a> { for (j, a) in v.args.iter().enumerate() { let bcx = this.bcx; let null = C_null(llptrty); - let ptr = adt::trans_field_ptr(bcx, repr, null, v.disr_val, j); + let ptr = adt::trans_field_ptr(bcx, &*repr, null, v.disr_val, j); let offset = p2i(ccx, ptr); let field_args = [this.c_uint(j), offset, @@ -401,9 +402,10 @@ pub fn emit_calls_to_trait_visit_ty<'a>( let final = fcx.new_temp_block("final"); let tydesc_ty = ty::get_tydesc_ty(bcx.tcx()).unwrap(); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); + let visitor_methods = ty::trait_methods(bcx.tcx(), visitor_trait_id); let mut r = Reflector { visitor_val: visitor_val, - visitor_methods: ty::trait_methods(bcx.tcx(), visitor_trait_id), + visitor_methods: visitor_methods.as_slice(), final_bcx: final, tydesc_ty: tydesc_ty, bcx: bcx diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 48c25fb985d..0a539d5e6c6 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -142,7 +142,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_tup(..) | ty::ty_enum(..) => { let repr = adt::represent_type(cx, t); - adt::sizing_type_of(cx, repr) + adt::sizing_type_of(cx, &*repr) } ty::ty_struct(..) => { @@ -152,7 +152,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { Type::vector(&type_of(cx, et), n as u64) } else { let repr = adt::represent_type(cx, t); - adt::sizing_type_of(cx, repr) + adt::sizing_type_of(cx, &*repr) } } @@ -213,7 +213,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { // of the enum's variants refers to the enum itself. let repr = adt::represent_type(cx, t); let name = llvm_type_name(cx, an_enum, did, substs.tps.as_slice()); - adt::incomplete_type_of(cx, repr, name) + adt::incomplete_type_of(cx, &*repr, name) } ty::ty_box(typ) => { Type::at_box(cx, type_of(cx, typ)).ptr_to() @@ -259,7 +259,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { ty::ty_trait(..) => Type::opaque_trait(cx), ty::ty_tup(..) => { let repr = adt::represent_type(cx, t); - adt::type_of(cx, repr) + adt::type_of(cx, &*repr) } ty::ty_struct(did, ref substs) => { if ty::type_is_simd(cx.tcx(), t) { @@ -275,7 +275,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { a_struct, did, substs.tps.as_slice()); - adt::incomplete_type_of(cx, repr, name) + adt::incomplete_type_of(cx, &*repr, name) } } @@ -297,7 +297,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { match ty::get(t).sty { ty::ty_enum(..) | ty::ty_struct(..) if !ty::type_is_simd(cx.tcx(), t) => { let repr = adt::represent_type(cx, t); - adt::finish_type_of(cx, repr, &mut llty); + adt::finish_type_of(cx, &*repr, &mut llty); } _ => () } diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 565805446f7..8f114827bfd 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -34,7 +34,7 @@ pub fn root_and_write_guard<'a, K:KindOps>(datum: &Datum, // // (Note: root'd values are always boxes) let ccx = bcx.ccx(); - match ccx.maps.root_map.borrow().find(&key) { + match ccx.maps.root_map.find(&key) { None => bcx, Some(&root_info) => root(datum, bcx, span, key, root_info) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 379ec57affc..9a3bdcc1e15 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -22,7 +22,7 @@ use middle::resolve_lifetime; use middle::ty; use middle::subst::Subst; use middle::typeck; -use middle::typeck::{MethodCall, MethodCallee, MethodMap}; +use middle::typeck::MethodCall; use middle::ty_fold; use middle::ty_fold::TypeFolder; use middle; @@ -38,9 +38,11 @@ use std::cmp; use std::fmt::Show; use std::fmt; use std::hash::{Hash, sip}; +use std::iter::AdditiveIterator; use std::ops; use std::rc::Rc; use collections::{HashMap, HashSet}; +use syntax::abi; use syntax::ast::*; use syntax::ast_util::{is_local, lit_is_str}; use syntax::ast_util; @@ -51,7 +53,7 @@ use syntax::parse::token; use syntax::parse::token::InternedString; use syntax::{ast, ast_map}; use syntax::owned_slice::OwnedSlice; -use syntax::abi; +use syntax::util::small_vector::SmallVector; use collections::enum_set::{EnumSet, CLike}; pub type Disr = u64; @@ -116,12 +118,6 @@ impl Method { } } -pub struct Impl { - pub did: DefId, - pub ident: Ident, - pub methods: Vec<@Method>, -} - #[deriving(Clone, Eq, TotalEq, Hash)] pub struct mt { pub ty: t, @@ -212,6 +208,7 @@ pub enum Variance { Bivariant, // T <: T -- e.g., unused type parameter } +#[deriving(Clone)] pub enum AutoAdjustment { AutoAddEnv(ty::TraitStore), AutoDerefRef(AutoDerefRef), @@ -221,13 +218,13 @@ pub enum AutoAdjustment { ty::substs /* Trait substitutions */) } -#[deriving(Decodable, Encodable)] +#[deriving(Clone, Decodable, Encodable)] pub struct AutoDerefRef { pub autoderefs: uint, pub autoref: Option } -#[deriving(Decodable, Encodable, Eq, Show)] +#[deriving(Clone, Decodable, Encodable, Eq, Show)] pub enum AutoRef { /// Convert from T to &T AutoPtr(Region, ast::Mutability), @@ -272,18 +269,18 @@ pub struct ctxt { pub node_type_substs: RefCell>>, // Maps from a method to the method "descriptor" - pub methods: RefCell>, + pub methods: RefCell>>, // Maps from a trait def-id to a list of the def-ids of its methods - pub trait_method_def_ids: RefCell >>, + pub trait_method_def_ids: RefCell>>>, // A cache for the trait_methods() routine - pub trait_methods_cache: RefCell >>, + pub trait_methods_cache: RefCell>>>>, - pub impl_trait_cache: RefCell>>, + pub impl_trait_cache: RefCell>>>, - pub trait_refs: RefCell>, - pub trait_defs: RefCell>, + pub trait_refs: RefCell>>, + pub trait_defs: RefCell>>, pub map: ast_map::Map, pub intrinsic_defs: RefCell>, @@ -294,20 +291,20 @@ pub struct ctxt { pub needs_unwind_cleanup_cache: RefCell>, pub tc_cache: RefCell>, pub ast_ty_to_ty_cache: RefCell>, - pub enum_var_cache: RefCell >>, + pub enum_var_cache: RefCell>>>>, pub ty_param_defs: RefCell>, - pub adjustments: RefCell>, + pub adjustments: RefCell>, pub normalized_cache: RefCell>, - pub lang_items: @middle::lang_items::LanguageItems, + pub lang_items: middle::lang_items::LanguageItems, // A mapping of fake provided method def_ids to the default implementation pub provided_method_sources: RefCell>, - pub supertraits: RefCell >>, + pub supertraits: RefCell>>>>, pub superstructs: RefCell>>, - pub struct_fields: RefCell>>, + pub struct_fields: RefCell>>>, // Maps from def-id of a type or region parameter to its // (inferred) variance. - pub item_variance_map: RefCell>, + pub item_variance_map: RefCell>>, // A mapping from the def ID of an enum or struct type to the def ID // of the method that implements its destructor. If the type is not @@ -319,18 +316,18 @@ pub struct ctxt { pub destructors: RefCell, // Maps a trait onto a list of impls of that trait. - pub trait_impls: RefCell >>>, + pub trait_impls: RefCell>>>>, - // Maps a def_id of a type to a list of its inherent impls. + // Maps a DefId of a type to a list of its inherent impls. // Contains implementations of methods that are inherent to a type. // Methods in these implementations don't need to be exported. - pub inherent_impls: RefCell >>>, + pub inherent_impls: RefCell>>>>, - // Maps a def_id of an impl to an Impl structure. + // Maps a DefId of an impl to a list of its methods. // Note that this contains all of the impls that we know about, // including ones in other crates. It's not clear that this is the best // way to do it. - pub impls: RefCell>, + pub impl_methods: RefCell>>, // Set of used unsafe nodes (functions or blocks). Unsafe nodes not // present in this set can be warned about. @@ -359,6 +356,9 @@ pub struct ctxt { // and variants that are found. pub extern_const_statics: RefCell>>, pub extern_const_variants: RefCell>>, + + pub method_map: typeck::MethodMap, + pub vtable_map: typeck::vtable_map, } pub enum tbox_flag { @@ -816,7 +816,6 @@ pub enum type_err { terr_regions_overly_polymorphic(BoundRegion, Region), terr_vstores_differ(terr_vstore_kind, expected_found), terr_trait_stores_differ(terr_vstore_kind, expected_found), - terr_in_field(@type_err, ast::Ident), terr_sorts(expected_found), terr_integer_as_char, terr_int_mismatch(expected_found), @@ -829,7 +828,8 @@ pub enum type_err { #[deriving(Eq, TotalEq, Hash)] pub struct ParamBounds { pub builtin_bounds: BuiltinBounds, - pub trait_bounds: Vec<@TraitRef> } + pub trait_bounds: Vec> +} pub type BuiltinBounds = EnumSet; @@ -983,7 +983,7 @@ impl fmt::Show for IntVarValue { pub struct TypeParameterDef { pub ident: ast::Ident, pub def_id: ast::DefId, - pub bounds: @ParamBounds, + pub bounds: Rc, pub default: Option } @@ -1038,7 +1038,7 @@ pub struct ParameterEnvironment { pub free_substs: ty::substs, /// Bound on the Self parameter - pub self_param_bound: Option<@TraitRef>, + pub self_param_bound: Option>, /// Bounds on each numbered type parameter pub type_param_bounds: Vec , @@ -1064,7 +1064,7 @@ pub struct ty_param_bounds_and_ty { pub struct TraitDef { pub generics: Generics, pub bounds: BuiltinBounds, - pub trait_ref: @ty::TraitRef, + pub trait_ref: Rc, } pub struct ty_param_substs_and_ty { @@ -1082,7 +1082,7 @@ pub fn mk_ctxt(s: Session, map: ast_map::Map, freevars: freevars::freevar_map, region_maps: middle::region::RegionMaps, - lang_items: @middle::lang_items::LanguageItems) + lang_items: middle::lang_items::LanguageItems) -> ctxt { ctxt { named_region_map: named_region_map, @@ -1122,7 +1122,7 @@ pub fn mk_ctxt(s: Session, destructors: RefCell::new(DefIdSet::new()), trait_impls: RefCell::new(DefIdMap::new()), inherent_impls: RefCell::new(DefIdMap::new()), - impls: RefCell::new(DefIdMap::new()), + impl_methods: RefCell::new(DefIdMap::new()), used_unsafe: RefCell::new(NodeSet::new()), used_mut_nodes: RefCell::new(NodeSet::new()), impl_vtables: RefCell::new(DefIdMap::new()), @@ -1131,6 +1131,8 @@ pub fn mk_ctxt(s: Session, upvar_borrow_map: RefCell::new(HashMap::new()), extern_const_statics: RefCell::new(DefIdMap::new()), extern_const_variants: RefCell::new(DefIdMap::new()), + method_map: RefCell::new(FnvHashMap::new()), + vtable_map: RefCell::new(FnvHashMap::new()), } } @@ -2174,7 +2176,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { // Self may be bounded if the associated trait has builtin kinds // for supertraits. If so we can use those bounds. let trait_def = lookup_trait_def(cx, def_id); - let traits = [trait_def.trait_ref]; + let traits = [trait_def.trait_ref.clone()]; kind_bounds_to_contents(cx, trait_def.bounds, traits) } @@ -2271,7 +2273,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { fn kind_bounds_to_contents(cx: &ctxt, bounds: BuiltinBounds, - traits: &[@TraitRef]) + traits: &[Rc]) -> TypeContents { let _i = indenter(); let mut tc = TC::All; @@ -2290,7 +2292,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { // those inherited from traits with builtin-kind-supertraits. fn each_inherited_builtin_bound(cx: &ctxt, bounds: BuiltinBounds, - traits: &[@TraitRef], + traits: &[Rc], f: |BuiltinBound|) { for bound in bounds.iter() { f(bound); @@ -2656,12 +2658,12 @@ pub fn index(t: t) -> Option { } } -pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> @ty::TraitRef { +pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc { match cx.trait_refs.borrow().find(&id) { - Some(&t) => t, - None => cx.sess.bug( - format!("node_id_to_trait_ref: no trait ref for node `{}`", - cx.map.node_to_str(id))) + Some(t) => t.clone(), + None => cx.sess.bug( + format!("node_id_to_trait_ref: no trait ref for node `{}`", + cx.map.node_to_str(id))) } } @@ -2791,10 +2793,7 @@ pub fn expr_ty_opt(cx: &ctxt, expr: &ast::Expr) -> Option { return node_id_to_type_opt(cx, expr.id); } -pub fn expr_ty_adjusted(cx: &ctxt, - expr: &ast::Expr, - method_map: &FnvHashMap) - -> t { +pub fn expr_ty_adjusted(cx: &ctxt, expr: &ast::Expr) -> t { /*! * * Returns the type of `expr`, considering any `AutoAdjustment` @@ -2808,11 +2807,9 @@ pub fn expr_ty_adjusted(cx: &ctxt, * task at hand! -nmatsakis */ - let unadjusted_ty = expr_ty(cx, expr); - let adjustment = cx.adjustments.borrow().find_copy(&expr.id); - adjust_ty(cx, expr.span, expr.id, unadjusted_ty, adjustment, |method_call| { - method_map.find(&method_call).map(|method| method.ty) - }) + adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr), + cx.adjustments.borrow().find(&expr.id), + |method_call| cx.method_map.borrow().find(&method_call).map(|method| method.ty)) } pub fn expr_span(cx: &ctxt, id: NodeId) -> Span { @@ -2857,8 +2854,8 @@ pub fn adjust_ty(cx: &ctxt, span: Span, expr_id: ast::NodeId, unadjusted_ty: ty::t, - adjustment: Option<@AutoAdjustment>, - method_type: |MethodCall| -> Option) + adjustment: Option<&AutoAdjustment>, + method_type: |typeck::MethodCall| -> Option) -> ty::t { /*! See `expr_ty_adjusted` */ @@ -2890,7 +2887,8 @@ pub fn adjust_ty(cx: &ctxt, if !ty::type_is_error(adjusted_ty) { for i in range(0, adj.autoderefs) { - match method_type(MethodCall::autoderef(expr_id, i as u32)) { + let method_call = typeck::MethodCall::autoderef(expr_id, i as u32); + match method_type(method_call) { Some(method_ty) => { adjusted_ty = ty_fn_ret(method_ty); } @@ -3051,8 +3049,8 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin) // method bounds, so we must preprend the tps from the // trait itself. This ought to be harmonized. let trait_type_param_defs = - lookup_trait_def(tcx, trt_id).generics.type_param_defs(); - Rc::new(Vec::from_slice(trait_type_param_defs).append( + Vec::from_slice(lookup_trait_def(tcx, trt_id).generics.type_param_defs()); + Rc::new(trait_type_param_defs.append( ty::trait_method(tcx, trt_id, n_mth).generics.type_param_defs())) } } @@ -3068,10 +3066,8 @@ pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> ast::Def { } } -pub fn expr_is_lval(tcx: &ctxt, - method_map: MethodMap, - e: &ast::Expr) -> bool { - match expr_kind(tcx, method_map, e) { +pub fn expr_is_lval(tcx: &ctxt, e: &ast::Expr) -> bool { + match expr_kind(tcx, e) { LvalueExpr => true, RvalueDpsExpr | RvalueDatumExpr | RvalueStmtExpr => false } @@ -3089,10 +3085,8 @@ pub enum ExprKind { RvalueStmtExpr } -pub fn expr_kind(tcx: &ctxt, - method_map: MethodMap, - expr: &ast::Expr) -> ExprKind { - if method_map.borrow().contains_key(&MethodCall::expr(expr.id)) { +pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { + if tcx.method_map.borrow().contains_key(&typeck::MethodCall::expr(expr.id)) { // Overloaded operations are generally calls, and hence they are // generated via DPS, but there are two exceptions: return match expr.node { @@ -3236,7 +3230,7 @@ pub fn expr_kind(tcx: &ctxt, } } - ast::ExprParen(e) => expr_kind(tcx, method_map, e), + ast::ExprParen(e) => expr_kind(tcx, e), ast::ExprMac(..) => { tcx.sess.span_bug( @@ -3265,7 +3259,7 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field]) fields.iter().map(|f| token::get_ident(f.ident).get().to_str()).collect::>())); } -pub fn method_idx(id: ast::Ident, meths: &[@Method]) -> Option { +pub fn method_idx(id: ast::Ident, meths: &[Rc]) -> Option { meths.iter().position(|m| m.ident == id) } @@ -3417,10 +3411,6 @@ pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str { trait_store_to_str(cx, (*values).expected), trait_store_to_str(cx, (*values).found)) } - terr_in_field(err, fname) => { - format!("in field `{}`, {}", token::get_ident(fname), - type_err_to_str(cx, err)) - } terr_sorts(values) => { format!("expected {} but found {}", ty_sort_str(cx, values.expected), @@ -3500,42 +3490,29 @@ pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { cx.provided_method_sources.borrow().find(&id).map(|x| *x) } -pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<@Method> { +pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec> { if is_local(id) { - { - match cx.map.find(id.node) { - Some(ast_map::NodeItem(item)) => { - match item.node { - ItemTrait(_, _, ref ms) => { - let (_, p) = - ast_util::split_trait_methods(ms.as_slice()); - p.iter() - .map(|m| method(cx, ast_util::local_def(m.id))) - .collect() - } - _ => { - cx.sess.bug(format!("provided_trait_methods: \ - `{:?}` is not a trait", - id)) - } + match cx.map.find(id.node) { + Some(ast_map::NodeItem(item)) => { + match item.node { + ItemTrait(_, _, ref ms) => { + let (_, p) = ast_util::split_trait_methods(ms.as_slice()); + p.iter().map(|m| method(cx, ast_util::local_def(m.id))).collect() } - } - _ => { - cx.sess.bug(format!("provided_trait_methods: `{:?}` is not \ - a trait", - id)) + _ => cx.sess.bug(format!("provided_trait_methods: `{}` is not a trait", id)) } } + _ => cx.sess.bug(format!("provided_trait_methods: `{}` is not a trait", id)) } } else { csearch::get_provided_trait_methods(cx, id) } } -pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> @Vec<@TraitRef> { +pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> Rc>> { // Check the cache. match cx.supertraits.borrow().find(&id) { - Some(&trait_refs) => { return trait_refs; } + Some(trait_refs) => { return trait_refs.clone(); } None => {} // Continue. } @@ -3545,12 +3522,12 @@ pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> @Vec<@TraitRef> { // Get the supertraits out of the metadata and create the // TraitRef for each. - let result = @csearch::get_supertraits(cx, id); - cx.supertraits.borrow_mut().insert(id, result); - return result; + let result = Rc::new(csearch::get_supertraits(cx, id)); + cx.supertraits.borrow_mut().insert(id, result.clone()); + result } -pub fn trait_ref_supertraits(cx: &ctxt, trait_ref: &ty::TraitRef) -> Vec<@TraitRef> { +pub fn trait_ref_supertraits(cx: &ctxt, trait_ref: &ty::TraitRef) -> Vec> { let supertrait_refs = trait_supertraits(cx, trait_ref.def_id); supertrait_refs.iter().map( |supertrait_ref| supertrait_ref.subst(cx, &trait_ref.substs)).collect() @@ -3584,44 +3561,46 @@ fn lookup_locally_or_in_crate_store( v } -pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> @Method { +pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> Rc { let method_def_id = *ty::trait_method_def_ids(cx, trait_did).get(idx); ty::method(cx, method_def_id) } -pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> @Vec<@Method> { +pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> Rc>> { let mut trait_methods = cx.trait_methods_cache.borrow_mut(); - match trait_methods.find(&trait_did) { - Some(&methods) => methods, + match trait_methods.find_copy(&trait_did) { + Some(methods) => methods, None => { let def_ids = ty::trait_method_def_ids(cx, trait_did); - let methods = @def_ids.iter().map(|d| ty::method(cx, *d)).collect(); - trait_methods.insert(trait_did, methods); + let methods: Rc>> = Rc::new(def_ids.iter().map(|d| { + ty::method(cx, *d) + }).collect()); + trait_methods.insert(trait_did, methods.clone()); methods } } } -pub fn method(cx: &ctxt, id: ast::DefId) -> @Method { +pub fn method(cx: &ctxt, id: ast::DefId) -> Rc { lookup_locally_or_in_crate_store("methods", id, &mut *cx.methods.borrow_mut(), || { - @csearch::get_method(cx, id) + Rc::new(csearch::get_method(cx, id)) }) } -pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> @Vec { +pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> Rc> { lookup_locally_or_in_crate_store("trait_method_def_ids", id, &mut *cx.trait_method_def_ids.borrow_mut(), || { - @csearch::get_trait_method_def_ids(&cx.sess.cstore, id) + Rc::new(csearch::get_trait_method_def_ids(&cx.sess.cstore, id)) }) } -pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<@TraitRef> { +pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option> { match cx.impl_trait_cache.borrow().find(&id) { - Some(&ret) => { return ret; } + Some(ret) => { return ret.clone(); } None => {} } @@ -3647,8 +3626,8 @@ pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<@TraitRef> { csearch::get_impl_trait(cx, id) }; - cx.impl_trait_cache.borrow_mut().insert(id, ret); - return ret; + cx.impl_trait_cache.borrow_mut().insert(id, ret.clone()); + ret } pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId { @@ -3751,18 +3730,18 @@ impl VariantInfo { pub fn substd_enum_variants(cx: &ctxt, id: ast::DefId, substs: &substs) - -> Vec<@VariantInfo> { + -> Vec> { enum_variants(cx, id).iter().map(|variant_info| { let substd_args = variant_info.args.iter() .map(|aty| subst(cx, substs, *aty)).collect(); let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty); - @VariantInfo { + Rc::new(VariantInfo { args: substd_args, ctor_ty: substd_ctor_ty, ..(**variant_info).clone() - } + }) }).collect() } @@ -3831,27 +3810,26 @@ pub fn type_is_empty(cx: &ctxt, t: t) -> bool { } } -pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> { +pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc>> { match cx.enum_var_cache.borrow().find(&id) { - Some(&variants) => return variants, + Some(variants) => return variants.clone(), _ => { /* fallthrough */ } } let result = if ast::LOCAL_CRATE != id.krate { - @csearch::get_enum_variants(cx, id) + Rc::new(csearch::get_enum_variants(cx, id)) } else { /* Although both this code and check_enum_variants in typeck/check call eval_const_expr, it should never get called twice for the same expr, since check_enum_variants also updates the enum_var_cache */ - { - match cx.map.get(id.node) { - ast_map::NodeItem(item) => { - match item.node { + match cx.map.get(id.node) { + ast_map::NodeItem(item) => { + match item.node { ast::ItemEnum(ref enum_definition, _) => { let mut last_discriminant: Option = None; - @enum_definition.variants.iter().map(|&variant| { + Rc::new(enum_definition.variants.iter().map(|&variant| { let mut discriminant = match last_discriminant { Some(val) => val + 1, @@ -3869,40 +3847,33 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> { Ok(_) => { cx.sess .span_err(e.span, - "expected signed integer \ - constant"); + "expected signed integer constant"); } Err(ref err) => { cx.sess .span_err(e.span, - format!("expected \ - constant: {}", + format!("expected constant: {}", *err)); } }, None => {} }; - let variant_info = - @VariantInfo::from_ast_variant(cx, - variant, - discriminant); last_discriminant = Some(discriminant); - variant_info - - }).collect() + Rc::new(VariantInfo::from_ast_variant(cx, variant, + discriminant)) + }).collect()) } _ => { cx.sess.bug("enum_variants: id not bound to an enum") } - } - } - _ => cx.sess.bug("enum_variants: id not bound to an enum") + } } + _ => cx.sess.bug("enum_variants: id not bound to an enum") } }; - cx.enum_var_cache.borrow_mut().insert(id, result); + cx.enum_var_cache.borrow_mut().insert(id, result.clone()); result } @@ -3911,17 +3882,11 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> { pub fn enum_variant_with_id(cx: &ctxt, enum_id: ast::DefId, variant_id: ast::DefId) - -> @VariantInfo { - let variants = enum_variants(cx, enum_id); - let mut i = 0; - while i < variants.len() { - let variant = *variants.get(i); - if variant.id == variant_id { - return variant - } - i += 1; - } - cx.sess.bug("enum_variant_with_id(): no variant exists with that ID"); + -> Rc { + enum_variants(cx, enum_id).iter() + .find(|variant| variant.id == variant_id) + .expect("enum_variant_with_id(): no variant exists with that ID") + .clone() } @@ -3944,19 +3909,19 @@ pub fn lookup_impl_vtables(cx: &ctxt, } /// Given the did of a trait, returns its canonical trait ref. -pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> @ty::TraitDef { +pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> Rc { let mut trait_defs = cx.trait_defs.borrow_mut(); - match trait_defs.find(&did) { - Some(&trait_def) => { + match trait_defs.find_copy(&did) { + Some(trait_def) => { // The item is in this crate. The caller should have added it to the // type cache already - return trait_def; + trait_def } None => { assert!(did.krate != ast::LOCAL_CRATE); - let trait_def = @csearch::get_trait_def(cx, did); - trait_defs.insert(did, trait_def); - return trait_def; + let trait_def = Rc::new(csearch::get_trait_def(cx, did)); + trait_defs.insert(did, trait_def.clone()); + trait_def } } } @@ -3964,7 +3929,7 @@ pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> @ty::TraitDef { /// Iterate over meta_items of a definition. // (This should really be an iterator, but that would require csearch and // decoder to use iterators instead of higher-order functions.) -pub fn each_attr(tcx: &ctxt, did: DefId, f: |@MetaItem| -> bool) -> bool { +pub fn each_attr(tcx: &ctxt, did: DefId, f: |@ast::MetaItem| -> bool) -> bool { if is_local(did) { let item = tcx.map.expect_item(did.node); item.attrs.iter().advance(|attr| f(attr.node.value)) @@ -4038,20 +4003,21 @@ pub fn lookup_field_type(tcx: &ctxt, // Lookup all ancestor structs of a struct indicated by did. That is the reflexive, // transitive closure of doing a single lookup in cx.superstructs. -fn lookup_super_structs(cx: &ctxt, - did: ast::DefId) -> Vec { - let mut this_result: Vec = vec!(did); - match cx.superstructs.borrow().find(&did) { - Some(&Some(def_id)) => { - let ss: Vec = lookup_super_structs(cx, def_id); - this_result.extend(ss.move_iter()); - this_result - }, - Some(&None) => this_result, - None => { - cx.sess.bug( - format!("ID not mapped to super-struct: {}", - cx.map.node_to_str(did.node))); +fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) { + let superstructs = cx.superstructs.borrow(); + + loop { + f(did); + match superstructs.find(&did) { + Some(&Some(def_id)) => { + did = def_id; + }, + Some(&None) => break, + None => { + cx.sess.bug( + format!("ID not mapped to super-struct: {}", + cx.map.node_to_str(did.node))); + } } } } @@ -4064,26 +4030,22 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec { // we have to walk the inheritance chain of the struct to get all the // structs (explicit and inherited) for a struct. If this is expensive // we could cache the whole list of fields here. - let structs = lookup_super_structs(cx, did); let struct_fields = cx.struct_fields.borrow(); - let results: Vec<&@Vec> = structs.iter().map(|s| { - match struct_fields.find(s) { - Some(fields) => fields, + let mut results: SmallVector<&[field_ty]> = SmallVector::zero(); + each_super_struct(cx, did, |s| { + match struct_fields.find(&s) { + Some(fields) => results.push(fields.as_slice()), _ => { cx.sess.bug( format!("ID not mapped to struct fields: {}", cx.map.node_to_str(did.node))); } } - }).collect(); + }); - let len = results.iter().map(|x| x.len()).fold(0, |a, b| a + b); + let len = results.as_slice().iter().map(|x| x.len()).sum(); let mut result: Vec = Vec::with_capacity(len); - for rs in results.iter() { - for r in rs.iter() { - result.push(*r); - } - } + result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|&f| f))); assert!(result.len() == len); result } else { @@ -4314,31 +4276,31 @@ pub fn eval_repeat_count(tcx: &T, count_expr: &ast::Expr) -> // relation on the supertraits from each bounded trait's constraint // list. pub fn each_bound_trait_and_supertraits(tcx: &ctxt, - bounds: &[@TraitRef], - f: |@TraitRef| -> bool) + bounds: &[Rc], + f: |Rc| -> bool) -> bool { - for &bound_trait_ref in bounds.iter() { + for bound_trait_ref in bounds.iter() { let mut supertrait_set = HashMap::new(); let mut trait_refs = Vec::new(); let mut i = 0; // Seed the worklist with the trait from the bound supertrait_set.insert(bound_trait_ref.def_id, ()); - trait_refs.push(bound_trait_ref); + trait_refs.push(bound_trait_ref.clone()); // Add the given trait ty to the hash map while i < trait_refs.len() { debug!("each_bound_trait_and_supertraits(i={:?}, trait_ref={})", i, trait_refs.get(i).repr(tcx)); - if !f(*trait_refs.get(i)) { + if !f(trait_refs.get(i).clone()) { return false; } // Add supertraits to supertrait_set let supertrait_refs = trait_ref_supertraits(tcx, - *trait_refs.get(i)); - for &supertrait_ref in supertrait_refs.iter() { + &**trait_refs.get(i)); + for supertrait_ref in supertrait_refs.iter() { debug!("each_bound_trait_and_supertraits(supertrait_ref={})", supertrait_ref.repr(tcx)); @@ -4346,7 +4308,7 @@ pub fn each_bound_trait_and_supertraits(tcx: &ctxt, if !supertrait_set.contains_key(&d_id) { // FIXME(#5527) Could have same trait multiple times supertrait_set.insert(d_id, ()); - trait_refs.push(supertrait_ref); + trait_refs.push(supertrait_ref.clone()); } } @@ -4371,7 +4333,7 @@ pub fn get_opaque_ty(tcx: &ctxt) -> Result { } pub fn visitor_object_ty(tcx: &ctxt, - region: ty::Region) -> Result<(@TraitRef, t), ~str> { + region: ty::Region) -> Result<(Rc, t), ~str> { let trait_lang_item = match tcx.lang_items.require(TyVisitorTraitLangItem) { Ok(id) => id, Err(s) => { return Err(s); } @@ -4381,8 +4343,8 @@ pub fn visitor_object_ty(tcx: &ctxt, self_ty: None, tps: Vec::new() }; - let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs }; - Ok((trait_ref, + let trait_ref = Rc::new(TraitRef { def_id: trait_lang_item, substs: substs }); + Ok((trait_ref.clone(), mk_trait(tcx, trait_ref.def_id, trait_ref.substs.clone(), @@ -4390,29 +4352,24 @@ pub fn visitor_object_ty(tcx: &ctxt, EmptyBuiltinBounds()))) } -pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> @ItemVariances { +pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { lookup_locally_or_in_crate_store( "item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(), - || @csearch::get_item_variances(&tcx.sess.cstore, item_id)) + || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id))) } /// Records a trait-to-implementation mapping. -fn record_trait_implementation(tcx: &ctxt, - trait_def_id: DefId, - implementation: @Impl) { - let implementation_list; - let mut trait_impls = tcx.trait_impls.borrow_mut(); - match trait_impls.find(&trait_def_id) { - None => { - implementation_list = @RefCell::new(Vec::new()); - trait_impls.insert(trait_def_id, implementation_list); - } - Some(&existing_implementation_list) => { - implementation_list = existing_implementation_list +pub fn record_trait_implementation(tcx: &ctxt, + trait_def_id: DefId, + impl_def_id: DefId) { + match tcx.trait_impls.borrow().find(&trait_def_id) { + Some(impls_for_trait) => { + impls_for_trait.borrow_mut().push(impl_def_id); + return; } + None => {} } - - implementation_list.borrow_mut().push(implementation); + tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id)))); } /// Populates the type context with all the implementations for the given type @@ -4427,45 +4384,38 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt, } csearch::each_implementation_for_type(&tcx.sess.cstore, type_id, - |implementation_def_id| { - let implementation = @csearch::get_impl(tcx, implementation_def_id); + |impl_def_id| { + let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id); // Record the trait->implementation mappings, if applicable. - let associated_traits = csearch::get_impl_trait(tcx, - implementation.did); + let associated_traits = csearch::get_impl_trait(tcx, impl_def_id); for trait_ref in associated_traits.iter() { - record_trait_implementation(tcx, - trait_ref.def_id, - implementation); + record_trait_implementation(tcx, trait_ref.def_id, impl_def_id); } // For any methods that use a default implementation, add them to // the map. This is a bit unfortunate. - for method in implementation.methods.iter() { - for source in method.provided_source.iter() { - tcx.provided_method_sources.borrow_mut() - .insert(method.def_id, *source); + for &method_def_id in methods.iter() { + for &source in ty::method(tcx, method_def_id).provided_source.iter() { + tcx.provided_method_sources.borrow_mut().insert(method_def_id, source); } } - // If this is an inherent implementation, record it. - if associated_traits.is_none() { - let implementation_list; - let mut inherent_impls = tcx.inherent_impls.borrow_mut(); - match inherent_impls.find(&type_id) { - None => { - implementation_list = @RefCell::new(Vec::new()); - inherent_impls.insert(type_id, implementation_list); - } - Some(&existing_implementation_list) => { - implementation_list = existing_implementation_list; - } - } - implementation_list.borrow_mut().push(implementation); - } - // Store the implementation info. - tcx.impls.borrow_mut().insert(implementation_def_id, implementation); + tcx.impl_methods.borrow_mut().insert(impl_def_id, methods); + + // If this is an inherent implementation, record it. + if associated_traits.is_none() { + match tcx.inherent_impls.borrow().find(&type_id) { + Some(implementation_list) => { + implementation_list.borrow_mut().push(impl_def_id); + return; + } + None => {} + } + tcx.inherent_impls.borrow_mut().insert(type_id, + Rc::new(RefCell::new(vec!(impl_def_id)))); + } }); tcx.populated_external_types.borrow_mut().insert(type_id); @@ -4485,22 +4435,21 @@ pub fn populate_implementations_for_trait_if_necessary( csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| { - let implementation = @csearch::get_impl(tcx, implementation_def_id); + let methods = csearch::get_impl_methods(&tcx.sess.cstore, implementation_def_id); // Record the trait->implementation mapping. - record_trait_implementation(tcx, trait_id, implementation); + record_trait_implementation(tcx, trait_id, implementation_def_id); // For any methods that use a default implementation, add them to // the map. This is a bit unfortunate. - for method in implementation.methods.iter() { - for source in method.provided_source.iter() { - tcx.provided_method_sources.borrow_mut() - .insert(method.def_id, *source); + for &method_def_id in methods.iter() { + for &source in ty::method(tcx, method_def_id).provided_source.iter() { + tcx.provided_method_sources.borrow_mut().insert(method_def_id, source); } } // Store the implementation info. - tcx.impls.borrow_mut().insert(implementation_def_id, implementation); + tcx.impl_methods.borrow_mut().insert(implementation_def_id, methods); }); tcx.populated_external_traits.borrow_mut().insert(trait_id); @@ -4535,7 +4484,7 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId) if def_id.krate != LOCAL_CRATE { return csearch::get_trait_of_method(&tcx.sess.cstore, def_id, tcx); } - match tcx.methods.borrow().find(&def_id).map(|m| *m) { + match tcx.methods.borrow().find_copy(&def_id) { Some(method) => { match method.container { TraitContainer(def_id) => Some(def_id), @@ -4555,7 +4504,7 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId) pub fn trait_method_of_method(tcx: &ctxt, def_id: ast::DefId) -> Option { let method = match tcx.methods.borrow().find(&def_id) { - Some(&m) => m, + Some(m) => m.clone(), None => return None, }; let name = method.ident.name; @@ -4724,7 +4673,7 @@ impl Variance { pub fn construct_parameter_environment( tcx: &ctxt, - self_bound: Option<@TraitRef>, + self_bound: Option>, item_type_params: &[TypeParameterDef], method_type_params: &[TypeParameterDef], item_region_params: &[RegionParameterDef], @@ -4739,7 +4688,7 @@ pub fn construct_parameter_environment( // // map Self => Self - let self_ty = self_bound.map(|t| ty::mk_self(tcx, t.def_id)); + let self_ty = self_bound.as_ref().map(|t| ty::mk_self(tcx, t.def_id)); // map A => A let num_item_type_params = item_type_params.len(); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 5de2a60114a..6ae68bdbad1 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -60,6 +60,7 @@ use middle::typeck::rscope::{RegionScope}; use middle::typeck::lookup_def_tcx; use util::ppaux::Repr; +use std::rc::Rc; use syntax::abi; use syntax::{ast, ast_util}; use syntax::codemap::Span; @@ -69,7 +70,7 @@ use syntax::print::pprust::{lifetime_to_str, path_to_str}; pub trait AstConv { fn tcx<'a>(&'a self) -> &'a ty::ctxt; fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty; - fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef; + fn get_trait_def(&self, id: ast::DefId) -> Rc; // what type should we use when a type is omitted? fn ty_infer(&self, span: Span) -> ty::t; @@ -261,25 +262,16 @@ pub fn ast_path_to_substs_and_ty( - this: &AC, - rscope: &RS, - trait_def_id: ast::DefId, - self_ty: Option, - path: &ast::Path) -> @ty::TraitRef -{ - let trait_def = - this.get_trait_def(trait_def_id); - let substs = - ast_path_substs( - this, - rscope, - &trait_def.generics, - self_ty, - path); - let trait_ref = - @ty::TraitRef {def_id: trait_def_id, - substs: substs}; - return trait_ref; + this: &AC, + rscope: &RS, + trait_def_id: ast::DefId, + self_ty: Option, + path: &ast::Path) -> Rc { + let trait_def = this.get_trait_def(trait_def_id); + Rc::new(ty::TraitRef { + def_id: trait_def_id, + substs: ast_path_substs(this, rscope, &trait_def.generics, self_ty, path) + }) } pub fn ast_path_to_ty( diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 286c8d17751..9ceb3132509 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -40,7 +40,7 @@ pub fn check_match(fcx: &FnCtxt, for arm in arms.iter() { let mut pcx = pat_ctxt { fcx: fcx, - map: pat_id_map(tcx.def_map, *arm.pats.get(0)), + map: pat_id_map(&tcx.def_map, *arm.pats.get(0)), }; for p in arm.pats.iter() { check_pat(&mut pcx, *p, discrim_ty);} @@ -467,14 +467,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { fcx.write_ty(pat.id, b_ty); } ast::PatEnum(..) | - ast::PatIdent(..) if pat_is_const(tcx.def_map, pat) => { + ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => { let const_did = ast_util::def_id_of_def(tcx.def_map.borrow() .get_copy(&pat.id)); let const_tpt = ty::lookup_item_type(tcx, const_did); demand::suptype(fcx, pat.span, expected, const_tpt.ty); fcx.write_ty(pat.id, const_tpt.ty); } - ast::PatIdent(bm, ref name, sub) if pat_is_binding(tcx.def_map, pat) => { + ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => { let typ = fcx.local_ty(pat.span, pat.id); match bm { diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 178d3c8b544..3b33a17d582 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -30,7 +30,7 @@ itself (note that inherent impls can only be defined in the same module as the type itself). Inherent candidates are not always derived from impls. If you have a -trait instance, such as a value of type `@ToStr`, then the trait +trait instance, such as a value of type `~ToStr`, then the trait methods (`to_str()`, in this case) are inherently associated with it. Another case is type parameters, in which case the methods of their bounds are inherent. @@ -97,7 +97,7 @@ use util::ppaux; use util::ppaux::Repr; use collections::HashSet; -use std::result; +use std::rc::Rc; use syntax::ast::{DefId, SelfValue, SelfRegion}; use syntax::ast::{SelfUniq, SelfStatic}; use syntax::ast::{MutMutable, MutImmutable}; @@ -203,7 +203,7 @@ pub fn lookup_in_trait<'a>( // to a trait and its supertraits. fn get_method_index(tcx: &ty::ctxt, trait_ref: &TraitRef, - subtrait: @TraitRef, + subtrait: Rc, n_method: uint) -> uint { // We need to figure the "real index" of the method in a // listing of all the methods of an object. We do this by @@ -311,7 +311,7 @@ struct LookupContext<'a> { struct Candidate { rcvr_match_condition: RcvrMatchCondition, rcvr_substs: ty::substs, - method_ty: @ty::Method, + method_ty: Rc, origin: MethodOrigin, } @@ -412,7 +412,7 @@ impl<'a> LookupContext<'a> { * `self.inherent_candidates`. See comment at the start of * the file. To find the inherent candidates, we repeatedly * deref the self-ty to find the "base-type". So, for - * example, if the receiver is @@C where `C` is a struct type, + * example, if the receiver is ~~C where `C` is a struct type, * we'll want to find the inherent impls for `C`. */ @@ -468,9 +468,11 @@ impl<'a> LookupContext<'a> { ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did); // Look for explicit implementations. + let impl_methods = self.tcx().impl_methods.borrow(); for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() { - for impl_info in impl_infos.borrow().iter() { - self.push_candidates_from_impl(*impl_info, true); + for impl_did in impl_infos.borrow().iter() { + let methods = impl_methods.get(impl_did); + self.push_candidates_from_impl(*impl_did, methods.as_slice(), true); } } } @@ -509,12 +511,15 @@ impl<'a> LookupContext<'a> { self_ty: Some(ty::mk_err()), ..(*substs).clone() }; - let trait_ref = @TraitRef { def_id: did, substs: rcvr_substs.clone() }; + let trait_ref = Rc::new(TraitRef { + def_id: did, + substs: rcvr_substs.clone() + }); - self.push_inherent_candidates_from_bounds_inner(&[trait_ref], + self.push_inherent_candidates_from_bounds_inner(&[trait_ref.clone()], |new_trait_ref, m, method_num, _bound_num| { - let vtable_index = get_method_index(tcx, new_trait_ref, - trait_ref, method_num); + let vtable_index = get_method_index(tcx, &*new_trait_ref, + trait_ref.clone(), method_num); let mut m = (*m).clone(); // We need to fix up the transformed self type. *m.fty.sig.inputs.get_mut(0) = @@ -524,7 +529,7 @@ impl<'a> LookupContext<'a> { Some(Candidate { rcvr_match_condition: RcvrMatchesIfObject(did), rcvr_substs: new_trait_ref.substs.clone(), - method_ty: @m, + method_ty: Rc::new(m), origin: MethodObject(MethodObject { trait_id: new_trait_ref.def_id, object_trait_id: did, @@ -561,14 +566,14 @@ impl<'a> LookupContext<'a> { debug!("push_inherent_candidates_from_self()"); self.push_inherent_candidates_from_bounds( rcvr_ty, - [self.fcx.inh.param_env.self_param_bound.unwrap()], + [self.fcx.inh.param_env.self_param_bound.clone().unwrap()], restrict_to, param_self) } fn push_inherent_candidates_from_bounds(&mut self, self_ty: ty::t, - bounds: &[@TraitRef], + bounds: &[Rc], restrict_to: Option, param: param_index) { self.push_inherent_candidates_from_bounds_inner(bounds, @@ -598,9 +603,9 @@ impl<'a> LookupContext<'a> { // Do a search through a list of bounds, using a callback to actually // create the candidates. fn push_inherent_candidates_from_bounds_inner(&mut self, - bounds: &[@TraitRef], - mk_cand: |tr: @TraitRef, - m: @ty::Method, + bounds: &[Rc], + mk_cand: |tr: Rc, + m: Rc, method_num: uint, bound_num: uint| -> Option) { @@ -616,7 +621,7 @@ impl<'a> LookupContext<'a> { m.explicit_self != ast::SelfStatic && m.ident.name == self.m_name }) { Some(pos) => { - let method = *trait_methods.get(pos); + let method = trait_methods.get(pos).clone(); match mk_cand(bound_trait_ref, method, pos, this_bound_idx) { Some(cand) => { @@ -643,40 +648,35 @@ impl<'a> LookupContext<'a> { // metadata if necessary. ty::populate_implementations_for_type_if_necessary(self.tcx(), did); + let impl_methods = self.tcx().impl_methods.borrow(); for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() { - for impl_info in impl_infos.borrow().iter() { - self.push_candidates_from_impl(*impl_info, false); + for impl_did in impl_infos.borrow().iter() { + let methods = impl_methods.get(impl_did); + self.push_candidates_from_impl(*impl_did, methods.as_slice(), false); } } } fn push_candidates_from_impl(&mut self, - impl_info: &ty::Impl, + impl_did: DefId, + impl_methods: &[DefId], is_extension: bool) { - if !self.impl_dups.insert(impl_info.did) { + if !self.impl_dups.insert(impl_did) { return; // already visited } - debug!("push_candidates_from_impl: {} {} {}", + debug!("push_candidates_from_impl: {} {}", token::get_name(self.m_name), - impl_info.ident.repr(self.tcx()), - impl_info.methods.iter() - .map(|m| m.ident) - .collect::>() - .repr(self.tcx())); + impl_methods.iter().map(|&did| ty::method(self.tcx(), did).ident) + .collect::>() + .repr(self.tcx())); - let idx = { - match impl_info.methods - .iter() - .position(|m| m.ident.name == self.m_name) { - Some(idx) => idx, - None => { return; } // No method with the right name. - } + let method = match impl_methods.iter().map(|&did| ty::method(self.tcx(), did)) + .find(|m| m.ident.name == self.m_name) { + Some(method) => method, + None => { return; } // No method with the right name. }; - let method = ty::method(self.tcx(), - impl_info.methods.get(idx).def_id); - // determine the `self` of the impl with fresh // variables for each parameter: let span = self.self_expr.map_or(self.span, |e| e.span); @@ -684,7 +684,7 @@ impl<'a> LookupContext<'a> { let ty::ty_param_substs_and_ty { substs: impl_substs, ty: impl_ty - } = impl_self_ty(&vcx, span, impl_info.did); + } = impl_self_ty(&vcx, span, impl_did); let candidates = if is_extension { &mut self.extension_candidates @@ -695,8 +695,8 @@ impl<'a> LookupContext<'a> { candidates.push(Candidate { rcvr_match_condition: RcvrMatchesIfSubtype(impl_ty), rcvr_substs: impl_substs, + origin: MethodStatic(method.def_id), method_ty: method, - origin: MethodStatic(method.def_id) }); } @@ -715,7 +715,7 @@ impl<'a> LookupContext<'a> { // an explicit adjustment, but rather we hardwire the single deref // that occurs in trans and mem_categorization. let adjustment = match self.self_expr { - Some(expr) => Some((expr.id, @ty::AutoDerefRef(auto_deref_ref))), + Some(expr) => Some((expr.id, ty::AutoDerefRef(auto_deref_ref))), None => return None }; @@ -877,7 +877,7 @@ impl<'a> LookupContext<'a> { } ty_trait(~ty::TyTrait { def_id: trt_did, substs: trt_substs, bounds: b, .. }) => { - // Coerce ~/@/&Trait instances to &Trait. + // Coerce ~/&Trait instances to &Trait. self.search_for_some_kind_of_autorefd_method( AutoBorrowObj, autoderefs, [MutImmutable, MutMutable], @@ -962,7 +962,7 @@ impl<'a> LookupContext<'a> { Some(self_expr_id) => { self.fcx.write_adjustment( self_expr_id, - @ty::AutoDerefRef(ty::AutoDerefRef { + ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: autoderefs, autoref: Some(kind(region, *mutbl)) })); @@ -1187,8 +1187,8 @@ impl<'a> LookupContext<'a> { let span = self.self_expr.map_or(self.span, |e| e.span); match self.fcx.mk_subty(false, infer::Misc(span), rcvr_ty, transformed_self_ty) { - result::Ok(_) => {} - result::Err(_) => { + Ok(_) => {} + Err(_) => { self.bug(format!("{} was a subtype of {} but now is not?", self.ty_to_str(rcvr_ty), self.ty_to_str(transformed_self_ty))); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index bddd7f43d99..dc5b4f6d520 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -117,7 +117,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; use std::cell::{Cell, RefCell}; use collections::HashMap; use std::mem::replace; -use std::result; +use std::rc::Rc; use std::vec::Vec; use syntax::abi; use syntax::ast::{Provided, Required}; @@ -155,13 +155,13 @@ pub mod method; /// share the inherited fields. pub struct Inherited<'a> { infcx: infer::InferCtxt<'a>, - locals: @RefCell>, + locals: RefCell>, param_env: ty::ParameterEnvironment, // Temporary tables: node_types: RefCell>, node_type_substs: RefCell>, - adjustments: RefCell>, + adjustments: RefCell>, method_map: MethodMap, vtable_map: vtable_map, upvar_borrow_map: RefCell, @@ -260,13 +260,13 @@ impl<'a> Inherited<'a> { -> Inherited<'a> { Inherited { infcx: infer::new_infer_ctxt(tcx), - locals: @RefCell::new(NodeMap::new()), + locals: RefCell::new(NodeMap::new()), param_env: param_env, node_types: RefCell::new(NodeMap::new()), node_type_substs: RefCell::new(NodeMap::new()), adjustments: RefCell::new(NodeMap::new()), - method_map: @RefCell::new(FnvHashMap::new()), - vtable_map: @RefCell::new(FnvHashMap::new()), + method_map: RefCell::new(FnvHashMap::new()), + vtable_map: RefCell::new(FnvHashMap::new()), upvar_borrow_map: RefCell::new(HashMap::new()), } } @@ -387,7 +387,7 @@ impl<'a> Visitor<()> for GatherLocalsVisitor<'a> { fn visit_pat(&mut self, p: &ast::Pat, _: ()) { match p.node { ast::PatIdent(_, ref path, _) - if pat_util::pat_is_binding(self.fcx.ccx.tcx.def_map, p) => { + if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => { self.assign(p.id, None); debug!("Pattern binding {} is assigned to {}", token::get_ident(path.segments.get(0).identifier), @@ -469,7 +469,7 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>, // Add formal parameters. for (arg_ty, input) in arg_tys.iter().zip(decl.inputs.iter()) { // Create type variables for each argument. - pat_util::pat_bindings(tcx.def_map, + pat_util::pat_bindings(&tcx.def_map, input.pat, |_bm, pat_id, _sp, _path| { visit.assign(pat_id, None); @@ -478,7 +478,7 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>, // Check the pattern. let pcx = pat_ctxt { fcx: &fcx, - map: pat_id_map(tcx.def_map, input.pat), + map: pat_id_map(&tcx.def_map, input.pat), }; _match::check_pat(&pcx, input.pat, *arg_ty); } @@ -622,9 +622,9 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { it.span, &impl_tpt.generics, ast_trait_ref, - impl_trait_ref, + &*impl_trait_ref, ms.as_slice()); - vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, impl_trait_ref); + vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, &*impl_trait_ref); } None => { } } @@ -640,7 +640,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { } Provided(m) => { check_method_body(ccx, &trait_def.generics, - Some(trait_def.trait_ref), m); + Some(trait_def.trait_ref.clone()), m); } } } @@ -682,7 +682,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { fn check_method_body(ccx: &CrateCtxt, item_generics: &ty::Generics, - self_bound: Option<@ty::TraitRef>, + self_bound: Option>, method: &ast::Method) { /*! * Type checks a method body. @@ -744,10 +744,10 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt, Some(trait_method_ty) => { compare_impl_method(ccx.tcx, impl_generics, - impl_method_ty, + &*impl_method_ty, impl_method.span, impl_method.body.id, - *trait_method_ty, + &**trait_method_ty, &impl_trait_ref.substs); } None => { @@ -800,7 +800,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt, */ fn compare_impl_method(tcx: &ty::ctxt, impl_generics: &ty::Generics, - impl_m: @ty::Method, + impl_m: &ty::Method, impl_m_span: Span, impl_m_body_id: ast::NodeId, trait_m: &ty::Method, @@ -973,8 +973,8 @@ fn compare_impl_method(tcx: &ty::ctxt, match infer::mk_subty(&infcx, false, infer::MethodCompatCheck(impl_m_span), impl_fty, trait_fty) { - result::Ok(()) => {} - result::Err(ref terr) => { + Ok(()) => {} + Err(ref terr) => { tcx.sess.span_err( impl_m_span, format!("method `{}` has an incompatible type for trait: {}", @@ -992,7 +992,7 @@ impl<'a> AstConv for FnCtxt<'a> { ty::lookup_item_type(self.tcx(), id) } - fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef { + fn get_trait_def(&self, id: ast::DefId) -> Rc { ty::lookup_trait_def(self.tcx(), id) } @@ -1076,7 +1076,7 @@ impl<'a> FnCtxt<'a> { if derefs == 0 { return; } self.write_adjustment( node_id, - @ty::AutoDerefRef(ty::AutoDerefRef { + ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: derefs, autoref: None }) ); @@ -1084,7 +1084,7 @@ impl<'a> FnCtxt<'a> { pub fn write_adjustment(&self, node_id: ast::NodeId, - adj: @ty::AutoAdjustment) { + adj: ty::AutoAdjustment) { debug!("write_adjustment(node_id={:?}, adj={:?})", node_id, adj); self.inh.adjustments.borrow_mut().insert(node_id, adj); } @@ -1175,8 +1175,8 @@ impl<'a> FnCtxt<'a> { infer::ExprAssignable(expr.span), sub, sup) { - Ok(None) => result::Ok(()), - Err(ref e) => result::Err((*e)), + Ok(None) => Ok(()), + Err(ref e) => Err((*e)), Ok(Some(adjustment)) => { self.write_adjustment(expr.id, adjustment); Ok(()) @@ -2100,7 +2100,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, op: ast::BinOp, rhs: @ast::Expr) -> ty::t { let tcx = fcx.ccx.tcx; - let lang = tcx.lang_items; + let lang = &tcx.lang_items; let (name, trait_did) = match op { ast::BiAdd => ("add", lang.add_trait()), ast::BiSub => ("sub", lang.sub_trait()), @@ -2690,7 +2690,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, demand::suptype(fcx, expr.span, result_t, lhs_t); let tcx = fcx.tcx(); - if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) { + if !ty::expr_is_lval(tcx, lhs) { tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); } @@ -2846,8 +2846,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt, match expr_opt { None => match fcx.mk_eqty(false, infer::Misc(expr.span), ret_ty, ty::mk_nil()) { - result::Ok(_) => { /* fall through */ } - result::Err(_) => { + Ok(_) => { /* fall through */ } + Err(_) => { tcx.sess.span_err( expr.span, "`return;` in function returning non-nil"); @@ -2867,7 +2867,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, check_expr_with_lvalue_pref(fcx, lhs, PreferMutLvalue); let tcx = fcx.tcx(); - if !ty::expr_is_lval(tcx, fcx.ccx.method_map, lhs) { + if !ty::expr_is_lval(tcx, lhs) { tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); } @@ -3268,7 +3268,7 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local) { let pcx = pat_ctxt { fcx: fcx, - map: pat_id_map(tcx.def_map, local.pat), + map: pat_id_map(&tcx.def_map, local.pat), }; _match::check_pat(&pcx, local.pat, t); let pat_ty = fcx.node_ty(local.pat.id); @@ -3543,10 +3543,10 @@ pub fn check_enum_variants(ccx: &CrateCtxt, vs: &[ast::P], id: ast::NodeId, hint: attr::ReprAttr) - -> Vec<@ty::VariantInfo> { + -> Vec> { let rty = ty::node_id_to_type(ccx.tcx, id); - let mut variants: Vec<@ty::VariantInfo> = Vec::new(); + let mut variants: Vec> = Vec::new(); let mut disr_vals: Vec = Vec::new(); let mut prev_disr_val: Option = None; @@ -3602,7 +3602,8 @@ pub fn check_enum_variants(ccx: &CrateCtxt, } disr_vals.push(current_disr_val); - let variant_info = @VariantInfo::from_ast_variant(ccx.tcx, v, current_disr_val); + let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, v, + current_disr_val)); prev_disr_val = Some(current_disr_val); variants.push(variant_info); @@ -3624,7 +3625,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt, let variants = do_check(ccx, vs, id, hint); // cache so that ty::enum_variants won't repeat this work - ccx.tcx.enum_var_cache.borrow_mut().insert(local_def(id), @variants); + ccx.tcx.enum_var_cache.borrow_mut().insert(local_def(id), Rc::new(variants)); // Check that it is possible to represent this enum. check_representable(ccx.tcx, sp, id, "enum"); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index f6a4d972a07..94cbd3a3a75 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -131,6 +131,7 @@ use middle::typeck::infer::resolve_type; use middle::typeck::infer; use middle::typeck::MethodCall; use middle::pat_util; +use util::nodemap::NodeMap; use util::ppaux::{ty_to_str, region_to_str, Repr}; use syntax::ast::{DefArg, DefBinding, DefLocal, DefUpvar}; @@ -140,6 +141,8 @@ use syntax::codemap::Span; use syntax::visit; use syntax::visit::Visitor; +use std::cell::RefCell; + // If mem categorization results in an error, it's because the type // check failed (or will fail, when the error is uncovered and // reported during writeback). In this case, we just ignore this part @@ -155,7 +158,6 @@ macro_rules! ignore_err( pub struct Rcx<'a> { fcx: &'a FnCtxt<'a>, - errors_reported: uint, // id of innermost fn or loop repeating_scope: ast::NodeId, @@ -234,7 +236,7 @@ impl<'a> Rcx<'a> { } /// Try to resolve the type for the given node. - fn resolve_node_type(&mut self, id: ast::NodeId) -> ty::t { + fn resolve_node_type(&self, id: ast::NodeId) -> ty::t { let t = self.fcx.node_ty(id); self.resolve_type(t) } @@ -252,19 +254,19 @@ impl<'a> Rcx<'a> { ty_unadjusted } else { let tcx = self.fcx.tcx(); - let adjustment = self.fcx.inh.adjustments.borrow().find_copy(&expr.id); - ty::adjust_ty(tcx, expr.span, expr.id, ty_unadjusted, adjustment, + ty::adjust_ty(tcx, expr.span, expr.id, ty_unadjusted, + self.fcx.inh.adjustments.borrow().find(&expr.id), |method_call| self.resolve_method_type(method_call)) } } } -impl<'a, 'b> mc::Typer for &'a mut Rcx<'b> { +impl<'a, 'b> mc::Typer for &'a Rcx<'b> { fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.fcx.tcx() } - fn node_ty(&mut self, id: ast::NodeId) -> mc::McResult { + fn node_ty(&self, id: ast::NodeId) -> mc::McResult { let t = self.resolve_node_type(id); if ty::type_is_error(t) {Err(())} else {Ok(t)} } @@ -273,26 +275,25 @@ impl<'a, 'b> mc::Typer for &'a mut Rcx<'b> { self.resolve_method_type(method_call) } - fn adjustment(&mut self, id: ast::NodeId) -> Option<@ty::AutoAdjustment> { - self.fcx.inh.adjustments.borrow().find_copy(&id) + fn adjustments<'a>(&'a self) -> &'a RefCell> { + &self.fcx.inh.adjustments } - fn is_method_call(&mut self, id: ast::NodeId) -> bool { + fn is_method_call(&self, id: ast::NodeId) -> bool { self.fcx.inh.method_map.borrow().contains_key(&MethodCall::expr(id)) } - fn temporary_scope(&mut self, id: ast::NodeId) -> Option { + fn temporary_scope(&self, id: ast::NodeId) -> Option { self.tcx().region_maps.temporary_scope(id) } - fn upvar_borrow(&mut self, id: ty::UpvarId) -> ty::UpvarBorrow { + fn upvar_borrow(&self, id: ty::UpvarId) -> ty::UpvarBorrow { self.fcx.inh.upvar_borrow_map.borrow().get_copy(&id) } } pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) { - let mut rcx = Rcx { fcx: fcx, errors_reported: 0, - repeating_scope: e.id }; + let mut rcx = Rcx { fcx: fcx, repeating_scope: e.id }; let rcx = &mut rcx; if fcx.err_count_since_creation() == 0 { // regionck assumes typeck succeeded @@ -302,8 +303,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) { } pub fn regionck_fn(fcx: &FnCtxt, blk: &ast::Block) { - let mut rcx = Rcx { fcx: fcx, errors_reported: 0, - repeating_scope: blk.id }; + let mut rcx = Rcx { fcx: fcx, repeating_scope: blk.id }; let rcx = &mut rcx; if fcx.err_count_since_creation() == 0 { // regionck assumes typeck succeeded @@ -361,7 +361,7 @@ fn visit_local(rcx: &mut Rcx, l: &ast::Local) { fn constrain_bindings_in_pat(pat: &ast::Pat, rcx: &mut Rcx) { let tcx = rcx.fcx.tcx(); debug!("regionck::visit_pat(pat={})", pat.repr(tcx)); - pat_util::pat_bindings(tcx.def_map, pat, |_, id, span, _| { + pat_util::pat_bindings(&tcx.def_map, pat, |_, id, span, _| { // If we have a variable that contains region'd data, that // data will be accessible from anywhere that the variable is // accessed. We must be wary of loops like this: @@ -402,7 +402,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { // Check any autoderefs or autorefs that appear. for &adjustment in rcx.fcx.inh.adjustments.borrow().find(&expr.id).iter() { debug!("adjustment={:?}", adjustment); - match **adjustment { + match *adjustment { ty::AutoDerefRef(ty::AutoDerefRef {autoderefs, autoref: opt_autoref}) => { let expr_ty = rcx.resolve_node_type(expr.id); constrain_autoderefs(rcx, expr, autoderefs, expr_ty); @@ -611,20 +611,21 @@ fn check_expr_fn_block(rcx: &mut Rcx, match ty::get(function_type).sty { ty::ty_closure(~ty::ClosureTy { store: ty::RegionTraitStore(region, _), ..}) => { - let freevars = freevars::get_freevars(tcx, expr.id); - if freevars.is_empty() { - // No free variables means that the environment - // will be NULL at runtime and hence the closure - // has static lifetime. - } else { - // Closure must not outlive the variables it closes over. - constrain_free_variables(rcx, region, expr, freevars); + freevars::with_freevars(tcx, expr.id, |freevars| { + if freevars.is_empty() { + // No free variables means that the environment + // will be NULL at runtime and hence the closure + // has static lifetime. + } else { + // Closure must not outlive the variables it closes over. + constrain_free_variables(rcx, region, expr, freevars); - // Closure cannot outlive the appropriate temporary scope. - let s = rcx.repeating_scope; - rcx.fcx.mk_subr(true, infer::InfStackClosure(expr.span), - region, ty::ReScope(s)); - } + // Closure cannot outlive the appropriate temporary scope. + let s = rcx.repeating_scope; + rcx.fcx.mk_subr(true, infer::InfStackClosure(expr.span), + region, ty::ReScope(s)); + } + }); } _ => () } @@ -635,8 +636,9 @@ fn check_expr_fn_block(rcx: &mut Rcx, match ty::get(function_type).sty { ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => { - let freevars = freevars::get_freevars(tcx, expr.id); - propagate_upupvar_borrow_kind(rcx, expr, freevars); + freevars::with_freevars(tcx, expr.id, |freevars| { + propagate_upupvar_borrow_kind(rcx, expr, freevars); + }); } _ => () } @@ -644,7 +646,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, fn constrain_free_variables(rcx: &mut Rcx, region: ty::Region, expr: &ast::Expr, - freevars: freevars::freevar_info) { + freevars: &[freevars::freevar_entry]) { /*! * Make sure that all free variables referenced inside the closure * outlive the closure itself. Also, create an entry in the @@ -690,7 +692,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, fn propagate_upupvar_borrow_kind(rcx: &mut Rcx, expr: &ast::Expr, - freevars: freevars::freevar_info) { + freevars: &[freevars::freevar_entry]) { let tcx = rcx.fcx.ccx.tcx; debug!("propagate_upupvar_borrow_kind({})", expr.repr(tcx)); for freevar in freevars.iter() { @@ -870,7 +872,7 @@ fn constrain_autoderefs(rcx: &mut Rcx, method.ty.repr(rcx.tcx()))) }; { - let mut mc = mc::MemCategorizationContext { typer: &mut *rcx }; + let mc = mc::MemCategorizationContext { typer: &*rcx }; let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i)); link_region(mc.typer, deref_expr.span, r, m, self_cmt); } @@ -948,8 +950,7 @@ fn constrain_regions_in_type_of_node( rcx: &mut Rcx, id: ast::NodeId, minimum_lifetime: ty::Region, - origin: infer::SubregionOrigin) -> bool -{ + origin: infer::SubregionOrigin) { //! Guarantees that any lifetimes which appear in the type of //! the node `id` (after applying adjustments) are valid for at //! least `minimum_lifetime` @@ -960,22 +961,21 @@ fn constrain_regions_in_type_of_node( // is going to fail anyway, so just stop here and let typeck // report errors later on in the writeback phase. let ty0 = rcx.resolve_node_type(id); - let adjustment = rcx.fcx.inh.adjustments.borrow().find_copy(&id); - let ty = ty::adjust_ty(tcx, origin.span(), id, ty0, adjustment, + let ty = ty::adjust_ty(tcx, origin.span(), id, ty0, + rcx.fcx.inh.adjustments.borrow().find(&id), |method_call| rcx.resolve_method_type(method_call)); debug!("constrain_regions_in_type_of_node(\ - ty={}, ty0={}, id={}, minimum_lifetime={:?}, adjustment={:?})", + ty={}, ty0={}, id={}, minimum_lifetime={:?})", ty_to_str(tcx, ty), ty_to_str(tcx, ty0), - id, minimum_lifetime, adjustment); - constrain_regions_in_type(rcx, minimum_lifetime, origin, ty) + id, minimum_lifetime); + constrain_regions_in_type(rcx, minimum_lifetime, origin, ty); } fn constrain_regions_in_type( rcx: &mut Rcx, minimum_lifetime: ty::Region, origin: infer::SubregionOrigin, - ty: ty::t) -> bool -{ + ty: ty::t) { /*! * Requires that any regions which appear in `ty` must be * superregions of `minimum_lifetime`. Also enforces the constraint @@ -990,7 +990,6 @@ fn constrain_regions_in_type( * code that R corresponds to." */ - let e = rcx.errors_reported; let tcx = rcx.fcx.ccx.tcx; debug!("constrain_regions_in_type(minimum_lifetime={}, ty={})", @@ -1009,7 +1008,7 @@ fn constrain_regions_in_type( // for regions that are as-yet-unknown. } else if r_sub == minimum_lifetime { rcx.fcx.mk_subr( - true, origin, + true, origin.clone(), r_sub, r_sup); } else { rcx.fcx.mk_subr( @@ -1017,8 +1016,6 @@ fn constrain_regions_in_type( r_sub, r_sup); } }); - - return e == rcx.errors_reported; } fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr, @@ -1032,13 +1029,13 @@ fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr, debug!("link_addr_of(base=?)"); let cmt = { - let mut mc = mc::MemCategorizationContext { typer: &mut *rcx }; + let mc = mc::MemCategorizationContext { typer: &*rcx }; ignore_err!(mc.cat_expr(base)) }; link_region_from_node_type(rcx, expr.span, expr.id, mutability, cmt); } -fn link_local(rcx: &mut Rcx, local: &ast::Local) { +fn link_local(rcx: &Rcx, local: &ast::Local) { /*! * Computes the guarantors for any ref bindings in a `let` and * then ensures that the lifetime of the resulting pointer is @@ -1050,12 +1047,12 @@ fn link_local(rcx: &mut Rcx, local: &ast::Local) { None => { return; } Some(expr) => expr, }; - let mut mc = mc::MemCategorizationContext { typer: rcx }; + let mc = mc::MemCategorizationContext { typer: rcx }; let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); - link_pattern(&mut mc, discr_cmt, local.pat); + link_pattern(mc, discr_cmt, local.pat); } -fn link_match(rcx: &mut Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { +fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { /*! * Computes the guarantors for any ref bindings in a match and * then ensures that the lifetime of the resulting pointer is @@ -1063,19 +1060,19 @@ fn link_match(rcx: &mut Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { */ debug!("regionck::for_match()"); - let mut mc = mc::MemCategorizationContext { typer: rcx }; + let mc = mc::MemCategorizationContext { typer: rcx }; let discr_cmt = ignore_err!(mc.cat_expr(discr)); debug!("discr_cmt={}", discr_cmt.repr(mc.typer.tcx())); for arm in arms.iter() { for &root_pat in arm.pats.iter() { - link_pattern(&mut mc, discr_cmt, root_pat); + link_pattern(mc, discr_cmt.clone(), root_pat); } } } -fn link_pattern(mc: &mut mc::MemCategorizationContext<&mut Rcx>, +fn link_pattern(mc: mc::MemCategorizationContext<&Rcx>, discr_cmt: mc::cmt, - root_pat: @ast::Pat) { + root_pat: &ast::Pat) { /*! * Link lifetimes of any ref bindings in `root_pat` to * the pointers found in the discriminant, if needed. @@ -1105,7 +1102,7 @@ fn link_pattern(mc: &mut mc::MemCategorizationContext<&mut Rcx>, }); } -fn link_autoref(rcx: &mut Rcx, +fn link_autoref(rcx: &Rcx, expr: &ast::Expr, autoderefs: uint, autoref: &ty::AutoRef) { @@ -1115,7 +1112,7 @@ fn link_autoref(rcx: &mut Rcx, */ debug!("link_autoref(autoref={:?})", autoref); - let mut mc = mc::MemCategorizationContext { typer: rcx }; + let mc = mc::MemCategorizationContext { typer: rcx }; let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs)); debug!("expr_cmt={}", expr_cmt.repr(mc.typer.tcx())); @@ -1138,7 +1135,7 @@ fn link_autoref(rcx: &mut Rcx, } } -fn link_by_ref(rcx: &mut Rcx, +fn link_by_ref(rcx: &Rcx, expr: &ast::Expr, callee_scope: ast::NodeId) { /*! @@ -1150,13 +1147,13 @@ fn link_by_ref(rcx: &mut Rcx, let tcx = rcx.tcx(); debug!("link_by_ref(expr={}, callee_scope={})", expr.repr(tcx), callee_scope); - let mut mc = mc::MemCategorizationContext { typer: rcx }; + let mc = mc::MemCategorizationContext { typer: rcx }; let expr_cmt = ignore_err!(mc.cat_expr(expr)); let region_min = ty::ReScope(callee_scope); link_region(mc.typer, expr.span, region_min, ast::MutImmutable, expr_cmt); } -fn link_region_from_node_type(rcx: &mut Rcx, +fn link_region_from_node_type(rcx: &Rcx, span: Span, id: ast::NodeId, mutbl: ast::Mutability, @@ -1176,7 +1173,7 @@ fn link_region_from_node_type(rcx: &mut Rcx, } } -fn link_region(rcx: &mut Rcx, +fn link_region(rcx: &Rcx, span: Span, region_min: ty::Region, mutbl: ast::Mutability, @@ -1197,7 +1194,7 @@ fn link_region(rcx: &mut Rcx, region_min.repr(rcx.tcx()), mutbl.repr(rcx.tcx()), cmt_borrowed.repr(rcx.tcx())); - match cmt_borrowed.cat { + match cmt_borrowed.cat.clone() { mc::cat_deref(base, _, mc::BorrowedPtr(_, r_borrowed)) => { // References to an upvar `x` are translated to // `*x`, since that is what happens in the @@ -1287,7 +1284,7 @@ fn link_region(rcx: &mut Rcx, } } -fn adjust_borrow_kind_for_assignment_lhs(rcx: &mut Rcx, +fn adjust_borrow_kind_for_assignment_lhs(rcx: &Rcx, lhs: &ast::Expr) { /*! * Adjusts the inferred borrow_kind as needed to account @@ -1295,19 +1292,19 @@ fn adjust_borrow_kind_for_assignment_lhs(rcx: &mut Rcx, * expression. */ - let mut mc = mc::MemCategorizationContext { typer: rcx }; + let mc = mc::MemCategorizationContext { typer: rcx }; let cmt = ignore_err!(mc.cat_expr(lhs)); adjust_upvar_borrow_kind_for_mut(mc.typer, cmt); } -fn adjust_upvar_borrow_kind_for_mut(rcx: &mut Rcx, +fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx, cmt: mc::cmt) { let mut cmt = cmt; loop { debug!("adjust_upvar_borrow_kind_for_mut(cmt={})", cmt.repr(rcx.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_deref(base, _, mc::OwnedPtr) | mc::cat_interior(base, _) | mc::cat_downcast(base) | @@ -1331,14 +1328,14 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &mut Rcx, return adjust_upvar_borrow_kind(*upvar_id, ub, ty::MutBorrow); } - _ => { - // assignment to deref of an `&mut` - // borrowed pointer implies that the - // pointer itself must be unique, but not - // necessarily *mutable* - return adjust_upvar_borrow_kind_for_unique(rcx, base); - } + _ => {} } + + // assignment to deref of an `&mut` + // borrowed pointer implies that the + // pointer itself must be unique, but not + // necessarily *mutable* + return adjust_upvar_borrow_kind_for_unique(rcx, base); } mc::cat_deref(_, _, mc::UnsafePtr(..)) | @@ -1355,14 +1352,13 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &mut Rcx, } } -fn adjust_upvar_borrow_kind_for_unique(rcx: &mut Rcx, - cmt: mc::cmt) { +fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) { let mut cmt = cmt; loop { debug!("adjust_upvar_borrow_kind_for_unique(cmt={})", cmt.repr(rcx.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_deref(base, _, mc::OwnedPtr) | mc::cat_interior(base, _) | mc::cat_downcast(base) | @@ -1385,12 +1381,12 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &mut Rcx, return adjust_upvar_borrow_kind(*upvar_id, ub, ty::UniqueImmBorrow); } - _ => { - // for a borrowed pointer to be unique, its - // base must be unique - return adjust_upvar_borrow_kind_for_unique(rcx, base); - } + _ => {} } + + // for a borrowed pointer to be unique, its + // base must be unique + return adjust_upvar_borrow_kind_for_unique(rcx, base); } mc::cat_deref(_, _, mc::UnsafePtr(..)) | diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 3f50a64e630..bb57fa2646b 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -27,9 +27,8 @@ use util::common::indenter; use util::ppaux; use util::ppaux::Repr; +use std::rc::Rc; use collections::HashSet; -use std::cell::RefCell; -use std::result; use syntax::ast; use syntax::ast_util; use syntax::codemap::Span; @@ -112,7 +111,7 @@ fn lookup_vtables(vcx: &VtableContext, type_param_defs.repr(vcx.tcx()), substs.repr(vcx.tcx()), result.repr(vcx.tcx())); - @result + result } fn lookup_vtables_for_param(vcx: &VtableContext, @@ -139,7 +138,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext, // Substitute the values of the type parameters that may // appear in the bound. - let trait_ref = substs.as_ref().map_or(trait_ref, |substs| { + let trait_ref = substs.as_ref().map_or(trait_ref.clone(), |substs| { debug!("about to subst: {}, {}", trait_ref.repr(tcx), substs.repr(tcx)); trait_ref.subst(tcx, *substs) @@ -147,13 +146,13 @@ fn lookup_vtables_for_param(vcx: &VtableContext, debug!("after subst: {}", trait_ref.repr(tcx)); - match lookup_vtable(vcx, span, ty, trait_ref, is_early) { + match lookup_vtable(vcx, span, ty, trait_ref.clone(), is_early) { Some(vtable) => param_result.push(vtable), None => { vcx.tcx().sess.span_fatal(span, format!("failed to find an implementation of \ trait {} for {}", - vcx.infcx.trait_ref_to_str(trait_ref), + vcx.infcx.trait_ref_to_str(&*trait_ref), vcx.infcx.ty_to_str(ty))); } } @@ -170,13 +169,13 @@ fn lookup_vtables_for_param(vcx: &VtableContext, ty.repr(vcx.tcx()), param_result.repr(vcx.tcx())); - return @param_result; + param_result } fn relate_trait_refs(vcx: &VtableContext, span: Span, - act_trait_ref: @ty::TraitRef, - exp_trait_ref: @ty::TraitRef) { + act_trait_ref: Rc, + exp_trait_ref: Rc) { /*! * * Checks that an implementation of `act_trait_ref` is suitable @@ -187,17 +186,17 @@ fn relate_trait_refs(vcx: &VtableContext, match infer::mk_sub_trait_refs(vcx.infcx, false, infer::RelateTraitRefs(span), - act_trait_ref, - exp_trait_ref) { - result::Ok(()) => {} // Ok. - result::Err(ref err) => { + act_trait_ref.clone(), + exp_trait_ref.clone()) { + Ok(()) => {} // Ok. + Err(ref err) => { // There is an error, but we need to do some work to make // the message good. // Resolve any type vars in the trait refs let r_act_trait_ref = - vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(act_trait_ref); + vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(&*act_trait_ref); let r_exp_trait_ref = - vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(exp_trait_ref); + vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(&*exp_trait_ref); // Only print the message if there aren't any previous type errors // inside the types. if !ty::trait_ref_contains_error(&r_act_trait_ref) && @@ -218,12 +217,12 @@ fn relate_trait_refs(vcx: &VtableContext, fn lookup_vtable(vcx: &VtableContext, span: Span, ty: ty::t, - trait_ref: @ty::TraitRef, + trait_ref: Rc, is_early: bool) -> Option { debug!("lookup_vtable(ty={}, trait_ref={})", vcx.infcx.ty_to_str(ty), - vcx.infcx.trait_ref_to_str(trait_ref)); + vcx.infcx.trait_ref_to_str(&*trait_ref)); let _i = indenter(); let ty = match fixup_ty(vcx, span, ty, is_early) { @@ -244,23 +243,23 @@ fn lookup_vtable(vcx: &VtableContext, ty::ty_param(param_ty {idx: n, ..}) => { let env_bounds = &vcx.param_env.type_param_bounds; if env_bounds.len() > n { - let type_param_bounds: &[@ty::TraitRef] = + let type_param_bounds: &[Rc] = env_bounds.get(n).trait_bounds.as_slice(); lookup_vtable_from_bounds(vcx, span, type_param_bounds, param_numbered(n), - trait_ref) + trait_ref.clone()) } else { None } } ty::ty_self(_) => { - let self_param_bound = vcx.param_env.self_param_bound.unwrap(); + let self_param_bound = vcx.param_env.self_param_bound.clone().unwrap(); lookup_vtable_from_bounds(vcx, span, [self_param_bound], param_self, - trait_ref) + trait_ref.clone()) } // Default case just falls through @@ -278,9 +277,9 @@ fn lookup_vtable(vcx: &VtableContext, // of them are the vtable we are looking for. fn lookup_vtable_from_bounds(vcx: &VtableContext, span: Span, - bounds: &[@ty::TraitRef], + bounds: &[Rc], param: param_index, - trait_ref: @ty::TraitRef) + trait_ref: Rc) -> Option { let tcx = vcx.tcx(); @@ -291,7 +290,7 @@ fn lookup_vtable_from_bounds(vcx: &VtableContext, bound_trait_ref.repr(vcx.tcx())); if bound_trait_ref.def_id == trait_ref.def_id { - relate_trait_refs(vcx, span, bound_trait_ref, trait_ref); + relate_trait_refs(vcx, span, bound_trait_ref, trait_ref.clone()); let vtable = vtable_param(param, n_bound); debug!("found param vtable: {:?}", vtable); @@ -308,7 +307,7 @@ fn lookup_vtable_from_bounds(vcx: &VtableContext, fn search_for_vtable(vcx: &VtableContext, span: Span, ty: ty::t, - trait_ref: @ty::TraitRef, + trait_ref: Rc, is_early: bool) -> Option { let tcx = vcx.tcx(); @@ -320,26 +319,28 @@ fn search_for_vtable(vcx: &VtableContext, ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id); - // FIXME: this is a bad way to do this, since we do - // pointless allocations. - let impls = tcx.trait_impls.borrow().find(&trait_ref.def_id) - .map_or(@RefCell::new(Vec::new()), |x| *x); + let impls = match tcx.trait_impls.borrow().find_copy(&trait_ref.def_id) { + Some(impls) => impls, + None => { + return None; + } + }; // impls is the list of all impls in scope for trait_ref. - for im in impls.borrow().iter() { + for &impl_did in impls.borrow().iter() { // im is one specific impl of trait_ref. // First, ensure we haven't processed this impl yet. - if impls_seen.contains(&im.did) { + if impls_seen.contains(&impl_did) { continue; } - impls_seen.insert(im.did); + impls_seen.insert(impl_did); // ty::impl_traits gives us the trait im implements. // // If foo implements a trait t, and if t is the same trait as // trait_ref, we need to unify it with trait_ref in order to // get all the ty vars sorted out. - let r = ty::impl_trait_ref(tcx, im.did); + let r = ty::impl_trait_ref(tcx, impl_did); let of_trait_ref = r.expect("trait_ref missing on trait impl"); if of_trait_ref.def_id != trait_ref.def_id { continue; } @@ -362,14 +363,14 @@ fn search_for_vtable(vcx: &VtableContext, let ty::ty_param_substs_and_ty { substs: substs, ty: for_ty - } = impl_self_ty(vcx, span, im.did); + } = impl_self_ty(vcx, span, impl_did); match infer::mk_subty(vcx.infcx, false, infer::RelateSelfType(span), ty, for_ty) { - result::Err(_) => continue, - result::Ok(()) => () + Err(_) => continue, + Ok(()) => () } // Now, in the previous example, for_ty is bound to @@ -388,13 +389,13 @@ fn search_for_vtable(vcx: &VtableContext, // some value of U) with some_trait. This would fail if T // and U weren't compatible. - debug!("(checking vtable) @2 relating trait \ + debug!("(checking vtable) \\#2 relating trait \ ty {} to of_trait_ref {}", - vcx.infcx.trait_ref_to_str(trait_ref), - vcx.infcx.trait_ref_to_str(of_trait_ref)); + vcx.infcx.trait_ref_to_str(&*trait_ref), + vcx.infcx.trait_ref_to_str(&*of_trait_ref)); let of_trait_ref = of_trait_ref.subst(tcx, &substs); - relate_trait_refs(vcx, span, of_trait_ref, trait_ref); + relate_trait_refs(vcx, span, of_trait_ref, trait_ref.clone()); // Recall that trait_ref -- the trait type we're casting to -- @@ -405,7 +406,7 @@ fn search_for_vtable(vcx: &VtableContext, // type variables in substs. This might still be OK: the // process of looking up bounds might constrain some of them. let im_generics = - ty::lookup_item_type(tcx, im.did).generics; + ty::lookup_item_type(tcx, impl_did).generics; let subres = lookup_vtables(vcx, span, im_generics.type_param_defs(), &substs, is_early); @@ -429,7 +430,7 @@ fn search_for_vtable(vcx: &VtableContext, they will be unified with the bounds for \ the target ty, {}", vcx.infcx.tys_to_str(substs_f.tps.as_slice()), - vcx.infcx.trait_ref_to_str(trait_ref)); + vcx.infcx.trait_ref_to_str(&*trait_ref)); // Next, we unify the fixed-up substitutions for the impl self // ty with the substitutions from the trait type that we're @@ -438,12 +439,12 @@ fn search_for_vtable(vcx: &VtableContext, // I am a little confused about this, since it seems to be // very similar to the relate_trait_refs we already do, // but problems crop up if it is removed, so... -sully - connect_trait_tps(vcx, span, &substs_f, trait_ref, im.did); + connect_trait_tps(vcx, span, &substs_f, trait_ref.clone(), impl_did); // Finally, we register that we found a matching impl, and // record the def ID of the impl as well as the resolved list // of type substitutions for the target trait. - found.push(vtable_static(im.did, substs_f.tps.clone(), subres)); + found.push(vtable_static(impl_did, substs_f.tps.clone(), subres)); } match found.len() { @@ -502,7 +503,7 @@ fn fixup_ty(vcx: &VtableContext, fn connect_trait_tps(vcx: &VtableContext, span: Span, impl_substs: &ty::substs, - trait_ref: @ty::TraitRef, + trait_ref: Rc, impl_did: ast::DefId) { let tcx = vcx.tcx(); @@ -561,14 +562,14 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) { }; let vcx = fcx.vtable_context(); - let target_trait_ref = @ty::TraitRef { + let target_trait_ref = Rc::new(ty::TraitRef { def_id: target_def_id, substs: ty::substs { tps: target_substs.tps.clone(), regions: target_substs.regions.clone(), self_ty: Some(typ) } - }; + }); let param_bounds = ty::ParamBounds { builtin_bounds: ty::EmptyBuiltinBounds(), @@ -583,7 +584,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) { is_early); if !is_early { - insert_vtables(fcx, MethodCall::expr(ex.id), @vec!(vtables)); + insert_vtables(fcx, MethodCall::expr(ex.id), vec!(vtables)); } // Now, if this is &trait, we need to link the @@ -683,7 +684,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) { // Search for auto-adjustments to find trait coercions match fcx.inh.adjustments.borrow().find(&ex.id) { Some(adjustment) => { - match **adjustment { + match *adjustment { AutoDerefRef(adj) => { for autoderef in range(0, adj.autoderefs) { let method_call = MethodCall::autoderef(ex.id, autoderef as u32); @@ -743,7 +744,7 @@ pub fn resolve_impl(tcx: &ty::ctxt, [], impl_item.id); - let impl_trait_ref = @impl_trait_ref.subst(tcx, ¶m_env.free_substs); + let impl_trait_ref = impl_trait_ref.subst(tcx, ¶m_env.free_substs); let infcx = &infer::new_infer_ctxt(tcx); let vcx = VtableContext { infcx: infcx, param_env: ¶m_env }; @@ -761,7 +762,7 @@ pub fn resolve_impl(tcx: &ty::ctxt, // but that falls out of doing this. let param_bounds = ty::ParamBounds { builtin_bounds: ty::EmptyBuiltinBounds(), - trait_bounds: vec!(impl_trait_ref) + trait_bounds: vec!(Rc::new(impl_trait_ref)) }; let t = ty::node_id_to_type(tcx, impl_item.id); let t = t.subst(tcx, ¶m_env.free_substs); diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 6ad3d380b28..3843c38fd18 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -51,49 +51,36 @@ fn resolve_type_vars_in_type(fcx: &FnCtxt, sp: Span, typ: ty::t) } } -fn resolve_type_vars_in_types(fcx: &FnCtxt, sp: Span, tys: &[ty::t]) - -> Vec { - tys.iter().map(|t| { - match resolve_type_vars_in_type(fcx, sp, *t) { - Some(t1) => t1, - None => ty::mk_err() - } - }).collect() -} - fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall) { let fcx = wbcx.fcx; let tcx = fcx.ccx.tcx; // Resolve any method map entry - match fcx.inh.method_map.borrow().find(&method_call) { + match fcx.inh.method_map.borrow_mut().pop(&method_call) { Some(method) => { debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})", method_call, method.repr(tcx)); - let method_ty = match resolve_type_vars_in_type(fcx, sp, method.ty) { - Some(t) => t, - None => { - wbcx.success = false; - return; - } - }; - let mut new_tps = Vec::new(); - for &subst in method.substs.tps.iter() { - match resolve_type_vars_in_type(fcx, sp, subst) { - Some(t) => new_tps.push(t), - None => { wbcx.success = false; return; } - } - } let new_method = MethodCallee { origin: method.origin, - ty: method_ty, + ty: match resolve_type_vars_in_type(fcx, sp, method.ty) { + Some(t) => t, + None => { + wbcx.success = false; + return; + } + }, substs: ty::substs { - tps: new_tps, + tps: method.substs.tps.move_iter().map(|subst| { + match resolve_type_vars_in_type(fcx, sp, subst) { + Some(t) => t, + None => { wbcx.success = false; ty::mk_err() } + } + }).collect(), regions: ty::ErasedRegions, self_ty: None } }; - fcx.ccx.method_map.borrow_mut().insert(method_call, new_method); + tcx.method_map.borrow_mut().insert(method_call, new_method); } None => {} } @@ -101,46 +88,46 @@ fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall fn resolve_vtable_map_entry(fcx: &FnCtxt, sp: Span, vtable_key: MethodCall) { // Resolve any vtable map entry - match fcx.inh.vtable_map.borrow().find_copy(&vtable_key) { + match fcx.inh.vtable_map.borrow_mut().pop(&vtable_key) { Some(origins) => { let r_origins = resolve_origins(fcx, sp, origins); - fcx.ccx.vtable_map.borrow_mut().insert(vtable_key, r_origins); debug!("writeback::resolve_vtable_map_entry(vtable_key={}, vtables={:?})", vtable_key, r_origins.repr(fcx.tcx())); + fcx.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins); } None => {} } fn resolve_origins(fcx: &FnCtxt, sp: Span, vtbls: vtable_res) -> vtable_res { - @vtbls.iter().map(|os| @os.iter().map(|origin| { + vtbls.move_iter().map(|os| os.move_iter().map(|origin| { match origin { - &vtable_static(def_id, ref tys, origins) => { - let r_tys = resolve_type_vars_in_types(fcx, - sp, - tys.as_slice()); + vtable_static(def_id, tys, origins) => { + let r_tys = tys.move_iter().map(|t| { + match resolve_type_vars_in_type(fcx, sp, t) { + Some(t1) => t1, + None => ty::mk_err() + } + }).collect(); let r_origins = resolve_origins(fcx, sp, origins); vtable_static(def_id, r_tys, r_origins) } - &vtable_param(n, b) => { - vtable_param(n, b) - } + vtable_param(n, b) => vtable_param(n, b) } }).collect()).collect() } } -fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) - -> Option { +fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) { let fcx = wbcx.fcx; let tcx = fcx.ccx.tcx; // Resolve any borrowings for the node with id `id` - match fcx.inh.adjustments.borrow().find_copy(&id) { - None => (), + let resolved_adj = match fcx.inh.adjustments.borrow_mut().pop(&id) { + None => None, Some(adjustment) => { - match *adjustment { + Some(match adjustment { ty::AutoAddEnv(store) => { let r = match store { ty::RegionTraitStore(r, _) => r, @@ -156,6 +143,8 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) format!("cannot resolve bound for closure: \ {}", infer::fixup_err_to_str(e))); + wbcx.success = false; + return; } Ok(r1) => { // FIXME(eddyb) #2190 Allow only statically resolved @@ -170,15 +159,12 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) "cannot coerce non-statically resolved bare fn") } - let resolved_adj = @ty::AutoAddEnv(match store { + ty::AutoAddEnv(match store { ty::RegionTraitStore(..) => { ty::RegionTraitStore(r1, ast::MutMutable) } ty::UniqTraitStore => ty::UniqTraitStore - }); - debug!("Adjustments for node {}: {:?}", - id, resolved_adj); - tcx.adjustments.borrow_mut().insert(id, resolved_adj); + }) } } } @@ -190,42 +176,38 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) resolve_vtable_map_entry(wbcx.fcx, sp, method_call); } - let fixup_region = |r| { - match resolve_region(fcx.infcx(), - r, - resolve_all | force_all) { - Ok(r1) => r1, - Err(e) => { - // This should not, I think, happen. - tcx.sess.span_err( - sp, - format!("cannot resolve scope of borrow: \ - {}", - infer::fixup_err_to_str(e))); - r - } - } - }; - - let resolved_autoref = match adj.autoref { - None => None, - Some(ref r) => Some(r.map_region(fixup_region)) - }; - - let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef { + ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: adj.autoderefs, - autoref: resolved_autoref, - }); - debug!("Adjustments for node {}: {:?}", id, resolved_adj); - tcx.adjustments.borrow_mut().insert(id, resolved_adj); + autoref: adj.autoref.map(|r| r.map_region(|r| { + match resolve_region(fcx.infcx(), r, + resolve_all | force_all) { + Ok(r1) => r1, + Err(e) => { + // This should not, I think, happen. + tcx.sess.span_err( + sp, + format!("cannot resolve scope of borrow: \ + {}", + infer::fixup_err_to_str(e))); + r + } + } + })), + }) } - ty::AutoObject(..) => { - debug!("Adjustments for node {}: {:?}", id, adjustment); - tcx.adjustments.borrow_mut().insert(id, adjustment); - } - } + adjustment => adjustment + }) } + }; + + debug!("Adjustments for node {}: {:?}", + id, resolved_adj); + match resolved_adj { + Some(adj) => { + tcx.adjustments.borrow_mut().insert(id, adj); + } + None => {} } // Resolve the type of the node with id `id` @@ -233,26 +215,23 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) match resolve_type_vars_in_type(fcx, sp, n_ty) { None => { wbcx.success = false; - return None; } Some(t) => { debug!("resolve_type_vars_for_node(id={}, n_ty={}, t={})", id, ppaux::ty_to_str(tcx, n_ty), ppaux::ty_to_str(tcx, t)); write_ty_to_tcx(tcx, id, t); - let mut ret = Some(t); fcx.opt_node_ty_substs(id, |substs| { let mut new_tps = Vec::new(); for subst in substs.tps.iter() { match resolve_type_vars_in_type(fcx, sp, *subst) { Some(t) => new_tps.push(t), - None => { wbcx.success = false; ret = None; break } + None => { wbcx.success = false; break } } } write_substs_to_tcx(tcx, id, new_tps); - ret.is_some() + wbcx.success }); - ret } } } @@ -401,7 +380,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt, decl: &ast::FnDecl, for arg in decl.inputs.iter() { wbcx.visit_pat(arg.pat, ()); // Privacy needs the type for the whole pattern, not just each binding - if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) { + if !pat_util::pat_is_binding(&fcx.tcx().def_map, arg.pat) { resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id); } } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index c0fd73f4a36..3a50b0681e8 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -27,7 +27,6 @@ use middle::ty::{ty_uint, ty_uniq, ty_bare_fn, ty_closure}; use middle::ty::type_is_ty_var; use middle::subst::Subst; use middle::ty; -use middle::ty::{Impl, Method}; use middle::typeck::CrateCtxt; use middle::typeck::infer::combine::Combine; use middle::typeck::infer::InferCtxt; @@ -252,7 +251,8 @@ impl<'a> CoherenceChecker<'a> { fn check_implementation(&self, item: &Item, associated_traits: &[TraitRef]) { let tcx = self.crate_context.tcx; - let self_type = ty::lookup_item_type(tcx, local_def(item.id)); + let impl_did = local_def(item.id); + let self_type = ty::lookup_item_type(tcx, impl_did); // If there are no traits, then this implementation must have a // base type. @@ -276,7 +276,7 @@ impl<'a> CoherenceChecker<'a> { } } - let implementation = self.create_impl_from_item(item); + let impl_methods = self.create_impl_from_item(item); for associated_trait in associated_traits.iter() { let trait_ref = ty::node_id_to_trait_ref( @@ -285,7 +285,7 @@ impl<'a> CoherenceChecker<'a> { trait_ref.repr(self.crate_context.tcx), token::get_ident(item.ident)); - self.add_trait_impl(trait_ref.def_id, implementation); + self.add_trait_impl(trait_ref.def_id, impl_did); } // Add the implementation to the mapping from implementation to base @@ -300,20 +300,20 @@ impl<'a> CoherenceChecker<'a> { Some(base_type_def_id) => { // FIXME: Gather up default methods? if associated_traits.len() == 0 { - self.add_inherent_impl(base_type_def_id, implementation); + self.add_inherent_impl(base_type_def_id, impl_did); } } } - tcx.impls.borrow_mut().insert(implementation.did, implementation); + tcx.impl_methods.borrow_mut().insert(impl_did, impl_methods); } // Creates default method IDs and performs type substitutions for an impl // and trait pair. Then, for each provided method in the trait, inserts a // `ProvidedMethodInfo` instance into the `provided_method_sources` map. - fn instantiate_default_methods(&self, impl_id: ast::DefId, + fn instantiate_default_methods(&self, impl_id: DefId, trait_ref: &ty::TraitRef, - all_methods: &mut Vec<@Method> ) { + all_methods: &mut Vec) { let tcx = self.crate_context.tcx; debug!("instantiate_default_methods(impl_id={:?}, trait_ref={})", impl_id, trait_ref.repr(tcx)); @@ -330,16 +330,16 @@ impl<'a> CoherenceChecker<'a> { // Create substitutions for the various trait parameters. let new_method_ty = - @subst_receiver_types_in_method_ty( + Rc::new(subst_receiver_types_in_method_ty( tcx, impl_id, trait_ref, new_did, - *trait_method, - Some(trait_method.def_id)); + &**trait_method, + Some(trait_method.def_id))); debug!("new_method_ty={}", new_method_ty.repr(tcx)); - all_methods.push(new_method_ty); + all_methods.push(new_did); // construct the polytype for the method based on the method_ty let new_generics = ty::Generics { @@ -366,40 +366,24 @@ impl<'a> CoherenceChecker<'a> { } } - fn add_inherent_impl(&self, base_def_id: DefId, - implementation: @Impl) { + fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) { let tcx = self.crate_context.tcx; - let implementation_list; - let mut inherent_impls = tcx.inherent_impls.borrow_mut(); - match inherent_impls.find(&base_def_id) { - None => { - implementation_list = @RefCell::new(Vec::new()); - inherent_impls.insert(base_def_id, implementation_list); - } - Some(&existing_implementation_list) => { - implementation_list = existing_implementation_list; + match tcx.inherent_impls.borrow().find(&base_def_id) { + Some(implementation_list) => { + implementation_list.borrow_mut().push(impl_def_id); + return; } + None => {} } - implementation_list.borrow_mut().push(implementation); + tcx.inherent_impls.borrow_mut().insert(base_def_id, + Rc::new(RefCell::new(vec!(impl_def_id)))); } - fn add_trait_impl(&self, base_def_id: DefId, - implementation: @Impl) { - let tcx = self.crate_context.tcx; - let implementation_list; - let mut trait_impls = tcx.trait_impls.borrow_mut(); - match trait_impls.find(&base_def_id) { - None => { - implementation_list = @RefCell::new(Vec::new()); - trait_impls.insert(base_def_id, implementation_list); - } - Some(&existing_implementation_list) => { - implementation_list = existing_implementation_list; - } - } - - implementation_list.borrow_mut().push(implementation); + fn add_trait_impl(&self, base_def_id: DefId, impl_def_id: DefId) { + ty::record_trait_implementation(self.crate_context.tcx, + base_def_id, + impl_def_id); } fn check_implementation_coherence(&self) { @@ -410,34 +394,32 @@ impl<'a> CoherenceChecker<'a> { fn check_implementation_coherence_of(&self, trait_def_id: DefId) { // Unify pairs of polytypes. - self.iter_impls_of_trait_local(trait_def_id, |a| { - let implementation_a = a; + self.iter_impls_of_trait_local(trait_def_id, |impl_a| { let polytype_a = - self.get_self_type_for_implementation(implementation_a); + self.get_self_type_for_implementation(impl_a); // "We have an impl of trait for type , - // and that impl is " - self.iter_impls_of_trait(trait_def_id, |b| { - let implementation_b = b; + // and that impl is " + self.iter_impls_of_trait(trait_def_id, |impl_b| { // An impl is coherent with itself - if a.did != b.did { + if impl_a != impl_b { let polytype_b = self.get_self_type_for_implementation( - implementation_b); + impl_b); if self.polytypes_unify(polytype_a.clone(), polytype_b) { let session = &self.crate_context.tcx.sess; session.span_err( - self.span_of_impl(implementation_a), + self.span_of_impl(impl_a), format!("conflicting implementations for trait `{}`", ty::item_path_str(self.crate_context.tcx, trait_def_id))); - if implementation_b.did.krate == LOCAL_CRATE { - session.span_note(self.span_of_impl(implementation_b), + if impl_b.krate == LOCAL_CRATE { + session.span_note(self.span_of_impl(impl_b), "note conflicting implementation here"); } else { let crate_store = &self.crate_context.tcx.sess.cstore; - let cdata = crate_store.get_crate_data(implementation_b.did.krate); + let cdata = crate_store.get_crate_data(impl_b.krate); session.note( "conflicting implementation in crate `" + cdata.name + "`"); } @@ -447,7 +429,7 @@ impl<'a> CoherenceChecker<'a> { }) } - fn iter_impls_of_trait(&self, trait_def_id: DefId, f: |@Impl|) { + fn iter_impls_of_trait(&self, trait_def_id: DefId, f: |DefId|) { self.iter_impls_of_trait_local(trait_def_id, |x| f(x)); if trait_def_id.krate == LOCAL_CRATE { @@ -456,17 +438,17 @@ impl<'a> CoherenceChecker<'a> { let crate_store = &self.crate_context.tcx.sess.cstore; csearch::each_implementation_for_trait(crate_store, trait_def_id, |impl_def_id| { - let implementation = @csearch::get_impl(self.crate_context.tcx, impl_def_id); - let _ = lookup_item_type(self.crate_context.tcx, implementation.did); - f(implementation); + // Is this actually necessary? + let _ = lookup_item_type(self.crate_context.tcx, impl_def_id); + f(impl_def_id); }); } - fn iter_impls_of_trait_local(&self, trait_def_id: DefId, f: |@Impl|) { + fn iter_impls_of_trait_local(&self, trait_def_id: DefId, f: |DefId|) { match self.crate_context.tcx.trait_impls.borrow().find(&trait_def_id) { Some(impls) => { - for &im in impls.borrow().iter() { - f(im); + for &impl_did in impls.borrow().iter() { + f(impl_did); } } None => { /* no impls? */ } @@ -526,9 +508,9 @@ impl<'a> CoherenceChecker<'a> { b.monotype).is_ok() } - fn get_self_type_for_implementation(&self, implementation: @Impl) + fn get_self_type_for_implementation(&self, impl_did: DefId) -> ty_param_bounds_and_ty { - self.crate_context.tcx.tcache.borrow().get_copy(&implementation.did) + self.crate_context.tcx.tcache.borrow().get_copy(&impl_did) } // Privileged scope checking @@ -538,7 +520,7 @@ impl<'a> CoherenceChecker<'a> { } fn trait_ref_to_trait_def_id(&self, trait_ref: &TraitRef) -> DefId { - let def_map = self.crate_context.tcx.def_map; + let def_map = &self.crate_context.tcx.def_map; let trait_def = def_map.borrow().get_copy(&trait_ref.ref_id); let trait_id = def_id_of_def(trait_def); return trait_id; @@ -580,15 +562,13 @@ impl<'a> CoherenceChecker<'a> { } } - // Converts an implementation in the AST to an Impl structure. - fn create_impl_from_item(&self, item: &Item) -> @Impl { - let tcx = self.crate_context.tcx; + // Converts an implementation in the AST to a vector of methods. + fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { ItemImpl(_, ref trait_refs, _, ref ast_methods) => { - let mut methods = Vec::new(); - for ast_method in ast_methods.iter() { - methods.push(ty::method(tcx, local_def(ast_method.id))); - } + let mut methods: Vec = ast_methods.iter().map(|ast_method| { + local_def(ast_method.id) + }).collect(); for trait_ref in trait_refs.iter() { let ty_trait_ref = ty::node_id_to_trait_ref( @@ -596,15 +576,11 @@ impl<'a> CoherenceChecker<'a> { trait_ref.ref_id); self.instantiate_default_methods(local_def(item.id), - ty_trait_ref, + &*ty_trait_ref, &mut methods); } - return @Impl { - did: local_def(item.id), - ident: item.ident, - methods: methods - }; + methods } _ => { self.crate_context.tcx.sess.span_bug(item.span, @@ -613,9 +589,9 @@ impl<'a> CoherenceChecker<'a> { } } - fn span_of_impl(&self, implementation: @Impl) -> Span { - assert_eq!(implementation.did.krate, LOCAL_CRATE); - self.crate_context.tcx.map.span(implementation.did.node) + fn span_of_impl(&self, impl_did: DefId) -> Span { + assert_eq!(impl_did.krate, LOCAL_CRATE); + self.crate_context.tcx.map.span(impl_did.node) } // External crate handling @@ -624,36 +600,35 @@ impl<'a> CoherenceChecker<'a> { impls_seen: &mut HashSet, impl_def_id: DefId) { let tcx = self.crate_context.tcx; - let implementation = @csearch::get_impl(tcx, impl_def_id); + let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id); // Make sure we don't visit the same implementation multiple times. - if !impls_seen.insert(implementation.did) { + if !impls_seen.insert(impl_def_id) { // Skip this one. return } // Good. Continue. - let _ = lookup_item_type(tcx, implementation.did); - let associated_traits = get_impl_trait(tcx, implementation.did); + let _ = lookup_item_type(tcx, impl_def_id); + let associated_traits = get_impl_trait(tcx, impl_def_id); // Do a sanity check. assert!(associated_traits.is_some()); // Record all the trait methods. for trait_ref in associated_traits.iter() { - self.add_trait_impl(trait_ref.def_id, implementation); + self.add_trait_impl(trait_ref.def_id, impl_def_id); } // For any methods that use a default implementation, add them to // the map. This is a bit unfortunate. - for method in implementation.methods.iter() { - for source in method.provided_source.iter() { - tcx.provided_method_sources.borrow_mut() - .insert(method.def_id, *source); + for &method_def_id in methods.iter() { + for &source in ty::method(tcx, method_def_id).provided_source.iter() { + tcx.provided_method_sources.borrow_mut().insert(method_def_id, source); } } - tcx.impls.borrow_mut().insert(implementation.did, implementation); + tcx.impl_methods.borrow_mut().insert(impl_def_id, methods); } // Adds implementations and traits from external crates to the coherence @@ -680,22 +655,21 @@ impl<'a> CoherenceChecker<'a> { Some(id) => id, None => { return } }; - let trait_impls = tcx.trait_impls.borrow(); - let impls_opt = trait_impls.find(&drop_trait); - let impls; - match impls_opt { + let impl_methods = tcx.impl_methods.borrow(); + let trait_impls = match tcx.trait_impls.borrow().find_copy(&drop_trait) { None => return, // No types with (new-style) dtors present. - Some(found_impls) => impls = found_impls - } + Some(found_impls) => found_impls + }; - for impl_info in impls.borrow().iter() { - if impl_info.methods.len() < 1 { + for &impl_did in trait_impls.borrow().iter() { + let methods = impl_methods.get(&impl_did); + if methods.len() < 1 { // We'll error out later. For now, just don't ICE. continue; } - let method_def_id = impl_info.methods.get(0).def_id; + let method_def_id = *methods.get(0); - let self_type = self.get_self_type_for_implementation(*impl_info); + let self_type = self.get_self_type_for_implementation(impl_did); match ty::get(self_type.ty).sty { ty::ty_enum(type_def_id, _) | ty::ty_struct(type_def_id, _) => { @@ -705,9 +679,9 @@ impl<'a> CoherenceChecker<'a> { } _ => { // Destructors only work on nominal types. - if impl_info.did.krate == ast::LOCAL_CRATE { + if impl_did.krate == ast::LOCAL_CRATE { { - match tcx.map.find(impl_info.did.node) { + match tcx.map.find(impl_did.node) { Some(ast_map::NodeItem(item)) => { tcx.sess.span_err((*item).span, "the Drop trait may \ diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 490a52df2ba..0102001aa3c 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -126,7 +126,7 @@ impl<'a> AstConv for CrateCtxt<'a> { } } - fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef { + fn get_trait_def(&self, id: ast::DefId) -> Rc { get_trait_def(self, id) } @@ -195,7 +195,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { // For each method, construct a suitable ty::Method and // store it into the `tcx.methods` table: for m in ms.iter() { - let ty_method = @match m { + let ty_method = Rc::new(match m { &ast::Required(ref m) => { ty_method_of_trait_method( ccx, trait_id, &trait_ty_generics, @@ -209,10 +209,10 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { &m.id, &m.ident, &m.explicit_self, &m.generics, &m.fn_style, m.decl) } - }; + }); if ty_method.explicit_self == ast::SelfStatic { - make_static_method_ty(ccx, trait_id, ty_method, + make_static_method_ty(ccx, trait_id, &*ty_method, &trait_ty_generics); } @@ -221,7 +221,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { } // Add an entry mapping - let method_def_ids = @ms.iter().map(|m| { + let method_def_ids = Rc::new(ms.iter().map(|m| { match m { &ast::Required(ref ty_method) => { local_def(ty_method.id) @@ -230,7 +230,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { local_def(method.id) } } - }).collect(); + }).collect()); let trait_def_id = local_def(trait_id); tcx.trait_method_def_ids.borrow_mut() @@ -342,10 +342,10 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { new_type_param_defs.push(ty::TypeParameterDef { ident: special_idents::self_, def_id: dummy_defid, - bounds: @ty::ParamBounds { + bounds: Rc::new(ty::ParamBounds { builtin_bounds: ty::EmptyBuiltinBounds(), trait_bounds: vec!(self_trait_ref) - }, + }), default: None }); @@ -412,7 +412,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, assert!(!tcx.supertraits.borrow().contains_key(&local_def(id))); let self_ty = ty::mk_self(ccx.tcx, local_def(id)); - let mut ty_trait_refs: Vec<@ty::TraitRef> = Vec::new(); + let mut ty_trait_refs: Vec> = Vec::new(); let mut bounds = ty::EmptyBuiltinBounds(); for ast_trait_ref in ast_trait_refs.iter() { let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, ast_trait_ref); @@ -434,7 +434,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, } } - tcx.supertraits.borrow_mut().insert(local_def(id), @ty_trait_refs); + tcx.supertraits.borrow_mut().insert(local_def(id), Rc::new(ty_trait_refs)); bounds } @@ -489,12 +489,12 @@ fn convert_methods(ccx: &CrateCtxt, let num_rcvr_ty_params = rcvr_ty_generics.type_param_defs().len(); let m_ty_generics = ty_generics_for_fn_or_method(ccx, &m.generics, num_rcvr_ty_params); - let mty = @ty_of_method(ccx, - container, - *m, - untransformed_rcvr_ty, - rcvr_ast_generics, - rcvr_visibility); + let mty = Rc::new(ty_of_method(ccx, + container, + *m, + untransformed_rcvr_ty, + rcvr_ast_generics, + rcvr_visibility)); let fty = ty::mk_bare_fn(tcx, mty.fty.clone()); debug!("method {} (id {}) has type {}", m.ident.repr(ccx.tcx), @@ -726,7 +726,7 @@ pub fn convert_struct(ccx: &CrateCtxt, result }).collect(); - tcx.struct_fields.borrow_mut().insert(local_def(id), @field_tys); + tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys)); let super_struct = match struct_def.super_struct { Some(t) => match t.node { @@ -813,8 +813,7 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) { pub fn instantiate_trait_ref(ccx: &CrateCtxt, ast_trait_ref: &ast::TraitRef, - self_ty: ty::t) -> @ty::TraitRef -{ + self_ty: ty::t) -> Rc { /*! * Instantiates the path for the given trait reference, assuming that * it's bound to a valid trait type. Returns the def_id for the defining @@ -831,8 +830,8 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, ccx, &rscope, trait_did, Some(self_ty), &ast_trait_ref.path); ccx.tcx.trait_refs.borrow_mut().insert(ast_trait_ref.ref_id, - trait_ref); - return trait_ref; + trait_ref.clone()); + trait_ref } _ => { ccx.tcx.sess.span_fatal( @@ -843,7 +842,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, } } -fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> @ty::TraitDef { +fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc { if trait_id.krate != ast::LOCAL_CRATE { return ty::lookup_trait_def(ccx.tcx, trait_id) } @@ -855,11 +854,11 @@ fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> @ty::TraitDef { } } -pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> @ty::TraitDef { +pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc { let def_id = local_def(it.id); let tcx = ccx.tcx; match tcx.trait_defs.borrow().find(&def_id) { - Some(&def) => return def, + Some(def) => return def.clone(), _ => {} } @@ -872,13 +871,16 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> @ty::TraitDef { it.id, it.span, supertraits.as_slice()); - let trait_ref = @ty::TraitRef {def_id: def_id, - substs: substs}; - let trait_def = @ty::TraitDef {generics: ty_generics, - bounds: bounds, - trait_ref: trait_ref}; - tcx.trait_defs.borrow_mut().insert(def_id, trait_def); - return trait_def; + let trait_def = Rc::new(ty::TraitDef { + generics: ty_generics, + bounds: bounds, + trait_ref: Rc::new(ty::TraitRef { + def_id: def_id, + substs: substs + }) + }); + tcx.trait_defs.borrow_mut().insert(def_id, trait_def.clone()); + trait_def } ref s => { tcx.sess.span_bug( @@ -999,24 +1001,24 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, } } -pub fn ty_generics_for_type(ccx: &CrateCtxt, - generics: &ast::Generics) - -> ty::Generics { +fn ty_generics_for_type(ccx: &CrateCtxt, + generics: &ast::Generics) + -> ty::Generics { ty_generics(ccx, &generics.lifetimes, &generics.ty_params, 0) } -pub fn ty_generics_for_fn_or_method(ccx: &CrateCtxt, - generics: &ast::Generics, - base_index: uint) - -> ty::Generics { +fn ty_generics_for_fn_or_method(ccx: &CrateCtxt, + generics: &ast::Generics, + base_index: uint) + -> ty::Generics { let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics); ty_generics(ccx, &early_lifetimes, &generics.ty_params, base_index) } -pub fn ty_generics(ccx: &CrateCtxt, - lifetimes: &Vec, - ty_params: &OwnedSlice, - base_index: uint) -> ty::Generics { +fn ty_generics(ccx: &CrateCtxt, + lifetimes: &Vec, + ty_params: &OwnedSlice, + base_index: uint) -> ty::Generics { return ty::Generics { region_param_defs: Rc::new(lifetimes.iter().map(|l| { ty::RegionParameterDef { name: l.name, @@ -1025,12 +1027,12 @@ pub fn ty_generics(ccx: &CrateCtxt, type_param_defs: Rc::new(ty_params.iter().enumerate().map(|(offset, param)| { let existing_def_opt = { let ty_param_defs = ccx.tcx.ty_param_defs.borrow(); - ty_param_defs.find(¶m.id).map(|&def| def) + ty_param_defs.find(¶m.id).map(|def| def.clone()) }; existing_def_opt.unwrap_or_else(|| { let param_ty = ty::param_ty {idx: base_index + offset, def_id: local_def(param.id)}; - let bounds = @compute_bounds(ccx, param_ty, ¶m.bounds); + let bounds = Rc::new(compute_bounds(ccx, param_ty, ¶m.bounds)); let default = param.default.map(|path| { let ty = ast_ty_to_ty(ccx, &ExplicitRscope, path); let cur_idx = param_ty.idx; @@ -1056,7 +1058,7 @@ pub fn ty_generics(ccx: &CrateCtxt, default: default }; debug!("def for param: {}", def.repr(ccx.tcx)); - ccx.tcx.ty_param_defs.borrow_mut().insert(param.id, def); + ccx.tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone()); def }) }).collect()), diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index ad0590318ea..e921674ad83 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -195,7 +195,7 @@ impl<'f> Coerce<'f> { } pub fn subtype(&self, a: ty::t, b: ty::t) -> CoerceResult { - match Sub(*self.get_ref()).tys(a, b) { + match Sub(self.get_ref().clone()).tys(a, b) { Ok(_) => Ok(None), // No coercion required. Err(ref e) => Err(*e) } @@ -232,8 +232,9 @@ impl<'f> Coerce<'f> { // to type check, we will construct the type that `&M*expr` would // yield. - let sub = Sub(*self.get_ref()); - let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); + let sub = Sub(self.get_ref().clone()); + let coercion = Coercion(self.get_ref().trace.clone()); + let r_borrow = self.get_ref().infcx.next_region_var(coercion); let inner_ty = match *sty_a { ty::ty_box(typ) | ty::ty_uniq(typ) => typ, @@ -247,7 +248,7 @@ impl<'f> Coerce<'f> { r_borrow, mt {ty: inner_ty, mutbl: mt_b.mutbl}); if_ok!(sub.tys(a_borrowed, b)); - Ok(Some(@AutoDerefRef(AutoDerefRef { + Ok(Some(AutoDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(AutoPtr(r_borrow, mt_b.mutbl)) }))) @@ -269,10 +270,11 @@ impl<'f> Coerce<'f> { } }; - let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); + let coercion = Coercion(self.get_ref().trace.clone()); + let r_a = self.get_ref().infcx.next_region_var(coercion); let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, VstoreSlice(r_a)); if_ok!(self.subtype(a_borrowed, b)); - Ok(Some(@AutoDerefRef(AutoDerefRef { + Ok(Some(AutoDerefRef(AutoDerefRef { autoderefs: 0, autoref: Some(AutoBorrowVec(r_a, MutImmutable)) }))) @@ -288,8 +290,9 @@ impl<'f> Coerce<'f> { a.inf_str(self.get_ref().infcx), sty_a, b.inf_str(self.get_ref().infcx)); - let sub = Sub(*self.get_ref()); - let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); + let sub = Sub(self.get_ref().clone()); + let coercion = Coercion(self.get_ref().trace.clone()); + let r_borrow = self.get_ref().infcx.next_region_var(coercion); let ty_inner = match *sty_a { ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) | ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty { @@ -307,7 +310,7 @@ impl<'f> Coerce<'f> { let a_borrowed = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow, mt {ty: ty_inner, mutbl: mutbl_b}); if_ok!(sub.tys(a_borrowed, b)); - Ok(Some(@AutoDerefRef(AutoDerefRef { + Ok(Some(AutoDerefRef(AutoDerefRef { autoderefs: 0, autoref: Some(AutoBorrowVec(r_borrow, mutbl_b)) }))) @@ -324,7 +327,8 @@ impl<'f> Coerce<'f> { b.inf_str(self.get_ref().infcx)); let tcx = self.get_ref().infcx.tcx; - let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace)); + let coercion = Coercion(self.get_ref().trace.clone()); + let r_a = self.get_ref().infcx.next_region_var(coercion); let a_borrowed = match *sty_a { ty::ty_trait(~ty::TyTrait { def_id, ref substs, bounds, .. }) => { @@ -337,7 +341,7 @@ impl<'f> Coerce<'f> { }; if_ok!(self.subtype(a_borrowed, b)); - Ok(Some(@AutoDerefRef(AutoDerefRef { + Ok(Some(AutoDerefRef(AutoDerefRef { autoderefs: 0, autoref: Some(AutoBorrowObj(r_a, b_mutbl)) }))) @@ -384,7 +388,7 @@ impl<'f> Coerce<'f> { _ => return self.subtype(a, b) }; - let adj = @ty::AutoAddEnv(fn_ty_b.store); + let adj = ty::AutoAddEnv(fn_ty_b.store); let a_closure = ty::mk_closure(self.get_ref().infcx.tcx, ty::ClosureTy { sig: fn_ty_a.sig.clone(), @@ -419,7 +423,7 @@ impl<'f> Coerce<'f> { // although references and unsafe ptrs have the same // representation, we still register an AutoDerefRef so that // regionck knows that the region for `a` must be valid here - Ok(Some(@AutoDerefRef(AutoDerefRef { + Ok(Some(AutoDerefRef(AutoDerefRef { autoderefs: 1, autoref: Some(ty::AutoUnsafe(mt_b.mutbl)) }))) @@ -438,7 +442,7 @@ impl<'f> Coerce<'f> { a.inf_str(self.get_ref().infcx), sty_a, b.inf_str(self.get_ref().infcx)); - Ok(Some(@ty::AutoObject(trait_store, bounds, - trait_def_id, trait_substs.clone()))) + Ok(Some(ty::AutoObject(trait_store, bounds, + trait_def_id, trait_substs.clone()))) } } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index bd3bb18fa33..54cf6524664 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -235,19 +235,6 @@ pub trait Combine { fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres; - fn flds(&self, a: ty::field, b: ty::field) -> cres { - if a.ident == b.ident { - self.mts(&a.mt, &b.mt) - .and_then(|mt| Ok(ty::field {ident: a.ident, mt: mt}) ) - .or_else(|e| Err(ty::terr_in_field(@e, a.ident)) ) - } else { - Err(ty::terr_record_fields( - expected_found(self, - a.ident, - b.ident))) - } - } - fn args(&self, a: ty::t, b: ty::t) -> cres { self.contratys(a, b).and_then(|t| Ok(t)) } @@ -337,6 +324,7 @@ pub trait Combine { } } +#[deriving(Clone)] pub struct CombineFields<'a> { pub infcx: &'a InferCtxt<'a>, pub a_is_expected: bool, diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 6ba727f9d4d..a5d41b15d5d 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -76,6 +76,7 @@ use middle::typeck::infer::region_inference::ProcessedErrors; use middle::typeck::infer::region_inference::SameRegions; use std::cell::{Cell, RefCell}; use std::char::from_u32; +use std::rc::Rc; use std::strbuf::StrBuf; use syntax::ast; use syntax::ast_map; @@ -158,7 +159,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> { let p_errors = self.process_errors(errors); let errors = if p_errors.is_empty() { errors } else { &p_errors }; for error in errors.iter() { - match *error { + match error.clone() { ConcreteFailure(origin, sub, sup) => { self.report_concrete_failure(origin, sub, sup); } @@ -206,7 +207,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> { let mut same_regions = Vec::new(); let mut processed_errors = Vec::new(); for error in errors.iter() { - match *error { + match error.clone() { ConcreteFailure(origin, sub, sup) => { debug!("processing ConcreteFailure") let trace = match origin { @@ -661,10 +662,10 @@ impl<'a> ErrorReporting for InferCtxt<'a> { same_regions: &[SameRegions]) { self.give_suggestion(same_regions); for vo in var_origins.iter() { - self.report_inference_failure(*vo); + self.report_inference_failure(vo.clone()); } - for &(trace, terr) in trace_origins.iter() { - self.report_type_error(trace, &terr); + for &(ref trace, terr) in trace_origins.iter() { + self.report_type_error(trace.clone(), &terr); } } @@ -1391,12 +1392,12 @@ impl Resolvable for ty::t { } } -impl Resolvable for @ty::TraitRef { - fn resolve(&self, infcx: &InferCtxt) -> @ty::TraitRef { - @infcx.resolve_type_vars_in_trait_ref_if_possible(*self) +impl Resolvable for Rc { + fn resolve(&self, infcx: &InferCtxt) -> Rc { + Rc::new(infcx.resolve_type_vars_in_trait_ref_if_possible(&**self)) } fn contains_error(&self) -> bool { - ty::trait_ref_contains_error(*self) + ty::trait_ref_contains_error(&**self) } } diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 9f87993279c..32bc7eedf2f 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -38,11 +38,11 @@ impl<'f> Combine for Glb<'f> { fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx } fn tag(&self) -> ~str { "glb".to_owned() } fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected } - fn trace(&self) -> TypeTrace { self.get_ref().trace } + fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() } - fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) } - fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) } - fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) } + fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) } + fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) } + fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) } fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { let tcx = self.get_ref().infcx.tcx; @@ -78,7 +78,7 @@ impl<'f> Combine for Glb<'f> { } fn contratys(&self, a: ty::t, b: ty::t) -> cres { - Lub(*self.get_ref()).tys(a, b) + self.lub().tys(a, b) } fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres { @@ -108,12 +108,12 @@ impl<'f> Combine for Glb<'f> { a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx)); - Ok(self.get_ref().infcx.region_vars.glb_regions(Subtype(self.get_ref().trace), a, b)) + Ok(self.get_ref().infcx.region_vars.glb_regions(Subtype(self.trace()), a, b)) } fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres { - Lub(*self.get_ref()).regions(a, b) + self.lub().regions(a, b) } fn tys(&self, a: ty::t, b: ty::t) -> cres { @@ -137,11 +137,11 @@ impl<'f> Combine for Glb<'f> { // Instantiate each bound region with a fresh region variable. let (a_with_fresh, a_map) = self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions( - self.get_ref().trace, a); + self.trace(), a); let a_vars = var_ids(self, &a_map); let (b_with_fresh, b_map) = self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions( - self.get_ref().trace, b); + self.trace(), b); let b_vars = var_ids(self, &b_map); // Collect constraints. diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 83cc9294244..ebfb17a8876 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -47,26 +47,26 @@ use util::common::indenter; use collections::HashMap; -pub trait LatticeValue { - fn sub(cf: &CombineFields, a: &Self, b: &Self) -> ures; - fn lub(cf: &CombineFields, a: &Self, b: &Self) -> cres; - fn glb(cf: &CombineFields, a: &Self, b: &Self) -> cres; +trait LatticeValue { + fn sub(cf: CombineFields, a: &Self, b: &Self) -> ures; + fn lub(cf: CombineFields, a: &Self, b: &Self) -> cres; + fn glb(cf: CombineFields, a: &Self, b: &Self) -> cres; } pub type LatticeOp<'a, T> = - |cf: &CombineFields, a: &T, b: &T|: 'a -> cres; + |cf: CombineFields, a: &T, b: &T|: 'a -> cres; impl LatticeValue for ty::t { - fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { - Sub(*cf).tys(*a, *b).to_ures() + fn sub(cf: CombineFields, a: &ty::t, b: &ty::t) -> ures { + Sub(cf).tys(*a, *b).to_ures() } - fn lub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { - Lub(*cf).tys(*a, *b) + fn lub(cf: CombineFields, a: &ty::t, b: &ty::t) -> cres { + Lub(cf).tys(*a, *b) } - fn glb(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres { - Glb(*cf).tys(*a, *b) + fn glb(cf: CombineFields, a: &ty::t, b: &ty::t) -> cres { + Glb(cf).tys(*a, *b) } } @@ -142,7 +142,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> { match (&a_bounds.ub, &b_bounds.lb) { (&Some(ref a_ub), &Some(ref b_lb)) => { let r = self.infcx.try( - || LatticeValue::sub(self, a_ub, b_lb)); + || LatticeValue::sub(self.clone(), a_ub, b_lb)); match r { Ok(()) => { return Ok(()); @@ -232,7 +232,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> { (&Some(_), &None) => Ok((*a).clone()), (&None, &Some(_)) => Ok((*b).clone()), (&Some(ref v_a), &Some(ref v_b)) => { - lattice_op(self, v_a, v_b).and_then(|v| Ok(Some(v))) + lattice_op(self.clone(), v_a, v_b).and_then(|v| Ok(Some(v))) } } } @@ -314,7 +314,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> { uok() } (&Some(ref t_a), &Some(ref t_b)) => { - LatticeValue::sub(self, t_a, t_b) + LatticeValue::sub(self.clone(), t_a, t_b) } } } @@ -337,7 +337,7 @@ pub trait TyLatticeDir { } impl<'f> LatticeDir for Lub<'f> { - fn combine_fields<'a>(&'a self) -> CombineFields<'a> { *self.get_ref() } + fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() } fn bnd(&self, b: &Bounds) -> Option { b.ub.clone() } fn with_bnd(&self, b: &Bounds, t: T) -> Bounds { Bounds { ub: Some(t), ..(*b).clone() } @@ -351,7 +351,7 @@ impl<'f> TyLatticeDir for Lub<'f> { } impl<'f> LatticeDir for Glb<'f> { - fn combine_fields<'a>(&'a self) -> CombineFields<'a> { *self.get_ref() } + fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() } fn bnd(&self, b: &Bounds) -> Option { b.lb.clone() } fn with_bnd(&self, b: &Bounds, t: T) -> Bounds { Bounds { lb: Some(t), ..(*b).clone() } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index d42205f0035..d09bbc4253b 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -37,11 +37,11 @@ impl<'f> Combine for Lub<'f> { fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx } fn tag(&self) -> ~str { "lub".to_owned() } fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected } - fn trace(&self) -> TypeTrace { self.get_ref().trace } + fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() } - fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) } - fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) } - fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) } + fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) } + fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) } + fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) } fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { let tcx = self.get_ref().infcx.tcx; @@ -72,7 +72,7 @@ impl<'f> Combine for Lub<'f> { } fn contratys(&self, a: ty::t, b: ty::t) -> cres { - Glb(*self.get_ref()).tys(a, b) + self.glb().tys(a, b) } fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres { @@ -98,7 +98,7 @@ impl<'f> Combine for Lub<'f> { fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres { - return Glb(*self.get_ref()).regions(a, b); + self.glb().regions(a, b) } fn regions(&self, a: ty::Region, b: ty::Region) -> cres { @@ -107,7 +107,7 @@ impl<'f> Combine for Lub<'f> { a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx)); - Ok(self.get_ref().infcx.region_vars.lub_regions(Subtype(self.get_ref().trace), a, b)) + Ok(self.get_ref().infcx.region_vars.lub_regions(Subtype(self.trace()), a, b)) } fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres { @@ -123,10 +123,10 @@ impl<'f> Combine for Lub<'f> { // Instantiate each bound region with a fresh region variable. let (a_with_fresh, a_map) = self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions( - self.get_ref().trace, a); + self.trace(), a); let (b_with_fresh, _) = self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions( - self.get_ref().trace, b); + self.trace(), b); // Collect constraints. let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh)); diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index b2143b7d798..258f286d8f0 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -38,7 +38,7 @@ use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{ValsAndBindings, Root}; use middle::typeck::infer::error_reporting::ErrorReporting; use std::cell::{Cell, RefCell}; -use std::result; +use std::rc::Rc; use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap; @@ -72,7 +72,7 @@ pub struct Bounds { pub type cres = Result; // "combine result" pub type ures = cres<()>; // "unify result" pub type fres = Result; // "fixup result" -pub type CoerceResult = cres>; +pub type CoerceResult = cres>; pub struct InferCtxt<'a> { pub tcx: &'a ty::ctxt, @@ -129,7 +129,7 @@ pub enum TypeOrigin { #[deriving(Clone)] pub enum ValuePairs { Types(ty::expected_found), - TraitRefs(ty::expected_found<@ty::TraitRef>), + TraitRefs(ty::expected_found>), } /// The trace designates the path through inference that we took to @@ -301,7 +301,7 @@ pub fn common_supertype(cx: &InferCtxt, values: Types(expected_found(a_is_expected, a, b)) }; - let result = cx.commit(|| cx.lub(a_is_expected, trace).tys(a, b)); + let result = cx.commit(|| cx.lub(a_is_expected, trace.clone()).tys(a, b)); match result { Ok(t) => t, Err(ref err) => { @@ -375,8 +375,8 @@ pub fn mk_eqty(cx: &InferCtxt, pub fn mk_sub_trait_refs(cx: &InferCtxt, a_is_expected: bool, origin: TypeOrigin, - a: @ty::TraitRef, - b: @ty::TraitRef) + a: Rc, + b: Rc) -> ures { debug!("mk_sub_trait_refs({} <: {})", @@ -385,10 +385,10 @@ pub fn mk_sub_trait_refs(cx: &InferCtxt, cx.commit(|| { let trace = TypeTrace { origin: origin, - values: TraitRefs(expected_found(a_is_expected, a, b)) + values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone())) }; let suber = cx.sub(a_is_expected, trace); - suber.trait_refs(a, b) + suber.trait_refs(&*a, &*b) }) }).to_ures() } @@ -666,8 +666,8 @@ impl<'a> InferCtxt<'a> { pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t { match resolve_type(self, typ, resolve_nested_tvar | resolve_ivar) { - result::Ok(new_type) => new_type, - result::Err(_) => typ + Ok(new_type) => new_type, + Err(_) => typ } } @@ -854,7 +854,7 @@ impl Repr for TypeOrigin { impl SubregionOrigin { pub fn span(&self) -> Span { match *self { - Subtype(a) => a.span(), + Subtype(ref a) => a.span(), InfStackClosure(a) => a, InvokeClosure(a) => a, DerefPointer(a) => a, @@ -877,7 +877,7 @@ impl SubregionOrigin { impl Repr for SubregionOrigin { fn repr(&self, tcx: &ty::ctxt) -> ~str { match *self { - Subtype(a) => format!("Subtype({})", a.repr(tcx)), + Subtype(ref a) => format!("Subtype({})", a.repr(tcx)), InfStackClosure(a) => format!("InfStackClosure({})", a.repr(tcx)), InvokeClosure(a) => format!("InvokeClosure({})", a.repr(tcx)), DerefPointer(a) => format!("DerefPointer({})", a.repr(tcx)), @@ -907,7 +907,7 @@ impl RegionVariableOrigin { AddrOfRegion(a) => a, AddrOfSlice(a) => a, Autoref(a) => a, - Coercion(a) => a.span(), + Coercion(ref a) => a.span(), EarlyBoundRegion(a, _) => a, LateBoundRegion(a, _) => a, BoundRegionInFnType(a, _) => a, @@ -925,7 +925,7 @@ impl Repr for RegionVariableOrigin { AddrOfRegion(a) => format!("AddrOfRegion({})", a.repr(tcx)), AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)), Autoref(a) => format!("Autoref({})", a.repr(tcx)), - Coercion(a) => format!("Coercion({})", a.repr(tcx)), + Coercion(ref a) => format!("Coercion({})", a.repr(tcx)), EarlyBoundRegion(a, b) => format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx)), LateBoundRegion(a, b) => format!("LateBoundRegion({},{})", diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index a446b94027b..bb6d479870b 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -212,7 +212,7 @@ impl<'a> RegionVarBindings<'a> { pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid { let id = self.num_vars(); - self.var_origins.borrow_mut().push(origin); + self.var_origins.borrow_mut().push(origin.clone()); let vid = RegionVid { id: id }; if self.in_snapshot() { self.undo_log.borrow_mut().push(AddVar(vid)); @@ -330,9 +330,9 @@ impl<'a> RegionVarBindings<'a> { _ => { self.combine_vars( - Lub, a, b, origin, + Lub, a, b, origin.clone(), |this, old_r, new_r| - this.make_subregion(origin, old_r, new_r)) + this.make_subregion(origin.clone(), old_r, new_r)) } } } @@ -354,9 +354,9 @@ impl<'a> RegionVarBindings<'a> { _ => { self.combine_vars( - Glb, a, b, origin, + Glb, a, b, origin.clone(), |this, old_r, new_r| - this.make_subregion(origin, new_r, old_r)) + this.make_subregion(origin.clone(), new_r, old_r)) } } } @@ -1150,10 +1150,10 @@ impl<'a> RegionVarBindings<'a> { if !self.is_subregion_of(lower_bound.region, upper_bound.region) { errors.push(SubSupConflict( - *self.var_origins.borrow().get(node_idx.to_uint()), - lower_bound.origin, + self.var_origins.borrow().get(node_idx.to_uint()).clone(), + lower_bound.origin.clone(), lower_bound.region, - upper_bound.origin, + upper_bound.origin.clone(), upper_bound.region)); return; } @@ -1200,10 +1200,10 @@ impl<'a> RegionVarBindings<'a> { Ok(_) => {} Err(_) => { errors.push(SupSupConflict( - *self.var_origins.borrow().get(node_idx.to_uint()), - upper_bound_1.origin, + self.var_origins.borrow().get(node_idx.to_uint()).clone(), + upper_bound_1.origin.clone(), upper_bound_1.region, - upper_bound_2.origin, + upper_bound_2.origin.clone(), upper_bound_2.region)); return; } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 6d02094669c..2c8acd0573b 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -37,15 +37,16 @@ impl<'f> Combine for Sub<'f> { fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx } fn tag(&self) -> ~str { "sub".to_owned() } fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected } - fn trace(&self) -> TypeTrace { self.get_ref().trace } + fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() } - fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) } - fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) } - fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) } + fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) } + fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) } + fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) } fn contratys(&self, a: ty::t, b: ty::t) -> cres { let opp = CombineFields { - a_is_expected: !self.get_ref().a_is_expected,.. *self.get_ref() + a_is_expected: !self.get_ref().a_is_expected, + ..self.get_ref().clone() }; Sub(opp).tys(b, a) } @@ -53,7 +54,8 @@ impl<'f> Combine for Sub<'f> { fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres { let opp = CombineFields { - a_is_expected: !self.get_ref().a_is_expected,.. *self.get_ref() + a_is_expected: !self.get_ref().a_is_expected, + ..self.get_ref().clone() }; Sub(opp).regions(b, a) } @@ -63,7 +65,7 @@ impl<'f> Combine for Sub<'f> { self.tag(), a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx)); - self.get_ref().infcx.region_vars.make_subregion(Subtype(self.get_ref().trace), a, b); + self.get_ref().infcx.region_vars.make_subregion(Subtype(self.trace()), a, b); Ok(a) } @@ -167,7 +169,7 @@ impl<'f> Combine for Sub<'f> { // region variable. let (a_sig, _) = self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions( - self.get_ref().trace, a); + self.trace(), a); // Second, we instantiate each bound region in the supertype with a // fresh concrete region. diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index f78f0a8f273..26f0bc7ec72 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -171,11 +171,11 @@ impl MethodCall { // maps from an expression id that corresponds to a method call to the details // of the method to be invoked -pub type MethodMap = @RefCell>; +pub type MethodMap = RefCell>; -pub type vtable_param_res = @Vec ; +pub type vtable_param_res = Vec; // Resolutions for bounds of all parameters, left to right, for a given path. -pub type vtable_res = @Vec ; +pub type vtable_res = Vec; #[deriving(Clone)] pub enum vtable_origin { @@ -184,7 +184,7 @@ pub enum vtable_origin { from whence comes the vtable, and tys are the type substs. vtable_res is the vtable itself */ - vtable_static(ast::DefId, Vec , vtable_res), + vtable_static(ast::DefId, Vec, vtable_res), /* Dynamic vtable, comes from a parameter that has a bound on it: @@ -215,7 +215,7 @@ impl Repr for vtable_origin { } } -pub type vtable_map = @RefCell>; +pub type vtable_map = RefCell>; // Information about the vtable resolutions for a trait impl. @@ -242,8 +242,6 @@ pub type impl_vtable_map = RefCell>; pub struct CrateCtxt<'a> { // A mapping from method call sites to traits that have that method. trait_map: resolve::TraitMap, - method_map: MethodMap, - vtable_map: vtable_map, tcx: &'a ty::ctxt } @@ -315,25 +313,6 @@ pub fn require_same_types(tcx: &ty::ctxt, } } -// a list of mapping from in-scope-region-names ("isr") to the -// corresponding ty::Region -pub type isr_alist = @Vec<(ty::BoundRegion, ty::Region)>; - -trait get_region<'a, T:'static> { - fn get(&'a self, br: ty::BoundRegion) -> ty::Region; -} - -impl<'a, T:'static> get_region <'a, T> for isr_alist { - fn get(&'a self, br: ty::BoundRegion) -> ty::Region { - let mut region = None; - for isr in self.iter() { - let (isr_br, isr_r) = *isr; - if isr_br == br { region = Some(isr_r); break; } - }; - region.unwrap() - } -} - fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::NodeId, main_span: Span) { @@ -445,13 +424,10 @@ fn check_for_entry_fn(ccx: &CrateCtxt) { pub fn check_crate(tcx: &ty::ctxt, trait_map: resolve::TraitMap, - krate: &ast::Crate) - -> (MethodMap, vtable_map) { + krate: &ast::Crate) { let time_passes = tcx.sess.time_passes(); let ccx = CrateCtxt { trait_map: trait_map, - method_map: @RefCell::new(FnvHashMap::new()), - vtable_map: @RefCell::new(FnvHashMap::new()), tcx: tcx }; @@ -473,5 +449,4 @@ pub fn check_crate(tcx: &ty::ctxt, check_for_entry_fn(&ccx); tcx.sess.abort_if_errors(); - (ccx.method_map, ccx.vtable_map) } diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 907153d6cbe..9e7c221d3c5 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -197,6 +197,7 @@ use arena; use arena::Arena; use middle::ty; use std::fmt; +use std::rc::Rc; use syntax::ast; use syntax::ast_map; use syntax::ast_util; @@ -254,7 +255,7 @@ struct TermsContext<'a> { tcx: &'a ty::ctxt, arena: &'a Arena, - empty_variances: @ty::ItemVariances, + empty_variances: Rc, // Maps from the node id of a type/generic parameter to the // corresponding inferred index. @@ -286,9 +287,11 @@ fn determine_parameters_to_be_inferred<'a>(tcx: &'a ty::ctxt, // cache and share the variance struct used for items with // no type/region parameters - empty_variances: @ty::ItemVariances { self_param: None, - type_params: OwnedSlice::empty(), - region_params: OwnedSlice::empty() } + empty_variances: Rc::new(ty::ItemVariances { + self_param: None, + type_params: OwnedSlice::empty(), + region_params: OwnedSlice::empty() + }) }; visit::walk_crate(&mut terms_cx, krate, ()); @@ -362,7 +365,7 @@ impl<'a> Visitor<()> for TermsContext<'a> { if self.num_inferred() == inferreds_on_entry { let newly_added = self.tcx.item_variance_map.borrow_mut().insert( ast_util::local_def(item.id), - self.empty_variances); + self.empty_variances.clone()); assert!(newly_added); } @@ -1016,7 +1019,7 @@ impl<'a> SolveContext<'a> { } let newly_added = tcx.item_variance_map.borrow_mut() - .insert(item_def_id, @item_variances); + .insert(item_def_id, Rc::new(item_variances)); assert!(newly_added); } } diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index ac4db178a00..7d7d5d16d74 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -16,12 +16,13 @@ use std::io; use syntax::ast; pub type FnvHashMap = HashMap; +pub type FnvHashSet = HashSet; pub type NodeMap = FnvHashMap; pub type DefIdMap = FnvHashMap; -pub type NodeSet = HashSet; -pub type DefIdSet = HashSet; +pub type NodeSet = FnvHashSet; +pub type DefIdSet = FnvHashSet; // Hacks to get good names pub mod FnvHashMap { @@ -31,6 +32,13 @@ pub mod FnvHashMap { HashMap::with_hasher(super::FnvHasher) } } +pub mod FnvHashSet { + use std::hash::Hash; + use collections::HashSet; + pub fn new + TotalEq>() -> super::FnvHashSet { + HashSet::with_hasher(super::FnvHasher) + } +} pub mod NodeMap { pub fn new() -> super::NodeMap { super::FnvHashMap::new() @@ -42,15 +50,13 @@ pub mod DefIdMap { } } pub mod NodeSet { - use collections::HashSet; pub fn new() -> super::NodeSet { - HashSet::with_hasher(super::FnvHasher) + super::FnvHashSet::new() } } pub mod DefIdSet { - use collections::HashSet; pub fn new() -> super::DefIdSet { - HashSet::with_hasher(super::FnvHasher) + super::FnvHashSet::new() } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1d98cc143de..316b5c6a45a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,7 +9,6 @@ // except according to those terms. -use metadata::encoder; use middle::ty::{ReSkolemized, ReVar}; use middle::ty::{BoundRegion, BrAnon, BrNamed}; use middle::ty::{BrFresh, ctxt}; @@ -23,6 +22,7 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer}; use middle::ty; use middle::typeck; +use std::rc::Rc; use std::strbuf::StrBuf; use syntax::abi; use syntax::ast_map; @@ -469,7 +469,7 @@ pub fn parameterized(cx: &ctxt, } pub fn ty_to_short_str(cx: &ctxt, typ: t) -> ~str { - let mut s = encoder::encoded_ty(cx, typ); + let mut s = typ.repr(cx); if s.len() >= 32u { s = s.slice(0u, 32u).to_owned(); } return s; } @@ -498,6 +498,12 @@ impl Repr for () { } } +impl Repr for Rc { + fn repr(&self, tcx: &ctxt) -> ~str { + (&**self).repr(tcx) + } +} + impl Repr for @T { fn repr(&self, tcx: &ctxt) -> ~str { (&**self).repr(tcx) @@ -888,7 +894,7 @@ impl Repr for Span { } } -impl UserString for @A { +impl UserString for Rc { fn user_string(&self, tcx: &ctxt) -> ~str { let this: &A = &**self; this.user_string(tcx) diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 792673e3298..693407b854f 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -9,6 +9,7 @@ // except according to those terms. use std::mem; +use std::slice; use std::vec; /// A vector type optimized for cases where the size is almost always 0 or 1 @@ -61,6 +62,14 @@ impl SmallVector { SmallVector { repr: Many(vs) } } + pub fn as_slice<'a>(&'a self) -> &'a [T] { + match self.repr { + Zero => &[], + One(ref v) => slice::ref_slice(v), + Many(ref vs) => vs.as_slice() + } + } + pub fn push(&mut self, v: T) { match self.repr { Zero => self.repr = One(v),