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.rs97
1 files changed, 29 insertions, 68 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 89d89fe223..198f715a6d 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -1,43 +1,39 @@
//! 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::{hash::Hash, iter};
+use std::iter;
-use base_db::CrateId;
+use base_db::Crate;
use chalk_ir::{
- fold::{FallibleTypeFolder, Shift},
DebruijnIndex,
+ fold::{FallibleTypeFolder, Shift},
};
use hir_def::{
+ EnumId, EnumVariantId, FunctionId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId,
db::DefDatabase,
- generics::{WherePredicate, WherePredicateTypeTarget},
+ hir::generics::WherePredicate,
lang_item::LangItem,
resolver::{HasResolver, TypeNs},
type_ref::{TraitBoundModifier, TypeRef},
- EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId,
- TypeOrConstParamId,
};
use hir_expand::name::Name;
use intern::sym;
use rustc_abi::TargetDataLayout;
use rustc_hash::FxHashSet;
-use smallvec::{smallvec, SmallVec};
+use smallvec::{SmallVec, smallvec};
use span::Edition;
use stdx::never;
use crate::{
+ ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef,
+ TraitRefExt, Ty, WhereClause,
consteval::unknown_const,
db::HirDatabase,
layout::{Layout, TagEncoding},
mir::pad16,
- ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef,
- TraitRefExt, Ty, WhereClause,
};
-pub(crate) fn fn_traits(
- db: &dyn DefDatabase,
- krate: CrateId,
-) -> impl Iterator<Item = TraitId> + '_ {
+pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
.into_iter()
.filter_map(move |lang| db.lang_item(krate, lang))
@@ -167,26 +163,20 @@ impl Iterator for ClauseElaborator<'_> {
fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
let resolver = trait_.resolver(db);
- let generic_params = db.generic_params(trait_.into());
+ let (generic_params, store) = db.generic_params_and_store(trait_.into());
let trait_self = generic_params.trait_self_param();
generic_params
.where_predicates()
.filter_map(|pred| match pred {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => {
- let is_trait = match target {
- WherePredicateTypeTarget::TypeRef(type_ref) => {
- match &generic_params.types_map[*type_ref] {
- TypeRef::Path(p) => p.is_self_type(),
- _ => false,
- }
- }
- WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
- Some(*local_id) == trait_self
- }
+ 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(&generic_params.types_map),
+ true => bound.as_path(&store),
false => None,
}
}
@@ -229,14 +219,14 @@ pub(super) fn associated_type_by_name_including_super_traits(
name: &Name,
) -> Option<(TraitRef, TypeAliasId)> {
all_super_trait_refs(db, trait_ref, |t| {
- let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?;
+ let assoc_type = db.trait_items(t.hir_trait_id()).associated_type_by_name(name)?;
Some((t, assoc_type))
})
}
/// It is a bit different from the rustc equivalent. Currently it stores:
-/// - 0: the function signature, encoded as a function pointer type
-/// - 1..n: generics of the parent
+/// - 0..n-1: generics of the parent
+/// - n: the function signature, encoded as a function pointer type
///
/// and it doesn't store the closure types and fields.
///
@@ -247,7 +237,7 @@ pub(crate) struct ClosureSubst<'a>(pub(crate) &'a Substitution);
impl<'a> ClosureSubst<'a> {
pub(crate) fn parent_subst(&self) -> &'a [GenericArg] {
match self.0.as_slice(Interner) {
- [_, x @ ..] => x,
+ [x @ .., _] => x,
_ => {
never!("Closure missing parameter");
&[]
@@ -257,7 +247,7 @@ impl<'a> ClosureSubst<'a> {
pub(crate) fn sig_ty(&self) -> &'a Ty {
match self.0.as_slice(Interner) {
- [x, ..] => x.assert_ty_ref(Interner),
+ [.., x] => x.assert_ty_ref(Interner),
_ => {
unreachable!("Closure missing sig_ty parameter");
}
@@ -279,7 +269,7 @@ pub fn is_fn_unsafe_to_call(
caller_target_features: &TargetFeatures,
call_edition: Edition,
) -> Unsafety {
- let data = db.function_data(func);
+ let data = db.function_signature(func);
if data.is_unsafe() {
return Unsafety::Unsafe;
}
@@ -301,16 +291,16 @@ pub fn is_fn_unsafe_to_call(
}
}
- let loc = func.lookup(db.upcast());
+ let loc = func.lookup(db);
match loc.container {
hir_def::ItemContainerId::ExternBlockId(block) => {
- let id = block.lookup(db.upcast()).id;
+ let id = block.lookup(db).id;
let is_intrinsic_block =
- id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
+ id.item_tree(db)[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
if is_intrinsic_block {
// legacy intrinsics
// extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
- if db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists() {
+ if db.attrs(func.into()).by_key(sym::rustc_safe_intrinsic).exists() {
Unsafety::Safe
} else {
Unsafety::Unsafe
@@ -318,11 +308,7 @@ pub fn is_fn_unsafe_to_call(
} else {
// Function in an `extern` block are always unsafe to call, except when
// it is marked as `safe`.
- if data.is_safe() {
- Unsafety::Safe
- } else {
- Unsafety::Unsafe
- }
+ if data.is_safe() { Unsafety::Safe } else { Unsafety::Unsafe }
}
}
_ => Unsafety::Safe,
@@ -372,7 +358,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
let (var_id, var_layout) = match &layout.variants {
hir_def::layout::Variants::Empty => unreachable!(),
hir_def::layout::Variants::Single { index } => {
- (db.enum_data(e).variants[index.0].0, layout)
+ (db.enum_variants(e).variants[index.0].0, layout)
}
hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
let size = tag.size(target_data_layout).bytes_usize();
@@ -382,7 +368,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
TagEncoding::Direct => {
let (var_idx, layout) =
variants.iter_enumerated().find_map(|(var_idx, v)| {
- let def = db.enum_data(e).variants[var_idx.0].0;
+ let def = db.enum_variants(e).variants[var_idx.0].0;
(db.const_eval_discriminant(def) == Ok(tag)).then_some((def, v))
})?;
(var_idx, layout)
@@ -395,35 +381,10 @@ pub(crate) fn detect_variant_from_bytes<'a>(
.filter(|x| x != untagged_variant)
.nth(candidate_tag)
.unwrap_or(*untagged_variant);
- (db.enum_data(e).variants[variant.0].0, &variants[variant])
+ (db.enum_variants(e).variants[variant.0].0, &variants[variant])
}
}
}
};
Some((var_id, var_layout))
}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub(crate) struct InTypeConstIdMetadata(pub(crate) Ty);
-
-impl OpaqueInternableThing for InTypeConstIdMetadata {
- fn dyn_hash(&self, mut state: &mut dyn std::hash::Hasher) {
- self.hash(&mut state);
- }
-
- fn dyn_eq(&self, other: &dyn OpaqueInternableThing) -> bool {
- other.as_any().downcast_ref::<Self>() == Some(self)
- }
-
- fn dyn_clone(&self) -> Box<dyn OpaqueInternableThing> {
- Box::new(self.clone())
- }
-
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn box_any(&self) -> Box<dyn std::any::Any> {
- Box::new(self.clone())
- }
-}