diff options
| author | Ralf Jung <post@ralfj.de> | 2025-06-18 10:04:43 +0900 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-06-26 18:11:24 +0200 |
| commit | bade3fd0580815f1a5a4abd33244982dc458d54d (patch) | |
| tree | 4e0ee736d00bcb324c517680895d5e6b9f771342 /compiler/rustc_const_eval | |
| parent | ff17a225e6f0545d447546a12c520b932c9bcc88 (diff) | |
| download | rust-bade3fd0580815f1a5a4abd33244982dc458d54d.tar.gz rust-bade3fd0580815f1a5a4abd33244982dc458d54d.zip | |
clarify and unify 'transient mutable borrow' errors
Diffstat (limited to 'compiler/rustc_const_eval')
| -rw-r--r-- | compiler/rustc_const_eval/messages.ftl | 27 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/check_consts/check.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/check_consts/ops.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/errors.rs | 17 |
4 files changed, 22 insertions, 51 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 84b08a80cf0..97b154ad142 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -124,12 +124,13 @@ 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_mutable_ref_escaping = - {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 +const_eval_interior_mutable_borrow_escaping = + interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed + .label = this borrow of an interior mutable value refers to a lifetime-extended temporary .help = to fix this, the value can be extracted to a separate `static` item and then referenced .teach_note = - References that escape into the final value of a constant or static must be immutable. + This creates a raw pointer to a temporary that has its lifetime extended to last for the entire program. + Lifetime-extended temporaries in constants and statics must be immutable. This is to avoid accidentally creating shared mutable state. @@ -213,25 +214,17 @@ const_eval_memory_exhausted = const_eval_modified_global = modifying a static's initial value from another static's initializer -const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} - -const_eval_mutable_raw_escaping = - raw mutable pointers are not allowed in the final value of {const_eval_const_context}s +const_eval_mutable_borrow_escaping = + mutable borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed .teach_note = - Pointers that escape into the final value of a constant or static must be immutable. + This creates a reference to a temporary that has its lifetime extended to last for the entire program. + Lifetime-extended temporaries in constants and statics must be immutable. This is to avoid accidentally creating shared mutable state. If you really want global mutable state, try using an interior mutable `static` or a `static mut`. -const_eval_mutable_ref_escaping = - mutable references are not allowed in the final value of {const_eval_const_context}s - .teach_note = - References that escape into the final value of a constant or static must be immutable. - This is to avoid accidentally creating shared mutable state. - - - If you really want global mutable state, try using an interior mutable `static` or a `static mut`. +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 diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 576b174369d..c151e8acf92 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -595,11 +595,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut); if !is_allowed && self.place_may_escape(place) { - self.check_op(ops::EscapingMutBorrow(if matches!(rvalue, Rvalue::Ref(..)) { - hir::BorrowKind::Ref - } else { - hir::BorrowKind::Raw - })); + self.check_op(ops::EscapingMutBorrow); } } diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index f5b7a6066c8..02edff8f632 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -567,7 +567,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow { DiagImportance::Secondary } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::InteriorMutableRefEscaping { + ccx.dcx().create_err(errors::InteriorMutableBorrowEscaping { span, opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)), kind: ccx.const_kind(), @@ -580,7 +580,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow { /// 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 EscapingMutBorrow(pub hir::BorrowKind); +pub(crate) struct EscapingMutBorrow; impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow { fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status { @@ -594,20 +594,11 @@ impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - match self.0 { - hir::BorrowKind::Raw => ccx.tcx.dcx().create_err(errors::MutableRawEscaping { - span, - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0764), - }), - hir::BorrowKind::Ref | hir::BorrowKind::Pin => { - ccx.dcx().create_err(errors::MutableRefEscaping { - span, - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0764), - }) - } - } + ccx.dcx().create_err(errors::MutableBorrowEscaping { + span, + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(E0764), + }) } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 6f028791916..b2c3103c34a 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -150,8 +150,8 @@ pub(crate) struct UnmarkedIntrinsicExposed { } #[derive(Diagnostic)] -#[diag(const_eval_mutable_ref_escaping, code = E0764)] -pub(crate) struct MutableRefEscaping { +#[diag(const_eval_mutable_borrow_escaping, code = E0764)] +pub(crate) struct MutableBorrowEscaping { #[primary_span] pub span: Span, pub kind: ConstContext, @@ -160,15 +160,6 @@ pub(crate) struct MutableRefEscaping { } #[derive(Diagnostic)] -#[diag(const_eval_mutable_raw_escaping, code = E0764)] -pub(crate) struct MutableRawEscaping { - #[primary_span] - pub span: Span, - pub kind: ConstContext, - #[note(const_eval_teach_note)] - pub teach: bool, -} -#[derive(Diagnostic)] #[diag(const_eval_non_const_fmt_macro_call, code = E0015)] pub(crate) struct NonConstFmtMacroCall { #[primary_span] @@ -225,8 +216,8 @@ pub(crate) struct UnallowedInlineAsm { } #[derive(Diagnostic)] -#[diag(const_eval_interior_mutable_ref_escaping, code = E0492)] -pub(crate) struct InteriorMutableRefEscaping { +#[diag(const_eval_interior_mutable_borrow_escaping, code = E0492)] +pub(crate) struct InteriorMutableBorrowEscaping { #[primary_span] #[label] pub span: Span, |
