Using Cow with the Vec/slice ToOwned impl for creating a recursive type fails to typecheck due to overflow #38962

Open
sdroege opened this Issue Jan 10, 2017 · 1 comment

Projects

None yet

1 participant

@sdroege
sdroege commented Jan 10, 2017 edited

See the following code

use std::borrow::Cow;

// Does not work either: #[derive(Clone)]
enum Foo<'a> {
    // Does not work:
    Bar(Cow<'a, [Foo<'static>]>),
    // Works: Bar(Vec<Foo<'a>>),
    Baz(&'a str),
}

impl<'a> Clone for Foo<'a> {
    fn clone(&self) -> Self {
        unimplemented!();
    }
}

fn main() {}

This currently fails to compile with

error[E0275]: overflow evaluating the requirement `<[Foo<'a>] as std::borrow::ToOwned>::Owned`
 --> test.rs:5:9
  |
5 |     Bar(Cow<'a, [Foo<'a>]>),
  |         ^^^^^^^^^^^^^^^^^^^
  |
  = note: required because it appears within the type `Foo<'a>`
  = note: required because of the requirements on the impl of `std::borrow::ToOwned` for `[Foo<'a>]`
  = note: required because it appears within the type `std::borrow::Cow<'a, [Foo<'a>]>`
  = note: only the last field of a struct may have a dynamically sized type

However in the end the Cow here is just an enum that is either a &[Foo] or a Vec (the ToOwned instance of [T] uses Vec for the owned variant), both having a known size and thus this all should really work, or am I missing something?

Is this a bug, a missing feature or can't this possibly work?

@sdroege
sdroege commented Jan 11, 2017

Something like

    BarOwned(Vec<Foo<'static>>),
    BarBorrowed(&'a [Foo<'a>]),

Also works FWIW (and then implementing Clone accordingly). Is the compiler for whatever reason evaluating the plain [Foo<'static>] here, although the traits never use it directly?

Independent of that, I also see another problem here when using Cow: the lifetime of Foo. For the Borrowed variant of Cow it should be 'a (&'a [Foo<'a>]), for the Owned variant it should be 'static (i.e. Vec<Foo<'static>>, it's cloned after all). This does not seem to be possible at all currently

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