aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/chalk_db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/chalk_db.rs')
-rw-r--r--crates/hir_ty/src/chalk_db.rs101
1 files changed, 61 insertions, 40 deletions
diff --git a/crates/hir_ty/src/chalk_db.rs b/crates/hir_ty/src/chalk_db.rs
index f5b2c5ff0..9d07ad597 100644
--- a/crates/hir_ty/src/chalk_db.rs
+++ b/crates/hir_ty/src/chalk_db.rs
@@ -4,13 +4,13 @@ use std::sync::Arc;
4 4
5use log::debug; 5use log::debug;
6 6
7use chalk_ir::{fold::shift::Shift, CanonicalVarKinds}; 7use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
8use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 8use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
9 9
10use base_db::{salsa::InternKey, CrateId}; 10use base_db::CrateId;
11use hir_def::{ 11use hir_def::{
12 lang_item::{lang_attr, LangItemTarget}, 12 lang_item::{lang_attr, LangItemTarget},
13 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, 13 AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
14}; 14};
15use hir_expand::name::name; 15use hir_expand::name::name;
16 16
@@ -18,16 +18,14 @@ use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id, make_only_type_binders, 20 from_assoc_type_id, make_only_type_binders,
21 mapping::{ 21 mapping::{from_chalk, ToChalk, TypeAliasAsValue},
22 convert_where_clauses, from_chalk, generic_predicate_to_inline_bound, ToChalk,
23 TypeAliasAsValue,
24 },
25 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 22 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
26 to_assoc_type_id, to_chalk_trait_id, 23 to_assoc_type_id, to_chalk_trait_id,
27 traits::ChalkContext, 24 traits::ChalkContext,
28 utils::generics, 25 utils::generics,
29 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy, 26 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy,
30 Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause, 27 ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
28 TyExt, TyKind, WhereClause,
31}; 29};
32 30
33pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 31pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
@@ -39,7 +37,6 @@ pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
39pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 37pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
40pub(crate) type TraitId = chalk_ir::TraitId<Interner>; 38pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
41pub(crate) type AdtId = chalk_ir::AdtId<Interner>; 39pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
42pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
43pub(crate) type ImplId = chalk_ir::ImplId<Interner>; 40pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
44pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; 41pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
45pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 42pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
@@ -679,38 +676,62 @@ pub(crate) fn adt_variance_query(
679 ) 676 )
680} 677}
681 678
682impl From<FnDefId> for crate::db::InternedCallableDefId { 679pub(super) fn convert_where_clauses(
683 fn from(fn_def_id: FnDefId) -> Self { 680 db: &dyn HirDatabase,
684 InternKey::from_intern_id(fn_def_id.0) 681 def: GenericDefId,
685 } 682 substs: &Substitution,
686} 683) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
687 684 let generic_predicates = db.generic_predicates(def);
688impl From<crate::db::InternedCallableDefId> for FnDefId { 685 let mut result = Vec::with_capacity(generic_predicates.len());
689 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { 686 for pred in generic_predicates.iter() {
690 chalk_ir::FnDefId(callable_def_id.as_intern_id()) 687 result.push(pred.clone().substitute(&Interner, substs));
691 } 688 }
692} 689 result
693
694impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
695 fn from(id: OpaqueTyId) -> Self {
696 InternKey::from_intern_id(id.0)
697 }
698}
699
700impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
701 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
702 chalk_ir::OpaqueTyId(id.as_intern_id())
703 }
704}
705
706impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
707 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
708 Self::from_intern_id(id.0)
709 }
710} 690}
711 691
712impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { 692pub(super) fn generic_predicate_to_inline_bound(
713 fn from(id: crate::db::InternedClosureId) -> Self { 693 db: &dyn HirDatabase,
714 chalk_ir::ClosureId(id.as_intern_id()) 694 pred: &QuantifiedWhereClause,
695 self_ty: &Ty,
696) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
697 // An InlineBound is like a GenericPredicate, except the self type is left out.
698 // We don't have a special type for this, but Chalk does.
699 let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE);
700 let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
701 match pred {
702 WhereClause::Implemented(trait_ref) => {
703 if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in {
704 // we can only convert predicates back to type bounds if they
705 // have the expected self type
706 return None;
707 }
708 let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..]
709 .iter()
710 .map(|ty| ty.clone().cast(&Interner))
711 .collect();
712 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
713 Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
714 }
715 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
716 if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in {
717 return None;
718 }
719 let trait_ = projection_ty.trait_(db);
720 let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
721 .iter()
722 .map(|ty| ty.clone().cast(&Interner))
723 .collect();
724 let alias_eq_bound = rust_ir::AliasEqBound {
725 value: ty.clone(),
726 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
727 associated_ty_id: projection_ty.associated_ty_id,
728 parameters: Vec::new(), // FIXME we don't support generic associated types yet
729 };
730 Some(chalk_ir::Binders::new(
731 binders,
732 rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
733 ))
734 }
735 _ => None,
715 } 736 }
716} 737}