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