Skip to content

HRTB bounds not resolving correctly (take 2) #89196

Open

Description

This is similar to the resolved issue #85636 , but details a newer iteration of that problem that has not yet been fixed.

Code example
trait MiniYokeable<'a> {
    type Output;
}

struct MiniYoke<Y: for<'a> MiniYokeable<'a>> {
    pub yokeable: Y,
}

impl<Y> Clone for MiniYoke<Y>
where
    Y: for<'a> MiniYokeable<'a>,
    for<'a> <Y as MiniYokeable<'a>>::Output: Clone
{
    fn clone(&self) -> Self {
        todo!()
    }
}

trait MiniDataMarker {
    type Yokeable: for<'a> MiniYokeable<'a>;
}

trait MiniDataProvider<M>
where
    M: MiniDataMarker
{
    fn mini_load_payload(&self) -> MiniYoke<M::Yokeable>;
}

struct MiniStructProvider<M>
where
    M: MiniDataMarker,
{
    pub yoke: MiniYoke<M::Yokeable>,
}

impl<M> MiniDataProvider<M> for MiniStructProvider<M>
where
    M: MiniDataMarker,
    for<'a> <M::Yokeable as MiniYokeable<'a>>::Output: Clone,
{
    fn mini_load_payload(&self) -> MiniYoke<M::Yokeable> {
        self.yoke.clone()
    }
}

#[derive(Clone)]
struct SimpleStruct(pub u32);

impl<'a> MiniYokeable<'a> for SimpleStruct {
    type Output = SimpleStruct;
}

impl MiniDataMarker for SimpleStruct {
    type Yokeable = SimpleStruct;
}

fn main() {
    let provider = MiniStructProvider {
        yoke: MiniYoke {
            yokeable: SimpleStruct(42)
        }
    };

    let yoke: MiniYoke<SimpleStruct> = provider.mini_load_payload();
    assert_eq!(yoke.yokeable.0, 42);
}

(playpen)

This fails to compile on beta/nightly (stable does not have #85499 so we cannot expect this to compile) with:

error[E0599]: the method `mini_load_payload` exists for struct `MiniStructProvider<_>`, but its trait bounds were not satisfied
  --> src/main.rs:65:49
   |
30 | / struct MiniStructProvider<M>
31 | | where
32 | |     M: MiniDataMarker,
33 | | {
34 | |     pub yoke: MiniYoke<M::Yokeable>,
35 | | }
   | | -
   | | |
   | |_method `mini_load_payload` not found for this
   |   doesn't satisfy `MiniStructProvider<_>: MiniDataProvider<_>`
...
65 |       let yoke: MiniYoke<SimpleStruct> = provider.mini_load_payload();
   |                                                   ^^^^^^^^^^^^^^^^^ method cannot be called on `MiniStructProvider<_>` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `<_ as MiniYokeable<'a>>::Output: Clone`
           which is required by `MiniStructProvider<_>: MiniDataProvider<_>`

The trait is implemented here: for<'a> <SimpleStruct as MiniYokeable>::Output is just SimpleStruct, which implements Clone.

cc @jackh726 @sffc

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

Metadata

Assignees

No one assigned

    Labels

    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsA-typesystemArea: The type systemC-bugCategory: This is a bug.S-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.T-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

    Issue actions