Skip to content

Rust 1.19 regression: cyclic reference detected for rusttype #41849

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
azriel91 opened this issue May 9, 2017 · 5 comments
Closed

Rust 1.19 regression: cyclic reference detected for rusttype #41849

azriel91 opened this issue May 9, 2017 · 5 comments
Assignees
Labels
P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@azriel91
Copy link
Contributor

azriel91 commented May 9, 2017

Prior to rustc 1.19.0-nightly (f1140a331 2017-05-08), rusttype 0.2.1 could compile okay. Now it gives the following error:

   Compiling rusttype v0.2.1
error[E0391]: unsupported cyclic reference between types/traits detected
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:5
   |
47 |     keys: [K; CAPACITY],
   |     ^^^^^^^^^^^^^^^^^^^ cyclic reference
   |
note: the cycle begins when processing `support::bst::node::LeafNode::keys`...

# ... full output in the Details section below ...

Steps to reproduce:

cargo init mytest
cd mytest
echo 'rusttype = "0.2.1"' >> Cargo.toml
cargo build

A minimal example that reproduces this (playpen's nightly is still on f4209651e 2017-05-05 so it compiles):

use std::ops::Mul;

const C: usize = 1;
const CAPACITY: usize = 1 * C;

struct A<X> {
    f: [X; CAPACITY],
}

struct B<T> {
    f: T,
}

impl<T> Mul for B<T> {
    type Output = Self;
    fn mul(self, _rhs: B<T>) -> Self::Output {
        self
    }
}

impl<T> Mul<usize> for B<T> {
    type Output = Self;
    fn mul(self, _rhs: usize) -> Self::Output {
        self
    }
}

fn main() {
    let a = A { f: [1] };
    let _ = B { f: a };
}

I have no idea why that reproduces it; I broke my brain coming up with that code.

My rustc version:

$ rustc --version --verbose
rustc 1.19.0-nightly (f1140a331 2017-05-08)
binary: rustc
commit-hash: f1140a33176a5fb2e91e26ea3ae42a834dd9bfdf
commit-date: 2017-05-08
host: x86_64-pc-windows-msvc
release: 1.19.0-nightly
LLVM version: 4.0

This is also seen on linux and OS X, such as in this travis build

$ cargo build
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling odds v0.2.25
   Compiling linked-hash-map v0.0.10
   Compiling byteorder v0.4.2
   Compiling stb_truetype v0.2.1
   Compiling nodrop v0.1.9
   Compiling arrayvec v0.3.23
   Compiling rusttype v0.2.1
error[E0391]: unsupported cyclic reference between types/traits detected
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:5
   |
47 |     keys: [K; CAPACITY],
   |     ^^^^^^^^^^^^^^^^^^^ cyclic reference
   |
note: the cycle begins when processing `support::bst::node::LeafNode::keys`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:5
   |
47 |     keys: [K; CAPACITY],
   |     ^^^^^^^^^^^^^^^^^^^
note: ...which then requires const-evaluating `support::bst::node::LeafNode::{{initializer}}`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:15
   |
47 |     keys: [K; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires processing `support::bst::node::LeafNode::{{initializer}}`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:15
   |
47 |     keys: [K; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:15
   |
47 |     keys: [K; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires coherence checking all impls of trait `std::ops::Mul`...
note: ...which then requires processing `geometry::Vector`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\geometry.rs:27:1
   |
27 | / pub struct Vector<N> {
28 | |     pub x: N,
29 | |     pub y: N
30 | | }
   | |_^
note: ...which then requires computing the variances for items in this crate...
   = note: ...which then again requires processing `support::bst::node::LeafNode::keys`, completing the cycle.

error[E0391]: unsupported cyclic reference between types/traits detected
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:15
   |
48 |     vals: [V; CAPACITY],
   |               ^^^^^^^^ cyclic reference
   |
note: the cycle begins when processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:47:15
   |
47 |     keys: [K; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires coherence checking all impls of trait `std::ops::Mul`...
note: ...which then requires processing `geometry::Vector`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\geometry.rs:27:1
   |
27 | / pub struct Vector<N> {
28 | |     pub x: N,
29 | |     pub y: N
30 | | }
   | |_^
note: ...which then requires computing the variances for items in this crate...
note: ...which then requires processing `support::bst::node::LeafNode::vals`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:5
   |
48 |     vals: [V; CAPACITY],
   |     ^^^^^^^^^^^^^^^^^^^
note: ...which then requires const-evaluating `support::bst::node::LeafNode::{{initializer}}`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:15
   |
48 |     vals: [V; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires processing `support::bst::node::LeafNode::{{initializer}}`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:15
   |
48 |     vals: [V; CAPACITY],
   |               ^^^^^^^^
   = note: ...which then again requires processing `support::bst::node::CAPACITY`, completing the cycle.

error[E0391]: unsupported cyclic reference between types/traits detected
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference
   |
note: the cycle begins when processing `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:44:1
   |
44 | pub const CAPACITY: usize = 2 * B - 1;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which then requires coherence checking all impls of trait `std::ops::Mul`...
note: ...which then requires processing `geometry::Vector`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\geometry.rs:27:1
   |
27 | / pub struct Vector<N> {
28 | |     pub x: N,
29 | |     pub y: N
30 | | }
   | |_^
note: ...which then requires computing the variances for items in this crate...
note: ...which then requires processing `support::bst::node::LeafNode::vals`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:5
   |
48 |     vals: [V; CAPACITY],
   |     ^^^^^^^^^^^^^^^^^^^
note: ...which then requires const-evaluating `support::bst::node::LeafNode::{{initializer}}`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:15
   |
48 |     vals: [V; CAPACITY],
   |               ^^^^^^^^
note: ...which then requires const-evaluating `support::bst::node::CAPACITY`...
  --> C:\Users\azrie\.cargo\registry\src\github.heygears.com-1ecc6299db9ec823\rusttype-0.2.1\src\support\bst\node.rs:48:15
   |
48 |     vals: [V; CAPACITY],
   |               ^^^^^^^^
   = note: ...which then again requires processing `support::bst::node::CAPACITY`, completing the cycle.

error: aborting due to 3 previous errors

error: Could not compile `rusttype`.

To learn more, run the command again with --verbose.
@hanna-kruppe
Copy link
Contributor

cc @nikomatsakis looks like fallout from a recent query-fication.

@nikomatsakis nikomatsakis added regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 9, 2017
@nikomatsakis
Copy link
Contributor

triage: P-high

@rust-highfive rust-highfive added the P-high High priority label May 9, 2017
@Mark-Simulacrum
Copy link
Member

Bisected to 42a4f37 -- rollup #41773, probably #41734. (confirming that it's probably fallout from queryfication).

@nikomatsakis
Copy link
Contributor

Hmm. So the problem is, more specifically, due to the fact that I removed the hacky "variance-computed-yet?" flag. The proper fix is for equality relations to ignore variance, I think. PR coming up. Thanks @Mark-Simulacrum for that handy tool btw!

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue May 11, 2017
Fixes rust-lang#41849. Problem was that evaluating the constant expression
required evaluating a trait, which would equate types, which would
request variance information, which it would then discard. However,
computing the variance information would require determining the type of
a field, which would evaluate the constant expression.

(This problem will potentially arise *later* as we move to more sophisticated
constants, however, where we need to check subtyping. We can tackle that
when we come to it.)
@nikomatsakis
Copy link
Contributor

Fix in #41913

bors added a commit that referenced this issue May 11, 2017
do not fetch variance for items when equating

Fixes #41849. Problem was that evaluating the constant expression
required evaluating a trait, which would equate types, which would
request variance information, which it would then discard. However,
computing the variance information would require determining the type of
a field, which would evaluate the constant expression.

(This problem will potentially arise *later* as we move to more sophisticated
constants, however, where we need to check subtyping. We can tackle that
when we come to it.)

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
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 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
Fixes rust-lang#41849. Problem was that evaluating the constant expression
required evaluating a trait, which would equate types, which would
request variance information, which it would then discard. However,
computing the variance information would require determining the type of
a field, which would evaluate the constant expression.

(This problem will potentially arise *later* as we move to more sophisticated
constants, however, where we need to check subtyping. We can tackle that
when we come to it.)
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants