diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 128 |
1 files changed, 118 insertions, 10 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 87f10e9d5..874c95411 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! The type system. We currently use this to infer types for completion, hover | 1 | //! The type system. We currently use this to infer types for completion, hover |
2 | //! information and various assists. | 2 | //! information and various assists. |
3 | |||
3 | #[allow(unused)] | 4 | #[allow(unused)] |
4 | macro_rules! eprintln { | 5 | macro_rules! eprintln { |
5 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; | 6 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; |
@@ -17,7 +18,6 @@ mod chalk_cast; | |||
17 | mod chalk_ext; | 18 | mod chalk_ext; |
18 | mod builder; | 19 | mod builder; |
19 | mod walk; | 20 | mod walk; |
20 | mod types; | ||
21 | 21 | ||
22 | pub mod display; | 22 | pub mod display; |
23 | pub mod db; | 23 | pub mod db; |
@@ -31,7 +31,11 @@ mod test_db; | |||
31 | use std::sync::Arc; | 31 | use std::sync::Arc; |
32 | 32 | ||
33 | use base_db::salsa; | 33 | use base_db::salsa; |
34 | use chalk_ir::UintTy; | 34 | use chalk_ir::{ |
35 | fold::{Fold, Shift}, | ||
36 | interner::HasInterner, | ||
37 | UintTy, | ||
38 | }; | ||
35 | use hir_def::{ | 39 | use hir_def::{ |
36 | expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, | 40 | expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, |
37 | TypeParamId, | 41 | TypeParamId, |
@@ -48,7 +52,6 @@ pub use lower::{ | |||
48 | TyDefId, TyLoweringContext, ValueTyDefId, | 52 | TyDefId, TyLoweringContext, ValueTyDefId, |
49 | }; | 53 | }; |
50 | pub use traits::{chalk::Interner, TraitEnvironment}; | 54 | pub use traits::{chalk::Interner, TraitEnvironment}; |
51 | pub use types::*; | ||
52 | pub use walk::TypeWalk; | 55 | pub use walk::TypeWalk; |
53 | 56 | ||
54 | pub use chalk_ir::{ | 57 | pub use chalk_ir::{ |
@@ -65,6 +68,21 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | |||
65 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | 68 | pub type VariableKind = chalk_ir::VariableKind<Interner>; |
66 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | 69 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; |
67 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 70 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
71 | pub type Binders<T> = chalk_ir::Binders<T>; | ||
72 | pub type Substitution = chalk_ir::Substitution<Interner>; | ||
73 | pub type GenericArg = chalk_ir::GenericArg<Interner>; | ||
74 | pub type GenericArgData = chalk_ir::GenericArgData<Interner>; | ||
75 | |||
76 | pub type Ty = chalk_ir::Ty<Interner>; | ||
77 | pub type TyKind = chalk_ir::TyKind<Interner>; | ||
78 | pub type DynTy = chalk_ir::DynTy<Interner>; | ||
79 | pub type FnPointer = chalk_ir::FnPointer<Interner>; | ||
80 | // pub type FnSubst = chalk_ir::FnSubst<Interner>; | ||
81 | pub use chalk_ir::FnSubst; | ||
82 | pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>; | ||
83 | pub type AliasTy = chalk_ir::AliasTy<Interner>; | ||
84 | pub type OpaqueTy = chalk_ir::OpaqueTy<Interner>; | ||
85 | pub type InferenceVar = chalk_ir::InferenceVar; | ||
68 | 86 | ||
69 | pub type Lifetime = chalk_ir::Lifetime<Interner>; | 87 | pub type Lifetime = chalk_ir::Lifetime<Interner>; |
70 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; | 88 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; |
@@ -79,9 +97,20 @@ pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | |||
79 | 97 | ||
80 | pub type FnSig = chalk_ir::FnSig<Interner>; | 98 | pub type FnSig = chalk_ir::FnSig<Interner>; |
81 | 99 | ||
100 | pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; | ||
101 | pub type DomainGoal = chalk_ir::DomainGoal<Interner>; | ||
102 | pub type AliasEq = chalk_ir::AliasEq<Interner>; | ||
103 | pub type Solution = chalk_solve::Solution<Interner>; | ||
104 | pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; | ||
105 | pub type Guidance = chalk_solve::Guidance<Interner>; | ||
106 | pub type WhereClause = chalk_ir::WhereClause<Interner>; | ||
107 | |||
82 | // FIXME: get rid of this | 108 | // FIXME: get rid of this |
83 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { | 109 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { |
84 | Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into()) | 110 | Substitution::from_iter( |
111 | &Interner, | ||
112 | s.interned()[..std::cmp::min(s.len(&Interner), n)].iter().cloned(), | ||
113 | ) | ||
85 | } | 114 | } |
86 | 115 | ||
87 | /// Return an index of a parameter in the generic type parameter list by it's id. | 116 | /// Return an index of a parameter in the generic type parameter list by it's id. |
@@ -91,12 +120,15 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
91 | 120 | ||
92 | pub fn wrap_empty_binders<T>(value: T) -> Binders<T> | 121 | pub fn wrap_empty_binders<T>(value: T) -> Binders<T> |
93 | where | 122 | where |
94 | T: TypeWalk, | 123 | T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>, |
95 | { | 124 | { |
96 | Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE)) | 125 | Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE)) |
97 | } | 126 | } |
98 | 127 | ||
99 | pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | 128 | pub fn make_only_type_binders<T: HasInterner<Interner = Interner>>( |
129 | num_vars: usize, | ||
130 | value: T, | ||
131 | ) -> Binders<T> { | ||
100 | Binders::new( | 132 | Binders::new( |
101 | VariableKinds::from_iter( | 133 | VariableKinds::from_iter( |
102 | &Interner, | 134 | &Interner, |
@@ -108,7 +140,7 @@ pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | |||
108 | } | 140 | } |
109 | 141 | ||
110 | // FIXME: get rid of this | 142 | // FIXME: get rid of this |
111 | pub fn make_canonical<T>( | 143 | pub fn make_canonical<T: HasInterner<Interner = Interner>>( |
112 | value: T, | 144 | value: T, |
113 | kinds: impl IntoIterator<Item = TyVariableKind>, | 145 | kinds: impl IntoIterator<Item = TyVariableKind>, |
114 | ) -> Canonical<T> { | 146 | ) -> Canonical<T> { |
@@ -121,6 +153,14 @@ pub fn make_canonical<T>( | |||
121 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | 153 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } |
122 | } | 154 | } |
123 | 155 | ||
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 | |||
124 | /// 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 |
125 | /// one return type. | 165 | /// one return type. |
126 | #[derive(Clone, PartialEq, Eq, Debug)] | 166 | #[derive(Clone, PartialEq, Eq, Debug)] |
@@ -144,7 +184,7 @@ impl CallableSig { | |||
144 | params_and_return: fn_ptr | 184 | params_and_return: fn_ptr |
145 | .substitution | 185 | .substitution |
146 | .clone() | 186 | .clone() |
147 | .shifted_out_to(DebruijnIndex::ONE) | 187 | .shifted_out_to(&Interner, DebruijnIndex::ONE) |
148 | .expect("unexpected lifetime vars in fn ptr") | 188 | .expect("unexpected lifetime vars in fn ptr") |
149 | .0 | 189 | .0 |
150 | .interned() | 190 | .interned() |
@@ -164,7 +204,22 @@ impl CallableSig { | |||
164 | } | 204 | } |
165 | } | 205 | } |
166 | 206 | ||
167 | impl Ty {} | 207 | impl Fold<Interner> for CallableSig { |
208 | type Result = CallableSig; | ||
209 | |||
210 | fn fold_with<'i>( | ||
211 | self, | ||
212 | folder: &mut dyn chalk_ir::fold::Folder<'i, Interner>, | ||
213 | outer_binder: DebruijnIndex, | ||
214 | ) -> chalk_ir::Fallible<Self::Result> | ||
215 | where | ||
216 | Interner: 'i, | ||
217 | { | ||
218 | let vec = self.params_and_return.to_vec(); | ||
219 | let folded = vec.fold_with(folder, outer_binder)?; | ||
220 | Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs }) | ||
221 | } | ||
222 | } | ||
168 | 223 | ||
169 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 224 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
170 | pub enum ImplTraitId { | 225 | pub enum ImplTraitId { |
@@ -244,3 +299,56 @@ pub fn dummy_usize_const() -> Const { | |||
244 | } | 299 | } |
245 | .intern(&Interner) | 300 | .intern(&Interner) |
246 | } | 301 | } |
302 | |||
303 | pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>( | ||
304 | t: T, | ||
305 | f: impl FnMut(BoundVar, DebruijnIndex) -> Ty, | ||
306 | ) -> T::Result { | ||
307 | use chalk_ir::{fold::Folder, Fallible}; | ||
308 | struct FreeVarFolder<F>(F); | ||
309 | impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder<F> { | ||
310 | fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { | ||
311 | self | ||
312 | } | ||
313 | |||
314 | fn interner(&self) -> &'i Interner { | ||
315 | &Interner | ||
316 | } | ||
317 | |||
318 | fn fold_free_var_ty( | ||
319 | &mut self, | ||
320 | bound_var: BoundVar, | ||
321 | outer_binder: DebruijnIndex, | ||
322 | ) -> Fallible<Ty> { | ||
323 | Ok(self.0(bound_var, outer_binder)) | ||
324 | } | ||
325 | } | ||
326 | t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly") | ||
327 | } | ||
328 | |||
329 | pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>( | ||
330 | t: T, | ||
331 | f: impl FnMut(Ty, DebruijnIndex) -> Ty, | ||
332 | binders: DebruijnIndex, | ||
333 | ) -> T::Result { | ||
334 | use chalk_ir::{ | ||
335 | fold::{Folder, SuperFold}, | ||
336 | Fallible, | ||
337 | }; | ||
338 | struct TyFolder<F>(F); | ||
339 | impl<'i, F: FnMut(Ty, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for TyFolder<F> { | ||
340 | fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { | ||
341 | self | ||
342 | } | ||
343 | |||
344 | fn interner(&self) -> &'i Interner { | ||
345 | &Interner | ||
346 | } | ||
347 | |||
348 | fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> { | ||
349 | let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?; | ||
350 | Ok(self.0(ty, outer_binder)) | ||
351 | } | ||
352 | } | ||
353 | t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly") | ||
354 | } | ||