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 | 151 |
1 files changed, 3 insertions, 148 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index e989e4c006..ca5e33fe6a 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -1,41 +1,30 @@ //! 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, iter}; +use std::cell::LazyCell; use base_db::{ Crate, target::{self, TargetData}, }; -use chalk_ir::{DebruijnIndex, fold::FallibleTypeFolder}; use hir_def::{ - EnumId, EnumVariantId, FunctionId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId, + EnumId, EnumVariantId, FunctionId, Lookup, TraitId, db::DefDatabase, hir::generics::WherePredicate, lang_item::LangItem, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, }; -use hir_expand::name::Name; use intern::sym; use rustc_abi::TargetDataLayout; -use rustc_hash::FxHashSet; -use rustc_type_ir::inherent::{IntoKind, SliceLike}; use smallvec::{SmallVec, smallvec}; use span::Edition; use crate::{ - ChalkTraitId, Const, ConstScalar, Interner, Substitution, TargetFeatures, TraitRef, - TraitRefExt, Ty, - consteval::unknown_const, + TargetFeatures, db::HirDatabase, layout::{Layout, TagEncoding}, mir::pad16, - next_solver::{ - DbInterner, - mapping::{ChalkToNextSolver, NextSolverToChalk, convert_args_for_result}, - }, - to_chalk_trait_id, }; pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ { @@ -76,49 +65,6 @@ pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[Trai result } -/// Given a trait ref (`Self: Trait`), builds all the implied trait refs for -/// super traits. The original trait ref will be included. So the difference to -/// `all_super_traits` is that we keep track of type parameters; for example if -/// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get -/// `Self: OtherTrait<i32>`. -pub(super) fn all_super_trait_refs<T>( - db: &dyn HirDatabase, - trait_ref: TraitRef, - cb: impl FnMut(TraitRef) -> Option<T>, -) -> Option<T> { - let seen = iter::once(trait_ref.trait_id).collect(); - SuperTraits { db, seen, stack: vec![trait_ref] }.find_map(cb) -} - -struct SuperTraits<'a> { - db: &'a dyn HirDatabase, - stack: Vec<TraitRef>, - seen: FxHashSet<ChalkTraitId>, -} - -impl SuperTraits<'_> { - fn elaborate(&mut self, trait_ref: &TraitRef) { - direct_super_trait_refs(self.db, trait_ref, |trait_ref| { - if !self.seen.contains(&trait_ref.trait_id) { - self.stack.push(trait_ref); - } - }); - } -} - -impl Iterator for SuperTraits<'_> { - type Item = TraitRef; - - fn next(&mut self) -> Option<Self::Item> { - if let Some(next) = self.stack.pop() { - self.elaborate(&next); - Some(next) - } else { - None - } - } -} - 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()); @@ -149,62 +95,6 @@ fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut( .for_each(cb); } -fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef, cb: impl FnMut(TraitRef)) { - let interner = DbInterner::new_with(db, None, None); - let generic_params = db.generic_params(trait_ref.hir_trait_id().into()); - let trait_self = match generic_params.trait_self_param() { - Some(p) => TypeOrConstParamId { parent: trait_ref.hir_trait_id().into(), local_id: p }, - None => return, - }; - let trait_ref_args: crate::next_solver::GenericArgs<'_> = - trait_ref.substitution.to_nextsolver(interner); - db.generic_predicates_for_param_ns(trait_self.parent, trait_self, None) - .iter() - .filter_map(|pred| { - let pred = pred.kind(); - // FIXME: how to correctly handle higher-ranked bounds here? - let pred = pred.no_bound_vars().expect("FIXME unexpected higher-ranked trait bound"); - match pred { - rustc_type_ir::ClauseKind::Trait(t) => { - let t = - rustc_type_ir::EarlyBinder::bind(t).instantiate(interner, trait_ref_args); - let trait_id = to_chalk_trait_id(t.def_id().0); - - let substitution = - convert_args_for_result(interner, t.trait_ref.args.as_slice()); - let tr = chalk_ir::TraitRef { trait_id, substitution }; - Some(tr) - } - _ => None, - } - }) - .for_each(cb); -} - -pub(super) fn associated_type_by_name_including_super_traits( - db: &dyn HirDatabase, - trait_ref: TraitRef, - name: &Name, -) -> Option<(TraitRef, TypeAliasId)> { - all_super_trait_refs(db, trait_ref, |t| { - let assoc_type = t.hir_trait_id().trait_items(db).associated_type_by_name(name)?; - Some((t, assoc_type)) - }) -} - -pub(crate) struct ClosureSubst<'a>(pub(crate) &'a Substitution); - -impl<'a> ClosureSubst<'a> { - pub(crate) fn sig_ty(&self, db: &dyn HirDatabase) -> Ty { - let interner = DbInterner::new_with(db, None, None); - let subst = - <Substitution as ChalkToNextSolver<crate::next_solver::GenericArgs<'_>>>::to_nextsolver( - self.0, interner, - ); - subst.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.to_chalk(interner) - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Unsafety { Safe, @@ -277,41 +167,6 @@ pub fn is_fn_unsafe_to_call( } } -pub(crate) struct UnevaluatedConstEvaluatorFolder<'a> { - pub(crate) db: &'a dyn HirDatabase, -} - -impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> { - type Error = (); - - fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = ()> { - self - } - - fn interner(&self) -> Interner { - Interner - } - - fn try_fold_const( - &mut self, - constant: Const, - _outer_binder: DebruijnIndex, - ) -> Result<Const, Self::Error> { - if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value - && let ConstScalar::UnevaluatedConst(id, subst) = &c.interned - { - let interner = DbInterner::conjure(); - if let Ok(eval) = self.db.const_eval(*id, subst.to_nextsolver(interner), None) { - return Ok(eval.to_chalk(interner)); - } else { - return Ok(unknown_const(constant.data(Interner).ty.to_nextsolver(interner)) - .to_chalk(interner)); - } - } - Ok(constant) - } -} - pub(crate) fn detect_variant_from_bytes<'a>( layout: &'a Layout, db: &dyn HirDatabase, |