diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 492 |
1 files changed, 215 insertions, 277 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 676519594..5cbb9a3cc 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -25,7 +25,7 @@ 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, |
31 | expr::ExprId, | 31 | expr::ExprId, |
@@ -57,192 +57,6 @@ pub enum Lifetime { | |||
57 | Static, | 57 | Static, |
58 | } | 58 | } |
59 | 59 | ||
60 | /// A type constructor or type name: this might be something like the primitive | ||
61 | /// type `bool`, a struct like `Vec`, or things like function pointers or | ||
62 | /// tuples. | ||
63 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | ||
64 | pub enum TypeCtor { | ||
65 | /// a scalar type like `bool` or `u32` | ||
66 | Scalar(Scalar), | ||
67 | |||
68 | /// Structures, enumerations and unions. | ||
69 | Adt(AdtId), | ||
70 | |||
71 | /// The pointee of a string slice. Written as `str`. | ||
72 | Str, | ||
73 | |||
74 | /// The pointee of an array slice. Written as `[T]`. | ||
75 | Slice, | ||
76 | |||
77 | /// An array with the given length. Written as `[T; n]`. | ||
78 | Array, | ||
79 | |||
80 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
81 | RawPtr(Mutability), | ||
82 | |||
83 | /// A reference; a pointer with an associated lifetime. Written as | ||
84 | /// `&'a mut T` or `&'a T`. | ||
85 | Ref(Mutability), | ||
86 | |||
87 | /// The anonymous type of a function declaration/definition. Each | ||
88 | /// function has a unique type, which is output (for a function | ||
89 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
90 | /// | ||
91 | /// This includes tuple struct / enum variant constructors as well. | ||
92 | /// | ||
93 | /// For example the type of `bar` here: | ||
94 | /// | ||
95 | /// ``` | ||
96 | /// fn foo() -> i32 { 1 } | ||
97 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
98 | /// ``` | ||
99 | FnDef(CallableDefId), | ||
100 | |||
101 | /// A pointer to a function. Written as `fn() -> i32`. | ||
102 | /// | ||
103 | /// For example the type of `bar` here: | ||
104 | /// | ||
105 | /// ``` | ||
106 | /// fn foo() -> i32 { 1 } | ||
107 | /// let bar: fn() -> i32 = foo; | ||
108 | /// ``` | ||
109 | // FIXME make this a Ty variant like in Chalk | ||
110 | FnPtr { num_args: u16, is_varargs: bool }, | ||
111 | |||
112 | /// The never type `!`. | ||
113 | Never, | ||
114 | |||
115 | /// A tuple type. For example, `(i32, bool)`. | ||
116 | Tuple { cardinality: u16 }, | ||
117 | |||
118 | /// Represents an associated item like `Iterator::Item`. This is used | ||
119 | /// when we have tried to normalize a projection like `T::Item` but | ||
120 | /// couldn't find a better representation. In that case, we generate | ||
121 | /// an **application type** like `(Iterator::Item)<T>`. | ||
122 | AssociatedType(TypeAliasId), | ||
123 | |||
124 | /// This represents a placeholder for an opaque type in situations where we | ||
125 | /// don't know the hidden type (i.e. currently almost always). This is | ||
126 | /// analogous to the `AssociatedType` type constructor. | ||
127 | /// It is also used as the type of async block, with one type parameter | ||
128 | /// representing the Future::Output type. | ||
129 | OpaqueType(OpaqueTyId), | ||
130 | |||
131 | /// Represents a foreign type declared in external blocks. | ||
132 | ForeignType(TypeAliasId), | ||
133 | |||
134 | /// The type of a specific closure. | ||
135 | /// | ||
136 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
137 | /// parameter. | ||
138 | Closure { def: DefWithBodyId, expr: ExprId }, | ||
139 | } | ||
140 | |||
141 | impl TypeCtor { | ||
142 | pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { | ||
143 | match self { | ||
144 | TypeCtor::Scalar(_) | ||
145 | | TypeCtor::Str | ||
146 | | TypeCtor::Never => 0, | ||
147 | TypeCtor::Slice | ||
148 | | TypeCtor::Array | ||
149 | | TypeCtor::RawPtr(_) | ||
150 | | TypeCtor::Ref(_) | ||
151 | | TypeCtor::Closure { .. } // 1 param representing the signature of the closure | ||
152 | => 1, | ||
153 | TypeCtor::Adt(adt) => { | ||
154 | let generic_params = generics(db.upcast(), adt.into()); | ||
155 | generic_params.len() | ||
156 | } | ||
157 | TypeCtor::FnDef(callable) => { | ||
158 | let generic_params = generics(db.upcast(), callable.into()); | ||
159 | generic_params.len() | ||
160 | } | ||
161 | TypeCtor::AssociatedType(type_alias) => { | ||
162 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
163 | generic_params.len() | ||
164 | } | ||
165 | TypeCtor::ForeignType(type_alias) => { | ||
166 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
167 | generic_params.len() | ||
168 | } | ||
169 | TypeCtor::OpaqueType(opaque_ty_id) => { | ||
170 | match opaque_ty_id { | ||
171 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
172 | let generic_params = generics(db.upcast(), func.into()); | ||
173 | generic_params.len() | ||
174 | } | ||
175 | // 1 param representing Future::Output type. | ||
176 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
177 | } | ||
178 | } | ||
179 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | ||
180 | TypeCtor::Tuple { cardinality } => cardinality as usize, | ||
181 | } | ||
182 | } | ||
183 | |||
184 | pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { | ||
185 | match self { | ||
186 | TypeCtor::Scalar(_) | ||
187 | | TypeCtor::Str | ||
188 | | TypeCtor::Never | ||
189 | | TypeCtor::Slice | ||
190 | | TypeCtor::Array | ||
191 | | TypeCtor::RawPtr(_) | ||
192 | | TypeCtor::Ref(_) | ||
193 | | TypeCtor::FnPtr { .. } | ||
194 | | TypeCtor::Tuple { .. } => None, | ||
195 | // Closure's krate is irrelevant for coherence I would think? | ||
196 | TypeCtor::Closure { .. } => None, | ||
197 | TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()), | ||
198 | TypeCtor::FnDef(callable) => Some(callable.krate(db)), | ||
199 | TypeCtor::AssociatedType(type_alias) => { | ||
200 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
201 | } | ||
202 | TypeCtor::ForeignType(type_alias) => { | ||
203 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate()) | ||
204 | } | ||
205 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { | ||
206 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | ||
207 | Some(func.lookup(db.upcast()).module(db.upcast()).krate()) | ||
208 | } | ||
209 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => { | ||
210 | Some(def.module(db.upcast()).krate()) | ||
211 | } | ||
212 | }, | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pub fn as_generic_def(self) -> Option<GenericDefId> { | ||
217 | match self { | ||
218 | TypeCtor::Scalar(_) | ||
219 | | TypeCtor::Str | ||
220 | | TypeCtor::Never | ||
221 | | TypeCtor::Slice | ||
222 | | TypeCtor::Array | ||
223 | | TypeCtor::RawPtr(_) | ||
224 | | TypeCtor::Ref(_) | ||
225 | | TypeCtor::FnPtr { .. } | ||
226 | | TypeCtor::Tuple { .. } | ||
227 | | TypeCtor::Closure { .. } => None, | ||
228 | TypeCtor::Adt(adt) => Some(adt.into()), | ||
229 | TypeCtor::FnDef(callable) => Some(callable.into()), | ||
230 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | ||
231 | TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), | ||
232 | TypeCtor::OpaqueType(_impl_trait_id) => None, | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | ||
238 | /// type like `bool`, a struct, tuple, function pointer, reference or | ||
239 | /// several other things. | ||
240 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
241 | pub struct ApplicationTy { | ||
242 | pub ctor: TypeCtor, | ||
243 | pub parameters: Substs, | ||
244 | } | ||
245 | |||
246 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
247 | pub struct OpaqueTy { | 61 | pub struct OpaqueTy { |
248 | pub opaque_ty_id: OpaqueTyId, | 62 | pub opaque_ty_id: OpaqueTyId, |
@@ -293,10 +107,80 @@ impl TypeWalk for ProjectionTy { | |||
293 | /// This should be cheap to clone. | 107 | /// This should be cheap to clone. |
294 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 108 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
295 | pub enum Ty { | 109 | pub enum Ty { |
296 | /// A nominal type with (maybe 0) type parameters. This might be a primitive | 110 | /// Structures, enumerations and unions. |
297 | /// type like `bool`, a struct, tuple, function pointer, reference or | 111 | Adt(AdtId, Substs), |
298 | /// several other things. | 112 | |
299 | Apply(ApplicationTy), | 113 | /// Represents an associated item like `Iterator::Item`. This is used |
114 | /// when we have tried to normalize a projection like `T::Item` but | ||
115 | /// couldn't find a better representation. In that case, we generate | ||
116 | /// an **application type** like `(Iterator::Item)<T>`. | ||
117 | AssociatedType(TypeAliasId, Substs), | ||
118 | |||
119 | /// a scalar type like `bool` or `u32` | ||
120 | Scalar(Scalar), | ||
121 | |||
122 | /// A tuple type. For example, `(i32, bool)`. | ||
123 | Tuple { cardinality: u16, substs: Substs }, | ||
124 | |||
125 | /// An array with the given length. Written as `[T; n]`. | ||
126 | Array(Substs), | ||
127 | |||
128 | /// The pointee of an array slice. Written as `[T]`. | ||
129 | Slice(Substs), | ||
130 | |||
131 | /// A raw pointer. Written as `*mut T` or `*const T` | ||
132 | RawPtr(Mutability, Substs), | ||
133 | |||
134 | /// A reference; a pointer with an associated lifetime. Written as | ||
135 | /// `&'a mut T` or `&'a T`. | ||
136 | Ref(Mutability, Substs), | ||
137 | |||
138 | /// This represents a placeholder for an opaque type in situations where we | ||
139 | /// don't know the hidden type (i.e. currently almost always). This is | ||
140 | /// analogous to the `AssociatedType` type constructor. | ||
141 | /// It is also used as the type of async block, with one type parameter | ||
142 | /// representing the Future::Output type. | ||
143 | OpaqueType(OpaqueTyId, Substs), | ||
144 | |||
145 | /// The anonymous type of a function declaration/definition. Each | ||
146 | /// function has a unique type, which is output (for a function | ||
147 | /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. | ||
148 | /// | ||
149 | /// This includes tuple struct / enum variant constructors as well. | ||
150 | /// | ||
151 | /// For example the type of `bar` here: | ||
152 | /// | ||
153 | /// ``` | ||
154 | /// fn foo() -> i32 { 1 } | ||
155 | /// let bar = foo; // bar: fn() -> i32 {foo} | ||
156 | /// ``` | ||
157 | FnDef(CallableDefId, Substs), | ||
158 | |||
159 | /// The pointee of a string slice. Written as `str`. | ||
160 | Str, | ||
161 | |||
162 | /// The never type `!`. | ||
163 | Never, | ||
164 | |||
165 | /// The type of a specific closure. | ||
166 | /// | ||
167 | /// The closure signature is stored in a `FnPtr` type in the first type | ||
168 | /// parameter. | ||
169 | Closure { def: DefWithBodyId, expr: ExprId, substs: Substs }, | ||
170 | |||
171 | /// Represents a foreign type declared in external blocks. | ||
172 | ForeignType(TypeAliasId, Substs), | ||
173 | |||
174 | /// A pointer to a function. Written as `fn() -> i32`. | ||
175 | /// | ||
176 | /// For example the type of `bar` here: | ||
177 | /// | ||
178 | /// ``` | ||
179 | /// fn foo() -> i32 { 1 } | ||
180 | /// let bar: fn() -> i32 = foo; | ||
181 | /// ``` | ||
182 | // FIXME make this a Ty variant like in Chalk | ||
183 | FnPtr { num_args: u16, is_varargs: bool, substs: Substs }, | ||
300 | 184 | ||
301 | /// A "projection" type corresponds to an (unnormalized) | 185 | /// A "projection" type corresponds to an (unnormalized) |
302 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 186 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
@@ -420,10 +304,6 @@ impl Substs { | |||
420 | Substs::builder(generic_params.len()) | 304 | Substs::builder(generic_params.len()) |
421 | } | 305 | } |
422 | 306 | ||
423 | pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { | ||
424 | Substs::builder(type_ctor.num_ty_params(db)) | ||
425 | } | ||
426 | |||
427 | fn builder(param_count: usize) -> SubstsBuilder { | 307 | fn builder(param_count: usize) -> SubstsBuilder { |
428 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | 308 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } |
429 | } | 309 | } |
@@ -701,54 +581,42 @@ impl TypeWalk for FnSig { | |||
701 | } | 581 | } |
702 | 582 | ||
703 | impl Ty { | 583 | impl Ty { |
704 | pub fn simple(ctor: TypeCtor) -> Ty { | ||
705 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() }) | ||
706 | } | ||
707 | pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty { | ||
708 | Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) }) | ||
709 | } | ||
710 | pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty { | ||
711 | Ty::Apply(ApplicationTy { ctor, parameters }) | ||
712 | } | ||
713 | pub fn unit() -> Self { | 584 | pub fn unit() -> Self { |
714 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 585 | Ty::Tuple { cardinality: 0, substs: Substs::empty() } |
715 | } | 586 | } |
587 | |||
716 | pub fn fn_ptr(sig: FnSig) -> Self { | 588 | pub fn fn_ptr(sig: FnSig) -> Self { |
717 | Ty::apply( | 589 | Ty::FnPtr { |
718 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, | 590 | num_args: sig.params().len() as u16, |
719 | Substs(sig.params_and_return), | 591 | is_varargs: sig.is_varargs, |
720 | ) | 592 | substs: Substs(sig.params_and_return), |
593 | } | ||
721 | } | 594 | } |
595 | |||
722 | pub fn builtin(builtin: BuiltinType) -> Self { | 596 | pub fn builtin(builtin: BuiltinType) -> Self { |
723 | Ty::simple(match builtin { | 597 | match builtin { |
724 | BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), | 598 | BuiltinType::Char => Ty::Scalar(Scalar::Char), |
725 | BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), | 599 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), |
726 | BuiltinType::Str => TypeCtor::Str, | 600 | BuiltinType::Str => Ty::Str, |
727 | BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | 601 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), |
728 | BuiltinType::Uint(t) => { | 602 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), |
729 | TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))) | 603 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), |
730 | } | 604 | } |
731 | BuiltinType::Float(t) => { | ||
732 | TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))) | ||
733 | } | ||
734 | }) | ||
735 | } | 605 | } |
736 | 606 | ||
737 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 607 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
738 | match self { | 608 | match self { |
739 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 609 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), |
740 | Some((parameters.as_single(), *mutability)) | ||
741 | } | ||
742 | _ => None, | 610 | _ => None, |
743 | } | 611 | } |
744 | } | 612 | } |
745 | 613 | ||
746 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 614 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
747 | match self { | 615 | match self { |
748 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 616 | Ty::Ref(mutability, parameters) => { |
749 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 617 | Some((parameters.as_single(), Rawness::Ref, *mutability)) |
750 | } | 618 | } |
751 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | 619 | Ty::RawPtr(mutability, parameters) => { |
752 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | 620 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) |
753 | } | 621 | } |
754 | _ => None, | 622 | _ => None, |
@@ -758,7 +626,7 @@ impl Ty { | |||
758 | pub fn strip_references(&self) -> &Ty { | 626 | pub fn strip_references(&self) -> &Ty { |
759 | let mut t: &Ty = self; | 627 | let mut t: &Ty = self; |
760 | 628 | ||
761 | while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { | 629 | while let Ty::Ref(_mutability, parameters) = t { |
762 | t = parameters.as_single(); | 630 | t = parameters.as_single(); |
763 | } | 631 | } |
764 | 632 | ||
@@ -767,30 +635,64 @@ impl Ty { | |||
767 | 635 | ||
768 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { | 636 | pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { |
769 | match self { | 637 | match self { |
770 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 638 | Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)), |
771 | Some((*adt_def, parameters)) | ||
772 | } | ||
773 | _ => None, | 639 | _ => None, |
774 | } | 640 | } |
775 | } | 641 | } |
776 | 642 | ||
777 | pub fn as_tuple(&self) -> Option<&Substs> { | 643 | pub fn as_tuple(&self) -> Option<&Substs> { |
778 | match self { | 644 | match self { |
779 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { | 645 | Ty::Tuple { substs: parameters, .. } => Some(parameters), |
780 | Some(parameters) | 646 | _ => None, |
781 | } | 647 | } |
648 | } | ||
649 | |||
650 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | ||
651 | match *self { | ||
652 | Ty::Adt(adt, ..) => Some(adt.into()), | ||
653 | Ty::FnDef(callable, ..) => Some(callable.into()), | ||
654 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | ||
655 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | ||
782 | _ => None, | 656 | _ => None, |
783 | } | 657 | } |
784 | } | 658 | } |
785 | 659 | ||
786 | pub fn is_never(&self) -> bool { | 660 | pub fn is_never(&self) -> bool { |
787 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 661 | matches!(self, Ty::Never) |
788 | } | 662 | } |
789 | 663 | ||
790 | pub fn is_unknown(&self) -> bool { | 664 | pub fn is_unknown(&self) -> bool { |
791 | matches!(self, Ty::Unknown) | 665 | matches!(self, Ty::Unknown) |
792 | } | 666 | } |
793 | 667 | ||
668 | pub fn equals_ctor(&self, other: &Ty) -> bool { | ||
669 | match (self, other) { | ||
670 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | ||
671 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | ||
672 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | ||
673 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | ||
674 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | ||
675 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | ||
676 | (Ty::Closure { def, expr, .. }, Ty::Closure { def: def2, expr: expr2, .. }) => { | ||
677 | expr == expr2 && def == def2 | ||
678 | } | ||
679 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
680 | | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => { | ||
681 | mutability == mutability2 | ||
682 | } | ||
683 | ( | ||
684 | Ty::FnPtr { num_args, is_varargs, .. }, | ||
685 | Ty::FnPtr { num_args: num_args2, is_varargs: is_varargs2, .. }, | ||
686 | ) => num_args == num_args2 && is_varargs == is_varargs2, | ||
687 | (Ty::Tuple { cardinality, .. }, Ty::Tuple { cardinality: cardinality2, .. }) => { | ||
688 | cardinality == cardinality2 | ||
689 | } | ||
690 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | ||
691 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | ||
692 | _ => false, | ||
693 | } | ||
694 | } | ||
695 | |||
794 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 696 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
795 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 697 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
796 | match self { | 698 | match self { |
@@ -809,41 +711,32 @@ impl Ty { | |||
809 | 711 | ||
810 | fn builtin_deref(&self) -> Option<Ty> { | 712 | fn builtin_deref(&self) -> Option<Ty> { |
811 | match self { | 713 | match self { |
812 | Ty::Apply(a_ty) => match a_ty.ctor { | 714 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), |
813 | TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), | 715 | Ty::RawPtr(.., parameters) => Some(Ty::clone(parameters.as_single())), |
814 | TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())), | ||
815 | _ => None, | ||
816 | }, | ||
817 | _ => None, | 716 | _ => None, |
818 | } | 717 | } |
819 | } | 718 | } |
820 | 719 | ||
821 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 720 | pub fn as_fn_def(&self) -> Option<FunctionId> { |
822 | match self { | 721 | match self { |
823 | &Ty::Apply(ApplicationTy { | 722 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), |
824 | ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), | ||
825 | .. | ||
826 | }) => Some(func), | ||
827 | _ => None, | 723 | _ => None, |
828 | } | 724 | } |
829 | } | 725 | } |
830 | 726 | ||
831 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 727 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { |
832 | match self { | 728 | match self { |
833 | Ty::Apply(a_ty) => match a_ty.ctor { | 729 | &Ty::FnPtr { is_varargs, substs: ref parameters, .. } => { |
834 | TypeCtor::FnPtr { is_varargs, .. } => { | 730 | Some(FnSig::from_fn_ptr_substs(¶meters, is_varargs)) |
835 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | 731 | } |
836 | } | 732 | &Ty::FnDef(def, ref parameters) => { |
837 | TypeCtor::FnDef(def) => { | 733 | let sig = db.callable_item_signature(def); |
838 | let sig = db.callable_item_signature(def); | 734 | Some(sig.subst(¶meters)) |
839 | Some(sig.subst(&a_ty.parameters)) | 735 | } |
840 | } | 736 | Ty::Closure { substs: parameters, .. } => { |
841 | TypeCtor::Closure { .. } => { | 737 | let sig_param = ¶meters[0]; |
842 | let sig_param = &a_ty.parameters[0]; | 738 | sig_param.callable_sig(db) |
843 | sig_param.callable_sig(db) | 739 | } |
844 | } | ||
845 | _ => None, | ||
846 | }, | ||
847 | _ => None, | 740 | _ => None, |
848 | } | 741 | } |
849 | } | 742 | } |
@@ -852,28 +745,71 @@ impl Ty { | |||
852 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | 745 | /// the `Substs` for these type parameters with the given ones. (So e.g. if |
853 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 746 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
854 | /// `Option<u32>` afterwards.) | 747 | /// `Option<u32>` afterwards.) |
855 | pub fn apply_substs(self, substs: Substs) -> Ty { | 748 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
856 | match self { | 749 | match &mut self { |
857 | Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { | 750 | Ty::Adt(_, substs) |
858 | assert_eq!(previous_substs.len(), substs.len()); | 751 | | Ty::Slice(substs) |
859 | Ty::Apply(ApplicationTy { ctor, parameters: substs }) | 752 | | Ty::Array(substs) |
753 | | Ty::RawPtr(_, substs) | ||
754 | | Ty::Ref(_, substs) | ||
755 | | Ty::FnDef(_, substs) | ||
756 | | Ty::FnPtr { substs, .. } | ||
757 | | Ty::Tuple { substs, .. } | ||
758 | | Ty::OpaqueType(_, substs) | ||
759 | | Ty::AssociatedType(_, substs) | ||
760 | | Ty::ForeignType(_, substs) | ||
761 | | Ty::Closure { substs, .. } => { | ||
762 | assert_eq!(substs.len(), new_substs.len()); | ||
763 | *substs = new_substs; | ||
860 | } | 764 | } |
861 | _ => self, | 765 | _ => (), |
862 | } | 766 | } |
767 | self | ||
863 | } | 768 | } |
864 | 769 | ||
865 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 770 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
866 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 771 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
867 | pub fn substs(&self) -> Option<Substs> { | 772 | pub fn substs(&self) -> Option<&Substs> { |
773 | match self { | ||
774 | Ty::Adt(_, substs) | ||
775 | | Ty::Slice(substs) | ||
776 | | Ty::Array(substs) | ||
777 | | Ty::RawPtr(_, substs) | ||
778 | | Ty::Ref(_, substs) | ||
779 | | Ty::FnDef(_, substs) | ||
780 | | Ty::FnPtr { substs, .. } | ||
781 | | Ty::Tuple { substs, .. } | ||
782 | | Ty::OpaqueType(_, substs) | ||
783 | | Ty::AssociatedType(_, substs) | ||
784 | | Ty::ForeignType(_, substs) | ||
785 | | Ty::Closure { substs, .. } => Some(substs), | ||
786 | |||
787 | _ => None, | ||
788 | } | ||
789 | } | ||
790 | |||
791 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | ||
868 | match self { | 792 | match self { |
869 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | 793 | Ty::Adt(_, substs) |
794 | | Ty::Slice(substs) | ||
795 | | Ty::Array(substs) | ||
796 | | Ty::RawPtr(_, substs) | ||
797 | | Ty::Ref(_, substs) | ||
798 | | Ty::FnDef(_, substs) | ||
799 | | Ty::FnPtr { substs, .. } | ||
800 | | Ty::Tuple { substs, .. } | ||
801 | | Ty::OpaqueType(_, substs) | ||
802 | | Ty::AssociatedType(_, substs) | ||
803 | | Ty::ForeignType(_, substs) | ||
804 | | Ty::Closure { substs, .. } => Some(substs), | ||
805 | |||
870 | _ => None, | 806 | _ => None, |
871 | } | 807 | } |
872 | } | 808 | } |
873 | 809 | ||
874 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 810 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
875 | match self { | 811 | match self { |
876 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | 812 | Ty::OpaqueType(opaque_ty_id, ..) => { |
877 | match opaque_ty_id { | 813 | match opaque_ty_id { |
878 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 814 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { |
879 | let krate = def.module(db.upcast()).krate(); | 815 | let krate = def.module(db.upcast()).krate(); |
@@ -934,7 +870,7 @@ impl Ty { | |||
934 | 870 | ||
935 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 871 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
936 | match self { | 872 | match self { |
937 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | 873 | Ty::AssociatedType(type_alias_id, ..) => { |
938 | match type_alias_id.lookup(db.upcast()).container { | 874 | match type_alias_id.lookup(db.upcast()).container { |
939 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 875 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
940 | _ => None, | 876 | _ => None, |
@@ -1049,11 +985,6 @@ pub trait TypeWalk { | |||
1049 | impl TypeWalk for Ty { | 985 | impl TypeWalk for Ty { |
1050 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 986 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
1051 | match self { | 987 | match self { |
1052 | Ty::Apply(a_ty) => { | ||
1053 | for t in a_ty.parameters.iter() { | ||
1054 | t.walk(f); | ||
1055 | } | ||
1056 | } | ||
1057 | Ty::Projection(p_ty) => { | 988 | Ty::Projection(p_ty) => { |
1058 | for t in p_ty.parameters.iter() { | 989 | for t in p_ty.parameters.iter() { |
1059 | t.walk(f); | 990 | t.walk(f); |
@@ -1069,7 +1000,13 @@ impl TypeWalk for Ty { | |||
1069 | t.walk(f); | 1000 | t.walk(f); |
1070 | } | 1001 | } |
1071 | } | 1002 | } |
1072 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1003 | _ => { |
1004 | if let Some(substs) = self.substs() { | ||
1005 | for t in substs.iter() { | ||
1006 | t.walk(f); | ||
1007 | } | ||
1008 | } | ||
1009 | } | ||
1073 | } | 1010 | } |
1074 | f(self); | 1011 | f(self); |
1075 | } | 1012 | } |
@@ -1080,9 +1017,6 @@ impl TypeWalk for Ty { | |||
1080 | binders: DebruijnIndex, | 1017 | binders: DebruijnIndex, |
1081 | ) { | 1018 | ) { |
1082 | match self { | 1019 | match self { |
1083 | Ty::Apply(a_ty) => { | ||
1084 | a_ty.parameters.walk_mut_binders(f, binders); | ||
1085 | } | ||
1086 | Ty::Projection(p_ty) => { | 1020 | Ty::Projection(p_ty) => { |
1087 | p_ty.parameters.walk_mut_binders(f, binders); | 1021 | p_ty.parameters.walk_mut_binders(f, binders); |
1088 | } | 1022 | } |
@@ -1094,7 +1028,11 @@ impl TypeWalk for Ty { | |||
1094 | Ty::Opaque(o_ty) => { | 1028 | Ty::Opaque(o_ty) => { |
1095 | o_ty.parameters.walk_mut_binders(f, binders); | 1029 | o_ty.parameters.walk_mut_binders(f, binders); |
1096 | } | 1030 | } |
1097 | Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | 1031 | _ => { |
1032 | if let Some(substs) = self.substs_mut() { | ||
1033 | substs.walk_mut_binders(f, binders); | ||
1034 | } | ||
1035 | } | ||
1098 | } | 1036 | } |
1099 | f(self, binders); | 1037 | f(self, binders); |
1100 | } | 1038 | } |