aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer/coerce.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer/coerce.rs')
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs27
1 files changed, 16 insertions, 11 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 719a0f395..83c0c2c3f 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -8,9 +8,9 @@ use hir_def::{lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutabilit
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk}; 11use crate::{autoderef, db::HirDatabase, Substs, Ty, TypeCtor, TypeWalk};
12 12
13use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; 13use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext};
14 14
15impl<'a, D: HirDatabase> InferenceContext<'a, D> { 15impl<'a, D: HirDatabase> InferenceContext<'a, D> {
16 /// Unify two types, but may coerce the first one to the second one 16 /// Unify two types, but may coerce the first one to the second one
@@ -54,10 +54,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
54 impls 54 impls
55 .iter() 55 .iter()
56 .filter_map(|&impl_id| { 56 .filter_map(|&impl_id| {
57 let trait_ref = match db.impl_ty(impl_id) { 57 let trait_ref = db.impl_trait(impl_id)?;
58 ImplTy::TraitRef(it) => it,
59 ImplTy::Inherent(_) => return None,
60 };
61 58
62 // `CoerseUnsized` has one generic parameter for the target type. 59 // `CoerseUnsized` has one generic parameter for the target type.
63 let cur_from_ty = trait_ref.substs.0.get(0)?; 60 let cur_from_ty = trait_ref.substs.0.get(0)?;
@@ -88,8 +85,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
88 match (&from_ty, to_ty) { 85 match (&from_ty, to_ty) {
89 // Never type will make type variable to fallback to Never Type instead of Unknown. 86 // Never type will make type variable to fallback to Never Type instead of Unknown.
90 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 87 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => {
91 let var = self.new_maybe_never_type_var(); 88 let var = self.table.new_maybe_never_type_var();
92 self.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); 89 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
93 return true; 90 return true;
94 } 91 }
95 (ty_app!(TypeCtor::Never), _) => return true, 92 (ty_app!(TypeCtor::Never), _) => return true,
@@ -97,7 +94,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
97 // Trivial cases, this should go after `never` check to 94 // Trivial cases, this should go after `never` check to
98 // avoid infer result type to be never 95 // avoid infer result type to be never
99 _ => { 96 _ => {
100 if self.unify_inner_trivial(&from_ty, &to_ty) { 97 if self.table.unify_inner_trivial(&from_ty, &to_ty) {
101 return true; 98 return true;
102 } 99 }
103 } 100 }
@@ -137,6 +134,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
137 } 134 }
138 } 135 }
139 136
137 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => {
138 from_ty = params[0].clone();
139 }
140
140 _ => {} 141 _ => {}
141 } 142 }
142 143
@@ -333,9 +334,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
333 // Stop when constructor matches. 334 // Stop when constructor matches.
334 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 335 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => {
335 // It will not recurse to `coerce`. 336 // It will not recurse to `coerce`.
336 return self.unify_substs(st1, st2, 0); 337 return self.table.unify_substs(st1, st2, 0);
338 }
339 _ => {
340 if self.table.unify_inner_trivial(&derefed_ty, &to_ty) {
341 return true;
342 }
337 } 343 }
338 _ => {}
339 } 344 }
340 } 345 }
341 346