From 4d2bed946016b17e888d605b5e2a0849aa23f0b2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 22 Nov 2018 14:33:08 +0100 Subject: [PATCH 01/25] Stabilize `const_let` inside const functions --- src/librustc/mir/mod.rs | 2 + src/librustc_mir/transform/qualify_consts.rs | 52 +++---------------- .../transform/qualify_min_const_fn.rs | 19 ++----- .../ui/consts/const-fn-destructuring-arg.rs | 14 +---- .../consts/const-fn-destructuring-arg.stderr | 35 ------------- .../ui/consts/const-fn-not-safe-for-const.rs | 6 --- .../consts/const-fn-not-safe-for-const.stderr | 52 +------------------ .../min_const_fn/min_const_fn.nll.stderr | 8 +-- .../ui/consts/min_const_fn/min_const_fn.rs | 2 +- .../consts/min_const_fn/min_const_fn.stderr | 8 +-- .../feature-gates/feature-gate-const_let.rs | 12 ++--- .../feature-gate-const_let.stderr | 34 ++++++++++-- 12 files changed, 56 insertions(+), 188 deletions(-) delete mode 100644 src/test/ui/consts/const-fn-destructuring-arg.stderr diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 368f83eb61127..2607f5fd08b42 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1748,6 +1748,8 @@ pub enum StatementKind<'tcx> { /// (e.g. inspecting constants and discriminant values), and the /// kind of pattern it comes from. This is in order to adapt potential /// error messages to these specific patterns. + /// + /// Note that this also is emitted for regular `let` bindings to aid destructuring diagnostics FakeRead(FakeReadCause, Place<'tcx>), /// Write the discriminant for a variant to the enum Place. diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 09fe7b14c7973..61e79990f9225 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - if self.tcx.features().const_let { + if self.const_let_allowed() { let mut dest = dest; let index = loop { match dest { @@ -320,6 +320,10 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } + fn const_let_allowed(&self) -> bool { + self.tcx.features().const_let || self.mode == Mode::ConstFn + } + /// Qualify a whole const, static initializer or const fn. fn qualify_const(&mut self) -> (Qualif, Lrc>) { debug!("qualifying {} {:?}", self.mode, self.def_id); @@ -357,7 +361,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseUnwind { .. } => None, TerminatorKind::Return => { - if !self.tcx.features().const_let { + if !self.const_let_allowed() { // Check for unused values. This usually means // there are extra statements in the AST. for temp in mir.temps_iter() { @@ -464,7 +468,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Var if !self.tcx.features().const_let => { + LocalKind::Var if !self.const_let_allowed() => { if self.mode != Mode::Fn { emit_feature_err(&self.tcx.sess.parse_sess, "const_let", self.span, GateIssue::Language, @@ -1154,48 +1158,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location); self.visit_rvalue(rvalue, location); - // Check the allowed const fn argument forms. - if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { - if self.mir.local_kind(index) == LocalKind::Var && - self.const_fn_arg_vars.insert(index) && - !self.tcx.features().const_let { - - // Direct use of an argument is permitted. - match *rvalue { - Rvalue::Use(Operand::Copy(Place::Local(local))) | - Rvalue::Use(Operand::Move(Place::Local(local))) => { - if self.mir.local_kind(local) == LocalKind::Arg { - return; - } - } - _ => {} - } - - // Avoid a generic error for other uses of arguments. - if self.qualif.contains(Qualif::FN_ARGUMENT) { - let decl = &self.mir.local_decls[index]; - let mut err = feature_err( - &self.tcx.sess.parse_sess, - "const_let", - decl.source_info.span, - GateIssue::Language, - "arguments of constant functions can only be immutable by-value bindings" - ); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("Constant functions are not allowed to mutate anything. Thus, \ - binding to an argument with a mutable pattern is not allowed."); - err.note("Remove any mutable bindings from the argument list to fix this \ - error. In case you need to mutate the argument, try lazily \ - initializing a global variable instead of using a const fn, or \ - refactoring the code to a functional style to avoid mutation if \ - possible."); - } - err.emit(); - return; - } - } - } - self.assign(dest, location); } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 13e134ba85928..5729775e15dc0 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -64,12 +64,6 @@ pub fn is_min_const_fn( } } - for local in mir.vars_iter() { - return Err(( - mir.local_decls[local].source_info.span, - "local variables in const fn are unstable".into(), - )); - } for local in &mir.local_decls { check_ty(tcx, local.ty, local.source_info.span)?; } @@ -229,7 +223,7 @@ fn check_statement( check_rvalue(tcx, mir, rval, span) } - StatementKind::FakeRead(..) => Err((span, "match in const fn is unstable".into())), + StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span, PlaceMode::Read), // just an assignment StatementKind::SetDiscriminant { .. } => Ok(()), @@ -270,15 +264,8 @@ fn check_place( mode: PlaceMode, ) -> McfResult { match place { - Place::Local(l) => match mode { - PlaceMode::Assign => match mir.local_kind(*l) { - LocalKind::Temp | LocalKind::ReturnPointer => Ok(()), - LocalKind::Arg | LocalKind::Var => { - Err((span, "assignments in const fn are unstable".into())) - } - }, - PlaceMode::Read => Ok(()), - }, + // assignments to locals, arguments, temporaries or the return slot are fine + Place::Local(_) => Ok(()), // promoteds are always fine, they are essentially constants Place::Promoted(_) => Ok(()), Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())), diff --git a/src/test/ui/consts/const-fn-destructuring-arg.rs b/src/test/ui/consts/const-fn-destructuring-arg.rs index fce1688716d30..8aa6871fa7587 100644 --- a/src/test/ui/consts/const-fn-destructuring-arg.rs +++ b/src/test/ui/consts/const-fn-destructuring-arg.rs @@ -8,20 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// test that certain things are disallowed in constant functions +// compile-pass -#![feature(const_fn)] - -// no destructuring -const fn i(( - a, - //~^ ERROR arguments of constant functions can only be immutable by-value bindings - b - //~^ ERROR arguments of constant functions can only be immutable by-value bindings - ): (u32, u32)) -> u32 { +const fn i((a, b): (u32, u32)) -> u32 { a + b - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-destructuring-arg.stderr b/src/test/ui/consts/const-fn-destructuring-arg.stderr deleted file mode 100644 index 029d63a7720a8..0000000000000 --- a/src/test/ui/consts/const-fn-destructuring-arg.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:17:13 - | -LL | a, - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:19:13 - | -LL | b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:22:5 - | -LL | a + b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:22:9 - | -LL | a + b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.rs b/src/test/ui/consts/const-fn-not-safe-for-const.rs index 30a738a83a3b6..aee5539980c6e 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.rs +++ b/src/test/ui/consts/const-fn-not-safe-for-const.rs @@ -38,14 +38,8 @@ const fn get_Y_addr() -> &'static u32 { const fn get() -> u32 { let x = 22; - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR statements in constant functions are unstable let y = 44; - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR statements in constant functions are unstable x + y - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr index 613670acc9326..90a7314b7d1fd 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr +++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr @@ -16,55 +16,7 @@ error[E0013]: constant functions cannot refer to statics, use a constant instead LL | &Y | ^^ -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:40:13 - | -LL | let x = 22; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:40:13 - | -LL | let x = 22; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:43:13 - | -LL | let y = 44; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:43:13 - | -LL | let y = 44; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:46:5 - | -LL | x + y - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:46:9 - | -LL | x + y - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 9 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0013, E0015, E0658. +Some errors occurred: E0013, E0015. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index f43befb37c134..39adf088642be 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ -error: local variables in const fn are unstable - --> $DIR/min_const_fn.rs:109:34 - | -LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn are unstable - | ^ - error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:110:44 | @@ -221,7 +215,7 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 35 previous errors +error: aborting due to 34 previous errors Some errors occurred: E0493, E0515. For more information about an error, try `rustc --explain E0493`. 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 0dba3a7de5378..80db24006ec3f 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 @@ -106,7 +106,7 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize } const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn -const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn are unstable +const fn foo30_6() -> bool { let x = true; x } const fn foo36(a: bool, b: bool) -> bool { a && b } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo37(a: bool, b: bool) -> bool { a || b } 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 bcb9be6e5485e..530282cfea923 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 @@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ -error: local variables in const fn are unstable - --> $DIR/min_const_fn.rs:109:34 - | -LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn are unstable - | ^ - error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:110:44 | @@ -208,6 +202,6 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 35 previous errors +error: aborting due to 34 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs index 05d02e62bc871..aad251a205e9a 100644 --- a/src/test/ui/feature-gates/feature-gate-const_let.rs +++ b/src/test/ui/feature-gates/feature-gate-const_let.rs @@ -10,13 +10,13 @@ // Test use of const let without feature gate. -#![feature(const_fn)] - -const fn foo() -> usize { +const FOO: usize = { + //~^ ERROR statements in constants are unstable + //~| ERROR: let bindings in constants are unstable let x = 42; - //~^ ERROR statements in constant functions are unstable - //~| ERROR: let bindings in constant functions are unstable + //~^ ERROR statements in constants are unstable + //~| ERROR: let bindings in constants are unstable 42 -} +}; fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_let.stderr b/src/test/ui/feature-gates/feature-gate-const_let.stderr index 6a7f6255678ff..4fab6ec540ebc 100644 --- a/src/test/ui/feature-gates/feature-gate-const_let.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_let.stderr @@ -1,4 +1,4 @@ -error[E0658]: let bindings in constant functions are unstable (see issue #48821) +error[E0658]: let bindings in constants are unstable (see issue #48821) --> $DIR/feature-gate-const_let.rs:16:13 | LL | let x = 42; @@ -6,7 +6,7 @@ LL | let x = 42; | = help: add #![feature(const_let)] to the crate attributes to enable -error[E0658]: statements in constant functions are unstable (see issue #48821) +error[E0658]: statements in constants are unstable (see issue #48821) --> $DIR/feature-gate-const_let.rs:16:13 | LL | let x = 42; @@ -14,6 +14,34 @@ LL | let x = 42; | = help: add #![feature(const_let)] to the crate attributes to enable -error: aborting due to 2 previous errors +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:13:1 + | +LL | / const FOO: usize = { +LL | | //~^ ERROR statements in constants are unstable +LL | | //~| ERROR: let bindings in constants are unstable +LL | | let x = 42; +... | +LL | | 42 +LL | | }; + | |__^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:13:1 + | +LL | / const FOO: usize = { +LL | | //~^ ERROR statements in constants are unstable +LL | | //~| ERROR: let bindings in constants are unstable +LL | | let x = 42; +... | +LL | | 42 +LL | | }; + | |__^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. From dba5ba02f769f2ba0a9bf391e887161f618ec4cf Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 22 Nov 2018 15:44:25 +0100 Subject: [PATCH 02/25] Update a test's diagnostics --- src/test/ui/issues/issue-37550.rs | 8 +----- src/test/ui/issues/issue-37550.stderr | 37 ++++----------------------- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/src/test/ui/issues/issue-37550.rs b/src/test/ui/issues/issue-37550.rs index af1f6ef5ed4ac..f6861b459d70e 100644 --- a/src/test/ui/issues/issue-37550.rs +++ b/src/test/ui/issues/issue-37550.rs @@ -8,15 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] - const fn x() { let t = true; - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR statements in constant functions are unstable - let x = || t; - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR statements in constant functions are unstable + let x = || t; //~ ERROR function pointers in const fn are unstable } fn main() {} diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr index 7468510de6a33..5b530de33f653 100644 --- a/src/test/ui/issues/issue-37550.stderr +++ b/src/test/ui/issues/issue-37550.stderr @@ -1,35 +1,8 @@ -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/issue-37550.rs:14:13 +error: function pointers in const fn are unstable + --> $DIR/issue-37550.rs:13:9 | -LL | let t = true; - | ^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/issue-37550.rs:14:13 - | -LL | let t = true; - | ^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/issue-37550.rs:17:13 - | -LL | let x = || t; - | ^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/issue-37550.rs:17:13 - | -LL | let x = || t; - | ^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable +LL | let x = || t; //~ ERROR function pointers in const fn are unstable + | ^ -error: aborting due to 4 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. From df2123cff2b1e6e4c7dfc0560ccf0eec3ae67a65 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 22 Nov 2018 17:19:55 +0100 Subject: [PATCH 03/25] Update compile-fail test --- src/test/compile-fail/const-fn-error.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/compile-fail/const-fn-error.rs b/src/test/compile-fail/const-fn-error.rs index 17dc9f94fe19c..759f0e50eccdd 100644 --- a/src/test/compile-fail/const-fn-error.rs +++ b/src/test/compile-fail/const-fn-error.rs @@ -14,8 +14,6 @@ const X : usize = 2; const fn f(x: usize) -> usize { let mut sum = 0; - //~^ let bindings in constant functions are unstable - //~| statements in constant functions are unstable for i in 0..x { //~^ ERROR E0015 //~| ERROR E0019 From 52b67b1766014ea73bac605ca643b1ddd69f1bca Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 23 Nov 2018 15:08:06 +0100 Subject: [PATCH 04/25] Remove a bunch of now-unnecessary `const_let` feature gates --- src/libcore/lib.rs | 2 +- .../ctfe/const-fn-destructuring-arg.rs | 26 ------------------- src/test/run-pass/ctfe/issue-37550.rs | 2 +- src/test/ui/consts/const_let_assign2.rs | 3 --- src/test/ui/issues/issue-44056.rs | 16 ------------ 5 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 src/test/run-pass/ctfe/const-fn-destructuring-arg.rs delete mode 100644 src/test/ui/issues/issue-44056.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 726e891df0ccf..ae223941778e7 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -120,7 +120,7 @@ #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] -#![feature(const_let)] +#![cfg_attr(stage0, feature(const_let))] #![feature(const_int_rotate)] #![feature(const_int_wrapping)] #![feature(const_int_sign)] diff --git a/src/test/run-pass/ctfe/const-fn-destructuring-arg.rs b/src/test/run-pass/ctfe/const-fn-destructuring-arg.rs deleted file mode 100644 index 88f0d0714f9a1..0000000000000 --- a/src/test/run-pass/ctfe/const-fn-destructuring-arg.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// run-pass -#![allow(dead_code)] - -// test that certain things are disallowed in constant functions - -#![feature(const_fn, const_let)] - -// no destructuring -const fn i(( - a, - b - ): (u32, u32)) -> u32 { - a + b -} - -fn main() {} diff --git a/src/test/run-pass/ctfe/issue-37550.rs b/src/test/run-pass/ctfe/issue-37550.rs index 54e0e83efed3a..2d278d115d5b6 100644 --- a/src/test/run-pass/ctfe/issue-37550.rs +++ b/src/test/run-pass/ctfe/issue-37550.rs @@ -12,7 +12,7 @@ #![allow(dead_code)] #![allow(unused_variables)] -#![feature(const_fn, const_let)] +#![feature(const_fn)] const fn x() { let t = true; diff --git a/src/test/ui/consts/const_let_assign2.rs b/src/test/ui/consts/const_let_assign2.rs index 0de7396501adc..1c44237e49b7a 100644 --- a/src/test/ui/consts/const_let_assign2.rs +++ b/src/test/ui/consts/const_let_assign2.rs @@ -1,8 +1,5 @@ // compile-pass -#![feature(const_let)] -#![feature(const_fn)] - pub struct AA { pub data: [u8; 10], } diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs deleted file mode 100644 index b2f0e917749d5..0000000000000 --- a/src/test/ui/issues/issue-44056.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-pass -// only-x86_64 -// no-prefer-dynamic -// compile-flags: -Ctarget-feature=+avx -Clto - -fn main() {} From ef38afc83db66dce317a3820121fb0233a0f4923 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 23 Nov 2018 15:08:36 +0100 Subject: [PATCH 05/25] Add a test for various const let features --- src/test/ui/consts/const_let_eq.rs | 468 +++++++++++++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 src/test/ui/consts/const_let_eq.rs diff --git a/src/test/ui/consts/const_let_eq.rs b/src/test/ui/consts/const_let_eq.rs new file mode 100644 index 0000000000000..434aeaac5fd5b --- /dev/null +++ b/src/test/ui/consts/const_let_eq.rs @@ -0,0 +1,468 @@ +// run-pass + +struct Foo(T); +struct Bar { x: T } +struct W(u32); +struct A { a: u32 } + +const fn basics((a,): (u32,)) -> u32 { + // Deferred assignment: + let b: u32; + b = a + 1; + + // Immediate assignment: + let c: u32 = b + 1; + + // Mutables: + let mut d: u32 = c + 1; + d = d + 1; + // +4 so far. + + // No effect statements work: + ; ; + 1; + + // Array projection + let mut arr: [u32; 1] = [0]; + arr[0] = 1; + d = d + arr[0]; + // +5 + + // Field projection: + let mut foo: Foo = Foo(0); + let mut bar: Bar = Bar { x: 0 }; + foo.0 = 1; + bar.x = 1; + d = d + foo.0 + bar.x; + // +7 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0)]; + arr[0].0 = 1; + d = d + arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0 }]; + arr[0].x = 1; + d = d + arr[0].x; + // +9 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([0]); + (arr.0)[0] = 1; + d = d + (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [0] }; + arr.x[0] = 1; + d = d + arr.x[0]; + // +11 + + d +} + +const fn add_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a + 1; + d += 1; + // +2 so far. + + // Array projection + let mut arr: [u32; 1] = [0]; + arr[0] += 1; + d += arr[0]; + // +3 + + // Field projection: + let mut foo: Foo = Foo(0); + let mut bar: Bar = Bar { x: 0 }; + foo.0 += 1; + bar.x += 1; + d += foo.0 + bar.x; + // +5 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0)]; + arr[0].0 += 1; + d += arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0 }]; + arr[0].x += 1; + d += arr[0].x; + // +7 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([0]); + (arr.0)[0] += 1; + d += (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [0] }; + arr.x[0] += 1; + d += arr.x[0]; + // +9 + + d +} + +const fn mul_assign(A { a }: A) -> u32 { + // Mutables: + let mut d: u32 = a + 1; + d *= 2; + // 2^1 * (a + 1) + + // Array projection + let mut arr: [u32; 1] = [1]; + arr[0] *= 2; + d *= arr[0]; + // 2^2 * (a + 1) + + // Field projection: + let mut foo: Foo = Foo(1); + let mut bar: Bar = Bar { x: 1 }; + foo.0 *= 2; + bar.x *= 2; + d *= foo.0 + bar.x; + // 2^4 * (a + 1) + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1)]; + arr[0].0 *= 2; + d *= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 1 }]; + arr[0].x *= 2; + d *= arr[0].x; + // 2^6 * (a + 1) + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([1]); + (arr.0)[0] *= 2; + d *= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [1] }; + arr.x[0] *= 2; + d *= arr.x[0]; + // 2^8 * (a + 1) + + d +} + +const fn div_assign(a: [u32; 1]) -> u32 { + let a = a[0]; + // Mutables: + let mut d: u32 = 1024 * a; + d /= 2; + // 512 + + // Array projection + let mut arr: [u32; 1] = [4]; + arr[0] /= 2; + d /= arr[0]; + // 256 + + // Field projection: + let mut foo: Foo = Foo(4); + let mut bar: Bar = Bar { x: 4 }; + foo.0 /= 2; + bar.x /= 2; + d /= foo.0; + d /= bar.x; + // 64 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4)]; + arr[0].0 /= 2; + d /= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 4 }]; + arr[0].x /= 2; + d /= arr[0].x; + // 16 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([4]); + (arr.0)[0] /= 2; + d /= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [4] }; + arr.x[0] /= 2; + d /= arr.x[0]; + // 4 + + d +} + +const fn rem_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d %= 10; + d += 10; + + // Array projection + let mut arr: [u32; 1] = [3]; + arr[0] %= 2; + d %= 9 + arr[0]; + d += 10; + + // Field projection: + let mut foo: Foo = Foo(5); + let mut bar: Bar = Bar { x: 7 }; + foo.0 %= 2; + bar.x %= 2; + d %= 8 + foo.0 + bar.x; + d += 10; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4)]; + arr[0].0 %= 3; + d %= 9 + arr[0].0; + d += 10; + let mut arr: [Bar; 1] = [Bar { x: 7 }]; + arr[0].x %= 3; + d %= 9 + arr[0].x; + d += 10; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([6]); + (arr.0)[0] %= 5; + d %= 9 + (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [11] }; + arr.x[0] %= 5; + d %= 9 + arr.x[0]; + + d +} + +const fn sub_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d -= 1; + + // Array projection + let mut arr: [u32; 1] = [2]; + arr[0] -= 1; + d -= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(2); + let mut bar: Bar = Bar { x: 2 }; + foo.0 -= 1; + bar.x -= 1; + d -= foo.0 + bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2)]; + arr[0].0 -= 1; + d -= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 2 }]; + arr[0].x -= 1; + d -= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([2]); + (arr.0)[0] -= 1; + d -= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [2] }; + arr.x[0] -= 1; + d -= arr.x[0]; + + d +} + +const fn shl_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d <<= 1; // 10 + + // Array projection + let mut arr: [u32; 1] = [1]; + arr[0] <<= 1; + d <<= arr[0]; // 10 << 2 + + // Field projection: + let mut foo: Foo = Foo(1); + let mut bar: Bar = Bar { x: 1 }; + foo.0 <<= 1; + bar.x <<= 1; + d <<= foo.0 + bar.x; // 1000 << 4 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1)]; + arr[0].0 <<= 1; + d <<= arr[0].0; // 1000_0000 << 2 + let mut arr: [Bar; 1] = [Bar { x: 1 }]; + arr[0].x <<= 1; + d <<= arr[0].x; // 1000_0000_00 << 2 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([1]); + (arr.0)[0] <<= 1; + d <<= (arr.0)[0]; // 1000_0000_0000 << 2 + let mut arr: Bar<[u32; 1]> = Bar { x: [1] }; + arr.x[0] <<= 1; + d <<= arr.x[0]; // 1000_0000_0000_00 << 2 + + d +} + +const fn shr_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d >>= 1; // /= 2 + + // Array projection + let mut arr: [u32; 1] = [2]; + arr[0] >>= 1; + d >>= arr[0]; // /= 4 + + // Field projection: + let mut foo: Foo = Foo(2); + let mut bar: Bar = Bar { x: 2 }; + foo.0 >>= 1; + bar.x >>= 1; + d >>= foo.0 + bar.x; // /= 16 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2)]; + arr[0].0 >>= 1; + d >>= arr[0].0; // /= 32 + let mut arr: [Bar; 1] = [Bar { x: 2 }]; + arr[0].x >>= 1; + d >>= arr[0].x; // /= 64 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([2]); + (arr.0)[0] >>= 1; + d >>= (arr.0)[0]; // /= 128 + let mut arr: Bar<[u32; 1]> = Bar { x: [2] }; + arr.x[0] >>= 1; + d >>= arr.x[0]; // /= 256 + + d +} + +const fn bit_and_assign(W(a): W) -> u32 { + let f = 0b1111_1111_1111_1111; + + // Mutables: + let mut d: u32 = a; + d &= 0b1111_1111_1111_1110; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] &= 0b1111_1111_1111_1101; + d &= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 &= 0b1111_1111_1111_0111; + bar.x &= 0b1111_1111_1101_1111; + d &= foo.0 & bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 &= 0b1111_1110_1111_1111; + d &= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x &= 0b1111_1101_1111_1111; + d &= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] &= 0b1011_1111_1111_1111; + d &= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] &= 0b0111_1111_1111_1111; + d &= arr.x[0]; + + d +} + +const fn bit_or_assign(W(a): W) -> u32 { + let f = 0b0000_0000_0000_0000; + + // Mutables: + let mut d: u32 = a; + d |= 0b0000_0000_0000_0001; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] |= 0b0000_0000_0000_1001; + d |= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 |= 0b0000_0000_0001_0000; + bar.x |= 0b0000_0000_0100_0000; + d |= foo.0 | bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 |= 0b0000_0001_0000_0000; + d |= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x |= 0b0000_0010_0000_0000; + d |= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] |= 0b1000_0000_0000_0000; + d |= (arr.0)[0]; // /= 128 + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] |= 0b1100_0000_0000_0000; + d |= arr.x[0]; // /= 256 + + d +} + +const fn bit_xor_assign(W(a): W) -> u32 { + let f = 0b0000_0000_0000_0000; + + // Mutables: + let mut d: u32 = a; + d ^= 0b0000_0000_0000_0001; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] ^= 0b0000_0000_0000_0010; + d ^= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 ^= 0b0000_0000_0001_0000; + bar.x ^= 0b0000_0000_1000_0000; + d ^= foo.0 ^ bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 ^= 0b0000_0001_0000_0000; + d ^= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x ^= 0b0000_0010_0000_0000; + d ^= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] ^= 0b0100_0000_0000_0000; + d ^= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] ^= 0b1000_0000_0000_0000; + d ^= arr.x[0]; + + d +} + +macro_rules! test { + ($c:ident, $e:expr, $r:expr) => { + const $c: u32 = $e; + assert_eq!($c, $r); + assert_eq!($e, $r); + } +} + +fn main() { + test!(BASICS, basics((2,)), 13); + test!(ADD, add_assign(W(1)), 10); + test!(MUL, mul_assign(A { a: 0 }), 256); + test!(DIV, div_assign([1]), 4); + test!(REM, rem_assign(W(5)), 5); + test!(SUB, sub_assign(W(8)), 0); + test!(SHL, shl_assign(W(1)), 0b1000_0000_0000_0000); + test!(SHR, shr_assign(W(256)), 1); + test!(AND, bit_and_assign(W(0b1011_1111_1111_1111_1111)), 0b0011_1100_1101_0100); + test!(OR, bit_or_assign(W(0b1011_0000_0000_0000)), 0b1111_0011_0101_1001); + test!(XOR, bit_xor_assign(W(0b0000_0000_0000_0000)), 0b1100_0011_1001_0011); +} \ No newline at end of file From 59c6c4942ab0f8ebfdfa0be7e2cc9f9a811d7585 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 23 Nov 2018 15:17:26 +0100 Subject: [PATCH 06/25] Also test the `const_let` feature gate in statics --- .../feature-gates/feature-gate-const_let.rs | 9 ++++ .../feature-gate-const_let.stderr | 46 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs index aad251a205e9a..9bf957a5f1e05 100644 --- a/src/test/ui/feature-gates/feature-gate-const_let.rs +++ b/src/test/ui/feature-gates/feature-gate-const_let.rs @@ -19,4 +19,13 @@ const FOO: usize = { 42 }; +static BAR: usize = { + //~^ ERROR statements in statics are unstable + //~| ERROR: let bindings in statics are unstable + let x = 42; + //~^ ERROR statements in statics are unstable + //~| ERROR: let bindings in statics are unstable + 42 +}; + fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_let.stderr b/src/test/ui/feature-gates/feature-gate-const_let.stderr index 4fab6ec540ebc..acb5165918e2a 100644 --- a/src/test/ui/feature-gates/feature-gate-const_let.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_let.stderr @@ -42,6 +42,50 @@ LL | | }; | = help: add #![feature(const_let)] to the crate attributes to enable -error: aborting due to 4 previous errors +error[E0658]: let bindings in statics are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:25:13 + | +LL | let x = 42; + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:25:13 + | +LL | let x = 42; + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in statics are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:22:1 + | +LL | / static BAR: usize = { +LL | | //~^ ERROR statements in statics are unstable +LL | | //~| ERROR: let bindings in statics are unstable +LL | | let x = 42; +... | +LL | | 42 +LL | | }; + | |__^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/feature-gate-const_let.rs:22:1 + | +LL | / static BAR: usize = { +LL | | //~^ ERROR statements in statics are unstable +LL | | //~| ERROR: let bindings in statics are unstable +LL | | let x = 42; +... | +LL | | 42 +LL | | }; + | |__^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0658`. From 7ec3c10d7e1bfac9e93b0138d2a9703d1f722dff Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 23 Nov 2018 15:30:10 +0100 Subject: [PATCH 07/25] Add tests for mutable borrows --- src/test/ui/consts/const_let_eq.rs | 2 +- .../ui/consts/min_const_fn/mutable_borrow.rs | 17 +++++++++++++++++ .../consts/min_const_fn/mutable_borrow.stderr | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/min_const_fn/mutable_borrow.rs create mode 100644 src/test/ui/consts/min_const_fn/mutable_borrow.stderr diff --git a/src/test/ui/consts/const_let_eq.rs b/src/test/ui/consts/const_let_eq.rs index 434aeaac5fd5b..a2364c392f26b 100644 --- a/src/test/ui/consts/const_let_eq.rs +++ b/src/test/ui/consts/const_let_eq.rs @@ -465,4 +465,4 @@ fn main() { test!(AND, bit_and_assign(W(0b1011_1111_1111_1111_1111)), 0b0011_1100_1101_0100); test!(OR, bit_or_assign(W(0b1011_0000_0000_0000)), 0b1111_0011_0101_1001); test!(XOR, bit_xor_assign(W(0b0000_0000_0000_0000)), 0b1100_0011_1001_0011); -} \ No newline at end of file +} diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.rs b/src/test/ui/consts/min_const_fn/mutable_borrow.rs new file mode 100644 index 0000000000000..85f9a154c8491 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.rs @@ -0,0 +1,17 @@ +const fn mutable_ref_in_const() -> u8 { + let mut a = 0; + let b = &mut a; //~ ERROR mutable references in const fn are unstable + *b +} + +struct X; + +impl X { + const fn inherent_mutable_ref_in_const() -> u8 { + let mut a = 0; + let b = &mut a; //~ ERROR mutable references in const fn are unstable + *b + } +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr new file mode 100644 index 0000000000000..7414fa94bfbca --- /dev/null +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -0,0 +1,14 @@ +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:3:9 + | +LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable + | ^ + +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:12:13 + | +LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable + | ^ + +error: aborting due to 2 previous errors + From d62bcad38da1b65ecd8a3544c3ff94855b88366a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 24 Nov 2018 14:38:31 +0100 Subject: [PATCH 08/25] Allow `let` bindings everywhere --- src/librustc/mir/mod.rs | 10 + src/librustc_mir/build/mod.rs | 20 +- src/librustc_mir/hair/cx/expr.rs | 2 + src/librustc_mir/hair/cx/mod.rs | 7 + src/librustc_mir/shim.rs | 12 +- src/librustc_mir/transform/promote_consts.rs | 3 +- src/librustc_mir/transform/qualify_consts.rs | 205 +++++------------- src/libsyntax/feature_gate.rs | 3 - .../ctfe/const-block-non-item-statement-3.rs | 2 - .../ctfe/const-block-non-item-statement.rs | 2 - src/test/run-pass/ctfe/locals-in-const-fn.rs | 2 +- ...check-static-values-constraints.nll.stderr | 62 +++++- .../ui/check-static-values-constraints.rs | 7 + .../ui/check-static-values-constraints.stderr | 62 +++++- .../const-block-non-item-statement-2.rs | 10 +- .../const-block-non-item-statement-2.stderr | 62 ------ .../const-block-non-item-statement-3.rs | 6 +- .../const-block-non-item-statement-3.stderr | 35 --- .../consts/const-block-non-item-statement.rs | 6 +- .../const-block-non-item-statement.stderr | 35 --- .../assign-to-static-within-other-static-2.rs | 3 +- ...ign-to-static-within-other-static-2.stderr | 10 +- .../assign-to-static-within-other-static.rs | 1 - ...ssign-to-static-within-other-static.stderr | 2 +- src/test/ui/consts/const-eval/const_let.rs | 2 - .../ui/consts/const-eval/const_let.stderr | 4 +- .../ui/consts/const-eval/infinite_loop.rs | 2 - .../ui/consts/const-eval/infinite_loop.stderr | 6 +- src/test/ui/consts/const-eval/issue-52475.rs | 2 - .../ui/consts/const-eval/issue-52475.stderr | 6 +- .../const-eval/mod-static-with-const-fn.rs | 5 +- .../mod-static-with-const-fn.stderr | 13 +- .../promoted_raw_ptr_ops.nll.stderr | 13 +- src/test/ui/consts/const-eval/ub-upvars.rs | 2 +- src/test/ui/consts/const_let_assign.rs | 2 - src/test/ui/consts/const_let_assign3.rs | 2 +- src/test/ui/consts/const_let_assign3.stderr | 11 +- src/test/ui/consts/dangling-alloc-id-ice.rs | 2 - .../ui/consts/dangling-alloc-id-ice.stderr | 2 +- src/test/ui/consts/dangling_raw_ptr.rs | 2 - src/test/ui/consts/dangling_raw_ptr.stderr | 2 +- src/test/ui/consts/issue-54224.rs | 5 +- src/test/ui/consts/issue-54224.stderr | 23 -- .../min_const_fn/mutable_borrow.nll.stderr | 51 +++++ .../ui/consts/min_const_fn/mutable_borrow.rs | 26 +++ .../consts/min_const_fn/mutable_borrow.stderr | 39 +++- src/test/ui/consts/partial_qualif.rs | 2 - src/test/ui/consts/partial_qualif.stderr | 2 +- src/test/ui/consts/projection_qualif.rs | 3 +- src/test/ui/consts/projection_qualif.stderr | 14 +- .../ui/consts/promote_const_let.nll.stderr | 2 +- src/test/ui/consts/promote_const_let.rs | 2 - src/test/ui/consts/promote_const_let.stderr | 2 +- src/test/ui/consts/qualif_overwrite.rs | 2 - src/test/ui/consts/qualif_overwrite.stderr | 2 +- src/test/ui/consts/qualif_overwrite_2.rs | 2 - src/test/ui/consts/qualif_overwrite_2.stderr | 2 +- src/test/ui/error-codes/E0010-teach.rs | 1 + src/test/ui/error-codes/E0010-teach.stderr | 14 +- src/test/ui/error-codes/E0010.rs | 1 + src/test/ui/error-codes/E0010.stderr | 11 +- .../ui/feature-gate-underscore_const_names.rs | 1 - ...feature-gate-underscore_const_names.stderr | 2 +- .../feature-gates/feature-gate-const_let.rs | 31 --- src/test/ui/issues/issue-18118.nll.stderr | 60 +---- src/test/ui/issues/issue-18118.rs | 5 - src/test/ui/issues/issue-18118.stderr | 60 +---- src/test/ui/issues/issue-32829-2.rs | 13 +- src/test/ui/issues/issue-32829-2.stderr | 83 +------ src/test/ui/issues/issue-7364.rs | 1 + src/test/ui/issues/issue-7364.stderr | 10 +- src/test/ui/static/static-mut-not-constant.rs | 1 + .../ui/static/static-mut-not-constant.stderr | 11 +- src/test/ui/underscore_const_names.rs | 1 - src/test/ui/write-to-static-mut-in-static.rs | 2 - .../ui/write-to-static-mut-in-static.stderr | 4 +- 76 files changed, 446 insertions(+), 692 deletions(-) delete mode 100644 src/test/ui/consts/const-block-non-item-statement-2.stderr delete mode 100644 src/test/ui/consts/const-block-non-item-statement-3.stderr delete mode 100644 src/test/ui/consts/const-block-non-item-statement.stderr delete mode 100644 src/test/ui/consts/issue-54224.stderr create mode 100644 src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-const_let.rs diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 2607f5fd08b42..a82a7b555a05e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -149,6 +149,12 @@ pub struct Mir<'tcx> { /// This is used for the "rust-call" ABI. pub spread_arg: Option, + /// Mark this MIR of a const context other than const functions as having converted a `&&` or + /// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop + /// this conversion from happening and use short circuiting, we will cause the following code + /// to change the value of `x`: `let mut x = 42; false && { x = 55; true };` + pub const_can_have_let_mut_bindings: bool, + /// A span representing this MIR, for error reporting pub span: Span, @@ -167,6 +173,7 @@ impl<'tcx> Mir<'tcx> { arg_count: usize, upvar_decls: Vec, span: Span, + const_can_have_let_mut_bindings: bool, ) -> Self { // We need `arg_count` locals, and one for the return place assert!( @@ -191,6 +198,7 @@ impl<'tcx> Mir<'tcx> { spread_arg: None, span, cache: cache::Cache::new(), + const_can_have_let_mut_bindings, } } @@ -421,6 +429,7 @@ impl_stable_hash_for!(struct Mir<'tcx> { arg_count, upvar_decls, spread_arg, + const_can_have_let_mut_bindings, span, cache }); @@ -2974,6 +2983,7 @@ BraceStructTypeFoldableImpl! { arg_count, upvar_decls, spread_arg, + const_can_have_let_mut_bindings, span, cache, } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d95a74be77696..ab19cd9dd5bed 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -854,15 +854,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } } - Mir::new(self.cfg.basic_blocks, - self.source_scopes, - ClearCrossCrate::Set(self.source_scope_local_data), - IndexVec::new(), - yield_ty, - self.local_decls, - self.arg_count, - self.upvar_decls, - self.fn_span + Mir::new( + self.cfg.basic_blocks, + self.source_scopes, + ClearCrossCrate::Set(self.source_scope_local_data), + IndexVec::new(), + yield_ty, + self.local_decls, + self.arg_count, + self.upvar_decls, + self.fn_span, + self.hir.const_can_have_let_mut_bindings(), ) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 2e9edf20c5708..951651aa1ce1c 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -372,6 +372,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // FIXME(eddyb) use logical ops in constants when // they can handle that kind of control-flow. (hir::BinOpKind::And, hir::Constness::Const) => { + cx.const_can_have_let_mut_bindings = false; ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), @@ -379,6 +380,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } (hir::BinOpKind::Or, hir::Constness::Const) => { + cx.const_can_have_let_mut_bindings = false; ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index c414088b65322..8ee1eac0e331a 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -56,6 +56,9 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { /// True if this constant/function needs overflow checks. check_overflow: bool, + + /// See field with the same name on `Mir` + const_can_have_let_mut_bindings: bool, } impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { @@ -96,9 +99,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { constness, body_owner_kind, check_overflow, + const_can_have_let_mut_bindings: true, } } + pub fn const_can_have_let_mut_bindings(&self) -> bool { + self.const_can_have_let_mut_bindings + } } impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 93bf1b3e36e38..5a08165608d53 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -219,7 +219,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, local_decls_for_sig(&sig, span), sig.inputs().len(), vec![], - span + span, + true, ); if let Some(..) = ty { @@ -387,7 +388,8 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { self.local_decls, self.sig.inputs().len(), vec![], - self.span + self.span, + true, ) } @@ -835,7 +837,8 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, local_decls, sig.inputs().len(), vec![], - span + span, + true, ); if let Abi::RustCall = sig.abi { mir.spread_arg = Some(Local::new(sig.inputs().len())); @@ -912,6 +915,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, local_decls, sig.inputs().len(), vec![], - span + span, + true, ) } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index c5add6260789a..3a0094bcd625a 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -412,7 +412,8 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, initial_locals, 0, vec![], - mir.span + mir.span, + false, ), tcx, source: mir, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 61e79990f9225..8eae45376642b 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -30,7 +30,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUs use rustc::middle::lang_items; use rustc_target::spec::abi::Abi; use syntax::ast::LitKind; -use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue}; +use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue}; use syntax_pos::{Span, DUMMY_SP}; use std::fmt; @@ -114,7 +114,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { param_env: ty::ParamEnv<'tcx>, local_qualif: IndexVec>, qualif: Qualif, - const_fn_arg_vars: BitSet, temp_promotion_state: IndexVec, promotion_candidates: Vec } @@ -149,7 +148,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { param_env, local_qualif, qualif: Qualif::empty(), - const_fn_arg_vars: BitSet::new_empty(mir.local_decls.len()), temp_promotion_state: temps, promotion_candidates: vec![] } @@ -178,26 +176,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } - /// Error about extra statements in a constant. - fn statement_like(&mut self) { - self.add(Qualif::NOT_CONST); - if self.mode != Mode::Fn { - let mut err = feature_err( - &self.tcx.sess.parse_sess, - "const_let", - self.span, - GateIssue::Language, - &format!("statements in {}s are unstable", self.mode), - ); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("Blocks in constants may only contain items (such as constant, function \ - definition, etc...) and a tail expression."); - err.help("To avoid it, you have to replace the non-item object."); - } - err.emit(); - } - } - /// Add the given qualification to self.qualif. fn add(&mut self, qualif: Qualif) { self.qualif = self.qualif | qualif; @@ -243,87 +221,48 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - if self.const_let_allowed() { - let mut dest = dest; - let index = loop { - match dest { - // with `const_let` active, we treat all locals equal - Place::Local(index) => break *index, - // projections are transparent for assignments - // we qualify the entire destination at once, even if just a field would have - // stricter qualification - Place::Projection(proj) => { - // Catch more errors in the destination. `visit_place` also checks various - // projection rules like union field access and raw pointer deref - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - dest = &proj.base; - }, - Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), - Place::Static(..) => { - // Catch more errors in the destination. `visit_place` also checks that we - // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - return; - } + let mut dest = dest; + let index = loop { + match dest { + Place::Local(index) => break *index, + // projections are transparent for assignments + // we qualify the entire destination at once, even if just a field would have + // stricter qualification + Place::Projection(proj) => { + // Catch more errors in the destination. `visit_place` also checks various + // projection rules like union field access and raw pointer deref + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + dest = &proj.base; + }, + Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), + Place::Static(..) => { + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; } - }; - debug!("store to var {:?}", index); - match &mut self.local_qualif[index] { - // this is overly restrictive, because even full assignments do not clear the qualif - // While we could special case full assignments, this would be inconsistent with - // aggregates where we overwrite all fields via assignments, which would not get - // that feature. - Some(ref mut qualif) => *qualif = *qualif | self.qualif, - // insert new qualification - qualif @ None => *qualif = Some(self.qualif), - } - return; - } - - match *dest { - Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp || - self.mir.local_kind(index) == LocalKind::ReturnPointer => { - debug!("store to {:?} (temp or return pointer)", index); - store(&mut self.local_qualif[index]) - } - - Place::Projection(box Projection { - base: Place::Local(index), - elem: ProjectionElem::Deref - }) if self.mir.local_kind(index) == LocalKind::Temp - && self.mir.local_decls[index].ty.is_box() - && self.local_qualif[index].map_or(false, |qualif| { - qualif.contains(Qualif::NOT_CONST) - }) => { - // Part of `box expr`, we should've errored - // already for the Box allocation Rvalue. - } - - // This must be an explicit assignment. - _ => { - // Catch more errors in the destination. - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - self.statement_like(); } + }; + debug!("store to var {:?}", index); + match &mut self.local_qualif[index] { + // this is overly restrictive, because even full assignments do not clear the qualif + // While we could special case full assignments, this would be inconsistent with + // aggregates where we overwrite all fields via assignments, which would not get + // that feature. + Some(ref mut qualif) => *qualif = *qualif | self.qualif, + // insert new qualification + qualif @ None => *qualif = Some(self.qualif), } } - fn const_let_allowed(&self) -> bool { - self.tcx.features().const_let || self.mode == Mode::ConstFn - } - /// Qualify a whole const, static initializer or const fn. fn qualify_const(&mut self) -> (Qualif, Lrc>) { debug!("qualifying {} {:?}", self.mode, self.def_id); @@ -360,48 +299,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseEdges { .. } | TerminatorKind::FalseUnwind { .. } => None, - TerminatorKind::Return => { - if !self.const_let_allowed() { - // Check for unused values. This usually means - // there are extra statements in the AST. - for temp in mir.temps_iter() { - if self.local_qualif[temp].is_none() { - continue; - } - - let state = self.temp_promotion_state[temp]; - if let TempState::Defined { location, uses: 0 } = state { - let data = &mir[location.block]; - let stmt_idx = location.statement_index; - - // Get the span for the initialization. - let source_info = if stmt_idx < data.statements.len() { - data.statements[stmt_idx].source_info - } else { - data.terminator().source_info - }; - self.span = source_info.span; - - // Treat this as a statement in the AST. - self.statement_like(); - } - } - - // Make sure there are no extra unassigned variables. - self.qualif = Qualif::NOT_CONST; - for index in mir.vars_iter() { - if !self.const_fn_arg_vars.contains(index) { - debug!("unassigned variable {:?}", index); - self.assign(&Place::Local(index), Location { - block: bb, - statement_index: usize::MAX, - }); - } - } - } - - break; - } + TerminatorKind::Return => break, }; match target { @@ -468,14 +366,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Var if !self.const_let_allowed() => { - if self.mode != Mode::Fn { - emit_feature_err(&self.tcx.sess.parse_sess, "const_let", - self.span, GateIssue::Language, - &format!("let bindings in {}s are unstable",self.mode)); - } - self.add(Qualif::NOT_CONST); - } LocalKind::Var | LocalKind::Arg | LocalKind::Temp => { @@ -556,7 +446,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.super_place(place, context, location); match proj.elem { ProjectionElem::Deref => { - this.add(Qualif::NOT_CONST); + if context.is_mutating_use() { + this.not_const() + } let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); match this.mode { Mode::Fn => {}, @@ -1291,6 +1183,19 @@ impl MirPass for QualifyAndPromoteConstants { // Do the actual promotion, now that we know what's viable. promote_consts::promote_candidates(mir, tcx, temps, candidates); } else { + if !mir.const_can_have_let_mut_bindings { + for local in mir.mut_vars_iter() { + let span = mir.local_decls[local].source_info.span; + tcx.sess.span_err( + span, + &format!( + "Cannot have both mutable bindings and \ + short circuiting operators in {}", + mode, + ), + ); + } + } let promoted_temps = if mode == Mode::Const { // Already computed by `mir_const_qualif`. const_promoted_temps.unwrap() diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3bc349170514c..586659ecd9ca2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -209,9 +209,6 @@ declare_features! ( // Allows the definition of `const fn` functions with some advanced features. (active, const_fn, "1.2.0", Some(24111), None), - // Allows let bindings and destructuring in `const fn` functions and constants. - (active, const_let, "1.22.1", Some(48821), None), - // Allows accessing fields of unions inside const fn. (active, const_fn_union, "1.27.0", Some(51909), None), diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs index 0fcf9a5acbdb1..997476853ec4e 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs @@ -11,8 +11,6 @@ // run-pass #![allow(dead_code)] -#![feature(const_let)] - type Array = [u32; { let x = 2; 5 }]; pub fn main() {} diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement.rs b/src/test/run-pass/ctfe/const-block-non-item-statement.rs index b7ed8af35d4c1..0943818e2b7dc 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement.rs @@ -11,8 +11,6 @@ // run-pass #![allow(dead_code)] -#![feature(const_let)] - enum Foo { Bar = { let x = 1; 3 } } diff --git a/src/test/run-pass/ctfe/locals-in-const-fn.rs b/src/test/run-pass/ctfe/locals-in-const-fn.rs index d10465b9dcd26..c4413dba69fb2 100644 --- a/src/test/run-pass/ctfe/locals-in-const-fn.rs +++ b/src/test/run-pass/ctfe/locals-in-const-fn.rs @@ -12,7 +12,7 @@ // https://github.com/rust-lang/rust/issues/48821 -#![feature(const_fn, const_let)] +#![feature(const_fn)] const fn foo(i: usize) -> usize { let x = i; diff --git a/src/test/ui/check-static-values-constraints.nll.stderr b/src/test/ui/check-static-values-constraints.nll.stderr index 5522e22fb1fa2..ac549cd8d1a48 100644 --- a/src/test/ui/check-static-values-constraints.nll.stderr +++ b/src/test/ui/check-static-values-constraints.nll.stderr @@ -13,44 +13,80 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:89:37 + | +LL | static STATIC11: Box = box MyOwned; + | ^^^^^^^ + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:99:32 + --> $DIR/check-static-values-constraints.rs:100:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:104:5 + --> $DIR/check-static-values-constraints.rs:105:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:105:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:105:5 + --> $DIR/check-static-values-constraints.rs:107:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:107:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:109:6 + --> $DIR/check-static-values-constraints.rs:112:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:112:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:110:6 + --> $DIR/check-static-values-constraints.rs:114:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:114:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:116:5 + --> $DIR/check-static-values-constraints.rs:121:5 | LL | box 3; | ^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:121:9 + | +LL | box 3; + | ^ + error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:120:45 + --> $DIR/check-static-values-constraints.rs:126:45 | LL | let y = { static x: Box = box 3; x }; | ^ @@ -59,12 +95,18 @@ LL | let y = { static x: Box = box 3; x }; | help: consider borrowing here: `&x` error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:120:38 + --> $DIR/check-static-values-constraints.rs:126:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error: aborting due to 10 previous errors +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:126:42 + | +LL | let y = { static x: Box = box 3; x }; + | ^ + +error: aborting due to 17 previous errors -Some errors occurred: E0010, E0015, E0493, E0507. +Some errors occurred: E0010, E0015, E0019, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/check-static-values-constraints.rs b/src/test/ui/check-static-values-constraints.rs index 37f665960c8c8..1822af333231e 100644 --- a/src/test/ui/check-static-values-constraints.rs +++ b/src/test/ui/check-static-values-constraints.rs @@ -88,6 +88,7 @@ struct MyOwned; static STATIC11: Box = box MyOwned; //~^ ERROR allocations are not allowed in statics +//~| ERROR contains unimplemented expression type static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -102,12 +103,16 @@ static mut STATIC14: SafeStruct = SafeStruct { static STATIC15: &'static [Box] = &[ box MyOwned, //~ ERROR allocations are not allowed in statics + //~^ ERROR contains unimplemented expression type box MyOwned, //~ ERROR allocations are not allowed in statics + //~^ ERROR contains unimplemented expression type ]; static STATIC16: (&'static Box, &'static Box) = ( &box MyOwned, //~ ERROR allocations are not allowed in statics + //~^ ERROR contains unimplemented expression type &box MyOwned, //~ ERROR allocations are not allowed in statics + //~^ ERROR contains unimplemented expression type ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; @@ -115,9 +120,11 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Box = box 3; //~^ ERROR allocations are not allowed in statics +//~| ERROR contains unimplemented expression type pub fn main() { let y = { static x: Box = box 3; x }; //~^ ERROR allocations are not allowed in statics //~^^ ERROR cannot move out of static item + //~| ERROR contains unimplemented expression type } diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr index ac979a3fa7cfc..40f8555f6afa7 100644 --- a/src/test/ui/check-static-values-constraints.stderr +++ b/src/test/ui/check-static-values-constraints.stderr @@ -13,55 +13,97 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:89:37 + | +LL | static STATIC11: Box = box MyOwned; + | ^^^^^^^ + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:99:32 + --> $DIR/check-static-values-constraints.rs:100:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:104:5 + --> $DIR/check-static-values-constraints.rs:105:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:105:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:105:5 + --> $DIR/check-static-values-constraints.rs:107:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:107:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:109:6 + --> $DIR/check-static-values-constraints.rs:112:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:112:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:110:6 + --> $DIR/check-static-values-constraints.rs:114:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:114:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:116:5 + --> $DIR/check-static-values-constraints.rs:121:5 | LL | box 3; | ^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:121:9 + | +LL | box 3; + | ^ + error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:120:45 + --> $DIR/check-static-values-constraints.rs:126:45 | LL | let y = { static x: Box = box 3; x }; | ^ cannot move out of static item error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:120:38 + --> $DIR/check-static-values-constraints.rs:126:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error: aborting due to 10 previous errors +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:126:42 + | +LL | let y = { static x: Box = box 3; x }; + | ^ + +error: aborting due to 17 previous errors -Some errors occurred: E0010, E0015, E0493, E0507. +Some errors occurred: E0010, E0015, E0019, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/consts/const-block-non-item-statement-2.rs b/src/test/ui/consts/const-block-non-item-statement-2.rs index f80d55cb34267..0e96f96e3d14e 100644 --- a/src/test/ui/consts/const-block-non-item-statement-2.rs +++ b/src/test/ui/consts/const-block-non-item-statement-2.rs @@ -8,21 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-pass + const A: usize = { 1; 2 }; -//~^ ERROR statements in constants are unstable const B: usize = { { } 2 }; -//~^ ERROR statements in constants are unstable macro_rules! foo { - () => (()) //~ ERROR statements in constants are unstable + () => (()) } const C: usize = { foo!(); 2 }; const D: usize = { let x = 4; 2 }; -//~^ ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable -//~| ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-2.stderr b/src/test/ui/consts/const-block-non-item-statement-2.stderr deleted file mode 100644 index 580f7e039d1c3..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-2.stderr +++ /dev/null @@ -1,62 +0,0 @@ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:11:20 - | -LL | const A: usize = { 1; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:14:20 - | -LL | const B: usize = { { } 2 }; - | ^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:18:12 - | -LL | () => (()) //~ ERROR statements in constants are unstable - | ^^ -LL | } -LL | const C: usize = { foo!(); 2 }; - | ------- in this macro invocation - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:22:28 - | -LL | const D: usize = { let x = 4; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:22:28 - | -LL | const D: usize = { let x = 4; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:22:1 - | -LL | const D: usize = { let x = 4; 2 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:22:1 - | -LL | const D: usize = { let x = 4; 2 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 7 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs index cfa4b778dde80..496e5486e9b99 100644 --- a/src/test/ui/consts/const-block-non-item-statement-3.rs +++ b/src/test/ui/consts/const-block-non-item-statement-3.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-pass + type Array = [u32; { let x = 2; 5 }]; -//~^ ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable -//~| ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-3.stderr b/src/test/ui/consts/const-block-non-item-statement-3.stderr deleted file mode 100644 index 0124288d43d57..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-3.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:11:31 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:11:31 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:11:20 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:11:20 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement.rs index f974a24c26f72..281a07808e927 100644 --- a/src/test/ui/consts/const-block-non-item-statement.rs +++ b/src/test/ui/consts/const-block-non-item-statement.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-pass + enum Foo { Bar = { let x = 1; 3 } - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable - //~| ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable } pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement.stderr b/src/test/ui/consts/const-block-non-item-statement.stderr deleted file mode 100644 index b367a9d99374e..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:12:21 - | -LL | Bar = { let x = 1; 3 } - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:12:21 - | -LL | Bar = { let x = 1; 3 } - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:12:11 - | -LL | Bar = { let x = 1; 3 } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:12:11 - | -LL | Bar = { let x = 1; 3 } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs index ef0de61d219ad..ad0dfabebedea 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs @@ -12,7 +12,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; @@ -24,7 +23,7 @@ unsafe impl Sync for Foo {} static FOO: Foo = Foo(UnsafeCell::new(42)); static BAR: () = unsafe { - *FOO.0.get() = 5; //~ ERROR could not evaluate static initializer + *FOO.0.get() = 5; //~ ERROR static contains unimplemented expression type }; fn main() {} diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr index 0892b05a69df2..740c1ab0b2d69 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr @@ -1,9 +1,9 @@ -error[E0080]: could not evaluate static initializer - --> $DIR/assign-to-static-within-other-static-2.rs:27:5 +error[E0019]: static contains unimplemented expression type + --> $DIR/assign-to-static-within-other-static-2.rs:26:5 | -LL | *FOO.0.get() = 5; //~ ERROR could not evaluate static initializer - | ^^^^^^^^^^^^^^^^ tried to modify a static's initial value from another static's initializer +LL | *FOO.0.get() = 5; //~ ERROR static contains unimplemented expression type + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs index 6f16f644eec68..2f786fb16cc80 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs @@ -12,7 +12,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr index ca652c9df32ad..031a87701266f 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr @@ -1,5 +1,5 @@ error: cannot mutate statics in the initializer of another static - --> $DIR/assign-to-static-within-other-static.rs:21:5 + --> $DIR/assign-to-static-within-other-static.rs:20:5 | LL | FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static | ^^^^^^^ diff --git a/src/test/ui/consts/const-eval/const_let.rs b/src/test/ui/consts/const-eval/const_let.rs index 602d4da24f383..3b5014a57b590 100644 --- a/src/test/ui/consts/const-eval/const_let.rs +++ b/src/test/ui/consts/const-eval/const_let.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_let)] - fn main() {} struct FakeNeedsDrop; diff --git a/src/test/ui/consts/const-eval/const_let.stderr b/src/test/ui/consts/const-eval/const_let.stderr index 86e3482fda6b9..f0c17bca36a7c 100644 --- a/src/test/ui/consts/const-eval/const_let.stderr +++ b/src/test/ui/consts/const-eval/const_let.stderr @@ -1,11 +1,11 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:25:55 + --> $DIR/const_let.rs:23:55 | LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:29:35 + --> $DIR/const_let.rs:27:35 | LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; | ^ diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index d23b6250b4df2..4aad5216442ce 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_let)] - fn main() { // Tests the Collatz conjecture with an incorrect base case (0 instead of 1). // The value of `n` will loop indefinitely (4 - 2 - 1 - 4). diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 2ff80e5efb57d..04a3362d95e78 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/infinite_loop.rs:19:9 + --> $DIR/infinite_loop.rs:17:9 | LL | / while n != 0 { //~ ERROR constant contains unimplemented expression type LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/infinite_loop.rs:16:18 + --> $DIR/infinite_loop.rs:14:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:20:20 + --> $DIR/infinite_loop.rs:18:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index b21c1827e2ba2..970d1a056f330 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_let)] - fn main() { let _ = [(); { //~^ WARNING Constant evaluating a complex constant, this might take some time diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index c0cd98b2fca1e..128979a67a912 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52475.rs:18:9 + --> $DIR/issue-52475.rs:16:9 | LL | / while n < 5 { //~ ERROR constant contains unimplemented expression type LL | | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/issue-52475.rs:14:18 + --> $DIR/issue-52475.rs:12:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:19:17 + --> $DIR/issue-52475.rs:17:17 | LL | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs index 01fcc8307c0c1..8132d26d63b14 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs @@ -12,7 +12,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; @@ -27,9 +26,7 @@ fn foo() {} static BAR: () = unsafe { *FOO.0.get() = 5; - // we do not error on the above access, because that is not detectable statically. Instead, - // const evaluation will error when trying to evaluate it. Due to the error below, we never even - // attempt to const evaluate `BAR`, so we don't see the error + //~^ ERROR static contains unimplemented expression foo(); //~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr index 01ad1fc9a21b9..eb5e88ad6931d 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr @@ -1,9 +1,16 @@ +error[E0019]: static contains unimplemented expression type + --> $DIR/mod-static-with-const-fn.rs:28:5 + | +LL | *FOO.0.get() = 5; + | ^^^^^^^^^^^^^^^^ + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/mod-static-with-const-fn.rs:34:5 + --> $DIR/mod-static-with-const-fn.rs:31:5 | LL | foo(); | ^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors occurred: E0015, E0019. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr index 7141d7ac8b862..20e6593f88ae8 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr @@ -20,17 +20,6 @@ LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR doe LL | } | - temporary value is freed at the end of this statement -error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_raw_ptr_ops.rs:17:28 - | -LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use - | | - | type annotation requires that borrow lasts for `'static` -LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough -LL | } - | - temporary value is freed at the end of this statement - error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:18:29 | @@ -41,6 +30,6 @@ LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does LL | } | - temporary value is freed at the end of this statement -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs index 6661de4ab2cb5..a9d5d6901522a 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.rs +++ b/src/test/ui/consts/const-eval/ub-upvars.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_transmute,const_let)] +#![feature(const_transmute)] #![allow(const_err)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const_let_assign.rs b/src/test/ui/consts/const_let_assign.rs index a3c53a451e106..0b09b8469fd75 100644 --- a/src/test/ui/consts/const_let_assign.rs +++ b/src/test/ui/consts/const_let_assign.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(const_let)] - struct S(i32); const A: () = { diff --git a/src/test/ui/consts/const_let_assign3.rs b/src/test/ui/consts/const_let_assign3.rs index 83825456b5c61..dd9690ef858b9 100644 --- a/src/test/ui/consts/const_let_assign3.rs +++ b/src/test/ui/consts/const_let_assign3.rs @@ -1,4 +1,3 @@ -#![feature(const_let)] #![feature(const_fn)] struct S { @@ -8,6 +7,7 @@ struct S { impl S { const fn foo(&mut self, x: u32) { self.state = x; + //~^ ERROR constant function contains unimplemented expression } } diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index 7f9a953c10fe8..7380906bec7b3 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -1,9 +1,16 @@ +error[E0019]: constant function contains unimplemented expression type + --> $DIR/const_let_assign3.rs:9:9 + | +LL | self.state = x; + | ^^^^^^^^^^^^^^ + error[E0017]: references in constants may only refer to immutable values --> $DIR/const_let_assign3.rs:16:5 | LL | s.foo(3); //~ ERROR references in constants may only refer to immutable values | ^ constants require immutable values -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0017`. +Some errors occurred: E0017, E0019. +For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/dangling-alloc-id-ice.rs b/src/test/ui/consts/dangling-alloc-id-ice.rs index 695d33b690898..dbc50f1fbd4b4 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.rs +++ b/src/test/ui/consts/dangling-alloc-id-ice.rs @@ -1,7 +1,5 @@ // https://github.com/rust-lang/rust/issues/55223 -#![feature(const_let)] - union Foo<'a> { y: &'a (), long_live_the_unit: &'static (), diff --git a/src/test/ui/consts/dangling-alloc-id-ice.stderr b/src/test/ui/consts/dangling-alloc-id-ice.stderr index a5fa88e5e6832..2cd8711f03d31 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.stderr +++ b/src/test/ui/consts/dangling-alloc-id-ice.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling-alloc-id-ice.rs:10:1 + --> $DIR/dangling-alloc-id-ice.rs:8:1 | LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error LL | | let y = (); diff --git a/src/test/ui/consts/dangling_raw_ptr.rs b/src/test/ui/consts/dangling_raw_ptr.rs index 7fc773412f2f8..c2d8e6d421a28 100644 --- a/src/test/ui/consts/dangling_raw_ptr.rs +++ b/src/test/ui/consts/dangling_raw_ptr.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - const FOO: *const u32 = { //~ ERROR any use of this value will cause an error let x = 42; &x diff --git a/src/test/ui/consts/dangling_raw_ptr.stderr b/src/test/ui/consts/dangling_raw_ptr.stderr index 3b20936f8ae97..091f1f785cb02 100644 --- a/src/test/ui/consts/dangling_raw_ptr.stderr +++ b/src/test/ui/consts/dangling_raw_ptr.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling_raw_ptr.rs:3:1 + --> $DIR/dangling_raw_ptr.rs:1:1 | LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error LL | | let x = 42; diff --git a/src/test/ui/consts/issue-54224.rs b/src/test/ui/consts/issue-54224.rs index b5a8fe8819cdd..bb6be37340cf9 100644 --- a/src/test/ui/consts/issue-54224.rs +++ b/src/test/ui/consts/issue-54224.rs @@ -1,6 +1,8 @@ +// compile-pass + #![feature(nll)] -const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed +const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); use std::borrow::Cow; @@ -9,6 +11,5 @@ pub const Y: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[X]); pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); -//~^ ERROR temporary value dropped while borrowed fn main() {} diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr deleted file mode 100644 index 451f49c1cb57a..0000000000000 --- a/src/test/ui/consts/issue-54224.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-54224.rs:3:39 - | -LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed - | ------^^^^^^^^^- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use - | using this value as a constant requires that borrow lasts for `'static` - -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-54224.rs:11:57 - | -LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); - | ---------------^^^^^^^^^- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use - | using this value as a constant requires that borrow lasts for `'static` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr new file mode 100644 index 0000000000000..7a0cd939c145c --- /dev/null +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr @@ -0,0 +1,51 @@ +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:3:9 + | +LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable + | ^ + +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:12:13 + | +LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable + | ^ + +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:19:13 + | +LL | let b = &mut a; //~ references in statics may only refer to immutable + | ^^^^^^ statics require immutable values + +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:26:15 + | +LL | { let b = &mut a; } //~ references in statics may only refer to immutable + | ^^^^^^ statics require immutable values + +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:37:17 + | +LL | let mut a = &mut None; //~ references in statics may only refer to immutable values + | ^^^^^^^^^ statics require immutable values + +error[E0019]: static contains unimplemented expression type + --> $DIR/mutable_borrow.rs:39:5 + | +LL | *a = Some(Foo); //~ unimplemented expression type + | ^^ + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mutable_borrow.rs:37:22 + | +LL | let mut a = &mut None; //~ references in statics may only refer to immutable values + | ^^^^ creates a temporary which is freed while still in use +... +LL | a + | - using this value as a static requires that borrow lasts for `'static` +LL | }; + | - temporary value is freed at the end of this statement + +error: aborting due to 7 previous errors + +Some errors occurred: E0017, E0019, E0716. +For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.rs b/src/test/ui/consts/min_const_fn/mutable_borrow.rs index 85f9a154c8491..d9a4164aa13eb 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.rs +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.rs @@ -14,4 +14,30 @@ impl X { } } +static mut FOO: u32 = { + let mut a = 0; + let b = &mut a; //~ references in statics may only refer to immutable + *b +}; + +static mut BAR: Option = { + let mut a = None; + // taking a mutable reference erases everything we know about `a` + { let b = &mut a; } //~ references in statics may only refer to immutable + a +}; + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +static mut BAR2: &mut Option = { + let mut a = &mut None; //~ references in statics may only refer to immutable values + //~^ does not live long enough + *a = Some(Foo); //~ unimplemented expression type + a +}; + fn main() {} diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr index 7414fa94bfbca..ac61949019744 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -10,5 +10,42 @@ error: mutable references in const fn are unstable LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable | ^ -error: aborting due to 2 previous errors +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:19:13 + | +LL | let b = &mut a; //~ references in statics may only refer to immutable + | ^^^^^^ statics require immutable values + +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:26:15 + | +LL | { let b = &mut a; } //~ references in statics may only refer to immutable + | ^^^^^^ statics require immutable values + +error[E0017]: references in statics may only refer to immutable values + --> $DIR/mutable_borrow.rs:37:17 + | +LL | let mut a = &mut None; //~ references in statics may only refer to immutable values + | ^^^^^^^^^ statics require immutable values + +error[E0019]: static contains unimplemented expression type + --> $DIR/mutable_borrow.rs:39:5 + | +LL | *a = Some(Foo); //~ unimplemented expression type + | ^^ + +error[E0597]: borrowed value does not live long enough + --> $DIR/mutable_borrow.rs:37:22 + | +LL | let mut a = &mut None; //~ references in statics may only refer to immutable values + | ^^^^ temporary value does not live long enough +... +LL | }; + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 7 previous errors +Some errors occurred: E0017, E0019, E0597. +For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/partial_qualif.rs b/src/test/ui/consts/partial_qualif.rs index 4ce41f80f82c8..32c68e69f4bed 100644 --- a/src/test/ui/consts/partial_qualif.rs +++ b/src/test/ui/consts/partial_qualif.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; const FOO: &(Cell, bool) = { diff --git a/src/test/ui/consts/partial_qualif.stderr b/src/test/ui/consts/partial_qualif.stderr index d695f64e2c3b5..967fb83b78b08 100644 --- a/src/test/ui/consts/partial_qualif.stderr +++ b/src/test/ui/consts/partial_qualif.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/partial_qualif.rs:8:5 + --> $DIR/partial_qualif.rs:6:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 34e8eaba9f28f..411cdff3d24d4 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; const FOO: &u32 = { @@ -7,6 +5,7 @@ const FOO: &u32 = { { let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants + //~^ ERROR constant contains unimplemented expression } &{a} }; diff --git a/src/test/ui/consts/projection_qualif.stderr b/src/test/ui/consts/projection_qualif.stderr index d5252f199beac..410c51c4b54e1 100644 --- a/src/test/ui/consts/projection_qualif.stderr +++ b/src/test/ui/consts/projection_qualif.stderr @@ -1,18 +1,24 @@ error[E0017]: references in constants may only refer to immutable values - --> $DIR/projection_qualif.rs:8:27 + --> $DIR/projection_qualif.rs:6:27 | LL | let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values | ^^^^^^ constants require immutable values +error[E0019]: constant contains unimplemented expression type + --> $DIR/projection_qualif.rs:7:18 + | +LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants + | ^^^^^^ + error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911) - --> $DIR/projection_qualif.rs:9:18 + --> $DIR/projection_qualif.rs:7:18 | LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants | ^^^^^^ | = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0017, E0658. +Some errors occurred: E0017, E0019, E0658. For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/promote_const_let.nll.stderr b/src/test/ui/consts/promote_const_let.nll.stderr index d8749bb5fd90b..1fc345d5a12fe 100644 --- a/src/test/ui/consts/promote_const_let.nll.stderr +++ b/src/test/ui/consts/promote_const_let.nll.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:6:9 + --> $DIR/promote_const_let.rs:4:9 | LL | let x: &'static u32 = { | ------------ type annotation requires that `y` is borrowed for `'static` diff --git a/src/test/ui/consts/promote_const_let.rs b/src/test/ui/consts/promote_const_let.rs index 8de9b00eb111d..cbebe84d9058c 100644 --- a/src/test/ui/consts/promote_const_let.rs +++ b/src/test/ui/consts/promote_const_let.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - fn main() { let x: &'static u32 = { let y = 42; diff --git a/src/test/ui/consts/promote_const_let.stderr b/src/test/ui/consts/promote_const_let.stderr index 6bbb7495fb0dc..2ec4ad90855a2 100644 --- a/src/test/ui/consts/promote_const_let.stderr +++ b/src/test/ui/consts/promote_const_let.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:6:10 + --> $DIR/promote_const_let.rs:4:10 | LL | &y //~ ERROR does not live long enough | ^ borrowed value does not live long enough diff --git a/src/test/ui/consts/qualif_overwrite.rs b/src/test/ui/consts/qualif_overwrite.rs index 806a74ee4530b..430eea37de73c 100644 --- a/src/test/ui/consts/qualif_overwrite.rs +++ b/src/test/ui/consts/qualif_overwrite.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; // this is overly conservative. The reset to `None` should clear `a` of all qualifications diff --git a/src/test/ui/consts/qualif_overwrite.stderr b/src/test/ui/consts/qualif_overwrite.stderr index 4fac64bf8063f..30479139e314c 100644 --- a/src/test/ui/consts/qualif_overwrite.stderr +++ b/src/test/ui/consts/qualif_overwrite.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite.rs:12:5 + --> $DIR/qualif_overwrite.rs:10:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/qualif_overwrite_2.rs b/src/test/ui/consts/qualif_overwrite_2.rs index 29557a3da4781..fa79b5c14a736 100644 --- a/src/test/ui/consts/qualif_overwrite_2.rs +++ b/src/test/ui/consts/qualif_overwrite_2.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; // const qualification is not smart enough to know about fields and always assumes that there might diff --git a/src/test/ui/consts/qualif_overwrite_2.stderr b/src/test/ui/consts/qualif_overwrite_2.stderr index 181b728c7b76f..8276db99a12c0 100644 --- a/src/test/ui/consts/qualif_overwrite_2.stderr +++ b/src/test/ui/consts/qualif_overwrite_2.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite_2.rs:10:5 + --> $DIR/qualif_overwrite_2.rs:8:5 | LL | &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^^^ diff --git a/src/test/ui/error-codes/E0010-teach.rs b/src/test/ui/error-codes/E0010-teach.rs index e5ccf32af1473..13371175f9caa 100644 --- a/src/test/ui/error-codes/E0010-teach.rs +++ b/src/test/ui/error-codes/E0010-teach.rs @@ -14,5 +14,6 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 +//~^ ERROR contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr index fa5c767caf24d..670698891d428 100644 --- a/src/test/ui/error-codes/E0010-teach.stderr +++ b/src/test/ui/error-codes/E0010-teach.stderr @@ -6,6 +6,16 @@ LL | const CON : Box = box 0; //~ ERROR E0010 | = note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. -error: aborting due to previous error +error[E0019]: constant contains unimplemented expression type + --> $DIR/E0010-teach.rs:16:28 + | +LL | const CON : Box = box 0; //~ ERROR E0010 + | ^ + | + = note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time. + = note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else. + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0010.rs b/src/test/ui/error-codes/E0010.rs index 66a9319a7df43..7a80b335c5619 100644 --- a/src/test/ui/error-codes/E0010.rs +++ b/src/test/ui/error-codes/E0010.rs @@ -12,5 +12,6 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 +//~^ ERROR contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr index 83c1b409a5174..01295469b2bb2 100644 --- a/src/test/ui/error-codes/E0010.stderr +++ b/src/test/ui/error-codes/E0010.stderr @@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in constants LL | const CON : Box = box 0; //~ ERROR E0010 | ^^^^^ allocation not allowed in constants -error: aborting due to previous error +error[E0019]: constant contains unimplemented expression type + --> $DIR/E0010.rs:14:28 + | +LL | const CON : Box = box 0; //~ ERROR E0010 + | ^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs index b283e28651487..3724eaf61ca0a 100644 --- a/src/test/ui/feature-gate-underscore_const_names.rs +++ b/src/test/ui/feature-gate-underscore_const_names.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_let)] trait Trt {} struct Str {} diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr index ab90ef8f11f7c..050ad8710309e 100644 --- a/src/test/ui/feature-gate-underscore_const_names.stderr +++ b/src/test/ui/feature-gate-underscore_const_names.stderr @@ -1,5 +1,5 @@ error[E0658]: naming constants with `_` is unstable (see issue #54912) - --> $DIR/feature-gate-underscore_const_names.rs:17:1 + --> $DIR/feature-gate-underscore_const_names.rs:16:1 | LL | / const _ : () = { LL | | use std::marker::PhantomData; diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs deleted file mode 100644 index 9bf957a5f1e05..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-const_let.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test use of const let without feature gate. - -const FOO: usize = { - //~^ ERROR statements in constants are unstable - //~| ERROR: let bindings in constants are unstable - let x = 42; - //~^ ERROR statements in constants are unstable - //~| ERROR: let bindings in constants are unstable - 42 -}; - -static BAR: usize = { - //~^ ERROR statements in statics are unstable - //~| ERROR: let bindings in statics are unstable - let x = 42; - //~^ ERROR statements in statics are unstable - //~| ERROR: let bindings in statics are unstable - 42 -}; - -fn main() {} diff --git a/src/test/ui/issues/issue-18118.nll.stderr b/src/test/ui/issues/issue-18118.nll.stderr index 9e680e87f79a8..9529b60c1b6ad 100644 --- a/src/test/ui/issues/issue-18118.nll.stderr +++ b/src/test/ui/issues/issue-18118.nll.stderr @@ -1,68 +1,14 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:15:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:15:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:18:9 - | -LL | &p //~ ERROR `p` does not live long enough - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:12:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:12:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:18:9 + --> $DIR/issue-18118.rs:14:9 | LL | &p //~ ERROR `p` does not live long enough | ^^ | | | borrowed value does not live long enough | using this value as a constant requires that `p` is borrowed for `'static` -LL | //~^ ERROR let bindings in constants are unstable LL | }; | - `p` dropped here while still borrowed -error: aborting due to 6 previous errors +error: aborting due to previous error -Some errors occurred: E0597, E0658. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-18118.rs b/src/test/ui/issues/issue-18118.rs index 7194c159c1e98..05e46230db29a 100644 --- a/src/test/ui/issues/issue-18118.rs +++ b/src/test/ui/issues/issue-18118.rs @@ -10,12 +10,7 @@ pub fn main() { const z: &'static isize = { - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable let p = 3; - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable &p //~ ERROR `p` does not live long enough - //~^ ERROR let bindings in constants are unstable }; } diff --git a/src/test/ui/issues/issue-18118.stderr b/src/test/ui/issues/issue-18118.stderr index 2d83b86e5f40b..4f755745b2857 100644 --- a/src/test/ui/issues/issue-18118.stderr +++ b/src/test/ui/issues/issue-18118.stderr @@ -1,67 +1,13 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:15:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:15:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:18:9 - | -LL | &p //~ ERROR `p` does not live long enough - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:12:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:12:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:18:10 + --> $DIR/issue-18118.rs:14:10 | LL | &p //~ ERROR `p` does not live long enough | ^ borrowed value does not live long enough -LL | //~^ ERROR let bindings in constants are unstable LL | }; | - borrowed value only lives until here | = note: borrowed value must be valid for the static lifetime... -error: aborting due to 6 previous errors +error: aborting due to previous error -Some errors occurred: E0597, E0658. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-32829-2.rs b/src/test/ui/issues/issue-32829-2.rs index 2b223bac8e67b..b5026d8c5e1e5 100644 --- a/src/test/ui/issues/issue-32829-2.rs +++ b/src/test/ui/issues/issue-32829-2.rs @@ -15,7 +15,6 @@ const bad : u32 = { { 5; - //~^ ERROR statements in constants are unstable 0 } }; @@ -23,8 +22,7 @@ const bad : u32 = { const bad_two : u32 = { { invalid(); - //~^ ERROR statements in constants are unstable - //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants + //~^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -32,7 +30,6 @@ const bad_two : u32 = { const bad_three : u32 = { { valid(); - //~^ ERROR statements in constants are unstable 0 } }; @@ -40,7 +37,6 @@ const bad_three : u32 = { static bad_four : u32 = { { 5; - //~^ ERROR statements in statics are unstable 0 } }; @@ -49,7 +45,6 @@ static bad_five : u32 = { { invalid(); //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants - //~| ERROR statements in statics are unstable 0 } }; @@ -57,7 +52,6 @@ static bad_five : u32 = { static bad_six : u32 = { { valid(); - //~^ ERROR statements in statics are unstable 0 } }; @@ -65,7 +59,6 @@ static bad_six : u32 = { static mut bad_seven : u32 = { { 5; - //~^ ERROR statements in statics are unstable 0 } }; @@ -73,8 +66,7 @@ static mut bad_seven : u32 = { static mut bad_eight : u32 = { { invalid(); - //~^ ERROR statements in statics are unstable - //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants + //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -82,7 +74,6 @@ static mut bad_eight : u32 = { static mut bad_nine : u32 = { { valid(); - //~^ ERROR statements in statics are unstable 0 } }; diff --git a/src/test/ui/issues/issue-32829-2.stderr b/src/test/ui/issues/issue-32829-2.stderr index 6d6b94ca4bc6d..5e5cdf8adda2c 100644 --- a/src/test/ui/issues/issue-32829-2.stderr +++ b/src/test/ui/issues/issue-32829-2.stderr @@ -1,94 +1,21 @@ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:17:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:25:9 + --> $DIR/issue-32829-2.rs:24:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:25:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:34:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:42:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:50:9 + --> $DIR/issue-32829-2.rs:46:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:50:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:59:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:67:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:75:9 + --> $DIR/issue-32829-2.rs:68:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:75:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:84:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 12 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs index 801a1301ad774..fca4fb62fad22 100644 --- a/src/test/ui/issues/issue-7364.rs +++ b/src/test/ui/issues/issue-7364.rs @@ -16,5 +16,6 @@ use std::cell::RefCell; static boxed: Box> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics //~| ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] +//~| ERROR contains unimplemented expression type fn main() { } diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr index b0d732bdb6fa6..b6594b1caca2c 100644 --- a/src/test/ui/issues/issue-7364.stderr +++ b/src/test/ui/issues/issue-7364.stderr @@ -4,6 +4,12 @@ error[E0010]: allocations are not allowed in statics LL | static boxed: Box> = box RefCell::new(0); | ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/issue-7364.rs:16:41 + | +LL | static boxed: Box> = box RefCell::new(0); + | ^^^^^^^^^^^^^^^ + error[E0277]: `std::cell::RefCell` cannot be shared between threads safely --> $DIR/issue-7364.rs:16:1 | @@ -15,7 +21,7 @@ LL | static boxed: Box> = box RefCell::new(0); = note: required because it appears within the type `std::boxed::Box>` = note: shared static variables must have a type that implements `Sync` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0010, E0277. +Some errors occurred: E0010, E0019, E0277. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs index 7e6ced12fe69a..a25236b53b51f 100644 --- a/src/test/ui/static/static-mut-not-constant.rs +++ b/src/test/ui/static/static-mut-not-constant.rs @@ -12,5 +12,6 @@ static mut a: Box = box 3; //~^ ERROR allocations are not allowed in statics +//~| ERROR static contains unimplemented expression fn main() {} diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr index ad44121e76316..d9250e85d3e3f 100644 --- a/src/test/ui/static/static-mut-not-constant.stderr +++ b/src/test/ui/static/static-mut-not-constant.stderr @@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in statics LL | static mut a: Box = box 3; | ^^^^^ allocation not allowed in statics -error: aborting due to previous error +error[E0019]: static contains unimplemented expression type + --> $DIR/static-mut-not-constant.rs:13:32 + | +LL | static mut a: Box = box 3; + | ^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs index 8d31fd0b1e93d..bb123f46a5772 100644 --- a/src/test/ui/underscore_const_names.rs +++ b/src/test/ui/underscore_const_names.rs @@ -10,7 +10,6 @@ // compile-pass -#![feature(const_let)] #![feature(underscore_const_names)] trait Trt {} diff --git a/src/test/ui/write-to-static-mut-in-static.rs b/src/test/ui/write-to-static-mut-in-static.rs index 191f09b54ee73..9a570a4381b32 100644 --- a/src/test/ui/write-to-static-mut-in-static.rs +++ b/src/test/ui/write-to-static-mut-in-static.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_let)] - pub static mut A: u32 = 0; pub static mut B: () = unsafe { A = 1; }; //~^ ERROR cannot mutate statics in the initializer of another static diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index 673a71b4642f3..e7233c5b8a5e0 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -1,11 +1,11 @@ error: cannot mutate statics in the initializer of another static - --> $DIR/write-to-static-mut-in-static.rs:14:33 + --> $DIR/write-to-static-mut-in-static.rs:12:33 | LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ error: cannot mutate statics in the initializer of another static - --> $DIR/write-to-static-mut-in-static.rs:17:34 + --> $DIR/write-to-static-mut-in-static.rs:15:34 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^ From 507ea97a3e245887bc8cbea0f0fe8474d082bd0e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 09:35:23 +0100 Subject: [PATCH 09/25] Properly name the flag for `&&` -> `&` conversion --- src/librustc/mir/mod.rs | 10 +++++----- src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 4 ++-- src/librustc_mir/hair/cx/mod.rs | 8 ++++---- src/librustc_mir/transform/qualify_consts.rs | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a82a7b555a05e..3968d9aece210 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -153,7 +153,7 @@ pub struct Mir<'tcx> { /// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop /// this conversion from happening and use short circuiting, we will cause the following code /// to change the value of `x`: `let mut x = 42; false && { x = 55; true };` - pub const_can_have_let_mut_bindings: bool, + pub control_flow_destroyed: bool, /// A span representing this MIR, for error reporting pub span: Span, @@ -173,7 +173,7 @@ impl<'tcx> Mir<'tcx> { arg_count: usize, upvar_decls: Vec, span: Span, - const_can_have_let_mut_bindings: bool, + control_flow_destroyed: bool, ) -> Self { // We need `arg_count` locals, and one for the return place assert!( @@ -198,7 +198,7 @@ impl<'tcx> Mir<'tcx> { spread_arg: None, span, cache: cache::Cache::new(), - const_can_have_let_mut_bindings, + control_flow_destroyed, } } @@ -429,7 +429,7 @@ impl_stable_hash_for!(struct Mir<'tcx> { arg_count, upvar_decls, spread_arg, - const_can_have_let_mut_bindings, + control_flow_destroyed, span, cache }); @@ -2983,7 +2983,7 @@ BraceStructTypeFoldableImpl! { arg_count, upvar_decls, spread_arg, - const_can_have_let_mut_bindings, + control_flow_destroyed, span, cache, } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index ab19cd9dd5bed..80cab0cf68687 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -864,7 +864,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.arg_count, self.upvar_decls, self.fn_span, - self.hir.const_can_have_let_mut_bindings(), + self.hir.control_flow_destroyed(), ) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 951651aa1ce1c..5acff380f2847 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -372,7 +372,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // FIXME(eddyb) use logical ops in constants when // they can handle that kind of control-flow. (hir::BinOpKind::And, hir::Constness::Const) => { - cx.const_can_have_let_mut_bindings = false; + cx.control_flow_destroyed = true; ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), @@ -380,7 +380,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } (hir::BinOpKind::Or, hir::Constness::Const) => { - cx.const_can_have_let_mut_bindings = false; + cx.control_flow_destroyed = true; ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 8ee1eac0e331a..76dde4ed02bc3 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -58,7 +58,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { check_overflow: bool, /// See field with the same name on `Mir` - const_can_have_let_mut_bindings: bool, + control_flow_destroyed: bool, } impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { @@ -99,12 +99,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { constness, body_owner_kind, check_overflow, - const_can_have_let_mut_bindings: true, + control_flow_destroyed: false, } } - pub fn const_can_have_let_mut_bindings(&self) -> bool { - self.const_can_have_let_mut_bindings + pub fn control_flow_destroyed(&self) -> bool { + self.control_flow_destroyed } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 8eae45376642b..b9c33ae8c1afa 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1183,7 +1183,7 @@ impl MirPass for QualifyAndPromoteConstants { // Do the actual promotion, now that we know what's viable. promote_consts::promote_candidates(mir, tcx, temps, candidates); } else { - if !mir.const_can_have_let_mut_bindings { + if mir.control_flow_destroyed { for local in mir.mut_vars_iter() { let span = mir.local_decls[local].source_info.span; tcx.sess.span_err( From 75ce28a9745940bbc56110911cfd83b2498bcef6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 09:41:56 +0100 Subject: [PATCH 10/25] Show auto-applicable correction warning for short circuiting in constants --- src/librustc_mir/hair/cx/expr.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 5acff380f2847..1dfd77dee1fed 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -23,6 +23,7 @@ use rustc::hir; use rustc::hir::def_id::LocalDefId; use rustc::mir::{BorrowKind}; use syntax_pos::Span; +use syntax::errors::Applicability; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; @@ -373,6 +374,17 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // they can handle that kind of control-flow. (hir::BinOpKind::And, hir::Constness::Const) => { cx.control_flow_destroyed = true; + cx.tcx.sess.struct_span_warn( + op.span, + "boolean short circuiting operators in constants do + not actually short circuit. Thus new const eval features + are not accessible in constants." + ).span_suggestion_with_applicability( + op.span, + "use a bit operator instead", + "&".into(), + Applicability::MachineApplicable, + ).emit(); ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), @@ -381,6 +393,17 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } (hir::BinOpKind::Or, hir::Constness::Const) => { cx.control_flow_destroyed = true; + cx.tcx.sess.struct_span_warn( + op.span, + "boolean short circuiting operators in constants do + not actually short circuit. Thus new const eval features + are not accessible in constants." + ).span_suggestion_with_applicability( + op.span, + "use a bit operator instead", + "|".into(), + Applicability::MachineApplicable, + ).emit(); ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), From d8ece188b88569da794c2916ee6034a1054d2f35 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 10:26:42 +0100 Subject: [PATCH 11/25] Improve the error around short circuiting and let bindings --- src/librustc_mir/hair/cx/expr.rs | 8 ++-- src/librustc_mir/transform/qualify_consts.rs | 6 +-- src/test/ui/consts/const_short_circuit.rs | 16 ++++++++ src/test/ui/consts/const_short_circuit.stderr | 38 +++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/consts/const_short_circuit.rs create mode 100644 src/test/ui/consts/const_short_circuit.stderr diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 1dfd77dee1fed..b058748fca024 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -376,8 +376,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, cx.control_flow_destroyed = true; cx.tcx.sess.struct_span_warn( op.span, - "boolean short circuiting operators in constants do - not actually short circuit. Thus new const eval features + "boolean short circuiting operators in constants do \ + not actually short circuit. Thus new const eval features \ are not accessible in constants." ).span_suggestion_with_applicability( op.span, @@ -395,8 +395,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, cx.control_flow_destroyed = true; cx.tcx.sess.struct_span_warn( op.span, - "boolean short circuiting operators in constants do - not actually short circuit. Thus new const eval features + "boolean short circuiting operators in constants do \ + not actually short circuit. Thus new const eval features \ are not accessible in constants." ).span_suggestion_with_applicability( op.span, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index b9c33ae8c1afa..d399543145dff 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1184,13 +1184,13 @@ impl MirPass for QualifyAndPromoteConstants { promote_consts::promote_candidates(mir, tcx, temps, candidates); } else { if mir.control_flow_destroyed { - for local in mir.mut_vars_iter() { + for local in mir.vars_iter() { let span = mir.local_decls[local].source_info.span; tcx.sess.span_err( span, &format!( - "Cannot have both mutable bindings and \ - short circuiting operators in {}", + "short circuiting operators do not actually short circuit in {}. \ + Thus new features like let bindings are not permitted", mode, ), ); diff --git a/src/test/ui/consts/const_short_circuit.rs b/src/test/ui/consts/const_short_circuit.rs new file mode 100644 index 0000000000000..9721c1969d577 --- /dev/null +++ b/src/test/ui/consts/const_short_circuit.rs @@ -0,0 +1,16 @@ +#![feature(underscore_const_names)] + +const _: bool = false && false; //~ WARN boolean short circuiting operators in constants +const _: bool = true && false; //~ WARN boolean short circuiting operators in constants +const _: bool = { + let mut x = true && false; //~ WARN boolean short circuiting operators in constants + //~^ ERROR short circuiting operators do not actually short circuit in constant + x +}; +const _: bool = { + let x = true && false; //~ WARN boolean short circuiting operators in constants + //~^ ERROR short circuiting operators do not actually short circuit in constant + x +}; + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/consts/const_short_circuit.stderr b/src/test/ui/consts/const_short_circuit.stderr new file mode 100644 index 0000000000000..4c1e531ea8727 --- /dev/null +++ b/src/test/ui/consts/const_short_circuit.stderr @@ -0,0 +1,38 @@ +warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. + --> $DIR/const_short_circuit.rs:3:23 + | +LL | const _: bool = false && false; //~ WARN boolean short circuiting operators in constants + | ^^ help: use a bit operator instead: `&` + +warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. + --> $DIR/const_short_circuit.rs:4:22 + | +LL | const _: bool = true && false; //~ WARN boolean short circuiting operators in constants + | ^^ help: use a bit operator instead: `&` + +warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. + --> $DIR/const_short_circuit.rs:6:22 + | +LL | let mut x = true && false; //~ WARN boolean short circuiting operators in constants + | ^^ help: use a bit operator instead: `&` + +error: short circuiting operators do not actually short circuit in constant. Thus new features like let bindings are not permitted + --> $DIR/const_short_circuit.rs:6:9 + | +LL | let mut x = true && false; //~ WARN boolean short circuiting operators in constants + | ^^^^^ + +warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. + --> $DIR/const_short_circuit.rs:11:18 + | +LL | let x = true && false; //~ WARN boolean short circuiting operators in constants + | ^^ help: use a bit operator instead: `&` + +error: short circuiting operators do not actually short circuit in constant. Thus new features like let bindings are not permitted + --> $DIR/const_short_circuit.rs:11:9 + | +LL | let x = true && false; //~ WARN boolean short circuiting operators in constants + | ^ + +error: aborting due to 2 previous errors + From 866664c8bb1a3f1eb7fa60c8d8243535675ea78f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 10:26:54 +0100 Subject: [PATCH 12/25] Add a test for single variant matches --- src/test/ui/consts/single_variant_match_ice.rs | 8 ++++++++ .../ui/consts/single_variant_match_ice.stderr | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/test/ui/consts/single_variant_match_ice.rs b/src/test/ui/consts/single_variant_match_ice.rs index 67a41bc5dc4ad..79dde3c18e8fa 100644 --- a/src/test/ui/consts/single_variant_match_ice.rs +++ b/src/test/ui/consts/single_variant_match_ice.rs @@ -2,6 +2,14 @@ enum Foo { Prob, } +const FOO: u32 = match Foo::Prob { + Foo::Prob => 42, //~ ERROR unimplemented expression type +}; + +const BAR: u32 = match Foo::Prob { + x => 42, //~ ERROR unimplemented expression type +}; + impl Foo { pub const fn as_val(&self) -> u8 { use self::Foo::*; diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr index a0222b0d489a4..f5c2cb5e0e9dc 100644 --- a/src/test/ui/consts/single_variant_match_ice.stderr +++ b/src/test/ui/consts/single_variant_match_ice.stderr @@ -1,8 +1,21 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/single_variant_match_ice.rs:6:5 + | +LL | Foo::Prob => 42, //~ ERROR unimplemented expression type + | ^^^^^^^^^ + +error[E0019]: constant contains unimplemented expression type + --> $DIR/single_variant_match_ice.rs:10:5 + | +LL | x => 42, //~ ERROR unimplemented expression type + | ^ + error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/single_variant_match_ice.rs:10:13 + --> $DIR/single_variant_match_ice.rs:18:13 | LL | Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn | ^^^^ -error: aborting due to previous error +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0019`. From 8937faa83795ccd55b19a5cb1869ce3b1097fe43 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 13:08:55 +0100 Subject: [PATCH 13/25] Reenable `const_let` feature gate --- src/librustc_mir/transform/qualify_consts.rs | 230 +++++++++++++++--- .../transform/qualify_min_const_fn.rs | 17 +- src/libsyntax/feature_gate.rs | 3 + .../ctfe/const-block-non-item-statement-3.rs | 2 + .../ctfe/const-block-non-item-statement.rs | 2 + src/test/run-pass/ctfe/locals-in-const-fn.rs | 2 +- ...check-static-values-constraints.nll.stderr | 62 +---- .../ui/check-static-values-constraints.rs | 7 - .../ui/check-static-values-constraints.stderr | 62 +---- .../const-block-non-item-statement-2.rs | 10 +- .../const-block-non-item-statement-2.stderr | 62 +++++ .../const-block-non-item-statement-3.rs | 6 +- .../const-block-non-item-statement-3.stderr | 35 +++ .../consts/const-block-non-item-statement.rs | 6 +- .../const-block-non-item-statement.stderr | 35 +++ .../assign-to-static-within-other-static-2.rs | 3 +- ...ign-to-static-within-other-static-2.stderr | 4 +- .../assign-to-static-within-other-static.rs | 1 + ...ssign-to-static-within-other-static.stderr | 2 +- src/test/ui/consts/const-eval/const_let.rs | 2 + .../ui/consts/const-eval/const_let.stderr | 4 +- .../ui/consts/const-eval/infinite_loop.rs | 2 + .../ui/consts/const-eval/infinite_loop.stderr | 6 +- src/test/ui/consts/const-eval/issue-52475.rs | 2 + .../ui/consts/const-eval/issue-52475.stderr | 6 +- .../const-eval/mod-static-with-const-fn.rs | 3 +- .../mod-static-with-const-fn.stderr | 4 +- .../promoted_raw_ptr_ops.nll.stderr | 13 +- src/test/ui/consts/const-eval/ub-upvars.rs | 2 +- .../ui/consts/const-fn-destructuring-arg.rs | 14 +- .../consts/const-fn-destructuring-arg.stderr | 35 +++ .../ui/consts/const-fn-not-safe-for-const.rs | 8 +- .../consts/const-fn-not-safe-for-const.stderr | 52 +++- src/test/ui/consts/const_let_assign.rs | 2 + src/test/ui/consts/const_let_assign2.rs | 3 + src/test/ui/consts/const_let_assign3.rs | 3 +- src/test/ui/consts/const_let_assign3.stderr | 4 +- src/test/ui/consts/const_let_eq.rs | 2 + src/test/ui/consts/const_short_circuit.rs | 4 +- src/test/ui/consts/dangling-alloc-id-ice.rs | 2 + .../ui/consts/dangling-alloc-id-ice.stderr | 2 +- src/test/ui/consts/dangling_raw_ptr.rs | 2 + src/test/ui/consts/dangling_raw_ptr.stderr | 2 +- src/test/ui/consts/issue-54224.rs | 5 +- src/test/ui/consts/issue-54224.stderr | 23 ++ .../min_const_fn/min_const_fn.nll.stderr | 8 +- .../ui/consts/min_const_fn/min_const_fn.rs | 2 +- .../consts/min_const_fn/min_const_fn.stderr | 8 +- .../min_const_fn/mutable_borrow.nll.stderr | 51 ---- .../ui/consts/min_const_fn/mutable_borrow.rs | 34 +-- .../consts/min_const_fn/mutable_borrow.stderr | 55 +---- src/test/ui/consts/partial_qualif.rs | 2 + src/test/ui/consts/partial_qualif.stderr | 2 +- src/test/ui/consts/projection_qualif.rs | 4 +- src/test/ui/consts/projection_qualif.stderr | 6 +- .../ui/consts/promote_const_let.nll.stderr | 2 +- src/test/ui/consts/promote_const_let.rs | 2 + src/test/ui/consts/promote_const_let.stderr | 2 +- src/test/ui/consts/qualif_overwrite.rs | 2 + src/test/ui/consts/qualif_overwrite.stderr | 2 +- src/test/ui/consts/qualif_overwrite_2.rs | 2 + src/test/ui/consts/qualif_overwrite_2.stderr | 2 +- src/test/ui/error-codes/E0010-teach.rs | 1 - src/test/ui/error-codes/E0010-teach.stderr | 14 +- src/test/ui/error-codes/E0010.rs | 1 - src/test/ui/error-codes/E0010.stderr | 11 +- .../ui/feature-gate-underscore_const_names.rs | 1 + ...feature-gate-underscore_const_names.stderr | 2 +- .../feature-gates/feature-gate-const_let.rs | 31 +++ src/test/ui/issues/issue-18118.nll.stderr | 60 ++++- src/test/ui/issues/issue-18118.rs | 5 + src/test/ui/issues/issue-18118.stderr | 60 ++++- src/test/ui/issues/issue-32829-2.rs | 13 +- src/test/ui/issues/issue-32829-2.stderr | 83 ++++++- src/test/ui/issues/issue-37550.rs | 4 +- src/test/ui/issues/issue-37550.stderr | 6 +- src/test/ui/issues/issue-7364.rs | 1 - src/test/ui/issues/issue-7364.stderr | 10 +- src/test/ui/static/static-mut-not-constant.rs | 1 - .../ui/static/static-mut-not-constant.stderr | 11 +- src/test/ui/underscore_const_names.rs | 1 + src/test/ui/write-to-static-mut-in-static.rs | 2 + .../ui/write-to-static-mut-in-static.stderr | 4 +- 83 files changed, 871 insertions(+), 395 deletions(-) create mode 100644 src/test/ui/consts/const-block-non-item-statement-2.stderr create mode 100644 src/test/ui/consts/const-block-non-item-statement-3.stderr create mode 100644 src/test/ui/consts/const-block-non-item-statement.stderr create mode 100644 src/test/ui/consts/const-fn-destructuring-arg.stderr create mode 100644 src/test/ui/consts/issue-54224.stderr delete mode 100644 src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-const_let.rs diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index d399543145dff..0f174d6da1fc3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -30,7 +30,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUs use rustc::middle::lang_items; use rustc_target::spec::abi::Abi; use syntax::ast::LitKind; -use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue}; +use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue}; use syntax_pos::{Span, DUMMY_SP}; use std::fmt; @@ -114,6 +114,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { param_env: ty::ParamEnv<'tcx>, local_qualif: IndexVec>, qualif: Qualif, + const_fn_arg_vars: BitSet, temp_promotion_state: IndexVec, promotion_candidates: Vec } @@ -148,6 +149,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { param_env, local_qualif, qualif: Qualif::empty(), + const_fn_arg_vars: BitSet::new_empty(mir.local_decls.len()), temp_promotion_state: temps, promotion_candidates: vec![] } @@ -176,6 +178,26 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } + /// Error about extra statements in a constant. + fn statement_like(&mut self) { + self.add(Qualif::NOT_CONST); + if self.mode != Mode::Fn { + let mut err = feature_err( + &self.tcx.sess.parse_sess, + "const_let", + self.span, + GateIssue::Language, + &format!("statements in {}s are unstable", self.mode), + ); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note("Blocks in constants may only contain items (such as constant, function \ + definition, etc...) and a tail expression."); + err.help("To avoid it, you have to replace the non-item object."); + } + err.emit(); + } + } + /// Add the given qualification to self.qualif. fn add(&mut self, qualif: Qualif) { self.qualif = self.qualif | qualif; @@ -221,46 +243,85 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - let mut dest = dest; - let index = loop { - match dest { - Place::Local(index) => break *index, - // projections are transparent for assignments - // we qualify the entire destination at once, even if just a field would have - // stricter qualification - Place::Projection(proj) => { - // Catch more errors in the destination. `visit_place` also checks various - // projection rules like union field access and raw pointer deref - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - dest = &proj.base; - }, - Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), - Place::Static(..) => { - // Catch more errors in the destination. `visit_place` also checks that we - // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - return; + if self.const_let_allowed() { + let mut dest = dest; + let index = loop { + match dest { + // with `const_let` active, we treat all locals equal + Place::Local(index) => break *index, + // projections are transparent for assignments + // we qualify the entire destination at once, even if just a field would have + // stricter qualification + Place::Projection(proj) => { + // Catch more errors in the destination. `visit_place` also checks various + // projection rules like union field access and raw pointer deref + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + dest = &proj.base; + }, + Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), + Place::Static(..) => { + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; + } } + }; + debug!("store to var {:?}", index); + match &mut self.local_qualif[index] { + // this is overly restrictive, because even full assignments do not clear the qualif + // While we could special case full assignments, this would be inconsistent with + // aggregates where we overwrite all fields via assignments, which would not get + // that feature. + Some(ref mut qualif) => *qualif = *qualif | self.qualif, + // insert new qualification + qualif @ None => *qualif = Some(self.qualif), } - }; - debug!("store to var {:?}", index); - match &mut self.local_qualif[index] { - // this is overly restrictive, because even full assignments do not clear the qualif - // While we could special case full assignments, this would be inconsistent with - // aggregates where we overwrite all fields via assignments, which would not get - // that feature. - Some(ref mut qualif) => *qualif = *qualif | self.qualif, - // insert new qualification - qualif @ None => *qualif = Some(self.qualif), + return; } + + match *dest { + Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp || + self.mir.local_kind(index) == LocalKind::ReturnPointer => { + debug!("store to {:?} (temp or return pointer)", index); + store(&mut self.local_qualif[index]) + } + + Place::Projection(box Projection { + base: Place::Local(index), + elem: ProjectionElem::Deref + }) if self.mir.local_kind(index) == LocalKind::Temp + && self.mir.local_decls[index].ty.is_box() + && self.local_qualif[index].map_or(false, |qualif| { + qualif.contains(Qualif::NOT_CONST) + }) => { + // Part of `box expr`, we should've errored + // already for the Box allocation Rvalue. + } + + // This must be an explicit assignment. + _ => { + // Catch more errors in the destination. + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + self.statement_like(); + } + } + } + + fn const_let_allowed(&self) -> bool { + self.tcx.features().const_let } /// Qualify a whole const, static initializer or const fn. @@ -299,7 +360,48 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseEdges { .. } | TerminatorKind::FalseUnwind { .. } => None, - TerminatorKind::Return => break, + TerminatorKind::Return => { + if !self.const_let_allowed() { + // Check for unused values. This usually means + // there are extra statements in the AST. + for temp in mir.temps_iter() { + if self.local_qualif[temp].is_none() { + continue; + } + + let state = self.temp_promotion_state[temp]; + if let TempState::Defined { location, uses: 0 } = state { + let data = &mir[location.block]; + let stmt_idx = location.statement_index; + + // Get the span for the initialization. + let source_info = if stmt_idx < data.statements.len() { + data.statements[stmt_idx].source_info + } else { + data.terminator().source_info + }; + self.span = source_info.span; + + // Treat this as a statement in the AST. + self.statement_like(); + } + } + + // Make sure there are no extra unassigned variables. + self.qualif = Qualif::NOT_CONST; + for index in mir.vars_iter() { + if !self.const_fn_arg_vars.contains(index) { + debug!("unassigned variable {:?}", index); + self.assign(&Place::Local(index), Location { + block: bb, + statement_index: usize::MAX, + }); + } + } + } + + break; + } }; match target { @@ -366,6 +468,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } + LocalKind::Var if !self.const_let_allowed() => { + if self.mode != Mode::Fn { + emit_feature_err(&self.tcx.sess.parse_sess, "const_let", + self.span, GateIssue::Language, + &format!("let bindings in {}s are unstable",self.mode)); + } + self.add(Qualif::NOT_CONST); + } LocalKind::Var | LocalKind::Arg | LocalKind::Temp => { @@ -448,6 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { ProjectionElem::Deref => { if context.is_mutating_use() { this.not_const() + } else { + this.qualif = Qualif::NOT_CONST; } let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); match this.mode { @@ -1050,6 +1162,46 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location); self.visit_rvalue(rvalue, location); + // Check the allowed const fn argument forms. + if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { + if self.mir.local_kind(index) == LocalKind::Var && + self.const_fn_arg_vars.insert(index) && + !self.tcx.sess.features_untracked().const_let { + // Direct use of an argument is permitted. + match *rvalue { + Rvalue::Use(Operand::Copy(Place::Local(local))) | + Rvalue::Use(Operand::Move(Place::Local(local))) => { + if self.mir.local_kind(local) == LocalKind::Arg { + return; + } + } + _ => {} + } + // Avoid a generic error for other uses of arguments. + if self.qualif.contains(Qualif::FN_ARGUMENT) { + let decl = &self.mir.local_decls[index]; + let mut err = feature_err( + &self.tcx.sess.parse_sess, + "const_let", + decl.source_info.span, + GateIssue::Language, + "arguments of constant functions can only be immutable by-value bindings" + ); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note("Constant functions are not allowed to mutate anything. Thus, \ + binding to an argument with a mutable pattern is not allowed."); + err.note("Remove any mutable bindings from the argument list to fix this \ + error. In case you need to mutate the argument, try lazily \ + initializing a global variable instead of using a const fn, or \ + refactoring the code to a functional style to avoid mutation if \ + possible."); + } + err.emit(); + return; + } + } + } + self.assign(dest, location); } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 5729775e15dc0..9e5d75a746e85 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -64,6 +64,12 @@ pub fn is_min_const_fn( } } + for local in mir.vars_iter() { + return Err(( + mir.local_decls[local].source_info.span, + "local variables in const fn are unstable".into(), + )); + } for local in &mir.local_decls { check_ty(tcx, local.ty, local.source_info.span)?; } @@ -264,8 +270,15 @@ fn check_place( mode: PlaceMode, ) -> McfResult { match place { - // assignments to locals, arguments, temporaries or the return slot are fine - Place::Local(_) => Ok(()), + Place::Local(l) => match mode { + PlaceMode::Assign => match mir.local_kind(*l) { + LocalKind::Temp | LocalKind::ReturnPointer => Ok(()), + LocalKind::Arg | LocalKind::Var => { + Err((span, "assignments in const fn are unstable".into())) + } + }, + PlaceMode::Read => Ok(()), + }, // promoteds are always fine, they are essentially constants Place::Promoted(_) => Ok(()), Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 586659ecd9ca2..3bc349170514c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -209,6 +209,9 @@ declare_features! ( // Allows the definition of `const fn` functions with some advanced features. (active, const_fn, "1.2.0", Some(24111), None), + // Allows let bindings and destructuring in `const fn` functions and constants. + (active, const_let, "1.22.1", Some(48821), None), + // Allows accessing fields of unions inside const fn. (active, const_fn_union, "1.27.0", Some(51909), None), diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs index 997476853ec4e..0fcf9a5acbdb1 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs @@ -11,6 +11,8 @@ // run-pass #![allow(dead_code)] +#![feature(const_let)] + type Array = [u32; { let x = 2; 5 }]; pub fn main() {} diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement.rs b/src/test/run-pass/ctfe/const-block-non-item-statement.rs index 0943818e2b7dc..b7ed8af35d4c1 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement.rs @@ -11,6 +11,8 @@ // run-pass #![allow(dead_code)] +#![feature(const_let)] + enum Foo { Bar = { let x = 1; 3 } } diff --git a/src/test/run-pass/ctfe/locals-in-const-fn.rs b/src/test/run-pass/ctfe/locals-in-const-fn.rs index c4413dba69fb2..d10465b9dcd26 100644 --- a/src/test/run-pass/ctfe/locals-in-const-fn.rs +++ b/src/test/run-pass/ctfe/locals-in-const-fn.rs @@ -12,7 +12,7 @@ // https://github.com/rust-lang/rust/issues/48821 -#![feature(const_fn)] +#![feature(const_fn, const_let)] const fn foo(i: usize) -> usize { let x = i; diff --git a/src/test/ui/check-static-values-constraints.nll.stderr b/src/test/ui/check-static-values-constraints.nll.stderr index ac549cd8d1a48..5522e22fb1fa2 100644 --- a/src/test/ui/check-static-values-constraints.nll.stderr +++ b/src/test/ui/check-static-values-constraints.nll.stderr @@ -13,80 +13,44 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:89:37 - | -LL | static STATIC11: Box = box MyOwned; - | ^^^^^^^ - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:100:32 + --> $DIR/check-static-values-constraints.rs:99:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:105:5 + --> $DIR/check-static-values-constraints.rs:104:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:105:9 - | -LL | box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:107:5 + --> $DIR/check-static-values-constraints.rs:105:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:107:9 - | -LL | box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:112:6 + --> $DIR/check-static-values-constraints.rs:109:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:112:10 - | -LL | &box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:114:6 + --> $DIR/check-static-values-constraints.rs:110:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:114:10 - | -LL | &box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:121:5 + --> $DIR/check-static-values-constraints.rs:116:5 | LL | box 3; | ^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:121:9 - | -LL | box 3; - | ^ - error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:126:45 + --> $DIR/check-static-values-constraints.rs:120:45 | LL | let y = { static x: Box = box 3; x }; | ^ @@ -95,18 +59,12 @@ LL | let y = { static x: Box = box 3; x }; | help: consider borrowing here: `&x` error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:126:38 + --> $DIR/check-static-values-constraints.rs:120:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:126:42 - | -LL | let y = { static x: Box = box 3; x }; - | ^ - -error: aborting due to 17 previous errors +error: aborting due to 10 previous errors -Some errors occurred: E0010, E0015, E0019, E0493, E0507. +Some errors occurred: E0010, E0015, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/check-static-values-constraints.rs b/src/test/ui/check-static-values-constraints.rs index 1822af333231e..37f665960c8c8 100644 --- a/src/test/ui/check-static-values-constraints.rs +++ b/src/test/ui/check-static-values-constraints.rs @@ -88,7 +88,6 @@ struct MyOwned; static STATIC11: Box = box MyOwned; //~^ ERROR allocations are not allowed in statics -//~| ERROR contains unimplemented expression type static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -103,16 +102,12 @@ static mut STATIC14: SafeStruct = SafeStruct { static STATIC15: &'static [Box] = &[ box MyOwned, //~ ERROR allocations are not allowed in statics - //~^ ERROR contains unimplemented expression type box MyOwned, //~ ERROR allocations are not allowed in statics - //~^ ERROR contains unimplemented expression type ]; static STATIC16: (&'static Box, &'static Box) = ( &box MyOwned, //~ ERROR allocations are not allowed in statics - //~^ ERROR contains unimplemented expression type &box MyOwned, //~ ERROR allocations are not allowed in statics - //~^ ERROR contains unimplemented expression type ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; @@ -120,11 +115,9 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Box = box 3; //~^ ERROR allocations are not allowed in statics -//~| ERROR contains unimplemented expression type pub fn main() { let y = { static x: Box = box 3; x }; //~^ ERROR allocations are not allowed in statics //~^^ ERROR cannot move out of static item - //~| ERROR contains unimplemented expression type } diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr index 40f8555f6afa7..ac979a3fa7cfc 100644 --- a/src/test/ui/check-static-values-constraints.stderr +++ b/src/test/ui/check-static-values-constraints.stderr @@ -13,97 +13,55 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:89:37 - | -LL | static STATIC11: Box = box MyOwned; - | ^^^^^^^ - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:100:32 + --> $DIR/check-static-values-constraints.rs:99:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:105:5 + --> $DIR/check-static-values-constraints.rs:104:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:105:9 - | -LL | box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:107:5 + --> $DIR/check-static-values-constraints.rs:105:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:107:9 - | -LL | box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:112:6 + --> $DIR/check-static-values-constraints.rs:109:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:112:10 - | -LL | &box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:114:6 + --> $DIR/check-static-values-constraints.rs:110:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:114:10 - | -LL | &box MyOwned, //~ ERROR allocations are not allowed in statics - | ^^^^^^^ - error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:121:5 + --> $DIR/check-static-values-constraints.rs:116:5 | LL | box 3; | ^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:121:9 - | -LL | box 3; - | ^ - error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:126:45 + --> $DIR/check-static-values-constraints.rs:120:45 | LL | let y = { static x: Box = box 3; x }; | ^ cannot move out of static item error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:126:38 + --> $DIR/check-static-values-constraints.rs:120:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/check-static-values-constraints.rs:126:42 - | -LL | let y = { static x: Box = box 3; x }; - | ^ - -error: aborting due to 17 previous errors +error: aborting due to 10 previous errors -Some errors occurred: E0010, E0015, E0019, E0493, E0507. +Some errors occurred: E0010, E0015, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/consts/const-block-non-item-statement-2.rs b/src/test/ui/consts/const-block-non-item-statement-2.rs index 0e96f96e3d14e..f80d55cb34267 100644 --- a/src/test/ui/consts/const-block-non-item-statement-2.rs +++ b/src/test/ui/consts/const-block-non-item-statement-2.rs @@ -8,17 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-pass - const A: usize = { 1; 2 }; +//~^ ERROR statements in constants are unstable const B: usize = { { } 2 }; +//~^ ERROR statements in constants are unstable macro_rules! foo { - () => (()) + () => (()) //~ ERROR statements in constants are unstable } const C: usize = { foo!(); 2 }; const D: usize = { let x = 4; 2 }; +//~^ ERROR let bindings in constants are unstable +//~| ERROR statements in constants are unstable +//~| ERROR let bindings in constants are unstable +//~| ERROR statements in constants are unstable pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-2.stderr b/src/test/ui/consts/const-block-non-item-statement-2.stderr new file mode 100644 index 0000000000000..580f7e039d1c3 --- /dev/null +++ b/src/test/ui/consts/const-block-non-item-statement-2.stderr @@ -0,0 +1,62 @@ +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:11:20 + | +LL | const A: usize = { 1; 2 }; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:14:20 + | +LL | const B: usize = { { } 2 }; + | ^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:18:12 + | +LL | () => (()) //~ ERROR statements in constants are unstable + | ^^ +LL | } +LL | const C: usize = { foo!(); 2 }; + | ------- in this macro invocation + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:22:28 + | +LL | const D: usize = { let x = 4; 2 }; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:22:28 + | +LL | const D: usize = { let x = 4; 2 }; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:22:1 + | +LL | const D: usize = { let x = 4; 2 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-2.rs:22:1 + | +LL | const D: usize = { let x = 4; 2 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs index 496e5486e9b99..cfa4b778dde80 100644 --- a/src/test/ui/consts/const-block-non-item-statement-3.rs +++ b/src/test/ui/consts/const-block-non-item-statement-3.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-pass - type Array = [u32; { let x = 2; 5 }]; +//~^ ERROR let bindings in constants are unstable +//~| ERROR statements in constants are unstable +//~| ERROR let bindings in constants are unstable +//~| ERROR statements in constants are unstable pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-3.stderr b/src/test/ui/consts/const-block-non-item-statement-3.stderr new file mode 100644 index 0000000000000..0124288d43d57 --- /dev/null +++ b/src/test/ui/consts/const-block-non-item-statement-3.stderr @@ -0,0 +1,35 @@ +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-3.rs:11:31 + | +LL | type Array = [u32; { let x = 2; 5 }]; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-3.rs:11:31 + | +LL | type Array = [u32; { let x = 2; 5 }]; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-3.rs:11:20 + | +LL | type Array = [u32; { let x = 2; 5 }]; + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement-3.rs:11:20 + | +LL | type Array = [u32; { let x = 2; 5 }]; + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement.rs index 281a07808e927..f974a24c26f72 100644 --- a/src/test/ui/consts/const-block-non-item-statement.rs +++ b/src/test/ui/consts/const-block-non-item-statement.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-pass - enum Foo { Bar = { let x = 1; 3 } + //~^ ERROR let bindings in constants are unstable + //~| ERROR statements in constants are unstable + //~| ERROR let bindings in constants are unstable + //~| ERROR statements in constants are unstable } pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement.stderr b/src/test/ui/consts/const-block-non-item-statement.stderr new file mode 100644 index 0000000000000..b367a9d99374e --- /dev/null +++ b/src/test/ui/consts/const-block-non-item-statement.stderr @@ -0,0 +1,35 @@ +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement.rs:12:21 + | +LL | Bar = { let x = 1; 3 } + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement.rs:12:21 + | +LL | Bar = { let x = 1; 3 } + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement.rs:12:11 + | +LL | Bar = { let x = 1; 3 } + | ^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/const-block-non-item-statement.rs:12:11 + | +LL | Bar = { let x = 1; 3 } + | ^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs index ad0dfabebedea..63e5bcccf5d34 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs @@ -12,6 +12,7 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] +#![feature(const_let)] use std::cell::UnsafeCell; @@ -23,7 +24,7 @@ unsafe impl Sync for Foo {} static FOO: Foo = Foo(UnsafeCell::new(42)); static BAR: () = unsafe { - *FOO.0.get() = 5; //~ ERROR static contains unimplemented expression type + *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type }; fn main() {} diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr index 740c1ab0b2d69..740954c6c6623 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr @@ -1,7 +1,7 @@ error[E0019]: static contains unimplemented expression type - --> $DIR/assign-to-static-within-other-static-2.rs:26:5 + --> $DIR/assign-to-static-within-other-static-2.rs:27:5 | -LL | *FOO.0.get() = 5; //~ ERROR static contains unimplemented expression type +LL | *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs index 2f786fb16cc80..6f16f644eec68 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs @@ -12,6 +12,7 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] +#![feature(const_let)] use std::cell::UnsafeCell; diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr index 031a87701266f..ca652c9df32ad 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr @@ -1,5 +1,5 @@ error: cannot mutate statics in the initializer of another static - --> $DIR/assign-to-static-within-other-static.rs:20:5 + --> $DIR/assign-to-static-within-other-static.rs:21:5 | LL | FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static | ^^^^^^^ diff --git a/src/test/ui/consts/const-eval/const_let.rs b/src/test/ui/consts/const-eval/const_let.rs index 3b5014a57b590..602d4da24f383 100644 --- a/src/test/ui/consts/const-eval/const_let.rs +++ b/src/test/ui/consts/const-eval/const_let.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_let)] + fn main() {} struct FakeNeedsDrop; diff --git a/src/test/ui/consts/const-eval/const_let.stderr b/src/test/ui/consts/const-eval/const_let.stderr index f0c17bca36a7c..86e3482fda6b9 100644 --- a/src/test/ui/consts/const-eval/const_let.stderr +++ b/src/test/ui/consts/const-eval/const_let.stderr @@ -1,11 +1,11 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:23:55 + --> $DIR/const_let.rs:25:55 | LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:27:35 + --> $DIR/const_let.rs:29:35 | LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; | ^ diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index 4aad5216442ce..d23b6250b4df2 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_let)] + fn main() { // Tests the Collatz conjecture with an incorrect base case (0 instead of 1). // The value of `n` will loop indefinitely (4 - 2 - 1 - 4). diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 04a3362d95e78..2ff80e5efb57d 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/infinite_loop.rs:17:9 + --> $DIR/infinite_loop.rs:19:9 | LL | / while n != 0 { //~ ERROR constant contains unimplemented expression type LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/infinite_loop.rs:14:18 + --> $DIR/infinite_loop.rs:16:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:18:20 + --> $DIR/infinite_loop.rs:20:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index 970d1a056f330..b21c1827e2ba2 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_let)] + fn main() { let _ = [(); { //~^ WARNING Constant evaluating a complex constant, this might take some time diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 128979a67a912..c0cd98b2fca1e 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52475.rs:16:9 + --> $DIR/issue-52475.rs:18:9 | LL | / while n < 5 { //~ ERROR constant contains unimplemented expression type LL | | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/issue-52475.rs:12:18 + --> $DIR/issue-52475.rs:14:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:17:17 + --> $DIR/issue-52475.rs:19:17 | LL | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs index 8132d26d63b14..6c2fdcc8615c8 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs @@ -12,6 +12,7 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] +#![feature(const_let)] use std::cell::UnsafeCell; @@ -26,7 +27,7 @@ fn foo() {} static BAR: () = unsafe { *FOO.0.get() = 5; - //~^ ERROR static contains unimplemented expression + //~^ contains unimplemented expression foo(); //~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr index eb5e88ad6931d..49b39e2f5c6c9 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr @@ -1,11 +1,11 @@ error[E0019]: static contains unimplemented expression type - --> $DIR/mod-static-with-const-fn.rs:28:5 + --> $DIR/mod-static-with-const-fn.rs:29:5 | LL | *FOO.0.get() = 5; | ^^^^^^^^^^^^^^^^ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/mod-static-with-const-fn.rs:31:5 + --> $DIR/mod-static-with-const-fn.rs:32:5 | LL | foo(); | ^^^^^ diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr index 20e6593f88ae8..7141d7ac8b862 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr @@ -20,6 +20,17 @@ LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR doe LL | } | - temporary value is freed at the end of this statement +error[E0716]: temporary value dropped while borrowed + --> $DIR/promoted_raw_ptr_ops.rs:17:28 + | +LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough +LL | } + | - temporary value is freed at the end of this statement + error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:18:29 | @@ -30,6 +41,6 @@ LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does LL | } | - temporary value is freed at the end of this statement -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs index a9d5d6901522a..6661de4ab2cb5 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.rs +++ b/src/test/ui/consts/const-eval/ub-upvars.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_transmute)] +#![feature(const_transmute,const_let)] #![allow(const_err)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const-fn-destructuring-arg.rs b/src/test/ui/consts/const-fn-destructuring-arg.rs index 8aa6871fa7587..fce1688716d30 100644 --- a/src/test/ui/consts/const-fn-destructuring-arg.rs +++ b/src/test/ui/consts/const-fn-destructuring-arg.rs @@ -8,10 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-pass +// test that certain things are disallowed in constant functions -const fn i((a, b): (u32, u32)) -> u32 { +#![feature(const_fn)] + +// no destructuring +const fn i(( + a, + //~^ ERROR arguments of constant functions can only be immutable by-value bindings + b + //~^ ERROR arguments of constant functions can only be immutable by-value bindings + ): (u32, u32)) -> u32 { a + b + //~^ ERROR let bindings in constant functions are unstable + //~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-destructuring-arg.stderr b/src/test/ui/consts/const-fn-destructuring-arg.stderr new file mode 100644 index 0000000000000..029d63a7720a8 --- /dev/null +++ b/src/test/ui/consts/const-fn-destructuring-arg.stderr @@ -0,0 +1,35 @@ +error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) + --> $DIR/const-fn-destructuring-arg.rs:17:13 + | +LL | a, + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) + --> $DIR/const-fn-destructuring-arg.rs:19:13 + | +LL | b + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-destructuring-arg.rs:22:5 + | +LL | a + b + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-destructuring-arg.rs:22:9 + | +LL | a + b + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.rs b/src/test/ui/consts/const-fn-not-safe-for-const.rs index aee5539980c6e..2f7e2ecaa4e40 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.rs +++ b/src/test/ui/consts/const-fn-not-safe-for-const.rs @@ -37,9 +37,13 @@ const fn get_Y_addr() -> &'static u32 { } const fn get() -> u32 { - let x = 22; - let y = 44; + let x = 22; //~ ERROR let bindings in constant functions are unstable +//~^ ERROR statements in constant functions + let y = 44; //~ ERROR let bindings in constant functions are unstable +//~^ ERROR statements in constant functions x + y +//~^ ERROR let bindings in constant functions are unstable +//~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr index 90a7314b7d1fd..1a8c5f558a212 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr +++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr @@ -16,7 +16,55 @@ error[E0013]: constant functions cannot refer to statics, use a constant instead LL | &Y | ^^ -error: aborting due to 3 previous errors +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:40:13 + | +LL | let x = 22; //~ ERROR let bindings in constant functions are unstable + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:40:13 + | +LL | let x = 22; //~ ERROR let bindings in constant functions are unstable + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:42:13 + | +LL | let y = 44; //~ ERROR let bindings in constant functions are unstable + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:42:13 + | +LL | let y = 44; //~ ERROR let bindings in constant functions are unstable + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:44:5 + | +LL | x + y + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constant functions are unstable (see issue #48821) + --> $DIR/const-fn-not-safe-for-const.rs:44:9 + | +LL | x + y + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 9 previous errors -Some errors occurred: E0013, E0015. +Some errors occurred: E0013, E0015, E0658. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/const_let_assign.rs b/src/test/ui/consts/const_let_assign.rs index 0b09b8469fd75..a3c53a451e106 100644 --- a/src/test/ui/consts/const_let_assign.rs +++ b/src/test/ui/consts/const_let_assign.rs @@ -1,5 +1,7 @@ // compile-pass +#![feature(const_let)] + struct S(i32); const A: () = { diff --git a/src/test/ui/consts/const_let_assign2.rs b/src/test/ui/consts/const_let_assign2.rs index 1c44237e49b7a..0de7396501adc 100644 --- a/src/test/ui/consts/const_let_assign2.rs +++ b/src/test/ui/consts/const_let_assign2.rs @@ -1,5 +1,8 @@ // compile-pass +#![feature(const_let)] +#![feature(const_fn)] + pub struct AA { pub data: [u8; 10], } diff --git a/src/test/ui/consts/const_let_assign3.rs b/src/test/ui/consts/const_let_assign3.rs index dd9690ef858b9..c2ed6cd85ab5c 100644 --- a/src/test/ui/consts/const_let_assign3.rs +++ b/src/test/ui/consts/const_let_assign3.rs @@ -1,3 +1,4 @@ +#![feature(const_let)] #![feature(const_fn)] struct S { @@ -7,7 +8,7 @@ struct S { impl S { const fn foo(&mut self, x: u32) { self.state = x; - //~^ ERROR constant function contains unimplemented expression + //~^ contains unimplemented expression } } diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index 7380906bec7b3..0f294616d255c 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -1,11 +1,11 @@ error[E0019]: constant function contains unimplemented expression type - --> $DIR/const_let_assign3.rs:9:9 + --> $DIR/const_let_assign3.rs:10:9 | LL | self.state = x; | ^^^^^^^^^^^^^^ error[E0017]: references in constants may only refer to immutable values - --> $DIR/const_let_assign3.rs:16:5 + --> $DIR/const_let_assign3.rs:17:5 | LL | s.foo(3); //~ ERROR references in constants may only refer to immutable values | ^ constants require immutable values diff --git a/src/test/ui/consts/const_let_eq.rs b/src/test/ui/consts/const_let_eq.rs index a2364c392f26b..8739cb80e9403 100644 --- a/src/test/ui/consts/const_let_eq.rs +++ b/src/test/ui/consts/const_let_eq.rs @@ -1,3 +1,5 @@ +#![feature(const_let, const_fn)] + // run-pass struct Foo(T); diff --git a/src/test/ui/consts/const_short_circuit.rs b/src/test/ui/consts/const_short_circuit.rs index 9721c1969d577..e644886b923e7 100644 --- a/src/test/ui/consts/const_short_circuit.rs +++ b/src/test/ui/consts/const_short_circuit.rs @@ -1,4 +1,4 @@ -#![feature(underscore_const_names)] +#![feature(underscore_const_names, const_let)] const _: bool = false && false; //~ WARN boolean short circuiting operators in constants const _: bool = true && false; //~ WARN boolean short circuiting operators in constants @@ -13,4 +13,4 @@ const _: bool = { x }; -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/consts/dangling-alloc-id-ice.rs b/src/test/ui/consts/dangling-alloc-id-ice.rs index dbc50f1fbd4b4..695d33b690898 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.rs +++ b/src/test/ui/consts/dangling-alloc-id-ice.rs @@ -1,5 +1,7 @@ // https://github.com/rust-lang/rust/issues/55223 +#![feature(const_let)] + union Foo<'a> { y: &'a (), long_live_the_unit: &'static (), diff --git a/src/test/ui/consts/dangling-alloc-id-ice.stderr b/src/test/ui/consts/dangling-alloc-id-ice.stderr index 2cd8711f03d31..a5fa88e5e6832 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.stderr +++ b/src/test/ui/consts/dangling-alloc-id-ice.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling-alloc-id-ice.rs:8:1 + --> $DIR/dangling-alloc-id-ice.rs:10:1 | LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error LL | | let y = (); diff --git a/src/test/ui/consts/dangling_raw_ptr.rs b/src/test/ui/consts/dangling_raw_ptr.rs index c2d8e6d421a28..7fc773412f2f8 100644 --- a/src/test/ui/consts/dangling_raw_ptr.rs +++ b/src/test/ui/consts/dangling_raw_ptr.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + const FOO: *const u32 = { //~ ERROR any use of this value will cause an error let x = 42; &x diff --git a/src/test/ui/consts/dangling_raw_ptr.stderr b/src/test/ui/consts/dangling_raw_ptr.stderr index 091f1f785cb02..3b20936f8ae97 100644 --- a/src/test/ui/consts/dangling_raw_ptr.stderr +++ b/src/test/ui/consts/dangling_raw_ptr.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling_raw_ptr.rs:1:1 + --> $DIR/dangling_raw_ptr.rs:3:1 | LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error LL | | let x = 42; diff --git a/src/test/ui/consts/issue-54224.rs b/src/test/ui/consts/issue-54224.rs index bb6be37340cf9..b5a8fe8819cdd 100644 --- a/src/test/ui/consts/issue-54224.rs +++ b/src/test/ui/consts/issue-54224.rs @@ -1,8 +1,6 @@ -// compile-pass - #![feature(nll)] -const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); +const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed use std::borrow::Cow; @@ -11,5 +9,6 @@ pub const Y: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[X]); pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); +//~^ ERROR temporary value dropped while borrowed fn main() {} diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr new file mode 100644 index 0000000000000..451f49c1cb57a --- /dev/null +++ b/src/test/ui/consts/issue-54224.stderr @@ -0,0 +1,23 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/issue-54224.rs:3:39 + | +LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed + | ------^^^^^^^^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/issue-54224.rs:11:57 + | +LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); + | ---------------^^^^^^^^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index 39adf088642be..6c4e9e0a067d7 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -112,6 +112,12 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ +error: local variables in const fn are unstable + --> $DIR/min_const_fn.rs:109:34 + | +LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn + | ^ + error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:110:44 | @@ -215,7 +221,7 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 34 previous errors +error: aborting due to 35 previous errors Some errors occurred: E0493, E0515. For more information about an error, try `rustc --explain E0493`. 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 80db24006ec3f..ba6989f8b417a 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 @@ -106,7 +106,7 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize } const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn -const fn foo30_6() -> bool { let x = true; x } +const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn const fn foo36(a: bool, b: bool) -> bool { a && b } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo37(a: bool, b: bool) -> bool { a || b } 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 530282cfea923..a93a4f817fc14 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 @@ -112,6 +112,12 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ +error: local variables in const fn are unstable + --> $DIR/min_const_fn.rs:109:34 + | +LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn + | ^ + error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:110:44 | @@ -202,6 +208,6 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 34 previous errors +error: aborting due to 35 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr deleted file mode 100644 index 7a0cd939c145c..0000000000000 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.nll.stderr +++ /dev/null @@ -1,51 +0,0 @@ -error: mutable references in const fn are unstable - --> $DIR/mutable_borrow.rs:3:9 - | -LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable - | ^ - -error: mutable references in const fn are unstable - --> $DIR/mutable_borrow.rs:12:13 - | -LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable - | ^ - -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:19:13 - | -LL | let b = &mut a; //~ references in statics may only refer to immutable - | ^^^^^^ statics require immutable values - -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:26:15 - | -LL | { let b = &mut a; } //~ references in statics may only refer to immutable - | ^^^^^^ statics require immutable values - -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:37:17 - | -LL | let mut a = &mut None; //~ references in statics may only refer to immutable values - | ^^^^^^^^^ statics require immutable values - -error[E0019]: static contains unimplemented expression type - --> $DIR/mutable_borrow.rs:39:5 - | -LL | *a = Some(Foo); //~ unimplemented expression type - | ^^ - -error[E0716]: temporary value dropped while borrowed - --> $DIR/mutable_borrow.rs:37:22 - | -LL | let mut a = &mut None; //~ references in statics may only refer to immutable values - | ^^^^ creates a temporary which is freed while still in use -... -LL | a - | - using this value as a static requires that borrow lasts for `'static` -LL | }; - | - temporary value is freed at the end of this statement - -error: aborting due to 7 previous errors - -Some errors occurred: E0017, E0019, E0716. -For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.rs b/src/test/ui/consts/min_const_fn/mutable_borrow.rs index d9a4164aa13eb..3dd76b630a883 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.rs +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.rs @@ -1,6 +1,6 @@ const fn mutable_ref_in_const() -> u8 { - let mut a = 0; - let b = &mut a; //~ ERROR mutable references in const fn are unstable + let mut a = 0; //~ ERROR local variables in const fn + let b = &mut a; *b } @@ -8,36 +8,10 @@ struct X; impl X { const fn inherent_mutable_ref_in_const() -> u8 { - let mut a = 0; - let b = &mut a; //~ ERROR mutable references in const fn are unstable + let mut a = 0; //~ ERROR local variables in const fn + let b = &mut a; *b } } -static mut FOO: u32 = { - let mut a = 0; - let b = &mut a; //~ references in statics may only refer to immutable - *b -}; - -static mut BAR: Option = { - let mut a = None; - // taking a mutable reference erases everything we know about `a` - { let b = &mut a; } //~ references in statics may only refer to immutable - a -}; - -struct Foo; - -impl Drop for Foo { - fn drop(&mut self) {} -} - -static mut BAR2: &mut Option = { - let mut a = &mut None; //~ references in statics may only refer to immutable values - //~^ does not live long enough - *a = Some(Foo); //~ unimplemented expression type - a -}; - fn main() {} diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr index ac61949019744..fa46f5c804fe0 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -1,51 +1,14 @@ -error: mutable references in const fn are unstable - --> $DIR/mutable_borrow.rs:3:9 +error: local variables in const fn are unstable + --> $DIR/mutable_borrow.rs:2:9 | -LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable - | ^ +LL | let mut a = 0; //~ ERROR local variables in const fn + | ^^^^^ -error: mutable references in const fn are unstable - --> $DIR/mutable_borrow.rs:12:13 +error: local variables in const fn are unstable + --> $DIR/mutable_borrow.rs:11:13 | -LL | let b = &mut a; //~ ERROR mutable references in const fn are unstable - | ^ +LL | let mut a = 0; //~ ERROR local variables in const fn + | ^^^^^ -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:19:13 - | -LL | let b = &mut a; //~ references in statics may only refer to immutable - | ^^^^^^ statics require immutable values - -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:26:15 - | -LL | { let b = &mut a; } //~ references in statics may only refer to immutable - | ^^^^^^ statics require immutable values - -error[E0017]: references in statics may only refer to immutable values - --> $DIR/mutable_borrow.rs:37:17 - | -LL | let mut a = &mut None; //~ references in statics may only refer to immutable values - | ^^^^^^^^^ statics require immutable values - -error[E0019]: static contains unimplemented expression type - --> $DIR/mutable_borrow.rs:39:5 - | -LL | *a = Some(Foo); //~ unimplemented expression type - | ^^ - -error[E0597]: borrowed value does not live long enough - --> $DIR/mutable_borrow.rs:37:22 - | -LL | let mut a = &mut None; //~ references in statics may only refer to immutable values - | ^^^^ temporary value does not live long enough -... -LL | }; - | - temporary value only lives until here - | - = note: borrowed value must be valid for the static lifetime... - -error: aborting due to 7 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0017, E0019, E0597. -For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/partial_qualif.rs b/src/test/ui/consts/partial_qualif.rs index 32c68e69f4bed..4ce41f80f82c8 100644 --- a/src/test/ui/consts/partial_qualif.rs +++ b/src/test/ui/consts/partial_qualif.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + use std::cell::Cell; const FOO: &(Cell, bool) = { diff --git a/src/test/ui/consts/partial_qualif.stderr b/src/test/ui/consts/partial_qualif.stderr index 967fb83b78b08..d695f64e2c3b5 100644 --- a/src/test/ui/consts/partial_qualif.stderr +++ b/src/test/ui/consts/partial_qualif.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/partial_qualif.rs:6:5 + --> $DIR/partial_qualif.rs:8:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 411cdff3d24d4..5863429a2f2c5 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + use std::cell::Cell; const FOO: &u32 = { @@ -5,7 +7,7 @@ const FOO: &u32 = { { let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants - //~^ ERROR constant contains unimplemented expression + //~^ contains unimplemented expression } &{a} }; diff --git a/src/test/ui/consts/projection_qualif.stderr b/src/test/ui/consts/projection_qualif.stderr index 410c51c4b54e1..cc3635a979b37 100644 --- a/src/test/ui/consts/projection_qualif.stderr +++ b/src/test/ui/consts/projection_qualif.stderr @@ -1,17 +1,17 @@ error[E0017]: references in constants may only refer to immutable values - --> $DIR/projection_qualif.rs:6:27 + --> $DIR/projection_qualif.rs:8:27 | LL | let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values | ^^^^^^ constants require immutable values error[E0019]: constant contains unimplemented expression type - --> $DIR/projection_qualif.rs:7:18 + --> $DIR/projection_qualif.rs:9:18 | LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants | ^^^^^^ error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911) - --> $DIR/projection_qualif.rs:7:18 + --> $DIR/projection_qualif.rs:9:18 | LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants | ^^^^^^ diff --git a/src/test/ui/consts/promote_const_let.nll.stderr b/src/test/ui/consts/promote_const_let.nll.stderr index 1fc345d5a12fe..d8749bb5fd90b 100644 --- a/src/test/ui/consts/promote_const_let.nll.stderr +++ b/src/test/ui/consts/promote_const_let.nll.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:4:9 + --> $DIR/promote_const_let.rs:6:9 | LL | let x: &'static u32 = { | ------------ type annotation requires that `y` is borrowed for `'static` diff --git a/src/test/ui/consts/promote_const_let.rs b/src/test/ui/consts/promote_const_let.rs index cbebe84d9058c..8de9b00eb111d 100644 --- a/src/test/ui/consts/promote_const_let.rs +++ b/src/test/ui/consts/promote_const_let.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + fn main() { let x: &'static u32 = { let y = 42; diff --git a/src/test/ui/consts/promote_const_let.stderr b/src/test/ui/consts/promote_const_let.stderr index 2ec4ad90855a2..6bbb7495fb0dc 100644 --- a/src/test/ui/consts/promote_const_let.stderr +++ b/src/test/ui/consts/promote_const_let.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:4:10 + --> $DIR/promote_const_let.rs:6:10 | LL | &y //~ ERROR does not live long enough | ^ borrowed value does not live long enough diff --git a/src/test/ui/consts/qualif_overwrite.rs b/src/test/ui/consts/qualif_overwrite.rs index 430eea37de73c..806a74ee4530b 100644 --- a/src/test/ui/consts/qualif_overwrite.rs +++ b/src/test/ui/consts/qualif_overwrite.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + use std::cell::Cell; // this is overly conservative. The reset to `None` should clear `a` of all qualifications diff --git a/src/test/ui/consts/qualif_overwrite.stderr b/src/test/ui/consts/qualif_overwrite.stderr index 30479139e314c..4fac64bf8063f 100644 --- a/src/test/ui/consts/qualif_overwrite.stderr +++ b/src/test/ui/consts/qualif_overwrite.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite.rs:10:5 + --> $DIR/qualif_overwrite.rs:12:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/qualif_overwrite_2.rs b/src/test/ui/consts/qualif_overwrite_2.rs index fa79b5c14a736..29557a3da4781 100644 --- a/src/test/ui/consts/qualif_overwrite_2.rs +++ b/src/test/ui/consts/qualif_overwrite_2.rs @@ -1,3 +1,5 @@ +#![feature(const_let)] + use std::cell::Cell; // const qualification is not smart enough to know about fields and always assumes that there might diff --git a/src/test/ui/consts/qualif_overwrite_2.stderr b/src/test/ui/consts/qualif_overwrite_2.stderr index 8276db99a12c0..181b728c7b76f 100644 --- a/src/test/ui/consts/qualif_overwrite_2.stderr +++ b/src/test/ui/consts/qualif_overwrite_2.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite_2.rs:8:5 + --> $DIR/qualif_overwrite_2.rs:10:5 | LL | &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^^^ diff --git a/src/test/ui/error-codes/E0010-teach.rs b/src/test/ui/error-codes/E0010-teach.rs index 13371175f9caa..e5ccf32af1473 100644 --- a/src/test/ui/error-codes/E0010-teach.rs +++ b/src/test/ui/error-codes/E0010-teach.rs @@ -14,6 +14,5 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 -//~^ ERROR contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr index 670698891d428..fa5c767caf24d 100644 --- a/src/test/ui/error-codes/E0010-teach.stderr +++ b/src/test/ui/error-codes/E0010-teach.stderr @@ -6,16 +6,6 @@ LL | const CON : Box = box 0; //~ ERROR E0010 | = note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. -error[E0019]: constant contains unimplemented expression type - --> $DIR/E0010-teach.rs:16:28 - | -LL | const CON : Box = box 0; //~ ERROR E0010 - | ^ - | - = note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time. - = note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else. - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0010, E0019. -For more information about an error, try `rustc --explain E0010`. +For more information about this error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0010.rs b/src/test/ui/error-codes/E0010.rs index 7a80b335c5619..66a9319a7df43 100644 --- a/src/test/ui/error-codes/E0010.rs +++ b/src/test/ui/error-codes/E0010.rs @@ -12,6 +12,5 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 -//~^ ERROR contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr index 01295469b2bb2..83c1b409a5174 100644 --- a/src/test/ui/error-codes/E0010.stderr +++ b/src/test/ui/error-codes/E0010.stderr @@ -4,13 +4,6 @@ error[E0010]: allocations are not allowed in constants LL | const CON : Box = box 0; //~ ERROR E0010 | ^^^^^ allocation not allowed in constants -error[E0019]: constant contains unimplemented expression type - --> $DIR/E0010.rs:14:28 - | -LL | const CON : Box = box 0; //~ ERROR E0010 - | ^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0010, E0019. -For more information about an error, try `rustc --explain E0010`. +For more information about this error, try `rustc --explain E0010`. diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs index 3724eaf61ca0a..b283e28651487 100644 --- a/src/test/ui/feature-gate-underscore_const_names.rs +++ b/src/test/ui/feature-gate-underscore_const_names.rs @@ -7,6 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_let)] trait Trt {} struct Str {} diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr index 050ad8710309e..ab90ef8f11f7c 100644 --- a/src/test/ui/feature-gate-underscore_const_names.stderr +++ b/src/test/ui/feature-gate-underscore_const_names.stderr @@ -1,5 +1,5 @@ error[E0658]: naming constants with `_` is unstable (see issue #54912) - --> $DIR/feature-gate-underscore_const_names.rs:16:1 + --> $DIR/feature-gate-underscore_const_names.rs:17:1 | LL | / const _ : () = { LL | | use std::marker::PhantomData; diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs new file mode 100644 index 0000000000000..9bf957a5f1e05 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-const_let.rs @@ -0,0 +1,31 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test use of const let without feature gate. + +const FOO: usize = { + //~^ ERROR statements in constants are unstable + //~| ERROR: let bindings in constants are unstable + let x = 42; + //~^ ERROR statements in constants are unstable + //~| ERROR: let bindings in constants are unstable + 42 +}; + +static BAR: usize = { + //~^ ERROR statements in statics are unstable + //~| ERROR: let bindings in statics are unstable + let x = 42; + //~^ ERROR statements in statics are unstable + //~| ERROR: let bindings in statics are unstable + 42 +}; + +fn main() {} diff --git a/src/test/ui/issues/issue-18118.nll.stderr b/src/test/ui/issues/issue-18118.nll.stderr index 9529b60c1b6ad..9e680e87f79a8 100644 --- a/src/test/ui/issues/issue-18118.nll.stderr +++ b/src/test/ui/issues/issue-18118.nll.stderr @@ -1,14 +1,68 @@ +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:15:17 + | +LL | let p = 3; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:15:17 + | +LL | let p = 3; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:18:9 + | +LL | &p //~ ERROR `p` does not live long enough + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:12:5 + | +LL | / const z: &'static isize = { +LL | | //~^ ERROR let bindings in constants are unstable +LL | | //~| ERROR statements in constants are unstable +LL | | let p = 3; +... | +LL | | //~^ ERROR let bindings in constants are unstable +LL | | }; + | |______^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:12:5 + | +LL | / const z: &'static isize = { +LL | | //~^ ERROR let bindings in constants are unstable +LL | | //~| ERROR statements in constants are unstable +LL | | let p = 3; +... | +LL | | //~^ ERROR let bindings in constants are unstable +LL | | }; + | |______^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:14:9 + --> $DIR/issue-18118.rs:18:9 | LL | &p //~ ERROR `p` does not live long enough | ^^ | | | borrowed value does not live long enough | using this value as a constant requires that `p` is borrowed for `'static` +LL | //~^ ERROR let bindings in constants are unstable LL | }; | - `p` dropped here while still borrowed -error: aborting due to previous error +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0597`. +Some errors occurred: E0597, E0658. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-18118.rs b/src/test/ui/issues/issue-18118.rs index 05e46230db29a..7194c159c1e98 100644 --- a/src/test/ui/issues/issue-18118.rs +++ b/src/test/ui/issues/issue-18118.rs @@ -10,7 +10,12 @@ pub fn main() { const z: &'static isize = { + //~^ ERROR let bindings in constants are unstable + //~| ERROR statements in constants are unstable let p = 3; + //~^ ERROR let bindings in constants are unstable + //~| ERROR statements in constants are unstable &p //~ ERROR `p` does not live long enough + //~^ ERROR let bindings in constants are unstable }; } diff --git a/src/test/ui/issues/issue-18118.stderr b/src/test/ui/issues/issue-18118.stderr index 4f755745b2857..2d83b86e5f40b 100644 --- a/src/test/ui/issues/issue-18118.stderr +++ b/src/test/ui/issues/issue-18118.stderr @@ -1,13 +1,67 @@ +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:15:17 + | +LL | let p = 3; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:15:17 + | +LL | let p = 3; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:18:9 + | +LL | &p //~ ERROR `p` does not live long enough + | ^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: let bindings in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:12:5 + | +LL | / const z: &'static isize = { +LL | | //~^ ERROR let bindings in constants are unstable +LL | | //~| ERROR statements in constants are unstable +LL | | let p = 3; +... | +LL | | //~^ ERROR let bindings in constants are unstable +LL | | }; + | |______^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-18118.rs:12:5 + | +LL | / const z: &'static isize = { +LL | | //~^ ERROR let bindings in constants are unstable +LL | | //~| ERROR statements in constants are unstable +LL | | let p = 3; +... | +LL | | //~^ ERROR let bindings in constants are unstable +LL | | }; + | |______^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:14:10 + --> $DIR/issue-18118.rs:18:10 | LL | &p //~ ERROR `p` does not live long enough | ^ borrowed value does not live long enough +LL | //~^ ERROR let bindings in constants are unstable LL | }; | - borrowed value only lives until here | = note: borrowed value must be valid for the static lifetime... -error: aborting due to previous error +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0597`. +Some errors occurred: E0597, E0658. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-32829-2.rs b/src/test/ui/issues/issue-32829-2.rs index b5026d8c5e1e5..2b223bac8e67b 100644 --- a/src/test/ui/issues/issue-32829-2.rs +++ b/src/test/ui/issues/issue-32829-2.rs @@ -15,6 +15,7 @@ const bad : u32 = { { 5; + //~^ ERROR statements in constants are unstable 0 } }; @@ -22,7 +23,8 @@ const bad : u32 = { const bad_two : u32 = { { invalid(); - //~^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants + //~^ ERROR statements in constants are unstable + //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -30,6 +32,7 @@ const bad_two : u32 = { const bad_three : u32 = { { valid(); + //~^ ERROR statements in constants are unstable 0 } }; @@ -37,6 +40,7 @@ const bad_three : u32 = { static bad_four : u32 = { { 5; + //~^ ERROR statements in statics are unstable 0 } }; @@ -45,6 +49,7 @@ static bad_five : u32 = { { invalid(); //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants + //~| ERROR statements in statics are unstable 0 } }; @@ -52,6 +57,7 @@ static bad_five : u32 = { static bad_six : u32 = { { valid(); + //~^ ERROR statements in statics are unstable 0 } }; @@ -59,6 +65,7 @@ static bad_six : u32 = { static mut bad_seven : u32 = { { 5; + //~^ ERROR statements in statics are unstable 0 } }; @@ -66,7 +73,8 @@ static mut bad_seven : u32 = { static mut bad_eight : u32 = { { invalid(); - //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants + //~^ ERROR statements in statics are unstable + //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -74,6 +82,7 @@ static mut bad_eight : u32 = { static mut bad_nine : u32 = { { valid(); + //~^ ERROR statements in statics are unstable 0 } }; diff --git a/src/test/ui/issues/issue-32829-2.stderr b/src/test/ui/issues/issue-32829-2.stderr index 5e5cdf8adda2c..6d6b94ca4bc6d 100644 --- a/src/test/ui/issues/issue-32829-2.stderr +++ b/src/test/ui/issues/issue-32829-2.stderr @@ -1,21 +1,94 @@ +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:17:9 + | +LL | 5; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:24:9 + --> $DIR/issue-32829-2.rs:25:9 | LL | invalid(); | ^^^^^^^^^ +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:25:9 + | +LL | invalid(); + | ^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in constants are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:34:9 + | +LL | valid(); + | ^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:42:9 + | +LL | 5; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:46:9 + --> $DIR/issue-32829-2.rs:50:9 | LL | invalid(); | ^^^^^^^^^ +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:50:9 + | +LL | invalid(); + | ^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:59:9 + | +LL | valid(); + | ^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:67:9 + | +LL | 5; + | ^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:68:9 + --> $DIR/issue-32829-2.rs:75:9 | LL | invalid(); | ^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:75:9 + | +LL | invalid(); + | ^^^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error[E0658]: statements in statics are unstable (see issue #48821) + --> $DIR/issue-32829-2.rs:84:9 + | +LL | valid(); + | ^^^^^^^ + | + = help: add #![feature(const_let)] to the crate attributes to enable + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors occurred: E0015, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/issues/issue-37550.rs b/src/test/ui/issues/issue-37550.rs index f6861b459d70e..a2f40b3f5396c 100644 --- a/src/test/ui/issues/issue-37550.rs +++ b/src/test/ui/issues/issue-37550.rs @@ -9,8 +9,8 @@ // except according to those terms. const fn x() { - let t = true; - let x = || t; //~ ERROR function pointers in const fn are unstable + let t = true; //~ ERROR local variables in const fn + let x = || t; } fn main() {} diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr index 5b530de33f653..5a7d1ad043ee4 100644 --- a/src/test/ui/issues/issue-37550.stderr +++ b/src/test/ui/issues/issue-37550.stderr @@ -1,7 +1,7 @@ -error: function pointers in const fn are unstable - --> $DIR/issue-37550.rs:13:9 +error: local variables in const fn are unstable + --> $DIR/issue-37550.rs:12:9 | -LL | let x = || t; //~ ERROR function pointers in const fn are unstable +LL | let t = true; //~ ERROR local variables in const fn | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs index fca4fb62fad22..801a1301ad774 100644 --- a/src/test/ui/issues/issue-7364.rs +++ b/src/test/ui/issues/issue-7364.rs @@ -16,6 +16,5 @@ use std::cell::RefCell; static boxed: Box> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics //~| ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] -//~| ERROR contains unimplemented expression type fn main() { } diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr index b6594b1caca2c..b0d732bdb6fa6 100644 --- a/src/test/ui/issues/issue-7364.stderr +++ b/src/test/ui/issues/issue-7364.stderr @@ -4,12 +4,6 @@ error[E0010]: allocations are not allowed in statics LL | static boxed: Box> = box RefCell::new(0); | ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/issue-7364.rs:16:41 - | -LL | static boxed: Box> = box RefCell::new(0); - | ^^^^^^^^^^^^^^^ - error[E0277]: `std::cell::RefCell` cannot be shared between threads safely --> $DIR/issue-7364.rs:16:1 | @@ -21,7 +15,7 @@ LL | static boxed: Box> = box RefCell::new(0); = note: required because it appears within the type `std::boxed::Box>` = note: shared static variables must have a type that implements `Sync` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0010, E0019, E0277. +Some errors occurred: E0010, E0277. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs index a25236b53b51f..7e6ced12fe69a 100644 --- a/src/test/ui/static/static-mut-not-constant.rs +++ b/src/test/ui/static/static-mut-not-constant.rs @@ -12,6 +12,5 @@ static mut a: Box = box 3; //~^ ERROR allocations are not allowed in statics -//~| ERROR static contains unimplemented expression fn main() {} diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr index d9250e85d3e3f..ad44121e76316 100644 --- a/src/test/ui/static/static-mut-not-constant.stderr +++ b/src/test/ui/static/static-mut-not-constant.stderr @@ -4,13 +4,6 @@ error[E0010]: allocations are not allowed in statics LL | static mut a: Box = box 3; | ^^^^^ allocation not allowed in statics -error[E0019]: static contains unimplemented expression type - --> $DIR/static-mut-not-constant.rs:13:32 - | -LL | static mut a: Box = box 3; - | ^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0010, E0019. -For more information about an error, try `rustc --explain E0010`. +For more information about this error, try `rustc --explain E0010`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs index bb123f46a5772..8d31fd0b1e93d 100644 --- a/src/test/ui/underscore_const_names.rs +++ b/src/test/ui/underscore_const_names.rs @@ -10,6 +10,7 @@ // compile-pass +#![feature(const_let)] #![feature(underscore_const_names)] trait Trt {} diff --git a/src/test/ui/write-to-static-mut-in-static.rs b/src/test/ui/write-to-static-mut-in-static.rs index 9a570a4381b32..191f09b54ee73 100644 --- a/src/test/ui/write-to-static-mut-in-static.rs +++ b/src/test/ui/write-to-static-mut-in-static.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_let)] + pub static mut A: u32 = 0; pub static mut B: () = unsafe { A = 1; }; //~^ ERROR cannot mutate statics in the initializer of another static diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index e7233c5b8a5e0..673a71b4642f3 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -1,11 +1,11 @@ error: cannot mutate statics in the initializer of another static - --> $DIR/write-to-static-mut-in-static.rs:12:33 + --> $DIR/write-to-static-mut-in-static.rs:14:33 | LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ error: cannot mutate statics in the initializer of another static - --> $DIR/write-to-static-mut-in-static.rs:15:34 + --> $DIR/write-to-static-mut-in-static.rs:17:34 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^ From 16d2a92b3d1ee85344eb956a6b1667ef1d1c65bd Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 26 Nov 2018 17:30:19 +0100 Subject: [PATCH 14/25] Improve the diagnostic message --- src/librustc/mir/mod.rs | 6 ++- src/librustc/ty/structural_impls.rs | 1 + src/librustc_mir/hair/cx/expr.rs | 29 +++---------- src/librustc_mir/hair/cx/mod.rs | 6 +-- src/librustc_mir/shim.rs | 8 ++-- src/librustc_mir/transform/promote_consts.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 25 ++++++++--- src/test/run-pass/ctfe/issue-37550.rs | 2 +- src/test/ui/consts/const_short_circuit.rs | 12 +++--- src/test/ui/consts/const_short_circuit.stderr | 42 +++++++------------ 10 files changed, 61 insertions(+), 72 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3968d9aece210..faecb7013b492 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -153,7 +153,9 @@ pub struct Mir<'tcx> { /// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop /// this conversion from happening and use short circuiting, we will cause the following code /// to change the value of `x`: `let mut x = 42; false && { x = 55; true };` - pub control_flow_destroyed: bool, + /// + /// List of places where control flow was destroyed. Used for error reporting. + pub control_flow_destroyed: Vec<(Span, String)>, /// A span representing this MIR, for error reporting pub span: Span, @@ -173,7 +175,7 @@ impl<'tcx> Mir<'tcx> { arg_count: usize, upvar_decls: Vec, span: Span, - control_flow_destroyed: bool, + control_flow_destroyed: Vec<(Span, String)>, ) -> Self { // We need `arg_count` locals, and one for the return place assert!( diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index d6aeb288b5cdc..1d28c4fa114ef 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -35,6 +35,7 @@ CloneTypeFoldableAndLiftImpls! { usize, ::ty::layout::VariantIdx, u64, + String, ::middle::region::Scope, ::syntax::ast::FloatTy, ::syntax::ast::NodeId, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index b058748fca024..81cccd9fd530b 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -23,7 +23,6 @@ use rustc::hir; use rustc::hir::def_id::LocalDefId; use rustc::mir::{BorrowKind}; use syntax_pos::Span; -use syntax::errors::Applicability; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; @@ -373,18 +372,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // FIXME(eddyb) use logical ops in constants when // they can handle that kind of control-flow. (hir::BinOpKind::And, hir::Constness::Const) => { - cx.control_flow_destroyed = true; - cx.tcx.sess.struct_span_warn( + cx.control_flow_destroyed.push(( op.span, - "boolean short circuiting operators in constants do \ - not actually short circuit. Thus new const eval features \ - are not accessible in constants." - ).span_suggestion_with_applicability( - op.span, - "use a bit operator instead", - "&".into(), - Applicability::MachineApplicable, - ).emit(); + "`&&` operator".into(), + )); ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), @@ -392,18 +383,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } (hir::BinOpKind::Or, hir::Constness::Const) => { - cx.control_flow_destroyed = true; - cx.tcx.sess.struct_span_warn( - op.span, - "boolean short circuiting operators in constants do \ - not actually short circuit. Thus new const eval features \ - are not accessible in constants." - ).span_suggestion_with_applicability( + cx.control_flow_destroyed.push(( op.span, - "use a bit operator instead", - "|".into(), - Applicability::MachineApplicable, - ).emit(); + "`||` operator".into(), + )); ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 76dde4ed02bc3..a7924b7b73876 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -58,7 +58,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { check_overflow: bool, /// See field with the same name on `Mir` - control_flow_destroyed: bool, + control_flow_destroyed: Vec<(Span, String)>, } impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { @@ -99,11 +99,11 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { constness, body_owner_kind, check_overflow, - control_flow_destroyed: false, + control_flow_destroyed: Vec::new(), } } - pub fn control_flow_destroyed(&self) -> bool { + pub fn control_flow_destroyed(self) -> Vec<(Span, String)> { self.control_flow_destroyed } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 5a08165608d53..9d90dc2931afa 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -220,7 +220,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sig.inputs().len(), vec![], span, - true, + vec![], ); if let Some(..) = ty { @@ -389,7 +389,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { self.sig.inputs().len(), vec![], self.span, - true, + vec![], ) } @@ -838,7 +838,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sig.inputs().len(), vec![], span, - true, + vec![], ); if let Abi::RustCall = sig.abi { mir.spread_arg = Some(Local::new(sig.inputs().len())); @@ -916,6 +916,6 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, sig.inputs().len(), vec![], span, - true, + vec![], ) } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 3a0094bcd625a..15a82fcadc1f2 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -413,7 +413,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, 0, vec![], mir.span, - false, + vec![], ), tcx, source: mir, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 0f174d6da1fc3..e49134409f0c6 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1335,17 +1335,32 @@ impl MirPass for QualifyAndPromoteConstants { // Do the actual promotion, now that we know what's viable. promote_consts::promote_candidates(mir, tcx, temps, candidates); } else { - if mir.control_flow_destroyed { - for local in mir.vars_iter() { + if !mir.control_flow_destroyed.is_empty() { + let mut locals = mir.vars_iter(); + if let Some(local) = locals.next() { let span = mir.local_decls[local].source_info.span; - tcx.sess.span_err( + let mut error = tcx.sess.struct_span_err( span, &format!( - "short circuiting operators do not actually short circuit in {}. \ - Thus new features like let bindings are not permitted", + "new features like let bindings are not permitted in {} \ + which also use short circuiting operators", mode, ), ); + for (span, kind) in mir.control_flow_destroyed.iter() { + error.span_note( + *span, + &format!("use of {} here", kind), + ); + } + for local in locals { + let span = mir.local_decls[local].source_info.span; + error.span_note( + span, + "more locals defined here", + ); + } + error.emit(); } } let promoted_temps = if mode == Mode::Const { diff --git a/src/test/run-pass/ctfe/issue-37550.rs b/src/test/run-pass/ctfe/issue-37550.rs index 2d278d115d5b6..54e0e83efed3a 100644 --- a/src/test/run-pass/ctfe/issue-37550.rs +++ b/src/test/run-pass/ctfe/issue-37550.rs @@ -12,7 +12,7 @@ #![allow(dead_code)] #![allow(unused_variables)] -#![feature(const_fn)] +#![feature(const_fn, const_let)] const fn x() { let t = true; diff --git a/src/test/ui/consts/const_short_circuit.rs b/src/test/ui/consts/const_short_circuit.rs index e644886b923e7..cc49e4696e58f 100644 --- a/src/test/ui/consts/const_short_circuit.rs +++ b/src/test/ui/consts/const_short_circuit.rs @@ -1,15 +1,15 @@ #![feature(underscore_const_names, const_let)] -const _: bool = false && false; //~ WARN boolean short circuiting operators in constants -const _: bool = true && false; //~ WARN boolean short circuiting operators in constants +const _: bool = false && false; +const _: bool = true && false; const _: bool = { - let mut x = true && false; //~ WARN boolean short circuiting operators in constants - //~^ ERROR short circuiting operators do not actually short circuit in constant + let mut x = true && false; + //~^ ERROR new features like let bindings are not permitted x }; const _: bool = { - let x = true && false; //~ WARN boolean short circuiting operators in constants - //~^ ERROR short circuiting operators do not actually short circuit in constant + let x = true && false; + //~^ ERROR new features like let bindings are not permitted x }; diff --git a/src/test/ui/consts/const_short_circuit.stderr b/src/test/ui/consts/const_short_circuit.stderr index 4c1e531ea8727..6f8fca60c8098 100644 --- a/src/test/ui/consts/const_short_circuit.stderr +++ b/src/test/ui/consts/const_short_circuit.stderr @@ -1,38 +1,26 @@ -warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. - --> $DIR/const_short_circuit.rs:3:23 - | -LL | const _: bool = false && false; //~ WARN boolean short circuiting operators in constants - | ^^ help: use a bit operator instead: `&` - -warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. - --> $DIR/const_short_circuit.rs:4:22 - | -LL | const _: bool = true && false; //~ WARN boolean short circuiting operators in constants - | ^^ help: use a bit operator instead: `&` - -warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. - --> $DIR/const_short_circuit.rs:6:22 - | -LL | let mut x = true && false; //~ WARN boolean short circuiting operators in constants - | ^^ help: use a bit operator instead: `&` - -error: short circuiting operators do not actually short circuit in constant. Thus new features like let bindings are not permitted +error: new features like let bindings are not permitted in constant which also use short circuiting operators --> $DIR/const_short_circuit.rs:6:9 | -LL | let mut x = true && false; //~ WARN boolean short circuiting operators in constants +LL | let mut x = true && false; | ^^^^^ - -warning: boolean short circuiting operators in constants do not actually short circuit. Thus new const eval features are not accessible in constants. - --> $DIR/const_short_circuit.rs:11:18 | -LL | let x = true && false; //~ WARN boolean short circuiting operators in constants - | ^^ help: use a bit operator instead: `&` +note: use of `&&` operator here + --> $DIR/const_short_circuit.rs:6:22 + | +LL | let mut x = true && false; + | ^^ -error: short circuiting operators do not actually short circuit in constant. Thus new features like let bindings are not permitted +error: new features like let bindings are not permitted in constant which also use short circuiting operators --> $DIR/const_short_circuit.rs:11:9 | -LL | let x = true && false; //~ WARN boolean short circuiting operators in constants +LL | let x = true && false; | ^ + | +note: use of `&&` operator here + --> $DIR/const_short_circuit.rs:11:18 + | +LL | let x = true && false; + | ^^ error: aborting due to 2 previous errors From ac47bd725ff6e9d0359acd2ac794232f94105d0c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 27 Nov 2018 09:43:16 +0100 Subject: [PATCH 15/25] Fix a compile-fail test --- src/test/compile-fail/const-fn-error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/const-fn-error.rs b/src/test/compile-fail/const-fn-error.rs index 759f0e50eccdd..397bc7efd633c 100644 --- a/src/test/compile-fail/const-fn-error.rs +++ b/src/test/compile-fail/const-fn-error.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(const_fn, const_let)] const X : usize = 2; From 25d1c073d199bfc58af311e8e84da173e22c6f44 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 27 Nov 2018 11:00:44 +0100 Subject: [PATCH 16/25] Remove unused feature gate from `libcore` --- src/libcore/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index ae223941778e7..d62f6b172580a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -120,7 +120,6 @@ #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] -#![cfg_attr(stage0, feature(const_let))] #![feature(const_int_rotate)] #![feature(const_int_wrapping)] #![feature(const_int_sign)] From 172b428881b2c3d5229dcd6fa7901c32c93089d8 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 27 Nov 2018 11:04:59 +0100 Subject: [PATCH 17/25] Re-add accidentally deleted test --- src/test/ui/issues/issue-44056.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/ui/issues/issue-44056.rs diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs new file mode 100644 index 0000000000000..e76f3bcb2b955 --- /dev/null +++ b/src/test/ui/issues/issue-44056.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass +// only-x86_64 +// no-prefer-dynamic +// compile-flags: -Ctarget-feature=+avx -Clto + +fn main() {} \ No newline at end of file From 42e5317f1d24d117afad5e77c0ac98eee41a714d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 27 Nov 2018 11:13:39 +0100 Subject: [PATCH 18/25] Add trailing newline --- src/test/ui/issues/issue-44056.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs index e76f3bcb2b955..b2f0e917749d5 100644 --- a/src/test/ui/issues/issue-44056.rs +++ b/src/test/ui/issues/issue-44056.rs @@ -13,4 +13,4 @@ // no-prefer-dynamic // compile-flags: -Ctarget-feature=+avx -Clto -fn main() {} \ No newline at end of file +fn main() {} From 9d2f97be78506fb57b4fce6d3c9207b1ec50143c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 27 Nov 2018 12:39:19 +0100 Subject: [PATCH 19/25] Test float assign ops --- src/test/ui/consts/const_let_eq_float.rs | 279 +++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 src/test/ui/consts/const_let_eq_float.rs diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs new file mode 100644 index 0000000000000..2c7262df367a3 --- /dev/null +++ b/src/test/ui/consts/const_let_eq_float.rs @@ -0,0 +1,279 @@ +// compile-pass + +#![feature(const_let, const_fn)] + +struct Foo(T); +struct Bar { x: T } +struct W(f32); +struct A { a: f32 } + +const fn basics((a,): (f32,)) -> f32 { + // Deferred assignment: + let b: f32; + b = a + 1.0; + + // Immediate assignment: + let c: f32 = b + 1.0; + + // Mutables: + let mut d: f32 = c + 1.0; + d = d + 1.0; + // +4 so far. + + // No effect statements work: + ; ; + 1; + + // Array projection + let mut arr: [f32; 1] = [0.0]; + arr[0] = 1.0; + d = d + arr[0]; + // +5 + + // Field projection: + let mut foo: Foo = Foo(0.0); + let mut bar: Bar = Bar { x: 0.0 }; + foo.0 = 1.0; + bar.x = 1.0; + d = d + foo.0 + bar.x; + // +7 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0.0)]; + arr[0].0 = 1.0; + d = d + arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0.0 }]; + arr[0].x = 1.0; + d = d + arr[0].x; + // +9 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([0.0]); + (arr.0)[0] = 1.0; + d = d + (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; + arr.x[0] = 1.0; + d = d + arr.x[0]; + // +11 + + d +} + +const fn add_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a + 1.0; + d += 1.0; + // +2 so far. + + // Array projection + let mut arr: [f32; 1] = [0.0]; + arr[0] += 1.0; + d += arr[0]; + // +3 + + // Field projection: + let mut foo: Foo = Foo(0.0); + let mut bar: Bar = Bar { x: 0.0 }; + foo.0 += 1.0; + bar.x += 1.0; + d += foo.0 + bar.x; + // +5 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0.0)]; + arr[0].0 += 1.0; + d += arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0.0 }]; + arr[0].x += 1.0; + d += arr[0].x; + // +7 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([0.0]); + (arr.0)[0] += 1.0; + d += (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; + arr.x[0] += 1.0; + d += arr.x[0]; + // +9 + + d +} + +const fn mul_assign(A { a }: A) -> f32 { + // Mutables: + let mut d: f32 = a + 1.0; + d *= 2.0; + // 2^1 * (a + 1) + + // Array projection + let mut arr: [f32; 1] = [1.0]; + arr[0] *= 2.0; + d *= arr[0]; + // 2^2 * (a + 1) + + // Field projection: + let mut foo: Foo = Foo(1.0); + let mut bar: Bar = Bar { x: 1.0 }; + foo.0 *= 2.0; + bar.x *= 2.0; + d *= foo.0 + bar.x; + // 2^4 * (a + 1) + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1.0)]; + arr[0].0 *= 2.0; + d *= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 1.0 }]; + arr[0].x *= 2.0; + d *= arr[0].x; + // 2^6 * (a + 1) + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([1.0]); + (arr.0)[0] *= 2.0; + d *= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [1.0] }; + arr.x[0] *= 2.0; + d *= arr.x[0]; + // 2^8 * (a + 1) + + d +} + +const fn div_assign(a: [f32; 1]) -> f32 { + let a = a[0]; + // Mutables: + let mut d: f32 = 1024.0 * a; + d /= 2.0; + // 512 + + // Array projection + let mut arr: [f32; 1] = [4.0]; + arr[0] /= 2.0; + d /= arr[0]; + // 256 + + // Field projection: + let mut foo: Foo = Foo(4.0); + let mut bar: Bar = Bar { x: 4.0 }; + foo.0 /= 2.0; + bar.x /= 2.0; + d /= foo.0; + d /= bar.x; + // 64 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4.0)]; + arr[0].0 /= 2.0; + d /= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 4.0 }]; + arr[0].x /= 2.0; + d /= arr[0].x; + // 16 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([4.0]); + (arr.0)[0] /= 2.0; + d /= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [4.0] }; + arr.x[0] /= 2.0; + d /= arr.x[0]; + // 4 + + d +} + +const fn rem_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a; + d %= 10.0; + d += 10.0; + + // Array projection + let mut arr: [f32; 1] = [3.0]; + arr[0] %= 2.0; + d %= 9.0 + arr[0]; + d += 10.0; + + // Field projection: + let mut foo: Foo = Foo(5.0); + let mut bar: Bar = Bar { x: 7.0 }; + foo.0 %= 2.0; + bar.x %= 2.0; + d %= 8.0 + foo.0 + bar.x; + d += 10.0; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4.0)]; + arr[0].0 %= 3.0; + d %= 9.0 + arr[0].0; + d += 10.0; + let mut arr: [Bar; 1] = [Bar { x: 7.0 }]; + arr[0].x %= 3.0; + d %= 9.0 + arr[0].x; + d += 10.0; + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([6.0]); + (arr.0)[0] %= 5.0; + d %= 9.0 + (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [11.0] }; + arr.x[0] %= 5.0; + d %= 9.0 + arr.x[0]; + + d +} + +const fn sub_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a; + d -= 1.0; + + // Array projection + let mut arr: [f32; 1] = [2.0]; + arr[0] -= 1.0; + d -= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(2.0); + let mut bar: Bar = Bar { x: 2.0 }; + foo.0 -= 1.0; + bar.x -= 1.0; + d -= foo.0 + bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2.0)]; + arr[0].0 -= 1.0; + d -= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 2.0 }]; + arr[0].x -= 1.0; + d -= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([2.0]); + (arr.0)[0] -= 1.0; + d -= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [2.0] }; + arr.x[0] -= 1.0; + d -= arr.x[0]; + + d +} + +macro_rules! test { + ($c:ident, $e:expr, $r:expr) => { + const $c: f32 = $e; + assert_eq!($c, $r); + assert_eq!($e, $r); + } +} + +fn main() { + test!(BASICS, basics((2.0,)), 13.0); + test!(ADD, add_assign(W(1.0)), 10.0); + test!(MUL, mul_assign(A { a: 0.0 }), 256.0); + test!(DIV, div_assign([1.0]), 4.0); + test!(REM, rem_assign(W(5.0)), 5.0); + test!(SUB, sub_assign(W(8.0)), 0.0); +} From e6e08c666c0481c96ab5a848fadc47fb06d75e16 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 30 Nov 2018 09:44:51 +0100 Subject: [PATCH 20/25] Fix rebase fallout --- src/librustc_mir/transform/qualify_consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index e49134409f0c6..0f54978c1dec6 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1166,7 +1166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { if self.mir.local_kind(index) == LocalKind::Var && self.const_fn_arg_vars.insert(index) && - !self.tcx.sess.features_untracked().const_let { + !self.const_let_allowed() { // Direct use of an argument is permitted. match *rvalue { Rvalue::Use(Operand::Copy(Place::Local(local))) | From 07345f041ee0bf7bdd0ea0395865872297725668 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 12 Dec 2018 09:34:43 +0100 Subject: [PATCH 21/25] Undo a change that got lost in the larger refactorings --- src/librustc_mir/transform/qualify_consts.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 0f54978c1dec6..2caeba6c06a31 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -557,9 +557,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { match proj.elem { ProjectionElem::Deref => { if context.is_mutating_use() { + // `not_const` errors out in const contexts this.not_const() } else { - this.qualif = Qualif::NOT_CONST; + // just make sure this doesn't get promoted + this.qualif.add(Qualif::NOT_CONST); } let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); match this.mode { From 2cb5e3d49045f9fe5b315b3cdf33da561b5b467d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 12 Dec 2018 09:34:57 +0100 Subject: [PATCH 22/25] Manually inline trivial function --- src/librustc_mir/transform/qualify_consts.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2caeba6c06a31..37d5e9dca3695 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - if self.const_let_allowed() { + if self.tcx.features().const_let { let mut dest = dest; let index = loop { match dest { @@ -320,10 +320,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } - fn const_let_allowed(&self) -> bool { - self.tcx.features().const_let - } - /// Qualify a whole const, static initializer or const fn. fn qualify_const(&mut self) -> (Qualif, Lrc>) { debug!("qualifying {} {:?}", self.mode, self.def_id); @@ -361,7 +357,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseUnwind { .. } => None, TerminatorKind::Return => { - if !self.const_let_allowed() { + if !self.tcx.features().const_let { // Check for unused values. This usually means // there are extra statements in the AST. for temp in mir.temps_iter() { @@ -468,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Var if !self.const_let_allowed() => { + LocalKind::Var if !self.tcx.features().const_let => { if self.mode != Mode::Fn { emit_feature_err(&self.tcx.sess.parse_sess, "const_let", self.span, GateIssue::Language, @@ -561,7 +557,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.not_const() } else { // just make sure this doesn't get promoted - this.qualif.add(Qualif::NOT_CONST); + this.add(Qualif::NOT_CONST); } let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); match this.mode { @@ -1168,7 +1164,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { if self.mir.local_kind(index) == LocalKind::Var && self.const_fn_arg_vars.insert(index) && - !self.const_let_allowed() { + !self.tcx.features().const_let { // Direct use of an argument is permitted. match *rvalue { Rvalue::Use(Operand::Copy(Place::Local(local))) | From 6ca2ad584459b62e444e726af6ec958c31c77c1d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 12 Dec 2018 13:09:36 +0100 Subject: [PATCH 23/25] Correct documentation about `FakeRead` --- src/librustc/mir/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index faecb7013b492..7b158c3958d4a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1760,7 +1760,8 @@ pub enum StatementKind<'tcx> { /// kind of pattern it comes from. This is in order to adapt potential /// error messages to these specific patterns. /// - /// Note that this also is emitted for regular `let` bindings to aid destructuring diagnostics + /// Note that this also is emitted for regular `let` bindings to ensure that locals that are + /// never accessed still get some sanity checks for e.g. `let x: ! = ..;` FakeRead(FakeReadCause, Place<'tcx>), /// Write the discriminant for a variant to the enum Place. From b678238070cf43e97ab263788897eb64430ee4b4 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 18 Dec 2018 09:16:56 +0100 Subject: [PATCH 24/25] Properly worded diagnostic message --- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/test/ui/consts/const_short_circuit.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 37d5e9dca3695..10d14c1e412a2 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1340,7 +1340,7 @@ impl MirPass for QualifyAndPromoteConstants { let mut error = tcx.sess.struct_span_err( span, &format!( - "new features like let bindings are not permitted in {} \ + "new features like let bindings are not permitted in {}s \ which also use short circuiting operators", mode, ), diff --git a/src/test/ui/consts/const_short_circuit.stderr b/src/test/ui/consts/const_short_circuit.stderr index 6f8fca60c8098..807134427061f 100644 --- a/src/test/ui/consts/const_short_circuit.stderr +++ b/src/test/ui/consts/const_short_circuit.stderr @@ -1,4 +1,4 @@ -error: new features like let bindings are not permitted in constant which also use short circuiting operators +error: new features like let bindings are not permitted in constants which also use short circuiting operators --> $DIR/const_short_circuit.rs:6:9 | LL | let mut x = true && false; @@ -10,7 +10,7 @@ note: use of `&&` operator here LL | let mut x = true && false; | ^^ -error: new features like let bindings are not permitted in constant which also use short circuiting operators +error: new features like let bindings are not permitted in constants which also use short circuiting operators --> $DIR/const_short_circuit.rs:11:9 | LL | let x = true && false; From d815e2b870793e8793900be0aeb8ccaf5e4c7291 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 18 Dec 2018 09:42:46 +0100 Subject: [PATCH 25/25] Explain that lack of short circuiting support in constants is temporary --- src/librustc_mir/transform/qualify_consts.rs | 5 ++++- src/test/ui/consts/const_short_circuit.stderr | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 10d14c1e412a2..cd6a9e98e8dad 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1348,7 +1348,10 @@ impl MirPass for QualifyAndPromoteConstants { for (span, kind) in mir.control_flow_destroyed.iter() { error.span_note( *span, - &format!("use of {} here", kind), + &format!("use of {} here does not actually short circuit due to \ + the const evaluator presently not being able to do control flow. \ + See https://github.com/rust-lang/rust/issues/49146 for more \ + information.", kind), ); } for local in locals { diff --git a/src/test/ui/consts/const_short_circuit.stderr b/src/test/ui/consts/const_short_circuit.stderr index 807134427061f..a67bb0b1b6d98 100644 --- a/src/test/ui/consts/const_short_circuit.stderr +++ b/src/test/ui/consts/const_short_circuit.stderr @@ -4,7 +4,7 @@ error: new features like let bindings are not permitted in constants which also LL | let mut x = true && false; | ^^^^^ | -note: use of `&&` operator here +note: use of `&&` operator here does not actually short circuit due to the const evaluator presently not being able to do control flow. See https://github.com/rust-lang/rust/issues/49146 for more information. --> $DIR/const_short_circuit.rs:6:22 | LL | let mut x = true && false; @@ -16,7 +16,7 @@ error: new features like let bindings are not permitted in constants which also LL | let x = true && false; | ^ | -note: use of `&&` operator here +note: use of `&&` operator here does not actually short circuit due to the const evaluator presently not being able to do control flow. See https://github.com/rust-lang/rust/issues/49146 for more information. --> $DIR/const_short_circuit.rs:11:18 | LL | let x = true && false;