diff options
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index fbfedb4e6..9c385b845 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 | } |
@@ -784,7 +802,7 @@ mod diagnostics { | |||
784 | 802 | ||
785 | #[derive(Debug, PartialEq, Eq, Clone)] | 803 | #[derive(Debug, PartialEq, Eq, Clone)] |
786 | pub(super) enum InferenceDiagnostic { | 804 | pub(super) enum InferenceDiagnostic { |
787 | NoSuchField { expr: ExprId, field: usize }, | 805 | NoSuchField { expr: ExprId }, |
788 | BreakOutsideOfLoop { expr: ExprId }, | 806 | BreakOutsideOfLoop { expr: ExprId }, |
789 | } | 807 | } |
790 | 808 | ||
@@ -796,9 +814,9 @@ mod diagnostics { | |||
796 | sink: &mut DiagnosticSink, | 814 | sink: &mut DiagnosticSink, |
797 | ) { | 815 | ) { |
798 | match self { | 816 | match self { |
799 | InferenceDiagnostic::NoSuchField { expr, field } => { | 817 | InferenceDiagnostic::NoSuchField { expr } => { |
800 | let (_, source_map) = db.body_with_source_map(owner); | 818 | let (_, source_map) = db.body_with_source_map(owner); |
801 | let field = source_map.field_syntax(*expr, *field); | 819 | let field = source_map.field_syntax(*expr); |
802 | sink.push(NoSuchField { file: field.file_id, field: field.value }) | 820 | sink.push(NoSuchField { file: field.file_id, field: field.value }) |
803 | } | 821 | } |
804 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { | 822 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { |