diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 615 |
1 files changed, 275 insertions, 340 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 50d248674..e77f24e4e 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -25,32 +25,31 @@ mod test_db; | |||
25 | 25 | ||
26 | use std::{iter, mem, ops::Deref, sync::Arc}; | 26 | use std::{iter, mem, ops::Deref, sync::Arc}; |
27 | 27 | ||
28 | use base_db::{salsa, CrateId}; | 28 | use base_db::salsa; |
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | builtin_type::BuiltinType, | 30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId, |
31 | expr::ExprId, | 31 | FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, |
32 | type_ref::{Mutability, Rawness}, | 32 | TypeParamId, |
33 | AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, | ||
34 | Lookup, TraitId, TypeAliasId, TypeParamId, | ||
35 | }; | 33 | }; |
36 | use itertools::Itertools; | 34 | use itertools::Itertools; |
37 | 35 | ||
38 | use crate::{ | 36 | use crate::{ |
39 | db::HirDatabase, | 37 | db::HirDatabase, |
40 | display::HirDisplay, | 38 | display::HirDisplay, |
41 | primitive::{FloatTy, IntTy}, | ||
42 | utils::{generics, make_mut_slice, Generics}, | 39 | utils::{generics, make_mut_slice, Generics}, |
43 | }; | 40 | }; |
44 | 41 | ||
45 | pub use autoderef::autoderef; | 42 | pub use autoderef::autoderef; |
46 | pub use infer::{InferTy, InferenceResult}; | 43 | pub use infer::{InferenceResult, InferenceVar}; |
47 | pub use lower::{ | 44 | pub use lower::{ |
48 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 45 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
49 | TyDefId, TyLoweringContext, ValueTyDefId, | 46 | TyDefId, TyLoweringContext, ValueTyDefId, |
50 | }; | 47 | }; |
51 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
52 | 49 | ||
53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; | 50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; |
51 | |||
52 | pub(crate) use crate::traits::chalk::Interner; | ||
54 | 53 | ||
55 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
56 | pub enum Lifetime { | 55 | pub enum Lifetime { |
@@ -58,211 +57,6 @@ pub enum Lifetime { | |||
58 | Static, | 57 | Static, |
59 | } | 58 | } |
60 | 59 | ||
61 | /// A type constructor or type name: this might be something like the primitive | ||
62 | /// type `bool`, a struct like `Vec`, or things like function pointers or | ||
63 | /// tuples. | ||
64 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | ||
65 | pub enum TypeCtor { | ||
66 | /// The primitive boolean type. Written as `bool`. | ||
67 | Bool, | ||
68 | |||
69 | /// The primitive character type; holds a Unicode scalar value | ||
70 | /// (a non-surrogate code point). Written as `char`. | ||
71 | Char, | ||
72 | |||
73 | /// A primitive integer type. For example, `i32`. | ||
74 | Int(IntTy), | ||
75 | |||
76 | /// A primitive floating-point type. For example, `f64`. | ||
77 | Float(FloatTy), | ||
78 | |||
79 | /// Structures, enumerations and unions. | ||
80 | Adt(AdtId), | ||
81 | |||
82 | /// The pointee of a string slice. Written as `str`. | ||
83 | Str, | ||
84 | |||
85 | /// The pointee of an array slice. Written as `[T]`. | ||
86 | Slice, | ||
87 | |||
88 | /// An array with the given length. Written as `[T; n]`. | ||
89 | Array, | ||
90 | |||
91 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
92 | RawPtr(Mutability), | ||
93 | |||
94 | /// A reference; a pointer with an associated lifetime. Written as | ||
95 | /// `&'a mut T` or `&'a T`. | ||
96 | Ref(Mutability), | ||
97 | |||
98 | /// The anonymous type of a function declaration/definition. Each | ||
99 | /// function has a unique type, which is output (for a function | ||
100 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
101 | /// | ||
102 | /// This includes tuple struct / enum variant constructors as well. | ||
103 | /// | ||
104 | /// For example the type of `bar` here: | ||
105 | /// | ||
106 | /// ``` | ||
107 | /// fn foo() -> i32 { 1 } | ||
108 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
109 | /// ``` | ||
110 | FnDef(CallableDefId), | ||
111 | |||
112 | /// A pointer to a function. Written as `fn() -> i32`. | ||
113 | /// | ||
114 | /// For example the type of `bar` here: | ||
115 | /// | ||
116 | /// ``` | ||
117 | /// fn foo() -> i32 { 1 } | ||
118 | /// let bar: fn() -> i32 = foo; | ||
119 | /// ``` | ||
120 | // FIXME make this a Ty variant like in Chalk | ||
121 | FnPtr { num_args: u16, is_varargs: bool }, | ||
122 | |||
123 | /// The never type `!`. | ||
124 | Never, | ||
125 | |||
126 | /// A tuple type. For example, `(i32, bool)`. | ||
127 | Tuple { cardinality: u16 }, | ||
128 | |||
129 | /// Represents an associated item like `Iterator::Item`. This is used | ||
130 | /// when we have tried to normalize a projection like `T::Item` but | ||
131 | /// couldn't find a better representation. In that case, we generate | ||
132 | /// an **application type** like `(Iterator::Item)<T>`. | ||
133 | AssociatedType(TypeAliasId), | ||
134 | |||
135 | /// This represents a placeholder for an opaque type in situations where we | ||
136 | /// don't know the hidden type (i.e. currently almost always). This is | ||
137 | /// analogous to the `AssociatedType` type constructor. | ||
138 | /// It is also used as the type of async block, with one type parameter | ||
139 | /// representing the Future::Output type. | ||
140 | OpaqueType(OpaqueTyId), | ||
141 | |||
142 | /// Represents a foreign type declared in external blocks. | ||
143 | ForeignType(TypeAliasId), | ||
144 | |||
145 | /// The type of a specific closure. | ||
146 | /// | ||
147 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
148 | /// parameter. | ||
149 | Closure { def: DefWithBodyId, expr: ExprId }, | ||
150 | } | ||
151 | |||
152 | impl TypeCtor { | ||
153 | pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { | ||
154 | match self { | ||
155 | TypeCtor::Bool | ||
156 | | TypeCtor::Char | ||
157 | | TypeCtor::Int(_) | ||
158 | | TypeCtor::Float(_) | ||
159 | | TypeCtor::Str | ||
160 | | TypeCtor::Never => 0, | ||
161 | TypeCtor::Slice | ||
162 | | TypeCtor::Array | ||
163 | | TypeCtor::RawPtr(_) | ||
164 | | TypeCtor::Ref(_) | ||
165 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | ||
166 | => 1, | ||
167 | TypeCtor::Adt(adt) => { | ||
168 | let generic_params = generics(db.upcast(), adt.into()); | ||
169 | generic_params.len() | ||
170 | } | ||
171 | TypeCtor::FnDef(callable) => { | ||
172 | let generic_params = generics(db.upcast(), callable.into()); | ||
173 | generic_params.len() | ||
174 | } | ||
175 | TypeCtor::AssociatedType(type_alias) => { | ||
176 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
177 | generic_params.len() | ||
178 | } | ||
179 | TypeCtor::ForeignType(type_alias) => { | ||
180 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
181 | generic_params.len() | ||
182 | } | ||
183 | TypeCtor::OpaqueType(opaque_ty_id) => { | ||
184 | match opaque_ty_id { | ||
185 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
186 | let generic_params = generics(db.upcast(), func.into()); | ||
187 | generic_params.len() | ||
188 | } | ||
189 | // 1 param representing Future::Output type. | ||
190 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
191 | } | ||
192 | } | ||
193 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | ||
194 | TypeCtor::Tuple { cardinality } => cardinality as usize, | ||
195 | } | ||
196 | } | ||
197 | |||
198 | pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { | ||
199 | match self { | ||
200 | TypeCtor::Bool | ||
201 | | TypeCtor::Char | ||
202 | | TypeCtor::Int(_) | ||
203 | | TypeCtor::Float(_) | ||
204 | | TypeCtor::Str | ||
205 | | TypeCtor::Never | ||
206 | | TypeCtor::Slice | ||
207 | | TypeCtor::Array | ||
208 | | TypeCtor::RawPtr(_) | ||
209 | | TypeCtor::Ref(_) | ||
210 | | TypeCtor::FnPtr { .. } | ||
211 | | TypeCtor::Tuple { .. } => None, | ||
212 | // Closure's krate is irrelevant for coherence I would think? | ||
213 | TypeCtor::Closure { .. } => None, | ||
214 | TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()), | ||
215 | TypeCtor::FnDef(callable) => Some(callable.krate(db)), | ||
216 | TypeCtor::AssociatedType(type_alias) => { | ||
217 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
218 | } | ||
219 | TypeCtor::ForeignType(type_alias) => { | ||
220 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
221 | } | ||
222 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { | ||
223 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
224 | Some(func.lookup(db.upcast()).module(db.upcast()).krate()) | ||
225 | } | ||
226 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => { | ||
227 | Some(def.module(db.upcast()).krate()) | ||
228 | } | ||
229 | }, | ||
230 | } | ||
231 | } | ||
232 | |||
233 | pub fn as_generic_def(self) -> Option<GenericDefId> { | ||
234 | match self { | ||
235 | TypeCtor::Bool | ||
236 | | TypeCtor::Char | ||
237 | | TypeCtor::Int(_) | ||
238 | | TypeCtor::Float(_) | ||
239 | | TypeCtor::Str | ||
240 | | TypeCtor::Never | ||
241 | | TypeCtor::Slice | ||
242 | | TypeCtor::Array | ||
243 | | TypeCtor::RawPtr(_) | ||
244 | | TypeCtor::Ref(_) | ||
245 | | TypeCtor::FnPtr { .. } | ||
246 | | TypeCtor::Tuple { .. } | ||
247 | | TypeCtor::Closure { .. } => None, | ||
248 | TypeCtor::Adt(adt) => Some(adt.into()), | ||
249 | TypeCtor::FnDef(callable) => Some(callable.into()), | ||
250 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | ||
251 | TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), | ||
252 | TypeCtor::OpaqueType(_impl_trait_id) => None, | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
257 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
258 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
259 | /// several other things. | ||
260 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
261 | pub struct ApplicationTy { | ||
262 | pub ctor: TypeCtor, | ||
263 | pub parameters: Substs, | ||
264 | } | ||
265 | |||
266 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
267 | pub struct OpaqueTy { | 61 | pub struct OpaqueTy { |
268 | pub opaque_ty_id: OpaqueTyId, | 62 | pub opaque_ty_id: OpaqueTyId, |
@@ -305,29 +99,118 @@ impl TypeWalk for ProjectionTy { | |||
305 | } | 99 | } |
306 | } | 100 | } |
307 | 101 | ||
308 | /// A type. | 102 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
309 | /// | 103 | pub struct FnSig { |
310 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 104 | pub variadic: bool, |
311 | /// the same thing (but in a different way). | 105 | } |
312 | /// | 106 | |
313 | /// This should be cheap to clone. | ||
314 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 107 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
315 | pub enum Ty { | 108 | pub struct FnPointer { |
316 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 109 | pub num_args: usize, |
317 | /// type like `bool`, a struct, tuple, function pointer, reference or | 110 | pub sig: FnSig, |
318 | /// several other things. | 111 | pub substs: Substs, |
319 | Apply(ApplicationTy), | 112 | } |
320 | 113 | ||
114 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
115 | pub enum AliasTy { | ||
321 | /// A "projection" type corresponds to an (unnormalized) | 116 | /// A "projection" type corresponds to an (unnormalized) |
322 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 117 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
323 | /// trait and all its parameters are fully known. | 118 | /// trait and all its parameters are fully known. |
324 | Projection(ProjectionTy), | 119 | Projection(ProjectionTy), |
325 | |||
326 | /// An opaque type (`impl Trait`). | 120 | /// An opaque type (`impl Trait`). |
327 | /// | 121 | /// |
328 | /// This is currently only used for return type impl trait; each instance of | 122 | /// This is currently only used for return type impl trait; each instance of |
329 | /// `impl Trait` in a return type gets its own ID. | 123 | /// `impl Trait` in a return type gets its own ID. |
330 | Opaque(OpaqueTy), | 124 | Opaque(OpaqueTy), |
125 | } | ||
126 | |||
127 | /// A type. | ||
128 | /// | ||
129 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | ||
130 | /// the same thing (but in a different way). | ||
131 | /// | ||
132 | /// This should be cheap to clone. | ||
133 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
134 | pub enum Ty { | ||
135 | /// Structures, enumerations and unions. | ||
136 | Adt(AdtId<Interner>, Substs), | ||
137 | |||
138 | /// Represents an associated item like `Iterator::Item`. This is used | ||
139 | /// when we have tried to normalize a projection like `T::Item` but | ||
140 | /// couldn't find a better representation. In that case, we generate | ||
141 | /// an **application type** like `(Iterator::Item)<T>`. | ||
142 | AssociatedType(TypeAliasId, Substs), | ||
143 | |||
144 | /// a scalar type like `bool` or `u32` | ||
145 | Scalar(Scalar), | ||
146 | |||
147 | /// A tuple type. For example, `(i32, bool)`. | ||
148 | Tuple(usize, Substs), | ||
149 | |||
150 | /// An array with the given length. Written as `[T; n]`. | ||
151 | Array(Substs), | ||
152 | |||
153 | /// The pointee of an array slice. Written as `[T]`. | ||
154 | Slice(Substs), | ||
155 | |||
156 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
157 | Raw(Mutability, Substs), | ||
158 | |||
159 | /// A reference; a pointer with an associated lifetime. Written as | ||
160 | /// `&'a mut T` or `&'a T`. | ||
161 | Ref(Mutability, Substs), | ||
162 | |||
163 | /// This represents a placeholder for an opaque type in situations where we | ||
164 | /// don't know the hidden type (i.e. currently almost always). This is | ||
165 | /// analogous to the `AssociatedType` type constructor. | ||
166 | /// It is also used as the type of async block, with one type parameter | ||
167 | /// representing the Future::Output type. | ||
168 | OpaqueType(OpaqueTyId, Substs), | ||
169 | |||
170 | /// The anonymous type of a function declaration/definition. Each | ||
171 | /// function has a unique type, which is output (for a function | ||
172 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
173 | /// | ||
174 | /// This includes tuple struct / enum variant constructors as well. | ||
175 | /// | ||
176 | /// For example the type of `bar` here: | ||
177 | /// | ||
178 | /// ``` | ||
179 | /// fn foo() -> i32 { 1 } | ||
180 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
181 | /// ``` | ||
182 | FnDef(CallableDefId, Substs), | ||
183 | |||
184 | /// The pointee of a string slice. Written as `str`. | ||
185 | Str, | ||
186 | |||
187 | /// The never type `!`. | ||
188 | Never, | ||
189 | |||
190 | /// The type of a specific closure. | ||
191 | /// | ||
192 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
193 | /// parameter. | ||
194 | Closure(DefWithBodyId, ExprId, Substs), | ||
195 | |||
196 | /// Represents a foreign type declared in external blocks. | ||
197 | ForeignType(TypeAliasId), | ||
198 | |||
199 | /// A pointer to a function. Written as `fn() -> i32`. | ||
200 | /// | ||
201 | /// For example the type of `bar` here: | ||
202 | /// | ||
203 | /// ``` | ||
204 | /// fn foo() -> i32 { 1 } | ||
205 | /// let bar: fn() -> i32 = foo; | ||
206 | /// ``` | ||
207 | Function(FnPointer), | ||
208 | |||
209 | /// An "alias" type represents some form of type alias, such as: | ||
210 | /// - An associated type projection like `<T as Iterator>::Item` | ||
211 | /// - `impl Trait` types | ||
212 | /// - Named type aliases like `type Foo<X> = Vec<X>` | ||
213 | Alias(AliasTy), | ||
331 | 214 | ||
332 | /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) | 215 | /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) |
333 | /// {}` when we're type-checking the body of that function. In this | 216 | /// {}` when we're type-checking the body of that function. In this |
@@ -340,10 +223,10 @@ pub enum Ty { | |||
340 | /// parameters get turned into variables; during trait resolution, inference | 223 | /// parameters get turned into variables; during trait resolution, inference |
341 | /// variables get turned into bound variables and back; and in `Dyn` the | 224 | /// variables get turned into bound variables and back; and in `Dyn` the |
342 | /// `Self` type is represented with a bound variable as well. | 225 | /// `Self` type is represented with a bound variable as well. |
343 | Bound(BoundVar), | 226 | BoundVar(BoundVar), |
344 | 227 | ||
345 | /// A type variable used during type checking. | 228 | /// A type variable used during type checking. |
346 | Infer(InferTy), | 229 | InferenceVar(InferenceVar, TyVariableKind), |
347 | 230 | ||
348 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). | 231 | /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). |
349 | /// | 232 | /// |
@@ -424,7 +307,7 @@ impl Substs { | |||
424 | generic_params | 307 | generic_params |
425 | .iter() | 308 | .iter() |
426 | .enumerate() | 309 | .enumerate() |
427 | .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) | 310 | .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) |
428 | .collect(), | 311 | .collect(), |
429 | ) | 312 | ) |
430 | } | 313 | } |
@@ -440,10 +323,6 @@ impl Substs { | |||
440 | Substs::builder(generic_params.len()) | 323 | Substs::builder(generic_params.len()) |
441 | } | 324 | } |
442 | 325 | ||
443 | pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | ||
444 | Substs::builder(type_ctor.num_ty_params(db)) | ||
445 | } | ||
446 | |||
447 | fn builder(param_count: usize) -> SubstsBuilder { | 326 | fn builder(param_count: usize) -> SubstsBuilder { |
448 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 327 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
449 | } | 328 | } |
@@ -476,7 +355,7 @@ impl SubstsBuilder { | |||
476 | } | 355 | } |
477 | 356 | ||
478 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { | 357 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { |
479 | self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx)))) | 358 | self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx)))) |
480 | } | 359 | } |
481 | 360 | ||
482 | pub fn fill_with_unknown(self) -> Self { | 361 | pub fn fill_with_unknown(self) -> Self { |
@@ -656,41 +535,41 @@ impl TypeWalk for GenericPredicate { | |||
656 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 535 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
657 | pub struct Canonical<T> { | 536 | pub struct Canonical<T> { |
658 | pub value: T, | 537 | pub value: T, |
659 | pub kinds: Arc<[TyKind]>, | 538 | pub kinds: Arc<[TyVariableKind]>, |
660 | } | 539 | } |
661 | 540 | ||
662 | impl<T> Canonical<T> { | 541 | impl<T> Canonical<T> { |
663 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { | 542 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { |
664 | Self { value, kinds: kinds.into_iter().collect() } | 543 | Self { value, kinds: kinds.into_iter().collect() } |
665 | } | 544 | } |
666 | } | 545 | } |
667 | 546 | ||
668 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
669 | pub enum TyKind { | ||
670 | General, | ||
671 | Integer, | ||
672 | Float, | ||
673 | } | ||
674 | |||
675 | /// A function signature as seen by type inference: Several parameter types and | 547 | /// A function signature as seen by type inference: Several parameter types and |
676 | /// one return type. | 548 | /// one return type. |
677 | #[derive(Clone, PartialEq, Eq, Debug)] | 549 | #[derive(Clone, PartialEq, Eq, Debug)] |
678 | pub struct FnSig { | 550 | pub struct CallableSig { |
679 | params_and_return: Arc<[Ty]>, | 551 | params_and_return: Arc<[Ty]>, |
680 | is_varargs: bool, | 552 | is_varargs: bool, |
681 | } | 553 | } |
682 | 554 | ||
683 | /// A polymorphic function signature. | 555 | /// A polymorphic function signature. |
684 | pub type PolyFnSig = Binders<FnSig>; | 556 | pub type PolyFnSig = Binders<CallableSig>; |
685 | 557 | ||
686 | impl FnSig { | 558 | impl CallableSig { |
687 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { | 559 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig { |
688 | params.push(ret); | 560 | params.push(ret); |
689 | FnSig { params_and_return: params.into(), is_varargs } | 561 | CallableSig { params_and_return: params.into(), is_varargs } |
562 | } | ||
563 | |||
564 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { | ||
565 | CallableSig { | ||
566 | params_and_return: Arc::clone(&fn_ptr.substs.0), | ||
567 | is_varargs: fn_ptr.sig.variadic, | ||
568 | } | ||
690 | } | 569 | } |
691 | 570 | ||
692 | pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { | 571 | pub fn from_substs(substs: &Substs) -> CallableSig { |
693 | FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } | 572 | CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } |
694 | } | 573 | } |
695 | 574 | ||
696 | pub fn params(&self) -> &[Ty] { | 575 | pub fn params(&self) -> &[Ty] { |
@@ -702,7 +581,7 @@ impl FnSig { | |||
702 | } | 581 | } |
703 | } | 582 | } |
704 | 583 | ||
705 | impl TypeWalk for FnSig { | 584 | impl TypeWalk for CallableSig { |
706 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 585 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
707 | for t in self.params_and_return.iter() { | 586 | for t in self.params_and_return.iter() { |
708 | t.walk(f); | 587 | t.walk(f); |
@@ -721,49 +600,46 @@ impl TypeWalk for FnSig { | |||
721 | } | 600 | } |
722 | 601 | ||
723 | impl Ty { | 602 | impl Ty { |
724 | pub fn simple(ctor: TypeCtor) -> Ty { | ||
725 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) | ||
726 | } | ||
727 | pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { | ||
728 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) | ||
729 | } | ||
730 | pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { | ||
731 | Ty::Apply(ApplicationTy { ctor, parameters }) | ||
732 | } | ||
733 | pub fn unit() -> Self { | 603 | pub fn unit() -> Self { |
734 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 604 | Ty::Tuple(0, Substs::empty()) |
735 | } | 605 | } |
736 | pub fn fn_ptr(sig: FnSig) -> Self { | 606 | |
737 | Ty::apply( | 607 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { |
738 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 608 | Ty::Adt(AdtId(adt), substs) |
739 | Substs(sig.params_and_return), | ||
740 | ) | ||
741 | } | 609 | } |
742 | pub fn builtin(builtin: BuiltinType) -> Self { | 610 | |
743 | Ty::simple(match builtin { | 611 | pub fn fn_ptr(sig: CallableSig) -> Self { |
744 | BuiltinType::Char => TypeCtor::Char, | 612 | Ty::Function(FnPointer { |
745 | BuiltinType::Bool => TypeCtor::Bool, | 613 | num_args: sig.params().len(), |
746 | BuiltinType::Str => TypeCtor::Str, | 614 | sig: FnSig { variadic: sig.is_varargs }, |
747 | BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), | 615 | substs: Substs(sig.params_and_return), |
748 | BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), | ||
749 | }) | 616 | }) |
750 | } | 617 | } |
751 | 618 | ||
619 | pub fn builtin(builtin: BuiltinType) -> Self { | ||
620 | match builtin { | ||
621 | BuiltinType::Char => Ty::Scalar(Scalar::Char), | ||
622 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), | ||
623 | BuiltinType::Str => Ty::Str, | ||
624 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | ||
625 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), | ||
626 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), | ||
627 | } | ||
628 | } | ||
629 | |||
752 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 630 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
753 | match self { | 631 | match self { |
754 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 632 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
755 | Some((parameters.as_single(), *mutability)) | ||
756 | } | ||
757 | _ => None, | 633 | _ => None, |
758 | } | 634 | } |
759 | } | 635 | } |
760 | 636 | ||
761 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 637 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
762 | match self { | 638 | match self { |
763 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 639 | Ty::Ref(mutability, parameters) => { |
764 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 640 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
765 | } | 641 | } |
766 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 642 | Ty::Raw(mutability, parameters) => { |
767 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 643 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
768 | } | 644 | } |
769 | _ => None, | 645 | _ => None, |
@@ -773,39 +649,69 @@ impl Ty { | |||
773 | pub fn strip_references(&self) -> &Ty { | 649 | pub fn strip_references(&self) -> &Ty { |
774 | let mut t: &Ty = self; | 650 | let mut t: &Ty = self; |
775 | 651 | ||
776 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 652 | while let Ty::Ref(_mutability, parameters) = t { |
777 | t = parameters.as_single(); | 653 | t = parameters.as_single(); |
778 | } | 654 | } |
779 | 655 | ||
780 | t | 656 | t |
781 | } | 657 | } |
782 | 658 | ||
783 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 659 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { |
784 | match self { | 660 | match self { |
785 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 661 | Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), |
786 | Some((*adt_def, parameters)) | ||
787 | } | ||
788 | _ => None, | 662 | _ => None, |
789 | } | 663 | } |
790 | } | 664 | } |
791 | 665 | ||
792 | pub fn as_tuple(&self) -> Option<&Substs> { | 666 | pub fn as_tuple(&self) -> Option<&Substs> { |
793 | match self { | 667 | match self { |
794 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 668 | Ty::Tuple(_, substs) => Some(substs), |
795 | Some(parameters) | 669 | _ => None, |
796 | } | 670 | } |
671 | } | ||
672 | |||
673 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | ||
674 | match *self { | ||
675 | Ty::Adt(AdtId(adt), ..) => Some(adt.into()), | ||
676 | Ty::FnDef(callable, ..) => Some(callable.into()), | ||
677 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | ||
678 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | ||
797 | _ => None, | 679 | _ => None, |
798 | } | 680 | } |
799 | } | 681 | } |
800 | 682 | ||
801 | pub fn is_never(&self) -> bool { | 683 | pub fn is_never(&self) -> bool { |
802 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 684 | matches!(self, Ty::Never) |
803 | } | 685 | } |
804 | 686 | ||
805 | pub fn is_unknown(&self) -> bool { | 687 | pub fn is_unknown(&self) -> bool { |
806 | matches!(self, Ty::Unknown) | 688 | matches!(self, Ty::Unknown) |
807 | } | 689 | } |
808 | 690 | ||
691 | pub fn equals_ctor(&self, other: &Ty) -> bool { | ||
692 | match (self, other) { | ||
693 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | ||
694 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | ||
695 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | ||
696 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | ||
697 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | ||
698 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | ||
699 | (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { | ||
700 | expr == expr2 && def == def2 | ||
701 | } | ||
702 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
703 | | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2, | ||
704 | ( | ||
705 | Ty::Function(FnPointer { num_args, sig, .. }), | ||
706 | Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), | ||
707 | ) => num_args == num_args2 && sig == sig2, | ||
708 | (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, | ||
709 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | ||
710 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | ||
711 | _ => false, | ||
712 | } | ||
713 | } | ||
714 | |||
809 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 715 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
810 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 716 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
811 | match self { | 717 | match self { |
@@ -824,41 +730,30 @@ impl Ty { | |||
824 | 730 | ||
825 | fn builtin_deref(&self) -> Option<Ty> { | 731 | fn builtin_deref(&self) -> Option<Ty> { |
826 | match self { | 732 | match self { |
827 | Ty::Apply(a_ty) => match a_ty.ctor { | 733 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
828 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 734 | Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), |
829 | TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
830 | _ => None, | ||
831 | }, | ||
832 | _ => None, | 735 | _ => None, |
833 | } | 736 | } |
834 | } | 737 | } |
835 | 738 | ||
836 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 739 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
837 | match self { | 740 | match self { |
838 | &Ty::Apply(ApplicationTy { | 741 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
839 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
840 | .. | ||
841 | }) => Some(func), | ||
842 | _ => None, | 742 | _ => None, |
843 | } | 743 | } |
844 | } | 744 | } |
845 | 745 | ||
846 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 746 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
847 | match self { | 747 | match self { |
848 | Ty::Apply(a_ty) => match a_ty.ctor { | 748 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
849 | TypeCtor::FnPtr { is_varargs, .. } => { | 749 | Ty::FnDef(def, parameters) => { |
850 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 750 | let sig = db.callable_item_signature(*def); |
851 | } | 751 | Some(sig.subst(¶meters)) |
852 | TypeCtor::FnDef(def) => { | 752 | } |
853 | let sig = db.callable_item_signature(def); | 753 | Ty::Closure(.., substs) => { |
854 | Some(sig.subst(&a_ty.parameters)) | 754 | let sig_param = &substs[0]; |
855 | } | 755 | sig_param.callable_sig(db) |
856 | TypeCtor::Closure { .. } => { | 756 | } |
857 | let sig_param = &a_ty.parameters[0]; | ||
858 | sig_param.callable_sig(db) | ||
859 | } | ||
860 | _ => None, | ||
861 | }, | ||
862 | _ => None, | 757 | _ => None, |
863 | } | 758 | } |
864 | } | 759 | } |
@@ -867,28 +762,66 @@ impl Ty { | |||
867 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 762 | /// the `Substs` for these type parameters with the given ones. (So e.g. if |
868 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 763 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
869 | /// `Option<u32>` afterwards.) | 764 | /// `Option<u32>` afterwards.) |
870 | pub fn apply_substs(self, substs: Substs) -> Ty { | 765 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
871 | match self { | 766 | match &mut self { |
872 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 767 | Ty::Adt(_, substs) |
873 | assert_eq!(previous_substs.len(), substs.len()); | 768 | | Ty::Slice(substs) |
874 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | 769 | | Ty::Array(substs) |
770 | | Ty::Raw(_, substs) | ||
771 | | Ty::Ref(_, substs) | ||
772 | | Ty::FnDef(_, substs) | ||
773 | | Ty::Function(FnPointer { substs, .. }) | ||
774 | | Ty::Tuple(_, substs) | ||
775 | | Ty::OpaqueType(_, substs) | ||
776 | | Ty::AssociatedType(_, substs) | ||
777 | | Ty::Closure(.., substs) => { | ||
778 | assert_eq!(substs.len(), new_substs.len()); | ||
779 | *substs = new_substs; | ||
875 | } | 780 | } |
876 | _ => self, | 781 | _ => (), |
877 | } | 782 | } |
783 | self | ||
878 | } | 784 | } |
879 | 785 | ||
880 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 786 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
881 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 787 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
882 | pub fn substs(&self) -> Option<Substs> { | 788 | pub fn substs(&self) -> Option<&Substs> { |
883 | match self { | 789 | match self { |
884 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 790 | Ty::Adt(_, substs) |
791 | | Ty::Slice(substs) | ||
792 | | Ty::Array(substs) | ||
793 | | Ty::Raw(_, substs) | ||
794 | | Ty::Ref(_, substs) | ||
795 | | Ty::FnDef(_, substs) | ||
796 | | Ty::Function(FnPointer { substs, .. }) | ||
797 | | Ty::Tuple(_, substs) | ||
798 | | Ty::OpaqueType(_, substs) | ||
799 | | Ty::AssociatedType(_, substs) | ||
800 | | Ty::Closure(.., substs) => Some(substs), | ||
801 | _ => None, | ||
802 | } | ||
803 | } | ||
804 | |||
805 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | ||
806 | match self { | ||
807 | Ty::Adt(_, substs) | ||
808 | | Ty::Slice(substs) | ||
809 | | Ty::Array(substs) | ||
810 | | Ty::Raw(_, substs) | ||
811 | | Ty::Ref(_, substs) | ||
812 | | Ty::FnDef(_, substs) | ||
813 | | Ty::Function(FnPointer { substs, .. }) | ||
814 | | Ty::Tuple(_, substs) | ||
815 | | Ty::OpaqueType(_, substs) | ||
816 | | Ty::AssociatedType(_, substs) | ||
817 | | Ty::Closure(.., substs) => Some(substs), | ||
885 | _ => None, | 818 | _ => None, |
886 | } | 819 | } |
887 | } | 820 | } |
888 | 821 | ||
889 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 822 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
890 | match self { | 823 | match self { |
891 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 824 | Ty::OpaqueType(opaque_ty_id, ..) => { |
892 | match opaque_ty_id { | 825 | match opaque_ty_id { |
893 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 826 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
894 | let krate = def.module(db.upcast()).krate(); | 827 | let krate = def.module(db.upcast()).krate(); |
@@ -911,7 +844,7 @@ impl Ty { | |||
911 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 844 | OpaqueTyId::ReturnTypeImplTrait(..) => None, |
912 | } | 845 | } |
913 | } | 846 | } |
914 | Ty::Opaque(opaque_ty) => { | 847 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { |
915 | let predicates = match opaque_ty.opaque_ty_id { | 848 | let predicates = match opaque_ty.opaque_ty_id { |
916 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 849 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
917 | db.return_type_impl_traits(func).map(|it| { | 850 | db.return_type_impl_traits(func).map(|it| { |
@@ -949,13 +882,13 @@ impl Ty { | |||
949 | 882 | ||
950 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 883 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
951 | match self { | 884 | match self { |
952 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 885 | Ty::AssociatedType(type_alias_id, ..) => { |
953 | match type_alias_id.lookup(db.upcast()).container { | 886 | match type_alias_id.lookup(db.upcast()).container { |
954 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 887 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
955 | _ => None, | 888 | _ => None, |
956 | } | 889 | } |
957 | } | 890 | } |
958 | Ty::Projection(projection_ty) => { | 891 | Ty::Alias(AliasTy::Projection(projection_ty)) => { |
959 | match projection_ty.associated_ty.lookup(db.upcast()).container { | 892 | match projection_ty.associated_ty.lookup(db.upcast()).container { |
960 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 893 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
961 | _ => None, | 894 | _ => None, |
@@ -1033,7 +966,7 @@ pub trait TypeWalk { | |||
1033 | { | 966 | { |
1034 | self.walk_mut_binders( | 967 | self.walk_mut_binders( |
1035 | &mut |ty, binders| { | 968 | &mut |ty, binders| { |
1036 | if let &mut Ty::Bound(bound) = ty { | 969 | if let &mut Ty::BoundVar(bound) = ty { |
1037 | if bound.debruijn >= binders { | 970 | if bound.debruijn >= binders { |
1038 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 971 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
1039 | } | 972 | } |
@@ -1051,8 +984,8 @@ pub trait TypeWalk { | |||
1051 | { | 984 | { |
1052 | self.fold_binders( | 985 | self.fold_binders( |
1053 | &mut |ty, binders| match ty { | 986 | &mut |ty, binders| match ty { |
1054 | Ty::Bound(bound) if bound.debruijn >= binders => { | 987 | Ty::BoundVar(bound) if bound.debruijn >= binders => { |
1055 | Ty::Bound(bound.shifted_in_from(n)) | 988 | Ty::BoundVar(bound.shifted_in_from(n)) |
1056 | } | 989 | } |
1057 | ty => ty, | 990 | ty => ty, |
1058 | }, | 991 | }, |
@@ -1064,13 +997,13 @@ pub trait TypeWalk { | |||
1064 | impl TypeWalk for Ty { | 997 | impl TypeWalk for Ty { |
1065 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 998 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1066 | match self { | 999 | match self { |
1067 | Ty::Apply(a_ty) => { | 1000 | Ty::Alias(AliasTy::Projection(p_ty)) => { |
1068 | for t in a_ty.parameters.iter() { | 1001 | for t in p_ty.parameters.iter() { |
1069 | t.walk(f); | 1002 | t.walk(f); |
1070 | } | 1003 | } |
1071 | } | 1004 | } |
1072 | Ty::Projection(p_ty) => { | 1005 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1073 | for t in p_ty.parameters.iter() { | 1006 | for t in o_ty.parameters.iter() { |
1074 | t.walk(f); | 1007 | t.walk(f); |
1075 | } | 1008 | } |
1076 | } | 1009 | } |
@@ -1079,12 +1012,13 @@ impl TypeWalk for Ty { | |||
1079 | p.walk(f); | 1012 | p.walk(f); |
1080 | } | 1013 | } |
1081 | } | 1014 | } |
1082 | Ty::Opaque(o_ty) => { | 1015 | _ => { |
1083 | for t in o_ty.parameters.iter() { | 1016 | if let Some(substs) = self.substs() { |
1084 | t.walk(f); | 1017 | for t in substs.iter() { |
1018 | t.walk(f); | ||
1019 | } | ||
1085 | } | 1020 | } |
1086 | } | 1021 | } |
1087 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
1088 | } | 1022 | } |
1089 | f(self); | 1023 | f(self); |
1090 | } | 1024 | } |
@@ -1095,10 +1029,7 @@ impl TypeWalk for Ty { | |||
1095 | binders: DebruijnIndex, | 1029 | binders: DebruijnIndex, |
1096 | ) { | 1030 | ) { |
1097 | match self { | 1031 | match self { |
1098 | Ty::Apply(a_ty) => { | 1032 | Ty::Alias(AliasTy::Projection(p_ty)) => { |
1099 | a_ty.parameters.walk_mut_binders(f, binders); | ||
1100 | } | ||
1101 | Ty::Projection(p_ty) => { | ||
1102 | p_ty.parameters.walk_mut_binders(f, binders); | 1033 | p_ty.parameters.walk_mut_binders(f, binders); |
1103 | } | 1034 | } |
1104 | Ty::Dyn(predicates) => { | 1035 | Ty::Dyn(predicates) => { |
@@ -1106,10 +1037,14 @@ impl TypeWalk for Ty { | |||
1106 | p.walk_mut_binders(f, binders.shifted_in()); | 1037 | p.walk_mut_binders(f, binders.shifted_in()); |
1107 | } | 1038 | } |
1108 | } | 1039 | } |
1109 | Ty::Opaque(o_ty) => { | 1040 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1110 | o_ty.parameters.walk_mut_binders(f, binders); | 1041 | o_ty.parameters.walk_mut_binders(f, binders); |
1111 | } | 1042 | } |
1112 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1043 | _ => { |
1044 | if let Some(substs) = self.substs_mut() { | ||
1045 | substs.walk_mut_binders(f, binders); | ||
1046 | } | ||
1047 | } | ||
1113 | } | 1048 | } |
1114 | f(self, binders); | 1049 | f(self, binders); |
1115 | } | 1050 | } |