diff options
author | Florian Diebold <[email protected]> | 2019-12-20 17:53:40 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-12-20 17:54:33 +0000 |
commit | 44b00aed4a7d7e329fcbfa95a8685437cfb06e41 (patch) | |
tree | 0b00ef7d63064a4f60e03427abf0803bb17b4596 | |
parent | 1d7931e5ffeb2d65ebcc14a63da1b84cc131bfb8 (diff) |
Coerce closures to fn pointers
E.g. `let x: fn(A) -> B = |x| { y };`
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 39 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 10 |
3 files changed, 48 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 0f4dac45e..83c0c2c3f 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -134,6 +134,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | ||
138 | from_ty = params[0].clone(); | ||
139 | } | ||
140 | |||
137 | _ => {} | 141 | _ => {} |
138 | } | 142 | } |
139 | 143 | ||
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 793c23e41..7e99a42ed 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -487,3 +487,42 @@ fn foo() { | |||
487 | "### | 487 | "### |
488 | ); | 488 | ); |
489 | } | 489 | } |
490 | |||
491 | #[test] | ||
492 | fn coerce_fn_item_to_fn_ptr() { | ||
493 | assert_snapshot!( | ||
494 | infer_with_mismatches(r#" | ||
495 | fn foo(x: u32) -> isize { 1 } | ||
496 | fn test() { | ||
497 | let f: fn(u32) -> isize = foo; | ||
498 | } | ||
499 | "#, true), | ||
500 | @r###" | ||
501 | [8; 9) 'x': u32 | ||
502 | [25; 30) '{ 1 }': isize | ||
503 | [27; 28) '1': isize | ||
504 | [41; 79) '{ ...foo; }': () | ||
505 | [51; 52) 'f': fn(u32) -> isize | ||
506 | [73; 76) 'foo': fn foo(u32) -> isize | ||
507 | "### | ||
508 | ); | ||
509 | } | ||
510 | |||
511 | #[test] | ||
512 | fn coerce_closure_to_fn_ptr() { | ||
513 | assert_snapshot!( | ||
514 | infer_with_mismatches(r#" | ||
515 | fn test() { | ||
516 | let f: fn(u32) -> isize = |x| { 1 }; | ||
517 | } | ||
518 | "#, true), | ||
519 | @r###" | ||
520 | [11; 55) '{ ...1 }; }': () | ||
521 | [21; 22) 'f': fn(u32) -> isize | ||
522 | [43; 52) '|x| { 1 }': |u32| -> isize | ||
523 | [44; 45) 'x': u32 | ||
524 | [47; 52) '{ 1 }': isize | ||
525 | [49; 50) '1': isize | ||
526 | "### | ||
527 | ); | ||
528 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 2d92a5eec..76e2198b6 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -393,11 +393,11 @@ fn test() -> u64 { | |||
393 | [54; 55) 'a': S | 393 | [54; 55) 'a': S |
394 | [58; 59) 'S': S(fn(u32) -> u64) -> S | 394 | [58; 59) 'S': S(fn(u32) -> u64) -> S |
395 | [58; 68) 'S(|i| 2*i)': S | 395 | [58; 68) 'S(|i| 2*i)': S |
396 | [60; 67) '|i| 2*i': |i32| -> i32 | 396 | [60; 67) '|i| 2*i': |u32| -> u64 |
397 | [61; 62) 'i': i32 | 397 | [61; 62) 'i': u32 |
398 | [64; 65) '2': i32 | 398 | [64; 65) '2': u32 |
399 | [64; 67) '2*i': i32 | 399 | [64; 67) '2*i': u32 |
400 | [66; 67) 'i': i32 | 400 | [66; 67) 'i': u32 |
401 | [78; 79) 'b': u64 | 401 | [78; 79) 'b': u64 |
402 | [82; 83) 'a': S | 402 | [82; 83) 'a': S |
403 | [82; 85) 'a.0': fn(u32) -> u64 | 403 | [82; 85) 'a.0': fn(u32) -> u64 |