aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_ty/src/chalk_db.rs101
-rw-r--r--crates/hir_ty/src/mapping.rs92
2 files changed, 93 insertions, 100 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}
diff --git a/crates/hir_ty/src/mapping.rs b/crates/hir_ty/src/mapping.rs
index f57115de6..37c935194 100644
--- a/crates/hir_ty/src/mapping.rs
+++ b/crates/hir_ty/src/mapping.rs
@@ -3,16 +3,12 @@
3//! Chalk (in both directions); plus some helper functions for more specialized 3//! Chalk (in both directions); plus some helper functions for more specialized
4//! conversions. 4//! conversions.
5 5
6use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex};
7use chalk_solve::rust_ir; 6use chalk_solve::rust_ir;
8 7
9use base_db::salsa::InternKey; 8use base_db::salsa::InternKey;
10use hir_def::{GenericDefId, TypeAliasId}; 9use hir_def::TypeAliasId;
11 10
12use crate::{ 11use crate::{chalk_db, db::HirDatabase, CallableDefId, FnDefId, Interner, OpaqueTyId};
13 chalk_db, db::HirDatabase, AliasEq, AliasTy, CallableDefId, FnDefId, Interner, ProjectionTyExt,
14 QuantifiedWhereClause, Substitution, Ty, WhereClause,
15};
16 12
17pub(crate) trait ToChalk { 13pub(crate) trait ToChalk {
18 type Chalk; 14 type Chalk;
@@ -80,62 +76,38 @@ impl ToChalk for TypeAliasAsValue {
80 } 76 }
81} 77}
82 78
83pub(super) fn convert_where_clauses( 79impl From<FnDefId> for crate::db::InternedCallableDefId {
84 db: &dyn HirDatabase, 80 fn from(fn_def_id: FnDefId) -> Self {
85 def: GenericDefId, 81 InternKey::from_intern_id(fn_def_id.0)
86 substs: &Substitution,
87) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
88 let generic_predicates = db.generic_predicates(def);
89 let mut result = Vec::with_capacity(generic_predicates.len());
90 for pred in generic_predicates.iter() {
91 result.push(pred.clone().substitute(&Interner, substs));
92 } 82 }
93 result
94} 83}
95 84
96pub(super) fn generic_predicate_to_inline_bound( 85impl From<crate::db::InternedCallableDefId> for FnDefId {
97 db: &dyn HirDatabase, 86 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
98 pred: &QuantifiedWhereClause, 87 chalk_ir::FnDefId(callable_def_id.as_intern_id())
99 self_ty: &Ty, 88 }
100) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { 89}
101 // An InlineBound is like a GenericPredicate, except the self type is left out. 90
102 // We don't have a special type for this, but Chalk does. 91impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
103 let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); 92 fn from(id: OpaqueTyId) -> Self {
104 let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); 93 InternKey::from_intern_id(id.0)
105 match pred { 94 }
106 WhereClause::Implemented(trait_ref) => { 95}
107 if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { 96
108 // we can only convert predicates back to type bounds if they 97impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
109 // have the expected self type 98 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
110 return None; 99 chalk_ir::OpaqueTyId(id.as_intern_id())
111 } 100 }
112 let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] 101}
113 .iter() 102
114 .map(|ty| ty.clone().cast(&Interner)) 103impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
115 .collect(); 104 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
116 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 105 Self::from_intern_id(id.0)
117 Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) 106 }
118 } 107}
119 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 108
120 if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { 109impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
121 return None; 110 fn from(id: crate::db::InternedClosureId) -> Self {
122 } 111 chalk_ir::ClosureId(id.as_intern_id())
123 let trait_ = projection_ty.trait_(db);
124 let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
125 .iter()
126 .map(|ty| ty.clone().cast(&Interner))
127 .collect();
128 let alias_eq_bound = rust_ir::AliasEqBound {
129 value: ty.clone(),
130 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
131 associated_ty_id: projection_ty.associated_ty_id,
132 parameters: Vec::new(), // FIXME we don't support generic associated types yet
133 };
134 Some(chalk_ir::Binders::new(
135 binders,
136 rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
137 ))
138 }
139 _ => None,
140 } 112 }
141} 113}