aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r--crates/hir_ty/src/infer.rs45
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};
31use hir_expand::{diagnostics::DiagnosticSink, name::name}; 31use hir_expand::name::name;
32use la_arena::ArenaMap; 32use la_arena::ArenaMap;
33use rustc_hash::FxHashMap; 33use rustc_hash::FxHashMap;
34use stdx::impl_from; 34use stdx::impl_from;
35use syntax::SmolStr; 35use syntax::SmolStr;
36 36
37use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; 37use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
38use crate::diagnostics_sink::DiagnosticSink;
38use crate::{ 39use 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)]
133pub struct InferenceResult { 134pub 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
154impl InferenceResult { 155impl 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
791mod diagnostics { 806mod 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)]