Auto merge of #77354 - ecstatic-morse:const-checking-moar-errors, r=oli-obk
Overhaul const-checking diagnostics The primary purpose of this PR was to remove `NonConstOp::STOPS_CONST_CHECKING`, which causes any additional errors found by the const-checker to be silenced. I used this flag to preserve diagnostic parity with `qualify_min_const_fn.rs`, which has since been removed. However, simply removing the flag caused a deluge of errors in some cases, since an error would be emitted any time a local or temporary had a wrong type. To remedy this, I added an alternative system (`DiagnosticImportance`) to silence additional error messages that were likely to distract the user from the underlying issue. When an error of the highest importance occurs, all less important errors are silenced. When no error of the highest importance occurs, all less important errors are emitted after checking is complete. Following the suggestions from the important error is usually enough to fix the less important errors, so this should lead to better UX most of the time. There's also some unrelated diagnostics improvements in this PR isolated in their own commits. Splitting them out would be possible, but a bit of a pain. This isn't as tidy as some of my other PRs, but it should *only* affect diagnostics, never whether or not something passes const-checking. Note that there are a few trivial exceptions to this, like banning `Yield` in all const-contexts, not just `const fn`. As always, meant to be reviewed commit-by-commit. r? `@oli-obk`
This commit is contained in:
commit
fc42fb8e70
|
@ -18,7 +18,6 @@ E0010: include_str!("./error_codes/E0010.md"),
|
|||
E0013: include_str!("./error_codes/E0013.md"),
|
||||
E0014: include_str!("./error_codes/E0014.md"),
|
||||
E0015: include_str!("./error_codes/E0015.md"),
|
||||
E0019: include_str!("./error_codes/E0019.md"),
|
||||
E0023: include_str!("./error_codes/E0023.md"),
|
||||
E0025: include_str!("./error_codes/E0025.md"),
|
||||
E0026: include_str!("./error_codes/E0026.md"),
|
||||
|
@ -463,6 +462,7 @@ E0776: include_str!("./error_codes/E0776.md"),
|
|||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
// E0019, merged into E0015
|
||||
// E0035, merged into E0087/E0089
|
||||
// E0036, merged into E0087/E0089
|
||||
// E0068,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
A function call isn't allowed in the const's initialization expression
|
||||
because the expression's value must be known at compile-time.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0019
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
struct MyOwned;
|
||||
|
||||
static STATIC11: Box<MyOwned> = box MyOwned; // error!
|
||||
}
|
||||
```
|
||||
|
||||
Remember: you can't use a function call inside a const's initialization
|
||||
expression! However, you can totally use it anywhere else:
|
||||
|
||||
```
|
||||
enum Test {
|
||||
V1
|
||||
}
|
||||
|
||||
impl Test {
|
||||
fn func(&self) -> i32 {
|
||||
12
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const FOO: Test = Test::V1;
|
||||
|
||||
FOO.func(); // here is good
|
||||
let x = FOO.func(); // or even here!
|
||||
}
|
||||
```
|
|
@ -670,7 +670,7 @@ impl Atom for Local {
|
|||
}
|
||||
|
||||
/// Classifies locals into categories. See `Body::local_kind`.
|
||||
#[derive(PartialEq, Eq, Debug, HashStable)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
|
||||
pub enum LocalKind {
|
||||
/// User-declared variable binding.
|
||||
Var,
|
||||
|
|
|
@ -57,6 +57,16 @@ impl ConstCx<'mir, 'tcx> {
|
|||
&& self.tcx.features().staged_api
|
||||
&& is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
|
||||
}
|
||||
|
||||
/// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`.
|
||||
pub fn fn_sig(&self) -> Option<&'tcx hir::FnSig<'tcx>> {
|
||||
// Get this from the HIR map instead of a query to avoid cycle errors.
|
||||
//
|
||||
// FIXME: Is this still an issue?
|
||||
let hir_map = self.tcx.hir();
|
||||
let hir_id = hir_map.local_def_id_to_hir_id(self.def_id);
|
||||
hir_map.fn_sig_by_hir_id(hir_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
//! Concrete error types for all operations which may be invalid in a certain const context.
|
||||
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -10,49 +11,6 @@ use rustc_span::{Span, Symbol};
|
|||
|
||||
use super::ConstCx;
|
||||
|
||||
/// Emits an error and returns `true` if `op` is not allowed in the given const context.
|
||||
pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> bool {
|
||||
debug!("illegal_op: op={:?}", op);
|
||||
|
||||
let gate = match op.status_in_item(ccx) {
|
||||
Status::Allowed => return false,
|
||||
|
||||
Status::Unstable(gate) if ccx.tcx.features().enabled(gate) => {
|
||||
let unstable_in_stable = ccx.is_const_stable_const_fn()
|
||||
&& !super::allow_internal_unstable(ccx.tcx, ccx.def_id.to_def_id(), gate);
|
||||
|
||||
if unstable_in_stable {
|
||||
ccx.tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
|
||||
)
|
||||
.span_suggestion(
|
||||
ccx.body.span,
|
||||
"if it is not part of the public API, make this function unstably const",
|
||||
concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.note("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks")
|
||||
.emit();
|
||||
}
|
||||
|
||||
return unstable_in_stable;
|
||||
}
|
||||
|
||||
Status::Unstable(gate) => Some(gate),
|
||||
Status::Forbidden => None,
|
||||
};
|
||||
|
||||
if ccx.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
|
||||
ccx.tcx.sess.miri_unleashed_feature(span, gate);
|
||||
return false;
|
||||
}
|
||||
|
||||
op.emit_error(ccx, span);
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Status {
|
||||
Allowed,
|
||||
|
@ -60,63 +18,44 @@ pub enum Status {
|
|||
Forbidden,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum DiagnosticImportance {
|
||||
/// An operation that must be removed for const-checking to pass.
|
||||
Primary,
|
||||
|
||||
/// An operation that causes const-checking to fail, but is usually a side-effect of a `Primary` operation elsewhere.
|
||||
Secondary,
|
||||
}
|
||||
|
||||
/// An operation that is not *always* allowed in a const context.
|
||||
pub trait NonConstOp: std::fmt::Debug {
|
||||
const STOPS_CONST_CHECKING: bool = false;
|
||||
|
||||
/// Returns an enum indicating whether this operation is allowed within the given item.
|
||||
fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
|
||||
Status::Forbidden
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0019,
|
||||
"{} contains unimplemented expression type",
|
||||
ccx.const_kind()
|
||||
);
|
||||
|
||||
if let Status::Unstable(gate) = self.status_in_item(ccx) {
|
||||
if !ccx.tcx.features().enabled(gate) && nightly_options::is_nightly_build() {
|
||||
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", gate));
|
||||
}
|
||||
}
|
||||
|
||||
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(
|
||||
"A function call isn't allowed in the const's initialization expression \
|
||||
because the expression's value must be known at compile-time.",
|
||||
);
|
||||
err.note(
|
||||
"Remember: you can't use a function call inside a const's initialization \
|
||||
expression! However, you can use it anywhere else.",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Abort;
|
||||
impl NonConstOp for Abort {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
mcf_status_in_item(ccx)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(ccx, span, "abort is not stable in const fn")
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
mcf_build_error(ccx, span, "abort is not stable in const fn")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FloatingPointOp;
|
||||
impl NonConstOp for FloatingPointOp {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
if ccx.const_kind() == hir::ConstContext::ConstFn {
|
||||
Status::Unstable(sym::const_fn_floating_point_arithmetic)
|
||||
|
@ -125,28 +64,13 @@ impl NonConstOp for FloatingPointOp {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_floating_point_arithmetic,
|
||||
span,
|
||||
&format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NonPrimitiveOp;
|
||||
impl NonConstOp for NonPrimitiveOp {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
mcf_status_in_item(ccx)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(ccx, span, "only int, `bool` and `char` operations are stable in const fn")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,10 +78,8 @@ impl NonConstOp for NonPrimitiveOp {
|
|||
#[derive(Debug)]
|
||||
pub struct FnCallIndirect;
|
||||
impl NonConstOp for FnCallIndirect {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
let mut err =
|
||||
ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn");
|
||||
err.emit();
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,16 +87,15 @@ impl NonConstOp for FnCallIndirect {
|
|||
#[derive(Debug)]
|
||||
pub struct FnCallNonConst(pub DefId);
|
||||
impl NonConstOp for FnCallNonConst {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
let mut err = struct_span_err!(
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0015,
|
||||
"calls in {}s are limited to constant functions, \
|
||||
tuple structs and tuple variants",
|
||||
ccx.const_kind(),
|
||||
);
|
||||
err.emit();
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +106,7 @@ impl NonConstOp for FnCallNonConst {
|
|||
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
|
||||
|
||||
impl NonConstOp for FnCallUnstable {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let FnCallUnstable(def_id, feature) = *self;
|
||||
|
||||
let mut err = ccx.tcx.sess.struct_span_err(
|
||||
|
@ -203,15 +124,14 @@ impl NonConstOp for FnCallUnstable {
|
|||
));
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FnPtrCast;
|
||||
impl NonConstOp for FnPtrCast {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
|
@ -220,37 +140,32 @@ impl NonConstOp for FnPtrCast {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_fn_ptr_basics,
|
||||
span,
|
||||
&format!("function pointer casts are not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
.emit()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Generator;
|
||||
impl NonConstOp for Generator {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
// FIXME: This means generator-only MIR is only forbidden in const fn. This is for
|
||||
// compatibility with the old code. Such MIR should be forbidden everywhere.
|
||||
mcf_status_in_item(ccx)
|
||||
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
||||
Status::Forbidden
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(ccx, span, "const fn generators are unstable");
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HeapAllocation;
|
||||
impl NonConstOp for HeapAllocation {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
|
@ -267,38 +182,48 @@ impl NonConstOp for HeapAllocation {
|
|||
be done at compile time.",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InlineAsm;
|
||||
impl NonConstOp for InlineAsm {}
|
||||
impl NonConstOp for InlineAsm {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0015,
|
||||
"inline assembly is not allowed in {}s",
|
||||
ccx.const_kind()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LiveDrop {
|
||||
pub dropped_at: Option<Span>,
|
||||
}
|
||||
impl NonConstOp for LiveDrop {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
let mut diagnostic = struct_span_err!(
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
E0493,
|
||||
"destructors cannot be evaluated at compile-time"
|
||||
);
|
||||
diagnostic.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()));
|
||||
err.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()));
|
||||
if let Some(span) = self.dropped_at {
|
||||
diagnostic.span_label(span, "value is dropped here");
|
||||
err.span_label(span, "value is dropped here");
|
||||
}
|
||||
diagnostic.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CellBorrow;
|
||||
impl NonConstOp for CellBorrow {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
|
@ -306,7 +231,6 @@ impl NonConstOp for CellBorrow {
|
|||
"cannot borrow a constant which may contain \
|
||||
interior mutability, create a static instead"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,7 +246,7 @@ impl NonConstOp for MutBorrow {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
|
@ -353,7 +277,7 @@ impl NonConstOp for MutBorrow {
|
|||
static mut or a global UnsafeCell.",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,14 +294,13 @@ impl NonConstOp for MutAddressOf {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_mut_refs,
|
||||
span,
|
||||
&format!("`&raw mut` is not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -387,6 +310,20 @@ impl NonConstOp for MutDeref {
|
|||
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
||||
Status::Unstable(sym::const_mut_refs)
|
||||
}
|
||||
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
// Usually a side-effect of a `MutBorrow` somewhere.
|
||||
DiagnosticImportance::Secondary
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_mut_refs,
|
||||
span,
|
||||
&format!("mutation through a reference is not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -396,21 +333,20 @@ impl NonConstOp for Panic {
|
|||
Status::Unstable(sym::const_panic)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_panic,
|
||||
span,
|
||||
&format!("panicking in {}s is unstable", ccx.const_kind()),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawPtrComparison;
|
||||
impl NonConstOp for RawPtrComparison {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = ccx
|
||||
.tcx
|
||||
.sess
|
||||
|
@ -419,7 +355,7 @@ impl NonConstOp for RawPtrComparison {
|
|||
"see issue #53020 <https://github.com/rust-lang/rust/issues/53020> \
|
||||
for more information",
|
||||
);
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,14 +366,13 @@ impl NonConstOp for RawPtrDeref {
|
|||
Status::Unstable(sym::const_raw_ptr_deref)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_raw_ptr_deref,
|
||||
span,
|
||||
&format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,14 +383,13 @@ impl NonConstOp for RawPtrToIntCast {
|
|||
Status::Unstable(sym::const_raw_ptr_to_usize_cast)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_raw_ptr_to_usize_cast,
|
||||
span,
|
||||
&format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,7 +405,7 @@ impl NonConstOp for StaticAccess {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
|
@ -489,7 +423,7 @@ impl NonConstOp for StaticAccess {
|
|||
);
|
||||
err.help("To fix this, the value can be extracted to a `const` and then used.");
|
||||
}
|
||||
err.emit();
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,7 +431,7 @@ impl NonConstOp for StaticAccess {
|
|||
#[derive(Debug)]
|
||||
pub struct ThreadLocalAccess;
|
||||
impl NonConstOp for ThreadLocalAccess {
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
span,
|
||||
|
@ -505,15 +439,12 @@ impl NonConstOp for ThreadLocalAccess {
|
|||
"thread-local statics cannot be \
|
||||
accessed at compile-time"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Transmute;
|
||||
impl NonConstOp for Transmute {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
|
@ -522,15 +453,15 @@ impl NonConstOp for Transmute {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
feature_err(
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_transmute,
|
||||
span,
|
||||
&format!("`transmute` is not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
.note("`transmute` is only allowed in constants and statics for now")
|
||||
.emit();
|
||||
);
|
||||
err.note("`transmute` is only allowed in constants and statics for now");
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,14 +477,13 @@ impl NonConstOp for UnionAccess {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_union,
|
||||
span,
|
||||
"unions in const fn are unstable",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,12 +497,12 @@ impl NonConstOp for UnsizingCast {
|
|||
mcf_status_in_item(ccx)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
mcf_build_error(
|
||||
ccx,
|
||||
span,
|
||||
"unsizing casts to types besides slices are not allowed in const fn",
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -581,29 +511,42 @@ pub mod ty {
|
|||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MutRef;
|
||||
pub struct MutRef(pub mir::LocalKind);
|
||||
impl NonConstOp for MutRef {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
|
||||
Status::Unstable(sym::const_mut_refs)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
match self.0 {
|
||||
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_mut_refs,
|
||||
span,
|
||||
&format!("mutable references are not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
.emit()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FnPtr;
|
||||
pub struct FnPtr(pub mir::LocalKind);
|
||||
impl NonConstOp for FnPtr {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
match self.0 {
|
||||
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
|
@ -613,46 +556,50 @@ pub mod ty {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_fn_ptr_basics,
|
||||
span,
|
||||
&format!("function pointers cannot appear in {}s", ccx.const_kind()),
|
||||
)
|
||||
.emit()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplTrait;
|
||||
impl NonConstOp for ImplTrait {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
mcf_status_in_item(ccx)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(ccx, span, "`impl Trait` in const fn is unstable");
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
mcf_build_error(ccx, span, "`impl Trait` in const fn is unstable")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TraitBound;
|
||||
pub struct TraitBound(pub mir::LocalKind);
|
||||
impl NonConstOp for TraitBound {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
match self.0 {
|
||||
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
mcf_status_in_item(ccx)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
mcf_emit_error(
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
mcf_build_error(
|
||||
ccx,
|
||||
span,
|
||||
"trait bounds other than `Sized` on const fn parameters are unstable",
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -660,20 +607,17 @@ pub mod ty {
|
|||
#[derive(Debug)]
|
||||
pub struct TraitBoundNotConst;
|
||||
impl NonConstOp for TraitBoundNotConst {
|
||||
const STOPS_CONST_CHECKING: bool = true;
|
||||
|
||||
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
||||
Status::Unstable(sym::const_trait_bound_opt_out)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_trait_bound_opt_out,
|
||||
span,
|
||||
"`?const Trait` syntax is unstable",
|
||||
)
|
||||
.emit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -686,12 +630,12 @@ fn mcf_status_in_item(ccx: &ConstCx<'_, '_>) -> Status {
|
|||
}
|
||||
}
|
||||
|
||||
fn mcf_emit_error(ccx: &ConstCx<'_, '_>, span: Span, msg: &str) {
|
||||
struct_span_err!(ccx.tcx.sess, span, E0723, "{}", msg)
|
||||
.note(
|
||||
"see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
|
||||
fn mcf_build_error(ccx: &ConstCx<'_, 'tcx>, span: Span, msg: &str) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(ccx.tcx.sess, span, E0723, "{}", msg);
|
||||
err.note(
|
||||
"see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
|
||||
for more information",
|
||||
)
|
||||
.help("add `#![feature(const_fn)]` to the crate attributes to enable")
|
||||
.emit();
|
||||
);
|
||||
err.help("add `#![feature(const_fn)]` to the crate attributes to enable");
|
||||
err
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_middle::mir::{self, BasicBlock, Location};
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::ops;
|
||||
use super::ops::{self, NonConstOp};
|
||||
use super::qualifs::{NeedsDrop, Qualif};
|
||||
use super::validation::Qualifs;
|
||||
use super::ConstCx;
|
||||
|
@ -56,7 +56,7 @@ impl std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
|
|||
|
||||
impl CheckLiveDrops<'mir, 'tcx> {
|
||||
fn check_live_drop(&self, span: Span) {
|
||||
ops::non_const(self.ccx, ops::LiveDrop { dropped_at: None }, span);
|
||||
ops::LiveDrop { dropped_at: None }.build_error(self.ccx, span).emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
|
||||
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir::{self as hir, LangItem};
|
||||
use rustc_hir::{def_id::DefId, HirId};
|
||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{self as hir, HirId, LangItem};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
|
@ -11,13 +11,14 @@ use rustc_middle::ty::subst::GenericArgKind;
|
|||
use rustc_middle::ty::{
|
||||
self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt, TypeAndMut,
|
||||
};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{self, TraitEngine};
|
||||
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
|
||||
use super::ops::{self, NonConstOp};
|
||||
use super::ops::{self, NonConstOp, Status};
|
||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
|
||||
use super::resolver::FlowSensitiveAnalysis;
|
||||
use super::{is_lang_panic_fn, ConstCx, Qualif};
|
||||
|
@ -180,7 +181,8 @@ pub struct Validator<'mir, 'tcx> {
|
|||
/// The span of the current statement.
|
||||
span: Span,
|
||||
|
||||
const_checking_stopped: bool,
|
||||
error_emitted: bool,
|
||||
secondary_errors: Vec<Diagnostic>,
|
||||
}
|
||||
|
||||
impl Deref for Validator<'mir, 'tcx> {
|
||||
|
@ -197,13 +199,21 @@ impl Validator<'mir, 'tcx> {
|
|||
span: ccx.body.span,
|
||||
ccx,
|
||||
qualifs: Default::default(),
|
||||
const_checking_stopped: false,
|
||||
error_emitted: false,
|
||||
secondary_errors: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_body(&mut self) {
|
||||
let ConstCx { tcx, body, def_id, .. } = *self.ccx;
|
||||
|
||||
// `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
|
||||
// no need to emit duplicate errors here.
|
||||
if is_async_fn(self.ccx) || body.generator_kind.is_some() {
|
||||
tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
|
||||
return;
|
||||
}
|
||||
|
||||
// The local type and predicate checks are not free and only relevant for `const fn`s.
|
||||
if self.const_kind() == hir::ConstContext::ConstFn {
|
||||
// Prevent const trait methods from being annotated as `stable`.
|
||||
|
@ -223,20 +233,21 @@ impl Validator<'mir, 'tcx> {
|
|||
|
||||
self.check_item_predicates();
|
||||
|
||||
for local in &body.local_decls {
|
||||
if local.internal {
|
||||
for (idx, local) in body.local_decls.iter_enumerated() {
|
||||
// Handle the return place below.
|
||||
if idx == RETURN_PLACE || local.internal {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.span = local.source_info.span;
|
||||
self.check_local_or_return_ty(local.ty);
|
||||
self.check_local_or_return_ty(local.ty, idx);
|
||||
}
|
||||
|
||||
// impl trait is gone in MIR, so check the return type of a const fn by its signature
|
||||
// instead of the type of the return place.
|
||||
self.span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
let return_ty = tcx.fn_sig(def_id).output();
|
||||
self.check_local_or_return_ty(return_ty.skip_binder());
|
||||
self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE);
|
||||
}
|
||||
|
||||
self.visit_body(&body);
|
||||
|
@ -250,6 +261,17 @@ impl Validator<'mir, 'tcx> {
|
|||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
check_return_ty_is_sync(tcx, &body, hir_id);
|
||||
}
|
||||
|
||||
// If we got through const-checking without emitting any "primary" errors, emit any
|
||||
// "secondary" errors if they occurred.
|
||||
let secondary_errors = mem::take(&mut self.secondary_errors);
|
||||
if !self.error_emitted {
|
||||
for error in secondary_errors {
|
||||
self.tcx.sess.diagnostic().emit_diagnostic(&error);
|
||||
}
|
||||
} else {
|
||||
assert!(self.tcx.sess.has_errors());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn qualifs_in_return_place(&mut self) -> ConstQualifs {
|
||||
|
@ -264,15 +286,38 @@ impl Validator<'mir, 'tcx> {
|
|||
/// Emits an error at the given `span` if an expression cannot be evaluated in the current
|
||||
/// context.
|
||||
pub fn check_op_spanned<O: NonConstOp>(&mut self, op: O, span: Span) {
|
||||
// HACK: This is for strict equivalence with the old `qualify_min_const_fn` pass, which
|
||||
// only emitted one error per function. It should be removed and the test output updated.
|
||||
if self.const_checking_stopped {
|
||||
let gate = match op.status_in_item(self.ccx) {
|
||||
Status::Allowed => return,
|
||||
|
||||
Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
|
||||
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
|
||||
&& !super::allow_internal_unstable(self.tcx, self.def_id.to_def_id(), gate);
|
||||
if unstable_in_stable {
|
||||
emit_unstable_in_stable_error(self.ccx, span, gate);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Status::Unstable(gate) => Some(gate),
|
||||
Status::Forbidden => None,
|
||||
};
|
||||
|
||||
if self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
|
||||
self.tcx.sess.miri_unleashed_feature(span, gate);
|
||||
return;
|
||||
}
|
||||
|
||||
let err_emitted = ops::non_const(self.ccx, op, span);
|
||||
if err_emitted && O::STOPS_CONST_CHECKING {
|
||||
self.const_checking_stopped = true;
|
||||
let mut err = op.build_error(self.ccx, span);
|
||||
assert!(err.is_error());
|
||||
|
||||
match op.importance() {
|
||||
ops::DiagnosticImportance::Primary => {
|
||||
self.error_emitted = true;
|
||||
err.emit();
|
||||
}
|
||||
|
||||
ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,7 +329,9 @@ impl Validator<'mir, 'tcx> {
|
|||
self.check_op_spanned(ops::StaticAccess, span)
|
||||
}
|
||||
|
||||
fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>) {
|
||||
fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) {
|
||||
let kind = self.body.local_kind(local);
|
||||
|
||||
for ty in ty.walk() {
|
||||
let ty = match ty.unpack() {
|
||||
GenericArgKind::Type(ty) => ty,
|
||||
|
@ -295,20 +342,20 @@ impl Validator<'mir, 'tcx> {
|
|||
};
|
||||
|
||||
match *ty.kind() {
|
||||
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef),
|
||||
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
|
||||
ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
|
||||
ty::FnPtr(..) => self.check_op(ops::ty::FnPtr),
|
||||
ty::FnPtr(..) => self.check_op(ops::ty::FnPtr(kind)),
|
||||
|
||||
ty::Dynamic(preds, _) => {
|
||||
for pred in preds.iter() {
|
||||
match pred.skip_binder() {
|
||||
ty::ExistentialPredicate::AutoTrait(_)
|
||||
| ty::ExistentialPredicate::Projection(_) => {
|
||||
self.check_op(ops::ty::TraitBound)
|
||||
self.check_op(ops::ty::TraitBound(kind))
|
||||
}
|
||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
||||
if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
|
||||
self.check_op(ops::ty::TraitBound)
|
||||
self.check_op(ops::ty::TraitBound(kind))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,15 +400,19 @@ impl Validator<'mir, 'tcx> {
|
|||
let def = generics.type_param(p, tcx);
|
||||
let span = tcx.def_span(def.def_id);
|
||||
|
||||
// These are part of the function signature, so treat them like
|
||||
// arguments when determining importance.
|
||||
let kind = LocalKind::Arg;
|
||||
|
||||
if constness == hir::Constness::Const {
|
||||
self.check_op_spanned(ops::ty::TraitBound, span);
|
||||
self.check_op_spanned(ops::ty::TraitBound(kind), span);
|
||||
} else if !tcx.features().const_fn
|
||||
|| self.ccx.is_const_stable_const_fn()
|
||||
{
|
||||
// HACK: We shouldn't need the conditional above, but trait
|
||||
// bounds on containing impl blocks are wrongly being marked as
|
||||
// "not-const".
|
||||
self.check_op_spanned(ops::ty::TraitBound, span);
|
||||
self.check_op_spanned(ops::ty::TraitBound(kind), span);
|
||||
}
|
||||
}
|
||||
// other kinds of bounds are either tautologies
|
||||
|
@ -877,3 +928,31 @@ fn place_as_reborrow(
|
|||
fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
|
||||
ty.is_bool() || ty.is_integral() || ty.is_char()
|
||||
}
|
||||
|
||||
fn is_async_fn(ccx: &ConstCx<'_, '_>) -> bool {
|
||||
ccx.fn_sig().map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async)
|
||||
}
|
||||
|
||||
fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
|
||||
let attr_span = ccx.fn_sig().map_or(ccx.body.span, |sig| sig.span.shrink_to_lo());
|
||||
|
||||
ccx.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
|
||||
)
|
||||
.span_suggestion(
|
||||
attr_span,
|
||||
"if it is not part of the public API, make this function unstably const",
|
||||
concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.span_suggestion(
|
||||
attr_span,
|
||||
"otherwise `#[allow_internal_unstable]` can be used to bypass stability checks",
|
||||
format!("#[allow_internal_unstable({})]\n", gate),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ const fn f(x: usize) -> usize {
|
|||
let mut sum = 0;
|
||||
for i in 0..x {
|
||||
//~^ ERROR mutable references
|
||||
//~| ERROR calls in constant functions
|
||||
//~| ERROR calls in constant functions
|
||||
//~| ERROR E0080
|
||||
//~| ERROR E0744
|
||||
sum += i;
|
||||
|
|
|
@ -3,4 +3,3 @@
|
|||
|
||||
pub const async fn x() {}
|
||||
//~^ ERROR functions cannot be both `const` and `async`
|
||||
//~| ERROR `impl Trait` in const fn is unstable
|
||||
|
|
|
@ -7,15 +7,5 @@ LL | pub const async fn x() {}
|
|||
| | `async` because of this
|
||||
| `const` because of this
|
||||
|
||||
error[E0723]: `impl Trait` in const fn is unstable
|
||||
--> $DIR/no-const-async.rs:4:24
|
||||
|
|
||||
LL | pub const async fn x() {}
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0723`.
|
||||
|
|
|
@ -78,7 +78,6 @@ struct MyOwned;
|
|||
|
||||
static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR static contains unimplemented expression type
|
||||
|
||||
static mut STATIC12: UnsafeStruct = UnsafeStruct;
|
||||
|
||||
|
@ -93,16 +92,12 @@ static mut STATIC14: SafeStruct = SafeStruct {
|
|||
|
||||
static STATIC15: &'static [Box<MyOwned>] = &[
|
||||
box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
];
|
||||
|
||||
static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) = (
|
||||
&box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
&box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
);
|
||||
|
||||
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
||||
|
@ -110,11 +105,9 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
|||
static STATIC19: Box<isize> =
|
||||
box 3;
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
|
||||
pub fn main() {
|
||||
let y = { static x: Box<isize> = box 3; x };
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR cannot move out of static item
|
||||
//~| ERROR contains unimplemented expression
|
||||
}
|
||||
|
|
|
@ -15,92 +15,44 @@ error[E0010]: allocations are not allowed in statics
|
|||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:79:37
|
||||
|
|
||||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/check-static-values-constraints.rs:90:32
|
||||
--> $DIR/check-static-values-constraints.rs:89:32
|
||||
|
|
||||
LL | field2: SafeEnum::Variant4("str".to_string())
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:94:5
|
||||
|
|
||||
LL | box MyOwned,
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:95:5
|
||||
|
|
||||
LL | box MyOwned,
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:95:9
|
||||
|
|
||||
LL | box MyOwned,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:97:5
|
||||
|
|
||||
LL | box MyOwned,
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:97:9
|
||||
|
|
||||
LL | box MyOwned,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:102:6
|
||||
--> $DIR/check-static-values-constraints.rs:99:6
|
||||
|
|
||||
LL | &box MyOwned,
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:102:10
|
||||
|
|
||||
LL | &box MyOwned,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:104:6
|
||||
--> $DIR/check-static-values-constraints.rs:100:6
|
||||
|
|
||||
LL | &box MyOwned,
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:104:10
|
||||
|
|
||||
LL | &box MyOwned,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:111:5
|
||||
--> $DIR/check-static-values-constraints.rs:106:5
|
||||
|
|
||||
LL | box 3;
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:111:9
|
||||
|
|
||||
LL | box 3;
|
||||
| ^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0507]: cannot move out of static item `x`
|
||||
--> $DIR/check-static-values-constraints.rs:116:45
|
||||
--> $DIR/check-static-values-constraints.rs:110:45
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^
|
||||
|
@ -109,20 +61,12 @@ LL | let y = { static x: Box<isize> = box 3; x };
|
|||
| help: consider borrowing here: `&x`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:116:38
|
||||
--> $DIR/check-static-values-constraints.rs:110:38
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:116:42
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015, E0019, E0493, E0507.
|
||||
Some errors have detailed explanations: E0010, E0015, E0493, E0507.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -2,8 +2,6 @@ const WRITE: () = unsafe {
|
|||
*std::ptr::null_mut() = 0;
|
||||
//~^ ERROR dereferencing raw pointers in constants is unstable
|
||||
//~| HELP add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
|
||||
//~| ERROR constant contains unimplemented expression type
|
||||
//~| HELP add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -7,15 +7,6 @@ LL | *std::ptr::null_mut() = 0;
|
|||
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
|
||||
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/const-suggest-feature.rs:2:5
|
||||
|
|
||||
LL | *std::ptr::null_mut() = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0658.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// New test for #53818: modifying static memory at compile-time is not allowed.
|
||||
// The test should never compile successfully
|
||||
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(const_raw_ptr_deref, const_mut_refs)]
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
|
@ -13,7 +13,7 @@ unsafe impl Sync for Foo {}
|
|||
static FOO: Foo = Foo(UnsafeCell::new(42));
|
||||
|
||||
static BAR: () = unsafe {
|
||||
*FOO.0.get() = 5; //~ ERROR contains unimplemented expression type
|
||||
*FOO.0.get() = 5; //~ ERROR
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
error[E0019]: static contains unimplemented expression type
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/assign-to-static-within-other-static-2.rs:16:5
|
||||
|
|
||||
LL | *FOO.0.get() = 5;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
| ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -12,14 +12,9 @@ unsafe impl Sync for Foo {}
|
|||
|
||||
static FOO: Foo = Foo(UnsafeCell::new(42));
|
||||
|
||||
fn foo() {}
|
||||
|
||||
static BAR: () = unsafe {
|
||||
*FOO.0.get() = 5;
|
||||
//~^ contains unimplemented expression
|
||||
|
||||
foo();
|
||||
//~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
//~^ mutation through a reference
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/mod-static-with-const-fn.rs:18:5
|
||||
error[E0658]: mutation through a reference is not allowed in statics
|
||||
--> $DIR/mod-static-with-const-fn.rs:16:5
|
||||
|
|
||||
LL | *FOO.0.get() = 5;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/mod-static-with-const-fn.rs:21:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0019.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
const unsafe extern "C" fn closure() -> fn() { || {} }
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer cast
|
||||
const unsafe extern fn use_float() { 1.0 + 1.0; }
|
||||
//~^ ERROR floating point arithmetic
|
||||
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
|
||||
|
|
|
@ -7,8 +7,17 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:4:48
|
||||
|
|
||||
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: floating point arithmetic is not allowed in constant functions
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:6:38
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:7:38
|
||||
|
|
||||
LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
|
||||
| ^^^^^^^^^
|
||||
|
@ -17,7 +26,7 @@ LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
|
|||
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: casting pointers to integers in constant functions is unstable
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:9:48
|
||||
|
|
||||
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -25,6 +34,6 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
|
|||
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
|
||||
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -6,23 +6,21 @@ struct S {
|
|||
|
||||
impl S {
|
||||
const fn foo(&mut self, x: u32) {
|
||||
//~^ ERROR mutable references
|
||||
//~^ ERROR mutable reference
|
||||
self.state = x;
|
||||
}
|
||||
}
|
||||
|
||||
const FOO: S = {
|
||||
let mut s = S { state: 42 };
|
||||
s.foo(3); //~ ERROR mutable references are not allowed in constants
|
||||
s.foo(3); //~ ERROR mutable reference
|
||||
s
|
||||
};
|
||||
|
||||
type Array = [u32; {
|
||||
let mut x = 2;
|
||||
let y = &mut x;
|
||||
//~^ ERROR mutable references are not allowed in constants
|
||||
let y = &mut x; //~ ERROR mutable reference
|
||||
*y = 42;
|
||||
//~^ ERROR constant contains unimplemented expression type
|
||||
*y
|
||||
}];
|
||||
|
||||
|
|
|
@ -19,15 +19,7 @@ error[E0764]: mutable references are not allowed in constants
|
|||
LL | let y = &mut x;
|
||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/const_let_assign3.rs:24:5
|
||||
|
|
||||
LL | *y = 42;
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0658, E0764.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
Some errors have detailed explanations: E0658, E0764.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(llvm_asm)]
|
||||
|
||||
const _: () = unsafe { llvm_asm!("nop") };
|
||||
//~^ ERROR contains unimplemented expression type
|
||||
//~^ ERROR inline assembly
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0019]: constant contains unimplemented expression type
|
||||
error[E0015]: inline assembly is not allowed in constants
|
||||
--> $DIR/inline_asm.rs:3:24
|
||||
|
|
||||
LL | const _: () = unsafe { llvm_asm!("nop") };
|
||||
|
@ -8,4 +8,4 @@ LL | const _: () = unsafe { llvm_asm!("nop") };
|
|||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -4,11 +4,14 @@ error: const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
|
|||
LL | const fn error(_: fn()) {}
|
||||
| ^
|
||||
|
|
||||
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
help: if it is not part of the public API, make this function unstably const
|
||||
|
|
||||
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
|
|
||||
help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
|
|
||||
LL | #[allow_internal_unstable(const_fn_fn_ptr_basics)]
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const fn foo(a: i32) -> Vec<i32> {
|
||||
vec![1, 2, 3]
|
||||
//~^ ERROR allocations are not allowed
|
||||
//~| ERROR unimplemented expression type
|
||||
//~| ERROR calls in constant functions
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,6 @@ LL | vec![1, 2, 3]
|
|||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0019]: constant function contains unimplemented expression type
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
LL | vec![1, 2, 3]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
|
@ -23,7 +14,7 @@ LL | vec![1, 2, 3]
|
|||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015, E0019.
|
||||
Some errors have detailed explanations: E0010, E0015.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -3,11 +3,15 @@ fn main() {}
|
|||
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
const fn closure() -> fn() { || {} }
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer cast
|
||||
const fn closure2() {
|
||||
(|| {}) as fn();
|
||||
//~^ ERROR function pointer
|
||||
}
|
||||
const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer
|
||||
//~| ERROR function pointer cast
|
||||
const fn reify2() { main as unsafe fn(); }
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer cast
|
||||
|
|
|
@ -7,17 +7,35 @@ LL | const fn closure() -> fn() { || {} }
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/cast_errors.rs:7:5
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/cast_errors.rs:4:30
|
||||
|
|
||||
LL | const fn closure() -> fn() { || {} }
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/cast_errors.rs:8:5
|
||||
|
|
||||
LL | (|| {}) as fn();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/cast_errors.rs:10:28
|
||||
--> $DIR/cast_errors.rs:11:16
|
||||
|
|
||||
LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/cast_errors.rs:11:28
|
||||
|
|
||||
LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -25,15 +43,33 @@ LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/cast_errors.rs:12:21
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/cast_errors.rs:11:42
|
||||
|
|
||||
LL | const fn reify2() { main as unsafe fn(); }
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/cast_errors.rs:15:21
|
||||
|
|
||||
LL | const fn reify2() { main as unsafe fn(); }
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/cast_errors.rs:15:21
|
||||
|
|
||||
LL | const fn reify2() { main as unsafe fn(); }
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointer
|
||||
const fn cmp(x: fn(), y: fn()) -> bool {
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer
|
||||
unsafe { x == y }
|
||||
//~^ ERROR pointers cannot be reliably compared
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -7,6 +7,23 @@ LL | const fn cmp(x: fn(), y: fn()) -> bool {
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/cmp_fn_pointers.rs:1:23
|
||||
|
|
||||
LL | const fn cmp(x: fn(), y: fn()) -> bool {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: pointers cannot be reliably compared during const eval.
|
||||
--> $DIR/cmp_fn_pointers.rs:4:14
|
||||
|
|
||||
LL | unsafe { x == y }
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -38,6 +38,8 @@ impl<T> Foo<T> {
|
|||
const fn get(&self) -> &T { &self.0 }
|
||||
const fn get_mut(&mut self) -> &mut T { &mut self.0 }
|
||||
//~^ mutable references
|
||||
//~| mutable references
|
||||
//~| mutable references
|
||||
}
|
||||
impl<'a, T> Foo<T> {
|
||||
const fn new_lt(t: T) -> Self { Foo(t) }
|
||||
|
@ -45,6 +47,8 @@ impl<'a, T> Foo<T> {
|
|||
const fn get_lt(&'a self) -> &T { &self.0 }
|
||||
const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
|
||||
//~^ mutable references
|
||||
//~| mutable references
|
||||
//~| mutable references
|
||||
}
|
||||
impl<T: Sized> Foo<T> {
|
||||
const fn new_s(t: T) -> Self { Foo(t) }
|
||||
|
@ -52,11 +56,15 @@ impl<T: Sized> Foo<T> {
|
|||
const fn get_s(&self) -> &T { &self.0 }
|
||||
const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
|
||||
//~^ mutable references
|
||||
//~| mutable references
|
||||
//~| mutable references
|
||||
}
|
||||
impl<T: ?Sized> Foo<T> {
|
||||
const fn get_sq(&self) -> &T { &self.0 }
|
||||
const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
|
||||
//~^ mutable references
|
||||
//~| mutable references
|
||||
//~| mutable references
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,17 +125,24 @@ impl<T: Sync + Sized> Foo<T> {
|
|||
struct AlanTuring<T>(T);
|
||||
const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||
//~| ERROR destructor
|
||||
const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
//~| ERROR destructor
|
||||
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
//~| ERROR unsizing cast
|
||||
//~| ERROR unsizing cast
|
||||
|
||||
const fn no_unsafe() { unsafe {} }
|
||||
|
||||
const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
//~^ ERROR unsizing cast
|
||||
|
||||
const fn no_fn_ptrs(_x: fn()) {}
|
||||
//~^ ERROR function pointer
|
||||
const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||
//~^ ERROR function pointer
|
||||
//~| ERROR function pointer cast
|
||||
|
|
|
@ -6,6 +6,15 @@ LL | const fn into_inner(self) -> T { self.0 }
|
|||
| |
|
||||
| constant functions cannot evaluate destructors
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:39:22
|
||||
|
|
||||
LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:39:36
|
||||
|
|
||||
|
@ -15,8 +24,17 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
|
|||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:39:45
|
||||
|
|
||||
LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/min_const_fn.rs:44:28
|
||||
--> $DIR/min_const_fn.rs:46:28
|
||||
|
|
||||
LL | const fn into_inner_lt(self) -> T { self.0 }
|
||||
| ^^^^ - value is dropped here
|
||||
|
@ -24,7 +42,16 @@ LL | const fn into_inner_lt(self) -> T { self.0 }
|
|||
| constant functions cannot evaluate destructors
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:46:42
|
||||
--> $DIR/min_const_fn.rs:48:25
|
||||
|
|
||||
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:48:42
|
||||
|
|
||||
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^
|
||||
|
@ -32,8 +59,17 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
|
|||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:48:51
|
||||
|
|
||||
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/min_const_fn.rs:51:27
|
||||
--> $DIR/min_const_fn.rs:55:27
|
||||
|
|
||||
LL | const fn into_inner_s(self) -> T { self.0 }
|
||||
| ^^^^ - value is dropped here
|
||||
|
@ -41,7 +77,16 @@ LL | const fn into_inner_s(self) -> T { self.0 }
|
|||
| constant functions cannot evaluate destructors
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:53:38
|
||||
--> $DIR/min_const_fn.rs:57:24
|
||||
|
|
||||
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:57:38
|
||||
|
|
||||
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^
|
||||
|
@ -50,7 +95,25 @@ LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
|
|||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:58:39
|
||||
--> $DIR/min_const_fn.rs:57:47
|
||||
|
|
||||
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:64:25
|
||||
|
|
||||
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:64:39
|
||||
|
|
||||
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^
|
||||
|
@ -58,8 +121,17 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
|
|||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:64:48
|
||||
|
|
||||
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:76:16
|
||||
--> $DIR/min_const_fn.rs:84:16
|
||||
|
|
||||
LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
|
||||
| ^
|
||||
|
@ -68,7 +140,7 @@ LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:78:18
|
||||
--> $DIR/min_const_fn.rs:86:18
|
||||
|
|
||||
LL | const fn foo11_2<T: Send>(t: T) -> T { t }
|
||||
| ^
|
||||
|
@ -77,7 +149,7 @@ LL | const fn foo11_2<T: Send>(t: T) -> T { t }
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
--> $DIR/min_const_fn.rs:82:27
|
||||
--> $DIR/min_const_fn.rs:90:27
|
||||
|
|
||||
LL | const fn foo25() -> u32 { BAR }
|
||||
| ^^^
|
||||
|
@ -85,7 +157,7 @@ LL | const fn foo25() -> u32 { BAR }
|
|||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
--> $DIR/min_const_fn.rs:83:37
|
||||
--> $DIR/min_const_fn.rs:91:37
|
||||
|
|
||||
LL | const fn foo26() -> &'static u32 { &BAR }
|
||||
| ^^^
|
||||
|
@ -93,7 +165,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
|
|||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0658]: casting pointers to integers in constant functions is unstable
|
||||
--> $DIR/min_const_fn.rs:84:42
|
||||
--> $DIR/min_const_fn.rs:92:42
|
||||
|
|
||||
LL | const fn foo30(x: *const u32) -> usize { x as usize }
|
||||
| ^^^^^^^^^^
|
||||
|
@ -102,7 +174,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
|
|||
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: casting pointers to integers in constant functions is unstable
|
||||
--> $DIR/min_const_fn.rs:86:63
|
||||
--> $DIR/min_const_fn.rs:94:63
|
||||
|
|
||||
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
|
||||
| ^^^^^^^^^^
|
||||
|
@ -111,7 +183,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
|
|||
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: casting pointers to integers in constant functions is unstable
|
||||
--> $DIR/min_const_fn.rs:88:42
|
||||
--> $DIR/min_const_fn.rs:96:42
|
||||
|
|
||||
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
||||
| ^^^^^^^^^^
|
||||
|
@ -120,7 +192,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
|||
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: casting pointers to integers in constant functions is unstable
|
||||
--> $DIR/min_const_fn.rs:90:63
|
||||
--> $DIR/min_const_fn.rs:98:63
|
||||
|
|
||||
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
|
||||
| ^^^^^^^^^^
|
||||
|
@ -129,7 +201,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
|
|||
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:93:14
|
||||
--> $DIR/min_const_fn.rs:101:14
|
||||
|
|
||||
LL | const fn inc(x: &mut i32) { *x += 1 }
|
||||
| ^
|
||||
|
@ -138,7 +210,7 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
|
|||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:102:6
|
||||
--> $DIR/min_const_fn.rs:110:6
|
||||
|
|
||||
LL | impl<T: std::fmt::Debug> Foo<T> {
|
||||
| ^
|
||||
|
@ -147,7 +219,7 @@ LL | impl<T: std::fmt::Debug> Foo<T> {
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:107:6
|
||||
--> $DIR/min_const_fn.rs:115:6
|
||||
|
|
||||
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
||||
| ^
|
||||
|
@ -156,7 +228,7 @@ LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:112:6
|
||||
--> $DIR/min_const_fn.rs:120:6
|
||||
|
|
||||
LL | impl<T: Sync + Sized> Foo<T> {
|
||||
| ^
|
||||
|
@ -165,7 +237,7 @@ LL | impl<T: Sync + Sized> Foo<T> {
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:118:34
|
||||
--> $DIR/min_const_fn.rs:126:34
|
||||
|
|
||||
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -173,8 +245,16 @@ LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/min_const_fn.rs:126:19
|
||||
|
|
||||
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||
| ^^ - value is dropped here
|
||||
| |
|
||||
| constant functions cannot evaluate destructors
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:120:22
|
||||
--> $DIR/min_const_fn.rs:129:22
|
||||
|
|
||||
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -182,8 +262,16 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/min_const_fn.rs:129:18
|
||||
|
|
||||
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||
| ^^ - value is dropped here
|
||||
| |
|
||||
| constant functions cannot evaluate destructors
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:121:23
|
||||
--> $DIR/min_const_fn.rs:132:23
|
||||
|
|
||||
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||
| ^^
|
||||
|
@ -192,7 +280,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
|||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:122:32
|
||||
--> $DIR/min_const_fn.rs:134:32
|
||||
|
|
||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -200,17 +288,35 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:127:41
|
||||
error[E0723]: unsizing casts to types besides slices are not allowed in const fn
|
||||
--> $DIR/min_const_fn.rs:134:63
|
||||
|
|
||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: unsizing casts to types besides slices are not allowed in const fn
|
||||
--> $DIR/min_const_fn.rs:134:63
|
||||
|
|
||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: unsizing casts to types besides slices are not allowed in const fn
|
||||
--> $DIR/min_const_fn.rs:141:42
|
||||
|
|
||||
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/min_const_fn.rs:130:21
|
||||
--> $DIR/min_const_fn.rs:144:21
|
||||
|
|
||||
LL | const fn no_fn_ptrs(_x: fn()) {}
|
||||
| ^^
|
||||
|
@ -219,7 +325,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
|
|||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
--> $DIR/min_const_fn.rs:132:27
|
||||
--> $DIR/min_const_fn.rs:146:27
|
||||
|
|
||||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||
| ^^^^
|
||||
|
@ -227,7 +333,16 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 26 previous errors
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/min_const_fn.rs:146:46
|
||||
|
|
||||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 39 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0013, E0493, E0658, E0723.
|
||||
For more information about an error, try `rustc --explain E0013`.
|
||||
|
|
|
@ -10,6 +10,6 @@ const fn no_inner_dyn_trait2(x: Hide) {
|
|||
//~^ ERROR trait bounds other than `Sized`
|
||||
}
|
||||
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||
//~^ ERROR trait bounds other than `Sized`
|
||||
//~^ ERROR unsizing cast
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | x.0.field;
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
error[E0723]: unsizing casts to types besides slices are not allowed in const fn
|
||||
--> $DIR/min_const_fn_dyn.rs:12:66
|
||||
|
|
||||
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | x.0.field;
|
|||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: function pointers cannot appear in constant functions
|
||||
error[E0658]: function pointer casts are not allowed in constant functions
|
||||
--> $DIR/min_const_fn_fn_ptr.rs:16:59
|
||||
|
|
||||
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) }
|
||||
|
|
|
@ -20,11 +20,14 @@ error: const-stable function cannot use `#[feature(const_fn_floating_point_arith
|
|||
LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
help: if it is not part of the public API, make this function unstably const
|
||||
|
|
||||
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
|
|
||||
help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
|
|
||||
LL | #[allow_internal_unstable(const_fn_floating_point_arithmetic)]
|
||||
|
|
||||
|
||||
error: `foo2_gated` is not yet stable as a const fn
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:39:32
|
||||
|
|
|
@ -20,11 +20,14 @@ error: const-stable function cannot use `#[feature(const_fn_floating_point_arith
|
|||
LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
help: if it is not part of the public API, make this function unstably const
|
||||
|
|
||||
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
|
|
||||
help: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
|
||||
|
|
||||
LL | #[allow_internal_unstable(const_fn_floating_point_arithmetic)]
|
||||
|
|
||||
|
||||
error: `foo2_gated` is not yet stable as a const fn
|
||||
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:39:48
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/mutable_borrow.rs:3:9
|
||||
--> $DIR/mutable_borrow.rs:3:13
|
||||
|
|
||||
LL | let b = &mut a;
|
||||
| ^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/mutable_borrow.rs:12:13
|
||||
--> $DIR/mutable_borrow.rs:12:17
|
||||
|
|
||||
LL | let b = &mut a;
|
||||
| ^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
|
|
@ -9,7 +9,6 @@ const FOO: &u32 = {
|
|||
{
|
||||
let b: *mut u32 = &mut a; //~ ERROR mutable references are not allowed in constants
|
||||
unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
|
||||
//[stock]~^ contains unimplemented expression
|
||||
}
|
||||
&{a}
|
||||
};
|
||||
|
|
|
@ -13,15 +13,7 @@ LL | unsafe { *b = 5; }
|
|||
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
|
||||
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/projection_qualif.rs:11:18
|
||||
|
|
||||
LL | unsafe { *b = 5; }
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0658, E0764.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
Some errors have detailed explanations: E0658, E0764.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -6,6 +6,5 @@ static mut STDERR_BUFFER_SPACE: u8 = 0;
|
|||
|
||||
pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
|
||||
//~^ ERROR mutable references are not allowed in statics
|
||||
//[stock]~| ERROR static contains unimplemented expression type
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -4,15 +4,6 @@ error[E0764]: mutable references are not allowed in statics
|
|||
LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/static_mut_containing_mut_ref2.rs:7:45
|
||||
|
|
||||
LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0764.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0764`.
|
||||
|
|
|
@ -4,6 +4,5 @@
|
|||
#![allow(warnings)]
|
||||
|
||||
const CON : Box<i32> = box 0; //~ ERROR E0010
|
||||
//~^ ERROR constant contains unimplemented expression type
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -6,17 +6,6 @@ LL | const CON : Box<i32> = box 0;
|
|||
|
|
||||
= 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.
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/E0010-teach.rs:6:28
|
||||
|
|
||||
LL | const CON : Box<i32> = box 0;
|
||||
| ^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
= note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time.
|
||||
= note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else.
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0019.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
For more information about this error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -2,6 +2,5 @@
|
|||
#![allow(warnings)]
|
||||
|
||||
const CON : Box<i32> = box 0; //~ ERROR E0010
|
||||
//~^ ERROR constant contains unimplemented expression type
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in constants
|
|||
LL | const CON : Box<i32> = box 0;
|
||||
| ^^^^^ allocation not allowed in constants
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/E0010.rs:4:28
|
||||
|
|
||||
LL | const CON : Box<i32> = box 0;
|
||||
| ^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0019.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
For more information about this error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -5,8 +5,8 @@ static mut M: i32 = 3;
|
|||
const CR: &'static mut i32 = &mut C; //~ ERROR E0764
|
||||
//~| WARN taking a mutable
|
||||
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764
|
||||
//~| ERROR E0019
|
||||
//~| ERROR cannot borrow
|
||||
|
||||
static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
|
||||
//~| WARN taking a mutable
|
||||
static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR E0764
|
||||
|
|
|
@ -19,14 +19,6 @@ error[E0764]: mutable references are not allowed in constants
|
|||
LL | const CR: &'static mut i32 = &mut C;
|
||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/E0017.rs:7:39
|
||||
|
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0764]: mutable references are not allowed in statics
|
||||
--> $DIR/E0017.rs:7:39
|
||||
|
|
||||
|
@ -65,7 +57,7 @@ error[E0764]: mutable references are not allowed in statics
|
|||
LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
|
||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error: aborting due to 6 previous errors; 2 warnings emitted
|
||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||
|
||||
Some errors have detailed explanations: E0019, E0596, E0764.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
Some errors have detailed explanations: E0596, E0764.
|
||||
For more information about an error, try `rustc --explain E0596`.
|
||||
|
|
|
@ -3,9 +3,9 @@ const C: i32 = 2;
|
|||
|
||||
const CR: &'static mut i32 = &mut C; //~ ERROR E0764
|
||||
//~| WARN taking a mutable
|
||||
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0019
|
||||
//~| ERROR cannot borrow
|
||||
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow
|
||||
//~| ERROR E0764
|
||||
|
||||
static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
|
||||
//~| WARN taking a mutable
|
||||
|
||||
|
|
|
@ -19,14 +19,6 @@ error[E0764]: mutable references are not allowed in constants
|
|||
LL | const CR: &'static mut i32 = &mut C;
|
||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/E0388.rs:6:39
|
||||
|
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0764]: mutable references are not allowed in statics
|
||||
--> $DIR/E0388.rs:6:39
|
||||
|
|
||||
|
@ -59,7 +51,7 @@ error[E0764]: mutable references are not allowed in statics
|
|||
LL | static CONST_REF: &'static mut i32 = &mut C;
|
||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||
|
||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||
error: aborting due to 4 previous errors; 2 warnings emitted
|
||||
|
||||
Some errors have detailed explanations: E0019, E0596, E0764.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
Some errors have detailed explanations: E0596, E0764.
|
||||
For more information about an error, try `rustc --explain E0596`.
|
||||
|
|
|
@ -6,6 +6,5 @@ use std::cell::RefCell;
|
|||
static boxed: Box<RefCell<isize>> = box RefCell::new(0);
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]
|
||||
//~| ERROR static contains unimplemented expression type
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -4,14 +4,6 @@ error[E0010]: allocations are not allowed in statics
|
|||
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
|
||||
| ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/issue-7364.rs:6:41
|
||||
|
|
||||
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0277]: `RefCell<isize>` cannot be shared between threads safely
|
||||
--> $DIR/issue-7364.rs:6:1
|
||||
|
|
||||
|
@ -23,7 +15,7 @@ LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
|
|||
= note: required because it appears within the type `Box<RefCell<isize>>`
|
||||
= note: shared static variables must have a type that implements `Sync`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0019, E0277.
|
||||
Some errors have detailed explanations: E0010, E0277.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -12,7 +12,6 @@ fn main() {
|
|||
extern "C" fn ff4() {} // OK.
|
||||
const async unsafe extern "C" fn ff5() {} // OK.
|
||||
//~^ ERROR functions cannot be both `const` and `async`
|
||||
//~| ERROR `from_generator` is not yet stable as a const fn
|
||||
|
||||
trait X {
|
||||
async fn ft1(); //~ ERROR functions in traits cannot be declared `async`
|
||||
|
@ -35,7 +34,6 @@ fn main() {
|
|||
const async unsafe extern "C" fn ft5() {}
|
||||
//~^ ERROR functions in traits cannot be declared `async`
|
||||
//~| ERROR functions in traits cannot be declared const
|
||||
//~| ERROR `from_generator` is not yet stable as a const fn
|
||||
//~| ERROR method `ft5` has an incompatible type for trait
|
||||
//~| ERROR functions cannot be both `const` and `async`
|
||||
}
|
||||
|
@ -47,7 +45,6 @@ fn main() {
|
|||
extern "C" fn fi4() {} // OK.
|
||||
const async unsafe extern "C" fn fi5() {}
|
||||
//~^ ERROR functions cannot be both `const` and `async`
|
||||
//~| ERROR `from_generator` is not yet stable as a const fn
|
||||
}
|
||||
|
||||
extern {
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | const async unsafe extern "C" fn ff5() {} // OK.
|
|||
| `const` because of this
|
||||
|
||||
error[E0706]: functions in traits cannot be declared `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:18:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:17:9
|
||||
|
|
||||
LL | async fn ft1();
|
||||
| -----^^^^^^^^^^
|
||||
|
@ -19,19 +19,19 @@ LL | async fn ft1();
|
|||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
||||
|
||||
error[E0379]: functions in traits cannot be declared const
|
||||
--> $DIR/fn-header-semantic-fail.rs:20:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:19:9
|
||||
|
|
||||
LL | const fn ft3();
|
||||
| ^^^^^ functions in traits cannot be const
|
||||
|
||||
error[E0379]: functions in traits cannot be declared const
|
||||
--> $DIR/fn-header-semantic-fail.rs:22:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:21:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5();
|
||||
| ^^^^^ functions in traits cannot be const
|
||||
|
||||
error[E0706]: functions in traits cannot be declared `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:22:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:21:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5();
|
||||
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -42,7 +42,7 @@ LL | const async unsafe extern "C" fn ft5();
|
|||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
||||
|
||||
error: functions cannot be both `const` and `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:22:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:21:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5();
|
||||
| ^^^^^-^^^^^----------------------------
|
||||
|
@ -51,7 +51,7 @@ LL | const async unsafe extern "C" fn ft5();
|
|||
| `const` because of this
|
||||
|
||||
error[E0706]: functions in traits cannot be declared `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:30:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:29:9
|
||||
|
|
||||
LL | async fn ft1() {}
|
||||
| -----^^^^^^^^^^^^
|
||||
|
@ -62,19 +62,19 @@ LL | async fn ft1() {}
|
|||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
||||
|
||||
error[E0379]: functions in traits cannot be declared const
|
||||
--> $DIR/fn-header-semantic-fail.rs:33:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:32:9
|
||||
|
|
||||
LL | const fn ft3() {}
|
||||
| ^^^^^ functions in traits cannot be const
|
||||
|
||||
error[E0379]: functions in traits cannot be declared const
|
||||
--> $DIR/fn-header-semantic-fail.rs:35:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:34:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
| ^^^^^ functions in traits cannot be const
|
||||
|
||||
error[E0706]: functions in traits cannot be declared `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:35:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:34:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -85,7 +85,7 @@ LL | const async unsafe extern "C" fn ft5() {}
|
|||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
||||
|
||||
error: functions cannot be both `const` and `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:35:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:34:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
| ^^^^^-^^^^^------------------------------
|
||||
|
@ -94,7 +94,7 @@ LL | const async unsafe extern "C" fn ft5() {}
|
|||
| `const` because of this
|
||||
|
||||
error: functions cannot be both `const` and `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:48:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:46:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn fi5() {}
|
||||
| ^^^^^-^^^^^------------------------------
|
||||
|
@ -103,7 +103,7 @@ LL | const async unsafe extern "C" fn fi5() {}
|
|||
| `const` because of this
|
||||
|
||||
error: functions in `extern` blocks cannot have qualifiers
|
||||
--> $DIR/fn-header-semantic-fail.rs:54:18
|
||||
--> $DIR/fn-header-semantic-fail.rs:51:18
|
||||
|
|
||||
LL | extern {
|
||||
| ------ in this `extern` block
|
||||
|
@ -113,7 +113,7 @@ LL | async fn fe1();
|
|||
| help: remove the qualifiers: `fn`
|
||||
|
||||
error: functions in `extern` blocks cannot have qualifiers
|
||||
--> $DIR/fn-header-semantic-fail.rs:55:19
|
||||
--> $DIR/fn-header-semantic-fail.rs:52:19
|
||||
|
|
||||
LL | extern {
|
||||
| ------ in this `extern` block
|
||||
|
@ -124,7 +124,7 @@ LL | unsafe fn fe2();
|
|||
| help: remove the qualifiers: `fn`
|
||||
|
||||
error: functions in `extern` blocks cannot have qualifiers
|
||||
--> $DIR/fn-header-semantic-fail.rs:56:18
|
||||
--> $DIR/fn-header-semantic-fail.rs:53:18
|
||||
|
|
||||
LL | extern {
|
||||
| ------ in this `extern` block
|
||||
|
@ -135,7 +135,7 @@ LL | const fn fe3();
|
|||
| help: remove the qualifiers: `fn`
|
||||
|
||||
error: functions in `extern` blocks cannot have qualifiers
|
||||
--> $DIR/fn-header-semantic-fail.rs:57:23
|
||||
--> $DIR/fn-header-semantic-fail.rs:54:23
|
||||
|
|
||||
LL | extern {
|
||||
| ------ in this `extern` block
|
||||
|
@ -146,7 +146,7 @@ LL | extern "C" fn fe4();
|
|||
| help: remove the qualifiers: `fn`
|
||||
|
||||
error: functions in `extern` blocks cannot have qualifiers
|
||||
--> $DIR/fn-header-semantic-fail.rs:58:42
|
||||
--> $DIR/fn-header-semantic-fail.rs:55:42
|
||||
|
|
||||
LL | extern {
|
||||
| ------ in this `extern` block
|
||||
|
@ -157,7 +157,7 @@ LL | const async unsafe extern "C" fn fe5();
|
|||
| help: remove the qualifiers: `fn`
|
||||
|
||||
error: functions cannot be both `const` and `async`
|
||||
--> $DIR/fn-header-semantic-fail.rs:58:9
|
||||
--> $DIR/fn-header-semantic-fail.rs:55:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn fe5();
|
||||
| ^^^^^-^^^^^----------------------------
|
||||
|
@ -165,16 +165,8 @@ LL | const async unsafe extern "C" fn fe5();
|
|||
| | `async` because of this
|
||||
| `const` because of this
|
||||
|
||||
error: `from_generator` is not yet stable as a const fn
|
||||
--> $DIR/fn-header-semantic-fail.rs:13:44
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ff5() {} // OK.
|
||||
| ^^
|
||||
|
|
||||
= help: add `#![feature(gen_future)]` to the crate attributes to enable
|
||||
|
||||
error[E0053]: method `ft1` has an incompatible type for trait
|
||||
--> $DIR/fn-header-semantic-fail.rs:30:24
|
||||
--> $DIR/fn-header-semantic-fail.rs:29:24
|
||||
|
|
||||
LL | async fn ft1();
|
||||
| - type in trait
|
||||
|
@ -189,7 +181,7 @@ LL | async fn ft1() {}
|
|||
found fn pointer `fn() -> impl Future`
|
||||
|
||||
error[E0053]: method `ft5` has an incompatible type for trait
|
||||
--> $DIR/fn-header-semantic-fail.rs:35:48
|
||||
--> $DIR/fn-header-semantic-fail.rs:34:48
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5();
|
||||
| - type in trait
|
||||
|
@ -203,23 +195,7 @@ LL | const async unsafe extern "C" fn ft5() {}
|
|||
= note: expected fn pointer `unsafe extern "C" fn()`
|
||||
found fn pointer `unsafe extern "C" fn() -> impl Future`
|
||||
|
||||
error: `from_generator` is not yet stable as a const fn
|
||||
--> $DIR/fn-header-semantic-fail.rs:35:48
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
| ^^
|
||||
|
|
||||
= help: add `#![feature(gen_future)]` to the crate attributes to enable
|
||||
|
||||
error: `from_generator` is not yet stable as a const fn
|
||||
--> $DIR/fn-header-semantic-fail.rs:48:48
|
||||
|
|
||||
LL | const async unsafe extern "C" fn fi5() {}
|
||||
| ^^
|
||||
|
|
||||
= help: add `#![feature(gen_future)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0053, E0379, E0706.
|
||||
For more information about an error, try `rustc --explain E0053`.
|
||||
|
|
|
@ -2,6 +2,5 @@
|
|||
|
||||
static mut a: Box<isize> = box 3;
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR static contains unimplemented expression type
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in statics
|
|||
LL | static mut a: Box<isize> = box 3;
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/static-mut-not-constant.rs:3:32
|
||||
|
|
||||
LL | static mut a: Box<isize> = box 3;
|
||||
| ^
|
||||
|
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0019.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
For more information about this error, try `rustc --explain E0010`.
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/ranged_ints2_const.rs:11:9
|
||||
--> $DIR/ranged_ints2_const.rs:11:13
|
||||
|
|
||||
LL | let y = &mut x.0;
|
||||
| ^
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: mutable references are not allowed in constant functions
|
||||
--> $DIR/ranged_ints2_const.rs:18:9
|
||||
--> $DIR/ranged_ints2_const.rs:18:22
|
||||
|
|
||||
LL | let y = unsafe { &mut x.0 };
|
||||
| ^
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
|
Loading…
Reference in New Issue