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

thir-unsafeck query loops on closures in const-generics #87414

Closed
syvb opened this issue Jul 23, 2021 · 1 comment · Fixed by #87645
Closed

thir-unsafeck query loops on closures in const-generics #87414

syvb opened this issue Jul 23, 2021 · 1 comment · Fixed by #87645
Assignees
Labels
-Zthir-unsafeck Unstable option: THIR unsafeck C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@syvb
Copy link
Contributor

syvb commented Jul 23, 2021

I tried this code with -Z thir-unsafeck=on:

fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
fn main() {}

I expected to see this happen: It compiles, as it does under the MIR checker

Instead, this happened:

error[E0391]: cycle detected when simplifying constant for the type system `bad::{constant#0}`
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires simplifying constant for the type system `bad::{constant#0}`...
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `bad::{constant#0}`...
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `bad::{constant#0}`...
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `bad::{constant#0}`...
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `bad::{constant#0}`...
 --> y.rs:1:45
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                             ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `bad::{constant#0}::{closure#0}`...
 --> y.rs:1:47
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                               ^^^^^^^^
note: ...which requires building MIR for `bad::{constant#0}::{closure#0}`...
 --> y.rs:1:47
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                               ^^^^^^^^
note: ...which requires unsafety-checking `bad::{constant#0}::{closure#0}`...
 --> y.rs:1:47
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  |                                               ^^^^^^^^
note: ...which requires unsafety-checking `bad`...
 --> y.rs:1:1
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building THIR for `bad`...
 --> y.rs:1:1
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `bad`...
 --> y.rs:1:1
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which again requires simplifying constant for the type system `bad::{constant#0}`, completing the cycle
note: cycle used when checking that `bad` is well-formed
 --> y.rs:1:1
  |
1 | fn bad<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> { todo!() }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Meta

rustc --version --verbose:

$ rustc +local --version --verbose
rustc 1.55.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.55.0-dev
LLVM version: 12.0.1

@syvb syvb added the C-bug Category: This is a bug. label Jul 23, 2021
@FabianWolff
Copy link
Contributor

Reduced (either of the following two functions reproduces the issue):

fn foo() -> [(); { |x: u32| { x }; 4 }] { todo!() }
fn bar() { let _: [(); { |x: u32| { x }; 4 }]; }

This is caused by the fact that closures are handled by their owner:

// Closures are handled by their owner, if it has a body
if tcx.is_closure(def.did.to_def_id()) {
let owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let owner_hir_id = tcx.hir().local_def_id_to_hir_id(owner);
if tcx.hir().maybe_body_owned_by(owner_hir_id).is_some() {
tcx.ensure().thir_check_unsafety(owner);
return;
}
}

@rustbot claim

@LeSeulArtichaut LeSeulArtichaut added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. -Zthir-unsafeck Unstable option: THIR unsafeck requires-nightly This issue requires a nightly compiler in some way. labels Jul 26, 2021
JohnTitor added a commit to JohnTitor/rust that referenced this issue Aug 3, 2021
Properly find owner of closure in THIR unsafeck

Previously, when encountering a closure in a constant, the THIR unsafeck gets invoked on the owner of the constant instead of the constant itself, producing cycles.
Supersedes rust-lang#87492. `@FabianWolff` thanks for your work on that PR, I copied your test file and added you as a co-author.

Fixes rust-lang#87414.
r? `@oli-obk`
JohnTitor added a commit to JohnTitor/rust that referenced this issue Aug 3, 2021
Properly find owner of closure in THIR unsafeck

Previously, when encountering a closure in a constant, the THIR unsafeck gets invoked on the owner of the constant instead of the constant itself, producing cycles.
Supersedes rust-lang#87492. ``@FabianWolff`` thanks for your work on that PR, I copied your test file and added you as a co-author.

Fixes rust-lang#87414.
r? ``@oli-obk``
@bors bors closed this as completed in 345862d Aug 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-Zthir-unsafeck Unstable option: THIR unsafeck C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
3 participants