Skip to content
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

Rust 1.19 regression: cyclic reference detected for rusttype #41849

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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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