Skip to content

Commit f0a4804

Browse files
committed
Add regression test
1 parent d9b265f commit f0a4804

5 files changed

+166
-0
lines changed

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

+28
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

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0391]: cycle detected when computing type of opaque `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::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: 14:33>::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: 14:33>::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: 14:33>::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: 14:33>::many::{opaque#0}>` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `Parser<<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}>: core::marker::Freeze`...
24+
= note: ...which again requires computing type of opaque `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}`, completing the cycle
25+
note: cycle used when computing type of `<impl at $DIR/const-fn-cycle.rs:12:1: 14:33>::many::{opaque#0}`
26+
--> $DIR/const-fn-cycle.rs:20:47
27+
|
28+
LL | pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
31+
32+
error: aborting due to previous error
33+
34+
For more information about this error, try `rustc --explain E0391`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
2+
--> $DIR/const-promoted-opaque.rs:14:20
3+
|
4+
LL | pub type Foo = impl Sized;
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires borrow-checking `helper::FOO`...
8+
--> $DIR/const-promoted-opaque.rs:21:5
9+
|
10+
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
11+
| ^^^^^^^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `helper::FOO`...
13+
--> $DIR/const-promoted-opaque.rs:21:5
14+
|
15+
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
16+
| ^^^^^^^^^^^^^^^^^^
17+
note: ...which requires const checking `helper::FOO`...
18+
--> $DIR/const-promoted-opaque.rs:21:5
19+
|
20+
LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
21+
| ^^^^^^^^^^^^^^^^^^
22+
= note: ...which requires computing whether `helper::Foo` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
24+
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
25+
note: cycle used when computing type of `helper::Foo::{opaque#0}`
26+
--> $DIR/const-promoted-opaque.rs:14:20
27+
|
28+
LL | pub type Foo = impl Sized;
29+
| ^^^^^^^^^^
30+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
31+
32+
error: aborting due to previous error
33+
34+
For more information about this error, try `rustc --explain E0391`.
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
mod helper {
14+
pub type Foo = impl Sized;
15+
//[string,atomic]~^ ERROR cycle detected
16+
17+
#[cfg(string)]
18+
pub const FOO: Foo = String::new();
19+
20+
#[cfg(atomic)]
21+
pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
22+
23+
#[cfg(unit)]
24+
pub const FOO: Foo = ();
25+
}
26+
use helper::*;
27+
28+
const BAR: () = {
29+
let _: &'static _ = &FOO;
30+
};
31+
32+
const BAZ: &Foo = &FOO;
33+
34+
fn main() {
35+
let _: &'static _ = &FOO;
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}`
2+
--> $DIR/const-promoted-opaque.rs:14:20
3+
|
4+
LL | pub type Foo = impl Sized;
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires borrow-checking `helper::FOO`...
8+
--> $DIR/const-promoted-opaque.rs:18:5
9+
|
10+
LL | pub const FOO: Foo = String::new();
11+
| ^^^^^^^^^^^^^^^^^^
12+
note: ...which requires promoting constants in MIR for `helper::FOO`...
13+
--> $DIR/const-promoted-opaque.rs:18:5
14+
|
15+
LL | pub const FOO: Foo = String::new();
16+
| ^^^^^^^^^^^^^^^^^^
17+
note: ...which requires const checking `helper::FOO`...
18+
--> $DIR/const-promoted-opaque.rs:18:5
19+
|
20+
LL | pub const FOO: Foo = String::new();
21+
| ^^^^^^^^^^^^^^^^^^
22+
= note: ...which requires computing whether `helper::Foo` is freeze...
23+
= note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`...
24+
= note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle
25+
note: cycle used when computing type of `helper::Foo::{opaque#0}`
26+
--> $DIR/const-promoted-opaque.rs:14:20
27+
|
28+
LL | pub type Foo = impl Sized;
29+
| ^^^^^^^^^^
30+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
31+
32+
error: aborting due to previous error
33+
34+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)