Auto merge of #25785 - arielb1:cleanup-201505, r=eddyb

The caching essentially eliminates "stability checking" time (my attempt to clean-up junk got tangled up with stability, so I added the caching while I was at it).

r? @eddyb
This commit is contained in:
bors 2015-05-26 12:15:30 +00:00
commit c654a07d29
18 changed files with 209 additions and 489 deletions

View file

@ -146,7 +146,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
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,
}

View file

@ -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<attr::Stability> {
@ -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)

View file

@ -30,7 +30,6 @@
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);

View file

@ -999,7 +999,7 @@ fn encode_extension_implementations(ecx: &EncodeContext,
});
}
fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
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 add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
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 add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
}
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());

View file

@ -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<T, F>(&mut self, f: F) -> VecPerParamSpace<T> 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 @@ fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> wh
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);

View file

@ -23,46 +23,47 @@
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<Stability>,
// cache for extern-crate items; unmarked stability == entry with None
extern_cache: DefIdMap<Option<Stability>>
pub struct Index<'tcx> {
/// This is mostly a cache, except the stabilities of local items
/// are filled by the annotator.
map: DefIdMap<Option<&'tcx Stability>>,
/// Maps for each crate whether it is part of the staged API.
staged_api: FnvHashMap<ast::CrateNum, bool>
}
// A private tree-walker for producing an Index.
struct Annotator<'a> {
sess: &'a Session,
index: &'a mut Index,
parent: Option<Stability>,
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<F>(&mut self, id: NodeId, use_parent: bool,
attrs: &Vec<Attribute>, 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 @@ fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
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 @@ fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
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 @@ fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
}
}
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 @@ fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
}
}
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 @@ pub fn build(&mut self, sess: &Session, krate: &Crate, export_map: &PublicItems)
}
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<Stability>) {
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 @@ fn check(&mut self, id: ast::DefId, span: Span, stab: &Option<Stability>) {
&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 @@ fn visit_pat(&mut self, pat: &ast::Pat) {
/// 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<Stability>)) {
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<Stability>)) {
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<Stability>)) {
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<Stability>)) {
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<Stability>)) {
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<Stability> {
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<Stability> {
}
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.
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);
lookup(tcx, trait_id)
} else {
None
debug!("lookup: trait_id={:?}", trait_id);
return lookup(tcx, trait_id);
}
}
None
})
}

View file

@ -32,7 +32,6 @@
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 @@ pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
// of the method to be invoked
pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
pub type vtable_param_res<'tcx> = Vec<vtable_origin<'tcx>>;
// Resolutions for bounds of all parameters, left to right, for a given path.
pub type vtable_res<'tcx> = VecPerParamSpace<vtable_param_res<'tcx>>;
#[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<T:quux,baz,bar>(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<NodeMap<ty::PolyTraitRef<'tcx>>>;
// 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<Substs<'tcx>>,
bare_fn: TypedArena<BareFnTy<'tcx>>,
region: TypedArena<Region>,
stability: TypedArena<attr::Stability>,
// references
trait_defs: TypedArena<TraitDef<'tcx>>
trait_defs: TypedArena<TraitDef<'tcx>>,
}
impl<'tcx> CtxtArenas<'tcx> {
@ -613,6 +563,7 @@ pub fn new() -> 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<FnvHashMap<&'tcx Substs<'tcx>, &'tcx Substs<'tcx>>>,
bare_fn_interner: RefCell<FnvHashMap<&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>>>,
region_interner: RefCell<FnvHashMap<&'tcx Region, &'tcx Region>>,
stability_interner: RefCell<FnvHashMap<&'tcx attr::Stability, &'tcx attr::Stability>>,
/// 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<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
pub impl_trait_cache: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
pub impl_trait_refs: RefCell<NodeMap<TraitRef<'tcx>>>,
pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
/// 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<DefIdMap<GenericPredicates<'tcx>>>,
/// Maps from node-id of a trait object cast (like `foo as
/// Box<Trait>`) to the trait reference.
pub object_cast_map: ObjectCastMap<'tcx>,
pub map: ast_map::Map<'tcx>,
pub freevars: RefCell<FreevarMap>,
pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>,
pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
@ -801,10 +746,7 @@ pub struct ctxt<'tcx> {
pub transmute_restrictions: RefCell<Vec<TransmuteRestriction<'tcx>>>,
/// Maps any item's def-id to its stability index.
pub stability: RefCell<stability::Index>,
/// Maps def IDs to true if and only if they're associated types.
pub associated_types: RefCell<DefIdMap<bool>>,
pub stability: RefCell<stability::Index<'tcx>>,
/// 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 @@ pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'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 @@ pub fn print_debug_stats(&self) {
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<FreevarMap>,
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 @@ fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
}
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<V, F>(descr: &str,
def_id: ast::DefId,
map: &mut DefIdMap<V>,
map: &RefCell<DefIdMap<V>>,
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<V, F>(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<Vec<ImplOrTraitItemId>> {
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<TraitRef<'tcx>> {
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<TraitRef<'tcx>>
{
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<ItemVariances> {
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 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
}
}
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>)

View file

@ -336,27 +336,6 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::MethodOrigin<'tc
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&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<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> ty::BuiltinBounds {
*self

View file

@ -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));

View file

@ -1798,20 +1798,21 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
pub struct Stability;
impl Stability {
fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option<attr::Stability>) {
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<attr::Stability>,
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)

View file

@ -98,7 +98,7 @@
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<ty::UpvarCaptureMap>,
closure_tys: RefCell<DefIdMap<ty::ClosureTy<'tcx>>>,
closure_kinds: RefCell<DefIdMap<ty::ClosureKind>>,
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 @@ fn new(tcx: &'a ty::ctxt<'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()),

View file

@ -81,7 +81,8 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
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) => {}

View file

@ -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 @@ fn visit_closures(&self) {
}
}
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);

View file

@ -36,7 +36,7 @@
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 @@ fn check(&self, krate: &Crate) {
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 @@ fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
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 @@ fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
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 @@ fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'tcx>, impl_def_id: DefId)
// Converts an implementation in the AST to a vector of items.
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
match item.node {
ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
ItemImpl(_, _, _, _, _, ref impl_items) => {
let mut items: Vec<ImplOrTraitItemId> =
impl_items.iter().map(|impl_item| {
match impl_item.node {
@ -287,10 +275,8 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
}
}).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 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
}
_ => {
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 @@ fn check_implementations_of_coerce_unsized(&self) {
}
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));

View file

@ -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,

View file

@ -2695,6 +2695,21 @@ fn clean(&self, _: &DocContext) -> Stability {
}
}
impl<'a> Clean<Stability> 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<Item> for ty::AssociatedConst<'tcx> {
fn clean(&self, cx: &DocContext) -> Item {
Item {

View file

@ -61,7 +61,8 @@ pub fn new(cx: &'a core::DocContext<'tcx>,
}
fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
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) {

View file

@ -366,7 +366,7 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], 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,