Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/chalk_db.rs')
| -rw-r--r-- | crates/hir-ty/src/chalk_db.rs | 610 |
1 files changed, 10 insertions, 600 deletions
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index 3ba7c93d4f..f523a5e8bf 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -1,47 +1,36 @@ //! The implementation of `RustIrDatabase` for Chalk, which provides information //! about the code that Chalk needs. -use core::ops; -use std::{iter, ops::ControlFlow, sync::Arc}; +use std::sync::Arc; -use hir_expand::name::Name; -use intern::sym; -use span::Edition; use tracing::debug; -use chalk_ir::{CanonicalVarKinds, cast::Caster, fold::shift::Shift}; -use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; +use chalk_ir::{cast::Caster, fold::shift::Shift}; +use chalk_solve::rust_ir::{self, WellKnownTrait}; use base_db::Crate; use hir_def::{ - AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup, - TypeAliasId, VariantId, - hir::Movability, + AssocItemId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, + VariantId, lang_item::LangItem, signatures::{ImplFlags, StructFlags, TraitFlags}, }; use crate::{ - AliasEq, AliasTy, BoundVar, DebruijnIndex, Interner, ProjectionTy, ProjectionTyExt, - QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, - WhereClause, - db::{HirDatabase, InternedCoroutine}, - from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, + AliasEq, AliasTy, DebruijnIndex, Interner, ProjectionTyExt, QuantifiedWhereClause, + Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause, + db::HirDatabase, + from_assoc_type_id, from_chalk_trait_id, generics::generics, lower::LifetimeElisionKind, - make_binders, make_single_type_binders, + make_binders, mapping::{ToChalk, TypeAliasAsValue, from_chalk}, - method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TraitImpls, TyFingerprint}, to_assoc_type_id, to_chalk_trait_id, - traits::ChalkContext, - utils::ClosureSubst, - wrap_empty_binders, }; pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; pub(crate) type AdtDatum = chalk_solve::rust_ir::AdtDatum<Interner>; pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; -pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; pub(crate) type TraitId = chalk_ir::TraitId<Interner>; @@ -52,551 +41,6 @@ pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Inte pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; pub(crate) type Variances = chalk_ir::Variances<Interner>; -impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> { - fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> { - self.db.associated_ty_data(from_assoc_type_id(id)) - } - fn associated_ty_from_impl( - &self, - impl_id: chalk_ir::ImplId<Interner>, - assoc_type_id: chalk_ir::AssocTypeId<Interner>, - ) -> Option<rust_ir::AssociatedTyValueId<Interner>> { - let alias_id = from_assoc_type_id(assoc_type_id); - let trait_sig = self.db.type_alias_signature(alias_id); - hir_def::ImplId::from_chalk(self.db, impl_id).impl_items(self.db).items.iter().find_map( - |(name, item)| match item { - AssocItemId::TypeAliasId(alias) if &trait_sig.name == name => { - Some(TypeAliasAsValue(*alias).to_chalk(self.db)) - } - _ => None, - }, - ) - } - fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> { - self.db.trait_datum(self.krate, trait_id) - } - fn adt_datum(&self, struct_id: AdtId) -> Arc<AdtDatum> { - self.db.adt_datum(self.krate, struct_id) - } - fn adt_repr(&self, _struct_id: AdtId) -> Arc<rust_ir::AdtRepr<Interner>> { - // FIXME: keep track of these - Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None }) - } - fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> { - if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) - && let hir_def::AdtId::EnumId(e) = id.0 - { - let enum_data = self.db.enum_signature(e); - let ty = enum_data.repr.unwrap_or_default().discr_type(); - return chalk_ir::TyKind::Scalar(match ty { - hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed { - true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize), - false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize), - }, - hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed { - true => chalk_ir::Scalar::Int(match size { - hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8, - hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16, - hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32, - hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64, - hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128, - }), - false => chalk_ir::Scalar::Uint(match size { - hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8, - hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16, - hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32, - hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64, - hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128, - }), - }, - }) - .intern(Interner); - } - chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner) - } - fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { - self.db.impl_datum(self.krate, impl_id) - } - - fn fn_def_datum( - &self, - fn_def_id: chalk_ir::FnDefId<Interner>, - ) -> Arc<rust_ir::FnDefDatum<Interner>> { - self.db.fn_def_datum(from_chalk(self.db, fn_def_id)) - } - - fn impls_for_trait( - &self, - trait_id: TraitId, - parameters: &[chalk_ir::GenericArg<Interner>], - binders: &CanonicalVarKinds<Interner>, - ) -> Vec<ImplId> { - debug!("impls_for_trait {:?}", trait_id); - let trait_: hir_def::TraitId = from_chalk_trait_id(trait_id); - - let ty: Ty = parameters[0].assert_ty_ref(Interner).clone(); - - fn binder_kind( - ty: &Ty, - binders: &CanonicalVarKinds<Interner>, - ) -> Option<chalk_ir::TyVariableKind> { - if let TyKind::BoundVar(bv) = ty.kind(Interner) { - let binders = binders.as_slice(Interner); - if bv.debruijn == DebruijnIndex::INNERMOST - && let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind - { - return Some(tk); - } - } - None - } - - let self_ty_fp = TyFingerprint::for_trait_impl(&ty); - let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { - Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS, - Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS, - _ => self_ty_fp.as_slice(), - }; - - let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); - - let mut result = vec![]; - if fps.is_empty() { - debug!("Unrestricted search for {:?} impls...", trait_); - _ = self.for_trait_impls(trait_, self_ty_fp, |impls| { - result.extend(impls.for_trait(trait_).map(id_to_chalk)); - ControlFlow::Continue(()) - }); - } else { - _ = - self.for_trait_impls(trait_, self_ty_fp, |impls| { - result.extend(fps.iter().flat_map(move |fp| { - impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) - })); - ControlFlow::Continue(()) - }); - }; - - debug!("impls_for_trait returned {} impls", result.len()); - result - } - - fn impl_provided_for(&self, auto_trait_id: TraitId, kind: &chalk_ir::TyKind<Interner>) -> bool { - debug!("impl_provided_for {:?}, {:?}", auto_trait_id, kind); - - let trait_id = from_chalk_trait_id(auto_trait_id); - let self_ty = kind.clone().intern(Interner); - // We cannot filter impls by `TyFingerprint` for the following types: - let self_ty_fp = match kind { - // because we need to find any impl whose Self type is a ref with the same mutability - // (we don't care about the inner type). - TyKind::Ref(..) => None, - // because we need to find any impl whose Self type is a tuple with the same arity. - TyKind::Tuple(..) => None, - _ => TyFingerprint::for_trait_impl(&self_ty), - }; - - let check_kind = |impl_id| { - let impl_self_ty = self.db.impl_self_ty(impl_id); - // NOTE(skip_binders): it's safe to skip binders here as we don't check substitutions. - let impl_self_kind = impl_self_ty.skip_binders().kind(Interner); - - match (kind, impl_self_kind) { - (TyKind::Adt(id_a, _), TyKind::Adt(id_b, _)) => id_a == id_b, - (TyKind::AssociatedType(id_a, _), TyKind::AssociatedType(id_b, _)) => id_a == id_b, - (TyKind::Scalar(scalar_a), TyKind::Scalar(scalar_b)) => scalar_a == scalar_b, - (TyKind::Error, TyKind::Error) - | (TyKind::Str, TyKind::Str) - | (TyKind::Slice(_), TyKind::Slice(_)) - | (TyKind::Never, TyKind::Never) - | (TyKind::Array(_, _), TyKind::Array(_, _)) => true, - (TyKind::Tuple(arity_a, _), TyKind::Tuple(arity_b, _)) => arity_a == arity_b, - (TyKind::OpaqueType(id_a, _), TyKind::OpaqueType(id_b, _)) => id_a == id_b, - (TyKind::FnDef(id_a, _), TyKind::FnDef(id_b, _)) => id_a == id_b, - (TyKind::Ref(id_a, _, _), TyKind::Ref(id_b, _, _)) - | (TyKind::Raw(id_a, _), TyKind::Raw(id_b, _)) => id_a == id_b, - (TyKind::Closure(id_a, _), TyKind::Closure(id_b, _)) => id_a == id_b, - (TyKind::Coroutine(id_a, _), TyKind::Coroutine(id_b, _)) - | (TyKind::CoroutineWitness(id_a, _), TyKind::CoroutineWitness(id_b, _)) => { - id_a == id_b - } - (TyKind::Foreign(id_a), TyKind::Foreign(id_b)) => id_a == id_b, - (_, _) => false, - } - }; - - if let Some(fp) = self_ty_fp { - self.for_trait_impls(trait_id, self_ty_fp, |impls| { - match impls.for_trait_and_self_ty(trait_id, fp).any(check_kind) { - true => ControlFlow::Break(()), - false => ControlFlow::Continue(()), - } - }) - } else { - self.for_trait_impls(trait_id, self_ty_fp, |impls| { - match impls.for_trait(trait_id).any(check_kind) { - true => ControlFlow::Break(()), - false => ControlFlow::Continue(()), - } - }) - } - .is_break() - } - - fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { - self.db.associated_ty_value(self.krate, id) - } - - fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> { - vec![] - } - fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> { - // We don't do coherence checking (yet) - unimplemented!() - } - fn interner(&self) -> Interner { - Interner - } - fn well_known_trait_id( - &self, - well_known_trait: WellKnownTrait, - ) -> Option<chalk_ir::TraitId<Interner>> { - let lang_item = lang_item_from_well_known_trait(well_known_trait); - let trait_ = lang_item.resolve_trait(self.db, self.krate)?; - Some(to_chalk_trait_id(trait_)) - } - fn well_known_assoc_type_id( - &self, - assoc_type: rust_ir::WellKnownAssocType, - ) -> Option<chalk_ir::AssocTypeId<Interner>> { - let lang_item = match assoc_type { - rust_ir::WellKnownAssocType::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput, - }; - let alias = lang_item.resolve_type_alias(self.db, self.krate)?; - Some(to_assoc_type_id(alias)) - } - - fn program_clauses_for_env( - &self, - environment: &chalk_ir::Environment<Interner>, - ) -> chalk_ir::ProgramClauses<Interner> { - self.db.program_clauses_for_chalk_env(self.krate, self.block, environment.clone()) - } - - fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { - let full_id = self.db.lookup_intern_impl_trait_id(id.into()); - let bound = match full_id { - crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { - let datas = self - .db - .return_type_impl_traits(func) - .expect("impl trait id without impl traits"); - let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders(); - let data = &datas.impl_traits[idx]; - let bound = OpaqueTyDatumBound { - bounds: make_single_type_binders(data.bounds.skip_binders().to_vec()), - where_clauses: chalk_ir::Binders::empty(Interner, vec![]), - }; - chalk_ir::Binders::new(binders, bound) - } - crate::ImplTraitId::TypeAliasImplTrait(alias, idx) => { - let datas = self - .db - .type_alias_impl_traits(alias) - .expect("impl trait id without impl traits"); - let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders(); - let data = &datas.impl_traits[idx]; - let bound = OpaqueTyDatumBound { - bounds: make_single_type_binders(data.bounds.skip_binders().to_vec()), - where_clauses: chalk_ir::Binders::empty(Interner, vec![]), - }; - chalk_ir::Binders::new(binders, bound) - } - crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { - if let Some((future_trait, future_output)) = - LangItem::Future.resolve_trait(self.db, self.krate).and_then(|trait_| { - let alias = trait_ - .trait_items(self.db) - .associated_type_by_name(&Name::new_symbol_root(sym::Output))?; - Some((trait_, alias)) - }) - { - // Making up Symbol’s value as variable is void: AsyncBlock<T>: - // - // |--------------------OpaqueTyDatum-------------------| - // |-------------OpaqueTyDatumBound--------------| - // for<T> <Self> [Future<Self>, Future::Output<Self> = T] - // ^1 ^0 ^0 ^0 ^1 - let impl_bound = WhereClause::Implemented(TraitRef { - trait_id: to_chalk_trait_id(future_trait), - // Self type as the first parameter. - substitution: Substitution::from1( - Interner, - TyKind::BoundVar(BoundVar { - debruijn: DebruijnIndex::INNERMOST, - index: 0, - }) - .intern(Interner), - ), - }); - let mut binder = vec![]; - binder.push(crate::wrap_empty_binders(impl_bound)); - let sized_trait = LangItem::Sized.resolve_trait(self.db, self.krate); - if let Some(sized_trait_) = sized_trait { - let sized_bound = WhereClause::Implemented(TraitRef { - trait_id: to_chalk_trait_id(sized_trait_), - // Self type as the first parameter. - substitution: Substitution::from1( - Interner, - TyKind::BoundVar(BoundVar { - debruijn: DebruijnIndex::INNERMOST, - index: 0, - }) - .intern(Interner), - ), - }); - binder.push(crate::wrap_empty_binders(sized_bound)); - } - let proj_bound = WhereClause::AliasEq(AliasEq { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id: to_assoc_type_id(future_output), - // Self type as the first parameter. - substitution: Substitution::from1( - Interner, - TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) - .intern(Interner), - ), - }), - // The parameter of the opaque type. - ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }) - .intern(Interner), - }); - binder.push(crate::wrap_empty_binders(proj_bound)); - let bound = OpaqueTyDatumBound { - bounds: make_single_type_binders(binder), - where_clauses: chalk_ir::Binders::empty(Interner, vec![]), - }; - // The opaque type has 1 parameter. - make_single_type_binders(bound) - } else { - // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback. - let bound = OpaqueTyDatumBound { - bounds: chalk_ir::Binders::empty(Interner, vec![]), - where_clauses: chalk_ir::Binders::empty(Interner, vec![]), - }; - // The opaque type has 1 parameter. - make_single_type_binders(bound) - } - } - }; - - Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound }) - } - - fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { - // FIXME: actually provide the hidden type; it is relevant for auto traits - TyKind::Error.intern(Interner) - } - - // object safety was renamed to dyn-compatibility but still remains here in chalk. - // This will be removed since we are going to migrate to next-gen trait solver. - fn is_object_safe(&self, trait_id: chalk_ir::TraitId<Interner>) -> bool { - let trait_ = from_chalk_trait_id(trait_id); - crate::dyn_compatibility::dyn_compatibility(self.db, trait_).is_none() - } - - fn closure_kind( - &self, - _closure_id: chalk_ir::ClosureId<Interner>, - _substs: &chalk_ir::Substitution<Interner>, - ) -> rust_ir::ClosureKind { - // Fn is the closure kind that implements all three traits - rust_ir::ClosureKind::Fn - } - fn closure_inputs_and_output( - &self, - _closure_id: chalk_ir::ClosureId<Interner>, - substs: &chalk_ir::Substitution<Interner>, - ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { - let sig_ty = ClosureSubst(substs).sig_ty(); - let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr"); - let io = rust_ir::FnDefInputsAndOutputDatum { - argument_types: sig.params().to_vec(), - return_type: sig.ret().clone(), - }; - chalk_ir::Binders::empty(Interner, io.shifted_in(Interner)) - } - fn closure_upvars( - &self, - _closure_id: chalk_ir::ClosureId<Interner>, - _substs: &chalk_ir::Substitution<Interner>, - ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { - let ty = TyBuilder::unit(); - chalk_ir::Binders::empty(Interner, ty) - } - fn closure_fn_substitution( - &self, - _closure_id: chalk_ir::ClosureId<Interner>, - _substs: &chalk_ir::Substitution<Interner>, - ) -> chalk_ir::Substitution<Interner> { - Substitution::empty(Interner) - } - - fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { - let id = from_chalk_trait_id(trait_id); - self.db.trait_signature(id).name.display(self.db, self.edition()).to_string() - } - fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String { - let edition = self.edition(); - match adt_id { - hir_def::AdtId::StructId(id) => { - self.db.struct_signature(id).name.display(self.db, edition).to_string() - } - hir_def::AdtId::EnumId(id) => { - self.db.enum_signature(id).name.display(self.db, edition).to_string() - } - hir_def::AdtId::UnionId(id) => { - self.db.union_signature(id).name.display(self.db, edition).to_string() - } - } - } - fn adt_size_align(&self, _id: chalk_ir::AdtId<Interner>) -> Arc<rust_ir::AdtSizeAlign> { - // FIXME - Arc::new(rust_ir::AdtSizeAlign::from_one_zst(false)) - } - fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String { - let id = self.db.associated_ty_data(from_assoc_type_id(assoc_ty_id)).name; - self.db.type_alias_signature(id).name.display(self.db, self.edition()).to_string() - } - fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String { - format!("Opaque_{:?}", opaque_ty_id.0) - } - fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId<Interner>) -> String { - format!("fn_{:?}", fn_def_id.0) - } - fn coroutine_datum( - &self, - id: chalk_ir::CoroutineId<Interner>, - ) -> Arc<chalk_solve::rust_ir::CoroutineDatum<Interner>> { - let InternedCoroutine(parent, expr) = self.db.lookup_intern_coroutine(id.into()); - - // We fill substitution with unknown type, because we only need to know whether the generic - // params are types or consts to build `Binders` and those being filled up are for - // `resume_type`, `yield_type`, and `return_type` of the coroutine in question. - let subst = TyBuilder::subst_for_coroutine(self.db, parent).fill_with_unknown().build(); - - let len = subst.len(Interner); - let input_output = rust_ir::CoroutineInputOutputDatum { - resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 3)) - .intern(Interner), - yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 2)) - .intern(Interner), - return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 1)) - .intern(Interner), - // FIXME: calculate upvars - upvars: vec![], - }; - - let it = subst - .iter(Interner) - .map(|it| it.constant(Interner).map(|c| c.data(Interner).ty.clone())); - let input_output = crate::make_type_and_const_binders(it, input_output); - - let movability = match self.db.body(parent)[expr] { - hir_def::hir::Expr::Closure { - closure_kind: hir_def::hir::ClosureKind::Coroutine(movability), - .. - } => movability, - _ => unreachable!("non coroutine expression interned as coroutine"), - }; - let movability = match movability { - Movability::Static => rust_ir::Movability::Static, - Movability::Movable => rust_ir::Movability::Movable, - }; - - Arc::new(rust_ir::CoroutineDatum { movability, input_output }) - } - fn coroutine_witness_datum( - &self, - id: chalk_ir::CoroutineId<Interner>, - ) -> Arc<chalk_solve::rust_ir::CoroutineWitnessDatum<Interner>> { - // FIXME: calculate inner types - let inner_types = - rust_ir::CoroutineWitnessExistential { types: wrap_empty_binders(vec![]) }; - - let InternedCoroutine(parent, _) = self.db.lookup_intern_coroutine(id.into()); - // See the comment in `coroutine_datum()` for unknown types. - let subst = TyBuilder::subst_for_coroutine(self.db, parent).fill_with_unknown().build(); - let it = subst - .iter(Interner) - .map(|it| it.constant(Interner).map(|c| c.data(Interner).ty.clone())); - let inner_types = crate::make_type_and_const_binders(it, inner_types); - - Arc::new(rust_ir::CoroutineWitnessDatum { inner_types }) - } - - fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> { - &self.db - } -} - -impl ChalkContext<'_> { - fn edition(&self) -> Edition { - self.krate.data(self.db).edition - } - - fn for_trait_impls( - &self, - trait_id: hir_def::TraitId, - self_ty_fp: Option<TyFingerprint>, - mut f: impl FnMut(&TraitImpls) -> ControlFlow<()>, - ) -> ControlFlow<()> { - // Note: Since we're using `impls_for_trait` and `impl_provided_for`, - // only impls where the trait can be resolved should ever reach Chalk. - // `impl_datum` relies on that and will panic if the trait can't be resolved. - let in_deps = self.db.trait_impls_in_deps(self.krate); - let in_self = self.db.trait_impls_in_crate(self.krate); - let trait_module = trait_id.module(self.db); - let type_module = match self_ty_fp { - Some(TyFingerprint::Adt(adt_id)) => Some(adt_id.module(self.db)), - Some(TyFingerprint::ForeignType(type_id)) => { - Some(from_foreign_def_id(type_id).module(self.db)) - } - Some(TyFingerprint::Dyn(trait_id)) => Some(trait_id.module(self.db)), - _ => None, - }; - - let mut def_blocks = - [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())]; - - let block_impls = iter::successors(self.block, |&block_id| { - cov_mark::hit!(block_local_impls); - block_id.loc(self.db).module.containing_block() - }) - .inspect(|&block_id| { - // make sure we don't search the same block twice - def_blocks.iter_mut().for_each(|block| { - if *block == Some(block_id) { - *block = None; - } - }); - }) - .filter_map(|block_id| self.db.trait_impls_in_block(block_id)); - f(&in_self)?; - for it in in_deps.iter().map(ops::Deref::deref) { - f(it)?; - } - for it in block_impls { - f(&it)?; - } - for it in def_blocks.into_iter().flatten().filter_map(|it| self.db.trait_impls_in_block(it)) - { - f(&it)?; - } - ControlFlow::Continue(()) - } -} - impl chalk_ir::UnificationDatabase<Interner> for &dyn HirDatabase { fn fn_def_variance( &self, @@ -610,15 +54,6 @@ impl chalk_ir::UnificationDatabase<Interner> for &dyn HirDatabase { } } -pub(crate) fn program_clauses_for_chalk_env_query( - db: &dyn HirDatabase, - krate: Crate, - block: Option<BlockId>, - environment: chalk_ir::Environment<Interner>, -) -> chalk_ir::ProgramClauses<Interner> { - chalk_solve::program_clauses_for_env(&ChalkContext { db, krate, block }, &environment) -} - pub(crate) fn associated_ty_data_query( db: &dyn HirDatabase, type_alias: TypeAliasId, @@ -749,31 +184,6 @@ fn well_known_trait_from_lang_item(item: LangItem) -> Option<WellKnownTrait> { }) } -fn lang_item_from_well_known_trait(trait_: WellKnownTrait) -> LangItem { - match trait_ { - WellKnownTrait::Clone => LangItem::Clone, - WellKnownTrait::CoerceUnsized => LangItem::CoerceUnsized, - WellKnownTrait::Copy => LangItem::Copy, - WellKnownTrait::DiscriminantKind => LangItem::DiscriminantKind, - WellKnownTrait::DispatchFromDyn => LangItem::DispatchFromDyn, - WellKnownTrait::Drop => LangItem::Drop, - WellKnownTrait::Fn => LangItem::Fn, - WellKnownTrait::FnMut => LangItem::FnMut, - WellKnownTrait::FnOnce => LangItem::FnOnce, - WellKnownTrait::AsyncFn => LangItem::AsyncFn, - WellKnownTrait::AsyncFnMut => LangItem::AsyncFnMut, - WellKnownTrait::AsyncFnOnce => LangItem::AsyncFnOnce, - WellKnownTrait::Coroutine => LangItem::Coroutine, - WellKnownTrait::Sized => LangItem::Sized, - WellKnownTrait::Tuple => LangItem::Tuple, - WellKnownTrait::Unpin => LangItem::Unpin, - WellKnownTrait::Unsize => LangItem::Unsize, - WellKnownTrait::Pointee => LangItem::PointeeTrait, - WellKnownTrait::FnPtr => LangItem::FnPtrTrait, - WellKnownTrait::Future => LangItem::Future, - } -} - pub(crate) fn adt_datum_query( db: &dyn HirDatabase, krate: Crate, |