Rollup merge of #131397 - RalfJung:const-escaping-ref-teach, r=chenyukang
fix/update teach_note from 'escaping mutable ref/ptr' const-check The old note was quite confusing since it talked about statics, but the message is also shown for consts. So let's reword to something that is true for both of them.
This commit is contained in:
commit
a2c43eb806
@ -134,14 +134,16 @@ 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_data_refer =
|
||||
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
|
||||
.help = to fix this, the value can be extracted to a separate `static` item and then referenced
|
||||
.teach_note =
|
||||
A constant containing interior mutable data behind a reference can allow you to modify that data.
|
||||
This would make multiple uses of a constant to be able to see different values and allow circumventing
|
||||
the `Send` and `Sync` requirements for shared mutable data, which is unsound.
|
||||
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_intern_kind = {$kind ->
|
||||
[static] static
|
||||
@ -229,6 +231,24 @@ const_eval_modified_global =
|
||||
|
||||
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
|
||||
.teach_note =
|
||||
Pointers 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_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_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
|
||||
const_eval_non_const_fmt_macro_call =
|
||||
cannot call non-const formatting macro in {const_eval_const_context}s
|
||||
@ -364,30 +384,11 @@ const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in
|
||||
const_eval_unallowed_heap_allocations =
|
||||
allocations are not allowed in {const_eval_const_context}s
|
||||
.label = allocation not allowed in {const_eval_const_context}s
|
||||
.teach_note = The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
|
||||
.teach_note =
|
||||
The runtime heap is not yet available at compile-time, so no runtime heap allocations can be created.
|
||||
|
||||
const_eval_unallowed_inline_asm =
|
||||
inline assembly is not allowed in {const_eval_const_context}s
|
||||
const_eval_unallowed_mutable_raw =
|
||||
raw mutable pointers are not allowed in the final value of {const_eval_const_context}s
|
||||
.teach_note =
|
||||
References in statics and constants may only refer to immutable values.
|
||||
|
||||
|
||||
Statics are shared everywhere, and if they refer to mutable data one might violate memory
|
||||
safety since holding multiple mutable references to shared data is not allowed.
|
||||
|
||||
|
||||
If you really want global mutable state, try using static mut or a global UnsafeCell.
|
||||
|
||||
const_eval_unallowed_mutable_refs =
|
||||
mutable references are not allowed in the final value of {const_eval_const_context}s
|
||||
.teach_note =
|
||||
Statics are shared everywhere, and if they refer to mutable data one might violate memory
|
||||
safety since holding multiple mutable references to shared data is not allowed.
|
||||
|
||||
|
||||
If you really want global mutable state, try using static mut or a global UnsafeCell.
|
||||
|
||||
const_eval_unallowed_op_in_const_context =
|
||||
{$msg}
|
||||
|
@ -666,6 +666,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
||||
}
|
||||
}
|
||||
|
||||
// This can be called on stable via the `vec!` macro.
|
||||
if tcx.is_lang_item(callee, LangItem::ExchangeMalloc) {
|
||||
self.check_op(ops::HeapAllocation);
|
||||
return;
|
||||
|
@ -402,7 +402,7 @@ fn importance(&self) -> DiagImportance {
|
||||
DiagImportance::Secondary
|
||||
}
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||
ccx.dcx().create_err(errors::InteriorMutableDataRefer {
|
||||
ccx.dcx().create_err(errors::InteriorMutableRefEscaping {
|
||||
span,
|
||||
opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)),
|
||||
kind: ccx.const_kind(),
|
||||
@ -430,12 +430,12 @@ fn importance(&self) -> DiagImportance {
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||
match self.0 {
|
||||
hir::BorrowKind::Raw => ccx.tcx.dcx().create_err(errors::UnallowedMutableRaw {
|
||||
hir::BorrowKind::Raw => ccx.tcx.dcx().create_err(errors::MutableRawEscaping {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(E0764),
|
||||
}),
|
||||
hir::BorrowKind::Ref => ccx.dcx().create_err(errors::UnallowedMutableRefs {
|
||||
hir::BorrowKind::Ref => ccx.dcx().create_err(errors::MutableRefEscaping {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(E0764),
|
||||
|
@ -118,8 +118,8 @@ pub(crate) struct UnstableConstFn {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_unallowed_mutable_refs, code = E0764)]
|
||||
pub(crate) struct UnallowedMutableRefs {
|
||||
#[diag(const_eval_mutable_ref_escaping, code = E0764)]
|
||||
pub(crate) struct MutableRefEscaping {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
@ -128,8 +128,8 @@ pub(crate) struct UnallowedMutableRefs {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_unallowed_mutable_raw, code = E0764)]
|
||||
pub(crate) struct UnallowedMutableRaw {
|
||||
#[diag(const_eval_mutable_raw_escaping, code = E0764)]
|
||||
pub(crate) struct MutableRawEscaping {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
@ -181,8 +181,8 @@ pub(crate) struct UnallowedInlineAsm {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_interior_mutable_data_refer, code = E0492)]
|
||||
pub(crate) struct InteriorMutableDataRefer {
|
||||
#[diag(const_eval_interior_mutable_ref_escaping, code = E0492)]
|
||||
pub(crate) struct InteriorMutableRefEscaping {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
|
@ -4,7 +4,7 @@ error[E0010]: allocations are not allowed in constants
|
||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in constants
|
||||
|
|
||||
= note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
|
||||
= note: The runtime heap is not yet available at compile-time, so no runtime heap allocations can be created.
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0015]: cannot call non-const fn `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constants
|
||||
|
Loading…
Reference in New Issue
Block a user