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.rs | 97 |
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()) - } -} |