提交 472b4165 编写于 作者: J John Kåre Alsaker

Querify all_traits

上级 49a2b808
......@@ -632,6 +632,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[input] MaybeUnusedTraitImport(DefId),
[input] MaybeUnusedExternCrates,
[eval_always] StabilityIndex,
[eval_always] AllTraits,
[input] AllCrateNums,
[] ExportedSymbols(CrateNum),
[eval_always] CollectAndPartitionTranslationItems,
......
......@@ -898,12 +898,6 @@ pub struct GlobalCtxt<'tcx> {
layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
/// A vector of every trait accessible in the whole crate
/// (i.e. including those from subcrates). This is used only for
/// error reporting, and so is lazily initialized and generally
/// shouldn't taint the common path (hence the RefCell).
pub all_traits: RefCell<Option<Vec<DefId>>>,
/// A general purpose channel to throw data out the back towards LLVM worker
/// threads.
///
......@@ -1283,7 +1277,6 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
derive_macros: RefCell::new(NodeMap()),
stability_interner: Lock::new(FxHashSet()),
interpret_interner: Default::default(),
all_traits: RefCell::new(None),
tx_to_llvm_workers: Lock::new(tx),
output_filenames: Arc::new(output_filenames.clone()),
};
......
......@@ -586,6 +586,12 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
}
}
impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("fetching all foreign and local traits")
}
}
impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("fetching all foreign CrateNum instances")
......
......@@ -386,6 +386,11 @@
[] fn stability_index: stability_index_node(CrateNum) -> Lrc<stability::Index<'tcx>>,
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
/// A vector of every trait accessible in the whole crate
/// (i.e. including those from subcrates). This is used only for
/// error reporting.
[] fn all_traits: all_traits_node(CrateNum) -> Lrc<Vec<DefId>>,
[] fn exported_symbols: ExportedSymbols(CrateNum)
-> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>>,
[] fn collect_and_partition_translation_items:
......@@ -575,6 +580,10 @@ fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::AllCrateNums
}
fn all_traits_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::AllTraits
}
fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::CollectAndPartitionTranslationItems
}
......
......@@ -1115,6 +1115,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
}
DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); }
DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
DepKind::CollectAndPartitionTranslationItems => {
......
......@@ -31,6 +31,7 @@
pub use self::MethodError::*;
pub use self::CandidateSource::*;
pub use self::suggest::TraitInfo;
mod confirm;
pub mod probe;
......@@ -38,6 +39,10 @@
use self::probe::{IsSuggestion, ProbeScope};
pub fn provide(providers: &mut ty::maps::Providers) {
suggest::provide(providers);
}
#[derive(Clone, Copy, Debug)]
pub struct MethodCallee<'tcx> {
/// Impl method ID, for inherent methods, or trait method ID, otherwise.
......
......@@ -13,6 +13,7 @@
use check::FnCtxt;
use rustc::hir::map as hir_map;
use rustc_data_structures::sync::Lrc;
use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
use hir::def::Def;
use hir::def_id::{CRATE_DEF_INDEX, DefId};
......@@ -26,12 +27,12 @@
use errors::DiagnosticBuilder;
use syntax_pos::Span;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir;
use rustc::hir::print;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::ty::TyAdt;
use std::cell;
use std::cmp::Ordering;
use super::{MethodError, NoMatchData, CandidateSource};
......@@ -208,6 +209,7 @@ pub fn report_method_error(&self,
// be used exists at all, and the type is an ambiuous numeric type
// ({integer}/{float}).
let mut candidates = all_traits(self.tcx)
.into_iter()
.filter(|info| {
self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
});
......@@ -519,6 +521,7 @@ fn suggest_traits_to_import(&self,
// implement, by finding ones that have the item name, and are
// legal to implement.
let mut candidates = all_traits(self.tcx)
.into_iter()
.filter(|info| {
// we approximate the coherence rules to only suggest
// traits that are legal to implement by requiring that
......@@ -603,18 +606,11 @@ fn is_local(ty: Ty) -> bool {
}
}
pub type AllTraitsVec = Vec<DefId>;
#[derive(Copy, Clone)]
pub struct TraitInfo {
pub def_id: DefId,
}
impl TraitInfo {
fn new(def_id: DefId) -> TraitInfo {
TraitInfo { def_id: def_id }
}
}
impl PartialEq for TraitInfo {
fn eq(&self, other: &TraitInfo) -> bool {
self.cmp(other) == Ordering::Equal
......@@ -638,8 +634,12 @@ fn cmp(&self, other: &TraitInfo) -> Ordering {
}
/// Retrieve all traits in this crate and any dependent crates.
pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a> {
if tcx.all_traits.borrow().is_none() {
pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<TraitInfo> {
tcx.all_traits(LOCAL_CRATE).iter().map(|&def_id| TraitInfo { def_id }).collect()
}
/// Compute all traits in this crate and any dependent crates.
fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId> {
use rustc::hir::itemlikevisit;
let mut traits = vec![];
......@@ -649,7 +649,7 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a>
// meh.
struct Visitor<'a, 'tcx: 'a> {
map: &'a hir_map::Map<'tcx>,
traits: &'a mut AllTraitsVec,
traits: &'a mut Vec<DefId>,
}
impl<'v, 'a, 'tcx> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a, 'tcx> {
fn visit_item(&mut self, i: &'v hir::Item) {
......@@ -676,7 +676,7 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
// Cross-crate:
let mut external_mods = FxHashSet();
fn handle_external_def(tcx: TyCtxt,
traits: &mut AllTraitsVec,
traits: &mut Vec<DefId>,
external_mods: &mut FxHashSet<DefId>,
def: Def) {
let def_id = def.def_id();
......@@ -703,43 +703,16 @@ fn handle_external_def(tcx: TyCtxt,
handle_external_def(tcx, &mut traits, &mut external_mods, Def::Mod(def_id));
}
*tcx.all_traits.borrow_mut() = Some(traits);
}
let borrow = tcx.all_traits.borrow();
assert!(borrow.is_some());
AllTraits {
borrow,
idx: 0,
}
traits
}
pub struct AllTraits<'a> {
borrow: cell::Ref<'a, Option<AllTraitsVec>>,
idx: usize,
}
impl<'a> Iterator for AllTraits<'a> {
type Item = TraitInfo;
fn next(&mut self) -> Option<TraitInfo> {
let AllTraits { ref borrow, ref mut idx } = *self;
// ugh.
borrow.as_ref().unwrap().get(*idx).map(|info| {
*idx += 1;
TraitInfo::new(*info)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.borrow.as_ref().unwrap().len() - self.idx;
(len, Some(len))
pub fn provide(providers: &mut ty::maps::Providers) {
providers.all_traits = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Lrc::new(compute_all_traits(tcx))
}
}
impl<'a> ExactSizeIterator for AllTraits<'a> {}
struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> {
target_module: ast::NodeId,
span: Option<Span>,
......
......@@ -730,6 +730,7 @@ fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: De
}
pub fn provide(providers: &mut Providers) {
method::provide(providers);
*providers = Providers {
typeck_item_bodies,
typeck_tables_of,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册