aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-02-28 19:16:51 +0000
committerGitHub <[email protected]>2021-02-28 19:16:51 +0000
commit2fc137b70f9d455676cc99a1a5c7e6e10c3e7cc2 (patch)
treeb9bc6434404e99a0829d01b08285d37f6faa3d2d /crates/hir_ty/src/lib.rs
parent0a913fd11194faff9c0100bc78f2d4fe682075aa (diff)
parentfaf2dd49e4845e1437b704a28bb5603be5fd605b (diff)
Merge #7813
7813: Inline TypeCtor into Ty r=flodiebold a=Veykril This removes the `ApplicationTy` variant from `Ty` bringing the representation a lot closer to chalk's `TyKind`. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs490
1 files changed, 213 insertions, 277 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 676519594..117d69f01 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -25,7 +25,7 @@ mod test_db;
25 25
26use std::{iter, mem, ops::Deref, sync::Arc}; 26use std::{iter, mem, ops::Deref, sync::Arc};
27 27
28use base_db::{salsa, CrateId}; 28use base_db::salsa;
29use hir_def::{ 29use 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)]
64pub 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
141impl 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)]
241pub 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)]
247pub struct OpaqueTy { 61pub 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)]
295pub enum Ty { 109pub 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
703impl Ty { 583impl 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: parameters, .. } => {
834 TypeCtor::FnPtr { is_varargs, .. } => { 730 Some(FnSig::from_fn_ptr_substs(&parameters, *is_varargs))
835 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 731 }
836 } 732 Ty::FnDef(def, 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(&parameters))
839 Some(sig.subst(&a_ty.parameters)) 735 }
840 } 736 Ty::Closure { substs: parameters, .. } => {
841 TypeCtor::Closure { .. } => { 737 let sig_param = &parameters[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,69 @@ 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 _ => None,
787 }
788 }
789
790 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
868 match self { 791 match self {
869 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 792 Ty::Adt(_, substs)
793 | Ty::Slice(substs)
794 | Ty::Array(substs)
795 | Ty::RawPtr(_, substs)
796 | Ty::Ref(_, substs)
797 | Ty::FnDef(_, substs)
798 | Ty::FnPtr { substs, .. }
799 | Ty::Tuple { substs, .. }
800 | Ty::OpaqueType(_, substs)
801 | Ty::AssociatedType(_, substs)
802 | Ty::ForeignType(_, substs)
803 | Ty::Closure { substs, .. } => Some(substs),
870 _ => None, 804 _ => None,
871 } 805 }
872 } 806 }
873 807
874 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 808 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
875 match self { 809 match self {
876 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 810 Ty::OpaqueType(opaque_ty_id, ..) => {
877 match opaque_ty_id { 811 match opaque_ty_id {
878 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 812 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
879 let krate = def.module(db.upcast()).krate(); 813 let krate = def.module(db.upcast()).krate();
@@ -934,7 +868,7 @@ impl Ty {
934 868
935 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 869 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
936 match self { 870 match self {
937 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 871 Ty::AssociatedType(type_alias_id, ..) => {
938 match type_alias_id.lookup(db.upcast()).container { 872 match type_alias_id.lookup(db.upcast()).container {
939 AssocContainerId::TraitId(trait_id) => Some(trait_id), 873 AssocContainerId::TraitId(trait_id) => Some(trait_id),
940 _ => None, 874 _ => None,
@@ -1049,11 +983,6 @@ pub trait TypeWalk {
1049impl TypeWalk for Ty { 983impl TypeWalk for Ty {
1050 fn walk(&self, f: &mut impl FnMut(&Ty)) { 984 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1051 match self { 985 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) => { 986 Ty::Projection(p_ty) => {
1058 for t in p_ty.parameters.iter() { 987 for t in p_ty.parameters.iter() {
1059 t.walk(f); 988 t.walk(f);
@@ -1069,7 +998,13 @@ impl TypeWalk for Ty {
1069 t.walk(f); 998 t.walk(f);
1070 } 999 }
1071 } 1000 }
1072 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1001 _ => {
1002 if let Some(substs) = self.substs() {
1003 for t in substs.iter() {
1004 t.walk(f);
1005 }
1006 }
1007 }
1073 } 1008 }
1074 f(self); 1009 f(self);
1075 } 1010 }
@@ -1080,9 +1015,6 @@ impl TypeWalk for Ty {
1080 binders: DebruijnIndex, 1015 binders: DebruijnIndex,
1081 ) { 1016 ) {
1082 match self { 1017 match self {
1083 Ty::Apply(a_ty) => {
1084 a_ty.parameters.walk_mut_binders(f, binders);
1085 }
1086 Ty::Projection(p_ty) => { 1018 Ty::Projection(p_ty) => {
1087 p_ty.parameters.walk_mut_binders(f, binders); 1019 p_ty.parameters.walk_mut_binders(f, binders);
1088 } 1020 }
@@ -1094,7 +1026,11 @@ impl TypeWalk for Ty {
1094 Ty::Opaque(o_ty) => { 1026 Ty::Opaque(o_ty) => {
1095 o_ty.parameters.walk_mut_binders(f, binders); 1027 o_ty.parameters.walk_mut_binders(f, binders);
1096 } 1028 }
1097 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1029 _ => {
1030 if let Some(substs) = self.substs_mut() {
1031 substs.walk_mut_binders(f, binders);
1032 }
1033 }
1098 } 1034 }
1099 f(self, binders); 1035 f(self, binders);
1100 } 1036 }