Overflow evaluating the requirement with references

Why doesn't it compile:

trait Awesome {}

struct Foo<S>
where
    for<'a> &'a mut S: Awesome,
{
    s: S,
}

impl<S> Foo<S>
where
    for<'a> &'a mut S: Awesome,
{
    pub fn new(s: S) -> Foo<S> {
        Foo { s }   
    }
}

impl<S> Awesome for &mut Foo<S> where for<'a> &'a mut S: Awesome {}

Error:

error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Foo<_>: Awesome`
  --> src/xxxxxxx.rs:15:9
   |
15 |         Foo { s }
   |         ^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`shadow_proxy`)
note: required for `&'a mut Foo<Foo<_>>` to implement `for<'a> Awesome`
  --> src/xxxxx.rs:19:9
   |
19 | impl<S> Awesome for &mut Foo<S> where for<'a> &'a mut S: Awesome {}
   |         ^^^^^^^     ^^^^^^^^^^^
   = note: 127 redundant requirements hidden
   = note: required for `&'a mut Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `for<'a> Awesome`
note: required by a bound in `Foo`
  --> src/xxxxxx/:5:24
   |
3  | struct Foo<S>
   |        --- required by a bound in this
4  | where
5  |     for<'a> &'a mut S: Awesome,
   |                        ^^^^^^^ required by this bound in `Foo`

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

I don't understand why for evaluating if Foo<S> is Awesome, it tries to evaluate if Foo<Foo<S>> is awesome, when the constraint just says &mut S should be Awesome....

Changing the constraints to something simpler like S: Awesome makes the error go away. No idea why a reference makes a difference here.

If you remove the bound on the struct definition you can get slightly further.

Weirdly if you try to use new the error pops back up, unless you manually specify the type of Foo's type parameter, even though there's only one possible type there in my example? I'm not entirely sure that's about

Playground

trait Awesome {}

struct Foo<S>
{
    s: S,
}

impl<S> Foo<S>
where
    for<'a> &'a mut S: Awesome,
{
    pub fn new(s: S) -> Foo<S> {
        Foo { s }   
    }
}

impl<S> Awesome for &mut Foo<S> where for<'a> &'a mut S: Awesome {}

impl Awesome for &mut String { }

fn main() {
    // Fails
    // Foo::new("Hello!".to_string());

    // Fails
    // awesome(Foo::<String>::new("Hello!".to_string()));
    
    // Succeeds
    awesome::<Foo<String>>(Foo::<String>::new("Hello!".to_string()));
}

fn awesome<T>(_: T) where for<'a> &'a mut T: Awesome { }

This feels like a bug to me

You'll have to fix your playground link - it normalizes the address bar now (which I hope is just a bug or is otherwise rolled back).

1 Like

Oh oops, that'll teach me to not check my links

Thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.