diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 901afc1d1904e..5f785fefa1241 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -146,7 +146,7 @@ enum_from_u32! { tag_table_closure_kinds = 0x65, tag_table_upvar_capture_map = 0x66, tag_table_capture_modes = 0x67, - tag_table_object_cast_map = 0x68, + // GAP 0x68 tag_table_const_qualif = 0x69, tag_table_cast_kinds = 0x6a, } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index f834076e8eab5..47aad257d156f 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -297,15 +297,6 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, decoder::get_impl_trait(&*cdata, def.node, tcx) } -// Given a def_id for an impl, return information about its vtables -pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>, - def: ast::DefId) - -> ty::vtable_res<'tcx> { - let cstore = &tcx.sess.cstore; - let cdata = cstore.get_crate_data(def.krate); - decoder::get_impl_vtables(&*cdata, def.node, tcx) -} - pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) -> Vec<(cstore::NativeLibraryKind, String)> { let cdata = cstore.get_crate_data(crate_num); @@ -389,6 +380,11 @@ pub fn is_const_fn(cstore: &cstore::CStore, did: ast::DefId) -> bool { decoder::is_const_fn(&*cdata, did.node) } +pub fn is_impl(cstore: &cstore::CStore, did: ast::DefId) -> bool { + let cdata = cstore.get_crate_data(did.krate); + decoder::is_impl(&*cdata, did.node) +} + pub fn get_stability(cstore: &cstore::CStore, def: ast::DefId) -> Option { @@ -396,8 +392,8 @@ pub fn get_stability(cstore: &cstore::CStore, decoder::get_stability(&*cdata, def.node) } -pub fn is_staged_api(cstore: &cstore::CStore, def: ast::DefId) -> bool { - let cdata = cstore.get_crate_data(def.krate); +pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool { + let cdata = cstore.get_crate_data(krate); let attrs = decoder::get_crate_attributes(cdata.data()); for attr in &attrs { if &attr.name()[..] == "staged_api" { @@ -414,11 +410,6 @@ pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId) decoder::get_repr_attrs(&*cdata, def.node) } -pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool { - let cdata = cstore.get_crate_data(def.krate); - decoder::is_associated_type(&*cdata, def.node) -} - pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) -> bool { let cdata = cstore.get_crate_data(trait_def_id.krate); decoder::is_defaulted_trait(&*cdata, trait_def_id.node) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index ee5fd0202d69e..42dcc9661ca2d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -30,7 +30,6 @@ use middle::lang_items; use middle::subst; use middle::ty::{ImplContainer, TraitContainer}; use middle::ty::{self, Ty}; -use middle::astencode::vtable_decoder_helpers; use util::nodemap::FnvHashMap; use std::cell::{Cell, RefCell}; @@ -522,18 +521,6 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd, } } -pub fn get_impl_vtables<'tcx>(cdata: Cmd, - id: ast::NodeId, - tcx: &ty::ctxt<'tcx>) - -> ty::vtable_res<'tcx> -{ - let item_doc = lookup_item(id, cdata.data()); - let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables); - let mut decoder = reader::Decoder::new(vtables_doc); - decoder.read_vtable_res(tcx, cdata) -} - - pub fn get_symbol(data: &[u8], id: ast::NodeId) -> String { return item_symbol(lookup_item(id, data)); } @@ -1546,6 +1533,14 @@ pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool { } } +pub fn is_impl(cdata: Cmd, id: ast::NodeId) -> bool { + let item_doc = lookup_item(id, cdata.data()); + match item_family(item_doc) { + Impl => true, + _ => false, + } +} + fn doc_generics<'tcx>(base_doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd, @@ -1623,14 +1618,6 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, ty::GenericPredicates { predicates: predicates } } -pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool { - let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items); - match maybe_find_item(id, items) { - None => false, - Some(item) => item_sort(item) == Some('t'), - } -} - pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool { let trait_doc = lookup_item(trait_id, cdata.data()); assert!(item_family(trait_doc) == Family::Trait); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 88e0b739a0fbb..0908ffd249fe4 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -999,7 +999,7 @@ fn encode_extension_implementations(ecx: &EncodeContext, }); } -fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option) { +fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) { stab_opt.map(|stab| { rbml_w.start_tag(tag_items_data_item_stability); stab.encode(rbml_w).unwrap(); @@ -1215,11 +1215,11 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(rbml_w, item.ident.name); encode_unsafety(rbml_w, unsafety); - let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id); + let trait_ref = ty::impl_trait_ref(tcx, local_def(item.id)).unwrap(); encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); rbml_w.end_tag(); } - ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => { + ast::ItemImpl(unsafety, polarity, _, _, ref ty, ref ast_items) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); @@ -1269,8 +1269,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } rbml_w.end_tag(); } - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id); + if let Some(trait_ref) = ty::impl_trait_ref(tcx, local_def(item.id)) { encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); } encode_path(rbml_w, path.clone()); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index b7e57819b93b4..fda57c9dc610a 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -696,19 +696,6 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) { pub trait vtable_decoder_helpers<'tcx> { fn read_vec_per_param_space(&mut self, f: F) -> VecPerParamSpace where F: FnMut(&mut Self) -> T; - fn read_vtable_res_with_key(&mut self, - tcx: &ty::ctxt<'tcx>, - cdata: &cstore::crate_metadata) - -> (u32, ty::vtable_res<'tcx>); - fn read_vtable_res(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) - -> ty::vtable_res<'tcx>; - fn read_vtable_param_res(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) - -> ty::vtable_param_res<'tcx>; - fn read_vtable_origin(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) - -> ty::vtable_origin<'tcx>; } impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { @@ -720,85 +707,6 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { let fns = self.read_to_vec(|this| Ok(f(this))).unwrap(); VecPerParamSpace::new(types, selfs, fns) } - - fn read_vtable_res_with_key(&mut self, - tcx: &ty::ctxt<'tcx>, - cdata: &cstore::crate_metadata) - -> (u32, ty::vtable_res<'tcx>) { - self.read_struct("VtableWithKey", 2, |this| { - let autoderef = this.read_struct_field("autoderef", 0, |this| { - Decodable::decode(this) - }).unwrap(); - Ok((autoderef, this.read_struct_field("vtable_res", 1, |this| { - Ok(this.read_vtable_res(tcx, cdata)) - }).unwrap())) - }).unwrap() - } - - fn read_vtable_res(&mut self, - tcx: &ty::ctxt<'tcx>, - cdata: &cstore::crate_metadata) - -> ty::vtable_res<'tcx> - { - self.read_vec_per_param_space( - |this| this.read_vtable_param_res(tcx, cdata)) - } - - fn read_vtable_param_res(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) - -> ty::vtable_param_res<'tcx> { - self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata))) - .unwrap().into_iter().collect() - } - - fn read_vtable_origin(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) - -> ty::vtable_origin<'tcx> { - self.read_enum("vtable_origin", |this| { - this.read_enum_variant(&["vtable_static", - "vtable_param", - "vtable_error", - "vtable_closure"], - |this, i| { - Ok(match i { - 0 => { - ty::vtable_static( - this.read_enum_variant_arg(0, |this| { - Ok(this.read_def_id_nodcx(cdata)) - }).unwrap(), - this.read_enum_variant_arg(1, |this| { - Ok(this.read_substs_nodcx(tcx, cdata)) - }).unwrap(), - this.read_enum_variant_arg(2, |this| { - Ok(this.read_vtable_res(tcx, cdata)) - }).unwrap() - ) - } - 1 => { - ty::vtable_param( - this.read_enum_variant_arg(0, |this| { - Decodable::decode(this) - }).unwrap(), - this.read_enum_variant_arg(1, |this| { - this.read_uint() - }).unwrap() - ) - } - 2 => { - ty::vtable_closure( - this.read_enum_variant_arg(0, |this| { - Ok(this.read_def_id_nodcx(cdata)) - }).unwrap() - ) - } - 3 => { - ty::vtable_error - } - _ => panic!("bad enum variant") - }) - }) - }).unwrap() - } } // ___________________________________________________________________________ @@ -1209,13 +1117,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) { - rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| { - rbml_w.id(id); - rbml_w.emit_trait_ref(ecx, &trait_ref.0); - }) - } - if let Some(adjustment) = tcx.adjustments.borrow().get(&id) { match *adjustment { ty::AdjustDerefRef(ref adj) => { @@ -1800,11 +1701,6 @@ fn decode_side_tables(dcx: &DecodeContext, }; dcx.tcx.method_map.borrow_mut().insert(method_call, method); } - c::tag_table_object_cast_map => { - let trait_ref = val_dsr.read_poly_trait_ref(dcx); - dcx.tcx.object_cast_map.borrow_mut() - .insert(id, trait_ref); - } c::tag_table_adjustments => { let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx); dcx.tcx.adjustments.borrow_mut().insert(id, adj); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d75dc861e8330..b29e40d2d5ec6 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -23,46 +23,47 @@ use syntax::{attr, visit}; use syntax::ast; use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant}; use syntax::ast::{Item, Generics, StructField}; -use syntax::ast_util::is_local; +use syntax::ast_util::{is_local, local_def}; use syntax::attr::{Stability, AttrMetaMethods}; use syntax::visit::{FnKind, Visitor}; use syntax::feature_gate::emit_feature_err; -use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap}; +use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; use util::ppaux::Repr; use std::mem::replace; /// A stability index, giving the stability level for items and methods. -pub struct Index { - // Indicates whether this crate has #![feature(staged_api)] - staged_api: bool, - // stability for crate-local items; unmarked stability == no entry - local: NodeMap, - // cache for extern-crate items; unmarked stability == entry with None - extern_cache: DefIdMap> +pub struct Index<'tcx> { + /// This is mostly a cache, except the stabilities of local items + /// are filled by the annotator. + map: DefIdMap>, + + /// Maps for each crate whether it is part of the staged API. + staged_api: FnvHashMap } // A private tree-walker for producing an Index. -struct Annotator<'a> { - sess: &'a Session, - index: &'a mut Index, - parent: Option, +struct Annotator<'a, 'tcx: 'a> { + tcx: &'a ty::ctxt<'tcx>, + index: &'a mut Index<'tcx>, + parent: Option<&'tcx Stability>, export_map: &'a PublicItems, } -impl<'a> Annotator<'a> { +impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. fn annotate(&mut self, id: NodeId, use_parent: bool, attrs: &Vec, item_sp: Span, f: F, required: bool) where F: FnOnce(&mut Annotator), { - if self.index.staged_api { + if self.index.staged_api[&ast::LOCAL_CRATE] { debug!("annotate(id = {:?}, attrs = {:?})", id, attrs); - match attr::find_stability(self.sess.diagnostic(), attrs, item_sp) { + match attr::find_stability(self.tcx.sess.diagnostic(), attrs, item_sp) { Some(stab) => { debug!("annotate: found {:?}", stab); - self.index.local.insert(id, stab.clone()); + let stab = self.tcx.intern_stability(stab); + self.index.map.insert(local_def(id), Some(stab)); // Don't inherit #[stable(feature = "rust1", since = "1.0.0")] if stab.level != attr::Stable { @@ -77,13 +78,14 @@ impl<'a> Annotator<'a> { debug!("annotate: not found, use_parent = {:?}, parent = {:?}", use_parent, self.parent); if use_parent { - if let Some(stab) = self.parent.clone() { - self.index.local.insert(id, stab); - } else if self.index.staged_api && required + if let Some(stab) = self.parent { + self.index.map.insert(local_def(id), Some(stab)); + } else if self.index.staged_api[&ast::LOCAL_CRATE] && required && self.export_map.contains(&id) - && !self.sess.opts.test { - self.sess.span_err(item_sp, - "This node does not have a stability attribute"); + && !self.tcx.sess.opts.test { + self.tcx.sess.span_err(item_sp, + "This node does not \ + have a stability attribute"); } } f(self); @@ -95,7 +97,7 @@ impl<'a> Annotator<'a> { let tag = attr.name(); if tag == "unstable" || tag == "stable" || tag == "deprecated" { attr::mark_used(attr); - self.sess.span_err(attr.span(), + self.tcx.sess.span_err(attr.span(), "stability attributes may not be used outside \ of the standard library"); } @@ -105,7 +107,7 @@ impl<'a> Annotator<'a> { } } -impl<'a, 'v> Visitor<'v> for Annotator<'a> { +impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { fn visit_item(&mut self, i: &Item) { // FIXME (#18969): the following is a hack around the fact // that we cannot currently annotate the stability of @@ -168,11 +170,11 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> { } } -impl Index { +impl<'tcx> Index<'tcx> { /// Construct the stability index for a crate being compiled. - pub fn build(&mut self, sess: &Session, krate: &Crate, export_map: &PublicItems) { + pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, krate: &Crate, export_map: &PublicItems) { let mut annotator = Annotator { - sess: sess, + tcx: tcx, index: self, parent: None, export_map: export_map, @@ -182,22 +184,23 @@ impl Index { } pub fn new(krate: &Crate) -> Index { - let mut staged_api = false; + let mut is_staged_api = false; for attr in &krate.attrs { if &attr.name()[..] == "staged_api" { match attr.node.value.node { ast::MetaWord(_) => { attr::mark_used(attr); - staged_api = true; + is_staged_api = true; } _ => (/*pass*/) } } } + let mut staged_api = FnvHashMap(); + staged_api.insert(ast::LOCAL_CRATE, is_staged_api); Index { staged_api: staged_api, - local: NodeMap(), - extern_cache: DefIdMap() + map: DefIdMap(), } } } @@ -232,13 +235,13 @@ struct Checker<'a, 'tcx: 'a> { } impl<'a, 'tcx> Checker<'a, 'tcx> { - fn check(&mut self, id: ast::DefId, span: Span, stab: &Option) { + fn check(&mut self, id: ast::DefId, span: Span, stab: &Option<&Stability>) { // Only the cross-crate scenario matters when checking unstable APIs let cross_crate = !is_local(id); if !cross_crate { return } match *stab { - Some(Stability { level: attr::Unstable, ref feature, ref reason, .. }) => { + Some(&Stability { level: attr::Unstable, ref feature, ref reason, .. }) => { self.used_features.insert(feature.clone(), attr::Unstable); if !self.active_features.contains(feature) { @@ -252,7 +255,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { &feature, span, &msg); } } - Some(Stability { level, ref feature, .. }) => { + Some(&Stability { level, ref feature, .. }) => { self.used_features.insert(feature.clone(), level); // Stable APIs are always ok to call and deprecated APIs are @@ -312,7 +315,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> { /// Helper for discovering nodes to check for stability pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool, - cb: &mut FnMut(ast::DefId, Span, &Option)) { + cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { match item.node { ast::ItemExternCrate(_) => { // compiler-generated `extern crate` items have a dummy span. @@ -349,7 +352,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool, /// Helper for discovering nodes to check for stability pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, - cb: &mut FnMut(ast::DefId, Span, &Option)) { + cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { let span; let id = match e.node { ast::ExprMethodCall(i, _, _) => { @@ -458,7 +461,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, } pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId, - cb: &mut FnMut(ast::DefId, Span, &Option)) { + cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) { Some(def::DefPrimTy(..)) => {} Some(def) => { @@ -470,7 +473,7 @@ pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId, } pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat, - cb: &mut FnMut(ast::DefId, Span, &Option)) { + cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { debug!("check_pat(pat = {:?})", pat); if is_internal(tcx, pat.span) { return; } @@ -511,7 +514,7 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat, } fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span, - cb: &mut FnMut(ast::DefId, Span, &Option)) { + cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { if !is_staged_api(tcx, id) { return } if is_internal(tcx, span) { return } let ref stability = lookup(tcx, id); @@ -528,20 +531,27 @@ fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool { if trait_method_id != id => { is_staged_api(tcx, trait_method_id) } - _ if is_local(id) => { - tcx.stability.borrow().staged_api - } _ => { - csearch::is_staged_api(&tcx.sess.cstore, id) + *tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with( + || csearch::is_staged_api(&tcx.sess.cstore, id.krate)) } } } /// Lookup the stability for a node, loading external crate /// metadata as necessary. -pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { - debug!("lookup(id={})", - id.repr(tcx)); +pub fn lookup<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stability> { + if let Some(st) = tcx.stability.borrow().map.get(&id) { + return *st; + } + + let st = lookup_uncached(tcx, id); + tcx.stability.borrow_mut().map.insert(id, st); + st +} + +fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stability> { + debug!("lookup(id={})", id.repr(tcx)); // is this definition the implementation of a trait method? match ty::trait_item_of_item(tcx, id) { @@ -553,25 +563,23 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { } let item_stab = if is_local(id) { - tcx.stability.borrow().local.get(&id.node).cloned() + None // The stability cache is filled partially lazily } else { - let stab = csearch::get_stability(&tcx.sess.cstore, id); - let mut index = tcx.stability.borrow_mut(); - (*index).extern_cache.insert(id, stab.clone()); - stab + csearch::get_stability(&tcx.sess.cstore, id).map(|st| tcx.intern_stability(st)) }; item_stab.or_else(|| { - if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) { - // FIXME (#18969): for the time being, simply use the - // stability of the trait to determine the stability of any - // unmarked impls for it. See FIXME above for more details. - - debug!("lookup: trait_id={:?}", trait_id); - lookup(tcx, trait_id) - } else { - None + if ty::is_impl(tcx, id) { + if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) { + // FIXME (#18969): for the time being, simply use the + // stability of the trait to determine the stability of any + // unmarked impls for it. See FIXME above for more details. + + debug!("lookup: trait_id={:?}", trait_id); + return lookup(tcx, trait_id); + } } + None }) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 5ff6ee3c8b081..2ccbb0c5c103e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -32,7 +32,6 @@ pub use self::ImplOrTraitItem::*; pub use self::BoundRegion::*; pub use self::sty::*; pub use self::IntVarValue::*; -pub use self::vtable_origin::*; pub use self::MethodOrigin::*; pub use self::CopyImplementationError::*; @@ -402,12 +401,6 @@ pub enum CustomCoerceUnsized { Struct(usize) } -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Debug)] -pub struct param_index { - pub space: subst::ParamSpace, - pub index: usize -} - #[derive(Clone, Debug)] pub enum MethodOrigin<'tcx> { // fully statically resolved method @@ -510,50 +503,6 @@ impl MethodCall { // of the method to be invoked pub type MethodMap<'tcx> = RefCell>>; -pub type vtable_param_res<'tcx> = Vec>; - -// Resolutions for bounds of all parameters, left to right, for a given path. -pub type vtable_res<'tcx> = VecPerParamSpace>; - -#[derive(Clone)] -pub enum vtable_origin<'tcx> { - /* - Statically known vtable. def_id gives the impl item - from whence comes the vtable, and tys are the type substs. - vtable_res is the vtable itself. - */ - vtable_static(ast::DefId, subst::Substs<'tcx>, vtable_res<'tcx>), - - /* - Dynamic vtable, comes from a parameter that has a bound on it: - fn foo(a: T) -- a's vtable would have a - vtable_param origin - - The first argument is the param index (identifying T in the example), - and the second is the bound number (identifying baz) - */ - vtable_param(param_index, usize), - - /* - Vtable automatically generated for a closure. The def ID is the - ID of the closure expression. - */ - vtable_closure(ast::DefId), - - /* - Asked to determine the vtable for ty_err. This is the value used - for the vtables of `Self` in a virtual call like `foo.bar()` - where `foo` is of object type. The same value is also used when - type errors occur. - */ - vtable_error, -} - - -// For every explicit cast into an object type, maps from the cast -// expr to the associated trait ref. -pub type ObjectCastMap<'tcx> = RefCell>>; - // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -601,9 +550,10 @@ pub struct CtxtArenas<'tcx> { substs: TypedArena>, bare_fn: TypedArena>, region: TypedArena, + stability: TypedArena, // references - trait_defs: TypedArena> + trait_defs: TypedArena>, } impl<'tcx> CtxtArenas<'tcx> { @@ -613,6 +563,7 @@ impl<'tcx> CtxtArenas<'tcx> { substs: TypedArena::new(), bare_fn: TypedArena::new(), region: TypedArena::new(), + stability: TypedArena::new(), trait_defs: TypedArena::new() } @@ -654,6 +605,7 @@ pub struct ctxt<'tcx> { substs_interner: RefCell, &'tcx Substs<'tcx>>>, bare_fn_interner: RefCell, &'tcx BareFnTy<'tcx>>>, region_interner: RefCell>, + stability_interner: RefCell>, /// Common types, pre-interned for your convenience. pub types: CommonTypes<'tcx>, @@ -692,9 +644,7 @@ pub struct ctxt<'tcx> { /// A cache for the trait_items() routine pub trait_items_cache: RefCell>>>>, - pub impl_trait_cache: RefCell>>>, - - pub impl_trait_refs: RefCell>>, + pub impl_trait_refs: RefCell>>>, pub trait_defs: RefCell>>, /// Maps from the def-id of an item (trait/struct/enum/fn) to its @@ -709,15 +659,10 @@ pub struct ctxt<'tcx> { /// additional acyclicity requirements). pub super_predicates: RefCell>>, - /// Maps from node-id of a trait object cast (like `foo as - /// Box`) to the trait reference. - pub object_cast_map: ObjectCastMap<'tcx>, - pub map: ast_map::Map<'tcx>, pub freevars: RefCell, pub tcache: RefCell>>, pub rcache: RefCell>>, - pub short_names_cache: RefCell, String>>, pub tc_cache: RefCell, TypeContents>>, pub ast_ty_to_ty_cache: RefCell>>, pub enum_var_cache: RefCell>>>>>, @@ -801,10 +746,7 @@ pub struct ctxt<'tcx> { pub transmute_restrictions: RefCell>>, /// Maps any item's def-id to its stability index. - pub stability: RefCell, - - /// Maps def IDs to true if and only if they're associated types. - pub associated_types: RefCell>, + pub stability: RefCell>, /// Caches the results of trait selection. This cache is used /// for things that do not have to do with the parameters in scope. @@ -847,6 +789,16 @@ impl<'tcx> ctxt<'tcx> { interned } + pub fn intern_stability(&self, stab: attr::Stability) -> &'tcx attr::Stability { + if let Some(st) = self.stability_interner.borrow().get(&stab) { + return st; + } + + let interned = self.arenas.stability.alloc(stab); + self.stability_interner.borrow_mut().insert(interned, interned); + interned + } + pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) { self.free_region_maps.borrow_mut() .insert(id, map); @@ -948,6 +900,7 @@ impl<'tcx> ctxt<'tcx> { println!("Substs interner: #{}", self.substs_interner.borrow().len()); println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len()); println!("Region interner: #{}", self.region_interner.borrow().len()); + println!("Stability interner: #{}", self.stability_interner.borrow().len()); } } @@ -2753,7 +2706,7 @@ pub fn mk_ctxt<'tcx>(s: Session, freevars: RefCell, region_maps: RegionMaps, lang_items: middle::lang_items::LanguageItems, - stability: stability::Index) -> ctxt<'tcx> + stability: stability::Index<'tcx>) -> ctxt<'tcx> { let mut interner = FnvHashMap(); let common_types = CommonTypes::new(&arenas.type_, &mut interner); @@ -2764,6 +2717,7 @@ pub fn mk_ctxt<'tcx>(s: Session, substs_interner: RefCell::new(FnvHashMap()), bare_fn_interner: RefCell::new(FnvHashMap()), region_interner: RefCell::new(FnvHashMap()), + stability_interner: RefCell::new(FnvHashMap()), types: common_types, named_region_map: named_region_map, region_maps: region_maps, @@ -2774,23 +2728,20 @@ pub fn mk_ctxt<'tcx>(s: Session, def_map: def_map, node_types: RefCell::new(FnvHashMap()), item_substs: RefCell::new(NodeMap()), - impl_trait_refs: RefCell::new(NodeMap()), + impl_trait_refs: RefCell::new(DefIdMap()), trait_defs: RefCell::new(DefIdMap()), predicates: RefCell::new(DefIdMap()), super_predicates: RefCell::new(DefIdMap()), - object_cast_map: RefCell::new(NodeMap()), map: map, freevars: freevars, tcache: RefCell::new(DefIdMap()), rcache: RefCell::new(FnvHashMap()), - short_names_cache: RefCell::new(FnvHashMap()), tc_cache: RefCell::new(FnvHashMap()), ast_ty_to_ty_cache: RefCell::new(NodeMap()), enum_var_cache: RefCell::new(DefIdMap()), impl_or_trait_items: RefCell::new(DefIdMap()), trait_item_def_ids: RefCell::new(DefIdMap()), trait_items_cache: RefCell::new(DefIdMap()), - impl_trait_cache: RefCell::new(DefIdMap()), ty_param_defs: RefCell::new(NodeMap()), adjustments: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FnvHashMap()), @@ -2816,7 +2767,6 @@ pub fn mk_ctxt<'tcx>(s: Session, node_lint_levels: RefCell::new(FnvHashMap()), transmute_restrictions: RefCell::new(Vec::new()), stability: RefCell::new(stability), - associated_types: RefCell::new(DefIdMap()), selection_cache: traits::SelectionCache::new(), repr_hint_cache: RefCell::new(DefIdMap()), type_impls_copy_cache: RefCell::new(HashMap::new()), @@ -4305,17 +4255,9 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) } pub fn type_is_trait(ty: Ty) -> bool { - type_trait_info(ty).is_some() -} - -pub fn type_trait_info<'tcx>(ty: Ty<'tcx>) -> Option<&'tcx TyTrait<'tcx>> { match ty.sty { - ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) | ty_ptr(mt { ty, ..}) => match ty.sty { - ty_trait(ref t) => Some(&**t), - _ => None - }, - ty_trait(ref t) => Some(&**t), - _ => None + ty_trait(..) => true, + _ => false } } @@ -4506,16 +4448,6 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>, } } -pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) - -> ty::TraitRef<'tcx> { - match cx.impl_trait_refs.borrow().get(&id) { - Some(ty) => *ty, - None => cx.sess.bug( - &format!("impl_id_to_trait_ref: no trait ref for impl `{}`", - cx.map.node_to_string(id))) - } -} - pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> { match node_id_to_type_opt(cx, id) { Some(ty) => ty, @@ -5310,12 +5242,12 @@ pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) /// the future). fn lookup_locally_or_in_crate_store(descr: &str, def_id: ast::DefId, - map: &mut DefIdMap, + map: &RefCell>, load_external: F) -> V where V: Clone, F: FnOnce() -> V, { - match map.get(&def_id).cloned() { + match map.borrow().get(&def_id).cloned() { Some(v) => { return v; } None => { } } @@ -5324,7 +5256,7 @@ fn lookup_locally_or_in_crate_store(descr: &str, panic!("No def'n found for {:?} in tcx.{}", def_id, descr); } let v = load_external(); - map.insert(def_id, v.clone()); + map.borrow_mut().insert(def_id, v.clone()); v } @@ -5390,33 +5322,9 @@ pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> ImplOrTraitItem<'tcx> { - lookup_locally_or_in_crate_store("impl_or_trait_items", - id, - &mut *cx.impl_or_trait_items - .borrow_mut(), - || { - csearch::get_impl_or_trait_item(cx, id) - }) -} - -/// Returns true if the given ID refers to an associated type and false if it -/// refers to anything else. -pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool { - memoized(&cx.associated_types, id, |id: ast::DefId| { - if id.krate == ast::LOCAL_CRATE { - match cx.impl_or_trait_items.borrow().get(&id) { - Some(ref item) => { - match **item { - TypeTraitItem(_) => true, - _ => false, - } - } - None => false, - } - } else { - csearch::is_associated_type(&cx.sess.cstore, id) - } - }) + lookup_locally_or_in_crate_store( + "impl_or_trait_items", id, &cx.impl_or_trait_items, + || csearch::get_impl_or_trait_item(cx, id)) } /// Returns the parameter index that the given associated type corresponds to. @@ -5434,34 +5342,33 @@ pub fn associated_type_parameter_index(cx: &ctxt, pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId) -> Rc> { - lookup_locally_or_in_crate_store("trait_item_def_ids", - id, - &mut *cx.trait_item_def_ids.borrow_mut(), - || { - Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id)) - }) + lookup_locally_or_in_crate_store( + "trait_item_def_ids", id, &cx.trait_item_def_ids, + || Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id))) } +/// Returns the trait-ref corresponding to a given impl, or None if it is +/// an inherent impl. pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Option> { - memoized(&cx.impl_trait_cache, id, |id: ast::DefId| { - if id.krate == ast::LOCAL_CRATE { - debug!("(impl_trait_ref) searching for trait impl {:?}", id); - if let Some(ast_map::NodeItem(item)) = cx.map.find(id.node) { - match item.node { - ast::ItemImpl(_, _, _, Some(_), _, _) | - ast::ItemDefaultImpl(..) => { - Some(ty::impl_id_to_trait_ref(cx, id.node)) - } - _ => None - } - } else { - None - } + -> Option> +{ + lookup_locally_or_in_crate_store( + "impl_trait_refs", id, &cx.impl_trait_refs, + || csearch::get_impl_trait(cx, id)) +} + +/// Returns whether this DefId refers to an impl +pub fn is_impl<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> bool { + if id.krate == ast::LOCAL_CRATE { + if let Some(ast_map::NodeItem( + &ast::Item { node: ast::ItemImpl(..), .. })) = cx.map.find(id.node) { + true } else { - csearch::get_impl_trait(cx, id) + false } - }) + } else { + csearch::is_impl(&cx.sess.cstore, id) + } } pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId { @@ -5944,37 +5851,35 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> TypeScheme<'tcx> { lookup_locally_or_in_crate_store( - "tcache", did, &mut *cx.tcache.borrow_mut(), + "tcache", did, &cx.tcache, || csearch::get_type(cx, did)) } /// Given the did of a trait, returns its canonical trait ref. pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> &'tcx TraitDef<'tcx> { - memoized(&cx.trait_defs, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did)) - }) + lookup_locally_or_in_crate_store( + "trait_defs", did, &cx.trait_defs, + || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did)) + ) } /// Given the did of an item, returns its full set of predicates. pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> GenericPredicates<'tcx> { - memoized(&cx.predicates, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - csearch::get_predicates(cx, did) - }) + lookup_locally_or_in_crate_store( + "predicates", did, &cx.predicates, + || csearch::get_predicates(cx, did)) } /// Given the did of a trait, returns its superpredicates. pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> GenericPredicates<'tcx> { - memoized(&cx.super_predicates, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - csearch::get_super_predicates(cx, did) - }) + lookup_locally_or_in_crate_store( + "super_predicates", did, &cx.super_predicates, + || csearch::get_super_predicates(cx, did)) } pub fn predicates<'tcx>( @@ -6344,7 +6249,7 @@ pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>, 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(), + "item_variance_map", item_id, &tcx.item_variance_map, || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id))) } @@ -7223,32 +7128,6 @@ impl<'tcx> Repr<'tcx> for ty::Predicate<'tcx> { } } -impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> { - fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { - match *self { - vtable_static(def_id, ref tys, ref vtable_res) => { - format!("vtable_static({:?}:{}, {}, {})", - def_id, - ty::item_path_str(tcx, def_id), - tys.repr(tcx), - vtable_res.repr(tcx)) - } - - vtable_param(x, y) => { - format!("vtable_param({:?}, {})", x, y) - } - - vtable_closure(def_id) => { - format!("vtable_closure({:?})", def_id) - } - - vtable_error => { - format!("vtable_error") - } - } - } -} - pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>, method: &ty::Method<'tcx>) diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 19a82e3f35492..6f098a53238b6 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -336,27 +336,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::vtable_origin<'tcx> { - match *self { - ty::vtable_static(def_id, ref substs, ref origins) => { - let r_substs = substs.fold_with(folder); - let r_origins = origins.fold_with(folder); - ty::vtable_static(def_id, r_substs, r_origins) - } - ty::vtable_param(n, b) => { - ty::vtable_param(n, b) - } - ty::vtable_closure(def_id) => { - ty::vtable_closure(def_id) - } - ty::vtable_error => { - ty::vtable_error - } - } - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds { fn fold_with>(&self, _folder: &mut F) -> ty::BuiltinBounds { *self diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7c49f1e01d85e..13dec30e0a016 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -653,7 +653,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session, // Do not move this check past lint time(time_passes, "stability index", (), |_| - ty_cx.stability.borrow_mut().build(&ty_cx.sess, krate, &public_items)); + ty_cx.stability.borrow_mut().build(&ty_cx, krate, &public_items)); time(time_passes, "intrinsic checking", (), |_| middle::intrinsicck::check_crate(&ty_cx)); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e9db80b71ea01..62726a3ae7b64 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1796,20 +1796,21 @@ declare_lint! { pub struct Stability; impl Stability { - fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option) { + fn lint(&self, cx: &Context, _id: ast::DefId, + span: Span, stability: &Option<&attr::Stability>) { // Deprecated attributes apply in-crate and cross-crate. let (lint, label) = match *stability { - Some(attr::Stability { deprecated_since: Some(_), .. }) => + Some(&attr::Stability { deprecated_since: Some(_), .. }) => (DEPRECATED, "deprecated"), _ => return }; output(cx, span, stability, lint, label); - fn output(cx: &Context, span: Span, stability: &Option, + fn output(cx: &Context, span: Span, stability: &Option<&attr::Stability>, lint: &'static Lint, label: &'static str) { let msg = match *stability { - Some(attr::Stability { reason: Some(ref s), .. }) => { + Some(&attr::Stability { reason: Some(ref s), .. }) => { format!("use of {} item: {}", label, *s) } _ => format!("use of {} item", label) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 24f429a9ca015..eb6e90414e3fd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -98,7 +98,7 @@ use middle::ty::{FnSig, GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{self, HasProjectionTypes, RegionEscape, ToPolyTraitRef, Ty}; use middle::ty::liberate_late_bound_regions; -use middle::ty::{MethodCall, MethodCallee, MethodMap, ObjectCastMap}; +use middle::ty::{MethodCall, MethodCallee, MethodMap}; use middle::ty_fold::{TypeFolder, TypeFoldable}; use rscope::RegionScope; use session::Session; @@ -164,7 +164,6 @@ pub struct Inherited<'a, 'tcx: 'a> { upvar_capture_map: RefCell, closure_tys: RefCell>>, closure_kinds: RefCell>, - object_cast_map: ObjectCastMap<'tcx>, // A mapping from each fn's id to its signature, with all bound // regions replaced with free ones. Unlike the other tables, this @@ -383,7 +382,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { item_substs: RefCell::new(NodeMap()), adjustments: RefCell::new(NodeMap()), method_map: RefCell::new(FnvHashMap()), - object_cast_map: RefCell::new(NodeMap()), upvar_capture_map: RefCell::new(FnvHashMap()), closure_tys: RefCell::new(DefIdMap()), closure_kinds: RefCell::new(DefIdMap()), diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 79736c08f3796..8ec406ff41b92 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -81,7 +81,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_impl(item); } ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => { - let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id); + let trait_ref = ty::impl_trait_ref(ccx.tcx, + local_def(item.id)).unwrap(); ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id); match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) { Some(ty::BoundSend) | Some(ty::BoundSync) => {} diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 889975f0eb2f9..7eba4c0375f9a 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -41,7 +41,6 @@ pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) { wbcx.visit_expr(e); wbcx.visit_upvar_borrow_map(); wbcx.visit_closures(); - wbcx.visit_object_cast_map(); } pub fn resolve_type_vars_in_fn(fcx: &FnCtxt, @@ -62,7 +61,6 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt, } wbcx.visit_upvar_borrow_map(); wbcx.visit_closures(); - wbcx.visit_object_cast_map(); } /////////////////////////////////////////////////////////////////////////// @@ -239,27 +237,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - fn visit_object_cast_map(&self) { - if self.fcx.writeback_errors.get() { - return - } - - for (&node_id, trait_ref) in self.fcx - .inh - .object_cast_map - .borrow() - .iter() - { - let span = ty::expr_span(self.tcx(), node_id); - let reason = ResolvingExpr(span); - let closure_ty = self.resolve(trait_ref, reason); - self.tcx() - .object_cast_map - .borrow_mut() - .insert(node_id, closure_ty); - } - } - fn visit_node_id(&self, reason: ResolveReason, id: ast::NodeId) { // Resolve any borrowings for the node with id `id` self.visit_adjustments(reason, id); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 58ad8ce86280d..212423d16d43b 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -36,7 +36,7 @@ use std::cell::RefCell; use std::rc::Rc; use syntax::ast::{Crate, DefId}; use syntax::ast::{Item, ItemImpl}; -use syntax::ast::{LOCAL_CRATE, TraitRef}; +use syntax::ast::{LOCAL_CRATE}; use syntax::ast; use syntax::ast_map::NodeItem; use syntax::ast_map; @@ -100,11 +100,8 @@ struct CoherenceCheckVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { - - //debug!("(checking coherence) item '{}'", token::get_ident(item.ident)); - - if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node { - self.cc.check_implementation(item, opt_trait.as_ref()) + if let ItemImpl(..) = item.node { + self.cc.check_implementation(item) } visit::walk_item(self, item); @@ -141,7 +138,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { self.check_implementations_of_coerce_unsized(); } - fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) { + fn check_implementation(&self, item: &Item) { let tcx = self.crate_context.tcx; let impl_did = local_def(item.id); let self_type = ty::lookup_item_type(tcx, impl_did); @@ -151,8 +148,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { let impl_items = self.create_impl_from_item(item); - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id); + if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, + impl_did) { debug!("(checking implementation) adding impl for trait '{}', item '{}'", trait_ref.repr(self.crate_context.tcx), token::get_ident(item.ident)); @@ -161,22 +158,13 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { item.span, trait_ref.def_id); self.add_trait_impl(trait_ref, impl_did); - } - - // Add the implementation to the mapping from implementation to base - // type def ID, if there is a base type for this implementation and - // the implementation does not have any associated traits. - match get_base_type_def_id(&self.inference_context, - item.span, - self_type.ty) { - None => { - // Nothing to do. - } - Some(base_type_def_id) => { - // FIXME: Gather up default methods? - if opt_trait.is_none() { - self.add_inherent_impl(base_type_def_id, impl_did); - } + } else { + // Add the implementation to the mapping from implementation to base + // type def ID, if there is a base type for this implementation and + // the implementation does not have any associated traits. + if let Some(base_type_def_id) = get_base_type_def_id( + &self.inference_context, item.span, self_type.ty) { + self.add_inherent_impl(base_type_def_id, impl_did); } } @@ -267,7 +255,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Converts an implementation in the AST to a vector of items. fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { - ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => { + ItemImpl(_, _, _, _, _, ref impl_items) => { let mut items: Vec = impl_items.iter().map(|impl_item| { match impl_item.node { @@ -287,10 +275,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }).collect(); - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, - item.id); - + if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, + local_def(item.id)) { self.instantiate_default_methods(local_def(item.id), &trait_ref, &mut items); @@ -300,7 +286,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } _ => { self.crate_context.tcx.sess.span_bug(item.span, - "can't convert a non-impl to an impl"); + "can't convert a non-impl \ + to an impl"); } } } @@ -453,8 +440,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } let source = ty::lookup_item_type(tcx, impl_did).ty; - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, - impl_did.node); + let trait_ref = ty::impl_trait_ref(self.crate_context.tcx, + impl_did).unwrap(); let target = *trait_ref.substs.types.get(subst::TypeSpace, 0); debug!("check_implementations_of_coerce_unsized: {} -> {} (bound)", source.repr(tcx), target.repr(tcx)); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 48876c2a1889a..2fba967b3b237 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -820,7 +820,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ty::record_trait_has_default_impl(tcx, trait_ref.def_id); - tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref); + tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), Some(trait_ref)); } ast::ItemImpl(_, _, ref generics, @@ -828,7 +828,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ref selfty, ref impl_items) => { // Create generics from the generics specified in the impl head. - debug!("convert: ast_generics={:?}", generics); let ty_generics = ty_generics_for_type_or_impl(ccx, generics); let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics); @@ -926,14 +925,16 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { } } - if let Some(ref ast_trait_ref) = *opt_trait_ref { - let trait_ref = - astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), - &ExplicitRscope, - ast_trait_ref, - Some(selfty)); - - tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref); + if let &Some(ref ast_trait_ref) = opt_trait_ref { + tcx.impl_trait_refs.borrow_mut().insert( + local_def(it.id), + Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), + &ExplicitRscope, + ast_trait_ref, + Some(selfty))) + ); + } else { + tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None); } enforce_impl_params_are_constrained(tcx, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 045a38228c685..95444bb915872 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2695,6 +2695,21 @@ impl Clean for attr::Stability { } } +impl<'a> Clean for &'a attr::Stability { + fn clean(&self, _: &DocContext) -> Stability { + Stability { + level: self.level, + feature: self.feature.to_string(), + since: self.since.as_ref().map_or("".to_string(), + |interned| interned.to_string()), + deprecated_since: self.deprecated_since.as_ref().map_or("".to_string(), + |istr| istr.to_string()), + reason: self.reason.as_ref().map_or("".to_string(), + |interned| interned.to_string()), + } + } +} + impl<'tcx> Clean for ty::AssociatedConst<'tcx> { fn clean(&self, cx: &DocContext) -> Item { Item { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e86d77a3be03e..e0a462dd43795 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -61,7 +61,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } fn stability(&self, id: ast::NodeId) -> Option { - self.cx.tcx_opt().and_then(|tcx| stability::lookup(tcx, ast_util::local_def(id))) + self.cx.tcx_opt().and_then( + |tcx| stability::lookup(tcx, ast_util::local_def(id)).map(|x| x.clone())) } pub fn visit(&mut self, krate: &ast::Crate) { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 755dd3bb4586f..3c4c4d70343c3 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -366,7 +366,7 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P], cfg: &ast::Me } /// Represents the #[deprecated] and friends attributes. -#[derive(RustcEncodable,RustcDecodable,Clone,Debug)] +#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)] pub struct Stability { pub level: StabilityLevel, pub feature: InternedString, @@ -378,7 +378,7 @@ pub struct Stability { } /// The available stability levels. -#[derive(RustcEncodable,RustcDecodable,PartialEq,PartialOrd,Clone,Debug,Copy)] +#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Copy, Eq, Hash)] pub enum StabilityLevel { Unstable, Stable,