]> git.lizzy.rs Git - rust.git/commitdiff
Coerce closures to fn pointers
authorFlorian Diebold <florian.diebold@freiheit.com>
Fri, 20 Dec 2019 17:53:40 +0000 (18:53 +0100)
committerFlorian Diebold <florian.diebold@freiheit.com>
Fri, 20 Dec 2019 17:54:33 +0000 (18:54 +0100)
E.g. `let x: fn(A) -> B = |x| { y };`

crates/ra_hir_ty/src/infer/coerce.rs
crates/ra_hir_ty/src/tests/coercion.rs
crates/ra_hir_ty/src/tests/traits.rs

index 0f4dac45edf2b454117bc9ed96af9e133815205e..83c0c2c3f334cba765ac75b6384a3ccac54be83e 100644 (file)
@@ -134,6 +134,10 @@ fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
                 }
             }
 
+            (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => {
+                from_ty = params[0].clone();
+            }
+
             _ => {}
         }
 
index 793c23e41c64f725dc6658fda506f374b571d259..7e99a42edc459e913900eb5f08765ae789a82731 100644 (file)
@@ -487,3 +487,42 @@ fn foo() {
     "###
     );
 }
+
+#[test]
+fn coerce_fn_item_to_fn_ptr() {
+    assert_snapshot!(
+        infer_with_mismatches(r#"
+fn foo(x: u32) -> isize { 1 }
+fn test() {
+    let f: fn(u32) -> isize = foo;
+}
+"#, true),
+        @r###"
+    [8; 9) 'x': u32
+    [25; 30) '{ 1 }': isize
+    [27; 28) '1': isize
+    [41; 79) '{     ...foo; }': ()
+    [51; 52) 'f': fn(u32) -> isize
+    [73; 76) 'foo': fn foo(u32) -> isize
+    "###
+    );
+}
+
+#[test]
+fn coerce_closure_to_fn_ptr() {
+    assert_snapshot!(
+        infer_with_mismatches(r#"
+fn test() {
+    let f: fn(u32) -> isize = |x| { 1 };
+}
+"#, true),
+        @r###"
+    [11; 55) '{     ...1 }; }': ()
+    [21; 22) 'f': fn(u32) -> isize
+    [43; 52) '|x| { 1 }': |u32| -> isize
+    [44; 45) 'x': u32
+    [47; 52) '{ 1 }': isize
+    [49; 50) '1': isize
+    "###
+    );
+}
index 2d92a5eec266040ddf66c05234c6e6f804420ef1..76e2198b6638474966767518cdd6b730047f6816 100644 (file)
@@ -393,11 +393,11 @@ fn test() -> u64 {
     [54; 55) 'a': S
     [58; 59) 'S': S(fn(u32) -> u64) -> S
     [58; 68) 'S(|i| 2*i)': S
-    [60; 67) '|i| 2*i': |i32| -> i32
-    [61; 62) 'i': i32
-    [64; 65) '2': i32
-    [64; 67) '2*i': i32
-    [66; 67) 'i': i32
+    [60; 67) '|i| 2*i': |u32| -> u64
+    [61; 62) 'i': u32
+    [64; 65) '2': u32
+    [64; 67) '2*i': u32
+    [66; 67) 'i': u32
     [78; 79) 'b': u64
     [82; 83) 'a': S
     [82; 85) 'a.0': fn(u32) -> u64