aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs26
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)]
251pub struct Ty(TyKind); 251pub struct Ty(Arc<TyKind>);
252 252
253impl TyKind { 253impl 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 }