diff options
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index f1cebbdb9..7a4268819 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -28,17 +28,18 @@ use hir_def::{ | |||
28 | AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup, | 28 | AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule, Lookup, |
29 | TraitId, TypeAliasId, VariantId, | 29 | TraitId, TypeAliasId, VariantId, |
30 | }; | 30 | }; |
31 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; | 31 | use hir_expand::name::name; |
32 | use la_arena::ArenaMap; | 32 | use la_arena::ArenaMap; |
33 | use rustc_hash::FxHashMap; | 33 | use rustc_hash::FxHashMap; |
34 | use stdx::impl_from; | 34 | use stdx::impl_from; |
35 | use syntax::SmolStr; | 35 | use syntax::SmolStr; |
36 | 36 | ||
37 | use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; | 37 | use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; |
38 | use crate::diagnostics_sink::DiagnosticSink; | ||
38 | use crate::{ | 39 | use crate::{ |
39 | db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic, | 40 | db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic, |
40 | lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, TyBuilder, | 41 | lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, Substitution, |
41 | TyExt, TyKind, | 42 | TyBuilder, TyExt, TyKind, |
42 | }; | 43 | }; |
43 | 44 | ||
44 | // This lint has a false positive here. See the link below for details. | 45 | // This lint has a false positive here. See the link below for details. |
@@ -132,7 +133,7 @@ impl Default for InternedStandardTypes { | |||
132 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 133 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
133 | pub struct InferenceResult { | 134 | pub struct InferenceResult { |
134 | /// For each method call expr, records the function it resolves to. | 135 | /// For each method call expr, records the function it resolves to. |
135 | method_resolutions: FxHashMap<ExprId, FunctionId>, | 136 | method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>, |
136 | /// For each field access expr, records the field it resolves to. | 137 | /// For each field access expr, records the field it resolves to. |
137 | field_resolutions: FxHashMap<ExprId, FieldId>, | 138 | field_resolutions: FxHashMap<ExprId, FieldId>, |
138 | /// For each struct literal or pattern, records the variant it resolves to. | 139 | /// For each struct literal or pattern, records the variant it resolves to. |
@@ -152,8 +153,8 @@ pub struct InferenceResult { | |||
152 | } | 153 | } |
153 | 154 | ||
154 | impl InferenceResult { | 155 | impl InferenceResult { |
155 | pub fn method_resolution(&self, expr: ExprId) -> Option<FunctionId> { | 156 | pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> { |
156 | self.method_resolutions.get(&expr).copied() | 157 | self.method_resolutions.get(&expr).cloned() |
157 | } | 158 | } |
158 | pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> { | 159 | pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> { |
159 | self.field_resolutions.get(&expr).copied() | 160 | self.field_resolutions.get(&expr).copied() |
@@ -284,14 +285,17 @@ impl<'a> InferenceContext<'a> { | |||
284 | self.table.propagate_diverging_flag(); | 285 | self.table.propagate_diverging_flag(); |
285 | let mut result = std::mem::take(&mut self.result); | 286 | let mut result = std::mem::take(&mut self.result); |
286 | for ty in result.type_of_expr.values_mut() { | 287 | for ty in result.type_of_expr.values_mut() { |
287 | *ty = self.table.resolve_ty_completely(ty.clone()); | 288 | *ty = self.table.resolve_completely(ty.clone()); |
288 | } | 289 | } |
289 | for ty in result.type_of_pat.values_mut() { | 290 | for ty in result.type_of_pat.values_mut() { |
290 | *ty = self.table.resolve_ty_completely(ty.clone()); | 291 | *ty = self.table.resolve_completely(ty.clone()); |
291 | } | 292 | } |
292 | for mismatch in result.type_mismatches.values_mut() { | 293 | for mismatch in result.type_mismatches.values_mut() { |
293 | mismatch.expected = self.table.resolve_ty_completely(mismatch.expected.clone()); | 294 | mismatch.expected = self.table.resolve_completely(mismatch.expected.clone()); |
294 | mismatch.actual = self.table.resolve_ty_completely(mismatch.actual.clone()); | 295 | mismatch.actual = self.table.resolve_completely(mismatch.actual.clone()); |
296 | } | ||
297 | for (_, subst) in result.method_resolutions.values_mut() { | ||
298 | *subst = self.table.resolve_completely(subst.clone()); | ||
295 | } | 299 | } |
296 | result | 300 | result |
297 | } | 301 | } |
@@ -300,8 +304,8 @@ impl<'a> InferenceContext<'a> { | |||
300 | self.result.type_of_expr.insert(expr, ty); | 304 | self.result.type_of_expr.insert(expr, ty); |
301 | } | 305 | } |
302 | 306 | ||
303 | fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) { | 307 | fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) { |
304 | self.result.method_resolutions.insert(expr, func); | 308 | self.result.method_resolutions.insert(expr, (func, subst)); |
305 | } | 309 | } |
306 | 310 | ||
307 | fn write_field_resolution(&mut self, expr: ExprId, field: FieldId) { | 311 | fn write_field_resolution(&mut self, expr: ExprId, field: FieldId) { |
@@ -554,7 +558,13 @@ impl<'a> InferenceContext<'a> { | |||
554 | 558 | ||
555 | self.infer_pat(*pat, &ty, BindingMode::default()); | 559 | self.infer_pat(*pat, &ty, BindingMode::default()); |
556 | } | 560 | } |
557 | let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT | 561 | let error_ty = &TypeRef::Error; |
562 | let return_ty = if data.is_async() { | ||
563 | data.async_ret_type.as_deref().unwrap_or(error_ty) | ||
564 | } else { | ||
565 | &*data.ret_type | ||
566 | }; | ||
567 | let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT | ||
558 | self.return_ty = return_ty; | 568 | self.return_ty = return_ty; |
559 | } | 569 | } |
560 | 570 | ||
@@ -575,9 +585,14 @@ impl<'a> InferenceContext<'a> { | |||
575 | } | 585 | } |
576 | 586 | ||
577 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { | 587 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { |
588 | // FIXME resolve via lang_item once try v2 is stable | ||
578 | let path = path![core::ops::Try]; | 589 | let path = path![core::ops::Try]; |
579 | let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; | 590 | let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; |
580 | self.db.trait_data(trait_).associated_type_by_name(&name![Ok]) | 591 | let trait_data = self.db.trait_data(trait_); |
592 | trait_data | ||
593 | // FIXME remove once try v2 is stable | ||
594 | .associated_type_by_name(&name![Ok]) | ||
595 | .or_else(|| trait_data.associated_type_by_name(&name![Output])) | ||
581 | } | 596 | } |
582 | 597 | ||
583 | fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { | 598 | fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { |
@@ -790,11 +805,11 @@ impl std::ops::BitOrAssign for Diverges { | |||
790 | 805 | ||
791 | mod diagnostics { | 806 | mod diagnostics { |
792 | use hir_def::{expr::ExprId, DefWithBodyId}; | 807 | use hir_def::{expr::ExprId, DefWithBodyId}; |
793 | use hir_expand::diagnostics::DiagnosticSink; | ||
794 | 808 | ||
795 | use crate::{ | 809 | use crate::{ |
796 | db::HirDatabase, | 810 | db::HirDatabase, |
797 | diagnostics::{BreakOutsideOfLoop, NoSuchField}, | 811 | diagnostics::{BreakOutsideOfLoop, NoSuchField}, |
812 | diagnostics_sink::DiagnosticSink, | ||
798 | }; | 813 | }; |
799 | 814 | ||
800 | #[derive(Debug, PartialEq, Eq, Clone)] | 815 | #[derive(Debug, PartialEq, Eq, Clone)] |