Skip to content

Rust 1.66 broke warp impl Reply on return types #107729

Open
@jxs

Description

@jxs

Hi there,
we just noticed on warp CI that one of the examples was broken (we have #![deny(warnings)] for the examples). The output is as follows:

warning: opaque type `impl warp::Filter + warp::filter::FilterBase<Extract = impl Reply, Error = Rejection> + Clone` does not satisfy its associated type bounds
  --> examples/todos.rs:39:22
   |
39 |     ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
  ::: /home/jxs/dev/oss/warp/src/filter/mod.rs:40:19
   |
40 |     type Extract: Tuple; // + Send;
   |                   ----- this associated type bound is unsatisfied for `impl Reply`
   |
   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
help: add this bound
   |
39 |     ) -> impl Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
   |                                                 ++++++++++++++++++++++

warning: opaque type `impl warp::Filter + warp::filter::FilterBase<Extract = impl Reply, Error = Rejection> + Clone` does not satisfy its associated type bounds
  --> examples/todos.rs:49:22
   |
49 |     ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
  ::: /home/jxs/dev/oss/warp/src/filter/mod.rs:40:19
   |
40 |     type Extract: Tuple; // + Send;
   |                   ----- this associated type bound is unsatisfied for `impl Reply`
   |
help: add this bound
   |
49 |     ) -> impl Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
   |                                                 ++++++++++++++++++++++

warning: opaque type `impl warp::Filter + warp::filter::FilterBase<Extract = impl Reply, Error = Rejection> + Clone` does not satisfy its associated type bounds
  --> examples/todos.rs:60:22
   |
60 |     ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
  ::: /home/jxs/dev/oss/warp/src/filter/mod.rs:40:19
   |
40 |     type Extract: Tuple; // + Send;
   |                   ----- this associated type bound is unsatisfied for `impl Reply`
   |
help: add this bound
   |
60 |     ) -> impl Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
   |                                                 ++++++++++++++++++++++

warning: opaque type `impl warp::Filter + warp::filter::FilterBase<Extract = impl Reply, Error = Rejection> + Clone` does not satisfy its associated type bounds
  --> examples/todos.rs:71:22
   |
71 |     ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
  ::: /home/jxs/dev/oss/warp/src/filter/mod.rs:40:19
   |
40 |     type Extract: Tuple; // + Send;
   |                   ----- this associated type bound is unsatisfied for `impl Reply`
   |
help: add this bound
   |
71 |     ) -> impl Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
   |                                                 ++++++++++++++++++++++

warning: opaque type `impl warp::Filter + warp::filter::FilterBase<Extract = impl Reply, Error = Rejection> + Clone` does not satisfy its associated type bounds
  --> examples/todos.rs:82:22
   |
82 |     ) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
  ::: /home/jxs/dev/oss/warp/src/filter/mod.rs:40:19
   |
40 |     type Extract: Tuple; // + Send;
   |                   ----- this associated type bound is unsatisfied for `impl Reply`
   |
help: add this bound
   |
82 |     ) -> impl Filter<Extract = impl warp::Reply + warp::generic::Tuple, Error = warp::Rejection> + Clone {
   |                                                 ++++++++++++++++++++++

It seems to have been introduced with Rust version 1.66 as with 1.65 the example compiles fine. I also tried with the latest nightly (cargo 1.69.0-nightly (e84a7928d 2023-01-31)) which still reproduces the problem. This feels like a bug as it being a warning doesn't provide help, btw warp::generic::Tuple is private.
The todos example should work as a MRE, but if required I can try to provide a simpler use case.

Thanks!

Activity

added
C-bugCategory: This is a bug.
on Feb 6, 2023
clubby789

clubby789 commented on Feb 6, 2023

@clubby789
Contributor

searched nightlies: from nightly-2022-10-01 to nightly-2023-01-01
regressed nightly: nightly-2022-10-05
searched commit range: f83e026...01af504
regressed commit: 02cd79a

bisected with cargo-bisect-rustc v0.6.5

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc 2022-10-01 --end 2023-01-01 

The lint was introduced in #102568

compiler-errors

compiler-errors commented on Feb 6, 2023

@compiler-errors
Member

Hey, yeah so I authored that warning. Sorry that it's so vague.

So the gist is that Extract requires the associate type to implement Tuple, but impl Reply doesn't implement Tuple though, at least not the public-facing side of the type. This is code that only compiles due to a hack in the compiler. We could downgrade the lint, I guess, but that just masks the issue that the impl Filter<...> still is not "valid".

The suggestion kinda sucks, because yeah, Tuple is unreachable, but the underlying issue still remains I think.

cc @oli-obk, maybe you have additional or different thoughts about this lint.

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.
on Feb 6, 2023
added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Feb 6, 2023
jonas-schievink

jonas-schievink commented on Feb 7, 2023

@jonas-schievink
Contributor

Hmm, why should code like this be rejected? The caller knows that the opaque type meets the bounds because the bound is on the associated type in the first place (and the function compiles, so whatever type it used there must meet the bound).

If anything it's weird that the equivalent -> RequiresTuple<impl Reply> doesn't compile, no? (where struct RequiresTuple<T: Tuple>(T);)

oli-obk

oli-obk commented on Feb 7, 2023

@oli-obk
Contributor

It makes sense from inside the body of the function, but from the outside it is a bit weird: impl Reply does not implement Tuple (since Tuple is not a super trait of Reply), so the bound on the RequiresTuple struct doesn't hold.

apiraino

apiraino commented on Feb 14, 2023

@apiraino
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium

added and removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Feb 14, 2023
ThomasHabets

ThomasHabets commented on Feb 20, 2023

@ThomasHabets

I encountered this warning. Everything seems to be working, but I want to fix the warning.

Could someone explain how to fix this, as if I've only used Rust for a week and this is happening in the first real program I write in it?

compiler-errors

compiler-errors commented on Feb 20, 2023

@compiler-errors
Member

You can replace Extract = impl warp::Reply with Extract = (impl warp::Reply,), I think.

See: seanmonstar/warp#1020 (comment)

ThomasHabets

ThomasHabets commented on Feb 20, 2023

@ThomasHabets

Indeed that gets rid of the warning. Thanks! I would not have guessed this solution.

olix0r

olix0r commented on Feb 27, 2023

@olix0r

May I ask why this warning is desirable? Let's say I have a function like

fn svc() -> impl Service<Request<Body>, Response = Response<Body>, Error = Error, Future = impl Send> {
  // ...
}

This warning prefers this as:

fn svc() -> impl Service<Request<Body>, Response = Response<Body>, Error = Error, Future = impl Future<Output = Result<Response<Body>, Error>> + Send> {
  // ...
}

This feels like needless boilerplate in our application -- it's obvious that the Future type attribute has to implement Future. Why is it desirable that this be made explicit everywhere the type is referenced?

olix0r

olix0r commented on Feb 27, 2023

@olix0r

Actually, what I wrote above is not correct. We are apparently unable to satisfy the proper Future bounds?

See @hawkw's comment on linkerd/linkerd2-proxy#2275:

Unfortunately, we cannot simply change our code to make the trait bound's type explicit, as changing impl Send to
impl Future<...> + Send in this position results in a surprising error which I don't think is correct:

error[E0277]: `impl std::marker::Send` is not a future
  --> linkerd/app/outbound/src/http/logical.rs:97:30
   |
97 |                     Future = impl Future<Output = Result<http::Response<http::BoxBody>, Error>> + Send,
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `impl std::marker::Send` is not a future
   |
   = help: the trait `futures::Future` is not implemented for `impl std::marker::Send`
   = note: impl std::marker::Send must be a future or must implement `IntoFuture` to be awaited
   = note: required for `stack::map_err::ResponseFuture<(), impl std::marker::Send>` to implement `futures::Future`

For more information about this error, try `rustc --explain E0277`.

See linkerd/linkerd2-proxy#2268 (comment) for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ThomasHabets@olix0r@oli-obk@jxs@jonas-schievink

        Issue actions

          Rust 1.66 broke warp impl Reply on return types · Issue #107729 · rust-lang/rust