diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/chalk_cast.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/chalk_db.rs (renamed from crates/hir_ty/src/traits/chalk.rs) | 150 | ||||
-rw-r--r-- | crates/hir_ty/src/db.rs | 52 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 14 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/interner.rs (renamed from crates/hir_ty/src/traits/chalk/interner.rs) | 42 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 108 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/mapping.rs | 154 | ||||
-rw-r--r-- | crates/hir_ty/src/primitive.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/tls.rs (renamed from crates/hir_ty/src/traits/chalk/tls.rs) | 14 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 131 |
14 files changed, 355 insertions, 361 deletions
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs deleted file mode 100644 index f27dee3fd..000000000 --- a/crates/hir_ty/src/chalk_cast.rs +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | //! Implementations of the Chalk `Cast` trait for our types. | ||
2 | |||
3 | use chalk_ir::interner::HasInterner; | ||
4 | |||
5 | use crate::{CallableSig, ReturnTypeImplTraits}; | ||
6 | |||
7 | macro_rules! has_interner { | ||
8 | ($t:ty) => { | ||
9 | impl HasInterner for $t { | ||
10 | type Interner = crate::Interner; | ||
11 | } | ||
12 | }; | ||
13 | } | ||
14 | |||
15 | has_interner!(CallableSig); | ||
16 | has_interner!(ReturnTypeImplTraits); | ||
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/chalk_db.rs index cd511477b..8f054d06b 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/chalk_db.rs | |||
@@ -1,50 +1,47 @@ | |||
1 | //! Conversion code from/to Chalk. | 1 | //! The implementation of `RustIrDatabase` for Chalk, which provides information |
2 | //! about the code that Chalk needs. | ||
2 | use std::sync::Arc; | 3 | use std::sync::Arc; |
3 | 4 | ||
4 | use log::debug; | 5 | use log::debug; |
5 | 6 | ||
6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds}; | 7 | use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 8 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 9 | ||
9 | use base_db::{salsa::InternKey, CrateId}; | 10 | use base_db::CrateId; |
10 | use hir_def::{ | 11 | use hir_def::{ |
11 | lang_item::{lang_attr, LangItemTarget}, | 12 | lang_item::{lang_attr, LangItemTarget}, |
12 | AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, | 13 | AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId, |
13 | }; | 14 | }; |
14 | use hir_expand::name::name; | 15 | use hir_expand::name::name; |
15 | 16 | ||
16 | use super::ChalkContext; | ||
17 | use crate::{ | 17 | 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, from_chalk_trait_id, make_only_type_binders, |
21 | mapping::{from_chalk, ToChalk, TypeAliasAsValue}, | ||
21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 22 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
22 | to_assoc_type_id, to_chalk_trait_id, | 23 | to_assoc_type_id, to_chalk_trait_id, |
24 | traits::ChalkContext, | ||
23 | utils::generics, | 25 | utils::generics, |
24 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, | 26 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy, |
25 | TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause, | 27 | ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, |
28 | TyExt, TyKind, WhereClause, | ||
26 | }; | 29 | }; |
27 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, TypeAliasAsValue}; | ||
28 | 30 | ||
29 | pub use self::interner::Interner; | 31 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; |
30 | pub(crate) use self::interner::*; | 32 | pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; |
31 | 33 | pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; | |
32 | pub(super) mod tls; | 34 | pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; |
33 | mod interner; | 35 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; |
34 | mod mapping; | 36 | |
35 | 37 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | |
36 | pub(crate) trait ToChalk { | 38 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; |
37 | type Chalk; | 39 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; |
38 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; | 40 | pub(crate) type ImplId = chalk_ir::ImplId<Interner>; |
39 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; | 41 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; |
40 | } | 42 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
41 | 43 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | |
42 | pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T | 44 | pub(crate) type Variances = chalk_ir::Variances<Interner>; |
43 | where | ||
44 | T: ToChalk<Chalk = ChalkT>, | ||
45 | { | ||
46 | T::from_chalk(db, chalk) | ||
47 | } | ||
48 | 45 | ||
49 | impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | 46 | impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { |
50 | fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> { | 47 | fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> { |
@@ -82,7 +79,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
82 | binders: &CanonicalVarKinds<Interner>, | 79 | binders: &CanonicalVarKinds<Interner>, |
83 | ) -> Vec<ImplId> { | 80 | ) -> Vec<ImplId> { |
84 | debug!("impls_for_trait {:?}", trait_id); | 81 | debug!("impls_for_trait {:?}", trait_id); |
85 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); | 82 | let trait_: hir_def::TraitId = from_chalk_trait_id(trait_id); |
86 | 83 | ||
87 | let ty: Ty = parameters[0].assert_ty_ref(&Interner).clone(); | 84 | let ty: Ty = parameters[0].assert_ty_ref(&Interner).clone(); |
88 | 85 | ||
@@ -164,7 +161,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
164 | Some(LangItemTarget::TraitId(trait_)) => trait_, | 161 | Some(LangItemTarget::TraitId(trait_)) => trait_, |
165 | _ => return None, | 162 | _ => return None, |
166 | }; | 163 | }; |
167 | Some(trait_.to_chalk(self.db)) | 164 | Some(to_chalk_trait_id(trait_)) |
168 | } | 165 | } |
169 | 166 | ||
170 | fn program_clauses_for_env( | 167 | fn program_clauses_for_env( |
@@ -311,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
311 | } | 308 | } |
312 | 309 | ||
313 | fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { | 310 | fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { |
314 | let id = from_chalk(self.db, trait_id); | 311 | let id = from_chalk_trait_id(trait_id); |
315 | self.db.trait_data(id).name.to_string() | 312 | self.db.trait_data(id).name.to_string() |
316 | } | 313 | } |
317 | fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String { | 314 | fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String { |
@@ -416,7 +413,7 @@ pub(crate) fn trait_datum_query( | |||
416 | trait_id: TraitId, | 413 | trait_id: TraitId, |
417 | ) -> Arc<TraitDatum> { | 414 | ) -> Arc<TraitDatum> { |
418 | debug!("trait_datum {:?}", trait_id); | 415 | debug!("trait_datum {:?}", trait_id); |
419 | let trait_: hir_def::TraitId = from_chalk(db, trait_id); | 416 | let trait_ = from_chalk_trait_id(trait_id); |
420 | let trait_data = db.trait_data(trait_); | 417 | let trait_data = db.trait_data(trait_); |
421 | debug!("trait {:?} = {:?}", trait_id, trait_data.name); | 418 | debug!("trait {:?} = {:?}", trait_id, trait_data.name); |
422 | let generic_params = generics(db.upcast(), trait_.into()); | 419 | let generic_params = generics(db.upcast(), trait_.into()); |
@@ -679,38 +676,65 @@ pub(crate) fn adt_variance_query( | |||
679 | ) | 676 | ) |
680 | } | 677 | } |
681 | 678 | ||
682 | impl From<FnDefId> for crate::db::InternedCallableDefId { | 679 | pub(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); | |
688 | impl 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 | |||
694 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | ||
695 | fn from(id: OpaqueTyId) -> Self { | ||
696 | InternKey::from_intern_id(id.0) | ||
697 | } | ||
698 | } | ||
699 | |||
700 | impl 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 | |||
706 | impl 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 | ||
712 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { | 692 | pub(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 { | ||
727 | trait_id: to_chalk_trait_id(trait_), | ||
728 | args_no_self, | ||
729 | }, | ||
730 | associated_ty_id: projection_ty.associated_ty_id, | ||
731 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
732 | }; | ||
733 | Some(chalk_ir::Binders::new( | ||
734 | binders, | ||
735 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
736 | )) | ||
737 | } | ||
738 | _ => None, | ||
715 | } | 739 | } |
716 | } | 740 | } |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 326c20240..1690926ad 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! The home of `HirDatabase`, which is the Salsa database containing all the |
2 | //! type inference-related queries. | ||
2 | 3 | ||
3 | use std::sync::Arc; | 4 | use std::sync::Arc; |
4 | 5 | ||
@@ -10,9 +11,9 @@ use hir_def::{ | |||
10 | use la_arena::ArenaMap; | 11 | use la_arena::ArenaMap; |
11 | 12 | ||
12 | use crate::{ | 13 | use crate::{ |
14 | chalk_db, | ||
13 | method_resolution::{InherentImpls, TraitImpls}, | 15 | method_resolution::{InherentImpls, TraitImpls}, |
14 | traits::chalk, | 16 | Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, Interner, PolyFnSig, |
15 | Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, | ||
16 | QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, | 17 | QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, |
17 | }; | 18 | }; |
18 | use hir_expand::name::Name; | 19 | use hir_expand::name::Name; |
@@ -94,33 +95,38 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
94 | #[salsa::interned] | 95 | #[salsa::interned] |
95 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; | 96 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; |
96 | 97 | ||
97 | #[salsa::invoke(chalk::associated_ty_data_query)] | 98 | #[salsa::invoke(chalk_db::associated_ty_data_query)] |
98 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; | 99 | fn associated_ty_data(&self, id: chalk_db::AssocTypeId) -> Arc<chalk_db::AssociatedTyDatum>; |
99 | 100 | ||
100 | #[salsa::invoke(chalk::trait_datum_query)] | 101 | #[salsa::invoke(chalk_db::trait_datum_query)] |
101 | fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc<chalk::TraitDatum>; | 102 | fn trait_datum(&self, krate: CrateId, trait_id: chalk_db::TraitId) |
103 | -> Arc<chalk_db::TraitDatum>; | ||
102 | 104 | ||
103 | #[salsa::invoke(chalk::struct_datum_query)] | 105 | #[salsa::invoke(chalk_db::struct_datum_query)] |
104 | fn struct_datum(&self, krate: CrateId, struct_id: chalk::AdtId) -> Arc<chalk::StructDatum>; | 106 | fn struct_datum( |
107 | &self, | ||
108 | krate: CrateId, | ||
109 | struct_id: chalk_db::AdtId, | ||
110 | ) -> Arc<chalk_db::StructDatum>; | ||
105 | 111 | ||
106 | #[salsa::invoke(crate::traits::chalk::impl_datum_query)] | 112 | #[salsa::invoke(chalk_db::impl_datum_query)] |
107 | fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; | 113 | fn impl_datum(&self, krate: CrateId, impl_id: chalk_db::ImplId) -> Arc<chalk_db::ImplDatum>; |
108 | 114 | ||
109 | #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] | 115 | #[salsa::invoke(chalk_db::fn_def_datum_query)] |
110 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>; | 116 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk_db::FnDefDatum>; |
111 | 117 | ||
112 | #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] | 118 | #[salsa::invoke(chalk_db::fn_def_variance_query)] |
113 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances; | 119 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk_db::Variances; |
114 | 120 | ||
115 | #[salsa::invoke(crate::traits::chalk::adt_variance_query)] | 121 | #[salsa::invoke(chalk_db::adt_variance_query)] |
116 | fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; | 122 | fn adt_variance(&self, krate: CrateId, adt_id: chalk_db::AdtId) -> chalk_db::Variances; |
117 | 123 | ||
118 | #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] | 124 | #[salsa::invoke(chalk_db::associated_ty_value_query)] |
119 | fn associated_ty_value( | 125 | fn associated_ty_value( |
120 | &self, | 126 | &self, |
121 | krate: CrateId, | 127 | krate: CrateId, |
122 | id: chalk::AssociatedTyValueId, | 128 | id: chalk_db::AssociatedTyValueId, |
123 | ) -> Arc<chalk::AssociatedTyValue>; | 129 | ) -> Arc<chalk_db::AssociatedTyValue>; |
124 | 130 | ||
125 | #[salsa::invoke(crate::traits::trait_solve_query)] | 131 | #[salsa::invoke(crate::traits::trait_solve_query)] |
126 | fn trait_solve( | 132 | fn trait_solve( |
@@ -129,12 +135,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
129 | goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, | 135 | goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, |
130 | ) -> Option<crate::Solution>; | 136 | ) -> Option<crate::Solution>; |
131 | 137 | ||
132 | #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] | 138 | #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] |
133 | fn program_clauses_for_chalk_env( | 139 | fn program_clauses_for_chalk_env( |
134 | &self, | 140 | &self, |
135 | krate: CrateId, | 141 | krate: CrateId, |
136 | env: chalk_ir::Environment<chalk::Interner>, | 142 | env: chalk_ir::Environment<Interner>, |
137 | ) -> chalk_ir::ProgramClauses<chalk::Interner>; | 143 | ) -> chalk_ir::ProgramClauses<Interner>; |
138 | } | 144 | } |
139 | 145 | ||
140 | fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { | 146 | fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { |
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 86f937e1d..84fc8ce14 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Type inference-based diagnostics. |
2 | mod expr; | 2 | mod expr; |
3 | mod match_check; | 3 | mod match_check; |
4 | mod unsafe_check; | 4 | mod unsafe_check; |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 92224b46b..e7c9dabc2 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! The `HirDisplay` trait, which serves two purposes: Turning various bits from |
2 | //! HIR back into source code, and just displaying them for debugging/testing | ||
3 | //! purposes. | ||
2 | 4 | ||
3 | use std::{ | 5 | use std::{ |
4 | array, | 6 | array, |
@@ -20,11 +22,11 @@ use hir_expand::name::Name; | |||
20 | 22 | ||
21 | use crate::{ | 23 | use crate::{ |
22 | const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id, | 24 | const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id, |
23 | from_placeholder_idx, lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id, | 25 | from_placeholder_idx, lt_from_placeholder_idx, mapping::from_chalk, primitive, subst_prefix, |
24 | traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, | 26 | to_assoc_type_id, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, Const, |
25 | CallableSig, Const, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, | 27 | ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, |
26 | LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, | 28 | LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, |
27 | QuantifiedWhereClause, Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause, | 29 | Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | pub struct HirFormatter<'a> { | 32 | pub struct HirFormatter<'a> { |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 7961f4a52..50497eecb 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -17,10 +17,11 @@ use syntax::ast::RangeOp; | |||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, dummy_usize_const, | 18 | autoderef, dummy_usize_const, |
19 | lower::lower_to_chalk_mutability, | 19 | lower::lower_to_chalk_mutability, |
20 | mapping::from_chalk, | ||
20 | method_resolution, op, | 21 | method_resolution, op, |
21 | primitive::{self, UintTy}, | 22 | primitive::{self, UintTy}, |
22 | static_lifetime, to_chalk_trait_id, | 23 | static_lifetime, to_chalk_trait_id, |
23 | traits::{chalk::from_chalk, FnTrait}, | 24 | traits::FnTrait, |
24 | utils::{generics, Generics}, | 25 | utils::{generics, Generics}, |
25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, | 26 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, |
26 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, | 27 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, |
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/interner.rs index b6a3cec6d..a1656115d 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/interner.rs | |||
@@ -1,8 +1,7 @@ | |||
1 | //! Implementation of the Chalk `Interner` trait, which allows customizing the | 1 | //! Implementation of the Chalk `Interner` trait, which allows customizing the |
2 | //! representation of the various objects Chalk deals with (types, goals etc.). | 2 | //! representation of the various objects Chalk deals with (types, goals etc.). |
3 | 3 | ||
4 | use super::tls; | 4 | use crate::{chalk_db, tls, GenericArg}; |
5 | use crate::GenericArg; | ||
6 | use base_db::salsa::InternId; | 5 | use base_db::salsa::InternId; |
7 | use chalk_ir::{Goal, GoalData}; | 6 | use chalk_ir::{Goal, GoalData}; |
8 | use hir_def::{ | 7 | use hir_def::{ |
@@ -15,21 +14,6 @@ use std::{fmt, sync::Arc}; | |||
15 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] | 14 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] |
16 | pub struct Interner; | 15 | pub struct Interner; |
17 | 16 | ||
18 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | ||
19 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; | ||
20 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; | ||
21 | pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; | ||
22 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; | ||
23 | pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; | ||
24 | pub(crate) type ImplId = chalk_ir::ImplId<Interner>; | ||
25 | pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; | ||
26 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; | ||
27 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | ||
28 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | ||
29 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
30 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | ||
31 | pub(crate) type Variances = chalk_ir::Variances<Interner>; | ||
32 | |||
33 | #[derive(PartialEq, Eq, Hash, Debug)] | 17 | #[derive(PartialEq, Eq, Hash, Debug)] |
34 | pub struct InternedWrapper<T>(T); | 18 | pub struct InternedWrapper<T>(T); |
35 | 19 | ||
@@ -76,15 +60,24 @@ impl chalk_ir::interner::Interner for Interner { | |||
76 | type Identifier = TypeAliasId; | 60 | type Identifier = TypeAliasId; |
77 | type FnAbi = (); | 61 | type FnAbi = (); |
78 | 62 | ||
79 | fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { | 63 | fn debug_adt_id( |
64 | type_kind_id: chalk_db::AdtId, | ||
65 | fmt: &mut fmt::Formatter<'_>, | ||
66 | ) -> Option<fmt::Result> { | ||
80 | tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) | 67 | tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) |
81 | } | 68 | } |
82 | 69 | ||
83 | fn debug_trait_id(type_kind_id: TraitId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { | 70 | fn debug_trait_id( |
71 | type_kind_id: chalk_db::TraitId, | ||
72 | fmt: &mut fmt::Formatter<'_>, | ||
73 | ) -> Option<fmt::Result> { | ||
84 | tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt))) | 74 | tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt))) |
85 | } | 75 | } |
86 | 76 | ||
87 | fn debug_assoc_type_id(id: AssocTypeId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { | 77 | fn debug_assoc_type_id( |
78 | id: chalk_db::AssocTypeId, | ||
79 | fmt: &mut fmt::Formatter<'_>, | ||
80 | ) -> Option<fmt::Result> { | ||
88 | tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt))) | 81 | tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt))) |
89 | } | 82 | } |
90 | 83 | ||
@@ -419,3 +412,12 @@ impl chalk_ir::interner::Interner for Interner { | |||
419 | impl chalk_ir::interner::HasInterner for Interner { | 412 | impl chalk_ir::interner::HasInterner for Interner { |
420 | type Interner = Self; | 413 | type Interner = Self; |
421 | } | 414 | } |
415 | |||
416 | #[macro_export] | ||
417 | macro_rules! has_interner { | ||
418 | ($t:ty) => { | ||
419 | impl HasInterner for $t { | ||
420 | type Interner = crate::Interner; | ||
421 | } | ||
422 | }; | ||
423 | } | ||
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index beb58d711..113234fa4 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -7,21 +7,23 @@ macro_rules! eprintln { | |||
7 | } | 7 | } |
8 | 8 | ||
9 | mod autoderef; | 9 | mod autoderef; |
10 | pub mod primitive; | ||
11 | pub mod traits; | ||
12 | pub mod method_resolution; | ||
13 | mod op; | ||
14 | mod lower; | ||
15 | pub(crate) mod infer; | ||
16 | pub(crate) mod utils; | ||
17 | mod chalk_cast; | ||
18 | mod chalk_ext; | ||
19 | mod builder; | 10 | mod builder; |
11 | mod chalk_db; | ||
12 | mod chalk_ext; | ||
13 | mod infer; | ||
14 | mod interner; | ||
15 | mod lower; | ||
16 | mod mapping; | ||
17 | mod op; | ||
18 | mod tls; | ||
19 | mod utils; | ||
20 | mod walk; | 20 | mod walk; |
21 | |||
22 | pub mod display; | ||
23 | pub mod db; | 21 | pub mod db; |
24 | pub mod diagnostics; | 22 | pub mod diagnostics; |
23 | pub mod display; | ||
24 | pub mod method_resolution; | ||
25 | pub mod primitive; | ||
26 | pub mod traits; | ||
25 | 27 | ||
26 | #[cfg(test)] | 28 | #[cfg(test)] |
27 | mod tests; | 29 | mod tests; |
@@ -30,16 +32,12 @@ mod test_db; | |||
30 | 32 | ||
31 | use std::sync::Arc; | 33 | use std::sync::Arc; |
32 | 34 | ||
33 | use base_db::salsa; | ||
34 | use chalk_ir::{ | 35 | use chalk_ir::{ |
35 | fold::{Fold, Shift}, | 36 | fold::{Fold, Shift}, |
36 | interner::HasInterner, | 37 | interner::HasInterner, |
37 | UintTy, | 38 | UintTy, |
38 | }; | 39 | }; |
39 | use hir_def::{ | 40 | use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId}; |
40 | expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, | ||
41 | TypeParamId, | ||
42 | }; | ||
43 | 41 | ||
44 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; | 42 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; |
45 | 43 | ||
@@ -47,11 +45,17 @@ pub use autoderef::autoderef; | |||
47 | pub use builder::TyBuilder; | 45 | pub use builder::TyBuilder; |
48 | pub use chalk_ext::*; | 46 | pub use chalk_ext::*; |
49 | pub use infer::{could_unify, InferenceResult}; | 47 | pub use infer::{could_unify, InferenceResult}; |
48 | pub use interner::Interner; | ||
50 | pub use lower::{ | 49 | pub use lower::{ |
51 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 50 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
52 | TyDefId, TyLoweringContext, ValueTyDefId, | 51 | TyDefId, TyLoweringContext, ValueTyDefId, |
53 | }; | 52 | }; |
54 | pub use traits::{chalk::Interner, TraitEnvironment}; | 53 | pub use mapping::{ |
54 | const_from_placeholder_idx, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, | ||
55 | from_placeholder_idx, lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id, | ||
56 | to_foreign_def_id, to_placeholder_idx, | ||
57 | }; | ||
58 | pub use traits::TraitEnvironment; | ||
55 | pub use walk::TypeWalk; | 59 | pub use walk::TypeWalk; |
56 | 60 | ||
57 | pub use chalk_ir::{ | 61 | pub use chalk_ir::{ |
@@ -94,6 +98,10 @@ pub type ConstValue = chalk_ir::ConstValue<Interner>; | |||
94 | pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>; | 98 | pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>; |
95 | 99 | ||
96 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | 100 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; |
101 | pub type TraitRef = chalk_ir::TraitRef<Interner>; | ||
102 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
103 | pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>; | ||
104 | pub type Canonical<T> = chalk_ir::Canonical<T>; | ||
97 | 105 | ||
98 | pub type FnSig = chalk_ir::FnSig<Interner>; | 106 | pub type FnSig = chalk_ir::FnSig<Interner>; |
99 | 107 | ||
@@ -118,14 +126,14 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
118 | generics(db.upcast(), id.parent).param_idx(id) | 126 | generics(db.upcast(), id.parent).param_idx(id) |
119 | } | 127 | } |
120 | 128 | ||
121 | pub fn wrap_empty_binders<T>(value: T) -> Binders<T> | 129 | pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T> |
122 | where | 130 | where |
123 | T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>, | 131 | T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>, |
124 | { | 132 | { |
125 | Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE)) | 133 | Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE)) |
126 | } | 134 | } |
127 | 135 | ||
128 | pub fn make_only_type_binders<T: HasInterner<Interner = Interner>>( | 136 | pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>( |
129 | num_vars: usize, | 137 | num_vars: usize, |
130 | value: T, | 138 | value: T, |
131 | ) -> Binders<T> { | 139 | ) -> Binders<T> { |
@@ -153,14 +161,6 @@ pub fn make_canonical<T: HasInterner<Interner = Interner>>( | |||
153 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | 161 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } |
154 | } | 162 | } |
155 | 163 | ||
156 | pub type TraitRef = chalk_ir::TraitRef<Interner>; | ||
157 | |||
158 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
159 | |||
160 | pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>; | ||
161 | |||
162 | pub type Canonical<T> = chalk_ir::Canonical<T>; | ||
163 | |||
164 | /// A function signature as seen by type inference: Several parameter types and | 164 | /// A function signature as seen by type inference: Several parameter types and |
165 | /// one return type. | 165 | /// one return type. |
166 | #[derive(Clone, PartialEq, Eq, Debug)] | 166 | #[derive(Clone, PartialEq, Eq, Debug)] |
@@ -169,6 +169,8 @@ pub struct CallableSig { | |||
169 | is_varargs: bool, | 169 | is_varargs: bool, |
170 | } | 170 | } |
171 | 171 | ||
172 | has_interner!(CallableSig); | ||
173 | |||
172 | /// A polymorphic function signature. | 174 | /// A polymorphic function signature. |
173 | pub type PolyFnSig = Binders<CallableSig>; | 175 | pub type PolyFnSig = Binders<CallableSig>; |
174 | 176 | ||
@@ -232,61 +234,13 @@ pub struct ReturnTypeImplTraits { | |||
232 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, | 234 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, |
233 | } | 235 | } |
234 | 236 | ||
237 | has_interner!(ReturnTypeImplTraits); | ||
238 | |||
235 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 239 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
236 | pub(crate) struct ReturnTypeImplTrait { | 240 | pub(crate) struct ReturnTypeImplTrait { |
237 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, | 241 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, |
238 | } | 242 | } |
239 | 243 | ||
240 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | ||
241 | chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) | ||
242 | } | ||
243 | |||
244 | pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { | ||
245 | salsa::InternKey::from_intern_id(id.0) | ||
246 | } | ||
247 | |||
248 | pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | ||
249 | chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) | ||
250 | } | ||
251 | |||
252 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | ||
253 | salsa::InternKey::from_intern_id(id.0) | ||
254 | } | ||
255 | |||
256 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
257 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
258 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
259 | db.lookup_intern_type_param_id(interned_id) | ||
260 | } | ||
261 | |||
262 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | ||
263 | let interned_id = db.intern_type_param_id(id); | ||
264 | PlaceholderIndex { | ||
265 | ui: chalk_ir::UniverseIndex::ROOT, | ||
266 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | ||
267 | } | ||
268 | } | ||
269 | |||
270 | pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { | ||
271 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
272 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
273 | db.lookup_intern_lifetime_param_id(interned_id) | ||
274 | } | ||
275 | |||
276 | pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId { | ||
277 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
278 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
279 | db.lookup_intern_const_param_id(interned_id) | ||
280 | } | ||
281 | |||
282 | pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { | ||
283 | chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) | ||
284 | } | ||
285 | |||
286 | pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { | ||
287 | salsa::InternKey::from_intern_id(id.0) | ||
288 | } | ||
289 | |||
290 | pub fn static_lifetime() -> Lifetime { | 244 | pub fn static_lifetime() -> Lifetime { |
291 | LifetimeData::Static.intern(&Interner) | 245 | LifetimeData::Static.intern(&Interner) |
292 | } | 246 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 8a22d9ea3..a035686bc 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -27,13 +27,14 @@ use stdx::impl_from; | |||
27 | 27 | ||
28 | use crate::{ | 28 | use crate::{ |
29 | db::HirDatabase, | 29 | db::HirDatabase, |
30 | dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, | 30 | dummy_usize_const, |
31 | traits::chalk::{Interner, ToChalk}, | 31 | mapping::ToChalk, |
32 | static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, | ||
32 | utils::{ | 33 | utils::{ |
33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics, | 34 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics, |
34 | }, | 35 | }, |
35 | AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, | 36 | AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, |
36 | FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, | 37 | FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, |
37 | QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, | 38 | QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, |
38 | TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, | 39 | TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, |
39 | }; | 40 | }; |
diff --git a/crates/hir_ty/src/mapping.rs b/crates/hir_ty/src/mapping.rs new file mode 100644 index 000000000..5e86fafe5 --- /dev/null +++ b/crates/hir_ty/src/mapping.rs | |||
@@ -0,0 +1,154 @@ | |||
1 | //! This module contains the implementations of the `ToChalk` trait, which | ||
2 | //! handles conversion between our data types and their corresponding types in | ||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | ||
4 | //! conversions. | ||
5 | |||
6 | use chalk_solve::rust_ir; | ||
7 | |||
8 | use base_db::salsa::{self, InternKey}; | ||
9 | use hir_def::{ConstParamId, LifetimeParamId, TraitId, TypeAliasId, TypeParamId}; | ||
10 | |||
11 | use crate::{ | ||
12 | chalk_db, db::HirDatabase, AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId, | ||
13 | Interner, OpaqueTyId, PlaceholderIndex, | ||
14 | }; | ||
15 | |||
16 | pub(crate) trait ToChalk { | ||
17 | type Chalk; | ||
18 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; | ||
19 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; | ||
20 | } | ||
21 | |||
22 | pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T | ||
23 | where | ||
24 | T: ToChalk<Chalk = ChalkT>, | ||
25 | { | ||
26 | T::from_chalk(db, chalk) | ||
27 | } | ||
28 | |||
29 | impl ToChalk for hir_def::ImplId { | ||
30 | type Chalk = chalk_db::ImplId; | ||
31 | |||
32 | fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::ImplId { | ||
33 | chalk_ir::ImplId(self.as_intern_id()) | ||
34 | } | ||
35 | |||
36 | fn from_chalk(_db: &dyn HirDatabase, impl_id: chalk_db::ImplId) -> hir_def::ImplId { | ||
37 | InternKey::from_intern_id(impl_id.0) | ||
38 | } | ||
39 | } | ||
40 | |||
41 | impl ToChalk for CallableDefId { | ||
42 | type Chalk = FnDefId; | ||
43 | |||
44 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { | ||
45 | db.intern_callable_def(self).into() | ||
46 | } | ||
47 | |||
48 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { | ||
49 | db.lookup_intern_callable_def(fn_def_id.into()) | ||
50 | } | ||
51 | } | ||
52 | |||
53 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); | ||
54 | |||
55 | impl ToChalk for TypeAliasAsValue { | ||
56 | type Chalk = chalk_db::AssociatedTyValueId; | ||
57 | |||
58 | fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::AssociatedTyValueId { | ||
59 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) | ||
60 | } | ||
61 | |||
62 | fn from_chalk( | ||
63 | _db: &dyn HirDatabase, | ||
64 | assoc_ty_value_id: chalk_db::AssociatedTyValueId, | ||
65 | ) -> TypeAliasAsValue { | ||
66 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
67 | } | ||
68 | } | ||
69 | |||
70 | impl From<FnDefId> for crate::db::InternedCallableDefId { | ||
71 | fn from(fn_def_id: FnDefId) -> Self { | ||
72 | InternKey::from_intern_id(fn_def_id.0) | ||
73 | } | ||
74 | } | ||
75 | |||
76 | impl From<crate::db::InternedCallableDefId> for FnDefId { | ||
77 | fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { | ||
78 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) | ||
79 | } | ||
80 | } | ||
81 | |||
82 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | ||
83 | fn from(id: OpaqueTyId) -> Self { | ||
84 | InternKey::from_intern_id(id.0) | ||
85 | } | ||
86 | } | ||
87 | |||
88 | impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { | ||
89 | fn from(id: crate::db::InternedOpaqueTyId) -> Self { | ||
90 | chalk_ir::OpaqueTyId(id.as_intern_id()) | ||
91 | } | ||
92 | } | ||
93 | |||
94 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId { | ||
95 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { | ||
96 | Self::from_intern_id(id.0) | ||
97 | } | ||
98 | } | ||
99 | |||
100 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { | ||
101 | fn from(id: crate::db::InternedClosureId) -> Self { | ||
102 | chalk_ir::ClosureId(id.as_intern_id()) | ||
103 | } | ||
104 | } | ||
105 | |||
106 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | ||
107 | chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) | ||
108 | } | ||
109 | |||
110 | pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { | ||
111 | salsa::InternKey::from_intern_id(id.0) | ||
112 | } | ||
113 | |||
114 | pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | ||
115 | chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) | ||
116 | } | ||
117 | |||
118 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | ||
119 | salsa::InternKey::from_intern_id(id.0) | ||
120 | } | ||
121 | |||
122 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
123 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
124 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
125 | db.lookup_intern_type_param_id(interned_id) | ||
126 | } | ||
127 | |||
128 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | ||
129 | let interned_id = db.intern_type_param_id(id); | ||
130 | PlaceholderIndex { | ||
131 | ui: chalk_ir::UniverseIndex::ROOT, | ||
132 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | ||
133 | } | ||
134 | } | ||
135 | |||
136 | pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { | ||
137 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
138 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
139 | db.lookup_intern_lifetime_param_id(interned_id) | ||
140 | } | ||
141 | |||
142 | pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId { | ||
143 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
144 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
145 | db.lookup_intern_const_param_id(interned_id) | ||
146 | } | ||
147 | |||
148 | pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { | ||
149 | chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) | ||
150 | } | ||
151 | |||
152 | pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { | ||
153 | salsa::InternKey::from_intern_id(id.0) | ||
154 | } | ||
diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs index 2449addfb..d7f48c69a 100644 --- a/crates/hir_ty/src/primitive.rs +++ b/crates/hir_ty/src/primitive.rs | |||
@@ -1,7 +1,4 @@ | |||
1 | //! Defines primitive types, which have a couple of peculiarities: | 1 | //! A few helper functions for dealing with primitives. |
2 | //! | ||
3 | //! * during type inference, they can be uncertain (ie, `let x = 92;`) | ||
4 | //! * they don't belong to any particular crate. | ||
5 | 2 | ||
6 | pub use chalk_ir::{FloatTy, IntTy, UintTy}; | 3 | pub use chalk_ir::{FloatTy, IntTy, UintTy}; |
7 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}; | 4 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}; |
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/tls.rs index 8892a63a9..87c671a42 100644 --- a/crates/hir_ty/src/traits/chalk/tls.rs +++ b/crates/hir_ty/src/tls.rs | |||
@@ -4,8 +4,10 @@ use std::fmt; | |||
4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; | 4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; |
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | 6 | ||
7 | use super::{from_chalk, Interner}; | 7 | use crate::{ |
8 | use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId}; | 8 | chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk, |
9 | CallableDefId, Interner, | ||
10 | }; | ||
9 | use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; | 11 | use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; |
10 | 12 | ||
11 | pub(crate) use unsafe_tls::{set_current_program, with_current_program}; | 13 | pub(crate) use unsafe_tls::{set_current_program, with_current_program}; |
@@ -15,7 +17,7 @@ pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase); | |||
15 | impl DebugContext<'_> { | 17 | impl DebugContext<'_> { |
16 | pub(crate) fn debug_struct_id( | 18 | pub(crate) fn debug_struct_id( |
17 | &self, | 19 | &self, |
18 | id: super::AdtId, | 20 | id: chalk_db::AdtId, |
19 | f: &mut fmt::Formatter<'_>, | 21 | f: &mut fmt::Formatter<'_>, |
20 | ) -> Result<(), fmt::Error> { | 22 | ) -> Result<(), fmt::Error> { |
21 | let name = match id.0 { | 23 | let name = match id.0 { |
@@ -28,17 +30,17 @@ impl DebugContext<'_> { | |||
28 | 30 | ||
29 | pub(crate) fn debug_trait_id( | 31 | pub(crate) fn debug_trait_id( |
30 | &self, | 32 | &self, |
31 | id: super::TraitId, | 33 | id: chalk_db::TraitId, |
32 | fmt: &mut fmt::Formatter<'_>, | 34 | fmt: &mut fmt::Formatter<'_>, |
33 | ) -> Result<(), fmt::Error> { | 35 | ) -> Result<(), fmt::Error> { |
34 | let trait_: hir_def::TraitId = from_chalk(self.0, id); | 36 | let trait_: hir_def::TraitId = from_chalk_trait_id(id); |
35 | let trait_data = self.0.trait_data(trait_); | 37 | let trait_data = self.0.trait_data(trait_); |
36 | write!(fmt, "{}", trait_data.name) | 38 | write!(fmt, "{}", trait_data.name) |
37 | } | 39 | } |
38 | 40 | ||
39 | pub(crate) fn debug_assoc_type_id( | 41 | pub(crate) fn debug_assoc_type_id( |
40 | &self, | 42 | &self, |
41 | id: super::AssocTypeId, | 43 | id: chalk_db::AssocTypeId, |
42 | fmt: &mut fmt::Formatter<'_>, | 44 | fmt: &mut fmt::Formatter<'_>, |
43 | ) -> Result<(), fmt::Error> { | 45 | ) -> Result<(), fmt::Error> { |
44 | let type_alias: TypeAliasId = from_assoc_type_id(id); | 46 | let type_alias: TypeAliasId = from_assoc_type_id(id); |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index 1cda72d22..9936d0803 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -1,28 +1,26 @@ | |||
1 | //! Trait solving using Chalk. | 1 | //! Trait solving using Chalk. |
2 | |||
2 | use std::env::var; | 3 | use std::env::var; |
3 | 4 | ||
4 | use base_db::CrateId; | ||
5 | use chalk_ir::cast::Cast; | 5 | use chalk_ir::cast::Cast; |
6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; | 6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; |
7 | |||
8 | use base_db::CrateId; | ||
7 | use hir_def::{lang_item::LangItemTarget, TraitId}; | 9 | use hir_def::{lang_item::LangItemTarget, TraitId}; |
8 | use stdx::panic_context; | 10 | use stdx::panic_context; |
9 | 11 | ||
10 | use crate::{ | 12 | use crate::{ |
11 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, | 13 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, |
12 | Solution, TraitRefExt, Ty, TyKind, WhereClause, | 14 | Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause, |
13 | }; | 15 | }; |
14 | 16 | ||
15 | use self::chalk::Interner; | ||
16 | |||
17 | pub(crate) mod chalk; | ||
18 | |||
19 | /// This controls how much 'time' we give the Chalk solver before giving up. | 17 | /// This controls how much 'time' we give the Chalk solver before giving up. |
20 | const CHALK_SOLVER_FUEL: i32 = 100; | 18 | const CHALK_SOLVER_FUEL: i32 = 100; |
21 | 19 | ||
22 | #[derive(Debug, Copy, Clone)] | 20 | #[derive(Debug, Copy, Clone)] |
23 | struct ChalkContext<'a> { | 21 | pub(crate) struct ChalkContext<'a> { |
24 | db: &'a dyn HirDatabase, | 22 | pub(crate) db: &'a dyn HirDatabase, |
25 | krate: CrateId, | 23 | pub(crate) krate: CrateId, |
26 | } | 24 | } |
27 | 25 | ||
28 | fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { | 26 | fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { |
@@ -148,7 +146,7 @@ fn solve( | |||
148 | // don't set the TLS for Chalk unless Chalk debugging is active, to make | 146 | // don't set the TLS for Chalk unless Chalk debugging is active, to make |
149 | // extra sure we only use it for debugging | 147 | // extra sure we only use it for debugging |
150 | let solution = | 148 | let solution = |
151 | if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; | 149 | if is_chalk_debug() { crate::tls::set_current_program(db, solve) } else { solve() }; |
152 | 150 | ||
153 | solution | 151 | solution |
154 | } | 152 | } |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs deleted file mode 100644 index e78581ea5..000000000 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | //! This module contains the implementations of the `ToChalk` trait, which | ||
2 | //! handles conversion between our data types and their corresponding types in | ||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | ||
4 | //! conversions. | ||
5 | |||
6 | use chalk_ir::cast::Cast; | ||
7 | use chalk_solve::rust_ir; | ||
8 | |||
9 | use base_db::salsa::InternKey; | ||
10 | use hir_def::{GenericDefId, TypeAliasId}; | ||
11 | |||
12 | use crate::{ | ||
13 | db::HirDatabase, AliasTy, CallableDefId, ProjectionTyExt, QuantifiedWhereClause, Substitution, | ||
14 | Ty, WhereClause, | ||
15 | }; | ||
16 | |||
17 | use super::interner::*; | ||
18 | use super::*; | ||
19 | |||
20 | impl ToChalk for hir_def::TraitId { | ||
21 | type Chalk = TraitId; | ||
22 | |||
23 | fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId { | ||
24 | chalk_ir::TraitId(self.as_intern_id()) | ||
25 | } | ||
26 | |||
27 | fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId { | ||
28 | InternKey::from_intern_id(trait_id.0) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | impl ToChalk for hir_def::ImplId { | ||
33 | type Chalk = ImplId; | ||
34 | |||
35 | fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { | ||
36 | chalk_ir::ImplId(self.as_intern_id()) | ||
37 | } | ||
38 | |||
39 | fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { | ||
40 | InternKey::from_intern_id(impl_id.0) | ||
41 | } | ||
42 | } | ||
43 | |||
44 | impl ToChalk for CallableDefId { | ||
45 | type Chalk = FnDefId; | ||
46 | |||
47 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { | ||
48 | db.intern_callable_def(self).into() | ||
49 | } | ||
50 | |||
51 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { | ||
52 | db.lookup_intern_callable_def(fn_def_id.into()) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); | ||
57 | |||
58 | impl ToChalk for TypeAliasAsValue { | ||
59 | type Chalk = AssociatedTyValueId; | ||
60 | |||
61 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { | ||
62 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) | ||
63 | } | ||
64 | |||
65 | fn from_chalk( | ||
66 | _db: &dyn HirDatabase, | ||
67 | assoc_ty_value_id: AssociatedTyValueId, | ||
68 | ) -> TypeAliasAsValue { | ||
69 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | pub(super) fn convert_where_clauses( | ||
74 | db: &dyn HirDatabase, | ||
75 | def: GenericDefId, | ||
76 | substs: &Substitution, | ||
77 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { | ||
78 | let generic_predicates = db.generic_predicates(def); | ||
79 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
80 | for pred in generic_predicates.iter() { | ||
81 | result.push(pred.clone().substitute(&Interner, substs)); | ||
82 | } | ||
83 | result | ||
84 | } | ||
85 | |||
86 | pub(super) fn generic_predicate_to_inline_bound( | ||
87 | db: &dyn HirDatabase, | ||
88 | pred: &QuantifiedWhereClause, | ||
89 | self_ty: &Ty, | ||
90 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | ||
91 | // An InlineBound is like a GenericPredicate, except the self type is left out. | ||
92 | // We don't have a special type for this, but Chalk does. | ||
93 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); | ||
94 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); | ||
95 | match pred { | ||
96 | WhereClause::Implemented(trait_ref) => { | ||
97 | if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
98 | // we can only convert predicates back to type bounds if they | ||
99 | // have the expected self type | ||
100 | return None; | ||
101 | } | ||
102 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] | ||
103 | .iter() | ||
104 | .map(|ty| ty.clone().cast(&Interner)) | ||
105 | .collect(); | ||
106 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | ||
107 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) | ||
108 | } | ||
109 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | ||
110 | if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
111 | return None; | ||
112 | } | ||
113 | let trait_ = projection_ty.trait_(db); | ||
114 | let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..] | ||
115 | .iter() | ||
116 | .map(|ty| ty.clone().cast(&Interner)) | ||
117 | .collect(); | ||
118 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
119 | value: ty.clone(), | ||
120 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
121 | associated_ty_id: projection_ty.associated_ty_id, | ||
122 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
123 | }; | ||
124 | Some(chalk_ir::Binders::new( | ||
125 | binders, | ||
126 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
127 | )) | ||
128 | } | ||
129 | _ => None, | ||
130 | } | ||
131 | } | ||