Skip to content

Commit 45e647d

Browse files
Add error description for E0174
1 parent e24d621 commit 45e647d

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
@@ -1972,6 +1972,89 @@ To learn more about traits, take a look at the Book:
19721972
https://doc.rust-lang.org/book/traits.html
19731973
"##,
19741974

1975+
E0174: r##"
1976+
This error occurs because of the explicit use of unboxed closure methods
1977+
that are an experimental feature in current Rust version.
1978+
1979+
Example of erroneous code:
1980+
1981+
```compile_fail
1982+
fn foo<F: Fn(&str)>(mut f: F) {
1983+
f.call(("call",));
1984+
// error: explicit use of unboxed closure method `call`
1985+
f.call_mut(("call_mut",));
1986+
// error: explicit use of unboxed closure method `call_mut`
1987+
f.call_once(("call_once",));
1988+
// error: explicit use of unboxed closure method `call_once`
1989+
}
1990+
1991+
fn bar(text: &str) {
1992+
println!("Calling {} it works!", text);
1993+
}
1994+
1995+
fn main() {
1996+
foo(bar);
1997+
}
1998+
```
1999+
2000+
Rust's implementation of closures is a bit different than other languages.
2001+
They are effectively syntax sugar for traits `Fn`, `FnMut` and `FnOnce`.
2002+
To understand better how the closures are implemented see here:
2003+
https://doc.rust-lang.org/book/closures.html#closure-implementation
2004+
2005+
To fix this you can call them using parenthesis, like this: `foo()`.
2006+
When you execute the closure with parenthesis, under the hood you are executing
2007+
the method `call`, `call_mut` or `call_once`. However, using them explicitly is
2008+
currently an experimental feature.
2009+
2010+
Example of an implicit call:
2011+
2012+
```
2013+
fn foo<F: Fn(&str)>(f: F) {
2014+
f("using ()"); // Calling using () it works!
2015+
}
2016+
2017+
fn bar(text: &str) {
2018+
println!("Calling {} it works!", text);
2019+
}
2020+
2021+
fn main() {
2022+
foo(bar);
2023+
}
2024+
```
2025+
2026+
To enable the explicit calls you need to add `#![feature(unboxed_closures)]`.
2027+
2028+
This feature is still unstable so you will also need to add
2029+
`#![feature(fn_traits)]`.
2030+
More details about this issue here:
2031+
https://github.com/rust-lang/rust/issues/29625
2032+
2033+
Example of use:
2034+
2035+
```
2036+
#![feature(fn_traits)]
2037+
#![feature(unboxed_closures)]
2038+
2039+
fn foo<F: Fn(&str)>(mut f: F) {
2040+
f.call(("call",)); // Calling 'call' it works!
2041+
f.call_mut(("call_mut",)); // Calling 'call_mut' it works!
2042+
f.call_once(("call_once",)); // Calling 'call_once' it works!
2043+
}
2044+
2045+
fn bar(text: &str) {
2046+
println!("Calling '{}' it works!", text);
2047+
}
2048+
2049+
fn main() {
2050+
foo(bar);
2051+
}
2052+
```
2053+
2054+
To see more about closures take a look here:
2055+
https://doc.rust-lang.org/book/closures.html`
2056+
"##,
2057+
19752058
E0178: r##"
19762059
In types, the `+` type operator has low precedence, so it is often necessary
19772060
to use parentheses.
@@ -3891,7 +3974,6 @@ register_diagnostics! {
38913974
E0167,
38923975
// E0168,
38933976
// E0173, // manual implementations of unboxed closure traits are experimental
3894-
E0174, // explicit use of unboxed closure methods are experimental
38953977
E0182,
38963978
E0183,
38973979
// E0187, // can't infer the kind of the closure

0 commit comments

Comments
 (0)