diff options
author | Florian Diebold <[email protected]> | 2019-12-08 10:23:05 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-12-08 12:06:59 +0000 |
commit | d0c9bb0abf764a3143fc0d13297d73184bc10397 (patch) | |
tree | 34e392bae6422cec8d8ef8ab975fbb48db4b808d | |
parent | 596e6db46c9c79b2b2be20a4b5461dca35d44b0f (diff) |
Fix coercion from &Foo to an inference variable in a reference
We didn't try to unify within the reference, but we should.
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 37 |
2 files changed, 42 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 9daa77cfa..0f4dac45e 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -332,7 +332,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
332 | // It will not recurse to `coerce`. | 332 | // It will not recurse to `coerce`. |
333 | return self.table.unify_substs(st1, st2, 0); | 333 | return self.table.unify_substs(st1, st2, 0); |
334 | } | 334 | } |
335 | _ => {} | 335 | _ => { |
336 | if self.table.unify_inner_trivial(&derefed_ty, &to_ty) { | ||
337 | return true; | ||
338 | } | ||
339 | } | ||
336 | } | 340 | } |
337 | } | 341 | } |
338 | 342 | ||
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 58b22396f..ac9e3872a 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -403,3 +403,40 @@ fn test() { | |||
403 | "### | 403 | "### |
404 | ); | 404 | ); |
405 | } | 405 | } |
406 | |||
407 | #[test] | ||
408 | fn coerce_autoderef_generic() { | ||
409 | assert_snapshot!( | ||
410 | infer_with_mismatches(r#" | ||
411 | struct Foo; | ||
412 | fn takes_ref<T>(x: &T) -> T { *x } | ||
413 | fn test() { | ||
414 | takes_ref(&Foo); | ||
415 | takes_ref(&&Foo); | ||
416 | takes_ref(&&&Foo); | ||
417 | } | ||
418 | "#, true), | ||
419 | @r###" | ||
420 | [29; 30) 'x': &T | ||
421 | [41; 47) '{ *x }': T | ||
422 | [43; 45) '*x': T | ||
423 | [44; 45) 'x': &T | ||
424 | [58; 127) '{ ...oo); }': () | ||
425 | [64; 73) 'takes_ref': fn takes_ref<Foo>(&T) -> T | ||
426 | [64; 79) 'takes_ref(&Foo)': Foo | ||
427 | [74; 78) '&Foo': &Foo | ||
428 | [75; 78) 'Foo': Foo | ||
429 | [85; 94) 'takes_ref': fn takes_ref<&Foo>(&T) -> T | ||
430 | [85; 101) 'takes_...&&Foo)': &Foo | ||
431 | [95; 100) '&&Foo': &&Foo | ||
432 | [96; 100) '&Foo': &Foo | ||
433 | [97; 100) 'Foo': Foo | ||
434 | [107; 116) 'takes_ref': fn takes_ref<&&Foo>(&T) -> T | ||
435 | [107; 124) 'takes_...&&Foo)': &&Foo | ||
436 | [117; 123) '&&&Foo': &&&Foo | ||
437 | [118; 123) '&&Foo': &&Foo | ||
438 | [119; 123) '&Foo': &Foo | ||
439 | [120; 123) 'Foo': Foo | ||
440 | "### | ||
441 | ); | ||
442 | } | ||