diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 484652073..0b2da8971 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -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. |
@@ -814,7 +822,7 @@ impl Ty { | |||
814 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | 822 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have |
815 | /// `Option<u32>` afterwards.) | 823 | /// `Option<u32>` afterwards.) |
816 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { | 824 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { |
817 | match &mut self.0 { | 825 | match self.interned_mut() { |
818 | TyKind::Adt(_, substs) | 826 | TyKind::Adt(_, substs) |
819 | | TyKind::Slice(substs) | 827 | | TyKind::Slice(substs) |
820 | | TyKind::Array(substs) | 828 | | TyKind::Array(substs) |
@@ -854,7 +862,7 @@ impl Ty { | |||
854 | } | 862 | } |
855 | 863 | ||
856 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | 864 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { |
857 | match &mut self.0 { | 865 | match self.interned_mut() { |
858 | TyKind::Adt(_, substs) | 866 | TyKind::Adt(_, substs) |
859 | | TyKind::Slice(substs) | 867 | | TyKind::Slice(substs) |
860 | | TyKind::Array(substs) | 868 | | TyKind::Array(substs) |
@@ -988,7 +996,7 @@ pub trait TypeWalk { | |||
988 | { | 996 | { |
989 | self.walk_mut_binders( | 997 | self.walk_mut_binders( |
990 | &mut |ty_mut, binders| { | 998 | &mut |ty_mut, binders| { |
991 | let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); | 999 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
992 | *ty_mut = f(ty, binders); | 1000 | *ty_mut = f(ty, binders); |
993 | }, | 1001 | }, |
994 | binders, | 1002 | binders, |
@@ -1001,7 +1009,7 @@ pub trait TypeWalk { | |||
1001 | Self: Sized, | 1009 | Self: Sized, |
1002 | { | 1010 | { |
1003 | self.walk_mut(&mut |ty_mut| { | 1011 | self.walk_mut(&mut |ty_mut| { |
1004 | let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); | 1012 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
1005 | *ty_mut = f(ty); | 1013 | *ty_mut = f(ty); |
1006 | }); | 1014 | }); |
1007 | self | 1015 | self |
@@ -1022,7 +1030,7 @@ pub trait TypeWalk { | |||
1022 | { | 1030 | { |
1023 | self.walk_mut_binders( | 1031 | self.walk_mut_binders( |
1024 | &mut |ty, binders| { | 1032 | &mut |ty, binders| { |
1025 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { | 1033 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
1026 | if bound.debruijn >= binders { | 1034 | if bound.debruijn >= binders { |
1027 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 1035 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
1028 | } | 1036 | } |
@@ -1039,7 +1047,7 @@ pub trait TypeWalk { | |||
1039 | Self: Sized, | 1047 | Self: Sized, |
1040 | { | 1048 | { |
1041 | self.fold_binders( | 1049 | self.fold_binders( |
1042 | &mut |ty, binders| match &ty.0 { | 1050 | &mut |ty, binders| match ty.interned(&Interner) { |
1043 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { | 1051 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { |
1044 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) | 1052 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) |
1045 | } | 1053 | } |
@@ -1084,7 +1092,7 @@ impl TypeWalk for Ty { | |||
1084 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 1092 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
1085 | binders: DebruijnIndex, | 1093 | binders: DebruijnIndex, |
1086 | ) { | 1094 | ) { |
1087 | match &mut self.0 { | 1095 | match self.interned_mut() { |
1088 | TyKind::Alias(AliasTy::Projection(p_ty)) => { | 1096 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1089 | p_ty.substitution.walk_mut_binders(f, binders); | 1097 | p_ty.substitution.walk_mut_binders(f, binders); |
1090 | } | 1098 | } |