diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 91 |
1 files changed, 34 insertions, 57 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 484652073..503910dde 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -151,17 +151,17 @@ pub enum TyKind { | |||
151 | Tuple(usize, Substs), | 151 | Tuple(usize, Substs), |
152 | 152 | ||
153 | /// An array with the given length. Written as `[T; n]`. | 153 | /// An array with the given length. Written as `[T; n]`. |
154 | Array(Substs), | 154 | Array(Ty), |
155 | 155 | ||
156 | /// The pointee of an array slice. Written as `[T]`. | 156 | /// The pointee of an array slice. Written as `[T]`. |
157 | Slice(Substs), | 157 | Slice(Ty), |
158 | 158 | ||
159 | /// A raw pointer. Written as `*mut T` or `*const T` | 159 | /// A raw pointer. Written as `*mut T` or `*const T` |
160 | Raw(Mutability, Substs), | 160 | Raw(Mutability, Ty), |
161 | 161 | ||
162 | /// A reference; a pointer with an associated lifetime. Written as | 162 | /// A reference; a pointer with an associated lifetime. Written as |
163 | /// `&'a mut T` or `&'a T`. | 163 | /// `&'a mut T` or `&'a T`. |
164 | Ref(Mutability, Substs), | 164 | Ref(Mutability, Ty), |
165 | 165 | ||
166 | /// This represents a placeholder for an opaque type in situations where we | 166 | /// This represents a placeholder for an opaque type in situations where we |
167 | /// don't know the hidden type (i.e. currently almost always). This is | 167 | /// don't know the hidden type (i.e. currently almost always). This is |
@@ -248,11 +248,11 @@ pub enum TyKind { | |||
248 | } | 248 | } |
249 | 249 | ||
250 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 250 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
251 | pub struct Ty(TyKind); | 251 | pub struct Ty(Arc<TyKind>); |
252 | 252 | ||
253 | impl TyKind { | 253 | impl TyKind { |
254 | pub fn intern(self, _interner: &Interner) -> Ty { | 254 | pub fn intern(self, _interner: &Interner) -> Ty { |
255 | Ty(self) | 255 | Ty(Arc::new(self)) |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
@@ -260,6 +260,14 @@ impl Ty { | |||
260 | pub fn interned(&self, _interner: &Interner) -> &TyKind { | 260 | pub fn interned(&self, _interner: &Interner) -> &TyKind { |
261 | &self.0 | 261 | &self.0 |
262 | } | 262 | } |
263 | |||
264 | pub fn interned_mut(&mut self) -> &mut TyKind { | ||
265 | Arc::make_mut(&mut self.0) | ||
266 | } | ||
267 | |||
268 | pub fn into_inner(self) -> TyKind { | ||
269 | Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone()) | ||
270 | } | ||
263 | } | 271 | } |
264 | 272 | ||
265 | /// A list of substitutions for generic parameters. | 273 | /// A list of substitutions for generic parameters. |
@@ -665,19 +673,15 @@ impl Ty { | |||
665 | 673 | ||
666 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 674 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
667 | match self.interned(&Interner) { | 675 | match self.interned(&Interner) { |
668 | TyKind::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), | 676 | TyKind::Ref(mutability, ty) => Some((ty, *mutability)), |
669 | _ => None, | 677 | _ => None, |
670 | } | 678 | } |
671 | } | 679 | } |
672 | 680 | ||
673 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 681 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
674 | match self.interned(&Interner) { | 682 | match self.interned(&Interner) { |
675 | TyKind::Ref(mutability, parameters) => { | 683 | TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)), |
676 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 684 | TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), |
677 | } | ||
678 | TyKind::Raw(mutability, parameters) => { | ||
679 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | ||
680 | } | ||
681 | _ => None, | 685 | _ => None, |
682 | } | 686 | } |
683 | } | 687 | } |
@@ -685,8 +689,8 @@ impl Ty { | |||
685 | pub fn strip_references(&self) -> &Ty { | 689 | pub fn strip_references(&self) -> &Ty { |
686 | let mut t: &Ty = self; | 690 | let mut t: &Ty = self; |
687 | 691 | ||
688 | while let TyKind::Ref(_mutability, parameters) = t.interned(&Interner) { | 692 | while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) { |
689 | t = parameters.as_single(); | 693 | t = ty; |
690 | } | 694 | } |
691 | 695 | ||
692 | t | 696 | t |
@@ -772,8 +776,8 @@ impl Ty { | |||
772 | 776 | ||
773 | fn builtin_deref(&self) -> Option<Ty> { | 777 | fn builtin_deref(&self) -> Option<Ty> { |
774 | match self.interned(&Interner) { | 778 | match self.interned(&Interner) { |
775 | TyKind::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), | 779 | TyKind::Ref(.., ty) => Some(ty.clone()), |
776 | TyKind::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), | 780 | TyKind::Raw(.., ty) => Some(ty.clone()), |
777 | _ => None, | 781 | _ => None, |
778 | } | 782 | } |
779 | } | 783 | } |
@@ -809,40 +813,11 @@ impl Ty { | |||
809 | } | 813 | } |
810 | } | 814 | } |
811 | 815 | ||
812 | /// If this is a type with type parameters (an ADT or function), replaces | ||
813 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | ||
814 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | ||
815 | /// `Option<u32>` afterwards.) | ||
816 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { | ||
817 | match &mut self.0 { | ||
818 | TyKind::Adt(_, substs) | ||
819 | | TyKind::Slice(substs) | ||
820 | | TyKind::Array(substs) | ||
821 | | TyKind::Raw(_, substs) | ||
822 | | TyKind::Ref(_, substs) | ||
823 | | TyKind::FnDef(_, substs) | ||
824 | | TyKind::Function(FnPointer { substs, .. }) | ||
825 | | TyKind::Tuple(_, substs) | ||
826 | | TyKind::OpaqueType(_, substs) | ||
827 | | TyKind::AssociatedType(_, substs) | ||
828 | | TyKind::Closure(.., substs) => { | ||
829 | assert_eq!(substs.len(), new_substs.len()); | ||
830 | *substs = new_substs; | ||
831 | } | ||
832 | _ => (), | ||
833 | } | ||
834 | self | ||
835 | } | ||
836 | |||
837 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 816 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
838 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 817 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
839 | pub fn substs(&self) -> Option<&Substs> { | 818 | pub fn substs(&self) -> Option<&Substs> { |
840 | match self.interned(&Interner) { | 819 | match self.interned(&Interner) { |
841 | TyKind::Adt(_, substs) | 820 | TyKind::Adt(_, substs) |
842 | | TyKind::Slice(substs) | ||
843 | | TyKind::Array(substs) | ||
844 | | TyKind::Raw(_, substs) | ||
845 | | TyKind::Ref(_, substs) | ||
846 | | TyKind::FnDef(_, substs) | 821 | | TyKind::FnDef(_, substs) |
847 | | TyKind::Function(FnPointer { substs, .. }) | 822 | | TyKind::Function(FnPointer { substs, .. }) |
848 | | TyKind::Tuple(_, substs) | 823 | | TyKind::Tuple(_, substs) |
@@ -853,13 +828,9 @@ impl Ty { | |||
853 | } | 828 | } |
854 | } | 829 | } |
855 | 830 | ||
856 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | 831 | fn substs_mut(&mut self) -> Option<&mut Substs> { |
857 | match &mut self.0 { | 832 | match self.interned_mut() { |
858 | TyKind::Adt(_, substs) | 833 | TyKind::Adt(_, substs) |
859 | | TyKind::Slice(substs) | ||
860 | | TyKind::Array(substs) | ||
861 | | TyKind::Raw(_, substs) | ||
862 | | TyKind::Ref(_, substs) | ||
863 | | TyKind::FnDef(_, substs) | 834 | | TyKind::FnDef(_, substs) |
864 | | TyKind::Function(FnPointer { substs, .. }) | 835 | | TyKind::Function(FnPointer { substs, .. }) |
865 | | TyKind::Tuple(_, substs) | 836 | | TyKind::Tuple(_, substs) |
@@ -988,7 +959,7 @@ pub trait TypeWalk { | |||
988 | { | 959 | { |
989 | self.walk_mut_binders( | 960 | self.walk_mut_binders( |
990 | &mut |ty_mut, binders| { | 961 | &mut |ty_mut, binders| { |
991 | let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); | 962 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
992 | *ty_mut = f(ty, binders); | 963 | *ty_mut = f(ty, binders); |
993 | }, | 964 | }, |
994 | binders, | 965 | binders, |
@@ -1001,7 +972,7 @@ pub trait TypeWalk { | |||
1001 | Self: Sized, | 972 | Self: Sized, |
1002 | { | 973 | { |
1003 | self.walk_mut(&mut |ty_mut| { | 974 | self.walk_mut(&mut |ty_mut| { |
1004 | let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); | 975 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
1005 | *ty_mut = f(ty); | 976 | *ty_mut = f(ty); |
1006 | }); | 977 | }); |
1007 | self | 978 | self |
@@ -1022,7 +993,7 @@ pub trait TypeWalk { | |||
1022 | { | 993 | { |
1023 | self.walk_mut_binders( | 994 | self.walk_mut_binders( |
1024 | &mut |ty, binders| { | 995 | &mut |ty, binders| { |
1025 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { | 996 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
1026 | if bound.debruijn >= binders { | 997 | if bound.debruijn >= binders { |
1027 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 998 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
1028 | } | 999 | } |
@@ -1039,7 +1010,7 @@ pub trait TypeWalk { | |||
1039 | Self: Sized, | 1010 | Self: Sized, |
1040 | { | 1011 | { |
1041 | self.fold_binders( | 1012 | self.fold_binders( |
1042 | &mut |ty, binders| match &ty.0 { | 1013 | &mut |ty, binders| match ty.interned(&Interner) { |
1043 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { | 1014 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { |
1044 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) | 1015 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) |
1045 | } | 1016 | } |
@@ -1068,6 +1039,9 @@ impl TypeWalk for Ty { | |||
1068 | p.walk(f); | 1039 | p.walk(f); |
1069 | } | 1040 | } |
1070 | } | 1041 | } |
1042 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1043 | ty.walk(f); | ||
1044 | } | ||
1071 | _ => { | 1045 | _ => { |
1072 | if let Some(substs) = self.substs() { | 1046 | if let Some(substs) = self.substs() { |
1073 | for t in substs.iter() { | 1047 | for t in substs.iter() { |
@@ -1084,7 +1058,7 @@ impl TypeWalk for Ty { | |||
1084 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 1058 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
1085 | binders: DebruijnIndex, | 1059 | binders: DebruijnIndex, |
1086 | ) { | 1060 | ) { |
1087 | match &mut self.0 { | 1061 | match self.interned_mut() { |
1088 | TyKind::Alias(AliasTy::Projection(p_ty)) => { | 1062 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1089 | p_ty.substitution.walk_mut_binders(f, binders); | 1063 | p_ty.substitution.walk_mut_binders(f, binders); |
1090 | } | 1064 | } |
@@ -1096,6 +1070,9 @@ impl TypeWalk for Ty { | |||
1096 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { | 1070 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { |
1097 | o_ty.substitution.walk_mut_binders(f, binders); | 1071 | o_ty.substitution.walk_mut_binders(f, binders); |
1098 | } | 1072 | } |
1073 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1074 | ty.walk_mut_binders(f, binders); | ||
1075 | } | ||
1099 | _ => { | 1076 | _ => { |
1100 | if let Some(substs) = self.substs_mut() { | 1077 | if let Some(substs) = self.substs_mut() { |
1101 | substs.walk_mut_binders(f, binders); | 1078 | substs.walk_mut_binders(f, binders); |