From 4d343a5e59502d62621526af5e204b541dccbb2d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 17:27:59 -0700 Subject: [PATCH 01/23] Useful derives on `mir::LocalKind` --- compiler/rustc_middle/src/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f9d84bb852f31..fee24f0bae8ca 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -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, From 325b7d42ecdfb9236837387a9febb827c1576d66 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 28 Sep 2020 21:51:11 -0700 Subject: [PATCH 02/23] Continue const-checking after errors when easy This doesn't change any UI test output --- .../src/transform/check_consts/ops.rs | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 3b8d8a5aa99dd..5c57f87103ed9 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -101,8 +101,6 @@ pub trait NonConstOp: std::fmt::Debug { #[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) } @@ -115,8 +113,6 @@ impl NonConstOp for Abort { #[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) @@ -136,20 +132,6 @@ impl NonConstOp for FloatingPointOp { } } -#[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") - } -} - /// A function call where the callee is a pointer. #[derive(Debug)] pub struct FnCallIndirect; @@ -234,8 +216,6 @@ impl NonConstOp for FnPtrCast { #[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. @@ -512,8 +492,6 @@ impl NonConstOp for ThreadLocalAccess { #[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 @@ -660,8 +638,6 @@ 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) } From 25c7753eeefd3fee0b2529d88ce8362d52f60877 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 19:13:11 -0700 Subject: [PATCH 03/23] Continue after `impl Trait` in `const fn` --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 5c57f87103ed9..60300d3ba510f 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -605,8 +605,6 @@ pub mod ty { #[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) } From c38aca0502316ae610ab93deda7efa7ef8ef8473 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 19:13:25 -0700 Subject: [PATCH 04/23] `delay_span_bug` if const-checking an `async` function This errors during AST lowering. Any errors we emit here are just noise. --- .../src/transform/check_consts/validation.rs | 19 +++++- src/test/ui/async-await/no-const-async.rs | 1 - src/test/ui/async-await/no-const-async.stderr | 12 +--- src/test/ui/parser/fn-header-semantic-fail.rs | 3 - .../ui/parser/fn-header-semantic-fail.stderr | 64 ++++++------------- 5 files changed, 38 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index ee6adbc7a455d..bee6aa60360bb 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -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_hir::def_id::{DefId, LocalDefId}; +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::*; @@ -204,6 +204,13 @@ impl Validator<'mir, 'tcx> { 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(tcx, def_id) || 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`. @@ -877,3 +884,11 @@ 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(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + let hir_map = tcx.hir(); + let hir_id = hir_map.local_def_id_to_hir_id(def_id); + hir_map + .fn_sig_by_hir_id(hir_id) + .map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async) +} diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index 57a9f175ca318..b3c59734e036f 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -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 diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 4e59bb507676f..90ec646c8c09c 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -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 for more information - = help: add `#![feature(const_fn)]` to the crate attributes to enable - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs index 6d3fc3ce2f171..c327667f4cdc7 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.rs +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -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 { diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr index f1e21884040f0..4193b3ee695bc 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.stderr +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -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`. From 20e07e7b8e1468f12a88281f6497304eb98d48f1 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 19:20:05 -0700 Subject: [PATCH 05/23] Forbid generator-specific MIR in all const-contexts --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 60300d3ba510f..280f3e02058c6 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -216,14 +216,12 @@ impl NonConstOp for FnPtrCast { #[derive(Debug)] pub struct Generator; impl NonConstOp for Generator { - 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"); + ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`").emit(); } } From 782a595d7cf32efcea7b7086e178f3efe392541a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 11:19:40 -0700 Subject: [PATCH 06/23] Return a `DiagnosticBuilder` from structured errors This ensures that `emit_error` will actually cause compilation to fail. --- .../src/transform/check_consts/ops.rs | 139 ++++++++---------- 1 file changed, 64 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 280f3e02058c6..920c73a08c3ed 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -1,6 +1,6 @@ //! 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, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::config::nightly_options; @@ -49,7 +49,9 @@ pub fn non_const(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> boo return false; } - op.emit_error(ccx, span); + let mut err = op.build_error(ccx, span); + assert!(err.is_error()); + err.emit(); true } @@ -69,7 +71,7 @@ pub trait NonConstOp: std::fmt::Debug { Status::Forbidden } - 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, @@ -94,7 +96,8 @@ pub trait NonConstOp: std::fmt::Debug { expression! However, you can use it anywhere else.", ); } - err.emit(); + + err } } @@ -105,8 +108,8 @@ impl NonConstOp for Abort { 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") } } @@ -121,14 +124,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(); } } @@ -136,10 +138,8 @@ impl NonConstOp for FloatingPointOp { #[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") } } @@ -147,16 +147,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(); + ) } } @@ -167,7 +166,7 @@ impl NonConstOp for FnCallNonConst { pub struct FnCallUnstable(pub DefId, pub Option); 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( @@ -185,7 +184,8 @@ impl NonConstOp for FnCallUnstable { )); } } - err.emit(); + + err } } @@ -202,14 +202,13 @@ 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() } } @@ -220,15 +219,15 @@ impl NonConstOp for Generator { Status::Forbidden } - fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) { - ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`").emit(); + 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, @@ -245,7 +244,7 @@ impl NonConstOp for HeapAllocation { be done at compile time.", ); } - err.emit(); + err } } @@ -258,25 +257,25 @@ pub struct LiveDrop { pub dropped_at: Option, } 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, @@ -284,7 +283,6 @@ impl NonConstOp for CellBorrow { "cannot borrow a constant which may contain \ interior mutability, create a static instead" ) - .emit(); } } @@ -300,7 +298,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, @@ -331,7 +329,7 @@ impl NonConstOp for MutBorrow { static mut or a global UnsafeCell.", ); } - err.emit(); + err } } @@ -348,14 +346,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(); } } @@ -374,21 +371,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 @@ -397,7 +393,7 @@ impl NonConstOp for RawPtrComparison { "see issue #53020 \ for more information", ); - err.emit(); + err } } @@ -408,14 +404,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(); } } @@ -426,14 +421,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(); } } @@ -449,7 +443,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, @@ -467,7 +461,7 @@ impl NonConstOp for StaticAccess { ); err.help("To fix this, the value can be extracted to a `const` and then used."); } - err.emit(); + err } } @@ -475,7 +469,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, @@ -483,7 +477,6 @@ impl NonConstOp for ThreadLocalAccess { "thread-local statics cannot be \ accessed at compile-time" ) - .emit(); } } @@ -498,15 +491,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 } } @@ -522,14 +515,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(); } } @@ -543,12 +535,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", - ); + ) } } @@ -565,14 +557,13 @@ pub mod ty { Status::Unstable(sym::const_mut_refs) } - 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!("mutable references are not allowed in {}s", ccx.const_kind()), ) - .emit() } } @@ -589,14 +580,13 @@ 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() } } @@ -607,8 +597,8 @@ pub mod ty { 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") } } @@ -621,12 +611,12 @@ pub mod ty { 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", - ); + ) } } @@ -638,14 +628,13 @@ pub mod ty { 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() } } } @@ -658,12 +647,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 \ +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 \ 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 } From ce5093995256721564510594216d55588278fa5f Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 13:18:43 -0700 Subject: [PATCH 07/23] Fix "unstable in stable" error The "otherwise" note is printed before the suggestion currently. --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 7 ++++++- src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr | 5 ++++- .../min_const_fn/min_const_fn_libstd_stability.stderr | 5 ++++- .../min_const_unsafe_fn_libstd_stability.stderr | 5 ++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 920c73a08c3ed..c111bdd707c5c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -33,7 +33,12 @@ pub fn non_const(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> boo concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(), Applicability::HasPlaceholders, ) - .note("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks") + .span_suggestion( + ccx.body.span, + "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks", + format!("#[allow_internal_unstable({})]", gate), + Applicability:: MaybeIncorrect, + ) .emit(); } diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr index 94f6cda209749..a08d57b6043d7 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr @@ -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 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index fa2260b40d19f..de6a9a19269b1 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -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 diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr index 1ca5964ce0fc4..f258deb12a9d9 100644 --- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr @@ -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 From de35c4293d030208f4026883e9d296c8cc5607cc Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 13:17:38 -0700 Subject: [PATCH 08/23] Remove `ops::non_const` This helper function was meant to reduce code duplication between const-checking pre- and post-drop-elaboration. Most of the functionality is only relevant for the pre-drop-elaboration pass. --- .../src/transform/check_consts/ops.rs | 52 +---------------- .../check_consts/post_drop_elaboration.rs | 4 +- .../src/transform/check_consts/validation.rs | 57 +++++++++++++++++-- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index c111bdd707c5c..3aa9aca97c2f3 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -1,6 +1,6 @@ //! Concrete error types for all operations which may be invalid in a certain const context. -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::config::nightly_options; @@ -10,56 +10,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(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, - ) - .span_suggestion( - ccx.body.span, - "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks", - format!("#[allow_internal_unstable({})]", gate), - Applicability:: MaybeIncorrect, - ) - .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; - } - - let mut err = op.build_error(ccx, span); - assert!(err.is_error()); - err.emit(); - true -} - #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Status { Allowed, diff --git a/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs index 0c171bbc464a2..9b2568d5abb05 100644 --- a/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs @@ -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(); } } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index bee6aa60360bb..4266dfb496565 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -1,6 +1,6 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, HirId, LangItem}; use rustc_infer::infer::TyCtxtInferExt; @@ -11,13 +11,13 @@ 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::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}; @@ -277,8 +277,33 @@ impl Validator<'mir, 'tcx> { return; } - let err_emitted = ops::non_const(self.ccx, op, span); - if err_emitted && O::STOPS_CONST_CHECKING { + 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 mut err = op.build_error(self.ccx, span); + assert!(err.is_error()); + err.emit(); + + if O::STOPS_CONST_CHECKING { self.const_checking_stopped = true; } } @@ -892,3 +917,25 @@ fn is_async_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { .fn_sig_by_hir_id(hir_id) .map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async) } + +fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) { + 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, + ) + .span_suggestion( + ccx.body.span, + "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks", + format!("#[allow_internal_unstable({})]", gate), + Applicability::MaybeIncorrect, + ) + .emit(); +} From b518ccb4c3b24fabbbdd22fa1a574279348cc472 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 14:40:14 -0700 Subject: [PATCH 09/23] Give `MutDeref` a real error message --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 3aa9aca97c2f3..e57fcfa1fc846 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -317,6 +317,15 @@ impl NonConstOp for MutDeref { fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { Status::Unstable(sym::const_mut_refs) } + + 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)] From a23297f5c05d956f33ad0b515cc4daf99a2be4f1 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 14:58:00 -0700 Subject: [PATCH 10/23] Bless mut tests --- .../src/transform/check_consts/ops.rs | 2 - .../assign-to-static-within-other-static-2.rs | 4 +- ...ign-to-static-within-other-static-2.stderr | 8 +- .../const-eval/mod-static-with-const-fn.rs | 7 +- .../mod-static-with-const-fn.stderr | 16 +- src/test/ui/consts/const_let_assign3.rs | 8 +- src/test/ui/consts/const_let_assign3.stderr | 14 +- .../min_const_fn/bad_const_fn_body_ice.rs | 1 - .../min_const_fn/bad_const_fn_body_ice.stderr | 13 +- .../ui/consts/min_const_fn/min_const_fn.rs | 12 ++ .../consts/min_const_fn/min_const_fn.stderr | 158 +++++++++++++++--- .../consts/min_const_fn/mutable_borrow.stderr | 8 +- src/test/ui/consts/projection_qualif.rs | 1 - .../ui/consts/projection_qualif.stock.stderr | 14 +- .../consts/static_mut_containing_mut_ref2.rs | 1 - ...tatic_mut_containing_mut_ref2.stock.stderr | 13 +- 16 files changed, 173 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index e57fcfa1fc846..fba6d0d2f80d8 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -515,8 +515,6 @@ pub mod ty { #[derive(Debug)] pub struct MutRef; impl NonConstOp for MutRef { - const STOPS_CONST_CHECKING: bool = true; - fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status { Status::Unstable(sym::const_mut_refs) } diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs index 4d3c714481a29..037c6f9f7e662 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs @@ -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() {} diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr index 14dcc074639e5..296a6bf542163 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr @@ -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`. diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs index 32f0062168b3d..481e046946344 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs @@ -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() { diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr index 44ae1ecf04718..12faf2e25e781 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr @@ -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:15:5 | LL | *FOO.0.get() = 5; | ^^^^^^^^^^^^^^^^ | + = note: see issue #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 2 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/consts/const_let_assign3.rs b/src/test/ui/consts/const_let_assign3.rs index 9d5ccb880aa1b..2fd6e060678e9 100644 --- a/src/test/ui/consts/const_let_assign3.rs +++ b/src/test/ui/consts/const_let_assign3.rs @@ -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 }]; diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index 15badea003736..dc86e178a42c3 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -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 4 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`. diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs index 589085871fba9..4e1b7bf119c6d 100644 --- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs @@ -1,7 +1,6 @@ const fn foo(a: i32) -> Vec { vec![1, 2, 3] //~^ ERROR allocations are not allowed - //~| ERROR unimplemented expression type //~| ERROR calls in constant functions } diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index 0f16890141f6b..23697a8e11811 100644 --- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -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`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 06a44b271064c..199295531d728 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -38,6 +38,9 @@ impl Foo { const fn get(&self) -> &T { &self.0 } const fn get_mut(&mut self) -> &mut T { &mut self.0 } //~^ mutable references + //~| mutable references + //~| mutable references + //~| mutable references } impl<'a, T> Foo { const fn new_lt(t: T) -> Self { Foo(t) } @@ -45,6 +48,9 @@ impl<'a, T> Foo { 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 + //~| mutable references } impl Foo { const fn new_s(t: T) -> Self { Foo(t) } @@ -52,11 +58,17 @@ impl Foo { 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 + //~| mutable references } impl Foo { 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 + //~| mutable references } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 5e6bf7ef89034..6ec33089401b6 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -15,8 +15,35 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } = note: see issue #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:22 + | +LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^ + | + = note: see issue #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 + | +LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: see issue #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 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:47:28 | LL | const fn into_inner_lt(self) -> T { self.0 } | ^^^^ - value is dropped here @@ -24,7 +51,7 @@ 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:49:42 | LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -32,8 +59,35 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } = note: see issue #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:49:25 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^ + | + = note: see issue #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:49:42 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: see issue #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:49:51 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^ + | + = note: see issue #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:57:27 | LL | const fn into_inner_s(self) -> T { self.0 } | ^^^^ - value is dropped here @@ -41,7 +95,7 @@ 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:59:38 | LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -50,7 +104,34 @@ 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:59:24 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^ + | + = note: see issue #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:59:38 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: see issue #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:59:47 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^ + | + = note: see issue #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:67:39 | LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -58,8 +139,35 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } = note: see issue #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:67:25 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^ + | + = note: see issue #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:67:39 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: see issue #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:67:48 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^ + | + = note: see issue #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:88:16 | LL | const fn foo11(t: T) -> T { t } | ^ @@ -68,7 +176,7 @@ LL | const fn foo11(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:90:18 | LL | const fn foo11_2(t: T) -> T { t } | ^ @@ -77,7 +185,7 @@ LL | const fn foo11_2(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:94:27 | LL | const fn foo25() -> u32 { BAR } | ^^^ @@ -85,7 +193,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:95:37 | LL | const fn foo26() -> &'static u32 { &BAR } | ^^^ @@ -93,7 +201,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:96:42 | LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ @@ -102,7 +210,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:98:63 | LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } | ^^^^^^^^^^ @@ -111,7 +219,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:100:42 | LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ @@ -120,7 +228,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:102:63 | LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } | ^^^^^^^^^^ @@ -129,7 +237,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:105:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ @@ -138,7 +246,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:114:6 | LL | impl Foo { | ^ @@ -147,7 +255,7 @@ LL | impl Foo { = 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:119:6 | LL | impl Foo { | ^ @@ -156,7 +264,7 @@ LL | impl Foo { = 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:124:6 | LL | impl Foo { | ^ @@ -165,7 +273,7 @@ LL | impl Foo { = 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:130:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +282,7 @@ LL | const fn no_apit2(_x: AlanTuring) {} = 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:120:22 + --> $DIR/min_const_fn.rs:132:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +291,7 @@ LL | const fn no_apit(_x: impl 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:121:23 + --> $DIR/min_const_fn.rs:133:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ @@ -192,7 +300,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 { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,7 +309,7 @@ LL | const fn no_dyn_trait_ret() -> &'static 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:127:41 + --> $DIR/min_const_fn.rs:139:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +318,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 = 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:142:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ @@ -219,7 +327,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:144:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ @@ -227,7 +335,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = note: see issue #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: aborting due to 38 previous errors Some errors have detailed explanations: E0013, E0493, E0658, E0723. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr index 4e5cdbb18aae3..8e95a4c68a2ad 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -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 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 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 7db970cf1379f..5e2584a6e951a 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -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} }; diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/projection_qualif.stock.stderr index 212f12286455f..fad8f011f75f5 100644 --- a/src/test/ui/consts/projection_qualif.stock.stderr +++ b/src/test/ui/consts/projection_qualif.stock.stderr @@ -13,15 +13,7 @@ LL | unsafe { *b = 5; } = note: see issue #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 3 previous errors +error: aborting due to 2 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`. diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs index a6bbe8d6ec24c..2821d1a015435 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs @@ -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() {} diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr index 57fb27e642e6f..36c280ca5c607 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr @@ -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 2 previous errors +error: aborting due to previous error -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`. From 5b3145574e828659cb9c6d671a4b19ac3989b0b4 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 17:52:12 -0700 Subject: [PATCH 11/23] Priority levels --- .../src/transform/check_consts/ops.rs | 41 +++++++++++++++++- .../src/transform/check_consts/validation.rs | 43 +++++++++++++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index fba6d0d2f80d8..c08f4b0ea51b8 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -3,6 +3,7 @@ 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; @@ -17,6 +18,15 @@ 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; @@ -26,6 +36,10 @@ pub trait NonConstOp: std::fmt::Debug { Status::Forbidden } + fn importance(&self) -> DiagnosticImportance { + DiagnosticImportance::Primary + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { let mut err = struct_span_err!( ccx.tcx.sess, @@ -318,6 +332,11 @@ impl NonConstOp for MutDeref { 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, @@ -513,12 +532,21 @@ pub mod ty { use super::*; #[derive(Debug)] - pub struct MutRef; + pub struct MutRef(pub mir::LocalKind); impl NonConstOp for MutRef { fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status { Status::Unstable(sym::const_mut_refs) } + 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, @@ -530,10 +558,19 @@ pub mod ty { } #[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 { Status::Allowed diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 4266dfb496565..e0dd797088321 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -1,6 +1,6 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, HirId, LangItem}; use rustc_infer::infer::TyCtxtInferExt; @@ -15,6 +15,7 @@ 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, Status}; @@ -181,6 +182,9 @@ pub struct Validator<'mir, 'tcx> { span: Span, const_checking_stopped: bool, + + error_emitted: bool, + secondary_errors: Vec, } impl Deref for Validator<'mir, 'tcx> { @@ -198,6 +202,8 @@ impl Validator<'mir, 'tcx> { ccx, qualifs: Default::default(), const_checking_stopped: false, + error_emitted: false, + secondary_errors: Vec::new(), } } @@ -230,20 +236,20 @@ impl Validator<'mir, 'tcx> { self.check_item_predicates(); - for local in &body.local_decls { + for (idx, local) in body.local_decls.iter_enumerated() { if 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); @@ -257,6 +263,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 { @@ -301,7 +318,15 @@ impl Validator<'mir, 'tcx> { let mut err = op.build_error(self.ccx, span); assert!(err.is_error()); - err.emit(); + + match op.importance() { + ops::DiagnosticImportance::Primary => { + self.error_emitted = true; + err.emit(); + } + + ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors), + } if O::STOPS_CONST_CHECKING { self.const_checking_stopped = true; @@ -316,7 +341,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, @@ -327,9 +354,9 @@ 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() { From b400871b9c07951d79dd9158af44dfdebcb8ad65 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 17:30:07 -0700 Subject: [PATCH 12/23] Don't emit duplicate errors for the return place --- compiler/rustc_mir/src/transform/check_consts/validation.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index e0dd797088321..0781a76a1663f 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -237,7 +237,8 @@ impl Validator<'mir, 'tcx> { self.check_item_predicates(); for (idx, local) in body.local_decls.iter_enumerated() { - if local.internal { + // Handle the return place below. + if idx == RETURN_PLACE || local.internal { continue; } From 51fbd555f07febe07d2b8c5beab6f3520bebe460 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 17:31:04 -0700 Subject: [PATCH 13/23] Bless tests --- .../ui/check-static-values-constraints.rs | 7 -- .../ui/check-static-values-constraints.stderr | 76 ++----------- src/test/ui/const-suggest-feature.rs | 2 - src/test/ui/const-suggest-feature.stderr | 13 +-- .../const-extern-fn-min-const-fn.stderr | 4 +- .../ui/consts/min_const_fn/cast_errors.stderr | 8 +- .../ui/consts/min_const_fn/min_const_fn.rs | 4 - .../consts/min_const_fn/min_const_fn.stderr | 100 ++++++------------ src/test/ui/error-codes/E0010-teach.rs | 1 - src/test/ui/error-codes/E0010-teach.stderr | 15 +-- src/test/ui/error-codes/E0010.rs | 1 - src/test/ui/error-codes/E0010.stderr | 13 +-- src/test/ui/error-codes/E0017.rs | 2 +- src/test/ui/error-codes/E0017.stderr | 14 +-- src/test/ui/error-codes/E0388.rs | 4 +- src/test/ui/error-codes/E0388.stderr | 14 +-- src/test/ui/issues/issue-7364.rs | 1 - src/test/ui/issues/issue-7364.stderr | 12 +-- src/test/ui/static/static-mut-not-constant.rs | 1 - .../ui/static/static-mut-not-constant.stderr | 13 +-- src/test/ui/unsafe/ranged_ints2_const.stderr | 8 +- 21 files changed, 71 insertions(+), 242 deletions(-) diff --git a/src/test/ui/check-static-values-constraints.rs b/src/test/ui/check-static-values-constraints.rs index acfb3b5e44bab..3d1b5a0822756 100644 --- a/src/test/ui/check-static-values-constraints.rs +++ b/src/test/ui/check-static-values-constraints.rs @@ -78,7 +78,6 @@ struct MyOwned; static STATIC11: Box = 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] = &[ 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, &'static Box) = ( &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 = box 3; //~^ ERROR allocations are not allowed in statics - //~| ERROR contains unimplemented expression pub fn main() { let y = { static x: Box = box 3; x }; //~^ ERROR allocations are not allowed in statics //~| ERROR cannot move out of static item - //~| ERROR contains unimplemented expression } diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr index 50c1b5088e7ab..eb640c88e026f 100644 --- a/src/test/ui/check-static-values-constraints.stderr +++ b/src/test/ui/check-static-values-constraints.stderr @@ -15,92 +15,44 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = 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 = 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:95:5 + --> $DIR/check-static-values-constraints.rs:94: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 + --> $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: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 = box 3; x }; | ^ @@ -109,20 +61,12 @@ LL | let y = { static x: Box = 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 = 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 = box 3; x }; - | ^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error: aborting due to 17 previous errors +error: aborting due to 10 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`. diff --git a/src/test/ui/const-suggest-feature.rs b/src/test/ui/const-suggest-feature.rs index 89fafbbe6f044..d11b91edb8857 100644 --- a/src/test/ui/const-suggest-feature.rs +++ b/src/test/ui/const-suggest-feature.rs @@ -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() {} diff --git a/src/test/ui/const-suggest-feature.stderr b/src/test/ui/const-suggest-feature.stderr index 6b91df6b42d91..1ccc3d754ff00 100644 --- a/src/test/ui/const-suggest-feature.stderr +++ b/src/test/ui/const-suggest-feature.stderr @@ -7,15 +7,6 @@ LL | *std::ptr::null_mut() = 0; = note: see issue #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 2 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr index 455a822e2d085..54067b462f819 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr @@ -1,8 +1,8 @@ error[E0658]: function pointers cannot appear in constant functions - --> $DIR/const-extern-fn-min-const-fn.rs:4:41 + --> $DIR/const-extern-fn-min-const-fn.rs:4:48 | LL | const unsafe extern "C" fn closure() -> fn() { || {} } - | ^^^^ + | ^^^^^ | = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr index ac77c181afda8..32eb1095e089b 100644 --- a/src/test/ui/consts/min_const_fn/cast_errors.stderr +++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr @@ -1,8 +1,8 @@ error[E0658]: function pointers cannot appear in constant functions - --> $DIR/cast_errors.rs:4:23 + --> $DIR/cast_errors.rs:4:30 | LL | const fn closure() -> fn() { || {} } - | ^^^^ + | ^^^^^ | = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable @@ -17,10 +17,10 @@ LL | (|| {}) as 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/cast_errors.rs:10:28 + --> $DIR/cast_errors.rs:10:16 | LL | const fn reify(f: fn()) -> unsafe fn() { f } - | ^^^^^^^^^^^ + | ^ | = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 199295531d728..4c06aeb76c75f 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -40,7 +40,6 @@ impl Foo { //~^ mutable references //~| mutable references //~| mutable references - //~| mutable references } impl<'a, T> Foo { const fn new_lt(t: T) -> Self { Foo(t) } @@ -50,7 +49,6 @@ impl<'a, T> Foo { //~^ mutable references //~| mutable references //~| mutable references - //~| mutable references } impl Foo { const fn new_s(t: T) -> Self { Foo(t) } @@ -60,7 +58,6 @@ impl Foo { //~^ mutable references //~| mutable references //~| mutable references - //~| mutable references } impl Foo { const fn get_sq(&self) -> &T { &self.0 } @@ -68,7 +65,6 @@ impl Foo { //~^ mutable references //~| mutable references //~| mutable references - //~| mutable references } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 6ec33089401b6..638276a4d062e 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -6,15 +6,6 @@ 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:36 - | -LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } - | ^^^^^^ - | - = note: see issue #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:22 | @@ -43,7 +34,7 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } = 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:47:28 + --> $DIR/min_const_fn.rs:46:28 | LL | const fn into_inner_lt(self) -> T { self.0 } | ^^^^ - value is dropped here @@ -51,16 +42,7 @@ 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:49:42 - | -LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } - | ^^^^^^ - | - = note: see issue #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:49:25 + --> $DIR/min_const_fn.rs:48:25 | LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^^^^ @@ -69,7 +51,7 @@ LL | const fn get_mut_lt(&'a 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:49:42 + --> $DIR/min_const_fn.rs:48:42 | LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -78,7 +60,7 @@ LL | const fn get_mut_lt(&'a 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:49:51 + --> $DIR/min_const_fn.rs:48:51 | LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^^^ @@ -87,7 +69,7 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } = 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:57:27 + --> $DIR/min_const_fn.rs:55:27 | LL | const fn into_inner_s(self) -> T { self.0 } | ^^^^ - value is dropped here @@ -95,16 +77,7 @@ 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:59:38 - | -LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } - | ^^^^^^ - | - = note: see issue #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:59:24 + --> $DIR/min_const_fn.rs:57:24 | LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^ @@ -113,7 +86,7 @@ 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:59:38 + --> $DIR/min_const_fn.rs:57:38 | LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -122,7 +95,7 @@ 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:59:47 + --> $DIR/min_const_fn.rs:57:47 | LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^^^ @@ -131,16 +104,7 @@ 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:67:39 - | -LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } - | ^^^^^^ - | - = note: see issue #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:67:25 + --> $DIR/min_const_fn.rs:64:25 | LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^ @@ -149,7 +113,7 @@ LL | const fn get_mut_sq(&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:67:39 + --> $DIR/min_const_fn.rs:64:39 | LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ @@ -158,7 +122,7 @@ LL | const fn get_mut_sq(&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:67:48 + --> $DIR/min_const_fn.rs:64:48 | LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^^^^^^ @@ -167,7 +131,7 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } = 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:88:16 + --> $DIR/min_const_fn.rs:84:16 | LL | const fn foo11(t: T) -> T { t } | ^ @@ -176,7 +140,7 @@ LL | const fn foo11(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:90:18 + --> $DIR/min_const_fn.rs:86:18 | LL | const fn foo11_2(t: T) -> T { t } | ^ @@ -185,7 +149,7 @@ LL | const fn foo11_2(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:94:27 + --> $DIR/min_const_fn.rs:90:27 | LL | const fn foo25() -> u32 { BAR } | ^^^ @@ -193,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:95:37 + --> $DIR/min_const_fn.rs:91:37 | LL | const fn foo26() -> &'static u32 { &BAR } | ^^^ @@ -201,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:96:42 + --> $DIR/min_const_fn.rs:92:42 | LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ @@ -210,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:98:63 + --> $DIR/min_const_fn.rs:94:63 | LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } | ^^^^^^^^^^ @@ -219,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:100:42 + --> $DIR/min_const_fn.rs:96:42 | LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ @@ -228,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:102:63 + --> $DIR/min_const_fn.rs:98:63 | LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } | ^^^^^^^^^^ @@ -237,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:105:14 + --> $DIR/min_const_fn.rs:101:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ @@ -246,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:114:6 + --> $DIR/min_const_fn.rs:110:6 | LL | impl Foo { | ^ @@ -255,7 +219,7 @@ LL | impl Foo { = 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:119:6 + --> $DIR/min_const_fn.rs:115:6 | LL | impl Foo { | ^ @@ -264,7 +228,7 @@ LL | impl Foo { = 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:124:6 + --> $DIR/min_const_fn.rs:120:6 | LL | impl Foo { | ^ @@ -273,7 +237,7 @@ LL | impl Foo { = 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:130:34 + --> $DIR/min_const_fn.rs:126:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -282,7 +246,7 @@ LL | const fn no_apit2(_x: AlanTuring) {} = 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:132:22 + --> $DIR/min_const_fn.rs:128:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +255,7 @@ LL | const fn no_apit(_x: impl 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:133:23 + --> $DIR/min_const_fn.rs:129:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ @@ -300,16 +264,16 @@ 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:134:32 + --> $DIR/min_const_fn.rs:130:63 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = note: see issue #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:139:41 + --> $DIR/min_const_fn.rs:135:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -318,7 +282,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 = 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:142:21 + --> $DIR/min_const_fn.rs:138:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ @@ -327,7 +291,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:144:27 + --> $DIR/min_const_fn.rs:140:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ @@ -335,7 +299,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable -error: aborting due to 38 previous errors +error: aborting due to 34 previous errors Some errors have detailed explanations: E0013, E0493, E0658, E0723. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/error-codes/E0010-teach.rs b/src/test/ui/error-codes/E0010-teach.rs index da51035ab5550..fc5dffb37cfe7 100644 --- a/src/test/ui/error-codes/E0010-teach.rs +++ b/src/test/ui/error-codes/E0010-teach.rs @@ -4,6 +4,5 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 -//~^ ERROR constant contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr index c15ab5c655a46..33de9fd685eb3 100644 --- a/src/test/ui/error-codes/E0010-teach.stderr +++ b/src/test/ui/error-codes/E0010-teach.stderr @@ -6,17 +6,6 @@ LL | const CON : Box = 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 = 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 2 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/error-codes/E0010.rs b/src/test/ui/error-codes/E0010.rs index 3398e2c28ba6b..e62997640f473 100644 --- a/src/test/ui/error-codes/E0010.rs +++ b/src/test/ui/error-codes/E0010.rs @@ -2,6 +2,5 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 -//~^ ERROR constant contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr index f49fb9c46326b..0042333b98ad1 100644 --- a/src/test/ui/error-codes/E0010.stderr +++ b/src/test/ui/error-codes/E0010.stderr @@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in constants LL | const CON : Box = box 0; | ^^^^^ allocation not allowed in constants -error[E0019]: constant contains unimplemented expression type - --> $DIR/E0010.rs:4:28 - | -LL | const CON : Box = box 0; - | ^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error: aborting due to 2 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs index 54d3cc54a84d9..262f7bc72c739 100644 --- a/src/test/ui/error-codes/E0017.rs +++ b/src/test/ui/error-codes/E0017.rs @@ -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 diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 40ef6bd97b3b0..ea591587e6daa 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -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`. diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs index 8ad586bb30f1e..bb0c4979b9ac9 100644 --- a/src/test/ui/error-codes/E0388.rs +++ b/src/test/ui/error-codes/E0388.rs @@ -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 diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 39bc717ceec3e..73e0b139cd056 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs index 39452897e67c3..29a1644673d4e 100644 --- a/src/test/ui/issues/issue-7364.rs +++ b/src/test/ui/issues/issue-7364.rs @@ -6,6 +6,5 @@ use std::cell::RefCell; static boxed: Box> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics //~| ERROR `RefCell` cannot be shared between threads safely [E0277] -//~| ERROR static contains unimplemented expression type fn main() { } diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr index 90f3bf53a7b0f..8ceb3be7ec913 100644 --- a/src/test/ui/issues/issue-7364.stderr +++ b/src/test/ui/issues/issue-7364.stderr @@ -4,14 +4,6 @@ error[E0010]: allocations are not allowed in statics LL | static boxed: Box> = 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> = box RefCell::new(0); - | ^^^^^^^^^^^^^^^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - error[E0277]: `RefCell` cannot be shared between threads safely --> $DIR/issue-7364.rs:6:1 | @@ -23,7 +15,7 @@ LL | static boxed: Box> = box RefCell::new(0); = note: required because it appears within the type `Box>` = 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`. diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs index 84d401c9fa61d..2091fffd418ee 100644 --- a/src/test/ui/static/static-mut-not-constant.rs +++ b/src/test/ui/static/static-mut-not-constant.rs @@ -2,6 +2,5 @@ static mut a: Box = box 3; //~^ ERROR allocations are not allowed in statics -//~| ERROR static contains unimplemented expression type fn main() {} diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr index a618b49d1089e..a0fa245156f87 100644 --- a/src/test/ui/static/static-mut-not-constant.stderr +++ b/src/test/ui/static/static-mut-not-constant.stderr @@ -4,15 +4,6 @@ error[E0010]: allocations are not allowed in statics LL | static mut a: Box = 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 = box 3; - | ^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error: aborting due to 2 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr index 1a6bcd36ee157..5ce4296458e6d 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.stderr +++ b/src/test/ui/unsafe/ranged_ints2_const.stderr @@ -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 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 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable From 37f37dc5ba47b12b7bab0e6d4d9af10efebfc7e3 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 18:32:08 -0700 Subject: [PATCH 14/23] Emit multiple function pointer errors from const-checker --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index c08f4b0ea51b8..49c465f3d38fd 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -161,8 +161,6 @@ impl NonConstOp for FnCallUnstable { #[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 @@ -560,8 +558,6 @@ pub mod ty { #[derive(Debug)] 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, From 879d3794d3140fcadc213688be32b21407497aa8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 18:32:38 -0700 Subject: [PATCH 15/23] Bless output --- .../mod-static-with-const-fn.stderr | 2 +- .../const-extern-fn-min-const-fn.rs | 1 + .../const-extern-fn-min-const-fn.stderr | 15 ++++-- .../ui/consts/min_const_fn/cast_errors.rs | 4 ++ .../ui/consts/min_const_fn/cast_errors.stderr | 50 ++++++++++++++++--- .../ui/consts/min_const_fn/cmp_fn_pointers.rs | 5 +- .../min_const_fn/cmp_fn_pointers.stderr | 19 ++++++- .../ui/consts/min_const_fn/min_const_fn.rs | 1 + .../consts/min_const_fn/min_const_fn.stderr | 11 +++- .../min_const_fn/min_const_fn_fn_ptr.stderr | 2 +- 10 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr index 12faf2e25e781..38282c0e3005d 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr @@ -1,5 +1,5 @@ error[E0658]: mutation through a reference is not allowed in statics - --> $DIR/mod-static-with-const-fn.rs:15:5 + --> $DIR/mod-static-with-const-fn.rs:16:5 | LL | *FOO.0.get() = 5; | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs index 8642954a75b45..645a957949c41 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs @@ -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; } diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr index 54067b462f819..694e229080870 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr @@ -1,4 +1,13 @@ error[E0658]: function pointers cannot appear in constant functions + --> $DIR/const-extern-fn-min-const-fn.rs:4:41 + | +LL | const unsafe extern "C" fn closure() -> fn() { || {} } + | ^^^^ + | + = note: see issue #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() { || {} } @@ -8,7 +17,7 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} } = 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 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`. diff --git a/src/test/ui/consts/min_const_fn/cast_errors.rs b/src/test/ui/consts/min_const_fn/cast_errors.rs index 43ef8ea12eb1f..b68f47f5cbcf1 100644 --- a/src/test/ui/consts/min_const_fn/cast_errors.rs +++ b/src/test/ui/consts/min_const_fn/cast_errors.rs @@ -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 diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr index 32eb1095e089b..fb962bdf906c3 100644 --- a/src/test/ui/consts/min_const_fn/cast_errors.stderr +++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr @@ -1,4 +1,13 @@ error[E0658]: function pointers cannot appear in constant functions + --> $DIR/cast_errors.rs:4:23 + | +LL | const fn closure() -> fn() { || {} } + | ^^^^ + | + = note: see issue #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:4:30 | LL | const fn closure() -> fn() { || {} } @@ -7,17 +16,17 @@ LL | const fn closure() -> fn() { || {} } = note: see issue #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:8:5 | LL | (|| {}) as fn(); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ | = note: see issue #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:16 + --> $DIR/cast_errors.rs:11:16 | LL | const fn reify(f: fn()) -> unsafe fn() { f } | ^ @@ -26,14 +35,41 @@ LL | const fn reify(f: fn()) -> unsafe fn() { f } = 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 + --> $DIR/cast_errors.rs:11:28 + | +LL | const fn reify(f: fn()) -> unsafe fn() { f } + | ^^^^^^^^^^^ + | + = note: see issue #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:11:42 + | +LL | const fn reify(f: fn()) -> unsafe fn() { f } + | ^ + | + = note: see issue #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 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 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: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs index 4aaf7b86e4560..638ff1d8b9c1c 100644 --- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs +++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs @@ -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() {} diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr index e913b187feeae..04c2febeb9768 100644 --- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr +++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr @@ -7,6 +7,23 @@ LL | const fn cmp(x: fn(), y: fn()) -> bool { = note: see issue #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 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 for more information + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 4c06aeb76c75f..acfd8d41eda94 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -139,3 +139,4 @@ 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 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 638276a4d062e..c82a07dc0f8d3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -299,7 +299,16 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable -error: aborting due to 34 previous errors +error[E0658]: function pointer casts are not allowed in constant functions + --> $DIR/min_const_fn.rs:140:46 + | +LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } + | ^^^ + | + = note: see issue #57563 for more information + = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable + +error: aborting due to 35 previous errors Some errors have detailed explanations: E0013, E0493, E0658, E0723. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr index 8d60436ea39bb..8d82674bbf2d9 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr @@ -7,7 +7,7 @@ LL | x.0.field; = note: see issue #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 }) } From e02ea835a75b75af740a45cf4b29c76610476569 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 18:52:00 -0700 Subject: [PATCH 16/23] Don't stop const-checking after erroneous trait bound --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 11 +++++++++-- .../src/transform/check_consts/validation.rs | 12 ++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 49c465f3d38fd..6d1125e352e0c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -598,9 +598,16 @@ pub mod ty { } #[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) diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 0781a76a1663f..a2dff46982b8e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -364,11 +364,11 @@ impl Validator<'mir, 'tcx> { 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)) } } } @@ -413,15 +413,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 From 4bbc79c5aed7d1457f8448c1723be1a366a20112 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 18:52:26 -0700 Subject: [PATCH 17/23] Bless tests --- .../ui/consts/min_const_fn/min_const_fn.rs | 12 +++-- .../consts/min_const_fn/min_const_fn.stderr | 54 +++++++++++++++---- .../consts/min_const_fn/min_const_fn_dyn.rs | 2 +- .../min_const_fn/min_const_fn_dyn.stderr | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index acfd8d41eda94..e46127c36bf6a 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -125,15 +125,21 @@ impl Foo { struct AlanTuring(T); const fn no_apit2(_x: AlanTuring) {} //~^ 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 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index c82a07dc0f8d3..ee5434b147b66 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -245,8 +245,16 @@ LL | const fn no_apit2(_x: AlanTuring) {} = note: see issue #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) {} + | ^^ - 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:128:22 + --> $DIR/min_const_fn.rs:129:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -254,8 +262,16 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} = note: see issue #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:129:23 + --> $DIR/min_const_fn.rs:132:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ @@ -264,7 +280,16 @@ 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:130:63 + --> $DIR/min_const_fn.rs:134:32 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #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 { &() } | ^^^ @@ -272,17 +297,26 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } = note: see issue #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:135: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 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 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:138:21 + --> $DIR/min_const_fn.rs:144:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ @@ -291,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:140:27 + --> $DIR/min_const_fn.rs:146:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ @@ -300,7 +334,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = 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/min_const_fn.rs:140:46 + --> $DIR/min_const_fn.rs:146:46 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^ @@ -308,7 +342,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = note: see issue #57563 for more information = help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable -error: aborting due to 35 previous errors +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`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs index 6ca1e59b3af10..4a22ef2dffddb 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs @@ -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() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr index 17e171c2fc953..1394db591cadd 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -7,7 +7,7 @@ LL | x.0.field; = note: see issue #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 }) } From 287993c9619c95ccde422032448125b8477e2f6d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 18:58:45 -0700 Subject: [PATCH 18/23] Remove machinery for halting error output --- .../rustc_mir/src/transform/check_consts/ops.rs | 2 -- .../src/transform/check_consts/validation.rs | 13 ------------- 2 files changed, 15 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 6d1125e352e0c..bbfe92ef1413e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -29,8 +29,6 @@ pub enum DiagnosticImportance { /// 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 diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index a2dff46982b8e..7588c01ed3cb7 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -181,8 +181,6 @@ pub struct Validator<'mir, 'tcx> { /// The span of the current statement. span: Span, - const_checking_stopped: bool, - error_emitted: bool, secondary_errors: Vec, } @@ -201,7 +199,6 @@ impl Validator<'mir, 'tcx> { span: ccx.body.span, ccx, qualifs: Default::default(), - const_checking_stopped: false, error_emitted: false, secondary_errors: Vec::new(), } @@ -289,12 +286,6 @@ 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(&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 { - return; - } - let gate = match op.status_in_item(self.ccx) { Status::Allowed => return, @@ -328,10 +319,6 @@ impl Validator<'mir, 'tcx> { ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors), } - - if O::STOPS_CONST_CHECKING { - self.const_checking_stopped = true; - } } fn check_static(&mut self, def_id: DefId, span: Span) { From bed7b295106c88a2a6cf922ace1483a48183675d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 19:45:06 -0700 Subject: [PATCH 19/23] Update `compile-fail` test --- src/test/compile-fail/consts/const-fn-error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/compile-fail/consts/const-fn-error.rs index 644748786036d..68a4d414ff34e 100644 --- a/src/test/compile-fail/consts/const-fn-error.rs +++ b/src/test/compile-fail/consts/const-fn-error.rs @@ -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; From 1513904c1c64954e38af8f98549fc56530c48b83 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 21:01:35 -0700 Subject: [PATCH 20/23] Remove default `build_error` impl Now all structured errors must have their own error code --- .../src/transform/check_consts/ops.rs | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index bbfe92ef1413e..6c34e0681c46c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -38,34 +38,7 @@ pub trait NonConstOp: std::fmt::Debug { DiagnosticImportance::Primary } - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - 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 - } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>; } #[derive(Debug)] @@ -215,7 +188,17 @@ impl NonConstOp for HeapAllocation { #[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, + E0019, + "{} contains unimplemented expression type", + ccx.const_kind() + ) + } +} #[derive(Debug)] pub struct LiveDrop { From 7c6d685551604dcb86f8239d09b21eeca5988f67 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 29 Sep 2020 21:09:45 -0700 Subject: [PATCH 21/23] Rewrite E0019 example Inline assembly is now the only user of E0019. What is it doing that E0015 is not? --- compiler/rustc_error_codes/src/error_codes/E0019.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0019.md b/compiler/rustc_error_codes/src/error_codes/E0019.md index 7832468a539d3..ef43a57a9810c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0019.md +++ b/compiler/rustc_error_codes/src/error_codes/E0019.md @@ -4,12 +4,14 @@ because the expression's value must be known at compile-time. Erroneous code example: ```compile_fail,E0019 -#![feature(box_syntax)] +#![feature(asm)] fn main() { - struct MyOwned; - - static STATIC11: Box = box MyOwned; // error! + static STATIC11: i32 = { + let x: i32; + unsafe { asm!("mov rax, 2", out("rax") x) }; // error! + x + }; } ``` From 0c26144b1ac75267c679bad6a4e2c4e7bc7957d3 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 30 Sep 2020 09:48:18 -0700 Subject: [PATCH 22/23] Better span for attribute suggestions `def_span` has the same issues as `body.span`, so do it this way instead. --- .../src/transform/check_consts/mod.rs | 10 ++++++++++ .../src/transform/check_consts/validation.rs | 20 +++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs index 8d4efd8ae8052..8df134860a5da 100644 --- a/compiler/rustc_mir/src/transform/check_consts/mod.rs +++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs @@ -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. diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 7588c01ed3cb7..ab63fd03a336e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -1,7 +1,7 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. use rustc_errors::{struct_span_err, Applicability, Diagnostic}; -use rustc_hir::def_id::{DefId, LocalDefId}; +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}; @@ -209,7 +209,7 @@ impl Validator<'mir, 'tcx> { // `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(tcx, def_id) || body.generator_kind.is_some() { + 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; } @@ -929,15 +929,13 @@ fn is_int_bool_or_char(ty: Ty<'_>) -> bool { ty.is_bool() || ty.is_integral() || ty.is_char() } -fn is_async_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let hir_map = tcx.hir(); - let hir_id = hir_map.local_def_id_to_hir_id(def_id); - hir_map - .fn_sig_by_hir_id(hir_id) - .map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async) +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( @@ -945,15 +943,15 @@ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol &format!("const-stable function cannot use `#[feature({})]`", gate.as_str()), ) .span_suggestion( - ccx.body.span, + 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( - ccx.body.span, + attr_span, "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks", - format!("#[allow_internal_unstable({})]", gate), + format!("#[allow_internal_unstable({})]\n", gate), Applicability::MaybeIncorrect, ) .emit(); From 1301f43119f8ae564a01abd3fa306e87d635e862 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 30 Sep 2020 09:58:01 -0700 Subject: [PATCH 23/23] Remove E0019, use E0015 for inline assembly in a const --- compiler/rustc_error_codes/src/error_codes.rs | 2 +- .../src/error_codes/E0019.md | 38 ------------------- .../src/transform/check_consts/ops.rs | 4 +- src/test/ui/consts/inline_asm.rs | 2 +- src/test/ui/consts/inline_asm.stderr | 4 +- 5 files changed, 6 insertions(+), 44 deletions(-) delete mode 100644 compiler/rustc_error_codes/src/error_codes/E0019.md diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index a202736ea6cbe..6af265d5069a0 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -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"), @@ -461,6 +460,7 @@ E0774: include_str!("./error_codes/E0774.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, diff --git a/compiler/rustc_error_codes/src/error_codes/E0019.md b/compiler/rustc_error_codes/src/error_codes/E0019.md deleted file mode 100644 index ef43a57a9810c..0000000000000 --- a/compiler/rustc_error_codes/src/error_codes/E0019.md +++ /dev/null @@ -1,38 +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(asm)] - -fn main() { - static STATIC11: i32 = { - let x: i32; - unsafe { asm!("mov rax, 2", out("rax") x) }; // error! - x - }; -} -``` - -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! -} -``` diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 6c34e0681c46c..25ed7859d2187 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -193,8 +193,8 @@ impl NonConstOp for InlineAsm { struct_span_err!( ccx.tcx.sess, span, - E0019, - "{} contains unimplemented expression type", + E0015, + "inline assembly is not allowed in {}s", ccx.const_kind() ) } diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs index c2ab97e54f0c8..b8b755018e61e 100644 --- a/src/test/ui/consts/inline_asm.rs +++ b/src/test/ui/consts/inline_asm.rs @@ -1,6 +1,6 @@ #![feature(llvm_asm)] const _: () = unsafe { llvm_asm!("nop") }; -//~^ ERROR contains unimplemented expression type +//~^ ERROR inline assembly fn main() {} diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr index 0a064c8136651..6fb6b69d220ca 100644 --- a/src/test/ui/consts/inline_asm.stderr +++ b/src/test/ui/consts/inline_asm.stderr @@ -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`.