diff options
author | Florian Diebold <[email protected]> | 2021-03-14 16:25:29 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-14 16:31:08 +0000 |
commit | af466f8542173002361eb134e66102908c7cd024 (patch) | |
tree | 75a970fa98bf1f67ae390ae5b6a71d09fd963641 | |
parent | 195414783402d6973f4e673e84be9b7bc19cbfa6 (diff) |
Make Ty wrap TyKind in an Arc
... like it will be in Chalk. We still keep `interned_mut` and
`into_inner` methods that will probably not exist with Chalk.
This worsens performance slightly (5ginstr inference on RA), but doesn't
include other simplifications we can do yet.
-rw-r--r-- | crates/hir_ty/src/infer.rs | 30 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 26 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 2 |
8 files changed, 53 insertions, 27 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index fbfedb4e6..6dfe53902 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -108,6 +108,17 @@ pub struct TypeMismatch { | |||
108 | pub actual: Ty, | 108 | pub actual: Ty, |
109 | } | 109 | } |
110 | 110 | ||
111 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
112 | struct InternedStandardTypes { | ||
113 | unknown: Ty, | ||
114 | } | ||
115 | |||
116 | impl Default for InternedStandardTypes { | ||
117 | fn default() -> Self { | ||
118 | InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } | ||
119 | } | ||
120 | } | ||
121 | |||
111 | /// The result of type inference: A mapping from expressions and patterns to types. | 122 | /// The result of type inference: A mapping from expressions and patterns to types. |
112 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 123 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
113 | pub struct InferenceResult { | 124 | pub struct InferenceResult { |
@@ -126,6 +137,8 @@ pub struct InferenceResult { | |||
126 | pub type_of_expr: ArenaMap<ExprId, Ty>, | 137 | pub type_of_expr: ArenaMap<ExprId, Ty>, |
127 | pub type_of_pat: ArenaMap<PatId, Ty>, | 138 | pub type_of_pat: ArenaMap<PatId, Ty>, |
128 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, | 139 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, |
140 | /// Interned Unknown to return references to. | ||
141 | standard_types: InternedStandardTypes, | ||
129 | } | 142 | } |
130 | 143 | ||
131 | impl InferenceResult { | 144 | impl InferenceResult { |
@@ -170,7 +183,7 @@ impl Index<ExprId> for InferenceResult { | |||
170 | type Output = Ty; | 183 | type Output = Ty; |
171 | 184 | ||
172 | fn index(&self, expr: ExprId) -> &Ty { | 185 | fn index(&self, expr: ExprId) -> &Ty { |
173 | self.type_of_expr.get(expr).unwrap_or(&Ty(TyKind::Unknown)) | 186 | self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown) |
174 | } | 187 | } |
175 | } | 188 | } |
176 | 189 | ||
@@ -178,7 +191,7 @@ impl Index<PatId> for InferenceResult { | |||
178 | type Output = Ty; | 191 | type Output = Ty; |
179 | 192 | ||
180 | fn index(&self, pat: PatId) -> &Ty { | 193 | fn index(&self, pat: PatId) -> &Ty { |
181 | self.type_of_pat.get(pat).unwrap_or(&Ty(TyKind::Unknown)) | 194 | self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown) |
182 | } | 195 | } |
183 | } | 196 | } |
184 | 197 | ||
@@ -723,14 +736,19 @@ impl Expectation { | |||
723 | 736 | ||
724 | /// This expresses no expectation on the type. | 737 | /// This expresses no expectation on the type. |
725 | fn none() -> Self { | 738 | fn none() -> Self { |
726 | Expectation { ty: TyKind::Unknown.intern(&Interner), rvalue_hint: false } | 739 | Expectation { |
740 | // FIXME | ||
741 | ty: TyKind::Unknown.intern(&Interner), | ||
742 | rvalue_hint: false, | ||
743 | } | ||
727 | } | 744 | } |
728 | 745 | ||
729 | fn coercion_target(&self) -> &Ty { | 746 | fn coercion_target(&self) -> Ty { |
730 | if self.rvalue_hint { | 747 | if self.rvalue_hint { |
731 | &Ty(TyKind::Unknown) | 748 | // FIXME |
749 | TyKind::Unknown.intern(&Interner) | ||
732 | } else { | 750 | } else { |
733 | &self.ty | 751 | self.ty.clone() |
734 | } | 752 | } |
735 | } | 753 | } |
736 | } | 754 | } |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 36670043a..435f7d0db 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { | |||
71 | } | 71 | } |
72 | 72 | ||
73 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
74 | match (&mut from_ty.0, to_ty.interned(&Interner)) { | 74 | match (from_ty.interned_mut(), to_ty.interned(&Interner)) { |
75 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
76 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 55163c963..e9ca2b86f 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -800,7 +800,7 @@ impl<'a> InferenceContext<'a> { | |||
800 | // we don't even make an attempt at coercion | 800 | // we don't even make an attempt at coercion |
801 | self.table.new_maybe_never_var() | 801 | self.table.new_maybe_never_var() |
802 | } else { | 802 | } else { |
803 | self.coerce(&Ty::unit(), expected.coercion_target()); | 803 | self.coerce(&Ty::unit(), &expected.coercion_target()); |
804 | Ty::unit() | 804 | Ty::unit() |
805 | } | 805 | } |
806 | }; | 806 | }; |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a16755cda..2e812ab94 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -158,11 +158,11 @@ impl<'a> InferenceContext<'a> { | |||
158 | if mutability != exp_mut { | 158 | if mutability != exp_mut { |
159 | // FIXME: emit type error? | 159 | // FIXME: emit type error? |
160 | } | 160 | } |
161 | inner_ty | 161 | inner_ty.clone() |
162 | } | 162 | } |
163 | _ => &Ty(TyKind::Unknown), | 163 | _ => self.result.standard_types.unknown.clone(), |
164 | }; | 164 | }; |
165 | let subty = self.infer_pat(*pat, expectation, default_bm); | 165 | let subty = self.infer_pat(*pat, &expectation, default_bm); |
166 | TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) | 166 | TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) |
167 | } | 167 | } |
168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
@@ -232,11 +232,11 @@ impl<'a> InferenceContext<'a> { | |||
232 | Pat::Box { inner } => match self.resolve_boxed_box() { | 232 | Pat::Box { inner } => match self.resolve_boxed_box() { |
233 | Some(box_adt) => { | 233 | Some(box_adt) => { |
234 | let inner_expected = match expected.as_adt() { | 234 | let inner_expected = match expected.as_adt() { |
235 | Some((adt, substs)) if adt == box_adt => substs.as_single(), | 235 | Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), |
236 | _ => &Ty(TyKind::Unknown), | 236 | _ => self.result.standard_types.unknown.clone(), |
237 | }; | 237 | }; |
238 | 238 | ||
239 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 239 | let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); |
240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) | 240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) |
241 | } | 241 | } |
242 | None => self.err_ty(), | 242 | None => self.err_ty(), |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index ebc612ca9..2501a4e0a 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -108,7 +108,7 @@ impl<T> Canonicalized<T> { | |||
108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
109 | ty.walk_mut_binders( | 109 | ty.walk_mut_binders( |
110 | &mut |ty, binders| { | 110 | &mut |ty, binders| { |
111 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { | 111 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
112 | if bound.debruijn >= binders { | 112 | if bound.debruijn >= binders { |
113 | let (v, k) = self.free_vars[bound.index]; | 113 | let (v, k) = self.free_vars[bound.index]; |
114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); | 114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); |
@@ -404,7 +404,7 @@ impl InferenceTable { | |||
404 | if i > 0 { | 404 | if i > 0 { |
405 | cov_mark::hit!(type_var_resolves_to_int_var); | 405 | cov_mark::hit!(type_var_resolves_to_int_var); |
406 | } | 406 | } |
407 | match &ty.0 { | 407 | match ty.interned(&Interner) { |
408 | TyKind::InferenceVar(tv, _) => { | 408 | TyKind::InferenceVar(tv, _) => { |
409 | let inner = tv.to_inner(); | 409 | let inner = tv.to_inner(); |
410 | match self.var_unification_table.inlined_probe_value(inner).known() { | 410 | match self.var_unification_table.inlined_probe_value(inner).known() { |
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 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index d026310f4..2a4ad9172 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -993,7 +993,7 @@ pub(crate) fn generic_defaults_query( | |||
993 | 993 | ||
994 | // Each default can only refer to previous parameters. | 994 | // Each default can only refer to previous parameters. |
995 | ty.walk_mut_binders( | 995 | ty.walk_mut_binders( |
996 | &mut |ty, binders| match &mut ty.0 { | 996 | &mut |ty, binders| match ty.interned_mut() { |
997 | TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { | 997 | TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { |
998 | if *index >= idx { | 998 | if *index >= idx { |
999 | // type variable default referring to parameter coming | 999 | // type variable default referring to parameter coming |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 05a4bf0df..2ab976190 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -24,7 +24,7 @@ use super::*; | |||
24 | impl ToChalk for Ty { | 24 | impl ToChalk for Ty { |
25 | type Chalk = chalk_ir::Ty<Interner>; | 25 | type Chalk = chalk_ir::Ty<Interner>; |
26 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { | 26 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { |
27 | match self.0 { | 27 | match self.into_inner() { |
28 | TyKind::Ref(m, parameters) => ref_to_chalk(db, m, parameters), | 28 | TyKind::Ref(m, parameters) => ref_to_chalk(db, m, parameters), |
29 | TyKind::Array(parameters) => array_to_chalk(db, parameters), | 29 | TyKind::Array(parameters) => array_to_chalk(db, parameters), |
30 | TyKind::Function(FnPointer { sig, substs, .. }) => { | 30 | TyKind::Function(FnPointer { sig, substs, .. }) => { |