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

Compiler fails to identify type mismatch on function that returns impl Trait #60249

Open
jxs opened this issue Apr 25, 2019 · 1 comment
Open
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jxs
Copy link
Contributor

jxs commented Apr 25, 2019

the following function, added to tower-grpc hello world client example, to wrap the service connection setup, when used, the compiler fails to identify the type mismatch, () in the return type should be BoxBody

pub fn get_service() -> impl Future<
    Item = hello_world::client::Greeter<
        RequestModifier<Connection<TcpStream, DefaultExecutor, BoxBody>, ()>,
    >,
    Error = ConnectError<std::io::Error>,
> {
    let uri: http::Uri = format!("http://localhost:50051")
        .parse()
        .expect("could not parse grpc address as uri");
    let h2_settings = Default::default();
    let mut make_client = Connect::new(Dst, h2_settings, DefaultExecutor::current());

    make_client.make_service(()).map(|conn| {
        let conn = tower_request_modifier::Builder::new()
            .set_origin(uri)
            .build(conn)
            .unwrap();

        hello_world::client::Greeter::new(conn)
    })
}

and gives the following error:

error[E0599]: no method named `say_hello` found for type `hello_world::client::Greeter<tower_request_modifier::RequestModifier<tower_h2::client::connection::Connection<tokio_tcp::stream::TcpStream, tokio_executor::global::DefaultExecutor, tower_grpc::body::BoxBody>, ()>>` in the current scope
  --> src/main.rs:22:18
   |
22 |                 .say_hello(Request::new(HelloRequest {
   |                  ^^^^^^^^^
   |
  ::: /Volumes/data/dev/jxs/tower-error-example/target/debug/build/tower-error-example-5d3017ffe78d8a92/out/helloworld.rs:19:5
   |
19 |     pub struct Greeter<T> {
   |     --------------------- method `say_hello` not found for this
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `say_hello`, perhaps you need to implement it:
           candidate #1: `hello_world::server::Greeter`

but if the following code is added just before the function return:

        let hello = hello_world::client::Greeter::new(conn).say_hello(Request::new(HelloRequest {
            name: "What is in a name?".to_string(),
        }));

the error given by the compiler becomes a lot more useful:

error[E0271]: type mismatch resolving `<[closure@src/main.rs:67:38: 78:6 uri:_] as std::ops::FnOnce<(tower_h2::client::connection::Connection<tokio_tcp::stream::TcpStream, tokio_executor::global::DefaultExecutor, tower_grpc::body::BoxBody>,)>>::Output == hello_world::client::Greeter<tower_request_modifier::RequestModifier<tower_h2::client::connection::Connection<tokio_tcp::stream::TcpStream, tokio_executor::global::DefaultExecutor, tower_grpc::body::BoxBody>, ()>>`
  --> src/main.rs:55:25
   |
55 |   pub fn get_service() -> impl Future<
   |  _________________________^
56 | |     Item = hello_world::client::Greeter<
57 | |         RequestModifier<Connection<TcpStream, DefaultExecutor, BoxBody>, ()>,
58 | |     >,
59 | |     Error = ConnectError<std::io::Error>,
60 | | > {
   | |_^ expected struct `tower_grpc::body::BoxBody`, found ()

pushed the whole example here

thanks

@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 25, 2019
@estebank estebank added the D-confusing Diagnostics: Confusing error or lint that should be reworked. label Jan 8, 2020
@estebank
Copy link
Contributor

Current output, more context, none of it useful for this case:

error[E0599]: the method `say_hello` exists for struct `Greeter<RequestModifier<Connection<TcpStream, DefaultExecutor, BoxBody>, ()>>`, but its trait bounds were not satisfied
   |
  ::: .../tower-error-example/target/debug/build/tower-error-example-7aa5e3a34e8c258f/out/helloworld.rs:19:5
   |
19 |     pub struct Greeter<T> {
   |     --------------------- method `say_hello` not found for this struct
  --> src/main.rs:35:18
   |
35 |                 .say_hello(Request::new(HelloRequest {
   |                  ^^^^^^^^^ method cannot be called due to unsatisfied trait bounds
   |
  ::: .../tower-h2-aaf68b3c8982de4c/a3c958a/src/client/connection.rs:18:1
   |
18 | pub struct Connection<T, E, S>
   | ------------------------------ doesn't satisfy `_: Service<Request<()>>`
   |
  ::: .../tower-http-8b33967e083bb0de/e7ef6ef/tower-request-modifier/src/lib.rs:13:1
   |
13 | pub struct RequestModifier<T, B> {
   | --------------------------------
   | |
   | doesn't satisfy `<_ as Service<Request<()>>>::Response = Response<_>`
   | doesn't satisfy `_: Service<Request<()>>`
   |
   = note: the following trait bounds were not satisfied:
           `<RequestModifier<tower_h2::client::Connection<tokio::net::TcpStream, DefaultExecutor, BoxBody>, ()> as tower_service::Service<http::Request<()>>>::Response = http::Response<_>`
           `RequestModifier<tower_h2::client::Connection<tokio::net::TcpStream, DefaultExecutor, BoxBody>, ()>: tower_service::Service<http::Request<()>>`
           `tower_h2::client::Connection<tokio::net::TcpStream, DefaultExecutor, BoxBody>: tower_service::Service<http::Request<()>>`

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 A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants