Skip to content

Commit 4a4a13a

Browse files
committed
Auto merge of #33920 - cristianoliveira:error-E0174-explanation, r=GuillaumeGomez
Add error description for E0174 Reference for issue: #32777 r? @GuillaumeGomez Hey Guillaume, sorry for taking too long to do it. I got some unexpected work during the week. Waiting for your review :)
2 parents 8519139 + 45e647d commit 4a4a13a

File tree

1 file changed

+83
-1
lines changed

1 file changed

+83
-1
lines changed

src/librustc_typeck/diagnostics.rs

+83-1
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,89 @@ To learn more about traits, take a look at the Book:
19901990
https://doc.rust-lang.org/book/traits.html
19911991
"##,
19921992

1993+
E0174: r##"
1994+
This error occurs because of the explicit use of unboxed closure methods
1995+
that are an experimental feature in current Rust version.
1996+
1997+
Example of erroneous code:
1998+
1999+
```compile_fail
2000+
fn foo<F: Fn(&str)>(mut f: F) {
2001+
f.call(("call",));
2002+
// error: explicit use of unboxed closure method `call`
2003+
f.call_mut(("call_mut",));
2004+
// error: explicit use of unboxed closure method `call_mut`
2005+
f.call_once(("call_once",));
2006+
// error: explicit use of unboxed closure method `call_once`
2007+
}
2008+
2009+
fn bar(text: &str) {
2010+
println!("Calling {} it works!", text);
2011+
}
2012+
2013+
fn main() {
2014+
foo(bar);
2015+
}
2016+
```
2017+
2018+
Rust's implementation of closures is a bit different than other languages.
2019+
They are effectively syntax sugar for traits `Fn`, `FnMut` and `FnOnce`.
2020+
To understand better how the closures are implemented see here:
2021+
https://doc.rust-lang.org/book/closures.html#closure-implementation
2022+
2023+
To fix this you can call them using parenthesis, like this: `foo()`.
2024+
When you execute the closure with parenthesis, under the hood you are executing
2025+
the method `call`, `call_mut` or `call_once`. However, using them explicitly is
2026+
currently an experimental feature.
2027+
2028+
Example of an implicit call:
2029+
2030+
```
2031+
fn foo<F: Fn(&str)>(f: F) {
2032+
f("using ()"); // Calling using () it works!
2033+
}
2034+
2035+
fn bar(text: &str) {
2036+
println!("Calling {} it works!", text);
2037+
}
2038+
2039+
fn main() {
2040+
foo(bar);
2041+
}
2042+
```
2043+
2044+
To enable the explicit calls you need to add `#![feature(unboxed_closures)]`.
2045+
2046+
This feature is still unstable so you will also need to add
2047+
`#![feature(fn_traits)]`.
2048+
More details about this issue here:
2049+
https://github.com/rust-lang/rust/issues/29625
2050+
2051+
Example of use:
2052+
2053+
```
2054+
#![feature(fn_traits)]
2055+
#![feature(unboxed_closures)]
2056+
2057+
fn foo<F: Fn(&str)>(mut f: F) {
2058+
f.call(("call",)); // Calling 'call' it works!
2059+
f.call_mut(("call_mut",)); // Calling 'call_mut' it works!
2060+
f.call_once(("call_once",)); // Calling 'call_once' it works!
2061+
}
2062+
2063+
fn bar(text: &str) {
2064+
println!("Calling '{}' it works!", text);
2065+
}
2066+
2067+
fn main() {
2068+
foo(bar);
2069+
}
2070+
```
2071+
2072+
To see more about closures take a look here:
2073+
https://doc.rust-lang.org/book/closures.html`
2074+
"##,
2075+
19932076
E0178: r##"
19942077
In types, the `+` type operator has low precedence, so it is often necessary
19952078
to use parentheses.
@@ -4007,7 +4090,6 @@ register_diagnostics! {
40074090
E0167,
40084091
// E0168,
40094092
// E0173, // manual implementations of unboxed closure traits are experimental
4010-
E0174, // explicit use of unboxed closure methods are experimental
40114093
E0182,
40124094
E0183,
40134095
// E0187, // can't infer the kind of the closure

0 commit comments

Comments
 (0)