Skip to content

Commit c7fed9f

Browse files
committed
Auto merge of #122204 - pnkfelix:downgrade-const-eval-dnagling-ptr-in-final-to-future-incompat-lint, r=wesleywiser
Downgrade const eval dangling ptr in final to future incompat lint Short term band-aid for issue #121610, downgrading the prior hard error to a future-incompat lint (tracked in issue #122153). Note we should not mark #121610 as resolved until after this (or something analogous) is beta backported.
2 parents 3cbb932 + 8f45a9e commit c7fed9f

16 files changed

+876
-83
lines changed

compiler/rustc_const_eval/src/errors.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ pub(crate) struct DanglingPtrInFinal {
2525
pub kind: InternKind,
2626
}
2727

28-
#[derive(Diagnostic)]
28+
#[derive(LintDiagnostic)]
2929
#[diag(const_eval_mutable_ptr_in_final)]
3030
pub(crate) struct MutablePtrInFinal {
31-
#[primary_span]
31+
// rust-lang/rust#122153: This was marked as `#[primary_span]` under
32+
// `derive(Diagnostic)`. Since we expect we may hard-error in future, we are
33+
// keeping the field (and skipping it under `derive(LintDiagnostic)`).
34+
#[skip_arg]
3235
pub span: Span,
3336
pub kind: InternKind,
3437
}

compiler/rustc_const_eval/src/interpret/intern.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_hir as hir;
2121
use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult};
2222
use rustc_middle::query::TyCtxtAt;
2323
use rustc_middle::ty::layout::TyAndLayout;
24+
use rustc_session::lint;
2425
use rustc_span::def_id::LocalDefId;
2526
use rustc_span::sym;
2627

@@ -262,10 +263,13 @@ pub fn intern_const_alloc_recursive<
262263
})?);
263264
}
264265
if found_bad_mutable_pointer {
265-
return Err(ecx
266-
.tcx
267-
.dcx()
268-
.emit_err(MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }));
266+
let err_diag = MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
267+
ecx.tcx.emit_node_span_lint(
268+
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
269+
ecx.best_lint_scope(),
270+
err_diag.span,
271+
err_diag,
272+
)
269273
}
270274

271275
Ok(())

compiler/rustc_lint_defs/src/builtin.rs

+46
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ declare_lint_pass! {
3030
CENUM_IMPL_DROP_CAST,
3131
COHERENCE_LEAK_CHECK,
3232
CONFLICTING_REPR_HINTS,
33+
CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
3334
CONST_EVALUATABLE_UNCHECKED,
3435
CONST_ITEM_MUTATION,
3536
DEAD_CODE,
@@ -2796,6 +2797,51 @@ declare_lint! {
27962797
@feature_gate = sym::strict_provenance;
27972798
}
27982799

2800+
declare_lint! {
2801+
/// The `const_eval_mutable_ptr_in_final_value` lint detects if a mutable pointer
2802+
/// has leaked into the final value of a const expression.
2803+
///
2804+
/// ### Example
2805+
///
2806+
/// ```rust
2807+
/// pub enum JsValue {
2808+
/// Undefined,
2809+
/// Object(std::cell::Cell<bool>),
2810+
/// }
2811+
///
2812+
/// impl ::std::ops::Drop for JsValue {
2813+
/// fn drop(&mut self) {}
2814+
/// }
2815+
///
2816+
/// const UNDEFINED: &JsValue = &JsValue::Undefined;
2817+
///
2818+
/// fn main() {
2819+
/// }
2820+
/// ```
2821+
///
2822+
/// {{produces}}
2823+
///
2824+
/// ### Explanation
2825+
///
2826+
/// In the 1.77 release, the const evaluation machinery adopted some
2827+
/// stricter rules to reject expressions with values that could
2828+
/// end up holding mutable references to state stored in static memory
2829+
/// (which is inherently immutable).
2830+
///
2831+
/// This is a [future-incompatible] lint to ease the transition to an error.
2832+
/// See [issue #122153] for more details.
2833+
///
2834+
/// [issue #122153]: https://github.com/rust-lang/rust/issues/122153
2835+
/// [future-incompatible]: ../index.md#future-incompatible-lints
2836+
pub CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
2837+
Warn,
2838+
"detects a mutable pointer that has leaked into final value of a const expression",
2839+
@future_incompatible = FutureIncompatibleInfo {
2840+
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
2841+
reference: "issue #122153 <https://github.com/rust-lang/rust/issues/122153>",
2842+
};
2843+
}
2844+
27992845
declare_lint! {
28002846
/// The `const_evaluatable_unchecked` lint detects a generic constant used
28012847
/// in a type.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#![feature(core_intrinsics)]
22
#![feature(const_heap)]
33
#![feature(const_mut_refs)]
4+
#![deny(const_eval_mutable_ptr_in_final_value)]
45
use std::intrinsics;
56

67
const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
78
//~^ error: mutable pointer in final value of constant
9+
//~| WARNING this was previously accepted by the compiler
810

911
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
error: encountered mutable pointer in final value of constant
2-
--> $DIR/alloc_intrinsic_untyped.rs:6:1
2+
--> $DIR/alloc_intrinsic_untyped.rs:7:1
33
|
44
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
55
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
9+
note: the lint level is defined here
10+
--> $DIR/alloc_intrinsic_untyped.rs:4:9
11+
|
12+
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
614

715
error: aborting due to 1 previous error
816

17+
Future incompatibility report: Future breakage diagnostic:
18+
error: encountered mutable pointer in final value of constant
19+
--> $DIR/alloc_intrinsic_untyped.rs:7:1
20+
|
21+
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
22+
| ^^^^^^^^^^^^^^^^^^^
23+
|
24+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
25+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
26+
note: the lint level is defined here
27+
--> $DIR/alloc_intrinsic_untyped.rs:4:9
28+
|
29+
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
use std::cell::Cell;
3+
4+
pub enum JsValue {
5+
Undefined,
6+
Object(Cell<bool>),
7+
}
8+
9+
impl ::std::ops::Drop for JsValue {
10+
fn drop(&mut self) {}
11+
}
12+
13+
const UNDEFINED: &JsValue = &JsValue::Undefined;
14+
//~^ WARN encountered mutable pointer in final value of constant
15+
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
16+
17+
fn main() {
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
warning: encountered mutable pointer in final value of constant
2+
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
3+
|
4+
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
9+
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
10+
11+
warning: 1 warning emitted
12+
13+
Future incompatibility report: Future breakage diagnostic:
14+
warning: encountered mutable pointer in final value of constant
15+
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
16+
|
17+
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
19+
|
20+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
21+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
22+
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
23+

tests/ui/consts/miri_unleashed/mutable_references.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
//@ compile-flags: -Zunleash-the-miri-inside-of-you
2+
//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
3+
//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
24

5+
#![deny(const_eval_mutable_ptr_in_final_value)]
36
use std::cell::UnsafeCell;
47

58
// a test demonstrating what things we could allow with a smarter const qualification
69

710
static FOO: &&mut u32 = &&mut 42;
811
//~^ ERROR encountered mutable pointer in final value of static
12+
//~| WARNING this was previously accepted by the compiler
913

1014
static BAR: &mut () = &mut ();
1115
//~^ ERROR encountered mutable pointer in final value of static
16+
//~| WARNING this was previously accepted by the compiler
1217

1318
struct Foo<T>(T);
1419

1520
static BOO: &mut Foo<()> = &mut Foo(());
1621
//~^ ERROR encountered mutable pointer in final value of static
22+
//~| WARNING this was previously accepted by the compiler
1723

1824
struct Meh {
1925
x: &'static UnsafeCell<i32>,
2026
}
2127
unsafe impl Sync for Meh {}
2228
static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
2329
//~^ ERROR encountered mutable pointer in final value of static
30+
//~| WARNING this was previously accepted by the compiler
2431

2532
static OH_YES: &mut i32 = &mut 42;
2633
//~^ ERROR encountered mutable pointer in final value of static
34+
//~| WARNING this was previously accepted by the compiler
35+
//~| ERROR it is undefined behavior to use this value
2736

2837
fn main() {
2938
unsafe {

0 commit comments

Comments
 (0)