Added several more migrations under ops.rs, failing some tests though
This commit is contained in:
parent
33e8aaf830
commit
d1f14ee1b0
3 changed files with 186 additions and 97 deletions
|
@ -111,3 +111,84 @@ pub(crate) struct UnstableConstFn {
|
|||
pub span: Span,
|
||||
pub def_id: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::unallowed_mutable_refs, code = "E0764")]
|
||||
pub(crate) struct UnallowedMutableRefs {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
#[note(const_eval::teach_note)]
|
||||
pub teach: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::unallowed_mutable_refs_raw, code = "E0764")]
|
||||
pub(crate) struct UnallowedMutableRefsRaw {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
#[note(const_eval::teach_note)]
|
||||
pub teach: Option<()>,
|
||||
}
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::non_const_fmt_macro_call, code = "E0015")]
|
||||
pub(crate) struct NonConstFmtMacroCall {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::non_const_fn_call, code = "E0015")]
|
||||
pub(crate) struct NonConstFnCall {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub def_path_str: String,
|
||||
pub kind: ConstContext,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::unallowed_op_in_const_context)]
|
||||
pub(crate) struct UnallowedOpInConstContext {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::unallowed_heap_allocations, code = "E0010")]
|
||||
pub(crate) struct UnallowedHeapAllocations {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
#[note(const_eval::teach_note)]
|
||||
pub teach: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::unallowed_inline_asm, code = "E0015")]
|
||||
pub(crate) struct UnallowedInlineAsm {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::interior_mutable_data_refer, code = "E0492")]
|
||||
pub(crate) struct InteriorMutableDataRefer {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[help]
|
||||
pub opt_help: Option<()>,
|
||||
pub kind: ConstContext,
|
||||
#[note(const_eval::teach_note)]
|
||||
pub teach: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(const_eval::interior_mutability_borrow)]
|
||||
pub(crate) struct InteriorMutabilityBorrow {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
|
|
@ -24,8 +24,11 @@ use rustc_trait_selection::traits::SelectionContext;
|
|||
|
||||
use super::ConstCx;
|
||||
use crate::errors::{
|
||||
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
|
||||
TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, UnstableConstFn,
|
||||
InteriorMutabilityBorrow, InteriorMutableDataRefer, MutDerefErr, NonConstFmtMacroCall,
|
||||
NonConstFnCall, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
|
||||
TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall,
|
||||
UnallowedHeapAllocations, UnallowedInlineAsm, UnallowedMutableRefs, UnallowedMutableRefsRaw,
|
||||
UnallowedOpInConstContext, UnstableConstFn,
|
||||
};
|
||||
use crate::util::{call_kind, CallDesugaringKind, CallKind};
|
||||
|
||||
|
@ -305,22 +308,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
|||
err
|
||||
}
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0015,
|
||||
"cannot call non-const formatting macro in {}s",
|
||||
ccx.const_kind(),
|
||||
)
|
||||
ccx.tcx.sess.create_err(NonConstFmtMacroCall { span, kind: ccx.const_kind() })
|
||||
}
|
||||
_ => struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
_ => ccx.tcx.sess.create_err(NonConstFnCall {
|
||||
span,
|
||||
E0015,
|
||||
"cannot call non-const fn `{}` in {}s",
|
||||
ccx.tcx.def_path_str_with_substs(callee, substs),
|
||||
ccx.const_kind(),
|
||||
),
|
||||
def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs),
|
||||
kind: ccx.const_kind(),
|
||||
}),
|
||||
};
|
||||
|
||||
err.note(&format!(
|
||||
|
@ -387,9 +381,12 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
|
|||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
|
||||
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
|
||||
feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg)
|
||||
ccx.tcx.sess.create_feature_err(
|
||||
UnallowedOpInConstContext { span, msg },
|
||||
sym::const_async_blocks,
|
||||
)
|
||||
} else {
|
||||
ccx.tcx.sess.struct_span_err(span, &msg)
|
||||
ccx.tcx.sess.create_err(UnallowedOpInConstContext { span, msg })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,23 +399,11 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
ccx.tcx.sess.create_err(UnallowedHeapAllocations {
|
||||
span,
|
||||
E0010,
|
||||
"allocations are not allowed in {}s",
|
||||
ccx.const_kind()
|
||||
);
|
||||
err.span_label(span, format!("allocation not allowed in {}s", ccx.const_kind()));
|
||||
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.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.",
|
||||
);
|
||||
}
|
||||
err
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(&error_code!(E0010)).then_some(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,13 +415,7 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0015,
|
||||
"inline assembly is not allowed in {}s",
|
||||
ccx.const_kind()
|
||||
)
|
||||
ccx.tcx.sess.create_err(UnallowedInlineAsm { span, kind: ccx.const_kind() })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,12 +461,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_refs_to_cell,
|
||||
span,
|
||||
"cannot borrow here, since the borrowed element may contain interior mutability",
|
||||
)
|
||||
ccx.tcx.sess.create_feature_err(InteriorMutabilityBorrow { span }, sym::const_refs_to_cell)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,32 +476,22 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0492,
|
||||
"{}s cannot refer to interior mutable data",
|
||||
ccx.const_kind(),
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
"this borrow of an interior mutable value may end up in the final value",
|
||||
);
|
||||
// FIXME: Maybe a more elegant solution to this if else case
|
||||
if let hir::ConstContext::Static(_) = ccx.const_kind() {
|
||||
err.help(
|
||||
"to fix this, the value can be extracted to a separate \
|
||||
`static` item and then referenced",
|
||||
);
|
||||
ccx.tcx.sess.create_err(InteriorMutableDataRefer {
|
||||
span,
|
||||
opt_help: Some(()),
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
|
||||
})
|
||||
} else {
|
||||
ccx.tcx.sess.create_err(InteriorMutableDataRefer {
|
||||
span,
|
||||
opt_help: None,
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
|
||||
})
|
||||
}
|
||||
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.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.",
|
||||
);
|
||||
}
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,33 +517,29 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
|
|||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let raw = match self.0 {
|
||||
hir::BorrowKind::Raw => "raw ",
|
||||
hir::BorrowKind::Ref => "",
|
||||
};
|
||||
// let raw = match self.0 {
|
||||
// hir::BorrowKind::Raw => "raw ",
|
||||
// hir::BorrowKind::Ref => "",
|
||||
// };
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0764,
|
||||
"{}mutable references are not allowed in the final value of {}s",
|
||||
raw,
|
||||
ccx.const_kind(),
|
||||
);
|
||||
|
||||
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(
|
||||
"References in statics and constants may only refer \
|
||||
to immutable values.\n\n\
|
||||
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.\n\n\
|
||||
If you really want global mutable state, try using \
|
||||
static mut or a global UnsafeCell.",
|
||||
);
|
||||
// ccx.tcx.sess.create_err(UnallowedMutableRefs {
|
||||
// span,
|
||||
// raw,
|
||||
// kind: ccx.const_kind(),
|
||||
// teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
|
||||
// })
|
||||
match self.0 {
|
||||
hir::BorrowKind::Raw => ccx.tcx.sess.create_err(UnallowedMutableRefsRaw {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
|
||||
}),
|
||||
hir::BorrowKind::Ref => ccx.tcx.sess.create_err(UnallowedMutableRefs {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
|
||||
}),
|
||||
}
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,4 +34,52 @@ const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant
|
|||
|
||||
const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s
|
||||
|
||||
const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn
|
||||
const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn
|
||||
|
||||
const_eval_unallowed_mutable_refs =
|
||||
mutable references are not allowed in the final value of {$kind}s
|
||||
.teach_note =
|
||||
References in statics and constants may only refer to immutable values.\n\n
|
||||
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.\n\n
|
||||
If you really want global mutable state, try using static mut or a global UnsafeCell.
|
||||
|
||||
const_eval_unallowed_mutable_refs_raw =
|
||||
raw mutable references are not allowed in the final value of {$kind}s
|
||||
.teach_note =
|
||||
References in statics and constants may only refer to immutable values.\n\n
|
||||
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.\n\n
|
||||
If you really want global mutable state, try using static mut or a global UnsafeCell.
|
||||
|
||||
const_eval_non_const_fmt_macro_call =
|
||||
cannot call non-const formatting macro in {$kind}s
|
||||
|
||||
const_eval_non_const_fn_call =
|
||||
cannot call non-const fn `{$def_path_str}` in {$kind}s
|
||||
|
||||
const_eval_unallowed_op_in_const_context =
|
||||
{$msg}
|
||||
|
||||
const_eval_unallowed_heap_allocations =
|
||||
allocations are not allowed in {$kind}s
|
||||
.label = allocation not allowed in {$kind}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.
|
||||
|
||||
const_eval_unallowed_inline_asm =
|
||||
inline assembly is not allowed in {$kind}s
|
||||
|
||||
const_eval_interior_mutable_data_refer =
|
||||
{$kind}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.
|
||||
|
||||
const_eval_interior_mutability_borrow =
|
||||
cannot borrow here, since the borrowed element may contain interior mutability
|
Loading…
Add table
Reference in a new issue