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

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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