Skip to content

Unary operators do not add bounds to closure, instead just errors #94543

Closed
@OleStrohm

Description

@OleStrohm

I tried this code:

(|a| -a)(42)

Howevery this unexpectedly fails, requiring the type to be specified in the closure definition. (|a| a + a)(42) on the other hand works just fine.

Digging a little deeper I discovered this related problem. It seems that the unary operator doesn't add an implicit trait bound to the closure, and instead just gives an error immediately.
This seems to be the behaviour for all unary operators, not just the unary minus.

fn closure_unary<T>() -> impl Fn(T) -> T {
    |a| -a
}

fn closure_binary<T>() -> impl Fn(T) -> T {
    |a| a+a
}

I expected to see this happen:
I expected both of these to have errors like closure_binary:

error[E0369]: cannot add `T` to `T`
 --> src/main.rs:6:10
  |
6 |     |a| a+a
  |         -^- T
  |         |
  |         T
  |
help: consider restricting type parameter `T`
  |
5 | fn closure_binary<T: std::ops::Add<Output = T>>() -> impl Fn(T) -> T {
  |                    +++++++++++++++++++++++++++

Instead, this happened:
Only closure_binary has such an error. Instead closure_unary has:

error[E0600]: cannot apply unary operator `-` to type `T`
 --> src/main.rs:2:9
  |
2 |     |a| -a
  |         ^^ cannot apply unary operator `-`

Meta

rustc --version --verbose:

rustc 1.59.0 (9d1b2106e 2022-02-23)
binary: rustc
commit-hash: 9d1b2106e23b1abd32fce1f17267604a5102f57a
commit-date: 2022-02-23
host: x86_64-unknown-linux-gnu
release: 1.59.0
LLVM version: 13.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions