Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
thepowersgang opened this issue May 12, 2017 · 3 comments
Assignees
Labels
A-type-system Area: Type system regression-from-stable-to-beta Performance or correctness regression from stable to beta.

Comments

@thepowersgang
Copy link
Contributor

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

@eddyb
Copy link
Member

eddyb commented May 12, 2017

This might be fixed by #41913, do you know if the latest nightly contains it?

EDIT: yes so it didn't get fixed. cc @nikomatsakis

@thepowersgang
Copy link
Contributor Author

Present in latest nightly on playpen, rustc 1.19.0-nightly (978d2cfee 2017-05-10), also in current nightly - rustc 1.19.0-nightly (e40beb3af 2017-05-11)

@kennytm
Copy link
Member

kennytm commented May 12, 2017

Still repro.

Error message, same as OP's
error: main function not found

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

error: aborting due to previous error
$ rustc -vV
rustc 1.19.0-nightly (e40beb3af 2017-05-11)
binary: rustc
commit-hash: e40beb3af162e676e40704854dd6547ee8d4cf60
commit-date: 2017-05-11
host: x86_64-apple-darwin
release: 1.19.0-nightly
LLVM version: 4.0

e40beb3 is the commit merging #41913.

@eddyb eddyb added the A-type-system Area: Type system label May 12, 2017
@nikomatsakis nikomatsakis added the regression-from-stable-to-beta Performance or correctness regression from stable to beta. label May 12, 2017
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue May 12, 2017
This seems both to be a safe, conservative choice,
and it sidesteps the cycle in rust-lang#41936.

Fixes rust-lang#41936.
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue May 12, 2017
…oerce-unsized-cycle, r=eddyb

use equality in the coerce-unsized check

This seems both to be a safe, conservative choice, and it sidesteps the cycle in rust-lang#41849. Note that, before I converted variance into proper queries, we were using a hybrid of subtyping and equality, due to the presence of a flag that forced invariance if variance had not yet been computed. (Also, Coerce Unsized is unstable.)

Fixes rust-lang#41936.

r? @eddyb
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue May 12, 2017
…oerce-unsized-cycle, r=eddyb

use equality in the coerce-unsized check

This seems both to be a safe, conservative choice, and it sidesteps the cycle in rust-lang#41849. Note that, before I converted variance into proper queries, we were using a hybrid of subtyping and equality, due to the presence of a flag that forced invariance if variance had not yet been computed. (Also, Coerce Unsized is unstable.)

Fixes rust-lang#41936.

r? @eddyb
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue May 15, 2017
This seems both to be a safe, conservative choice,
and it sidesteps the cycle in rust-lang#41936.

Fixes rust-lang#41936.
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue May 16, 2017
…oerce-unsized-cycle, r=eddyb

use equality in the coerce-unsized check

This seems both to be a safe, conservative choice, and it sidesteps the cycle in rust-lang#41849. Note that, before I converted variance into proper queries, we were using a hybrid of subtyping and equality, due to the presence of a flag that forced invariance if variance had not yet been computed. (Also, Coerce Unsized is unstable.)

Fixes rust-lang#41936.

r? @eddyb
nikomatsakis added a commit to nikomatsakis/rust that referenced this issue May 23, 2017
This seems both to be a safe, conservative choice,
and it sidesteps the cycle in rust-lang#41936.

Fixes rust-lang#41936.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-type-system Area: Type system regression-from-stable-to-beta Performance or correctness regression from stable to beta.
Projects
None yet
Development

No branches or pull requests

4 participants