From 8b7d2bc270af4bc873303e7c43000e49a0d5fa5a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 11:41:27 -0800 Subject: [PATCH 01/14] Add E0744 for control flow in consts --- src/librustc_passes/error_codes.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs index e22e69a069737..3f5b0dcab74e0 100644 --- a/src/librustc_passes/error_codes.rs +++ b/src/librustc_passes/error_codes.rs @@ -626,6 +626,28 @@ async fn foo() {} Switch to the Rust 2018 edition to use `async fn`. "##, +E0744: r##" +Control-flow expressions are not allowed inside a const context. + +At the moment, `if` and `match`, as well as the looping constructs `for`, +`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. + +```compile_fail,E0744 +const _: { + let mut x = 0; + loop { + x += 1; + if x == 4 { + break; + } + } + + x +}; +``` + +"##, + ; E0226, // only a single explicit lifetime bound is permitted E0472, // asm! is unsupported on this target From 33b62be8626b28f3c6fa0e6186ad114c452bc966 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 11:43:33 -0800 Subject: [PATCH 02/14] Get `FnSig` by `HirId` --- src/librustc/hir/map/mod.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d7b1676c1d4d3..83372dd8adefd 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -79,6 +79,33 @@ impl<'hir> Entry<'hir> { } } + fn fn_sig(&self) -> Option<&'hir FnSig> { + match &self.node { + Node::Item(item) => { + match &item.kind { + ItemKind::Fn(sig, _, _) => Some(sig), + _ => None, + } + } + + Node::TraitItem(item) => { + match &item.kind { + TraitItemKind::Method(sig, _) => Some(sig), + _ => None + } + } + + Node::ImplItem(item) => { + match &item.kind { + ImplItemKind::Method(sig, _) => Some(sig), + _ => None, + } + } + + _ => None, + } + } + fn associated_body(self) -> Option { match self.node { Node::Item(item) => { @@ -450,6 +477,14 @@ impl<'hir> Map<'hir> { } } + pub fn fn_sig_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnSig> { + if let Some(entry) = self.find_entry(hir_id) { + entry.fn_sig() + } else { + bug!("no entry for hir_id `{}`", hir_id) + } + } + /// Returns the `HirId` that corresponds to the definition of /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. From 3a84efd0cc05ab2724b1f6a215dca089f863c310 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 11:44:56 -0800 Subject: [PATCH 03/14] Add HIR pass to check for `if`s and `loop`s in a `const` These high-level constructs get mapped to control-flow primitives by the time the MIR const-checker runs, making it hard to get the span for the erroneous expression. --- src/librustc/query/mod.rs | 5 + src/librustc_passes/check_const.rs | 157 +++++++++++++++++++++++++++++ src/librustc_passes/lib.rs | 2 + 3 files changed, 164 insertions(+) create mode 100644 src/librustc_passes/check_const.rs diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index bd7b77b0abb17..9bd2a933c1c69 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -329,6 +329,11 @@ rustc_queries! { desc { |tcx| "checking for unstable API usage in {}", key.describe_as_module(tcx) } } + /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`). + query check_mod_const_bodies(key: DefId) -> () { + desc { |tcx| "checking consts in {}", key.describe_as_module(tcx) } + } + /// Checks the loops in the module. query check_mod_loops(key: DefId) -> () { desc { |tcx| "checking loops in {}", key.describe_as_module(tcx) } diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs new file mode 100644 index 0000000000000..70e4a19e96fa1 --- /dev/null +++ b/src/librustc_passes/check_const.rs @@ -0,0 +1,157 @@ +//! This pass checks the HIR bodies in a const context (e.g., `const`, `static`, `const fn`) for +//! structured control flow (e.g. `if`, `while`), which is forbidden in a const context. +//! +//! By the time the MIR const-checker runs, these high-level constructs have been lowered to +//! control-flow primitives (e.g., `Goto`, `SwitchInt`), making it tough to properly attribute +//! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips +//! through, but errors for structured control flow in a `const` should be emitted here. + +use rustc::hir::def_id::DefId; +use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; +use rustc::hir::map::Map; +use rustc::hir; +use rustc::session::Session; +use rustc::ty::TyCtxt; +use rustc::ty::query::Providers; +use syntax::span_err; +use syntax_pos::Span; + +use std::fmt; + +#[derive(Copy, Clone)] +enum ConstKind { + Static, + StaticMut, + ConstFn, + Const, + AnonConst, +} + +impl ConstKind { + fn for_body(body: &hir::Body, hir_map: &Map<'_>) -> Option { + let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const(); + + let owner = hir_map.body_owner(body.id()); + let const_kind = match hir_map.body_owner_kind(owner) { + hir::BodyOwnerKind::Const => Self::Const, + hir::BodyOwnerKind::Static(hir::Mutability::MutMutable) => Self::StaticMut, + hir::BodyOwnerKind::Static(hir::Mutability::MutImmutable) => Self::Static, + + hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn, + hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None, + }; + + Some(const_kind) + } +} + +impl fmt::Display for ConstKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match self { + Self::Static => "static", + Self::StaticMut => "static mut", + Self::Const | Self::AnonConst => "const", + Self::ConstFn => "const fn", + }; + + write!(f, "{}", s) + } +} + +fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: DefId) { + if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + return; + } + + let mut vis = CheckConstVisitor::new(tcx); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis.as_deep_visitor()); +} + +pub(crate) fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_const_bodies, + ..*providers + }; +} + +#[derive(Copy, Clone)] +struct CheckConstVisitor<'tcx> { + sess: &'tcx Session, + hir_map: &'tcx Map<'tcx>, + const_kind: Option, +} + +impl<'tcx> CheckConstVisitor<'tcx> { + fn new(tcx: TyCtxt<'tcx>) -> Self { + CheckConstVisitor { + sess: &tcx.sess, + hir_map: tcx.hir(), + const_kind: None, + } + } + + /// Emits an error when an unsupported expression is found in a const context. + fn const_check_violated(&self, bad_op: &str, span: Span) { + let const_kind = self.const_kind + .expect("`const_check_violated` may only be called inside a const context"); + + span_err!(self.sess, span, E0744, "`{}` is not allowed in a `{}`", bad_op, const_kind); + } + + /// Saves the parent `const_kind` before visiting a nested `Body` and restores it afterwards. + fn recurse_into(&mut self, kind: Option, f: impl FnOnce(&mut Self)) { + let parent_kind = self.const_kind; + self.const_kind = kind; + f(self); + self.const_kind = parent_kind; + } +} + +impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.hir_map) + } + + fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) { + let kind = Some(ConstKind::AnonConst); + self.recurse_into(kind, |this| hir::intravisit::walk_anon_const(this, anon)); + } + + fn visit_body(&mut self, body: &'tcx hir::Body) { + let kind = ConstKind::for_body(body, self.hir_map); + self.recurse_into(kind, |this| hir::intravisit::walk_body(this, body)); + } + + fn visit_expr(&mut self, e: &'tcx hir::Expr) { + match &e.kind { + // Skip these checks if the current item is not const. + _ if self.const_kind.is_none() => {} + + hir::ExprKind::Loop(_, _, source) => { + self.const_check_violated(source.name(), e.span); + } + + hir::ExprKind::Match(_, _, source) => { + use hir::MatchSource::*; + + let op = match source { + Normal => Some("match"), + IfDesugar { .. } | IfLetDesugar { .. } => Some("if"), + TryDesugar => Some("?"), + AwaitDesugar => Some(".await"), + + // These are handled by `ExprKind::Loop` above. + WhileDesugar | WhileLetDesugar | ForLoopDesugar => None, + }; + + if let Some(op) = op { + self.const_check_violated(op, e.span); + } + } + + _ => {}, + } + + hir::intravisit::walk_expr(self, e); + } +} diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index db59d8e101f77..1cbe6a652af96 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -23,6 +23,7 @@ use rustc::ty::query::Providers; pub mod error_codes; pub mod ast_validation; +mod check_const; pub mod hir_stats; pub mod layout_test; pub mod loops; @@ -32,6 +33,7 @@ mod liveness; mod intrinsicck; pub fn provide(providers: &mut Providers<'_>) { + check_const::provide(providers); entry::provide(providers); loops::provide(providers); liveness::provide(providers); From 267733b7960c8816345071fc028aa2ce15ea8e63 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 11:46:55 -0800 Subject: [PATCH 04/14] Enable const-checking HIR bodies --- src/librustc_interface/passes.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c57622b8b8fe5..83b936dd7aa2c 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -875,6 +875,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { tcx.ensure().check_mod_loops(local_def_id); tcx.ensure().check_mod_attrs(local_def_id); tcx.ensure().check_mod_unstable_api_usage(local_def_id); + tcx.ensure().check_mod_const_bodies(local_def_id); }); }); }); From 92386e8e57acccc5894041c877c1da1fe3b50e10 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 12:24:23 -0800 Subject: [PATCH 05/14] Remove if/loop tests from min_const_fn These errors will be triggered before the MIR const-checker runs, causing all other errors to be silenced. They are now checked in the `const-{if,loop}` tests. --- src/test/ui/consts/min_const_fn/min_const_fn.rs | 4 ---- 1 file changed, 4 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 db68a05905a14..c3436d4840ac7 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 @@ -97,10 +97,6 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize } //~^ ERROR casting pointers to ints is unstable const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } //~^ ERROR casting pointers to ints is unstable -const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } -//~^ ERROR loops and conditional expressions are not stable in const fn -const fn foo30_5(b: bool) { while b { } } -//~^ ERROR loops are not allowed in const fn const fn foo30_6() -> bool { let x = true; x } const fn foo36(a: bool, b: bool) -> bool { a && b } //~^ ERROR loops and conditional expressions are not stable in const fn From 67336bb399deac766faed5e13a032f017c3353b3 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 12:26:59 -0800 Subject: [PATCH 06/14] Extend const-loop and const-if to handle more cases This makes sure that our HIR visitor is visiting as many const-items as possible. --- src/test/ui/consts/const-if.rs | 22 ++++++++-- src/test/ui/consts/const-loop.rs | 70 ++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/test/ui/consts/const-if.rs b/src/test/ui/consts/const-if.rs index 9bb5bcc499e61..440723a3fe1b9 100644 --- a/src/test/ui/consts/const-if.rs +++ b/src/test/ui/consts/const-if.rs @@ -1,5 +1,21 @@ -const _X: i32 = if true { 5 } else { 6 }; -//~^ ERROR constant contains unimplemented expression type -//~| ERROR constant contains unimplemented expression type +const _: i32 = if true { //~ ERROR if expression is not allowed in a const + 5 +} else { + 6 +}; + +const _: i32 = match 1 { //~ ERROR match expression is not allowed in a const + 2 => 3, + 4 => 5, + _ => 0, +}; + +const fn foo() -> i32 { + if true { 5 } else { 6 } //~ ERROR if expression is not allowed in a const fn +} + +const fn bar() -> i32 { + match 0 { 1 => 2, _ => 0 } //~ ERROR match expression is not allowed in a const fn +} fn main() {} diff --git a/src/test/ui/consts/const-loop.rs b/src/test/ui/consts/const-loop.rs index 954f269d30e59..b94f3de4d47f1 100644 --- a/src/test/ui/consts/const-loop.rs +++ b/src/test/ui/consts/const-loop.rs @@ -1,13 +1,49 @@ +const _: () = loop {}; //~ ERROR loop is not allowed in a const + +static FOO: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a static + +const fn foo() { + loop {} //~ ERROR loop is not allowed in a const fn +} + +pub trait Foo { + const BAR: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a const +} + +impl Foo for () { + const BAR: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a const +} + +fn non_const_outside() { + const fn const_inside() { + loop {} //~ ERROR `loop` is not allowed in a `const fn` + } +} + +const fn const_outside() { + fn non_const_inside() { + loop {} + } +} + +fn main() { + let x = [0; { + while false {} + //~^ ERROR `while` is not allowed in a `const` + //~| ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type + 4 + }]; +} + const _: i32 = { let mut x = 0; - while x < 4 { - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type + while x < 4 { //~ ERROR while loop is not allowed in a const x += 1; } - while x < 8 { + while x < 8 { //~ ERROR while loop is not allowed in a const x += 1; } @@ -17,16 +53,11 @@ const _: i32 = { const _: i32 = { let mut x = 0; - for i in 0..4 { - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type - //~| ERROR references in constants may only refer to immutable values - //~| ERROR calls in constants are limited to constant functions, tuple - // structs and tuple variants + for i in 0..4 { //~ ERROR for loop is not allowed in a const x += i; } - for i in 0..4 { + for i in 0..4 { //~ ERROR for loop is not allowed in a const x += i; } @@ -36,18 +67,16 @@ const _: i32 = { const _: i32 = { let mut x = 0; - loop { + loop { //~ ERROR loop is not allowed in a const x += 1; - if x == 4 { - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type + if x == 4 { //~ ERROR if expression is not allowed in a const break; } } - loop { + loop { //~ ERROR loop is not allowed in a const x += 1; - if x == 8 { + if x == 8 { //~ ERROR if expression is not allowed in a const break; } } @@ -55,4 +84,9 @@ const _: i32 = { x }; -fn main() {} +const _: i32 = { + let mut x = 0; + while let None = Some(x) { } //~ ERROR while loop is not allowed in a const + while let None = Some(x) { } //~ ERROR while loop is not allowed in a const + x +}; From 3ce8ca45d63a65e0c0eaaa4a29f8ce3ccf5350b9 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 12:29:30 -0800 Subject: [PATCH 07/14] Bless const tests with improved diagnostics --- .../compile-fail/consts/const-fn-error.rs | 1 + src/test/compile-fail/issue-52443.rs | 4 + src/test/ui/borrowck/issue-64453.rs | 5 +- src/test/ui/borrowck/issue-64453.stderr | 29 +--- src/test/ui/closures/issue-52437.rs | 1 + src/test/ui/closures/issue-52437.stderr | 11 +- .../ui/consts/const-eval/infinite_loop.rs | 2 + .../ui/consts/const-eval/infinite_loop.stderr | 27 +++- src/test/ui/consts/const-eval/issue-52475.rs | 3 +- .../ui/consts/const-eval/issue-52475.stderr | 19 ++- .../consts/const-eval/match-test-ptr-null.rs | 1 + .../const-eval/match-test-ptr-null.stderr | 18 ++- src/test/ui/consts/const-if.rs | 8 +- src/test/ui/consts/const-if.stderr | 42 +++-- src/test/ui/consts/const-loop.rs | 30 ++-- src/test/ui/consts/const-loop.stderr | 152 +++++++++++++----- src/test/ui/consts/const-match-pattern-arm.rs | 8 +- .../ui/consts/const-match-pattern-arm.stderr | 39 ++--- src/test/ui/consts/min_const_fn/loop_ice.rs | 2 +- .../ui/consts/min_const_fn/loop_ice.stderr | 7 +- .../consts/min_const_fn/min_const_fn.stderr | 50 ++---- .../ui/consts/single_variant_match_ice.rs | 7 +- .../ui/consts/single_variant_match_ice.stderr | 38 +++-- src/test/ui/issues/issue-46843.rs | 5 +- src/test/ui/issues/issue-46843.stderr | 30 ++-- src/test/ui/issues/issue-50577.rs | 3 + src/test/ui/issues/issue-50577.stderr | 29 +++- src/test/ui/issues/issue-50582.rs | 1 + src/test/ui/issues/issue-50582.stderr | 11 +- src/test/ui/issues/issue-50585.rs | 1 + src/test/ui/issues/issue-50585.stderr | 11 +- src/test/ui/issues/issue-51714.rs | 1 + src/test/ui/issues/issue-51714.stderr | 11 +- .../ui/return/return-match-array-const.rs | 12 +- .../ui/return/return-match-array-const.stderr | 27 +++- .../disallowed-positions.rs | 3 + .../disallowed-positions.stderr | 36 +++-- 37 files changed, 442 insertions(+), 243 deletions(-) diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/compile-fail/consts/const-fn-error.rs index 1de23f2a5e94f..6f414dab88eb2 100644 --- a/src/test/compile-fail/consts/const-fn-error.rs +++ b/src/test/compile-fail/consts/const-fn-error.rs @@ -10,6 +10,7 @@ const fn f(x: usize) -> usize { //~| ERROR E0019 //~| ERROR E0019 //~| ERROR E0080 + //~| ERROR E0744 sum += i; } sum diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index 28d9937b5e881..90b9a1c265ad3 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -1,12 +1,16 @@ fn main() { [(); & { loop { continue } } ]; //~ ERROR mismatched types + //~^ ERROR `loop` is not allowed in a `const` [(); loop { break }]; //~ ERROR mismatched types + //~^ ERROR `loop` is not allowed in a `const` [(); {while true {break}; 0}]; //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| ERROR `while` is not allowed in a `const` //~| WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; //~^ ERROR calls in constants are limited to constant functions + //~| ERROR `for` is not allowed in a `const` //~| ERROR references in constants may only refer to immutable values //~| ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type diff --git a/src/test/ui/borrowck/issue-64453.rs b/src/test/ui/borrowck/issue-64453.rs index d8ab6b6e25f6f..8a405edb04655 100644 --- a/src/test/ui/borrowck/issue-64453.rs +++ b/src/test/ui/borrowck/issue-64453.rs @@ -2,9 +2,7 @@ struct Project; struct Value; static settings_dir: String = format!(""); -//~^ ERROR [E0019] -//~| ERROR [E0015] -//~| ERROR [E0015] +//~^ ERROR `match` is not allowed in a `static` fn from_string(_: String) -> Value { Value @@ -13,7 +11,6 @@ fn set_editor(_: Value) {} fn main() { let settings_data = from_string(settings_dir); - //~^ ERROR cannot move out of static item `settings_dir` [E0507] let args: i32 = 0; match args { diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr index 6987417fe192e..f437880a1655f 100644 --- a/src/test/ui/borrowck/issue-64453.stderr +++ b/src/test/ui/borrowck/issue-64453.stderr @@ -1,26 +1,4 @@ -error[E0507]: cannot move out of static item `settings_dir` - --> $DIR/issue-64453.rs:15:37 - | -LL | let settings_data = from_string(settings_dir); - | ^^^^^^^^^^^^ move occurs because `settings_dir` has type `std::string::String`, which does not implement the `Copy` trait - -error[E0019]: static contains unimplemented expression type - --> $DIR/issue-64453.rs:4:31 - | -LL | static settings_dir: String = format!(""); - | ^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-64453.rs:4:31 - | -LL | static settings_dir: String = format!(""); - | ^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants +error[E0744]: `match` is not allowed in a `static` --> $DIR/issue-64453.rs:4:31 | LL | static settings_dir: String = format!(""); @@ -28,7 +6,6 @@ LL | static settings_dir: String = format!(""); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0019, E0507. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/closures/issue-52437.rs b/src/test/ui/closures/issue-52437.rs index 6ac5380a5aa23..1e649a556e01d 100644 --- a/src/test/ui/closures/issue-52437.rs +++ b/src/test/ui/closures/issue-52437.rs @@ -1,5 +1,6 @@ fn main() { [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //~^ ERROR: invalid label name `'static` + //~| ERROR: `loop` is not allowed in a `const` //~| ERROR: type annotations needed } diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr index e76f942e9ba57..b4b40336aa926 100644 --- a/src/test/ui/closures/issue-52437.stderr +++ b/src/test/ui/closures/issue-52437.stderr @@ -4,12 +4,19 @@ error: invalid label name `'static` LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^^^^^^^ +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/issue-52437.rs:2:13 + | +LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0282]: type annotations needed --> $DIR/issue-52437.rs:2:30 | LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^ consider giving this closure parameter a type -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0282, E0744. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index 8fa5b0a961f9f..ee1d588e553e1 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -7,8 +7,10 @@ fn main() { while n != 0 { //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| ERROR `while` is not allowed in a `const` n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed + //~| ERROR `if` is not allowed in a `const` } n }]; diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 68e7fdb12517b..bf5d2c8c32855 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,3 +1,21 @@ +error[E0744]: `while` is not allowed in a `const` + --> $DIR/infinite_loop.rs:7:9 + | +LL | / while n != 0 { +LL | | +LL | | +LL | | +... | +LL | | +LL | | } + | |_________^ + +error[E0744]: `if` is not allowed in a `const` + --> $DIR/infinite_loop.rs:11:17 + | +LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0019]: constant contains unimplemented expression type --> $DIR/infinite_loop.rs:7:15 | @@ -10,7 +28,8 @@ error[E0019]: constant contains unimplemented expression type LL | / while n != 0 { LL | | LL | | -LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; +LL | | +... | LL | | LL | | } | |_________^ @@ -29,12 +48,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:10:20 + --> $DIR/infinite_loop.rs:11:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0019, E0080. +Some errors have detailed explanations: E0019, E0080, E0744. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index b42249e57fa9a..b9cdf09b85f51 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -4,7 +4,8 @@ fn main() { let mut x = &0; let mut n = 0; while n < 5 { - //~^ ERROR constant contains unimplemented expression type + //~^ ERROR `while` is not allowed in a `const` + //~| ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type n = (n + 1) % 5; //~ ERROR evaluation of constant value failed x = &0; // Materialize a new AllocId diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 1e83cbcff2bf1..25d56e3fac494 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,3 +1,15 @@ +error[E0744]: `while` is not allowed in a `const` + --> $DIR/issue-52475.rs:6:9 + | +LL | / while n < 5 { +LL | | +LL | | +LL | | +LL | | n = (n + 1) % 5; +LL | | x = &0; // Materialize a new AllocId +LL | | } + | |_________^ + error[E0019]: constant contains unimplemented expression type --> $DIR/issue-52475.rs:6:15 | @@ -10,6 +22,7 @@ error[E0019]: constant contains unimplemented expression type LL | / while n < 5 { LL | | LL | | +LL | | LL | | n = (n + 1) % 5; LL | | x = &0; // Materialize a new AllocId LL | | } @@ -29,12 +42,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:9:17 + --> $DIR/issue-52475.rs:10:17 | LL | n = (n + 1) % 5; | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0019, E0080. +Some errors have detailed explanations: E0019, E0080, E0744. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 5b89b0262aca5..0dc3652bbee98 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -5,6 +5,7 @@ fn main() { let _: [u8; 0] = [4; { match &1 as *const i32 as usize { //~^ ERROR casting pointers to integers in constants + //~| ERROR `match` is not allowed in a `const` //~| ERROR constant contains unimplemented expression type //~| ERROR evaluation of constant value failed 0 => 42, //~ ERROR constant contains unimplemented expression type diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index 3d34ac4266270..ab4d28c045598 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -1,3 +1,15 @@ +error[E0744]: `match` is not allowed in a `const` + --> $DIR/match-test-ptr-null.rs:6:9 + | +LL | / match &1 as *const i32 as usize { +LL | | +LL | | +LL | | +... | +LL | | n => n, +LL | | } + | |_________^ + error[E0658]: casting pointers to integers in constants is unstable --> $DIR/match-test-ptr-null.rs:6:15 | @@ -14,7 +26,7 @@ LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:10:13 + --> $DIR/match-test-ptr-null.rs:11:13 | LL | 0 => 42, | ^ @@ -25,7 +37,7 @@ error[E0080]: evaluation of constant value failed LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0019, E0080, E0658. +Some errors have detailed explanations: E0019, E0080, E0658, E0744. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-if.rs b/src/test/ui/consts/const-if.rs index 440723a3fe1b9..94cce60453dcc 100644 --- a/src/test/ui/consts/const-if.rs +++ b/src/test/ui/consts/const-if.rs @@ -1,21 +1,21 @@ -const _: i32 = if true { //~ ERROR if expression is not allowed in a const +const _: i32 = if true { //~ ERROR `if` is not allowed in a `const` 5 } else { 6 }; -const _: i32 = match 1 { //~ ERROR match expression is not allowed in a const +const _: i32 = match 1 { //~ ERROR `match` is not allowed in a `const` 2 => 3, 4 => 5, _ => 0, }; const fn foo() -> i32 { - if true { 5 } else { 6 } //~ ERROR if expression is not allowed in a const fn + if true { 5 } else { 6 } //~ ERROR `if` is not allowed in a `const fn` } const fn bar() -> i32 { - match 0 { 1 => 2, _ => 0 } //~ ERROR match expression is not allowed in a const fn + match 0 { 1 => 2, _ => 0 } //~ ERROR `match` is not allowed in a `const fn` } fn main() {} diff --git a/src/test/ui/consts/const-if.stderr b/src/test/ui/consts/const-if.stderr index 655fcdae58748..6fb2a0e150190 100644 --- a/src/test/ui/consts/const-if.stderr +++ b/src/test/ui/consts/const-if.stderr @@ -1,15 +1,37 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-if.rs:1:20 +error[E0744]: `if` is not allowed in a `const` + --> $DIR/const-if.rs:1:16 | -LL | const _X: i32 = if true { 5 } else { 6 }; - | ^^^^ +LL | const _: i32 = if true { + | ________________^ +LL | | 5 +LL | | } else { +LL | | 6 +LL | | }; + | |_^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-if.rs:1:17 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/const-if.rs:7:16 | -LL | const _X: i32 = if true { 5 } else { 6 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const _: i32 = match 1 { + | ________________^ +LL | | 2 => 3, +LL | | 4 => 5, +LL | | _ => 0, +LL | | }; + | |_^ -error: aborting due to 2 previous errors +error[E0744]: `if` is not allowed in a `const fn` + --> $DIR/const-if.rs:14:5 + | +LL | if true { 5 } else { 6 } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0744]: `match` is not allowed in a `const fn` + --> $DIR/const-if.rs:18:5 + | +LL | match 0 { 1 => 2, _ => 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0019`. +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/consts/const-loop.rs b/src/test/ui/consts/const-loop.rs index b94f3de4d47f1..383db24ad6350 100644 --- a/src/test/ui/consts/const-loop.rs +++ b/src/test/ui/consts/const-loop.rs @@ -1,17 +1,17 @@ -const _: () = loop {}; //~ ERROR loop is not allowed in a const +const _: () = loop {}; //~ ERROR `loop` is not allowed in a `const` -static FOO: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a static +static FOO: i32 = loop { break 4; }; //~ ERROR `loop` is not allowed in a `static` const fn foo() { - loop {} //~ ERROR loop is not allowed in a const fn + loop {} //~ ERROR `loop` is not allowed in a `const fn` } pub trait Foo { - const BAR: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a const + const BAR: i32 = loop { break 4; }; //~ ERROR `loop` is not allowed in a `const` } impl Foo for () { - const BAR: i32 = loop { break 4; }; //~ ERROR loop is not allowed in a const + const BAR: i32 = loop { break 4; }; //~ ERROR `loop` is not allowed in a `const` } fn non_const_outside() { @@ -39,11 +39,11 @@ fn main() { const _: i32 = { let mut x = 0; - while x < 4 { //~ ERROR while loop is not allowed in a const + while x < 4 { //~ ERROR `while` is not allowed in a `const` x += 1; } - while x < 8 { //~ ERROR while loop is not allowed in a const + while x < 8 { //~ ERROR `while` is not allowed in a `const` x += 1; } @@ -53,11 +53,11 @@ const _: i32 = { const _: i32 = { let mut x = 0; - for i in 0..4 { //~ ERROR for loop is not allowed in a const + for i in 0..4 { //~ ERROR `for` is not allowed in a `const` x += i; } - for i in 0..4 { //~ ERROR for loop is not allowed in a const + for i in 0..4 { //~ ERROR `for` is not allowed in a `const` x += i; } @@ -67,16 +67,16 @@ const _: i32 = { const _: i32 = { let mut x = 0; - loop { //~ ERROR loop is not allowed in a const + loop { //~ ERROR `loop` is not allowed in a `const` x += 1; - if x == 4 { //~ ERROR if expression is not allowed in a const + if x == 4 { //~ ERROR `if` is not allowed in a `const` break; } } - loop { //~ ERROR loop is not allowed in a const + loop { //~ ERROR `loop` is not allowed in a `const` x += 1; - if x == 8 { //~ ERROR if expression is not allowed in a const + if x == 8 { //~ ERROR `if` is not allowed in a `const` break; } } @@ -86,7 +86,7 @@ const _: i32 = { const _: i32 = { let mut x = 0; - while let None = Some(x) { } //~ ERROR while loop is not allowed in a const - while let None = Some(x) { } //~ ERROR while loop is not allowed in a const + while let None = Some(x) { } //~ ERROR `while let` is not allowed in a `const` + while let None = Some(x) { } //~ ERROR `while let` is not allowed in a `const` x }; diff --git a/src/test/ui/consts/const-loop.stderr b/src/test/ui/consts/const-loop.stderr index e6e4e2f5bb808..bfb953547d354 100644 --- a/src/test/ui/consts/const-loop.stderr +++ b/src/test/ui/consts/const-loop.stderr @@ -1,60 +1,140 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:4:11 +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/const-loop.rs:1:15 | -LL | while x < 4 { - | ^^^^^ +LL | const _: () = loop {}; + | ^^^^^^^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:4:5 +error[E0744]: `loop` is not allowed in a `static` + --> $DIR/const-loop.rs:3:19 + | +LL | static FOO: i32 = loop { break 4; }; + | ^^^^^^^^^^^^^^^^^ + +error[E0744]: `loop` is not allowed in a `const fn` + --> $DIR/const-loop.rs:6:5 + | +LL | loop {} + | ^^^^^^^ + +error[E0744]: `loop` is not allowed in a `const fn` + --> $DIR/const-loop.rs:19:9 + | +LL | loop {} + | ^^^^^^^ + +error[E0744]: `while` is not allowed in a `const` + --> $DIR/const-loop.rs:31:9 + | +LL | while false {} + | ^^^^^^^^^^^^^^ + +error[E0744]: `while` is not allowed in a `const` + --> $DIR/const-loop.rs:42:5 | LL | / while x < 4 { -LL | | -LL | | LL | | x += 1; LL | | } | |_____^ -error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/const-loop.rs:20:14 +error[E0744]: `while` is not allowed in a `const` + --> $DIR/const-loop.rs:46:5 | -LL | for i in 0..4 { - | ^^^^ +LL | / while x < 8 { +LL | | x += 1; +LL | | } + | |_____^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:20:14 +error[E0744]: `for` is not allowed in a `const` + --> $DIR/const-loop.rs:56:5 | -LL | for i in 0..4 { - | ^^^^ +LL | / for i in 0..4 { +LL | | x += i; +LL | | } + | |_____^ -error[E0017]: references in constants may only refer to immutable values - --> $DIR/const-loop.rs:20:14 +error[E0744]: `for` is not allowed in a `const` + --> $DIR/const-loop.rs:60:5 | -LL | for i in 0..4 { - | ^^^^ constants require immutable values +LL | / for i in 0..4 { +LL | | x += i; +LL | | } + | |_____^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:20:9 +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/const-loop.rs:70:5 | -LL | for i in 0..4 { - | ^ +LL | / loop { +LL | | x += 1; +LL | | if x == 4 { +LL | | break; +LL | | } +LL | | } + | |_____^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:41:12 +error[E0744]: `if` is not allowed in a `const` + --> $DIR/const-loop.rs:72:9 + | +LL | / if x == 4 { +LL | | break; +LL | | } + | |_________^ + +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/const-loop.rs:77:5 | -LL | if x == 4 { - | ^^^^^^ +LL | / loop { +LL | | x += 1; +LL | | if x == 8 { +LL | | break; +LL | | } +LL | | } + | |_____^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:41:9 +error[E0744]: `if` is not allowed in a `const` + --> $DIR/const-loop.rs:79:9 | -LL | / if x == 4 { -LL | | -LL | | +LL | / if x == 8 { LL | | break; LL | | } | |_________^ -error: aborting due to 8 previous errors +error[E0744]: `while let` is not allowed in a `const` + --> $DIR/const-loop.rs:89:5 + | +LL | while let None = Some(x) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0744]: `while let` is not allowed in a `const` + --> $DIR/const-loop.rs:90:5 + | +LL | while let None = Some(x) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/const-loop.rs:10:22 + | +LL | const BAR: i32 = loop { break 4; }; + | ^^^^^^^^^^^^^^^^^ + +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/const-loop.rs:14:22 + | +LL | const BAR: i32 = loop { break 4; }; + | ^^^^^^^^^^^^^^^^^ + +error[E0019]: constant contains unimplemented expression type + --> $DIR/const-loop.rs:31:15 + | +LL | while false {} + | ^^^^^ + +error[E0019]: constant contains unimplemented expression type + --> $DIR/const-loop.rs:31:9 + | +LL | while false {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 19 previous errors -Some errors have detailed explanations: E0015, E0017, E0019. -For more information about an error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0019, E0744. +For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-match-pattern-arm.rs b/src/test/ui/consts/const-match-pattern-arm.rs index 6ed3ac2356243..0482f7f7daeab 100644 --- a/src/test/ui/consts/const-match-pattern-arm.rs +++ b/src/test/ui/consts/const-match-pattern-arm.rs @@ -1,17 +1,13 @@ #![allow(warnings)] -const x: bool = match Some(true) { - //~^ ERROR: constant contains unimplemented expression type [E0019] +const x: bool = match Some(true) { //~ ERROR `match` is not allowed in a `const` Some(value) => true, - //~^ ERROR: constant contains unimplemented expression type [E0019] _ => false }; const y: bool = { - match Some(true) { - //~^ ERROR: constant contains unimplemented expression type [E0019] + match Some(true) { //~ ERROR `match` is not allowed in a `const` Some(value) => true, - //~^ ERROR: constant contains unimplemented expression type [E0019] _ => false } }; diff --git a/src/test/ui/consts/const-match-pattern-arm.stderr b/src/test/ui/consts/const-match-pattern-arm.stderr index 709b66b7bf016..57ef349a377fd 100644 --- a/src/test/ui/consts/const-match-pattern-arm.stderr +++ b/src/test/ui/consts/const-match-pattern-arm.stderr @@ -1,27 +1,22 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-match-pattern-arm.rs:3:23 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/const-match-pattern-arm.rs:3:17 | -LL | const x: bool = match Some(true) { - | ^^^^^^^^^^ +LL | const x: bool = match Some(true) { + | _________________^ +LL | | Some(value) => true, +LL | | _ => false +LL | | }; + | |_^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-match-pattern-arm.rs:5:5 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/const-match-pattern-arm.rs:9:5 | -LL | Some(value) => true, - | ^^^^^^^^^^^ +LL | / match Some(true) { +LL | | Some(value) => true, +LL | | _ => false +LL | | } + | |_____^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-match-pattern-arm.rs:11:11 - | -LL | match Some(true) { - | ^^^^^^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-match-pattern-arm.rs:13:9 - | -LL | Some(value) => true, - | ^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0019`. +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/consts/min_const_fn/loop_ice.rs b/src/test/ui/consts/min_const_fn/loop_ice.rs index 4278a8e2d0036..754a1d7c2a3a7 100644 --- a/src/test/ui/consts/min_const_fn/loop_ice.rs +++ b/src/test/ui/consts/min_const_fn/loop_ice.rs @@ -1,5 +1,5 @@ const fn foo() { - loop {} //~ ERROR loops are not allowed in const fn + loop {} //~ ERROR `loop` is not allowed in a `const fn` } fn main() {} diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr index edf983fc56b11..87db65fbb7dac 100644 --- a/src/test/ui/consts/min_const_fn/loop_ice.stderr +++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr @@ -1,12 +1,9 @@ -error[E0723]: loops are not allowed in const fn +error[E0744]: `loop` is not allowed in a `const fn` --> $DIR/loop_ice.rs:2:5 | LL | loop {} | ^^^^^^^ - | - = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0723`. +For more information about this error, try `rustc --explain E0744`. 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 64b2ce83da2f8..5ce21e378cd1e 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 @@ -161,25 +161,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:100:38 - | -LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add `#![feature(const_fn)]` to the crate attributes to enable - -error[E0723]: loops are not allowed in const fn - --> $DIR/min_const_fn.rs:102:29 - | -LL | const fn foo30_5(b: bool) { while b { } } - | ^^^^^^^^^^^ - | - = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add `#![feature(const_fn)]` to the crate attributes to enable - -error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:105:44 + --> $DIR/min_const_fn.rs:101:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } | ^^^^^^ @@ -188,7 +170,7 @@ LL | const fn foo36(a: bool, b: bool) -> bool { a && b } = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:107:44 + --> $DIR/min_const_fn.rs:103:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } | ^^^^^^ @@ -197,7 +179,7 @@ LL | const fn foo37(a: bool, b: bool) -> bool { a || b } = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable - --> $DIR/min_const_fn.rs:109:14 + --> $DIR/min_const_fn.rs:105:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ @@ -206,7 +188,7 @@ LL | const fn inc(x: &mut i32) { *x += 1 } = 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:114:6 + --> $DIR/min_const_fn.rs:110:6 | LL | impl Foo { | ^ @@ -215,7 +197,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 { | ^ @@ -224,7 +206,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 { | ^ @@ -233,7 +215,7 @@ LL | impl Foo { = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:130:24 + --> $DIR/min_const_fn.rs:126:24 | LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +224,7 @@ LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } = 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:34 + --> $DIR/min_const_fn.rs:128:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -251,7 +233,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:134:22 + --> $DIR/min_const_fn.rs:130:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -260,7 +242,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:135:23 + --> $DIR/min_const_fn.rs:131:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} | ^^^^^^^^^^^^^^^^^^^^ @@ -269,7 +251,7 @@ LL | const fn no_rpit() -> 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:136:23 + --> $DIR/min_const_fn.rs:132:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ @@ -278,7 +260,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:137:32 + --> $DIR/min_const_fn.rs:133:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +269,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:142:41 + --> $DIR/min_const_fn.rs:138:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -296,7 +278,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[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:145:21 + --> $DIR/min_const_fn.rs:141:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ @@ -305,7 +287,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {} = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:147:27 + --> $DIR/min_const_fn.rs:143:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ @@ -313,7 +295,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add `#![feature(const_fn)]` to the crate attributes to enable -error: aborting due to 36 previous errors +error: aborting due to 34 previous errors Some errors have detailed explanations: E0493, E0723. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/single_variant_match_ice.rs b/src/test/ui/consts/single_variant_match_ice.rs index 75793c904838d..80a92c4c96558 100644 --- a/src/test/ui/consts/single_variant_match_ice.rs +++ b/src/test/ui/consts/single_variant_match_ice.rs @@ -2,11 +2,11 @@ enum Foo { Prob, } -const FOO: u32 = match Foo::Prob { //~ ERROR unimplemented expression type +const FOO: u32 = match Foo::Prob { //~ ERROR `match` is not allowed in a `const` Foo::Prob => 42, }; -const BAR: u32 = match Foo::Prob { //~ ERROR unimplemented expression type +const BAR: u32 = match Foo::Prob { //~ ERROR `match` is not allowed in a `const` x => 42, }; @@ -14,8 +14,7 @@ impl Foo { pub const fn as_val(&self) -> u8 { use self::Foo::*; - match *self { - //~^ ERROR loops and conditional expressions are not stable in const fn + match *self { //~ ERROR `match` is not allowed in a `const fn` Prob => 0x1, } } diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr index 3f37a6c645056..780dd0dcddf49 100644 --- a/src/test/ui/consts/single_variant_match_ice.stderr +++ b/src/test/ui/consts/single_variant_match_ice.stderr @@ -1,25 +1,29 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/single_variant_match_ice.rs:5:24 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/single_variant_match_ice.rs:5:18 | -LL | const FOO: u32 = match Foo::Prob { - | ^^^^^^^^^ +LL | const FOO: u32 = match Foo::Prob { + | __________________^ +LL | | Foo::Prob => 42, +LL | | }; + | |_^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/single_variant_match_ice.rs:9:24 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/single_variant_match_ice.rs:9:18 | -LL | const BAR: u32 = match Foo::Prob { - | ^^^^^^^^^ +LL | const BAR: u32 = match Foo::Prob { + | __________________^ +LL | | x => 42, +LL | | }; + | |_^ -error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/single_variant_match_ice.rs:17:15 +error[E0744]: `match` is not allowed in a `const fn` + --> $DIR/single_variant_match_ice.rs:17:9 | -LL | match *self { - | ^^^^^ - | - = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add `#![feature(const_fn)]` to the crate attributes to enable +LL | / match *self { +LL | | Prob => 0x1, +LL | | } + | |_________^ error: aborting due to 3 previous errors -Some errors have detailed explanations: E0019, E0723. -For more information about an error, try `rustc --explain E0019`. +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/issues/issue-46843.rs b/src/test/ui/issues/issue-46843.rs index aa252efea464b..e5b271367393d 100644 --- a/src/test/ui/issues/issue-46843.rs +++ b/src/test/ui/issues/issue-46843.rs @@ -5,9 +5,8 @@ fn non_const() -> Thing { } pub const Q: i32 = match non_const() { - //~^ ERROR E0015 - //~^^ ERROR unimplemented expression type - Thing::This => 1, //~ ERROR unimplemented expression type + //~^ ERROR `match` is not allowed in a `const` + Thing::This => 1, Thing::That => 0 }; diff --git a/src/test/ui/issues/issue-46843.stderr b/src/test/ui/issues/issue-46843.stderr index 92ee154552c68..9d5332978644e 100644 --- a/src/test/ui/issues/issue-46843.stderr +++ b/src/test/ui/issues/issue-46843.stderr @@ -1,22 +1,14 @@ -error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-46843.rs:7:26 +error[E0744]: `match` is not allowed in a `const` + --> $DIR/issue-46843.rs:7:20 | -LL | pub const Q: i32 = match non_const() { - | ^^^^^^^^^^^ +LL | pub const Q: i32 = match non_const() { + | ____________________^ +LL | | +LL | | Thing::This => 1, +LL | | Thing::That => 0 +LL | | }; + | |_^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-46843.rs:7:26 - | -LL | pub const Q: i32 = match non_const() { - | ^^^^^^^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-46843.rs:10:5 - | -LL | Thing::This => 1, - | ^^^^^^^^^^^ - -error: aborting due to 3 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 E0744`. diff --git a/src/test/ui/issues/issue-50577.rs b/src/test/ui/issues/issue-50577.rs index f0f1dc6c28667..f3f680e7b8ecd 100644 --- a/src/test/ui/issues/issue-50577.rs +++ b/src/test/ui/issues/issue-50577.rs @@ -2,5 +2,8 @@ fn main() { enum Foo { Drop = assert_eq!(1, 1) //~^ ERROR if may be missing an else clause + //~| ERROR `match` is not allowed in a `const` + //~| ERROR `match` is not allowed in a `const` + //~| ERROR `if` is not allowed in a `const` } } diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr index 0c3ba2ea4f94d..055a71f468dd2 100644 --- a/src/test/ui/issues/issue-50577.stderr +++ b/src/test/ui/issues/issue-50577.stderr @@ -1,3 +1,27 @@ +error[E0744]: `match` is not allowed in a `const` + --> $DIR/issue-50577.rs:3:16 + | +LL | Drop = assert_eq!(1, 1) + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error[E0744]: `if` is not allowed in a `const` + --> $DIR/issue-50577.rs:3:16 + | +LL | Drop = assert_eq!(1, 1) + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error[E0744]: `match` is not allowed in a `const` + --> $DIR/issue-50577.rs:3:16 + | +LL | Drop = assert_eq!(1, 1) + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + error[E0317]: if may be missing an else clause --> $DIR/issue-50577.rs:3:16 | @@ -13,6 +37,7 @@ LL | Drop = assert_eq!(1, 1) = help: consider adding an `else` block that evaluates to the expected type = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0317`. +Some errors have detailed explanations: E0317, E0744. +For more information about an error, try `rustc --explain E0317`. diff --git a/src/test/ui/issues/issue-50582.rs b/src/test/ui/issues/issue-50582.rs index 1358e0bde4c82..2d5c935875296 100644 --- a/src/test/ui/issues/issue-50582.rs +++ b/src/test/ui/issues/issue-50582.rs @@ -1,4 +1,5 @@ fn main() { Vec::<[(); 1 + for x in 0..1 {}]>::new(); //~^ ERROR cannot add + //~| ERROR `for` is not allowed in a `const` } diff --git a/src/test/ui/issues/issue-50582.stderr b/src/test/ui/issues/issue-50582.stderr index 226f5a3f0fed2..13f6c4d763392 100644 --- a/src/test/ui/issues/issue-50582.stderr +++ b/src/test/ui/issues/issue-50582.stderr @@ -1,3 +1,9 @@ +error[E0744]: `for` is not allowed in a `const` + --> $DIR/issue-50582.rs:2:20 + | +LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); + | ^^^^^^^^^^^^^^^^ + error[E0277]: cannot add `()` to `{integer}` --> $DIR/issue-50582.rs:2:18 | @@ -6,6 +12,7 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | = help: the trait `std::ops::Add<()>` is not implemented for `{integer}` -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0744. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-50585.rs b/src/test/ui/issues/issue-50585.rs index ca2ece8d53bec..a2f11c98d5a30 100644 --- a/src/test/ui/issues/issue-50585.rs +++ b/src/test/ui/issues/issue-50585.rs @@ -1,4 +1,5 @@ fn main() { |y: Vec<[(); for x in 0..2 {}]>| {}; //~^ ERROR mismatched types + //~| ERROR `for` is not allowed in a `const` } diff --git a/src/test/ui/issues/issue-50585.stderr b/src/test/ui/issues/issue-50585.stderr index 4c41da8fc33a9..8e57c9806e3ee 100644 --- a/src/test/ui/issues/issue-50585.stderr +++ b/src/test/ui/issues/issue-50585.stderr @@ -1,3 +1,9 @@ +error[E0744]: `for` is not allowed in a `const` + --> $DIR/issue-50585.rs:2:18 + | +LL | |y: Vec<[(); for x in 0..2 {}]>| {}; + | ^^^^^^^^^^^^^^^^ + error[E0308]: mismatched types --> $DIR/issue-50585.rs:2:18 | @@ -7,6 +13,7 @@ LL | |y: Vec<[(); for x in 0..2 {}]>| {}; = note: expected type `usize` found type `()` -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0744. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-51714.rs b/src/test/ui/issues/issue-51714.rs index 0dc588d75c654..e0fd7ff896cd3 100644 --- a/src/test/ui/issues/issue-51714.rs +++ b/src/test/ui/issues/issue-51714.rs @@ -10,4 +10,5 @@ fn main() { [(); return while let Some(n) = Some(0) {}]; //~^ ERROR return statement outside of function body + //~| ERROR `while let` is not allowed in a `const` } diff --git a/src/test/ui/issues/issue-51714.stderr b/src/test/ui/issues/issue-51714.stderr index 023d9013ab4ed..a3b20cf97f87d 100644 --- a/src/test/ui/issues/issue-51714.stderr +++ b/src/test/ui/issues/issue-51714.stderr @@ -1,3 +1,9 @@ +error[E0744]: `while let` is not allowed in a `const` + --> $DIR/issue-51714.rs:11:17 + | +LL | [(); return while let Some(n) = Some(0) {}]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0572]: return statement outside of function body --> $DIR/issue-51714.rs:2:14 | @@ -22,6 +28,7 @@ error[E0572]: return statement outside of function body LL | [(); return while let Some(n) = Some(0) {}]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0572`. +Some errors have detailed explanations: E0572, E0744. +For more information about an error, try `rustc --explain E0572`. diff --git a/src/test/ui/return/return-match-array-const.rs b/src/test/ui/return/return-match-array-const.rs index bbcd9600b2257..9f3b9651642a2 100644 --- a/src/test/ui/return/return-match-array-const.rs +++ b/src/test/ui/return/return-match-array-const.rs @@ -1,7 +1,13 @@ fn main() { - [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body + [(); return match 0 { n => n }]; + //~^ ERROR: return statement outside of function body + //~| ERROR: `match` is not allowed in a `const` - [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body + [(); return match 0 { 0 => 0 }]; + //~^ ERROR: return statement outside of function body + //~| ERROR: `match` is not allowed in a `const` - [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body + [(); return match () { 'a' => 0, _ => 0 }]; + //~^ ERROR: return statement outside of function body + //~| ERROR: `match` is not allowed in a `const` } diff --git a/src/test/ui/return/return-match-array-const.stderr b/src/test/ui/return/return-match-array-const.stderr index 6e8c9ed40bbee..496e9208b6106 100644 --- a/src/test/ui/return/return-match-array-const.stderr +++ b/src/test/ui/return/return-match-array-const.stderr @@ -1,3 +1,21 @@ +error[E0744]: `match` is not allowed in a `const` + --> $DIR/return-match-array-const.rs:2:17 + | +LL | [(); return match 0 { n => n }]; + | ^^^^^^^^^^^^^^^^^^ + +error[E0744]: `match` is not allowed in a `const` + --> $DIR/return-match-array-const.rs:6:17 + | +LL | [(); return match 0 { 0 => 0 }]; + | ^^^^^^^^^^^^^^^^^^ + +error[E0744]: `match` is not allowed in a `const` + --> $DIR/return-match-array-const.rs:10:17 + | +LL | [(); return match () { 'a' => 0, _ => 0 }]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0572]: return statement outside of function body --> $DIR/return-match-array-const.rs:2:10 | @@ -5,17 +23,18 @@ LL | [(); return match 0 { n => n }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0572]: return statement outside of function body - --> $DIR/return-match-array-const.rs:4:10 + --> $DIR/return-match-array-const.rs:6:10 | LL | [(); return match 0 { 0 => 0 }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0572]: return statement outside of function body - --> $DIR/return-match-array-const.rs:6:10 + --> $DIR/return-match-array-const.rs:10:10 | LL | [(); return match () { 'a' => 0, _ => 0 }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0572`. +Some errors have detailed explanations: E0572, E0744. +For more information about an error, try `rustc --explain E0572`. diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs index 7d1e5c3d64df3..3baa19b5aed62 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -218,18 +218,21 @@ fn inside_const_generic_arguments() { true && let 1 = 1 //~ ERROR `let` expressions are not supported here //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| ERROR `match` is not allowed in a `const` }>::O = 5 {} while let A::<{ true && let 1 = 1 //~ ERROR `let` expressions are not supported here //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| ERROR `match` is not allowed in a `const` }>::O = 5 {} if A::<{ true && let 1 = 1 //~ ERROR `let` expressions are not supported here //~^ ERROR constant contains unimplemented expression type //~| ERROR constant contains unimplemented expression type + //~| ERROR `match` is not allowed in a `const` }>::O == 5 {} // In the cases above we have `ExprKind::Block` to help us out. diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 65de150b10071..92cdead785689 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -1,5 +1,5 @@ error: expected one of `,` or `>`, found `&&` - --> $DIR/disallowed-positions.rs:242:14 + --> $DIR/disallowed-positions.rs:245:14 | LL | true && let 1 = 1 | ^^ expected one of `,` or `>` @@ -482,7 +482,7 @@ LL | true && let 1 = 1 = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:224:17 + --> $DIR/disallowed-positions.rs:225:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -491,7 +491,7 @@ LL | true && let 1 = 1 = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:230:17 + --> $DIR/disallowed-positions.rs:232:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -513,6 +513,24 @@ warning: the feature `let_chains` is incomplete and may cause the compiler to cr LL | #![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. | ^^^^^^^^^^ +error[E0744]: `match` is not allowed in a `const` + --> $DIR/disallowed-positions.rs:218:17 + | +LL | true && let 1 = 1 + | ^^^^^^^^^ + +error[E0744]: `match` is not allowed in a `const` + --> $DIR/disallowed-positions.rs:225:17 + | +LL | true && let 1 = 1 + | ^^^^^^^^^ + +error[E0744]: `match` is not allowed in a `const` + --> $DIR/disallowed-positions.rs:232:17 + | +LL | true && let 1 = 1 + | ^^^^^^^^^ + error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:32:8 | @@ -966,30 +984,30 @@ LL | true && let 1 = 1 | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:224:25 + --> $DIR/disallowed-positions.rs:225:25 | LL | true && let 1 = 1 | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:224:21 + --> $DIR/disallowed-positions.rs:225:21 | LL | true && let 1 = 1 | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:230:25 + --> $DIR/disallowed-positions.rs:232:25 | LL | true && let 1 = 1 | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:230:21 + --> $DIR/disallowed-positions.rs:232:21 | LL | true && let 1 = 1 | ^ -error: aborting due to 109 previous errors +error: aborting due to 112 previous errors -Some errors have detailed explanations: E0019, E0277, E0308, E0600, E0614. +Some errors have detailed explanations: E0019, E0277, E0308, E0600, E0614, E0744. For more information about an error, try `rustc --explain E0019`. From 281e898ecfb07ab1347a2c7d745542028d4376a8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 6 Nov 2019 17:45:10 -0800 Subject: [PATCH 08/14] Bless back-compat breakages This PR BREAKS CODE THAT WAS ACCEPTED ON STABLE. It's arguably a bug that this was accepted in the first place, but here we are. See #62272 for more info. --- src/test/ui/consts/const-eval/issue-52442.rs | 1 + src/test/ui/consts/const-eval/issue-52442.stderr | 10 ++++++++-- src/test/ui/consts/const-eval/issue-62272.rs | 12 +++++++----- src/test/ui/consts/const-eval/issue-62272.stderr | 15 +++++++++++++++ src/test/ui/consts/const-labeled-break.rs | 8 +++++--- src/test/ui/consts/const-labeled-break.stderr | 9 +++++++++ 6 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/consts/const-eval/issue-62272.stderr create mode 100644 src/test/ui/consts/const-labeled-break.stderr diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs index ea24578c7dd0c..d820c70516124 100644 --- a/src/test/ui/consts/const-eval/issue-52442.rs +++ b/src/test/ui/consts/const-eval/issue-52442.rs @@ -1,5 +1,6 @@ fn main() { [(); { &loop { break } as *const _ as usize } ]; //~^ ERROR casting pointers to integers in constants is unstable + //~| ERROR `loop` is not allowed in a `const` //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr index 5bd4979bdb33c..fa2272f8d634d 100644 --- a/src/test/ui/consts/const-eval/issue-52442.stderr +++ b/src/test/ui/consts/const-eval/issue-52442.stderr @@ -1,3 +1,9 @@ +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/issue-52442.rs:2:14 + | +LL | [(); { &loop { break } as *const _ as usize } ]; + | ^^^^^^^^^^^^^^ + error[E0658]: casting pointers to integers in constants is unstable --> $DIR/issue-52442.rs:2:13 | @@ -13,7 +19,7 @@ error[E0080]: evaluation of constant value failed LL | [(); { &loop { break } as *const _ as usize } ]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0658. +Some errors have detailed explanations: E0080, E0658, E0744. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-62272.rs b/src/test/ui/consts/const-eval/issue-62272.rs index ad8589c73788c..19abd91252db9 100644 --- a/src/test/ui/consts/const-eval/issue-62272.rs +++ b/src/test/ui/consts/const-eval/issue-62272.rs @@ -1,9 +1,11 @@ -// run-pass +// `loop`s unconditionally-broken-from used to be allowed in constants, but are now forbidden by +// the HIR const-checker. +// +// See https://github.com/rust-lang/rust/pull/66170 and +// https://github.com/rust-lang/rust/issues/62272. -// Tests that `loop`s unconditionally-broken-from are allowed in constants. - -const FOO: () = loop { break; }; +const FOO: () = loop { break; }; //~ ERROR `loop` is not allowed in a `const` fn main() { - [FOO; { let x; loop { x = 5; break; } x }]; + [FOO; { let x; loop { x = 5; break; } x }]; //~ ERROR `loop` is not allowed in a `const` } diff --git a/src/test/ui/consts/const-eval/issue-62272.stderr b/src/test/ui/consts/const-eval/issue-62272.stderr new file mode 100644 index 0000000000000..573d04f5e4786 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-62272.stderr @@ -0,0 +1,15 @@ +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/issue-62272.rs:7:17 + | +LL | const FOO: () = loop { break; }; + | ^^^^^^^^^^^^^^^ + +error[E0744]: `loop` is not allowed in a `const` + --> $DIR/issue-62272.rs:10:20 + | +LL | [FOO; { let x; loop { x = 5; break; } x }]; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/consts/const-labeled-break.rs b/src/test/ui/consts/const-labeled-break.rs index 7cdbb22f92459..45e3cf438888e 100644 --- a/src/test/ui/consts/const-labeled-break.rs +++ b/src/test/ui/consts/const-labeled-break.rs @@ -1,10 +1,12 @@ -// build-pass - // Using labeled break in a while loop has caused an illegal instruction being // generated, and an ICE later. // // See https://github.com/rust-lang/rust/issues/51350 for more information. +// +// It is now forbidden by the HIR const-checker. +// +// See https://github.com/rust-lang/rust/pull/66170. -const CRASH: () = 'a: while break 'a {}; +const CRASH: () = 'a: while break 'a {}; //~ ERROR `while` is not allowed in a `const` fn main() {} diff --git a/src/test/ui/consts/const-labeled-break.stderr b/src/test/ui/consts/const-labeled-break.stderr new file mode 100644 index 0000000000000..ec32386439fdc --- /dev/null +++ b/src/test/ui/consts/const-labeled-break.stderr @@ -0,0 +1,9 @@ +error[E0744]: `while` is not allowed in a `const` + --> $DIR/const-labeled-break.rs:10:19 + | +LL | const CRASH: () = 'a: while break 'a {}; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0744`. From eff83e5f49f42e174424da2dd517c1bc5821aa13 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 7 Nov 2019 10:02:01 -0800 Subject: [PATCH 09/14] Small fixes to comments --- src/librustc_passes/check_const.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index 70e4a19e96fa1..ff0de4a73b791 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -1,5 +1,6 @@ -//! This pass checks the HIR bodies in a const context (e.g., `const`, `static`, `const fn`) for -//! structured control flow (e.g. `if`, `while`), which is forbidden in a const context. +//! This pass checks HIR bodies that may be evaluated at compile-time (e.g., `const`, `static`, +//! `const fn`) for structured control flow (e.g. `if`, `while`), which is forbidden in a const +//! context. //! //! By the time the MIR const-checker runs, these high-level constructs have been lowered to //! control-flow primitives (e.g., `Goto`, `SwitchInt`), making it tough to properly attribute @@ -98,7 +99,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { span_err!(self.sess, span, E0744, "`{}` is not allowed in a `{}`", bad_op, const_kind); } - /// Saves the parent `const_kind` before visiting a nested `Body` and restores it afterwards. + /// Saves the parent `const_kind` before calling `f` and restores it afterwards. fn recurse_into(&mut self, kind: Option, f: impl FnOnce(&mut Self)) { let parent_kind = self.const_kind; self.const_kind = kind; @@ -124,7 +125,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { fn visit_expr(&mut self, e: &'tcx hir::Expr) { match &e.kind { - // Skip these checks if the current item is not const. + // Skip the following checks if we are not currently in a const context. _ if self.const_kind.is_none() => {} hir::ExprKind::Loop(_, _, source) => { From 0123cbdc31a994033cffd505a758beba20709de0 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 7 Nov 2019 16:13:35 -0800 Subject: [PATCH 10/14] Fix broken doc-test --- src/librustc_passes/error_codes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs index 3f5b0dcab74e0..72cf0c7ed77c8 100644 --- a/src/librustc_passes/error_codes.rs +++ b/src/librustc_passes/error_codes.rs @@ -633,7 +633,7 @@ At the moment, `if` and `match`, as well as the looping constructs `for`, `while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. ```compile_fail,E0744 -const _: { +const _: i32 = { let mut x = 0; loop { x += 1; From 70aa781c2d8f4ebe0e826d2cdeb8fcd371676a88 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 9 Nov 2019 09:07:13 -0800 Subject: [PATCH 11/14] Change control flow error to delay span bug --- .../transform/check_consts/validation.rs | 9 ++++++++- src/librustc_mir/transform/qualify_consts.rs | 15 ++++++++++++--- src/librustc_passes/check_const.rs | 9 +++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 244d434a51eab..88f16299dc0f7 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -461,7 +461,14 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { self.super_statement(statement, location); } StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { - self.check_op(ops::IfOrMatch); + // FIXME: make this the `emit_error` impl of `ops::IfOrMatch` once the const + // checker is no longer run in compatability mode. + if !self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + self.tcx.sess.delay_span_bug( + self.span, + "complex control flow is forbidden in a const context", + ); + } } // FIXME(eddyb) should these really do nothing? StatementKind::FakeRead(..) | diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 39720af4cb5d6..255e71db89d55 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -723,8 +723,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { bb = target; } _ => { - self.not_const(ops::Loop); - validator.check_op(ops::Loop); + if !self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + self.tcx.sess.delay_span_bug( + self.span, + "complex control flow is forbidden in a const context", + ); + } break; } } @@ -1253,7 +1257,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { self.super_statement(statement, location); } StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { - self.not_const(ops::IfOrMatch); + if !self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + self.tcx.sess.delay_span_bug( + self.span, + "complex control flow is forbidden in a const context", + ); + } } // FIXME(eddyb) should these really do nothing? StatementKind::FakeRead(..) | diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index ff0de4a73b791..3263ee512a950 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -60,10 +60,6 @@ impl fmt::Display for ConstKind { } fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: DefId) { - if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { - return; - } - let mut vis = CheckConstVisitor::new(tcx); tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis.as_deep_visitor()); } @@ -93,6 +89,11 @@ impl<'tcx> CheckConstVisitor<'tcx> { /// Emits an error when an unsupported expression is found in a const context. fn const_check_violated(&self, bad_op: &str, span: Span) { + if self.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + self.sess.span_warn(span, "skipping const checks"); + return; + } + let const_kind = self.const_kind .expect("`const_check_violated` may only be called inside a const context"); From 86734b13bb99c83333ca820e01be3aeace18af75 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 9 Nov 2019 09:29:57 -0800 Subject: [PATCH 12/14] Bless less verbose error messages The MIR const-checker errors for if/match/loop are now delay span bugs, so nothing will be emitted unless the HIR checker misses something. --- .../compile-fail/consts/const-fn-error.rs | 2 - src/test/compile-fail/issue-52443.rs | 6 +-- .../ui/consts/const-eval/infinite_loop.rs | 4 +- .../ui/consts/const-eval/infinite_loop.stderr | 31 +++-------- src/test/ui/consts/const-eval/issue-52475.rs | 2 - .../ui/consts/const-eval/issue-52475.stderr | 28 ++-------- .../consts/const-eval/match-test-ptr-null.rs | 3 +- .../const-eval/match-test-ptr-null.stderr | 20 ++----- src/test/ui/consts/const-loop.rs | 2 - src/test/ui/consts/const-loop.stderr | 37 +++++-------- .../miri_unleashed/enum_discriminants.stderr | 43 ++++++++++----- .../disallowed-positions.rs | 6 --- .../disallowed-positions.stderr | 52 +++---------------- 13 files changed, 68 insertions(+), 168 deletions(-) diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/compile-fail/consts/const-fn-error.rs index 6f414dab88eb2..4adad16a57010 100644 --- a/src/test/compile-fail/consts/const-fn-error.rs +++ b/src/test/compile-fail/consts/const-fn-error.rs @@ -7,8 +7,6 @@ const fn f(x: usize) -> usize { for i in 0..x { //~^ ERROR E0015 //~| ERROR E0017 - //~| ERROR E0019 - //~| ERROR E0019 //~| ERROR E0080 //~| ERROR E0744 sum += i; diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index 90b9a1c265ad3..04eecb5687fd9 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -4,15 +4,11 @@ fn main() { [(); loop { break }]; //~ ERROR mismatched types //~^ ERROR `loop` is not allowed in a `const` [(); {while true {break}; 0}]; - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type - //~| ERROR `while` is not allowed in a `const` + //~^ ERROR `while` is not allowed in a `const` //~| WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; //~^ ERROR calls in constants are limited to constant functions //~| ERROR `for` is not allowed in a `const` //~| ERROR references in constants may only refer to immutable values - //~| ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index ee1d588e553e1..af5e7658d48d2 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -5,9 +5,7 @@ fn main() { //~^ WARNING Constant evaluating a complex constant, this might take some time let mut n = 113383; // #20 in https://oeis.org/A006884 while n != 0 { - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type - //~| ERROR `while` is not allowed in a `const` + //~^ ERROR `while` is not allowed in a `const` n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed //~| ERROR `if` is not allowed in a `const` diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index bf5d2c8c32855..2af6af95c5565 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -3,37 +3,18 @@ error[E0744]: `while` is not allowed in a `const` | LL | / while n != 0 { LL | | +LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; LL | | LL | | -... | -LL | | LL | | } | |_________^ error[E0744]: `if` is not allowed in a `const` - --> $DIR/infinite_loop.rs:11:17 + --> $DIR/infinite_loop.rs:9:17 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/infinite_loop.rs:7:15 - | -LL | while n != 0 { - | ^^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/infinite_loop.rs:7:9 - | -LL | / while n != 0 { -LL | | -LL | | -LL | | -... | -LL | | -LL | | } - | |_________^ - warning: Constant evaluating a complex constant, this might take some time --> $DIR/infinite_loop.rs:4:18 | @@ -48,12 +29,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:11:20 + --> $DIR/infinite_loop.rs:9:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0019, E0080, E0744. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0744. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index b9cdf09b85f51..3788167f44902 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -5,8 +5,6 @@ fn main() { let mut n = 0; while n < 5 { //~^ ERROR `while` is not allowed in a `const` - //~| ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type n = (n + 1) % 5; //~ ERROR evaluation of constant value failed x = &0; // Materialize a new AllocId } diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 25d56e3fac494..b8267f495de94 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -3,26 +3,6 @@ error[E0744]: `while` is not allowed in a `const` | LL | / while n < 5 { LL | | -LL | | -LL | | -LL | | n = (n + 1) % 5; -LL | | x = &0; // Materialize a new AllocId -LL | | } - | |_________^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52475.rs:6:15 - | -LL | while n < 5 { - | ^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52475.rs:6:9 - | -LL | / while n < 5 { -LL | | -LL | | -LL | | LL | | n = (n + 1) % 5; LL | | x = &0; // Materialize a new AllocId LL | | } @@ -42,12 +22,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:10:17 + --> $DIR/issue-52475.rs:8:17 | LL | n = (n + 1) % 5; | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0019, E0080, E0744. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0744. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 0dc3652bbee98..80494d1662987 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -6,9 +6,8 @@ fn main() { match &1 as *const i32 as usize { //~^ ERROR casting pointers to integers in constants //~| ERROR `match` is not allowed in a `const` - //~| ERROR constant contains unimplemented expression type //~| ERROR evaluation of constant value failed - 0 => 42, //~ ERROR constant contains unimplemented expression type + 0 => 42, n => n, } }]; diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index ab4d28c045598..587dca4c1f279 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -5,7 +5,7 @@ LL | / match &1 as *const i32 as usize { LL | | LL | | LL | | -... | +LL | | 0 => 42, LL | | n => n, LL | | } | |_________^ @@ -19,25 +19,13 @@ LL | match &1 as *const i32 as usize { = note: for more information, see https://github.com/rust-lang/rust/issues/51910 = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable -error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:6:15 - | -LL | match &1 as *const i32 as usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:11:13 - | -LL | 0 => 42, - | ^ - error[E0080]: evaluation of constant value failed --> $DIR/match-test-ptr-null.rs:6:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0019, E0080, E0658, E0744. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0658, E0744. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-loop.rs b/src/test/ui/consts/const-loop.rs index 383db24ad6350..b0fe5e320f4a6 100644 --- a/src/test/ui/consts/const-loop.rs +++ b/src/test/ui/consts/const-loop.rs @@ -30,8 +30,6 @@ fn main() { let x = [0; { while false {} //~^ ERROR `while` is not allowed in a `const` - //~| ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type 4 }]; } diff --git a/src/test/ui/consts/const-loop.stderr b/src/test/ui/consts/const-loop.stderr index bfb953547d354..2c96d18175983 100644 --- a/src/test/ui/consts/const-loop.stderr +++ b/src/test/ui/consts/const-loop.stderr @@ -29,7 +29,7 @@ LL | while false {} | ^^^^^^^^^^^^^^ error[E0744]: `while` is not allowed in a `const` - --> $DIR/const-loop.rs:42:5 + --> $DIR/const-loop.rs:40:5 | LL | / while x < 4 { LL | | x += 1; @@ -37,7 +37,7 @@ LL | | } | |_____^ error[E0744]: `while` is not allowed in a `const` - --> $DIR/const-loop.rs:46:5 + --> $DIR/const-loop.rs:44:5 | LL | / while x < 8 { LL | | x += 1; @@ -45,7 +45,7 @@ LL | | } | |_____^ error[E0744]: `for` is not allowed in a `const` - --> $DIR/const-loop.rs:56:5 + --> $DIR/const-loop.rs:54:5 | LL | / for i in 0..4 { LL | | x += i; @@ -53,7 +53,7 @@ LL | | } | |_____^ error[E0744]: `for` is not allowed in a `const` - --> $DIR/const-loop.rs:60:5 + --> $DIR/const-loop.rs:58:5 | LL | / for i in 0..4 { LL | | x += i; @@ -61,7 +61,7 @@ LL | | } | |_____^ error[E0744]: `loop` is not allowed in a `const` - --> $DIR/const-loop.rs:70:5 + --> $DIR/const-loop.rs:68:5 | LL | / loop { LL | | x += 1; @@ -72,7 +72,7 @@ LL | | } | |_____^ error[E0744]: `if` is not allowed in a `const` - --> $DIR/const-loop.rs:72:9 + --> $DIR/const-loop.rs:70:9 | LL | / if x == 4 { LL | | break; @@ -80,7 +80,7 @@ LL | | } | |_________^ error[E0744]: `loop` is not allowed in a `const` - --> $DIR/const-loop.rs:77:5 + --> $DIR/const-loop.rs:75:5 | LL | / loop { LL | | x += 1; @@ -91,7 +91,7 @@ LL | | } | |_____^ error[E0744]: `if` is not allowed in a `const` - --> $DIR/const-loop.rs:79:9 + --> $DIR/const-loop.rs:77:9 | LL | / if x == 8 { LL | | break; @@ -99,13 +99,13 @@ LL | | } | |_________^ error[E0744]: `while let` is not allowed in a `const` - --> $DIR/const-loop.rs:89:5 + --> $DIR/const-loop.rs:87:5 | LL | while let None = Some(x) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0744]: `while let` is not allowed in a `const` - --> $DIR/const-loop.rs:90:5 + --> $DIR/const-loop.rs:88:5 | LL | while let None = Some(x) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,19 +122,6 @@ error[E0744]: `loop` is not allowed in a `const` LL | const BAR: i32 = loop { break 4; }; | ^^^^^^^^^^^^^^^^^ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:31:15 - | -LL | while false {} - | ^^^^^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/const-loop.rs:31:9 - | -LL | while false {} - | ^^^^^^^^^^^^^^ - -error: aborting due to 19 previous errors +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0019, E0744. -For more information about an error, try `rustc --explain E0019`. +For more information about this error, try `rustc --explain E0744`. diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr index df366ba22e4d1..38eeb327135ac 100644 --- a/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr +++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr @@ -1,24 +1,43 @@ warning: skipping const checks - --> $DIR/enum_discriminants.rs:23:13 + --> $DIR/enum_discriminants.rs:24:5 | -LL | let x = Foo::B; - | ^^^^^^ +LL | / match x { +LL | | Foo::B => 0, +LL | | _ => panic!(), +LL | | } + | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:25:9 + --> $DIR/enum_discriminants.rs:88:5 | -LL | Foo::B => 0, - | ^^^^^^ +LL | / if let E1::V2 { .. } = (E1::V1 { f: true }) { +LL | | unreachable!() +LL | | } + | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:88:28 + --> $DIR/enum_discriminants.rs:91:5 | -LL | if let E1::V2 { .. } = (E1::V1 { f: true }) { - | ^^^^^^^^^^^^^^^^^^^^ +LL | / if let E1::V1 { .. } = (E1::V1 { f: true }) { +LL | | } else { +LL | | unreachable!() +LL | | } + | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:88:12 + --> $DIR/enum_discriminants.rs:96:5 | -LL | if let E1::V2 { .. } = (E1::V1 { f: true }) { - | ^^^^^^^^^^^^^ +LL | / if let E2::V1 { .. } = E2::V3:: { +LL | | unreachable!() +LL | | } + | |_____^ + +warning: skipping const checks + --> $DIR/enum_discriminants.rs:99:5 + | +LL | / if let E2::V3 { .. } = E2::V3:: { +LL | | } else { +LL | | unreachable!() +LL | | } + | |_____^ diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs index 3baa19b5aed62..d5756737f1791 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -216,22 +216,16 @@ fn inside_const_generic_arguments() { if let A::<{ true && let 1 = 1 //~ ERROR `let` expressions are not supported here - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type //~| ERROR `match` is not allowed in a `const` }>::O = 5 {} while let A::<{ true && let 1 = 1 //~ ERROR `let` expressions are not supported here - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type //~| ERROR `match` is not allowed in a `const` }>::O = 5 {} if A::<{ true && let 1 = 1 //~ ERROR `let` expressions are not supported here - //~^ ERROR constant contains unimplemented expression type - //~| ERROR constant contains unimplemented expression type //~| ERROR `match` is not allowed in a `const` }>::O == 5 {} diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 92cdead785689..aa7c342819e80 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -1,5 +1,5 @@ error: expected one of `,` or `>`, found `&&` - --> $DIR/disallowed-positions.rs:245:14 + --> $DIR/disallowed-positions.rs:239:14 | LL | true && let 1 = 1 | ^^ expected one of `,` or `>` @@ -482,7 +482,7 @@ LL | true && let 1 = 1 = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:225:17 + --> $DIR/disallowed-positions.rs:223:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -491,7 +491,7 @@ LL | true && let 1 = 1 = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:232:17 + --> $DIR/disallowed-positions.rs:228:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -520,13 +520,13 @@ LL | true && let 1 = 1 | ^^^^^^^^^ error[E0744]: `match` is not allowed in a `const` - --> $DIR/disallowed-positions.rs:225:17 + --> $DIR/disallowed-positions.rs:223:17 | LL | true && let 1 = 1 | ^^^^^^^^^ error[E0744]: `match` is not allowed in a `const` - --> $DIR/disallowed-positions.rs:232:17 + --> $DIR/disallowed-positions.rs:228:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -971,43 +971,7 @@ LL | let 0 = 0?; = help: the trait `std::ops::Try` is not implemented for `{integer}` = note: required by `std::ops::Try::into_result` -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:218:25 - | -LL | true && let 1 = 1 - | ^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:218:21 - | -LL | true && let 1 = 1 - | ^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:225:25 - | -LL | true && let 1 = 1 - | ^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:225:21 - | -LL | true && let 1 = 1 - | ^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:232:25 - | -LL | true && let 1 = 1 - | ^ - -error[E0019]: constant contains unimplemented expression type - --> $DIR/disallowed-positions.rs:232:21 - | -LL | true && let 1 = 1 - | ^ - -error: aborting due to 112 previous errors +error: aborting due to 106 previous errors -Some errors have detailed explanations: E0019, E0277, E0308, E0600, E0614, E0744. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0277, E0308, E0600, E0614, E0744. +For more information about an error, try `rustc --explain E0277`. From 5e048da5a553cae9a6842856fb5eb61425e51f96 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 11 Nov 2019 08:00:49 -0800 Subject: [PATCH 13/14] Bless miri unleashed test now that errors are mandatory --- .../ui/consts/miri_unleashed/enum_discriminants.rs | 10 ++++++---- .../ui/consts/miri_unleashed/enum_discriminants.stderr | 10 +++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.rs b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs index 623fa2a1547c8..d7cdb0babc5c5 100644 --- a/src/test/ui/consts/miri_unleashed/enum_discriminants.rs +++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs @@ -20,9 +20,9 @@ const OVERFLOW: usize = { C(WithWraparoundInvalidValues), } - let x = Foo::B; //~ WARNING skipping const checks - match x { - Foo::B => 0, //~ WARNING skipping const checks + let x = Foo::B; + match x { //~ WARNING skipping const checks + Foo::B => 0, _ => panic!(), } }; @@ -87,18 +87,20 @@ const MORE_OVERFLOW: usize = { if let E1::V2 { .. } = (E1::V1 { f: true }) { //~^ WARNING skipping const checks - //~| WARNING skipping const checks unreachable!() } if let E1::V1 { .. } = (E1::V1 { f: true }) { + //~^ WARNING skipping const checks } else { unreachable!() } if let E2::V1 { .. } = E2::V3:: { + //~^ WARNING skipping const checks unreachable!() } if let E2::V3 { .. } = E2::V3:: { + //~^ WARNING skipping const checks } else { unreachable!() } diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr index 38eeb327135ac..b7fce223af80a 100644 --- a/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr +++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr @@ -11,31 +11,35 @@ warning: skipping const checks --> $DIR/enum_discriminants.rs:88:5 | LL | / if let E1::V2 { .. } = (E1::V1 { f: true }) { +LL | | LL | | unreachable!() LL | | } | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:91:5 + --> $DIR/enum_discriminants.rs:92:5 | LL | / if let E1::V1 { .. } = (E1::V1 { f: true }) { +LL | | LL | | } else { LL | | unreachable!() LL | | } | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:96:5 + --> $DIR/enum_discriminants.rs:98:5 | LL | / if let E2::V1 { .. } = E2::V3:: { +LL | | LL | | unreachable!() LL | | } | |_____^ warning: skipping const checks - --> $DIR/enum_discriminants.rs:99:5 + --> $DIR/enum_discriminants.rs:102:5 | LL | / if let E2::V3 { .. } = E2::V3:: { +LL | | LL | | } else { LL | | unreachable!() LL | | } From 7552bd662f89c67c54e61e2f7c1c1979f6b510e2 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 13 Nov 2019 10:46:44 -0800 Subject: [PATCH 14/14] Use `ast::Mutability` --- src/librustc_passes/check_const.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index 3263ee512a950..a6d7eeabc8864 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -14,6 +14,7 @@ use rustc::hir; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; +use syntax::ast::Mutability; use syntax::span_err; use syntax_pos::Span; @@ -35,8 +36,8 @@ impl ConstKind { let owner = hir_map.body_owner(body.id()); let const_kind = match hir_map.body_owner_kind(owner) { hir::BodyOwnerKind::Const => Self::Const, - hir::BodyOwnerKind::Static(hir::Mutability::MutMutable) => Self::StaticMut, - hir::BodyOwnerKind::Static(hir::Mutability::MutImmutable) => Self::Static, + hir::BodyOwnerKind::Static(Mutability::Mutable) => Self::StaticMut, + hir::BodyOwnerKind::Static(Mutability::Immutable) => Self::Static, hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn, hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None,