Skip to content

Commit b39f459

Browse files
committed
Pessimistically assume opaque types are !Freeze
1 parent 55bfcb8 commit b39f459

8 files changed

+115
-116
lines changed

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::LangItem;
77
use rustc_infer::infer::TyCtxtInferExt;
88
use rustc_middle::mir;
99
use rustc_middle::mir::*;
10+
use rustc_middle::ty::TypeVisitableExt;
1011
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
1112
use rustc_trait_selection::traits::{
1213
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
@@ -91,7 +92,8 @@ impl Qualif for HasMutInterior {
9192
}
9293

9394
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
94-
!ty.is_freeze(cx.tcx, cx.param_env)
95+
// Pessimistically assume opaque types are `!Freeze`
96+
ty.has_opaque_types() || !ty.is_freeze(cx.tcx, cx.param_env)
9597
}
9698

9799
fn in_adt_inherently<'tcx>(
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(type_alias_impl_trait)]
2+
3+
//! Test that we pessimistically assume the `Drop` impl of
4+
//! a hidden type is not const.
5+
6+
pub struct Parser<H>(H);
7+
8+
type Tait = impl Sized;
9+
10+
const fn constrain() -> Tait {}
11+
12+
pub const fn take(_: Tait) {}
13+
//~^ ERROR: destructor of `Tait` cannot be evaluated at compile-time
14+
15+
fn main() {
16+
println!("Hello, world!");
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0493]: destructor of `Tait` cannot be evaluated at compile-time
2+
--> $DIR/const-fn-cycle-tait.rs:12:19
3+
|
4+
LL | pub const fn take(_: Tait) {}
5+
| ^ - value is dropped here
6+
| |
7+
| the destructor for this type cannot be evaluated in constant functions
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0493`.

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
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.
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+
// check-pass
911

1012
pub struct Parser<H>(H);
1113

@@ -18,7 +20,6 @@ where
1820
}
1921

2022
pub const fn many<'s>(&'s self) -> Parser<impl for<'a> Fn(&'a str) -> Vec<T> + 's> {
21-
//~^ ERROR: cycle detected
2223
Parser::new(|_| unimplemented!())
2324
}
2425
}

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

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
1-
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
2-
--> $DIR/const-promoted-opaque.rs:13:12
1+
error[E0493]: destructor of `Foo` cannot be evaluated at compile-time
2+
--> $DIR/const-promoted-opaque.rs:25:26
33
|
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
4+
LL | let _: &'static _ = &FOO;
5+
| ^^^ the destructor for this type cannot be evaluated in constants
6+
...
7+
LL | };
8+
| - value is dropped here
9+
10+
error[E0716]: temporary value dropped while borrowed
11+
--> $DIR/const-promoted-opaque.rs:25:26
1412
|
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
13+
LL | let _: &'static _ = &FOO;
14+
| ---------- ^^^ creates a temporary value which is freed while still in use
15+
| |
16+
| type annotation requires that borrow lasts for `'static`
17+
...
18+
LL | };
19+
| - temporary value is freed at the end of this statement
20+
21+
error[E0492]: constants cannot refer to interior mutable data
22+
--> $DIR/const-promoted-opaque.rs:30:19
1923
|
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
24+
LL | const BAZ: &Foo = &FOO;
25+
| ^^^^ this borrow of an interior mutable value may end up in the final value
26+
27+
error[E0716]: temporary value dropped while borrowed
28+
--> $DIR/const-promoted-opaque.rs:34:26
2729
|
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-
| |_^
30+
LL | let _: &'static _ = &FOO;
31+
| ---------- ^^^ creates a temporary value which is freed while still in use
32+
| |
33+
| type annotation requires that borrow lasts for `'static`
34+
LL |
35+
LL | }
36+
| - temporary value is freed at the end of this statement
3637

37-
error: aborting due to previous error
38+
error: aborting due to 4 previous errors
3839

39-
For more information about this error, try `rustc --explain E0391`.
40+
Some errors have detailed explanations: E0492, E0493, E0716.
41+
For more information about an error, try `rustc --explain E0492`.

tests/ui/consts/const-promoted-opaque.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//[unit] check-pass
1212

1313
type Foo = impl Sized;
14-
//[string,atomic]~^ ERROR cycle detected
1514

1615
#[cfg(string)]
1716
const FOO: Foo = String::new();
@@ -24,10 +23,14 @@ const FOO: Foo = ();
2423

2524
const BAR: () = {
2625
let _: &'static _ = &FOO;
26+
//[string,atomic]~^ ERROR: destructor of `Foo` cannot be evaluated at compile-time
27+
//[string,atomic]~| ERROR: temporary value dropped while borrowed
2728
};
2829

2930
const BAZ: &Foo = &FOO;
31+
//[string,atomic]~^ ERROR: constants cannot refer to interior mutable data
3032

3133
fn main() {
3234
let _: &'static _ = &FOO;
35+
//[string,atomic]~^ ERROR: temporary value dropped while borrowed
3336
}
Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
1-
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
2-
--> $DIR/const-promoted-opaque.rs:13:12
1+
error[E0493]: destructor of `Foo` cannot be evaluated at compile-time
2+
--> $DIR/const-promoted-opaque.rs:25:26
33
|
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
4+
LL | let _: &'static _ = &FOO;
5+
| ^^^ the destructor for this type cannot be evaluated in constants
6+
...
7+
LL | };
8+
| - value is dropped here
9+
10+
error[E0716]: temporary value dropped while borrowed
11+
--> $DIR/const-promoted-opaque.rs:25:26
1412
|
15-
LL | const FOO: Foo = String::new();
16-
| ^^^^^^^^^^^^^^
17-
note: ...which requires const checking `FOO`...
18-
--> $DIR/const-promoted-opaque.rs:17:1
13+
LL | let _: &'static _ = &FOO;
14+
| ---------- ^^^ creates a temporary value which is freed while still in use
15+
| |
16+
| type annotation requires that borrow lasts for `'static`
17+
...
18+
LL | };
19+
| - temporary value is freed at the end of this statement
20+
21+
error[E0492]: constants cannot refer to interior mutable data
22+
--> $DIR/const-promoted-opaque.rs:30:19
1923
|
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
24+
LL | const BAZ: &Foo = &FOO;
25+
| ^^^^ this borrow of an interior mutable value may end up in the final value
26+
27+
error[E0716]: temporary value dropped while borrowed
28+
--> $DIR/const-promoted-opaque.rs:34:26
2729
|
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-
| |_^
30+
LL | let _: &'static _ = &FOO;
31+
| ---------- ^^^ creates a temporary value which is freed while still in use
32+
| |
33+
| type annotation requires that borrow lasts for `'static`
34+
LL |
35+
LL | }
36+
| - temporary value is freed at the end of this statement
3637

37-
error: aborting due to previous error
38+
error: aborting due to 4 previous errors
3839

39-
For more information about this error, try `rustc --explain E0391`.
40+
Some errors have detailed explanations: E0492, E0493, E0716.
41+
For more information about an error, try `rustc --explain E0492`.

0 commit comments

Comments
 (0)