diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 216 |
1 files changed, 139 insertions, 77 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 87f10e9d5..113234fa4 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -1,27 +1,29 @@ | |||
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)*) }; |
6 | } | 7 | } |
7 | 8 | ||
8 | mod autoderef; | 9 | mod autoderef; |
9 | pub mod primitive; | ||
10 | pub mod traits; | ||
11 | pub mod method_resolution; | ||
12 | mod op; | ||
13 | mod lower; | ||
14 | pub(crate) mod infer; | ||
15 | pub(crate) mod utils; | ||
16 | mod chalk_cast; | ||
17 | mod chalk_ext; | ||
18 | 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; | ||
19 | mod walk; | 20 | mod walk; |
20 | mod types; | ||
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,12 +32,12 @@ mod test_db; | |||
30 | 32 | ||
31 | use std::sync::Arc; | 33 | use std::sync::Arc; |
32 | 34 | ||
33 | use base_db::salsa; | 35 | use chalk_ir::{ |
34 | use chalk_ir::UintTy; | 36 | fold::{Fold, Shift}, |
35 | use hir_def::{ | 37 | interner::HasInterner, |
36 | expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, | 38 | UintTy, |
37 | TypeParamId, | ||
38 | }; | 39 | }; |
40 | use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId}; | ||
39 | 41 | ||
40 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; | 42 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; |
41 | 43 | ||
@@ -43,12 +45,17 @@ pub use autoderef::autoderef; | |||
43 | pub use builder::TyBuilder; | 45 | pub use builder::TyBuilder; |
44 | pub use chalk_ext::*; | 46 | pub use chalk_ext::*; |
45 | pub use infer::{could_unify, InferenceResult}; | 47 | pub use infer::{could_unify, InferenceResult}; |
48 | pub use interner::Interner; | ||
46 | pub use lower::{ | 49 | pub use lower::{ |
47 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 50 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
48 | TyDefId, TyLoweringContext, ValueTyDefId, | 51 | TyDefId, TyLoweringContext, ValueTyDefId, |
49 | }; | 52 | }; |
50 | pub use traits::{chalk::Interner, TraitEnvironment}; | 53 | pub use mapping::{ |
51 | pub use types::*; | 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; | ||
52 | pub use walk::TypeWalk; | 59 | pub use walk::TypeWalk; |
53 | 60 | ||
54 | pub use chalk_ir::{ | 61 | pub use chalk_ir::{ |
@@ -65,6 +72,21 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | |||
65 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | 72 | pub type VariableKind = chalk_ir::VariableKind<Interner>; |
66 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | 73 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; |
67 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 74 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
75 | pub type Binders<T> = chalk_ir::Binders<T>; | ||
76 | pub type Substitution = chalk_ir::Substitution<Interner>; | ||
77 | pub type GenericArg = chalk_ir::GenericArg<Interner>; | ||
78 | pub type GenericArgData = chalk_ir::GenericArgData<Interner>; | ||
79 | |||
80 | pub type Ty = chalk_ir::Ty<Interner>; | ||
81 | pub type TyKind = chalk_ir::TyKind<Interner>; | ||
82 | pub type DynTy = chalk_ir::DynTy<Interner>; | ||
83 | pub type FnPointer = chalk_ir::FnPointer<Interner>; | ||
84 | // pub type FnSubst = chalk_ir::FnSubst<Interner>; | ||
85 | pub use chalk_ir::FnSubst; | ||
86 | pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>; | ||
87 | pub type AliasTy = chalk_ir::AliasTy<Interner>; | ||
88 | pub type OpaqueTy = chalk_ir::OpaqueTy<Interner>; | ||
89 | pub type InferenceVar = chalk_ir::InferenceVar; | ||
68 | 90 | ||
69 | pub type Lifetime = chalk_ir::Lifetime<Interner>; | 91 | pub type Lifetime = chalk_ir::Lifetime<Interner>; |
70 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; | 92 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; |
@@ -76,12 +98,27 @@ pub type ConstValue = chalk_ir::ConstValue<Interner>; | |||
76 | pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>; | 98 | pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>; |
77 | 99 | ||
78 | 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>; | ||
79 | 105 | ||
80 | pub type FnSig = chalk_ir::FnSig<Interner>; | 106 | pub type FnSig = chalk_ir::FnSig<Interner>; |
81 | 107 | ||
108 | pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; | ||
109 | pub type DomainGoal = chalk_ir::DomainGoal<Interner>; | ||
110 | pub type AliasEq = chalk_ir::AliasEq<Interner>; | ||
111 | pub type Solution = chalk_solve::Solution<Interner>; | ||
112 | pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; | ||
113 | pub type Guidance = chalk_solve::Guidance<Interner>; | ||
114 | pub type WhereClause = chalk_ir::WhereClause<Interner>; | ||
115 | |||
82 | // FIXME: get rid of this | 116 | // FIXME: get rid of this |
83 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { | 117 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { |
84 | Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into()) | 118 | Substitution::from_iter( |
119 | &Interner, | ||
120 | s.as_slice(&Interner)[..std::cmp::min(s.len(&Interner), n)].iter().cloned(), | ||
121 | ) | ||
85 | } | 122 | } |
86 | 123 | ||
87 | /// Return an index of a parameter in the generic type parameter list by it's id. | 124 | /// Return an index of a parameter in the generic type parameter list by it's id. |
@@ -89,14 +126,17 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
89 | generics(db.upcast(), id.parent).param_idx(id) | 126 | generics(db.upcast(), id.parent).param_idx(id) |
90 | } | 127 | } |
91 | 128 | ||
92 | pub fn wrap_empty_binders<T>(value: T) -> Binders<T> | 129 | pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T> |
93 | where | 130 | where |
94 | T: TypeWalk, | 131 | T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>, |
95 | { | 132 | { |
96 | Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE)) | 133 | Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE)) |
97 | } | 134 | } |
98 | 135 | ||
99 | pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | 136 | pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>( |
137 | num_vars: usize, | ||
138 | value: T, | ||
139 | ) -> Binders<T> { | ||
100 | Binders::new( | 140 | Binders::new( |
101 | VariableKinds::from_iter( | 141 | VariableKinds::from_iter( |
102 | &Interner, | 142 | &Interner, |
@@ -108,7 +148,7 @@ pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | |||
108 | } | 148 | } |
109 | 149 | ||
110 | // FIXME: get rid of this | 150 | // FIXME: get rid of this |
111 | pub fn make_canonical<T>( | 151 | pub fn make_canonical<T: HasInterner<Interner = Interner>>( |
112 | value: T, | 152 | value: T, |
113 | kinds: impl IntoIterator<Item = TyVariableKind>, | 153 | kinds: impl IntoIterator<Item = TyVariableKind>, |
114 | ) -> Canonical<T> { | 154 | ) -> Canonical<T> { |
@@ -129,6 +169,8 @@ pub struct CallableSig { | |||
129 | is_varargs: bool, | 169 | is_varargs: bool, |
130 | } | 170 | } |
131 | 171 | ||
172 | has_interner!(CallableSig); | ||
173 | |||
132 | /// A polymorphic function signature. | 174 | /// A polymorphic function signature. |
133 | pub type PolyFnSig = Binders<CallableSig>; | 175 | pub type PolyFnSig = Binders<CallableSig>; |
134 | 176 | ||
@@ -144,10 +186,10 @@ impl CallableSig { | |||
144 | params_and_return: fn_ptr | 186 | params_and_return: fn_ptr |
145 | .substitution | 187 | .substitution |
146 | .clone() | 188 | .clone() |
147 | .shifted_out_to(DebruijnIndex::ONE) | 189 | .shifted_out_to(&Interner, DebruijnIndex::ONE) |
148 | .expect("unexpected lifetime vars in fn ptr") | 190 | .expect("unexpected lifetime vars in fn ptr") |
149 | .0 | 191 | .0 |
150 | .interned() | 192 | .as_slice(&Interner) |
151 | .iter() | 193 | .iter() |
152 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) | 194 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) |
153 | .collect(), | 195 | .collect(), |
@@ -164,7 +206,22 @@ impl CallableSig { | |||
164 | } | 206 | } |
165 | } | 207 | } |
166 | 208 | ||
167 | impl Ty {} | 209 | impl Fold<Interner> for CallableSig { |
210 | type Result = CallableSig; | ||
211 | |||
212 | fn fold_with<'i>( | ||
213 | self, | ||
214 | folder: &mut dyn chalk_ir::fold::Folder<'i, Interner>, | ||
215 | outer_binder: DebruijnIndex, | ||
216 | ) -> chalk_ir::Fallible<Self::Result> | ||
217 | where | ||
218 | Interner: 'i, | ||
219 | { | ||
220 | let vec = self.params_and_return.to_vec(); | ||
221 | let folded = vec.fold_with(folder, outer_binder)?; | ||
222 | Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs }) | ||
223 | } | ||
224 | } | ||
168 | 225 | ||
169 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 226 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
170 | pub enum ImplTraitId { | 227 | pub enum ImplTraitId { |
@@ -177,70 +234,75 @@ pub struct ReturnTypeImplTraits { | |||
177 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, | 234 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, |
178 | } | 235 | } |
179 | 236 | ||
237 | has_interner!(ReturnTypeImplTraits); | ||
238 | |||
180 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 239 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
181 | pub(crate) struct ReturnTypeImplTrait { | 240 | pub(crate) struct ReturnTypeImplTrait { |
182 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, | 241 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, |
183 | } | 242 | } |
184 | 243 | ||
185 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | 244 | pub fn static_lifetime() -> Lifetime { |
186 | chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) | 245 | LifetimeData::Static.intern(&Interner) |
187 | } | ||
188 | |||
189 | pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { | ||
190 | salsa::InternKey::from_intern_id(id.0) | ||
191 | } | ||
192 | |||
193 | pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | ||
194 | chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) | ||
195 | } | ||
196 | |||
197 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | ||
198 | salsa::InternKey::from_intern_id(id.0) | ||
199 | } | ||
200 | |||
201 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
202 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
203 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
204 | db.lookup_intern_type_param_id(interned_id) | ||
205 | } | 246 | } |
206 | 247 | ||
207 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | 248 | pub fn dummy_usize_const() -> Const { |
208 | let interned_id = db.intern_type_param_id(id); | 249 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); |
209 | PlaceholderIndex { | 250 | chalk_ir::ConstData { |
210 | ui: chalk_ir::UniverseIndex::ROOT, | 251 | ty: usize_ty, |
211 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | 252 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), |
212 | } | 253 | } |
254 | .intern(&Interner) | ||
213 | } | 255 | } |
214 | 256 | ||
215 | pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { | 257 | pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>( |
216 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | 258 | t: T, |
217 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | 259 | f: impl FnMut(BoundVar, DebruijnIndex) -> Ty, |
218 | db.lookup_intern_lifetime_param_id(interned_id) | 260 | ) -> T::Result { |
219 | } | 261 | use chalk_ir::{fold::Folder, Fallible}; |
262 | struct FreeVarFolder<F>(F); | ||
263 | impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder<F> { | ||
264 | fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { | ||
265 | self | ||
266 | } | ||
220 | 267 | ||
221 | pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId { | 268 | fn interner(&self) -> &'i Interner { |
222 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | 269 | &Interner |
223 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | 270 | } |
224 | db.lookup_intern_const_param_id(interned_id) | ||
225 | } | ||
226 | 271 | ||
227 | pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { | 272 | fn fold_free_var_ty( |
228 | chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) | 273 | &mut self, |
274 | bound_var: BoundVar, | ||
275 | outer_binder: DebruijnIndex, | ||
276 | ) -> Fallible<Ty> { | ||
277 | Ok(self.0(bound_var, outer_binder)) | ||
278 | } | ||
279 | } | ||
280 | t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly") | ||
229 | } | 281 | } |
230 | 282 | ||
231 | pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { | 283 | pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>( |
232 | salsa::InternKey::from_intern_id(id.0) | 284 | t: T, |
233 | } | 285 | f: impl FnMut(Ty, DebruijnIndex) -> Ty, |
286 | binders: DebruijnIndex, | ||
287 | ) -> T::Result { | ||
288 | use chalk_ir::{ | ||
289 | fold::{Folder, SuperFold}, | ||
290 | Fallible, | ||
291 | }; | ||
292 | struct TyFolder<F>(F); | ||
293 | impl<'i, F: FnMut(Ty, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for TyFolder<F> { | ||
294 | fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { | ||
295 | self | ||
296 | } | ||
234 | 297 | ||
235 | pub fn static_lifetime() -> Lifetime { | 298 | fn interner(&self) -> &'i Interner { |
236 | LifetimeData::Static.intern(&Interner) | 299 | &Interner |
237 | } | 300 | } |
238 | 301 | ||
239 | pub fn dummy_usize_const() -> Const { | 302 | fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> { |
240 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); | 303 | let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?; |
241 | chalk_ir::ConstData { | 304 | Ok(self.0(ty, outer_binder)) |
242 | ty: usize_ty, | 305 | } |
243 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), | ||
244 | } | 306 | } |
245 | .intern(&Interner) | 307 | t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly") |
246 | } | 308 | } |