Skip to content

Commit 2101271

Browse files
committed
Add regression test
1 parent 921f669 commit 2101271

File tree

5 files changed

+178
-0
lines changed

5 files changed

+178
-0
lines changed

tests/ui/consts/const-fn-cycle.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// Discovered in https://github.com/rust-lang/rust/issues/112602.
2+
/// This caused a cycle error, which made no sense.
3+
/// Removing the `const` part of the `many` function would make the
4+
/// test pass again.
5+
/// The issue was that we were running const qualif checks on
6+
/// `const fn`s, but never using them. During const qualif checks we tend
7+
/// to end up revealing opaque types (the RPIT in `many`'s return type),
8+
/// which can quickly lead to cycles.
9+
10+
pub struct Parser<H>(H);
11+
12+
impl<H, T> Parser<H>
13+
where
14+
H: for<'a> Fn(&'a str) -> T,
15+
{
16+
pub const fn new(handler: H) -> Parser<H> {
17+
Parser(handler)
18+
}
19+
20+
pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
21+
//~^ ERROR: cycle detected
22+
Parser::new(|_| unimplemented!())
23+
}
24+
}
25+
26+
fn main() {
27+
println!("Hello, world!");
28+
}

tests/ui/consts/const-fn-cycle.stderr

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0391]: cycle detected when computing type of `<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many::{opaque#0}`
2+
--> $DIR/const-fn-cycle.rs:20:47
3+
|
4+
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires borrow-checking `<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many`...
8+
--> $DIR/const-fn-cycle.rs:20:5
9+
|
10+
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many`...
13+
--> $DIR/const-fn-cycle.rs:20:5
14+
|
15+
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
note: ...which requires const checking `<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many`...
18+
--> $DIR/const-fn-cycle.rs:20:5
19+
|
20+
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
= note: ...which requires computing whether `Parser<<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many::{opaque#0}>` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `Parser<<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many::{opaque#0}>: core::marker::Freeze`...
24+
= note: ...which again requires computing type of `<impl at $DIR/const-fn-cycle.rs:12:1: 12:21>::many::{opaque#0}`, completing the cycle
25+
note: cycle used when checking item types in top-level module
26+
--> $DIR/const-fn-cycle.rs:1:1
27+
|
28+
LL | / /// Discovered in https://github.com/rust-lang/rust/issues/112602.
29+
LL | | /// This caused a cycle error, which made no sense.
30+
LL | | /// Removing the `const` part of the `many` function would make the
31+
LL | | /// test pass again.
32+
... |
33+
LL | | println!("Hello, world!");
34+
LL | | }
35+
| |_^
36+
37+
error: aborting due to previous error
38+
39+
For more information about this error, try `rustc --explain E0391`.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
2+
--> $DIR/const-promoted-opaque.rs:13:12
3+
|
4+
LL | type Foo = impl Sized;
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires borrow-checking `FOO`...
8+
--> $DIR/const-promoted-opaque.rs:20:1
9+
|
10+
LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
11+
| ^^^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `FOO`...
13+
--> $DIR/const-promoted-opaque.rs:20:1
14+
|
15+
LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
16+
| ^^^^^^^^^^^^^^
17+
note: ...which requires const checking `FOO`...
18+
--> $DIR/const-promoted-opaque.rs:20:1
19+
|
20+
LL | const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
21+
| ^^^^^^^^^^^^^^
22+
= note: ...which requires computing whether `Foo` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`...
24+
= note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
25+
note: cycle used when checking item types in top-level module
26+
--> $DIR/const-promoted-opaque.rs:2:1
27+
|
28+
LL | / #![feature(type_alias_impl_trait)]
29+
LL | |
30+
LL | | //! Check that we do not cause cycle errors when trying to
31+
LL | | //! obtain information about interior mutability of an opaque type.
32+
... |
33+
LL | | let _: &'static _ = &FOO;
34+
LL | | }
35+
| |_^
36+
37+
error: aborting due to previous error
38+
39+
For more information about this error, try `rustc --explain E0391`.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// revisions: string unit atomic
2+
#![feature(type_alias_impl_trait)]
3+
4+
//! Check that we do not cause cycle errors when trying to
5+
//! obtain information about interior mutability of an opaque type.
6+
//! This used to happen, because when the body-analysis failed, we
7+
//! checked the type instead, but the constant was also defining the
8+
//! hidden type of the opaque type. Thus we ended up relying on the
9+
//! result of our analysis to compute the result of our analysis.
10+
11+
//[unit] check-pass
12+
13+
type Foo = impl Sized;
14+
//[string,atomic]~^ ERROR cycle detected
15+
16+
#[cfg(string)]
17+
const FOO: Foo = String::new();
18+
19+
#[cfg(atomic)]
20+
const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
21+
22+
#[cfg(unit)]
23+
const FOO: Foo = ();
24+
25+
const BAR: () = {
26+
let _: &'static _ = &FOO;
27+
};
28+
29+
const BAZ: &Foo = &FOO;
30+
31+
fn main() {
32+
let _: &'static _ = &FOO;
33+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
2+
--> $DIR/const-promoted-opaque.rs:13:12
3+
|
4+
LL | type Foo = impl Sized;
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires borrow-checking `FOO`...
8+
--> $DIR/const-promoted-opaque.rs:17:1
9+
|
10+
LL | const FOO: Foo = String::new();
11+
| ^^^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `FOO`...
13+
--> $DIR/const-promoted-opaque.rs:17:1
14+
|
15+
LL | const FOO: Foo = String::new();
16+
| ^^^^^^^^^^^^^^
17+
note: ...which requires const checking `FOO`...
18+
--> $DIR/const-promoted-opaque.rs:17:1
19+
|
20+
LL | const FOO: Foo = String::new();
21+
| ^^^^^^^^^^^^^^
22+
= note: ...which requires computing whether `Foo` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`...
24+
= note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
25+
note: cycle used when checking item types in top-level module
26+
--> $DIR/const-promoted-opaque.rs:2:1
27+
|
28+
LL | / #![feature(type_alias_impl_trait)]
29+
LL | |
30+
LL | | //! Check that we do not cause cycle errors when trying to
31+
LL | | //! obtain information about interior mutability of an opaque type.
32+
... |
33+
LL | | let _: &'static _ = &FOO;
34+
LL | | }
35+
| |_^
36+
37+
error: aborting due to previous error
38+
39+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)