Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Try invoking the function" hint #63100

Closed
Patryk27 opened this issue Jul 29, 2019 · 11 comments
Closed

"Try invoking the function" hint #63100

Patryk27 opened this issue Jul 29, 2019 · 11 comments

Comments

@Patryk27
Copy link
Contributor

@Patryk27 Patryk27 commented Jul 29, 2019

Hi,

Let's consider following code:

fn foo() -> usize {
    0
}

fn bar(i: usize) {
    
}

fn main() {
    bar(foo);
}

Right now it fails with the expected usize, found fn item message - I think it would be helpful if compiler bragged about missing parentheses when function's return type matches expected type:

fn main() {
    bar(foo);
//      ^^^ expected usize, found fn item
//          hint: try invoking the function: foo()
}

It may even help a little bit when dealing with async functions - recently I've written:

async fn foo() {
    
}

fn bar(f: impl Future<Output=()>) {
    
}

fn main() {
    bar(foo);
}

... and it took me a few minutes to notice that what I actually wanted was bar(foo()).

@cramertj
Copy link
Member

@cramertj cramertj commented Jul 29, 2019

@Centril why was this tagged async-await?

Loading

@Centril
Copy link
Contributor

@Centril Centril commented Jul 29, 2019

@Centril why was this tagged async-await?

It may even help a little bit when dealing with async functions - recently I've written:

Loading

@cramertj
Copy link
Member

@cramertj cramertj commented Jul 30, 2019

I don't think that makes this an async/await issue in any way, though. 🤷‍♀️

Loading

@gilescope
Copy link
Contributor

@gilescope gilescope commented Jul 31, 2019

It's a great suggestion either way. Going to take a crack at it if I may?
@rustbot claim

Loading

@gilescope
Copy link
Contributor

@gilescope gilescope commented Aug 17, 2019

Move to close this as PR #63337 now merged in nightly fixes this:

   |
2  | fn foo() -> usize {
   | ----------------- fn() -> usize {foo} defined here
...
11 |     bar(foo);
   |         ^^^
   |         |
   |         expected usize, found fn item
   |         help: use parentheses to call this function: `foo()`
   |
   = note: expected type `usize`
              found type `fn() -> usize {foo}`

Loading

@gilescope
Copy link
Contributor

@gilescope gilescope commented Aug 17, 2019

@Centril thoughts?

Loading

@Centril
Copy link
Contributor

@Centril Centril commented Aug 17, 2019

The message for async/await is still bad:


error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> src/main.rs:10:5
   |
10 |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
note: required by `bar`
  --> src/main.rs:7:1
   |
7  | fn bar(f: impl Future<Output = ()>) {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Leaving this up to @estebank

Loading

@Patryk27
Copy link
Contributor Author

@Patryk27 Patryk27 commented Aug 17, 2019

IMO the {foo} defined here part looks weird (why curly braces?) - how about:

2  | fn foo() -> usize {
   | ----------------- function `fn() -> usize` (named `foo`) defined here

Loading

@estebank
Copy link
Contributor

@estebank estebank commented Aug 19, 2019

@Patryk27 I feel like fn foo() -> usize could also work and be more natural. At the same time, I'd like to unify how we refer to functions and closures (currently [closure@file.rs:LL:CC]), and I feel that the braces style is would be suitable for them: fn(_) -> _ {file.rs:LL::CC}.

Loading

@Patryk27
Copy link
Contributor Author

@Patryk27 Patryk27 commented Aug 20, 2019

@estebank Thanks, I understand - I'm not certain about curly braces in this position, since it changes their meaning though (from denoting block to denoting location, depending on whether it is part of code block or message) and thus, to me, they are kinda confusing.

IMO the fn(_) -> _ [file.rs:LL:CC] construct could be more legible, since brackets are not usually set together with functions (contrary to curly braces), so they stand out more.

Loading

@estebank
Copy link
Contributor

@estebank estebank commented Aug 24, 2019

#63870:

error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`

😊

Loading

Centril added a commit to Centril/rust that referenced this issue Aug 25, 2019
…trochenkov

Suggest calling closure with resolved return type when appropriate

Follow up to rust-lang#63337. CC rust-lang#63100.

```
error[E0308]: mismatched types
  --> $DIR/fn-or-tuple-struct-without-args.rs:46:20
   |
LL |     let closure = || 42;
   |                   -- closure defined here
LL |     let _: usize = closure;
   |                    ^^^^^^^
   |                    |
   |                    expected usize, found closure
   |                    help: use parentheses to call this closure: `closure()`
   |
   = note: expected type `usize`
              found type `[closure@$DIR/fn-or-tuple-struct-without-args.rs:45:19: 45:24]`
```
bors added a commit that referenced this issue Aug 30, 2019
Suggest call fn ctor passed as arg to fn with type param bounds

_Reviewer note: the relevant changes are in the second commit, the first is simple and mechanical, but verbose._

When forgetting to call a fn in an argument position to an fn that has a generic bound:

```rust
async fn foo() {}

fn bar(f: impl Future<Output=()>) {}

fn main() {
    bar(foo); // <- should be `bar(foo());`
}
```

suggest calling it:

```
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`
```

Fix #63100. Follow up to #63833 and #63337.
bors added a commit that referenced this issue Aug 31, 2019
Suggest call fn ctor passed as arg to fn with type param bounds

_Reviewer note: the relevant changes are in the second commit, the first is simple and mechanical, but verbose._

When forgetting to call a fn in an argument position to an fn that has a generic bound:

```rust
async fn foo() {}

fn bar(f: impl Future<Output=()>) {}

fn main() {
    bar(foo); // <- should be `bar(foo());`
}
```

suggest calling it:

```
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`
```

Fix #63100. Follow up to #63833 and #63337.
bors added a commit that referenced this issue Aug 31, 2019
Suggest call fn ctor passed as arg to fn with type param bounds

_Reviewer note: the relevant changes are in the second commit, the first is simple and mechanical, but verbose._

When forgetting to call a fn in an argument position to an fn that has a generic bound:

```rust
async fn foo() {}

fn bar(f: impl Future<Output=()>) {}

fn main() {
    bar(foo); // <- should be `bar(foo());`
}
```

suggest calling it:

```
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`
```

Fix #63100. Follow up to #63833 and #63337.
bors added a commit that referenced this issue Sep 1, 2019
Suggest call fn ctor passed as arg to fn with type param bounds

_Reviewer note: the relevant changes are in the second commit, the first is simple and mechanical, but verbose._

When forgetting to call a fn in an argument position to an fn that has a generic bound:

```rust
async fn foo() {}

fn bar(f: impl Future<Output=()>) {}

fn main() {
    bar(foo); // <- should be `bar(foo());`
}
```

suggest calling it:

```
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`
```

Fix #63100. Follow up to #63833 and #63337.
bors added a commit that referenced this issue Sep 1, 2019
Suggest call fn ctor passed as arg to fn with type param bounds

_Reviewer note: the relevant changes are in the second commit, the first is simple and mechanical, but verbose._

When forgetting to call a fn in an argument position to an fn that has a generic bound:

```rust
async fn foo() {}

fn bar(f: impl Future<Output=()>) {}

fn main() {
    bar(foo); // <- should be `bar(foo());`
}
```

suggest calling it:

```
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
   |
LL | fn bar(f: impl Future<Output=()>) {}
   | --------------------------------- required by `bar`
...
LL |     bar(foo);
   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
   |
   = help: it looks like you forgot to use parentheses to call the function: `foo()`
```

Fix #63100. Follow up to #63833 and #63337.
@bors bors closed this in dfd43f0 Sep 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

5 participants