diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 607 |
1 files changed, 268 insertions, 339 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 50d248674..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 | builtin_type::BuiltinType, | 30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AdtId, AssocContainerId, |
31 | expr::ExprId, | 31 | DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, |
32 | type_ref::{Mutability, Rawness}, | 32 | TypeAliasId, 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::{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,211 +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, _) => { | ||
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)] | 58 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
267 | pub struct OpaqueTy { | 59 | pub struct OpaqueTy { |
268 | pub opaque_ty_id: OpaqueTyId, | 60 | pub opaque_ty_id: OpaqueTyId, |
@@ -305,29 +97,118 @@ impl TypeWalk for ProjectionTy { | |||
305 | } | 97 | } |
306 | } | 98 | } |
307 | 99 | ||
308 | /// A type. | 100 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
309 | /// | 101 | pub struct FnSig { |
310 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 102 | pub variadic: bool, |
311 | /// the same thing (but in a different way). | 103 | } |
312 | /// | 104 | |
313 | /// This should be cheap to clone. | ||
314 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 105 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
315 | pub enum Ty { | 106 | pub struct FnPointer { |
316 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 107 | pub num_args: usize, |
317 | /// type like `bool`, a struct, tuple, function pointer, reference or | 108 | pub sig: FnSig, |
318 | /// several other things. | 109 | pub substs: Substs, |
319 | Apply(ApplicationTy), | 110 | } |
320 | 111 | ||
112 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
113 | pub enum AliasTy { | ||
321 | /// A "projection" type corresponds to an (unnormalized) | 114 | /// A "projection" type corresponds to an (unnormalized) |
322 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 115 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
323 | /// trait and all its parameters are fully known. | 116 | /// trait and all its parameters are fully known. |
324 | Projection(ProjectionTy), | 117 | Projection(ProjectionTy), |
325 | |||
326 | /// An opaque type (`impl Trait`). | 118 | /// An opaque type (`impl Trait`). |
327 | /// | 119 | /// |
328 | /// 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 |
329 | /// `impl Trait` in a return type gets its own ID. | 121 | /// `impl Trait` in a return type gets its own ID. |
330 | 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), | ||
331 | 212 | ||
332 | /// 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) |
333 | /// {}` 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 |
@@ -340,10 +221,10 @@ pub enum Ty { | |||
340 | /// parameters get turned into variables; during trait resolution, inference | 221 | /// parameters get turned into variables; during trait resolution, inference |
341 | /// 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 |
342 | /// `Self` type is represented with a bound variable as well. | 223 | /// `Self` type is represented with a bound variable as well. |
343 | Bound(BoundVar), | 224 | BoundVar(BoundVar), |
344 | 225 | ||
345 | /// A type variable used during type checking. | 226 | /// A type variable used during type checking. |
346 | Infer(InferTy), | 227 | InferenceVar(InferenceVar, TyVariableKind), |
347 | 228 | ||
348 | /// 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). |
349 | /// | 230 | /// |
@@ -424,7 +305,7 @@ impl Substs { | |||
424 | generic_params | 305 | generic_params |
425 | .iter() | 306 | .iter() |
426 | .enumerate() | 307 | .enumerate() |
427 | .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) | 308 | .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) |
428 | .collect(), | 309 | .collect(), |
429 | ) | 310 | ) |
430 | } | 311 | } |
@@ -440,10 +321,6 @@ impl Substs { | |||
440 | Substs::builder(generic_params.len()) | 321 | Substs::builder(generic_params.len()) |
441 | } | 322 | } |
442 | 323 | ||
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 { | 324 | fn builder(param_count: usize) -> SubstsBuilder { |
448 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 325 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
449 | } | 326 | } |
@@ -476,7 +353,7 @@ impl SubstsBuilder { | |||
476 | } | 353 | } |
477 | 354 | ||
478 | 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 { |
479 | 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)))) |
480 | } | 357 | } |
481 | 358 | ||
482 | pub fn fill_with_unknown(self) -> Self { | 359 | pub fn fill_with_unknown(self) -> Self { |
@@ -656,41 +533,41 @@ impl TypeWalk for GenericPredicate { | |||
656 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 533 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
657 | pub struct Canonical<T> { | 534 | pub struct Canonical<T> { |
658 | pub value: T, | 535 | pub value: T, |
659 | pub kinds: Arc<[TyKind]>, | 536 | pub kinds: Arc<[TyVariableKind]>, |
660 | } | 537 | } |
661 | 538 | ||
662 | impl<T> Canonical<T> { | 539 | impl<T> Canonical<T> { |
663 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { | 540 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { |
664 | Self { value, kinds: kinds.into_iter().collect() } | 541 | Self { value, kinds: kinds.into_iter().collect() } |
665 | } | 542 | } |
666 | } | 543 | } |
667 | 544 | ||
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 | 545 | /// A function signature as seen by type inference: Several parameter types and |
676 | /// one return type. | 546 | /// one return type. |
677 | #[derive(Clone, PartialEq, Eq, Debug)] | 547 | #[derive(Clone, PartialEq, Eq, Debug)] |
678 | pub struct FnSig { | 548 | pub struct CallableSig { |
679 | params_and_return: Arc<[Ty]>, | 549 | params_and_return: Arc<[Ty]>, |
680 | is_varargs: bool, | 550 | is_varargs: bool, |
681 | } | 551 | } |
682 | 552 | ||
683 | /// A polymorphic function signature. | 553 | /// A polymorphic function signature. |
684 | pub type PolyFnSig = Binders<FnSig>; | 554 | pub type PolyFnSig = Binders<CallableSig>; |
685 | 555 | ||
686 | impl FnSig { | 556 | impl CallableSig { |
687 | 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 { |
688 | params.push(ret); | 558 | params.push(ret); |
689 | FnSig { params_and_return: params.into(), is_varargs } | 559 | CallableSig { params_and_return: params.into(), is_varargs } |
690 | } | 560 | } |
691 | 561 | ||
692 | pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { | 562 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
693 | 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 } | ||
694 | } | 571 | } |
695 | 572 | ||
696 | pub fn params(&self) -> &[Ty] { | 573 | pub fn params(&self) -> &[Ty] { |
@@ -702,7 +579,7 @@ impl FnSig { | |||
702 | } | 579 | } |
703 | } | 580 | } |
704 | 581 | ||
705 | impl TypeWalk for FnSig { | 582 | impl TypeWalk for CallableSig { |
706 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 583 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
707 | for t in self.params_and_return.iter() { | 584 | for t in self.params_and_return.iter() { |
708 | t.walk(f); | 585 | t.walk(f); |
@@ -721,49 +598,42 @@ impl TypeWalk for FnSig { | |||
721 | } | 598 | } |
722 | 599 | ||
723 | impl Ty { | 600 | 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 { | 601 | pub fn unit() -> Self { |
734 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 602 | Ty::Tuple(0, Substs::empty()) |
735 | } | 603 | } |
736 | pub fn fn_ptr(sig: FnSig) -> Self { | 604 | |
737 | Ty::apply( | 605 | pub fn fn_ptr(sig: CallableSig) -> Self { |
738 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 606 | Ty::Function(FnPointer { |
739 | Substs(sig.params_and_return), | 607 | num_args: sig.params().len(), |
740 | ) | 608 | sig: FnSig { variadic: sig.is_varargs }, |
609 | substs: Substs(sig.params_and_return), | ||
610 | }) | ||
741 | } | 611 | } |
612 | |||
742 | pub fn builtin(builtin: BuiltinType) -> Self { | 613 | pub fn builtin(builtin: BuiltinType) -> Self { |
743 | Ty::simple(match builtin { | 614 | match builtin { |
744 | BuiltinType::Char => TypeCtor::Char, | 615 | BuiltinType::Char => Ty::Scalar(Scalar::Char), |
745 | BuiltinType::Bool => TypeCtor::Bool, | 616 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), |
746 | BuiltinType::Str => TypeCtor::Str, | 617 | BuiltinType::Str => Ty::Str, |
747 | BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), | 618 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), |
748 | BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), | 619 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), |
749 | }) | 620 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), |
621 | } | ||
750 | } | 622 | } |
751 | 623 | ||
752 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 624 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
753 | match self { | 625 | match self { |
754 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 626 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
755 | Some((parameters.as_single(), *mutability)) | ||
756 | } | ||
757 | _ => None, | 627 | _ => None, |
758 | } | 628 | } |
759 | } | 629 | } |
760 | 630 | ||
761 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 631 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
762 | match self { | 632 | match self { |
763 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 633 | Ty::Ref(mutability, parameters) => { |
764 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 634 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
765 | } | 635 | } |
766 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 636 | Ty::Raw(mutability, parameters) => { |
767 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 637 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
768 | } | 638 | } |
769 | _ => None, | 639 | _ => None, |
@@ -773,7 +643,7 @@ impl Ty { | |||
773 | pub fn strip_references(&self) -> &Ty { | 643 | pub fn strip_references(&self) -> &Ty { |
774 | let mut t: &Ty = self; | 644 | let mut t: &Ty = self; |
775 | 645 | ||
776 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 646 | while let Ty::Ref(_mutability, parameters) = t { |
777 | t = parameters.as_single(); | 647 | t = parameters.as_single(); |
778 | } | 648 | } |
779 | 649 | ||
@@ -782,30 +652,60 @@ impl Ty { | |||
782 | 652 | ||
783 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 653 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { |
784 | match self { | 654 | match self { |
785 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 655 | Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)), |
786 | Some((*adt_def, parameters)) | ||
787 | } | ||
788 | _ => None, | 656 | _ => None, |
789 | } | 657 | } |
790 | } | 658 | } |
791 | 659 | ||
792 | pub fn as_tuple(&self) -> Option<&Substs> { | 660 | pub fn as_tuple(&self) -> Option<&Substs> { |
793 | match self { | 661 | match self { |
794 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 662 | Ty::Tuple(_, substs) => Some(substs), |
795 | Some(parameters) | 663 | _ => None, |
796 | } | 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()), | ||
797 | _ => None, | 673 | _ => None, |
798 | } | 674 | } |
799 | } | 675 | } |
800 | 676 | ||
801 | pub fn is_never(&self) -> bool { | 677 | pub fn is_never(&self) -> bool { |
802 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 678 | matches!(self, Ty::Never) |
803 | } | 679 | } |
804 | 680 | ||
805 | pub fn is_unknown(&self) -> bool { | 681 | pub fn is_unknown(&self) -> bool { |
806 | matches!(self, Ty::Unknown) | 682 | matches!(self, Ty::Unknown) |
807 | } | 683 | } |
808 | 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 | |||
809 | /// 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. |
810 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 710 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
811 | match self { | 711 | match self { |
@@ -824,41 +724,30 @@ impl Ty { | |||
824 | 724 | ||
825 | fn builtin_deref(&self) -> Option<Ty> { | 725 | fn builtin_deref(&self) -> Option<Ty> { |
826 | match self { | 726 | match self { |
827 | Ty::Apply(a_ty) => match a_ty.ctor { | 727 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
828 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 728 | 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, | 729 | _ => None, |
833 | } | 730 | } |
834 | } | 731 | } |
835 | 732 | ||
836 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 733 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
837 | match self { | 734 | match self { |
838 | &Ty::Apply(ApplicationTy { | 735 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
839 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
840 | .. | ||
841 | }) => Some(func), | ||
842 | _ => None, | 736 | _ => None, |
843 | } | 737 | } |
844 | } | 738 | } |
845 | 739 | ||
846 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 740 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
847 | match self { | 741 | match self { |
848 | Ty::Apply(a_ty) => match a_ty.ctor { | 742 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
849 | TypeCtor::FnPtr { is_varargs, .. } => { | 743 | Ty::FnDef(def, parameters) => { |
850 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 744 | let sig = db.callable_item_signature(*def); |
851 | } | 745 | Some(sig.subst(¶meters)) |
852 | TypeCtor::FnDef(def) => { | 746 | } |
853 | let sig = db.callable_item_signature(def); | 747 | Ty::Closure(.., substs) => { |
854 | Some(sig.subst(&a_ty.parameters)) | 748 | let sig_param = &substs[0]; |
855 | } | 749 | sig_param.callable_sig(db) |
856 | TypeCtor::Closure { .. } => { | 750 | } |
857 | let sig_param = &a_ty.parameters[0]; | ||
858 | sig_param.callable_sig(db) | ||
859 | } | ||
860 | _ => None, | ||
861 | }, | ||
862 | _ => None, | 751 | _ => None, |
863 | } | 752 | } |
864 | } | 753 | } |
@@ -867,28 +756,66 @@ impl Ty { | |||
867 | /// 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 |
868 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 757 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
869 | /// `Option<u32>` afterwards.) | 758 | /// `Option<u32>` afterwards.) |
870 | pub fn apply_substs(self, substs: Substs) -> Ty { | 759 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
871 | match self { | 760 | match &mut self { |
872 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 761 | Ty::Adt(_, substs) |
873 | assert_eq!(previous_substs.len(), substs.len()); | 762 | | Ty::Slice(substs) |
874 | 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; | ||
875 | } | 774 | } |
876 | _ => self, | 775 | _ => (), |
877 | } | 776 | } |
777 | self | ||
878 | } | 778 | } |
879 | 779 | ||
880 | /// 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 |
881 | /// 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`. |
882 | pub fn substs(&self) -> Option<Substs> { | 782 | pub fn substs(&self) -> Option<&Substs> { |
883 | match self { | 783 | match self { |
884 | 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), | ||
885 | _ => None, | 812 | _ => None, |
886 | } | 813 | } |
887 | } | 814 | } |
888 | 815 | ||
889 | 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>> { |
890 | match self { | 817 | match self { |
891 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 818 | Ty::OpaqueType(opaque_ty_id, ..) => { |
892 | match opaque_ty_id { | 819 | match opaque_ty_id { |
893 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 820 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
894 | let krate = def.module(db.upcast()).krate(); | 821 | let krate = def.module(db.upcast()).krate(); |
@@ -911,7 +838,7 @@ impl Ty { | |||
911 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 838 | OpaqueTyId::ReturnTypeImplTrait(..) => None, |
912 | } | 839 | } |
913 | } | 840 | } |
914 | Ty::Opaque(opaque_ty) => { | 841 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { |
915 | let predicates = match opaque_ty.opaque_ty_id { | 842 | let predicates = match opaque_ty.opaque_ty_id { |
916 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 843 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
917 | db.return_type_impl_traits(func).map(|it| { | 844 | db.return_type_impl_traits(func).map(|it| { |
@@ -949,13 +876,13 @@ impl Ty { | |||
949 | 876 | ||
950 | 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> { |
951 | match self { | 878 | match self { |
952 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 879 | Ty::AssociatedType(type_alias_id, ..) => { |
953 | match type_alias_id.lookup(db.upcast()).container { | 880 | match type_alias_id.lookup(db.upcast()).container { |
954 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 881 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
955 | _ => None, | 882 | _ => None, |
956 | } | 883 | } |
957 | } | 884 | } |
958 | Ty::Projection(projection_ty) => { | 885 | Ty::Alias(AliasTy::Projection(projection_ty)) => { |
959 | match projection_ty.associated_ty.lookup(db.upcast()).container { | 886 | match projection_ty.associated_ty.lookup(db.upcast()).container { |
960 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 887 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
961 | _ => None, | 888 | _ => None, |
@@ -1033,7 +960,7 @@ pub trait TypeWalk { | |||
1033 | { | 960 | { |
1034 | self.walk_mut_binders( | 961 | self.walk_mut_binders( |
1035 | &mut |ty, binders| { | 962 | &mut |ty, binders| { |
1036 | if let &mut Ty::Bound(bound) = ty { | 963 | if let &mut Ty::BoundVar(bound) = ty { |
1037 | if bound.debruijn >= binders { | 964 | if bound.debruijn >= binders { |
1038 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 965 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
1039 | } | 966 | } |
@@ -1051,8 +978,8 @@ pub trait TypeWalk { | |||
1051 | { | 978 | { |
1052 | self.fold_binders( | 979 | self.fold_binders( |
1053 | &mut |ty, binders| match ty { | 980 | &mut |ty, binders| match ty { |
1054 | Ty::Bound(bound) if bound.debruijn >= binders => { | 981 | Ty::BoundVar(bound) if bound.debruijn >= binders => { |
1055 | Ty::Bound(bound.shifted_in_from(n)) | 982 | Ty::BoundVar(bound.shifted_in_from(n)) |
1056 | } | 983 | } |
1057 | ty => ty, | 984 | ty => ty, |
1058 | }, | 985 | }, |
@@ -1064,13 +991,13 @@ pub trait TypeWalk { | |||
1064 | impl TypeWalk for Ty { | 991 | impl TypeWalk for Ty { |
1065 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 992 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1066 | match self { | 993 | match self { |
1067 | Ty::Apply(a_ty) => { | 994 | Ty::Alias(AliasTy::Projection(p_ty)) => { |
1068 | for t in a_ty.parameters.iter() { | 995 | for t in p_ty.parameters.iter() { |
1069 | t.walk(f); | 996 | t.walk(f); |
1070 | } | 997 | } |
1071 | } | 998 | } |
1072 | Ty::Projection(p_ty) => { | 999 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1073 | for t in p_ty.parameters.iter() { | 1000 | for t in o_ty.parameters.iter() { |
1074 | t.walk(f); | 1001 | t.walk(f); |
1075 | } | 1002 | } |
1076 | } | 1003 | } |
@@ -1079,12 +1006,13 @@ impl TypeWalk for Ty { | |||
1079 | p.walk(f); | 1006 | p.walk(f); |
1080 | } | 1007 | } |
1081 | } | 1008 | } |
1082 | Ty::Opaque(o_ty) => { | 1009 | _ => { |
1083 | for t in o_ty.parameters.iter() { | 1010 | if let Some(substs) = self.substs() { |
1084 | t.walk(f); | 1011 | for t in substs.iter() { |
1012 | t.walk(f); | ||
1013 | } | ||
1085 | } | 1014 | } |
1086 | } | 1015 | } |
1087 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
1088 | } | 1016 | } |
1089 | f(self); | 1017 | f(self); |
1090 | } | 1018 | } |
@@ -1095,10 +1023,7 @@ impl TypeWalk for Ty { | |||
1095 | binders: DebruijnIndex, | 1023 | binders: DebruijnIndex, |
1096 | ) { | 1024 | ) { |
1097 | match self { | 1025 | match self { |
1098 | Ty::Apply(a_ty) => { | 1026 | 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); | 1027 | p_ty.parameters.walk_mut_binders(f, binders); |
1103 | } | 1028 | } |
1104 | Ty::Dyn(predicates) => { | 1029 | Ty::Dyn(predicates) => { |
@@ -1106,10 +1031,14 @@ impl TypeWalk for Ty { | |||
1106 | p.walk_mut_binders(f, binders.shifted_in()); | 1031 | p.walk_mut_binders(f, binders.shifted_in()); |
1107 | } | 1032 | } |
1108 | } | 1033 | } |
1109 | Ty::Opaque(o_ty) => { | 1034 | Ty::Alias(AliasTy::Opaque(o_ty)) => { |
1110 | o_ty.parameters.walk_mut_binders(f, binders); | 1035 | o_ty.parameters.walk_mut_binders(f, binders); |
1111 | } | 1036 | } |
1112 | 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 | } | ||
1113 | } | 1042 | } |
1114 | f(self, binders); | 1043 | f(self, binders); |
1115 | } | 1044 | } |