Skip to content

Unsupported cyclic reference when implementing CoerceUnsized for pointer to wrapper #41936

Closed
@thepowersgang

Description

@thepowersgang

Encountered when forward-porting my kernel to latest nightly.

Implementing CoerceUnsized on a type that wraps a pointer to a wrapping type errors when there is also a struct that wraps an array in the same crate.

error[E0391]: unsupported cyclic reference between types/traits detected
 --> <anon>:8:19
  |
8 | struct LogDataBuf([u8;8]);
  |                   ^^^^^^^ cyclic reference
  |
note: the cycle begins when processing `LogDataBuf::0`...
 --> <anon>:8:19
  |
8 | struct LogDataBuf([u8;8]);
  |                   ^^^^^^^
note: ...which then requires const-evaluating `LogDataBuf::{{initializer}}`...
 --> <anon>:8:23
  |
8 | struct LogDataBuf([u8;8]);
  |                       ^
note: ...which then requires processing `LogDataBuf::{{initializer}}`...
 --> <anon>:8:23
  |
8 | struct LogDataBuf([u8;8]);
  |                       ^
note: ...which then requires coherence checking all impls of trait `std::ops::CoerceUnsized`...
note: ...which then requires processing `<impl at <anon>:15:1: 15:90>`...
 --> <anon>:15:1
  |
15| impl<T: ?Sized + marker::Unsize<U>, U: ?Sized> ops::CoerceUnsized<Aref<U>> for Aref<T> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires processing `ArefInner`...
 --> <anon>:17:1
  |
17| / struct ArefInner<T: ?Sized>
18| | {
19| |     // Even with this field commented out, the error is raised.
20| |     data: T,
21| | }
  | |_^
note: ...which then requires computing the variances for items in this crate...
  = note: ...which then again requires processing `LogDataBuf::0`, completing the cycle.
use std::{marker,ops};

// Change the array to a non-array, and error disappears
// Adding a new field to the end keeps the error
struct LogDataBuf([u8;8]);

struct Aref<T: ?Sized>
{
    // Inner structure triggers the error, removing the inner removes the message.
    ptr: Box<ArefInner<T>>,
}
impl<T: ?Sized + marker::Unsize<U>, U: ?Sized> ops::CoerceUnsized<Aref<U>> for Aref<T> {}

struct ArefInner<T: ?Sized>
{
    // Even with this field commented out, the error is raised.
    data: T,
}

Playground version
https://play.rust-lang.org/?gist=854452b1dea1fc197d3bd9d6b1848eed&version=nightly&backtrace=0

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions