Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize &mut (and *mut) as well as &Cell (and *const Cell) in const #129195

Merged
merged 4 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ const_eval_incompatible_return_types =
const_eval_incompatible_types =
calling a function with argument of type {$callee_ty} passing data of type {$caller_ty}

const_eval_interior_mutability_borrow =
cannot borrow here, since the borrowed element may contain interior mutability

const_eval_interior_mutable_data_refer =
{const_eval_const_context}s cannot refer to interior mutable data
.label = this borrow of an interior mutable value may end up in the final value
Expand Down Expand Up @@ -230,9 +227,6 @@ const_eval_memory_exhausted =
const_eval_modified_global =
modifying a static's initial value from another static's initializer

const_eval_mut_deref =
mutation through a reference is not allowed in {const_eval_const_context}s

const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}

const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
Expand Down Expand Up @@ -363,10 +357,6 @@ const_eval_too_generic =
const_eval_too_many_caller_args =
calling a function with more arguments than it expected

const_eval_transient_mut_borrow = mutable references are not allowed in {const_eval_const_context}s

const_eval_transient_mut_raw = raw mutable pointers are not allowed in {const_eval_const_context}s

const_eval_try_block_from_output_non_const =
`try` block cannot convert `{$ty}` to the result in {const_eval_const_context}s
const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {const_eval_const_context}s
Expand Down
254 changes: 25 additions & 229 deletions compiler/rustc_const_eval/src/check_consts/check.rs

Large diffs are not rendered by default.

116 changes: 5 additions & 111 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource};
use rustc_middle::mir::CallSource;
use rustc_middle::span_bug;
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
use rustc_middle::ty::{
Expand Down Expand Up @@ -391,27 +391,12 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
}
}

#[derive(Debug)]
/// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow never escapes to
/// the final value of the constant.
pub(crate) struct TransientCellBorrow;
impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_refs_to_cell)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
ccx.tcx
.sess
.create_feature_err(errors::InteriorMutabilityBorrow { span }, sym::const_refs_to_cell)
}
}

#[derive(Debug)]
/// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow might escape to
/// the final value of the constant, and thus we cannot allow this (for now). We may allow
/// it in the future for static items.
pub(crate) struct CellBorrow;
impl<'tcx> NonConstOp<'tcx> for CellBorrow {
pub(crate) struct EscapingCellBorrow;
impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow {
fn importance(&self) -> DiagImportance {
// Most likely the code will try to do mutation with these borrows, which
// triggers its own errors. Only show this one if that does not happen.
Expand All @@ -431,9 +416,9 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
/// This op is for `&mut` borrows in the trailing expression of a constant
/// which uses the "enclosing scopes rule" to leak its locals into anonymous
/// static or const items.
pub(crate) struct MutBorrow(pub hir::BorrowKind);
pub(crate) struct EscapingMutBorrow(pub hir::BorrowKind);

impl<'tcx> NonConstOp<'tcx> for MutBorrow {
impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow {
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
Status::Forbidden
}
Expand All @@ -460,49 +445,6 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
}
}

#[derive(Debug)]
pub(crate) struct TransientMutBorrow(pub hir::BorrowKind);

impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
let kind = ccx.const_kind();
match self.0 {
hir::BorrowKind::Raw => ccx
.tcx
.sess
.create_feature_err(errors::TransientMutRawErr { span, kind }, sym::const_mut_refs),
hir::BorrowKind::Ref => ccx.tcx.sess.create_feature_err(
errors::TransientMutBorrowErr { span, kind },
sym::const_mut_refs,
),
}
}
}

#[derive(Debug)]
pub(crate) struct MutDeref;
impl<'tcx> NonConstOp<'tcx> for MutDeref {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}

fn importance(&self) -> DiagImportance {
// Usually a side-effect of a `TransientMutBorrow` somewhere.
DiagImportance::Secondary
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
ccx.tcx.sess.create_feature_err(
errors::MutDerefErr { span, kind: ccx.const_kind() },
sym::const_mut_refs,
)
}
}

/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
#[derive(Debug)]
pub(crate) struct PanicNonStr;
Expand All @@ -524,24 +466,6 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
}
}

#[derive(Debug)]
pub(crate) struct RawMutPtrDeref;
impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_mut_refs)
}

#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
feature_err(
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
)
}
}

/// Casting raw pointer or function pointer to an integer.
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
/// allocation base addresses that are not known at compile-time.
Expand Down Expand Up @@ -588,33 +512,3 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
ccx.dcx().create_err(errors::ThreadLocalAccessErr { span })
}
}

/// Types that cannot appear in the signature or locals of a `const fn`.
pub(crate) mod mut_ref {
use super::*;

#[derive(Debug)]
pub(crate) struct MutRef(pub mir::LocalKind);
impl<'tcx> NonConstOp<'tcx> for MutRef {
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}

fn importance(&self) -> DiagImportance {
match self.0 {
mir::LocalKind::Temp => DiagImportance::Secondary,
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => DiagImportance::Primary,
}
}

#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
feature_err(
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("mutable references are not allowed in {}s", ccx.const_kind()),
)
}
}
}
31 changes: 0 additions & 31 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,6 @@ pub(crate) struct PanicNonStrErr {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(const_eval_mut_deref, code = E0658)]
pub(crate) struct MutDerefErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}

#[derive(Diagnostic)]
#[diag(const_eval_transient_mut_borrow, code = E0658)]
pub(crate) struct TransientMutBorrowErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}

#[derive(Diagnostic)]
#[diag(const_eval_transient_mut_raw, code = E0658)]
pub(crate) struct TransientMutRawErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}

#[derive(Diagnostic)]
#[diag(const_eval_max_num_nodes_in_const)]
pub(crate) struct MaxNumNodesInConstErr {
Expand Down Expand Up @@ -217,13 +193,6 @@ pub(crate) struct InteriorMutableDataRefer {
pub teach: bool,
}

#[derive(Diagnostic)]
#[diag(const_eval_interior_mutability_borrow)]
pub(crate) struct InteriorMutabilityBorrow {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(const_eval_long_running)]
#[note]
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0764.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ A mutable reference was used in a constant.
Erroneous code example:

```compile_fail,E0764
#![feature(const_mut_refs)]

fn main() {
const OH_NO: &'static mut usize = &mut 1; // error!
}
Expand All @@ -26,8 +24,6 @@ Remember: you cannot use a function call inside a constant or static. However,
you can totally use it in constant functions:

```
#![feature(const_mut_refs)]

const fn foo(x: usize) -> usize {
let mut y = 1;
let z = &mut y;
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,14 @@ declare_features! (
(accepted, const_let, "1.33.0", Some(48821)),
/// Allows the use of `loop` and `while` in constants.
(accepted, const_loop, "1.46.0", Some(52000)),
/// Allows using `&mut` in constant functions.
(accepted, const_mut_refs, "CURRENT_RUSTC_VERSION", Some(57349)),
/// Allows panicking during const eval (producing compile-time errors).
(accepted, const_panic, "1.57.0", Some(51999)),
/// Allows dereferencing raw pointers during const eval.
(accepted, const_raw_ptr_deref, "1.58.0", Some(51911)),
/// Allows references to types with interior mutability within constants
(accepted, const_refs_to_cell, "CURRENT_RUSTC_VERSION", Some(80384)),
/// Allows implementing `Copy` for closures where possible (RFC 2132).
(accepted, copy_closures, "1.26.0", Some(44490)),
/// Allows `crate` in paths.
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,8 @@ declare_features! (
(incomplete, const_closures, "1.68.0", Some(106003)),
/// Allows `for _ in _` loops in const contexts.
(unstable, const_for, "1.56.0", Some(87575)),
/// Allows using `&mut` in constant functions.
(unstable, const_mut_refs, "1.41.0", Some(57349)),
/// Be more precise when looking for live drops in a const context.
(unstable, const_precise_live_drops, "1.46.0", Some(73255)),
/// Allows references to types with interior mutability within constants
(unstable, const_refs_to_cell, "1.51.0", Some(80384)),
/// Allows creating pointers and references to `static` items in constants.
(unstable, const_refs_to_static, "1.78.0", Some(119618)),
/// Allows `impl const Trait for T` syntax.
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
#![feature(const_maybe_uninit_write)]
#![feature(const_option)]
#![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
#![feature(core_intrinsics)]
#![feature(deprecated_suggestion)]
Expand Down Expand Up @@ -164,13 +163,14 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
#![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_internals)]
#![feature(allow_internal_unstable)]
#![feature(cfg_sanitize)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_ptr_write)]
#![feature(const_try)]
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_ptr_write)]
#![feature(const_try)]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
#![feature(abi_unadjusted)]
#![feature(adt_const_params)]
#![feature(allow_internal_unsafe)]
Expand All @@ -201,9 +203,7 @@
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(cfg_ub_checks)]
#![feature(const_for)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_refs_to_cell)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,7 @@ impl<T: ?Sized> *mut T {
///
/// ```
/// #![feature(const_pointer_is_aligned)]
/// #![feature(const_mut_refs)]
/// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
///
/// // On some platforms, the alignment of primitives is less than their size.
/// #[repr(align(4))]
Expand Down Expand Up @@ -1695,7 +1695,7 @@ impl<T: ?Sized> *mut T {
/// ```
/// #![feature(pointer_is_aligned_to)]
/// #![feature(const_pointer_is_aligned)]
/// #![feature(const_mut_refs)]
/// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
///
/// // On some platforms, the alignment of i32 is less than 4.
/// #[repr(align(4))]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ impl<T> [T] {
/// [`as_mut_ptr`]: slice::as_mut_ptr
#[stable(feature = "slice_ptr_range", since = "1.48.0")]
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
#[rustc_allow_const_fn_unstable(const_mut_refs)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell))]
#[inline]
#[must_use]
pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![cfg_attr(test, feature(cfg_match))]
#![feature(alloc_layout_extra)]
Expand Down Expand Up @@ -26,7 +27,6 @@
#![feature(const_ipv6)]
#![feature(const_likely)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_mut_refs)]
#![feature(const_nonnull_new)]
#![feature(const_option)]
#![feature(const_option_ext)]
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![feature(alloc_error_handler)]
#![feature(allocator_internals)]
#![feature(allow_internal_unsafe)]
Expand All @@ -281,7 +282,6 @@
#![feature(cfg_target_thread_local)]
#![feature(cfi_encoding)]
#![feature(concat_idents)]
#![feature(const_mut_refs)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]
Expand Down
Loading
Loading