diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-21 18:51:53 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-21 18:51:53 +0100 |
commit | edbde25ca2f13ffacfd006ada7b38618d36d97c6 (patch) | |
tree | b1c5208c74ce56a36c8a9c454b9c479a3312ee94 /crates/hir_ty/src/infer/expr.rs | |
parent | de403b10448e23f232804596538de92fc57203d6 (diff) | |
parent | ef558c97d09b0be8639c92f490e5ad380aa04288 (diff) |
Merge #8856
8856: Use Chalk for unification r=flodiebold a=flodiebold
- use Chalk's unification, get rid of our own `unify`
- rewrite coercion to not use unification internals and to be more analogous to rustc
- fix various coercion bugs
- rewrite handling of obligations, since the old hacky optimization where we noted when an inference variable changes wasn't possible anymore
- stop trying to deeply resolve types all the time during inference, instead only do it shallowly where necessary
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 142 |
1 files changed, 84 insertions, 58 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 7278faeec..08c05c67c 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -35,39 +35,43 @@ use super::{ | |||
35 | impl<'a> InferenceContext<'a> { | 35 | impl<'a> InferenceContext<'a> { |
36 | pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 36 | pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
37 | let ty = self.infer_expr_inner(tgt_expr, expected); | 37 | let ty = self.infer_expr_inner(tgt_expr, expected); |
38 | if ty.is_never() { | 38 | if self.resolve_ty_shallow(&ty).is_never() { |
39 | // Any expression that produces a value of type `!` must have diverged | 39 | // Any expression that produces a value of type `!` must have diverged |
40 | self.diverges = Diverges::Always; | 40 | self.diverges = Diverges::Always; |
41 | } | 41 | } |
42 | let could_unify = self.unify(&ty, &expected.ty); | 42 | if let Some(expected_ty) = expected.only_has_type(&mut self.table) { |
43 | if !could_unify { | 43 | let could_unify = self.unify(&ty, &expected_ty); |
44 | self.result.type_mismatches.insert( | 44 | if !could_unify { |
45 | tgt_expr.into(), | 45 | self.result.type_mismatches.insert( |
46 | TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, | 46 | tgt_expr.into(), |
47 | ); | 47 | TypeMismatch { expected: expected_ty.clone(), actual: ty.clone() }, |
48 | ); | ||
49 | } | ||
48 | } | 50 | } |
49 | self.resolve_ty_as_possible(ty) | 51 | ty |
50 | } | 52 | } |
51 | 53 | ||
52 | /// Infer type of expression with possibly implicit coerce to the expected type. | 54 | /// Infer type of expression with possibly implicit coerce to the expected type. |
53 | /// Return the type after possible coercion. | 55 | /// Return the type after possible coercion. |
54 | pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 56 | pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
55 | let ty = self.infer_expr_inner(expr, &expected); | 57 | let ty = self.infer_expr_inner(expr, &expected); |
56 | let ty = if !self.coerce(&ty, &expected.coercion_target()) { | 58 | let ty = if let Some(target) = expected.only_has_type(&mut self.table) { |
57 | self.result.type_mismatches.insert( | 59 | if !self.coerce(&ty, &target) { |
58 | expr.into(), | 60 | self.result.type_mismatches.insert( |
59 | TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, | 61 | expr.into(), |
60 | ); | 62 | TypeMismatch { expected: target.clone(), actual: ty.clone() }, |
61 | // Return actual type when type mismatch. | 63 | ); |
62 | // This is needed for diagnostic when return type mismatch. | 64 | // Return actual type when type mismatch. |
63 | ty | 65 | // This is needed for diagnostic when return type mismatch. |
64 | } else if expected.coercion_target().is_unknown() { | 66 | ty |
65 | ty | 67 | } else { |
68 | target.clone() | ||
69 | } | ||
66 | } else { | 70 | } else { |
67 | expected.ty.clone() | 71 | ty |
68 | }; | 72 | }; |
69 | 73 | ||
70 | self.resolve_ty_as_possible(ty) | 74 | ty |
71 | } | 75 | } |
72 | 76 | ||
73 | fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { | 77 | fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { |
@@ -98,10 +102,10 @@ impl<'a> InferenceContext<'a> { | |||
98 | goal: projection.trait_ref(self.db).cast(&Interner), | 102 | goal: projection.trait_ref(self.db).cast(&Interner), |
99 | environment: trait_env, | 103 | environment: trait_env, |
100 | }; | 104 | }; |
101 | let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone()); | 105 | let canonical = self.canonicalize(obligation.clone()); |
102 | if self.db.trait_solve(krate, canonical.value).is_some() { | 106 | if self.db.trait_solve(krate, canonical.value.cast(&Interner)).is_some() { |
103 | self.push_obligation(obligation.goal); | 107 | self.push_obligation(obligation.goal); |
104 | let return_ty = self.normalize_projection_ty(projection); | 108 | let return_ty = self.table.normalize_projection_ty(projection); |
105 | Some((arg_tys, return_ty)) | 109 | Some((arg_tys, return_ty)) |
106 | } else { | 110 | } else { |
107 | None | 111 | None |
@@ -131,17 +135,21 @@ impl<'a> InferenceContext<'a> { | |||
131 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 135 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
132 | let mut both_arms_diverge = Diverges::Always; | 136 | let mut both_arms_diverge = Diverges::Always; |
133 | 137 | ||
138 | let mut result_ty = self.table.new_type_var(); | ||
134 | let then_ty = self.infer_expr_inner(*then_branch, &expected); | 139 | let then_ty = self.infer_expr_inner(*then_branch, &expected); |
135 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); | 140 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); |
141 | result_ty = self.coerce_merge_branch(Some(*then_branch), &result_ty, &then_ty); | ||
136 | let else_ty = match else_branch { | 142 | let else_ty = match else_branch { |
137 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), | 143 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), |
138 | None => TyBuilder::unit(), | 144 | None => TyBuilder::unit(), |
139 | }; | 145 | }; |
140 | both_arms_diverge &= self.diverges; | 146 | both_arms_diverge &= self.diverges; |
147 | // FIXME: create a synthetic `else {}` so we have something to refer to here instead of None? | ||
148 | result_ty = self.coerce_merge_branch(*else_branch, &result_ty, &else_ty); | ||
141 | 149 | ||
142 | self.diverges = condition_diverges | both_arms_diverge; | 150 | self.diverges = condition_diverges | both_arms_diverge; |
143 | 151 | ||
144 | self.coerce_merge_branch(&then_ty, &else_ty) | 152 | result_ty |
145 | } | 153 | } |
146 | Expr::Block { statements, tail, label, id: _ } => { | 154 | Expr::Block { statements, tail, label, id: _ } => { |
147 | let old_resolver = mem::replace( | 155 | let old_resolver = mem::replace( |
@@ -277,12 +285,13 @@ impl<'a> InferenceContext<'a> { | |||
277 | // Eagerly try to relate the closure type with the expected | 285 | // Eagerly try to relate the closure type with the expected |
278 | // type, otherwise we often won't have enough information to | 286 | // type, otherwise we often won't have enough information to |
279 | // infer the body. | 287 | // infer the body. |
280 | self.coerce(&closure_ty, &expected.ty); | 288 | if let Some(t) = expected.only_has_type(&mut self.table) { |
289 | self.coerce(&closure_ty, &t); | ||
290 | } | ||
281 | 291 | ||
282 | // Now go through the argument patterns | 292 | // Now go through the argument patterns |
283 | for (arg_pat, arg_ty) in args.iter().zip(sig_tys) { | 293 | for (arg_pat, arg_ty) in args.iter().zip(sig_tys) { |
284 | let resolved = self.resolve_ty_as_possible(arg_ty); | 294 | self.infer_pat(*arg_pat, &arg_ty, BindingMode::default()); |
285 | self.infer_pat(*arg_pat, &resolved, BindingMode::default()); | ||
286 | } | 295 | } |
287 | 296 | ||
288 | let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 297 | let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
@@ -297,13 +306,13 @@ impl<'a> InferenceContext<'a> { | |||
297 | } | 306 | } |
298 | Expr::Call { callee, args } => { | 307 | Expr::Call { callee, args } => { |
299 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); | 308 | let callee_ty = self.infer_expr(*callee, &Expectation::none()); |
300 | let canonicalized = self.canonicalizer().canonicalize_ty(callee_ty.clone()); | 309 | let canonicalized = self.canonicalize(callee_ty.clone()); |
301 | let mut derefs = autoderef( | 310 | let mut derefs = autoderef( |
302 | self.db, | 311 | self.db, |
303 | self.resolver.krate(), | 312 | self.resolver.krate(), |
304 | InEnvironment { | 313 | InEnvironment { |
305 | goal: canonicalized.value.clone(), | 314 | goal: canonicalized.value.clone(), |
306 | environment: self.trait_env.env.clone(), | 315 | environment: self.table.trait_env.env.clone(), |
307 | }, | 316 | }, |
308 | ); | 317 | ); |
309 | let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs | 318 | let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs |
@@ -350,7 +359,7 @@ impl<'a> InferenceContext<'a> { | |||
350 | 359 | ||
351 | let arm_ty = self.infer_expr_inner(arm.expr, &expected); | 360 | let arm_ty = self.infer_expr_inner(arm.expr, &expected); |
352 | all_arms_diverge &= self.diverges; | 361 | all_arms_diverge &= self.diverges; |
353 | result_ty = self.coerce_merge_branch(&result_ty, &arm_ty); | 362 | result_ty = self.coerce_merge_branch(Some(arm.expr), &result_ty, &arm_ty); |
354 | } | 363 | } |
355 | 364 | ||
356 | self.diverges = matchee_diverges | all_arms_diverge; | 365 | self.diverges = matchee_diverges | all_arms_diverge; |
@@ -364,12 +373,6 @@ impl<'a> InferenceContext<'a> { | |||
364 | } | 373 | } |
365 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), | 374 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
366 | Expr::Break { expr, label } => { | 375 | Expr::Break { expr, label } => { |
367 | let val_ty = if let Some(expr) = expr { | ||
368 | self.infer_expr(*expr, &Expectation::none()) | ||
369 | } else { | ||
370 | TyBuilder::unit() | ||
371 | }; | ||
372 | |||
373 | let last_ty = | 376 | let last_ty = |
374 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 377 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
375 | ctxt.break_ty.clone() | 378 | ctxt.break_ty.clone() |
@@ -377,7 +380,14 @@ impl<'a> InferenceContext<'a> { | |||
377 | self.err_ty() | 380 | self.err_ty() |
378 | }; | 381 | }; |
379 | 382 | ||
380 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 383 | let val_ty = if let Some(expr) = expr { |
384 | self.infer_expr(*expr, &Expectation::none()) | ||
385 | } else { | ||
386 | TyBuilder::unit() | ||
387 | }; | ||
388 | |||
389 | // FIXME: create a synthetic `()` during lowering so we have something to refer to here? | ||
390 | let merged_type = self.coerce_merge_branch(*expr, &last_ty, &val_ty); | ||
381 | 391 | ||
382 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 392 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
383 | ctxt.break_ty = merged_type; | 393 | ctxt.break_ty = merged_type; |
@@ -411,7 +421,9 @@ impl<'a> InferenceContext<'a> { | |||
411 | self.write_variant_resolution(tgt_expr.into(), variant); | 421 | self.write_variant_resolution(tgt_expr.into(), variant); |
412 | } | 422 | } |
413 | 423 | ||
414 | self.unify(&ty, &expected.ty); | 424 | if let Some(t) = expected.only_has_type(&mut self.table) { |
425 | self.unify(&ty, &t); | ||
426 | } | ||
415 | 427 | ||
416 | let substs = ty | 428 | let substs = ty |
417 | .as_adt() | 429 | .as_adt() |
@@ -442,7 +454,7 @@ impl<'a> InferenceContext<'a> { | |||
442 | } | 454 | } |
443 | Expr::Field { expr, name } => { | 455 | Expr::Field { expr, name } => { |
444 | let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 456 | let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
445 | let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); | 457 | let canonicalized = self.canonicalize(receiver_ty); |
446 | let ty = autoderef::autoderef( | 458 | let ty = autoderef::autoderef( |
447 | self.db, | 459 | self.db, |
448 | self.resolver.krate(), | 460 | self.resolver.krate(), |
@@ -514,6 +526,7 @@ impl<'a> InferenceContext<'a> { | |||
514 | self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()) | 526 | self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()) |
515 | } | 527 | } |
516 | Expr::Cast { expr, type_ref } => { | 528 | Expr::Cast { expr, type_ref } => { |
529 | // FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary) | ||
517 | let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 530 | let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
518 | let cast_ty = self.make_ty(type_ref); | 531 | let cast_ty = self.make_ty(type_ref); |
519 | // FIXME check the cast... | 532 | // FIXME check the cast... |
@@ -521,15 +534,17 @@ impl<'a> InferenceContext<'a> { | |||
521 | } | 534 | } |
522 | Expr::Ref { expr, rawness, mutability } => { | 535 | Expr::Ref { expr, rawness, mutability } => { |
523 | let mutability = lower_to_chalk_mutability(*mutability); | 536 | let mutability = lower_to_chalk_mutability(*mutability); |
524 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = | 537 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected |
525 | &expected.ty.as_reference_or_ptr() | 538 | .only_has_type(&mut self.table) |
539 | .as_ref() | ||
540 | .and_then(|t| t.as_reference_or_ptr()) | ||
526 | { | 541 | { |
527 | if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { | 542 | if exp_mutability == Mutability::Mut && mutability == Mutability::Not { |
528 | // FIXME: throw type error - expected mut reference but found shared ref, | 543 | // FIXME: record type error - expected mut reference but found shared ref, |
529 | // which cannot be coerced | 544 | // which cannot be coerced |
530 | } | 545 | } |
531 | if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { | 546 | if exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { |
532 | // FIXME: throw type error - expected reference but found ptr, | 547 | // FIXME: record type error - expected reference but found ptr, |
533 | // which cannot be coerced | 548 | // which cannot be coerced |
534 | } | 549 | } |
535 | Expectation::rvalue_hint(Ty::clone(exp_inner)) | 550 | Expectation::rvalue_hint(Ty::clone(exp_inner)) |
@@ -556,10 +571,11 @@ impl<'a> InferenceContext<'a> { | |||
556 | } | 571 | } |
557 | Expr::UnaryOp { expr, op } => { | 572 | Expr::UnaryOp { expr, op } => { |
558 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 573 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
574 | let inner_ty = self.resolve_ty_shallow(&inner_ty); | ||
559 | match op { | 575 | match op { |
560 | UnaryOp::Deref => match self.resolver.krate() { | 576 | UnaryOp::Deref => match self.resolver.krate() { |
561 | Some(krate) => { | 577 | Some(krate) => { |
562 | let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); | 578 | let canonicalized = self.canonicalize(inner_ty); |
563 | match autoderef::deref( | 579 | match autoderef::deref( |
564 | self.db, | 580 | self.db, |
565 | krate, | 581 | krate, |
@@ -612,8 +628,10 @@ impl<'a> InferenceContext<'a> { | |||
612 | _ => Expectation::none(), | 628 | _ => Expectation::none(), |
613 | }; | 629 | }; |
614 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 630 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
631 | let lhs_ty = self.resolve_ty_shallow(&lhs_ty); | ||
615 | let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone()); | 632 | let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone()); |
616 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); | 633 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); |
634 | let rhs_ty = self.resolve_ty_shallow(&rhs_ty); | ||
617 | 635 | ||
618 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); | 636 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); |
619 | 637 | ||
@@ -676,7 +694,7 @@ impl<'a> InferenceContext<'a> { | |||
676 | if let (Some(index_trait), Some(krate)) = | 694 | if let (Some(index_trait), Some(krate)) = |
677 | (self.resolve_ops_index(), self.resolver.krate()) | 695 | (self.resolve_ops_index(), self.resolver.krate()) |
678 | { | 696 | { |
679 | let canonicalized = self.canonicalizer().canonicalize_ty(base_ty); | 697 | let canonicalized = self.canonicalize(base_ty); |
680 | let self_ty = method_resolution::resolve_indexing_op( | 698 | let self_ty = method_resolution::resolve_indexing_op( |
681 | self.db, | 699 | self.db, |
682 | &canonicalized.value, | 700 | &canonicalized.value, |
@@ -696,8 +714,12 @@ impl<'a> InferenceContext<'a> { | |||
696 | } | 714 | } |
697 | } | 715 | } |
698 | Expr::Tuple { exprs } => { | 716 | Expr::Tuple { exprs } => { |
699 | let mut tys = match expected.ty.kind(&Interner) { | 717 | let mut tys = match expected |
700 | TyKind::Tuple(_, substs) => substs | 718 | .only_has_type(&mut self.table) |
719 | .as_ref() | ||
720 | .map(|t| t.kind(&Interner)) | ||
721 | { | ||
722 | Some(TyKind::Tuple(_, substs)) => substs | ||
701 | .iter(&Interner) | 723 | .iter(&Interner) |
702 | .map(|a| a.assert_ty_ref(&Interner).clone()) | 724 | .map(|a| a.assert_ty_ref(&Interner).clone()) |
703 | .chain(repeat_with(|| self.table.new_type_var())) | 725 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -713,14 +735,16 @@ impl<'a> InferenceContext<'a> { | |||
713 | TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) | 735 | TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) |
714 | } | 736 | } |
715 | Expr::Array(array) => { | 737 | Expr::Array(array) => { |
716 | let elem_ty = match expected.ty.kind(&Interner) { | 738 | let elem_ty = |
717 | TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), | 739 | match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) { |
718 | _ => self.table.new_type_var(), | 740 | Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(), |
719 | }; | 741 | _ => self.table.new_type_var(), |
742 | }; | ||
720 | 743 | ||
721 | let len = match array { | 744 | let len = match array { |
722 | Array::ElementList(items) => { | 745 | Array::ElementList(items) => { |
723 | for expr in items.iter() { | 746 | for expr in items.iter() { |
747 | // FIXME: use CoerceMany (coerce_merge_branch) | ||
724 | self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); | 748 | self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); |
725 | } | 749 | } |
726 | Some(items.len() as u64) | 750 | Some(items.len() as u64) |
@@ -785,7 +809,6 @@ impl<'a> InferenceContext<'a> { | |||
785 | }; | 809 | }; |
786 | // use a new type variable if we got unknown here | 810 | // use a new type variable if we got unknown here |
787 | let ty = self.insert_type_vars_shallow(ty); | 811 | let ty = self.insert_type_vars_shallow(ty); |
788 | let ty = self.resolve_ty_as_possible(ty); | ||
789 | self.write_expr_ty(tgt_expr, ty.clone()); | 812 | self.write_expr_ty(tgt_expr, ty.clone()); |
790 | ty | 813 | ty |
791 | } | 814 | } |
@@ -813,7 +836,6 @@ impl<'a> InferenceContext<'a> { | |||
813 | } | 836 | } |
814 | } | 837 | } |
815 | 838 | ||
816 | let ty = self.resolve_ty_as_possible(ty); | ||
817 | self.infer_pat(*pat, &ty, BindingMode::default()); | 839 | self.infer_pat(*pat, &ty, BindingMode::default()); |
818 | } | 840 | } |
819 | Statement::Expr { expr, .. } => { | 841 | Statement::Expr { expr, .. } => { |
@@ -836,7 +858,9 @@ impl<'a> InferenceContext<'a> { | |||
836 | // we don't even make an attempt at coercion | 858 | // we don't even make an attempt at coercion |
837 | self.table.new_maybe_never_var() | 859 | self.table.new_maybe_never_var() |
838 | } else { | 860 | } else { |
839 | self.coerce(&TyBuilder::unit(), &expected.coercion_target()); | 861 | if let Some(t) = expected.only_has_type(&mut self.table) { |
862 | self.coerce(&TyBuilder::unit(), &t); | ||
863 | } | ||
840 | TyBuilder::unit() | 864 | TyBuilder::unit() |
841 | } | 865 | } |
842 | }; | 866 | }; |
@@ -852,7 +876,7 @@ impl<'a> InferenceContext<'a> { | |||
852 | generic_args: Option<&GenericArgs>, | 876 | generic_args: Option<&GenericArgs>, |
853 | ) -> Ty { | 877 | ) -> Ty { |
854 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); | 878 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); |
855 | let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone()); | 879 | let canonicalized_receiver = self.canonicalize(receiver_ty.clone()); |
856 | 880 | ||
857 | let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast()); | 881 | let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast()); |
858 | 882 | ||
@@ -891,7 +915,8 @@ impl<'a> InferenceContext<'a> { | |||
891 | }; | 915 | }; |
892 | // Apply autoref so the below unification works correctly | 916 | // Apply autoref so the below unification works correctly |
893 | // FIXME: return correct autorefs from lookup_method | 917 | // FIXME: return correct autorefs from lookup_method |
894 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 918 | let actual_receiver_ty = match self.resolve_ty_shallow(&expected_receiver_ty).as_reference() |
919 | { | ||
895 | Some((_, lifetime, mutability)) => { | 920 | Some((_, lifetime, mutability)) => { |
896 | TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner) | 921 | TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner) |
897 | } | 922 | } |
@@ -971,6 +996,7 @@ impl<'a> InferenceContext<'a> { | |||
971 | } | 996 | } |
972 | 997 | ||
973 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 998 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
999 | let callable_ty = self.resolve_ty_shallow(&callable_ty); | ||
974 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { | 1000 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { |
975 | let def: CallableDefId = from_chalk(self.db, *fn_def); | 1001 | let def: CallableDefId = from_chalk(self.db, *fn_def); |
976 | let generic_predicates = self.db.generic_predicates(def.into()); | 1002 | let generic_predicates = self.db.generic_predicates(def.into()); |