about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCristian Oliveira <contato@cristianoliveira.com.br>2016-05-27 22:38:09 -0300
committerCristian Oliveira <contato@cristianoliveira.com.br>2016-06-06 01:02:26 -0300
commit45e647dfe2e961bcab3d588e9ff1e1fafd89a9c9 (patch)
tree7c3b2c0bf216f6d07dd58b8360be7c1c460f6901
parente24d621fcacf59fa8ecc1c1af1c4adeded4bddee (diff)
downloadrust-45e647dfe2e961bcab3d588e9ff1e1fafd89a9c9.tar.gz
rust-45e647dfe2e961bcab3d588e9ff1e1fafd89a9c9.zip
Add error description for E0174
-rw-r--r--src/librustc_typeck/diagnostics.rs84
1 files changed, 83 insertions, 1 deletions
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 45aec9558fe..d7d8c60e911 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1972,6 +1972,89 @@ To learn more about traits, take a look at the Book:
 https://doc.rust-lang.org/book/traits.html
 "##,
 
+E0174: r##"
+This error occurs because of the explicit use of unboxed closure methods
+that are an experimental feature in current Rust version.
+
+Example of erroneous code:
+
+```compile_fail
+fn foo<F: Fn(&str)>(mut f: F) {
+    f.call(("call",));
+    // error: explicit use of unboxed closure method `call`
+    f.call_mut(("call_mut",));
+    // error: explicit use of unboxed closure method `call_mut`
+    f.call_once(("call_once",));
+    // error: explicit use of unboxed closure method `call_once`
+}
+
+fn bar(text: &str) {
+    println!("Calling {} it works!", text);
+}
+
+fn main() {
+    foo(bar);
+}
+```
+
+Rust's implementation of closures is a bit different than other languages.
+They are effectively syntax sugar for traits `Fn`, `FnMut` and `FnOnce`.
+To understand better how the closures are implemented see here:
+https://doc.rust-lang.org/book/closures.html#closure-implementation
+
+To fix this you can call them using parenthesis, like this: `foo()`.
+When you execute the closure with parenthesis, under the hood you are executing
+the method `call`, `call_mut` or `call_once`. However, using them explicitly is
+currently an experimental feature.
+
+Example of an implicit call:
+
+```
+fn foo<F: Fn(&str)>(f: F) {
+    f("using ()"); // Calling using () it works!
+}
+
+fn bar(text: &str) {
+    println!("Calling {} it works!", text);
+}
+
+fn main() {
+    foo(bar);
+}
+```
+
+To enable the explicit calls you need to add `#![feature(unboxed_closures)]`.
+
+This feature is still unstable so you will also need to add
+`#![feature(fn_traits)]`.
+More details about this issue here:
+https://github.com/rust-lang/rust/issues/29625
+
+Example of use:
+
+```
+#![feature(fn_traits)]
+#![feature(unboxed_closures)]
+
+fn foo<F: Fn(&str)>(mut f: F) {
+    f.call(("call",)); // Calling 'call' it works!
+    f.call_mut(("call_mut",)); // Calling 'call_mut' it works!
+    f.call_once(("call_once",)); // Calling 'call_once' it works!
+}
+
+fn bar(text: &str) {
+    println!("Calling '{}' it works!", text);
+}
+
+fn main() {
+    foo(bar);
+}
+```
+
+To see more about closures take a look here:
+https://doc.rust-lang.org/book/closures.html`
+"##,
+
 E0178: r##"
 In types, the `+` type operator has low precedence, so it is often necessary
 to use parentheses.
@@ -3891,7 +3974,6 @@ register_diagnostics! {
     E0167,
 //  E0168,
 //  E0173, // manual implementations of unboxed closure traits are experimental
-    E0174, // explicit use of unboxed closure methods are experimental
     E0182,
     E0183,
 //  E0187, // can't infer the kind of the closure