Skip to content

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

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

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions