diff options
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 44 | ||||
-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) | 152 | ||||
-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/method_resolution.rs | 82 | ||||
-rw-r--r-- | crates/hir_ty/src/primitive.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 38 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 30 | ||||
-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 |
18 files changed, 526 insertions, 386 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index f8e9db9ae..71bc436e6 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -6,14 +6,15 @@ | |||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::cast::Cast; | 9 | use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, VariableKind}; |
10 | use hir_def::lang_item::LangItemTarget; | 10 | use hir_def::lang_item::LangItemTarget; |
11 | use hir_expand::name::name; | 11 | use hir_expand::name::name; |
12 | use log::{info, warn}; | 12 | use log::{info, warn}; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, | 15 | db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, |
16 | InEnvironment, Interner, ProjectionTyExt, Solution, Ty, TyBuilder, TyKind, | 16 | DebruijnIndex, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution, Ty, TyBuilder, |
17 | TyKind, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -103,7 +104,7 @@ fn deref_by_trait( | |||
103 | binders: CanonicalVarKinds::from_iter( | 104 | binders: CanonicalVarKinds::from_iter( |
104 | &Interner, | 105 | &Interner, |
105 | ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( | 106 | ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( |
106 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), | 107 | VariableKind::Ty(chalk_ir::TyVariableKind::General), |
107 | chalk_ir::UniverseIndex::ROOT, | 108 | chalk_ir::UniverseIndex::ROOT, |
108 | ))), | 109 | ))), |
109 | ), | 110 | ), |
@@ -136,7 +137,9 @@ fn deref_by_trait( | |||
136 | return None; | 137 | return None; |
137 | } | 138 | } |
138 | } | 139 | } |
139 | Some(Canonical { | 140 | // FIXME: we remove lifetime variables here since they can confuse |
141 | // the method resolution code later | ||
142 | Some(fixup_lifetime_variables(Canonical { | ||
140 | value: vars | 143 | value: vars |
141 | .value | 144 | .value |
142 | .subst | 145 | .subst |
@@ -144,7 +147,7 @@ fn deref_by_trait( | |||
144 | .assert_ty_ref(&Interner) | 147 | .assert_ty_ref(&Interner) |
145 | .clone(), | 148 | .clone(), |
146 | binders: vars.binders.clone(), | 149 | binders: vars.binders.clone(), |
147 | }) | 150 | })) |
148 | } | 151 | } |
149 | Solution::Ambig(_) => { | 152 | Solution::Ambig(_) => { |
150 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); | 153 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); |
@@ -152,3 +155,32 @@ fn deref_by_trait( | |||
152 | } | 155 | } |
153 | } | 156 | } |
154 | } | 157 | } |
158 | |||
159 | fn fixup_lifetime_variables<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>( | ||
160 | c: Canonical<T>, | ||
161 | ) -> Canonical<T> { | ||
162 | // Removes lifetime variables from the Canonical, replacing them by static lifetimes. | ||
163 | let mut i = 0; | ||
164 | let subst = Substitution::from_iter( | ||
165 | &Interner, | ||
166 | c.binders.iter(&Interner).map(|vk| match vk.kind { | ||
167 | VariableKind::Ty(_) => { | ||
168 | let index = i; | ||
169 | i += 1; | ||
170 | BoundVar::new(DebruijnIndex::INNERMOST, index).to_ty(&Interner).cast(&Interner) | ||
171 | } | ||
172 | VariableKind::Lifetime => static_lifetime().cast(&Interner), | ||
173 | VariableKind::Const(_) => unimplemented!(), | ||
174 | }), | ||
175 | ); | ||
176 | let binders = CanonicalVarKinds::from_iter( | ||
177 | &Interner, | ||
178 | c.binders.iter(&Interner).filter(|vk| match vk.kind { | ||
179 | VariableKind::Ty(_) => true, | ||
180 | VariableKind::Lifetime => false, | ||
181 | VariableKind::Const(_) => true, | ||
182 | }), | ||
183 | ); | ||
184 | let value = subst.apply(c.value, &Interner); | ||
185 | Canonical { binders, value } | ||
186 | } | ||
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 b8c390b2e..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 | ||
@@ -101,7 +98,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
101 | None | 98 | None |
102 | } | 99 | } |
103 | 100 | ||
104 | let self_ty_fp = TyFingerprint::for_impl(&ty); | 101 | let self_ty_fp = TyFingerprint::for_trait_impl(&ty); |
105 | let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { | 102 | let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { |
106 | Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS, | 103 | Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS, |
107 | Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS, | 104 | Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS, |
@@ -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/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index be3e4f09a..ece884241 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -13,6 +13,7 @@ use hir_def::{ | |||
13 | }; | 13 | }; |
14 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use stdx::always; | ||
16 | 17 | ||
17 | use crate::{ | 18 | use crate::{ |
18 | autoderef, | 19 | autoderef, |
@@ -21,32 +22,36 @@ use crate::{ | |||
21 | primitive::{self, FloatTy, IntTy, UintTy}, | 22 | primitive::{self, FloatTy, IntTy, UintTy}, |
22 | static_lifetime, | 23 | static_lifetime, |
23 | utils::all_super_traits, | 24 | utils::all_super_traits, |
24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, | 25 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner, |
25 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, | 26 | Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, |
26 | TyExt, TyKind, | ||
27 | }; | 27 | }; |
28 | 28 | ||
29 | /// This is used as a key for indexing impls. | 29 | /// This is used as a key for indexing impls. |
30 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 30 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
31 | pub enum TyFingerprint { | 31 | pub enum TyFingerprint { |
32 | // These are lang item impls: | ||
32 | Str, | 33 | Str, |
33 | Slice, | 34 | Slice, |
34 | Array, | 35 | Array, |
35 | Never, | 36 | Never, |
36 | RawPtr(Mutability), | 37 | RawPtr(Mutability), |
37 | Scalar(Scalar), | 38 | Scalar(Scalar), |
39 | // These can have user-defined impls: | ||
38 | Adt(hir_def::AdtId), | 40 | Adt(hir_def::AdtId), |
39 | Dyn(TraitId), | 41 | Dyn(TraitId), |
40 | Tuple(usize), | ||
41 | ForeignType(ForeignDefId), | 42 | ForeignType(ForeignDefId), |
42 | FnPtr(usize, FnSig), | 43 | // These only exist for trait impls |
44 | Unit, | ||
45 | Unnameable, | ||
46 | Function(u32), | ||
43 | } | 47 | } |
44 | 48 | ||
45 | impl TyFingerprint { | 49 | impl TyFingerprint { |
46 | /// Creates a TyFingerprint for looking up an impl. Only certain types can | 50 | /// Creates a TyFingerprint for looking up an inherent impl. Only certain |
47 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 51 | /// types can have inherent impls: if we have some `struct S`, we can have |
48 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 52 | /// an `impl S`, but not `impl &S`. Hence, this will return `None` for |
49 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 53 | /// reference types and such. |
54 | pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> { | ||
50 | let fp = match ty.kind(&Interner) { | 55 | let fp = match ty.kind(&Interner) { |
51 | TyKind::Str => TyFingerprint::Str, | 56 | TyKind::Str => TyFingerprint::Str, |
52 | TyKind::Never => TyFingerprint::Never, | 57 | TyKind::Never => TyFingerprint::Never, |
@@ -54,17 +59,52 @@ impl TyFingerprint { | |||
54 | TyKind::Array(..) => TyFingerprint::Array, | 59 | TyKind::Array(..) => TyFingerprint::Array, |
55 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), | 60 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), |
56 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), | 61 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), |
57 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality), | ||
58 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), | 62 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), |
59 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), | 63 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), |
60 | TyKind::Function(FnPointer { sig, substitution: substs, .. }) => { | ||
61 | TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig) | ||
62 | } | ||
63 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | 64 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, |
64 | _ => return None, | 65 | _ => return None, |
65 | }; | 66 | }; |
66 | Some(fp) | 67 | Some(fp) |
67 | } | 68 | } |
69 | |||
70 | /// Creates a TyFingerprint for looking up a trait impl. | ||
71 | pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> { | ||
72 | let fp = match ty.kind(&Interner) { | ||
73 | TyKind::Str => TyFingerprint::Str, | ||
74 | TyKind::Never => TyFingerprint::Never, | ||
75 | TyKind::Slice(..) => TyFingerprint::Slice, | ||
76 | TyKind::Array(..) => TyFingerprint::Array, | ||
77 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), | ||
78 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), | ||
79 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), | ||
80 | TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), | ||
81 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
82 | TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty), | ||
83 | TyKind::Tuple(_, subst) => { | ||
84 | let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(&Interner)); | ||
85 | if let Some(ty) = first_ty { | ||
86 | return TyFingerprint::for_trait_impl(ty); | ||
87 | } else { | ||
88 | TyFingerprint::Unit | ||
89 | } | ||
90 | } | ||
91 | TyKind::AssociatedType(_, _) | ||
92 | | TyKind::OpaqueType(_, _) | ||
93 | | TyKind::FnDef(_, _) | ||
94 | | TyKind::Closure(_, _) | ||
95 | | TyKind::Generator(..) | ||
96 | | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable, | ||
97 | TyKind::Function(fn_ptr) => { | ||
98 | TyFingerprint::Function(fn_ptr.substitution.0.len(&Interner) as u32) | ||
99 | } | ||
100 | TyKind::Alias(_) | ||
101 | | TyKind::Placeholder(_) | ||
102 | | TyKind::BoundVar(_) | ||
103 | | TyKind::InferenceVar(_, _) | ||
104 | | TyKind::Error => return None, | ||
105 | }; | ||
106 | Some(fp) | ||
107 | } | ||
68 | } | 108 | } |
69 | 109 | ||
70 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 110 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ |
@@ -112,7 +152,7 @@ impl TraitImpls { | |||
112 | None => continue, | 152 | None => continue, |
113 | }; | 153 | }; |
114 | let self_ty = db.impl_self_ty(impl_id); | 154 | let self_ty = db.impl_self_ty(impl_id); |
115 | let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders()); | 155 | let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders()); |
116 | impls | 156 | impls |
117 | .map | 157 | .map |
118 | .entry(target_trait) | 158 | .entry(target_trait) |
@@ -157,10 +197,13 @@ impl TraitImpls { | |||
157 | } | 197 | } |
158 | 198 | ||
159 | /// Queries all trait impls for the given type. | 199 | /// Queries all trait impls for the given type. |
160 | pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { | 200 | pub fn for_self_ty_without_blanket_impls( |
201 | &self, | ||
202 | fp: TyFingerprint, | ||
203 | ) -> impl Iterator<Item = ImplId> + '_ { | ||
161 | self.map | 204 | self.map |
162 | .values() | 205 | .values() |
163 | .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) | 206 | .flat_map(move |impls| impls.get(&Some(fp)).into_iter()) |
164 | .flat_map(|it| it.iter().copied()) | 207 | .flat_map(|it| it.iter().copied()) |
165 | } | 208 | } |
166 | 209 | ||
@@ -215,7 +258,9 @@ impl InherentImpls { | |||
215 | } | 258 | } |
216 | 259 | ||
217 | let self_ty = db.impl_self_ty(impl_id); | 260 | let self_ty = db.impl_self_ty(impl_id); |
218 | if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) { | 261 | let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); |
262 | always!(fp.is_some()); | ||
263 | if let Some(fp) = fp { | ||
219 | map.entry(fp).or_default().push(impl_id); | 264 | map.entry(fp).or_default().push(impl_id); |
220 | } | 265 | } |
221 | } | 266 | } |
@@ -228,7 +273,7 @@ impl InherentImpls { | |||
228 | } | 273 | } |
229 | 274 | ||
230 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { | 275 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { |
231 | match TyFingerprint::for_impl(self_ty) { | 276 | match TyFingerprint::for_inherent_impl(self_ty) { |
232 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), | 277 | Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), |
233 | None => &[], | 278 | None => &[], |
234 | } | 279 | } |
@@ -609,6 +654,7 @@ fn iterate_trait_method_candidates( | |||
609 | } | 654 | } |
610 | } | 655 | } |
611 | known_implemented = true; | 656 | known_implemented = true; |
657 | // FIXME: we shouldn't be ignoring the binders here | ||
612 | if callback(&self_ty.value, *item) { | 658 | if callback(&self_ty.value, *item) { |
613 | return true; | 659 | return true; |
614 | } | 660 | } |
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/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index b69f86050..9cd9f473d 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs | |||
@@ -974,3 +974,41 @@ fn param_overrides_fn() { | |||
974 | "#, | 974 | "#, |
975 | ) | 975 | ) |
976 | } | 976 | } |
977 | |||
978 | #[test] | ||
979 | fn lifetime_from_chalk_during_deref() { | ||
980 | check_types( | ||
981 | r#" | ||
982 | #[lang = "deref"] | ||
983 | pub trait Deref { | ||
984 | type Target; | ||
985 | } | ||
986 | |||
987 | struct Box<T: ?Sized> {} | ||
988 | impl<T> Deref for Box<T> { | ||
989 | type Target = T; | ||
990 | |||
991 | fn deref(&self) -> &Self::Target { | ||
992 | loop {} | ||
993 | } | ||
994 | } | ||
995 | |||
996 | trait Iterator { | ||
997 | type Item; | ||
998 | } | ||
999 | |||
1000 | pub struct Iter<'a, T: 'a> { | ||
1001 | inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>, | ||
1002 | } | ||
1003 | |||
1004 | trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> { | ||
1005 | fn clone_box(&self); | ||
1006 | } | ||
1007 | |||
1008 | fn clone_iter<T>(s: Iter<T>) { | ||
1009 | s.inner.clone_box(); | ||
1010 | //^^^^^^^^^^^^^^^^^^^ () | ||
1011 | } | ||
1012 | "#, | ||
1013 | ) | ||
1014 | } | ||
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 65b71fdfa..1c1aa491d 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -3413,3 +3413,33 @@ fn foo() { | |||
3413 | "#]], | 3413 | "#]], |
3414 | ); | 3414 | ); |
3415 | } | 3415 | } |
3416 | |||
3417 | #[test] | ||
3418 | fn renamed_extern_crate_in_block() { | ||
3419 | check_types( | ||
3420 | r#" | ||
3421 | //- /lib.rs crate:lib deps:serde | ||
3422 | use serde::Deserialize; | ||
3423 | |||
3424 | struct Foo {} | ||
3425 | |||
3426 | const _ : () = { | ||
3427 | extern crate serde as _serde; | ||
3428 | impl _serde::Deserialize for Foo { | ||
3429 | fn deserialize() -> u8 { 0 } | ||
3430 | } | ||
3431 | }; | ||
3432 | |||
3433 | fn foo() { | ||
3434 | Foo::deserialize(); | ||
3435 | //^^^^^^^^^^^^^^^^^^ u8 | ||
3436 | } | ||
3437 | |||
3438 | //- /serde.rs crate:serde | ||
3439 | |||
3440 | pub trait Deserialize { | ||
3441 | fn deserialize() -> u8; | ||
3442 | } | ||
3443 | "#, | ||
3444 | ); | ||
3445 | } | ||
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 | } | ||