Skip to content

Cycle detected when computing type, but only when function is const #112602

Closed
@K4rakara

Description

@K4rakara

I tried this code:

pub struct Parser<H>(H);

impl<H, T> Parser<H>
where
    H: for<'a> Fn(&'a str) -> T,
{
    pub const fn new(handler: H) -> Parser<H> {
        Parser(handler)
    }

    pub const fn many<'s>(
        &'s self,
    ) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
        Parser::new(|_| unimplemented!())
    }
}

fn main() {
    println!("Hello, world!");
}

Which causes the following error:

error[E0391]: cycle detected when computing type of `<impl at src/main.rs:3:1: 3:21>::many::{opaque#0}`
  --> src/main.rs:13:17
   |
13 |     ) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: ...which requires borrow-checking `<impl at src/main.rs:3:1: 3:21>::many`...
  --> src/main.rs:11:5
   |
11 | /     pub const fn many<'s>(
12 | |         &'s self,
13 | |     ) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
   | |________________________________________________________^
note: ...which requires const checking `<impl at src/main.rs:3:1: 3:21>::many`...
  --> src/main.rs:11:5
   |
11 | /     pub const fn many<'s>(
12 | |         &'s self,
13 | |     ) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
   | |________________________________________________________^
   = note: ...which requires computing whether `Parser<<impl at src/main.rs:3:1: 3:21>::many::{opaque#0}>` is freeze...
   = note: ...which requires evaluating trait selection obligation `Parser<<impl at src/main.rs:3:1: 3:21>::many::{opaque#0}>: core::marker::Freeze`...
   = note: ...which again requires computing type of `<impl at src/main.rs:3:1: 3:21>::many::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
  --> src/main.rs:1:1
   |
1  | / pub struct Parser<H>(H);
2  | |
3  | | impl<H, T> Parser<H>
4  | | where
...  |
19 | |     println!("Hello, world!");
20 | | }
   | |_^

For more information about this error, try `rustc --explain E0391`.
error: could not compile `miri-cycle` (bin "miri-cycle") due to previous error

However, what is peculiar is that if you remove the const keyword from the many function, compilation succeeds, with absolutely no warnings or errors.

Meta

rustc --version --verbose:

rustc 1.72.0-nightly (df77afbca 2023-06-12)
binary: rustc
commit-hash: df77afbcaf3365a32066a8ca4a00ae6fc9a69647
commit-date: 2023-06-12
host: x86_64-unknown-linux-gnu
release: 1.72.0-nightly
LLVM version: 16.0.5

No backtrace is emitted when I use RUST_BACKTRACE=1 cargo build.

Metadata

Metadata

Assignees

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-cycleIssue: A query cycle occurred while none was expectedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions