diff options
-rw-r--r-- | crates/hir_ty/src/lib.rs | 35 | ||||
-rw-r--r-- | crates/hir_ty/src/types.rs | 549 | ||||
-rw-r--r-- | crates/hir_ty/src/walk.rs | 2 |
3 files changed, 32 insertions, 554 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 87f10e9d5..3378015ca 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -17,7 +17,6 @@ mod chalk_cast; | |||
17 | mod chalk_ext; | 17 | mod chalk_ext; |
18 | mod builder; | 18 | mod builder; |
19 | mod walk; | 19 | mod walk; |
20 | mod types; | ||
21 | 20 | ||
22 | pub mod display; | 21 | pub mod display; |
23 | pub mod db; | 22 | pub mod db; |
@@ -48,7 +47,6 @@ pub use lower::{ | |||
48 | TyDefId, TyLoweringContext, ValueTyDefId, | 47 | TyDefId, TyLoweringContext, ValueTyDefId, |
49 | }; | 48 | }; |
50 | pub use traits::{chalk::Interner, TraitEnvironment}; | 49 | pub use traits::{chalk::Interner, TraitEnvironment}; |
51 | pub use types::*; | ||
52 | pub use walk::TypeWalk; | 50 | pub use walk::TypeWalk; |
53 | 51 | ||
54 | pub use chalk_ir::{ | 52 | pub use chalk_ir::{ |
@@ -65,6 +63,21 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | |||
65 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | 63 | pub type VariableKind = chalk_ir::VariableKind<Interner>; |
66 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | 64 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; |
67 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 65 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
66 | pub type Binders<T> = chalk_ir::Binders<T>; | ||
67 | pub type Substitution = chalk_ir::Substitution<Interner>; | ||
68 | pub type GenericArg = chalk_ir::GenericArg<Interner>; | ||
69 | pub type GenericArgData = chalk_ir::GenericArgData<Interner>; | ||
70 | |||
71 | pub type Ty = chalk_ir::Ty<Interner>; | ||
72 | pub type TyKind = chalk_ir::TyKind<Interner>; | ||
73 | pub type DynTy = chalk_ir::DynTy<Interner>; | ||
74 | pub type FnPointer = chalk_ir::FnPointer<Interner>; | ||
75 | // pub type FnSubst = chalk_ir::FnSubst<Interner>; | ||
76 | pub use chalk_ir::FnSubst; | ||
77 | pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>; | ||
78 | pub type AliasTy = chalk_ir::AliasTy<Interner>; | ||
79 | pub type OpaqueTy = chalk_ir::OpaqueTy<Interner>; | ||
80 | pub type InferenceVar = chalk_ir::InferenceVar; | ||
68 | 81 | ||
69 | pub type Lifetime = chalk_ir::Lifetime<Interner>; | 82 | pub type Lifetime = chalk_ir::Lifetime<Interner>; |
70 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; | 83 | pub type LifetimeData = chalk_ir::LifetimeData<Interner>; |
@@ -79,6 +92,14 @@ pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | |||
79 | 92 | ||
80 | pub type FnSig = chalk_ir::FnSig<Interner>; | 93 | pub type FnSig = chalk_ir::FnSig<Interner>; |
81 | 94 | ||
95 | pub type InEnvironment<T> = chalk_ir::InEnvironment<T>; | ||
96 | pub type DomainGoal = chalk_ir::DomainGoal<Interner>; | ||
97 | pub type AliasEq = chalk_ir::AliasEq<Interner>; | ||
98 | pub type Solution = chalk_solve::Solution<Interner>; | ||
99 | pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>; | ||
100 | pub type Guidance = chalk_solve::Guidance<Interner>; | ||
101 | pub type WhereClause = chalk_ir::WhereClause<Interner>; | ||
102 | |||
82 | // FIXME: get rid of this | 103 | // FIXME: get rid of this |
83 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { | 104 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { |
84 | Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into()) | 105 | Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into()) |
@@ -121,6 +142,14 @@ pub fn make_canonical<T>( | |||
121 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | 142 | Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } |
122 | } | 143 | } |
123 | 144 | ||
145 | pub type TraitRef = chalk_ir::TraitRef<Interner>; | ||
146 | |||
147 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
148 | |||
149 | pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>; | ||
150 | |||
151 | pub type Canonical<T> = chalk_ir::Canonical<T>; | ||
152 | |||
124 | /// A function signature as seen by type inference: Several parameter types and | 153 | /// A function signature as seen by type inference: Several parameter types and |
125 | /// one return type. | 154 | /// one return type. |
126 | #[derive(Clone, PartialEq, Eq, Debug)] | 155 | #[derive(Clone, PartialEq, Eq, Debug)] |
@@ -164,8 +193,6 @@ impl CallableSig { | |||
164 | } | 193 | } |
165 | } | 194 | } |
166 | 195 | ||
167 | impl Ty {} | ||
168 | |||
169 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 196 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
170 | pub enum ImplTraitId { | 197 | pub enum ImplTraitId { |
171 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 198 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs deleted file mode 100644 index 89adad108..000000000 --- a/crates/hir_ty/src/types.rs +++ /dev/null | |||
@@ -1,549 +0,0 @@ | |||
1 | //! This is the home of `Ty` etc. until they get replaced by their chalk_ir | ||
2 | //! equivalents. | ||
3 | |||
4 | use std::sync::Arc; | ||
5 | |||
6 | use chalk_ir::{ | ||
7 | cast::{Cast, CastTo, Caster}, | ||
8 | BoundVar, Mutability, Scalar, TyVariableKind, | ||
9 | }; | ||
10 | use smallvec::SmallVec; | ||
11 | |||
12 | use crate::{ | ||
13 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, Const, FnDefId, FnSig, ForeignDefId, | ||
14 | Interner, Lifetime, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, VariableKinds, | ||
15 | }; | ||
16 | |||
17 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
18 | pub struct OpaqueTy { | ||
19 | pub opaque_ty_id: OpaqueTyId, | ||
20 | pub substitution: Substitution, | ||
21 | } | ||
22 | |||
23 | /// A "projection" type corresponds to an (unnormalized) | ||
24 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | ||
25 | /// trait and all its parameters are fully known. | ||
26 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
27 | pub struct ProjectionTy { | ||
28 | pub associated_ty_id: AssocTypeId, | ||
29 | pub substitution: Substitution, | ||
30 | } | ||
31 | |||
32 | impl ProjectionTy { | ||
33 | pub fn self_type_parameter(&self, interner: &Interner) -> Ty { | ||
34 | self.substitution.interned()[0].assert_ty_ref(interner).clone() | ||
35 | } | ||
36 | } | ||
37 | |||
38 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
39 | pub struct DynTy { | ||
40 | /// The unknown self type. | ||
41 | pub bounds: Binders<QuantifiedWhereClauses>, | ||
42 | pub lifetime: Lifetime, | ||
43 | } | ||
44 | |||
45 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
46 | pub struct FnPointer { | ||
47 | pub num_binders: usize, | ||
48 | pub sig: FnSig, | ||
49 | pub substitution: FnSubst, | ||
50 | } | ||
51 | /// A wrapper for the substs on a Fn. | ||
52 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
53 | pub struct FnSubst(pub Substitution); | ||
54 | |||
55 | impl FnPointer { | ||
56 | /// Represent the current `Fn` as if it was wrapped in `Binders` | ||
57 | pub fn into_binders(self, interner: &Interner) -> Binders<FnSubst> { | ||
58 | Binders::new( | ||
59 | VariableKinds::from_iter( | ||
60 | interner, | ||
61 | (0..self.num_binders).map(|_| VariableKind::Lifetime), | ||
62 | ), | ||
63 | self.substitution, | ||
64 | ) | ||
65 | } | ||
66 | |||
67 | /// Represent the current `Fn` as if it was wrapped in `Binders` | ||
68 | pub fn as_binders(&self, interner: &Interner) -> Binders<&FnSubst> { | ||
69 | Binders::new( | ||
70 | VariableKinds::from_iter( | ||
71 | interner, | ||
72 | (0..self.num_binders).map(|_| VariableKind::Lifetime), | ||
73 | ), | ||
74 | &self.substitution, | ||
75 | ) | ||
76 | } | ||
77 | } | ||
78 | |||
79 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
80 | pub enum AliasTy { | ||
81 | /// A "projection" type corresponds to an (unnormalized) | ||
82 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | ||
83 | /// trait and all its parameters are fully known. | ||
84 | Projection(ProjectionTy), | ||
85 | /// An opaque type (`impl Trait`). | ||
86 | /// | ||
87 | /// This is currently only used for return type impl trait; each instance of | ||
88 | /// `impl Trait` in a return type gets its own ID. | ||
89 | Opaque(OpaqueTy), | ||
90 | } | ||
91 | |||
92 | /// A type. | ||
93 | /// | ||
94 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | ||
95 | /// the same thing (but in a different way). | ||
96 | /// | ||
97 | /// This should be cheap to clone. | ||
98 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
99 | pub enum TyKind { | ||
100 | /// Structures, enumerations and unions. | ||
101 | Adt(chalk_ir::AdtId<Interner>, Substitution), | ||
102 | |||
103 | /// Represents an associated item like `Iterator::Item`. This is used | ||
104 | /// when we have tried to normalize a projection like `T::Item` but | ||
105 | /// couldn't find a better representation. In that case, we generate | ||
106 | /// an **application type** like `(Iterator::Item)<T>`. | ||
107 | AssociatedType(AssocTypeId, Substitution), | ||
108 | |||
109 | /// a scalar type like `bool` or `u32` | ||
110 | Scalar(Scalar), | ||
111 | |||
112 | /// A tuple type. For example, `(i32, bool)`. | ||
113 | Tuple(usize, Substitution), | ||
114 | |||
115 | /// An array with the given length. Written as `[T; n]`. | ||
116 | Array(Ty, Const), | ||
117 | |||
118 | /// The pointee of an array slice. Written as `[T]`. | ||
119 | Slice(Ty), | ||
120 | |||
121 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
122 | Raw(Mutability, Ty), | ||
123 | |||
124 | /// A reference; a pointer with an associated lifetime. Written as | ||
125 | /// `&'a mut T` or `&'a T`. | ||
126 | Ref(Mutability, Lifetime, Ty), | ||
127 | |||
128 | /// This represents a placeholder for an opaque type in situations where we | ||
129 | /// don't know the hidden type (i.e. currently almost always). This is | ||
130 | /// analogous to the `AssociatedType` type constructor. | ||
131 | /// It is also used as the type of async block, with one type parameter | ||
132 | /// representing the Future::Output type. | ||
133 | OpaqueType(OpaqueTyId, Substitution), | ||
134 | |||
135 | /// The anonymous type of a function declaration/definition. Each | ||
136 | /// function has a unique type, which is output (for a function | ||
137 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
138 | /// | ||
139 | /// This includes tuple struct / enum variant constructors as well. | ||
140 | /// | ||
141 | /// For example the type of `bar` here: | ||
142 | /// | ||
143 | /// ``` | ||
144 | /// fn foo() -> i32 { 1 } | ||
145 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
146 | /// ``` | ||
147 | FnDef(FnDefId, Substitution), | ||
148 | |||
149 | /// The pointee of a string slice. Written as `str`. | ||
150 | Str, | ||
151 | |||
152 | /// The never type `!`. | ||
153 | Never, | ||
154 | |||
155 | /// The type of a specific closure. | ||
156 | /// | ||
157 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
158 | /// parameter. | ||
159 | Closure(ClosureId, Substitution), | ||
160 | |||
161 | /// Represents a foreign type declared in external blocks. | ||
162 | Foreign(ForeignDefId), | ||
163 | |||
164 | /// A pointer to a function. Written as `fn() -> i32`. | ||
165 | /// | ||
166 | /// For example the type of `bar` here: | ||
167 | /// | ||
168 | /// ``` | ||
169 | /// fn foo() -> i32 { 1 } | ||
170 | /// let bar: fn() -> i32 = foo; | ||
171 | /// ``` | ||
172 | Function(FnPointer), | ||
173 | |||
174 | /// An "alias" type represents some form of type alias, such as: | ||
175 | /// - An associated type projection like `<T as Iterator>::Item` | ||
176 | /// - `impl Trait` types | ||
177 | /// - Named type aliases like `type Foo<X> = Vec<X>` | ||
178 | Alias(AliasTy), | ||
179 | |||
180 | /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) | ||
181 | /// {}` when we're type-checking the body of that function. In this | ||
182 | /// situation, we know this stands for *some* type, but don't know the exact | ||
183 | /// type. | ||
184 | Placeholder(PlaceholderIndex), | ||
185 | |||
186 | /// A bound type variable. This is used in various places: when representing | ||
187 | /// some polymorphic type like the type of function `fn f<T>`, the type | ||
188 | /// parameters get turned into variables; during trait resolution, inference | ||
189 | /// variables get turned into bound variables and back; and in `Dyn` the | ||
190 | /// `Self` type is represented with a bound variable as well. | ||
191 | BoundVar(BoundVar), | ||
192 | |||
193 | /// A type variable used during type checking. | ||
194 | InferenceVar(InferenceVar, TyVariableKind), | ||
195 | |||
196 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). | ||
197 | /// | ||
198 | /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)` | ||
199 | /// represents the `Self` type inside the bounds. This is currently | ||
200 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it | ||
201 | /// didn't seem worth the overhead yet. | ||
202 | Dyn(DynTy), | ||
203 | |||
204 | /// A placeholder for a type which could not be computed; this is propagated | ||
205 | /// to avoid useless error messages. Doubles as a placeholder where type | ||
206 | /// variables are inserted before type checking, since we want to try to | ||
207 | /// infer a better type here anyway -- for the IDE use case, we want to try | ||
208 | /// to infer as much as possible even in the presence of type errors. | ||
209 | Error, | ||
210 | } | ||
211 | |||
212 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
213 | pub struct Ty(Arc<TyKind>); | ||
214 | |||
215 | impl TyKind { | ||
216 | pub fn intern(self, _interner: &Interner) -> Ty { | ||
217 | Ty(Arc::new(self)) | ||
218 | } | ||
219 | } | ||
220 | |||
221 | impl Ty { | ||
222 | pub fn kind(&self, _interner: &Interner) -> &TyKind { | ||
223 | &self.0 | ||
224 | } | ||
225 | |||
226 | pub fn interned_mut(&mut self) -> &mut TyKind { | ||
227 | Arc::make_mut(&mut self.0) | ||
228 | } | ||
229 | |||
230 | pub fn into_inner(self) -> TyKind { | ||
231 | Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone()) | ||
232 | } | ||
233 | } | ||
234 | |||
235 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
236 | pub struct GenericArg { | ||
237 | interned: GenericArgData, | ||
238 | } | ||
239 | |||
240 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
241 | pub enum GenericArgData { | ||
242 | Ty(Ty), | ||
243 | } | ||
244 | |||
245 | impl GenericArg { | ||
246 | /// Constructs a generic argument using `GenericArgData`. | ||
247 | pub fn new(_interner: &Interner, data: GenericArgData) -> Self { | ||
248 | GenericArg { interned: data } | ||
249 | } | ||
250 | |||
251 | /// Gets the interned value. | ||
252 | pub fn interned(&self) -> &GenericArgData { | ||
253 | &self.interned | ||
254 | } | ||
255 | |||
256 | /// Asserts that this is a type argument. | ||
257 | pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty { | ||
258 | self.ty(interner).unwrap() | ||
259 | } | ||
260 | |||
261 | /// Checks whether the generic argument is a type. | ||
262 | pub fn is_ty(&self, _interner: &Interner) -> bool { | ||
263 | match self.interned() { | ||
264 | GenericArgData::Ty(_) => true, | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /// Returns the type if it is one, `None` otherwise. | ||
269 | pub fn ty(&self, _interner: &Interner) -> Option<&Ty> { | ||
270 | match self.interned() { | ||
271 | GenericArgData::Ty(t) => Some(t), | ||
272 | } | ||
273 | } | ||
274 | |||
275 | pub fn interned_mut(&mut self) -> &mut GenericArgData { | ||
276 | &mut self.interned | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /// A list of substitutions for generic parameters. | ||
281 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
282 | pub struct Substitution(SmallVec<[GenericArg; 2]>); | ||
283 | |||
284 | impl Substitution { | ||
285 | pub fn interned(&self) -> &SmallVec<[GenericArg; 2]> { | ||
286 | &self.0 | ||
287 | } | ||
288 | |||
289 | pub fn len(&self, _: &Interner) -> usize { | ||
290 | self.0.len() | ||
291 | } | ||
292 | |||
293 | pub fn is_empty(&self, _: &Interner) -> bool { | ||
294 | self.0.is_empty() | ||
295 | } | ||
296 | |||
297 | pub fn at(&self, _: &Interner, i: usize) -> &GenericArg { | ||
298 | &self.0[i] | ||
299 | } | ||
300 | |||
301 | pub fn empty(_: &Interner) -> Substitution { | ||
302 | Substitution(SmallVec::new()) | ||
303 | } | ||
304 | |||
305 | pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> { | ||
306 | self.0.iter() | ||
307 | } | ||
308 | |||
309 | pub fn from1(_interner: &Interner, ty: Ty) -> Substitution { | ||
310 | Substitution::intern({ | ||
311 | let mut v = SmallVec::new(); | ||
312 | v.push(ty.cast(&Interner)); | ||
313 | v | ||
314 | }) | ||
315 | } | ||
316 | |||
317 | pub fn from_iter( | ||
318 | interner: &Interner, | ||
319 | elements: impl IntoIterator<Item = impl CastTo<GenericArg>>, | ||
320 | ) -> Self { | ||
321 | Substitution(elements.into_iter().casted(interner).collect()) | ||
322 | } | ||
323 | |||
324 | pub fn apply<T: TypeWalk>(&self, value: T, _interner: &Interner) -> T { | ||
325 | value.subst_bound_vars(self) | ||
326 | } | ||
327 | |||
328 | // Temporary helper functions, to be removed | ||
329 | pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { | ||
330 | Substitution(interned) | ||
331 | } | ||
332 | |||
333 | pub fn interned_mut(&mut self) -> &mut SmallVec<[GenericArg; 2]> { | ||
334 | &mut self.0 | ||
335 | } | ||
336 | } | ||
337 | |||
338 | #[derive(Clone, PartialEq, Eq, Hash)] | ||
339 | pub struct Binders<T> { | ||
340 | /// The binders that quantify over the value. | ||
341 | pub binders: VariableKinds, | ||
342 | value: T, | ||
343 | } | ||
344 | |||
345 | impl<T> Binders<T> { | ||
346 | pub fn new(binders: VariableKinds, value: T) -> Self { | ||
347 | Self { binders, value } | ||
348 | } | ||
349 | |||
350 | pub fn empty(_interner: &Interner, value: T) -> Self { | ||
351 | crate::make_only_type_binders(0, value) | ||
352 | } | ||
353 | |||
354 | pub fn as_ref(&self) -> Binders<&T> { | ||
355 | Binders { binders: self.binders.clone(), value: &self.value } | ||
356 | } | ||
357 | |||
358 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { | ||
359 | Binders { binders: self.binders, value: f(self.value) } | ||
360 | } | ||
361 | |||
362 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | ||
363 | Some(Binders { binders: self.binders, value: f(self.value)? }) | ||
364 | } | ||
365 | |||
366 | pub fn skip_binders(&self) -> &T { | ||
367 | &self.value | ||
368 | } | ||
369 | |||
370 | pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) { | ||
371 | (self.value, self.binders) | ||
372 | } | ||
373 | |||
374 | /// Returns the number of binders. | ||
375 | pub fn len(&self, interner: &Interner) -> usize { | ||
376 | self.binders.len(interner) | ||
377 | } | ||
378 | |||
379 | // Temporary helper function, to be removed | ||
380 | pub fn skip_binders_mut(&mut self) -> &mut T { | ||
381 | &mut self.value | ||
382 | } | ||
383 | } | ||
384 | |||
385 | impl<T: Clone> Binders<&T> { | ||
386 | pub fn cloned(&self) -> Binders<T> { | ||
387 | Binders::new(self.binders.clone(), self.value.clone()) | ||
388 | } | ||
389 | } | ||
390 | |||
391 | impl<T: TypeWalk> Binders<T> { | ||
392 | /// Substitutes all variables. | ||
393 | pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T { | ||
394 | let (value, binders) = self.into_value_and_skipped_binders(); | ||
395 | assert_eq!(subst.len(interner), binders.len(interner)); | ||
396 | value.subst_bound_vars(subst) | ||
397 | } | ||
398 | } | ||
399 | |||
400 | impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> { | ||
401 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { | ||
402 | let Binders { ref binders, ref value } = *self; | ||
403 | write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?; | ||
404 | std::fmt::Debug::fmt(value, fmt) | ||
405 | } | ||
406 | } | ||
407 | |||
408 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | ||
409 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
410 | pub struct TraitRef { | ||
411 | pub trait_id: ChalkTraitId, | ||
412 | pub substitution: Substitution, | ||
413 | } | ||
414 | |||
415 | impl TraitRef { | ||
416 | pub fn self_type_parameter(&self, interner: &Interner) -> Ty { | ||
417 | self.substitution.at(interner, 0).assert_ty_ref(interner).clone() | ||
418 | } | ||
419 | } | ||
420 | |||
421 | /// Like `generics::WherePredicate`, but with resolved types: A condition on the | ||
422 | /// parameters of a generic item. | ||
423 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
424 | pub enum WhereClause { | ||
425 | /// The given trait needs to be implemented for its type parameters. | ||
426 | Implemented(TraitRef), | ||
427 | /// An associated type bindings like in `Iterator<Item = T>`. | ||
428 | AliasEq(AliasEq), | ||
429 | } | ||
430 | |||
431 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
432 | |||
433 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
434 | pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>); | ||
435 | |||
436 | impl QuantifiedWhereClauses { | ||
437 | pub fn from_iter( | ||
438 | _interner: &Interner, | ||
439 | elements: impl IntoIterator<Item = QuantifiedWhereClause>, | ||
440 | ) -> Self { | ||
441 | QuantifiedWhereClauses(elements.into_iter().collect()) | ||
442 | } | ||
443 | |||
444 | pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> { | ||
445 | &self.0 | ||
446 | } | ||
447 | |||
448 | pub fn interned_mut(&mut self) -> &mut Arc<[QuantifiedWhereClause]> { | ||
449 | &mut self.0 | ||
450 | } | ||
451 | } | ||
452 | |||
453 | /// Basically a claim (currently not validated / checked) that the contained | ||
454 | /// type / trait ref contains no inference variables; any inference variables it | ||
455 | /// contained have been replaced by bound variables, and `kinds` tells us how | ||
456 | /// many there are and whether they were normal or float/int variables. This is | ||
457 | /// used to erase irrelevant differences between types before using them in | ||
458 | /// queries. | ||
459 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
460 | pub struct Canonical<T> { | ||
461 | pub value: T, | ||
462 | pub binders: CanonicalVarKinds, | ||
463 | } | ||
464 | |||
465 | /// Something (usually a goal), along with an environment. | ||
466 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
467 | pub struct InEnvironment<T> { | ||
468 | pub environment: chalk_ir::Environment<Interner>, | ||
469 | pub goal: T, | ||
470 | } | ||
471 | |||
472 | impl<T> InEnvironment<T> { | ||
473 | pub fn new(environment: &chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> { | ||
474 | InEnvironment { environment: environment.clone(), goal: value } | ||
475 | } | ||
476 | } | ||
477 | |||
478 | /// Something that needs to be proven (by Chalk) during type checking, e.g. that | ||
479 | /// a certain type implements a certain trait. Proving the Obligation might | ||
480 | /// result in additional information about inference variables. | ||
481 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
482 | pub enum DomainGoal { | ||
483 | Holds(WhereClause), | ||
484 | } | ||
485 | |||
486 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
487 | pub struct AliasEq { | ||
488 | pub alias: AliasTy, | ||
489 | pub ty: Ty, | ||
490 | } | ||
491 | |||
492 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
493 | pub struct ConstrainedSubst { | ||
494 | pub subst: Substitution, | ||
495 | } | ||
496 | |||
497 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
498 | /// A (possible) solution for a proposed goal. | ||
499 | pub enum Solution { | ||
500 | /// The goal indeed holds, and there is a unique value for all existential | ||
501 | /// variables. | ||
502 | Unique(Canonical<ConstrainedSubst>), | ||
503 | |||
504 | /// The goal may be provable in multiple ways, but regardless we may have some guidance | ||
505 | /// for type inference. In this case, we don't return any lifetime | ||
506 | /// constraints, since we have not "committed" to any particular solution | ||
507 | /// yet. | ||
508 | Ambig(Guidance), | ||
509 | } | ||
510 | |||
511 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
512 | /// When a goal holds ambiguously (e.g., because there are multiple possible | ||
513 | /// solutions), we issue a set of *guidance* back to type inference. | ||
514 | pub enum Guidance { | ||
515 | /// The existential variables *must* have the given values if the goal is | ||
516 | /// ever to hold, but that alone isn't enough to guarantee the goal will | ||
517 | /// actually hold. | ||
518 | Definite(Canonical<Substitution>), | ||
519 | |||
520 | /// There are multiple plausible values for the existentials, but the ones | ||
521 | /// here are suggested as the preferred choice heuristically. These should | ||
522 | /// be used for inference fallback only. | ||
523 | Suggested(Canonical<Substitution>), | ||
524 | |||
525 | /// There's no useful information to feed back to type inference | ||
526 | Unknown, | ||
527 | } | ||
528 | |||
529 | /// The kinds of placeholders we need during type inference. There's separate | ||
530 | /// values for general types, and for integer and float variables. The latter | ||
531 | /// two are used for inference of literal values (e.g. `100` could be one of | ||
532 | /// several integer types). | ||
533 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||
534 | pub struct InferenceVar { | ||
535 | index: u32, | ||
536 | } | ||
537 | |||
538 | impl From<u32> for InferenceVar { | ||
539 | fn from(index: u32) -> InferenceVar { | ||
540 | InferenceVar { index } | ||
541 | } | ||
542 | } | ||
543 | |||
544 | impl InferenceVar { | ||
545 | /// Gets the underlying index value. | ||
546 | pub fn index(self) -> u32 { | ||
547 | self.index | ||
548 | } | ||
549 | } | ||
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index 91116dcda..873d563c0 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs | |||
@@ -408,7 +408,7 @@ impl TypeWalk for AliasEq { | |||
408 | } | 408 | } |
409 | } | 409 | } |
410 | 410 | ||
411 | impl TypeWalk for FnSubst { | 411 | impl TypeWalk for FnSubst<Interner> { |
412 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 412 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
413 | self.0.walk(f) | 413 | self.0.walk(f) |
414 | } | 414 | } |