6

Suggest fn ptr rather than fn item and suggest to use `Fn` trait bounds rather t...

 3 years ago
source link: https://github.com/rust-lang/rust/pull/80284
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Contributor

ThePuzzlemaker commented 12 days ago

Previously, using _ as a return type in a function that returned a function/closure would provide a diagnostic that would cause a papercut. For example:

fn f() -> i32 { 0 }
fn fn_ptr() -> _ { f }
fn closure() -> _ { || 0 }

would result in this diagnostic:

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
 --> <anon>:2:16
  |
2 | fn fn_ptr() -> _ { f }
  |                ^
  |                |
  |                not allowed in type signatures
  |                help: replace with the correct return type: `fn() -> i32 {f}`

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
 --> <anon>:3:17
  |
3 | fn closure() -> _ { || 0 }
  |                 ^
  |                 |
  |                 not allowed in type signatures
  |                 help: replace with the correct return type: `[closure@<anon>:3:21: 3:25]`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0121`.

As can be seen, it was suggested to use the function definition return type fn() -> i32 { f } which is not valid syntax as a return type. Additionally, closures cause a papercut as unique closure types (notated in this case as [closure@<anon>:3:21: 3:25]) are not valid syntax either.

Instead, this PR implements this version of the diagnostic (this example is for the same code featured above):

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
 --> <anon>:2:16
  |
2 | fn fn_ptr() -> _ { f }
  |                ^
  |                |
  |                not allowed in type signatures
  |                help: replace with the correct return type: `fn() -> i32`

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
 --> <anon>:3:17
  |
3 | fn closure() -> _ { || 0 }
  |                 ^ not allowed in type signatures
  |
  = help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
  = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0121`.

As can be seen in this diagnostic, the papercut for returning a function item is fixed by suggesting the usage of a function pointer as the return type. As for closures, it's suggested to use an Fn, FnMut, or FnOnce trait bound (with further reading on closures and Fn traits in The Book for beginners). I did not implement a suggestion to use impl Fn() -> i32 syntax as that was out-of-scope for my abilities at the moment, therefore someone in the future may want to implement that. Also, it's possible to use either impl Trait syntax, generics, or generics with a where clause, and some users may not want to use impl Trait syntax for their own reasons.

This PR fixes #80179.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK