aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-03-14 16:25:29 +0000
committerFlorian Diebold <[email protected]>2021-03-14 16:31:08 +0000
commitaf466f8542173002361eb134e66102908c7cd024 (patch)
tree75a970fa98bf1f67ae390ae5b6a71d09fd963641
parent195414783402d6973f4e673e84be9b7bc19cbfa6 (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.rs30
-rw-r--r--crates/hir_ty/src/infer/coerce.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs2
-rw-r--r--crates/hir_ty/src/infer/pat.rs12
-rw-r--r--crates/hir_ty/src/infer/unify.rs4
-rw-r--r--crates/hir_ty/src/lib.rs26
-rw-r--r--crates/hir_ty/src/lower.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs2
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)]
112struct InternedStandardTypes {
113 unknown: Ty,
114}
115
116impl 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)]
113pub struct InferenceResult { 124pub 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
131impl InferenceResult { 144impl 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)]
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 }
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::*;
24impl ToChalk for Ty { 24impl 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, .. }) => {