Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/utils.rs')
-rw-r--r--crates/hir-ty/src/utils.rs77
1 files changed, 9 insertions, 68 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 7dd73f1e7a..509109543c 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -1,27 +1,20 @@
//! Helper functions for working with def, which don't need to be a separate
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
-use std::cell::LazyCell;
-
use base_db::target::{self, TargetData};
use hir_def::{
- EnumId, EnumVariantId, FunctionId, Lookup, TraitId,
- attrs::AttrFlags,
- db::DefDatabase,
- hir::generics::WherePredicate,
- lang_item::LangItems,
- resolver::{HasResolver, TypeNs},
- type_ref::{TraitBoundModifier, TypeRef},
+ EnumId, EnumVariantId, FunctionId, Lookup, TraitId, attrs::AttrFlags, lang_item::LangItems,
+ signatures::FunctionSignature,
};
use intern::sym;
use rustc_abi::TargetDataLayout;
-use smallvec::{SmallVec, smallvec};
use span::Edition;
use crate::{
TargetFeatures,
db::HirDatabase,
layout::{Layout, TagEncoding},
+ lower::SupertraitsInfo,
mir::pad16,
};
@@ -50,65 +43,13 @@ pub(crate) fn fn_traits(lang_items: &LangItems) -> impl Iterator<Item = TraitId>
}
/// Returns an iterator over the direct super traits (including the trait itself).
-pub fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
- let mut result = smallvec![trait_];
- direct_super_traits_cb(db, trait_, |tt| {
- if !result.contains(&tt) {
- result.push(tt);
- }
- });
- result
+pub fn direct_super_traits(db: &dyn HirDatabase, trait_: TraitId) -> &[TraitId] {
+ &SupertraitsInfo::query(db, trait_).direct_supertraits
}
-/// Returns an iterator over the whole super trait hierarchy (including the
-/// trait itself).
-pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
- // we need to take care a bit here to avoid infinite loops in case of cycles
- // (i.e. if we have `trait A: B; trait B: A;`)
-
- let mut result = smallvec![trait_];
- let mut i = 0;
- while let Some(&t) = result.get(i) {
- // yeah this is quadratic, but trait hierarchies should be flat
- // enough that this doesn't matter
- direct_super_traits_cb(db, t, |tt| {
- if !result.contains(&tt) {
- result.push(tt);
- }
- });
- i += 1;
- }
- result
-}
-
-fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
- let resolver = LazyCell::new(|| trait_.resolver(db));
- let (generic_params, store) = db.generic_params_and_store(trait_.into());
- let trait_self = generic_params.trait_self_param();
- generic_params
- .where_predicates()
- .iter()
- .filter_map(|pred| match pred {
- WherePredicate::ForLifetime { target, bound, .. }
- | WherePredicate::TypeBound { target, bound } => {
- let is_trait = match &store[*target] {
- TypeRef::Path(p) => p.is_self_type(),
- TypeRef::TypeParam(p) => Some(p.local_id()) == trait_self,
- _ => false,
- };
- match is_trait {
- true => bound.as_path(&store),
- false => None,
- }
- }
- WherePredicate::Lifetime { .. } => None,
- })
- .filter(|(_, bound_modifier)| matches!(bound_modifier, TraitBoundModifier::None))
- .filter_map(|(path, _)| match resolver.resolve_path_in_type_ns_fully(db, path) {
- Some(TypeNs::TraitId(t)) => Some(t),
- _ => None,
- })
- .for_each(cb);
+/// Returns the whole super trait hierarchy (including the trait itself).
+pub fn all_super_traits(db: &dyn HirDatabase, trait_: TraitId) -> &[TraitId] {
+ &SupertraitsInfo::query(db, trait_).all_supertraits
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -139,7 +80,7 @@ pub fn is_fn_unsafe_to_call(
call_edition: Edition,
target_feature_is_safe: TargetFeatureIsSafeInTarget,
) -> Unsafety {
- let data = db.function_signature(func);
+ let data = FunctionSignature::of(db, func);
if data.is_unsafe() {
return Unsafety::Unsafe;
}