-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Self-referential struct with Cow<[Self]>
as the last field errors
#89940
Comments
Cow
only works with Option
For some reason, it works when I do it without using ExamplesNot Working:use std::borrow::ToOwned;
struct Element<'a> {
arr: CowVec<'a, Element<'a>>,
}
impl Clone for Element<'_> {
fn clone(&self) -> Self { todo!() }
}
enum CowVec<'a, B>
where
B: 'a + Clone,
{
Borrowed(&'a [B]),
Owned(<[B] as ToOwned>::Owned),
} Changing Borrowed(&'a [B]),
- Owned(<[B] as ToOwned>::Owned),
+ Owned(Vec<B>),
} |
It also happens in a simpler example with the use std::borrow::Cow;
#[derive(Clone)]
struct Foo {
foo: Cow<'static, [Foo]>,
} This results in the following error: error[E0277]: the trait bound `[Foo]: ToOwned` is not satisfied in `Foo`
--> src/lib.rs:5:23
|
5 | foo: Cow<'static, [Foo]>,
| ^^^^^ within `Foo`, the trait `ToOwned` is not implemented for `[Foo]`
|
= help: the following implementations were found:
<[T] as ToOwned>
note: required because it appears within the type `Foo`
--> src/lib.rs:4:8
|
4 | struct Foo {
| ^^^
= note: slice and array elements must have `Sized` type
error[E0277]: the trait bound `[Foo]: ToOwned` is not satisfied in `Foo`
--> src/lib.rs:3:10
|
3 | #[derive(Clone)]
| ^^^^^ within `Foo`, the trait `ToOwned` is not implemented for `[Foo]`
|
= help: the following implementations were found:
<[T] as ToOwned>
note: required because it appears within the type `Foo`
--> src/lib.rs:4:8
|
4 | struct Foo {
| ^^^
note: required by a bound in `Clone`
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) |
This only seems to happen when the For example, this compiles (playground): use std::borrow::Cow;
#[derive(Clone)]
struct Foo<'a> {
children: Cow<'a, [Self]>,
_foo: (),
} But this does not (playground): use std::borrow::Cow;
#[derive(Clone)]
struct Foo<'a> {
children: Cow<'a, [Self]>,
} It almost looks like the compiler is wrongly determining that the second If you write it out like this: use std::borrow::Cow;
struct Foo<'a> {
children: Cow<'a, [Self]>,
}
impl<'a> Clone for Foo<'a> {
fn clone(&self) -> Self {
let children = match self.children {
Cow::Owned(x) => Cow::Owned(x.clone()),
Cow::Borrowed(x) => Cow::Borrowed(x),
};
Self { children }
}
} You get the last compiler error pointing at an unsatisfied
|
This also affects enums. #[derive(Clone)]
enum Element {
First( Cow<'static, [Element]>)
} gives
And the trick of adding a field works also: #[derive(Clone)]
enum Element {
First( Cow<'static, [Element]>, ())
} Compiles (playground ) |
Cow
only works with Option
Cow<Self>
as the last field errors
Cow<Self>
as the last field errorsCow<[Self]>
as the last field errors
This gave a requirement evaluation overflow error on 1.48; 1.49 changed it to the snippetuse std::borrow::ToOwned;
#[derive(Clone)]
pub enum Test {
Owned(<[Test] as ToOwned>::Owned),
} 1.48
1.49
From the release notes, compatibility note Trait bounds are no longer inferred for associated types. seems highly relevant. @rustbot modify labels: +D-confusing +D-incorrect +A-traits +E-needs-mcve Also suggesting
regression-from-stable-to-stable
Two more interesting observations: defining It appears that the underlying issue preventing this from working is that the field projection is not known to be Replicating this without std involvement will help. Note this seems to require two crates, which makes this significantly more interesting. |
I tried this code:
Compiling it, I got these errors:
(this is presumably because there is a reference to the
struct
)A "fix"
Changing line 4 to use an
Option
works for no obvious reason, and will also add an extra cost to using the field:Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: