aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-08 10:23:05 +0000
committerFlorian Diebold <[email protected]>2019-12-08 12:06:59 +0000
commitd0c9bb0abf764a3143fc0d13297d73184bc10397 (patch)
tree34e392bae6422cec8d8ef8ab975fbb48db4b808d
parent596e6db46c9c79b2b2be20a4b5461dca35d44b0f (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.rs6
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs37
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]
408fn coerce_autoderef_generic() {
409 assert_snapshot!(
410 infer_with_mismatches(r#"
411struct Foo;
412fn takes_ref<T>(x: &T) -> T { *x }
413fn 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}