Added several more migrations under ops.rs, failing some tests though

This commit is contained in:
nidnogg 2022-08-19 15:36:09 -03:00
parent 33e8aaf830
commit d1f14ee1b0
3 changed files with 186 additions and 97 deletions

View file

@ -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,
}

View file

@ -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
}
}

View file

@ -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