Skip to content

Error about number of arguments, when number is correct but type is wrong #46295

New issue

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

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

Already on GitHub? # to your account

Closed
djmitche opened this issue Nov 27, 2017 · 6 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. WG-diagnostics Working group: Diagnostics

Comments

@djmitche
Copy link

I'm struggling with types in async code, and came across an error that was very misleading. I tried this code:

    fn run(&self) -> Box<Future<Item = (), Error = ()>> {
        let (writer, reader) = self.socket.framed(transport::new()).split();
        Box::new(
            writer
                .send_all(reader.and_then(move |req| future::ok(req)))
                .then(move |_| {
                    debug!("connection to neighbor {:?} closed", self.peer);
                    Ok(())
                })
                .then(|_: ()| Ok(())), // XXX                                                                                                                                                                                                                                               
        )
    }

I expected to see an error that my closure on the line annotated with "XXX" has the wrong argument type.

Instead, this happened:

error[E0593]: closure takes 0 arguments but 1 argument is required
  --> src/net/mod.rs:82:18
   |
82 |                 .then(|_: ()| Ok(())), // XXX
   |                  ^^^^ -------------- takes 0 arguments
   |                  |
   |                  expected closure that takes 1 argument

error[E0593]: closure takes 0 arguments but 1 argument is required
  --> src/net/mod.rs:75:9
   |
75 | /         Box::new(
76 | |             writer
77 | |                 .send_all(reader.and_then(move |req| future::ok(req)))
78 | |                 .then(move |_| {
...  |
82 | |                 .then(|_: ()| Ok(())), // XXX
   | |                       -------------- takes 0 arguments
83 | |         )
   | |_________^ expected closure that takes 1 argument
   |
   = note: required because of the requirements on the impl of `futures::Future` for `futures::Then<futures::Then<futures::sink::SendAll<futures::stream::SplitSink<tokio_io::codec::Framed<tokio_core::net::TcpStream, net::transport::Codec>>, futures::stream::AndThen<futures::stream::SplitStream<tokio_io::codec::Framed<tokio_core::net::TcpStream, net::transport::Codec>>, [closure@src/net/mod.rs:77:43: 77:69], futures::FutureResult<std::string::String, std::io::Error>>>, std::result::Result<(), _>, [closure@src/net/mod.rs:78:23: 81:18 self:_]>, std::result::Result<(), ()>, [closure@src/net/mod.rs:82:23: 82:37]>`
   = note: required for the cast to the object type `futures::Future<Error=(), Item=()>`

Meta

dustin@jemison ~/p/rubbish [issue14*] $ rustc --version --verbose
rustc 1.21.0 (3b72af97e 2017-10-09)
binary: rustc
commit-hash: 3b72af97e42989b2fe104d8edbaee123cdf7c58f
commit-date: 2017-10-09
host: x86_64-unknown-linux-gnu
release: 1.21.0
LLVM version: 4.0

/cc @Mark-Simulacrum

@Mark-Simulacrum
Copy link
Member

cc @estebank

Simpler reproduction, though still requiring the futures crate: https://play.rust-lang.org/?gist=2ff931e3b3f6ef7b7592d2d1f20a1e4c&version=stable

@djmitche
Copy link
Author

(BTW, the type should be Result<_, _>)

@Mark-Simulacrum
Copy link
Member

Never mind, my reduction is bogus and doesn't actually reproduce the problem.

@stephaneyfx
Copy link
Contributor

I think this is fixed in rust 1.22. The following code gives the same bogus error message about the closure arity with rust 1.21 but not with rust 1.22.
https://play.rust-lang.org/?gist=d23e25ef15d9732bd484c21f07656461&version=stable

fn main() {
    let x: Result<i32, ()> = Ok(1);
    x.map(|_: ()| ()).unwrap();
}

@estebank
Copy link
Contributor

@stephaneyfx thanks for the minimal repro. @djmitche, can you verify wether you see the same incorrect behaviour with your code in 1.22 or later? If you don't, we can close this ticket :)

Related to #42143, might have been fixed in #44735.

@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. WG-diagnostics Working group: Diagnostics labels Nov 27, 2017
@djmitche
Copy link
Author

Indeed, I now see

error[E0631]: type mismatch in closure arguments
  --> src/net/mod.rs:77:9
   |
77 | /         Box::new(
78 | |             writer
79 | |                 .send_all(reader.and_then(move |req| future::ok(req)))
80 | |                 .then(move |_| {
...  |
84 | |                 .then(|_: ()| Ok(())),
   | |                       -------------- found signature of `fn(()) -> _`
85 | |         )
   | |_________^ expected signature of `fn(std::result::Result<(), _>) -> _`

Awesome :)

@arielb1 arielb1 closed this as completed Nov 27, 2017
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

No branches or pull requests

5 participants