mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 04:26:48 +00:00
Auto merge of #52011 - oli-obk:dont_you_hate_it_too_when_everything_panics_constantly, r=eddyb
Allow panicking with string literal messages inside constants r? @eddyb cc https://github.com/rust-lang/rust/issues/51999 we can't implement things like `panic!("foo: {}", x)` right now because we can't call trait methods (most notably `Display::fmt`) inside constants. Also most of these impls probably have loops and conditions, so it's messy anyway. But hey `panic!("foo")` works at least. cc @japaric got any test ideas for `#![no_std]`?
This commit is contained in:
commit
917945d662
@ -536,7 +536,6 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||
DeallocateNonBasePtr |
|
||||
HeapAllocZeroBytes |
|
||||
Unreachable |
|
||||
Panic |
|
||||
ReadFromReturnPointer |
|
||||
UnimplementedTraitSelection |
|
||||
TypeckError |
|
||||
@ -550,6 +549,12 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||
GeneratorResumedAfterReturn |
|
||||
GeneratorResumedAfterPanic |
|
||||
InfiniteLoop => {}
|
||||
Panic { ref msg, ref file, line, col } => {
|
||||
msg.hash_stable(hcx, hasher);
|
||||
file.hash_stable(hcx, hasher);
|
||||
line.hash_stable(hcx, hasher);
|
||||
col.hash_stable(hcx, hasher);
|
||||
},
|
||||
ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
|
||||
MachineError(ref err) => err.hash_stable(hcx, hasher),
|
||||
FunctionPointerTyMismatch(a, b) => {
|
||||
|
@ -305,6 +305,8 @@ language_item_table! {
|
||||
PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn;
|
||||
PanicInfoLangItem, "panic_info", panic_info;
|
||||
PanicImplLangItem, "panic_impl", panic_impl;
|
||||
// Libstd panic entry point. Necessary for const eval to be able to catch it
|
||||
BeginPanicFnLangItem, "begin_panic", begin_panic_fn;
|
||||
|
||||
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
|
||||
BoxFreeFnLangItem, "box_free", box_free_fn;
|
||||
|
@ -17,6 +17,7 @@ use errors::DiagnosticBuilder;
|
||||
|
||||
use syntax_pos::Span;
|
||||
use syntax::ast;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
|
||||
|
||||
@ -250,7 +251,12 @@ pub enum EvalErrorKind<'tcx, O> {
|
||||
HeapAllocZeroBytes,
|
||||
HeapAllocNonPowerOfTwoAlignment(u64),
|
||||
Unreachable,
|
||||
Panic,
|
||||
Panic {
|
||||
msg: Symbol,
|
||||
line: u32,
|
||||
col: u32,
|
||||
file: Symbol,
|
||||
},
|
||||
ReadFromReturnPointer,
|
||||
PathNotFound(Vec<String>),
|
||||
UnimplementedTraitSelection,
|
||||
@ -370,7 +376,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
|
||||
"tried to re-, de-, or allocate heap memory with alignment that is not a power of two",
|
||||
Unreachable =>
|
||||
"entered unreachable code",
|
||||
Panic =>
|
||||
Panic { .. } =>
|
||||
"the evaluated program panicked",
|
||||
ReadFromReturnPointer =>
|
||||
"tried to read from the return pointer",
|
||||
@ -465,6 +471,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
|
||||
write!(f, "{}", inner),
|
||||
IncorrectAllocationInformation(size, size2, align, align2) =>
|
||||
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size.bytes(), align.abi(), size2.bytes(), align2.abi()),
|
||||
Panic { ref msg, line, col, ref file } =>
|
||||
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
|
||||
_ => write!(f, "{}", self.description()),
|
||||
}
|
||||
}
|
||||
|
@ -574,7 +574,11 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
|
||||
HeapAllocZeroBytes => HeapAllocZeroBytes,
|
||||
HeapAllocNonPowerOfTwoAlignment(n) => HeapAllocNonPowerOfTwoAlignment(n),
|
||||
Unreachable => Unreachable,
|
||||
Panic => Panic,
|
||||
Panic { ref msg, ref file, line, col } => Panic {
|
||||
msg: msg.clone(),
|
||||
file: file.clone(),
|
||||
line, col,
|
||||
},
|
||||
ReadFromReturnPointer => ReadFromReturnPointer,
|
||||
PathNotFound(ref v) => PathNotFound(v.clone()),
|
||||
UnimplementedTraitSelection => UnimplementedTraitSelection,
|
||||
|
@ -5,13 +5,14 @@ use rustc::hir;
|
||||
use rustc::mir::interpret::ConstEvalErr;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, TyCtxt, Instance};
|
||||
use rustc::ty::layout::{LayoutOf, Primitive, TyLayout};
|
||||
use rustc::ty::layout::{LayoutOf, Primitive, TyLayout, Size};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
|
||||
use syntax::ast::Mutability;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
EvalResult, EvalError, EvalErrorKind, GlobalId,
|
||||
@ -19,7 +20,7 @@ use rustc::mir::interpret::{
|
||||
};
|
||||
use super::{
|
||||
Place, PlaceExtra, PlaceTy, MemPlace, OpTy, Operand, Value,
|
||||
EvalContext, StackPopCleanup, Memory, MemoryKind
|
||||
EvalContext, StackPopCleanup, Memory, MemoryKind, MPlaceTy,
|
||||
};
|
||||
|
||||
pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
|
||||
@ -237,23 +238,56 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
|
||||
if !ecx.tcx.is_const_fn(instance.def_id()) {
|
||||
let def_id = instance.def_id();
|
||||
// Some fn calls are actually BinOp intrinsics
|
||||
let (op, oflo) = if let Some(op) = ecx.tcx.is_binop_lang_item(def_id) {
|
||||
op
|
||||
let _: ! = if let Some((op, oflo)) = ecx.tcx.is_binop_lang_item(def_id) {
|
||||
let (dest, bb) = destination.expect("128 lowerings can't diverge");
|
||||
let l = ecx.read_value(args[0])?;
|
||||
let r = ecx.read_value(args[1])?;
|
||||
if oflo {
|
||||
ecx.binop_with_overflow(op, l, r, dest)?;
|
||||
} else {
|
||||
ecx.binop_ignore_overflow(op, l, r, dest)?;
|
||||
}
|
||||
ecx.goto_block(bb);
|
||||
return Ok(true);
|
||||
} else if Some(def_id) == ecx.tcx.lang_items().panic_fn() {
|
||||
assert!(args.len() == 1);
|
||||
// &(&'static str, &'static str, u32, u32)
|
||||
let ptr = ecx.read_value(args[0])?;
|
||||
let place = ecx.ref_to_mplace(ptr)?;
|
||||
let (msg, file, line, col) = (
|
||||
place_field(ecx, 0, place)?,
|
||||
place_field(ecx, 1, place)?,
|
||||
place_field(ecx, 2, place)?,
|
||||
place_field(ecx, 3, place)?,
|
||||
);
|
||||
|
||||
let msg = to_str(ecx, msg)?;
|
||||
let file = to_str(ecx, file)?;
|
||||
let line = to_u32(line)?;
|
||||
let col = to_u32(col)?;
|
||||
return Err(EvalErrorKind::Panic { msg, file, line, col }.into());
|
||||
} else if Some(def_id) == ecx.tcx.lang_items().begin_panic_fn() {
|
||||
assert!(args.len() == 2);
|
||||
// &'static str, &(&'static str, u32, u32)
|
||||
let msg = ecx.read_value(args[0])?;
|
||||
let ptr = ecx.read_value(args[1])?;
|
||||
let place = ecx.ref_to_mplace(ptr)?;
|
||||
let (file, line, col) = (
|
||||
place_field(ecx, 0, place)?,
|
||||
place_field(ecx, 1, place)?,
|
||||
place_field(ecx, 2, place)?,
|
||||
);
|
||||
|
||||
let msg = to_str(ecx, msg.value)?;
|
||||
let file = to_str(ecx, file)?;
|
||||
let line = to_u32(line)?;
|
||||
let col = to_u32(col)?;
|
||||
return Err(EvalErrorKind::Panic { msg, file, line, col }.into());
|
||||
} else {
|
||||
return Err(
|
||||
ConstEvalError::NotConst(format!("calling non-const fn `{}`", instance)).into(),
|
||||
);
|
||||
};
|
||||
let (dest, bb) = destination.expect("128 lowerings can't diverge");
|
||||
let l = ecx.read_value(args[0])?;
|
||||
let r = ecx.read_value(args[1])?;
|
||||
if oflo {
|
||||
ecx.binop_with_overflow(op, l, r, dest)?;
|
||||
} else {
|
||||
ecx.binop_ignore_overflow(op, l, r, dest)?;
|
||||
}
|
||||
ecx.goto_block(bb);
|
||||
return Ok(true);
|
||||
}
|
||||
let mir = match ecx.load_mir(instance.def) {
|
||||
Ok(mir) => mir,
|
||||
@ -412,6 +446,39 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
fn place_field<'a, 'tcx, 'mir>(
|
||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>,
|
||||
i: u64,
|
||||
place: MPlaceTy<'tcx>,
|
||||
) -> EvalResult<'tcx, Value> {
|
||||
let place = ecx.mplace_field(place, i)?;
|
||||
Ok(ecx.try_read_value_from_mplace(place)?.expect("bad panic arg layout"))
|
||||
}
|
||||
|
||||
fn to_str<'a, 'tcx, 'mir>(
|
||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>,
|
||||
val: Value,
|
||||
) -> EvalResult<'tcx, Symbol> {
|
||||
if let Value::ScalarPair(ptr, len) = val {
|
||||
let len = len.not_undef()?.to_bits(ecx.memory.pointer_size())?;
|
||||
let bytes = ecx.memory.read_bytes(ptr.not_undef()?, Size::from_bytes(len as u64))?;
|
||||
let str = ::std::str::from_utf8(bytes).map_err(|err| EvalErrorKind::ValidationFailure(err.to_string()))?;
|
||||
Ok(Symbol::intern(str))
|
||||
} else {
|
||||
bug!("panic arg is not a str")
|
||||
}
|
||||
}
|
||||
|
||||
fn to_u32<'a, 'tcx, 'mir>(
|
||||
val: Value,
|
||||
) -> EvalResult<'tcx, u32> {
|
||||
if let Value::Scalar(n) = val {
|
||||
Ok(n.not_undef()?.to_bits(Size::from_bits(32))? as u32)
|
||||
} else {
|
||||
bug!("panic arg is not a str")
|
||||
}
|
||||
}
|
||||
|
||||
/// Project to a field of a (variant of a) const
|
||||
pub fn const_field<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
@ -213,7 +213,7 @@ fn from_known_layout<'tcx>(
|
||||
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
/// Try reading a value in memory; this is interesting particularily for ScalarPair.
|
||||
/// Return None if the layout does not permit loading this as a value.
|
||||
fn try_read_value_from_mplace(
|
||||
pub(super) fn try_read_value_from_mplace(
|
||||
&self,
|
||||
mplace: MPlaceTy<'tcx>,
|
||||
) -> EvalResult<'tcx, Option<Value>> {
|
||||
|
@ -230,7 +230,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
// FIXME: implement
|
||||
=> {},
|
||||
|
||||
| Panic
|
||||
| Panic { .. }
|
||||
| BoundsCheck{..}
|
||||
| Overflow(_)
|
||||
| OverflowNeg
|
||||
|
@ -400,6 +400,11 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
|
||||
(self.qualif, Lrc::new(promoted_temps))
|
||||
}
|
||||
|
||||
fn is_const_panic_fn(&self, def_id: DefId) -> bool {
|
||||
Some(def_id) == self.tcx.lang_items().panic_fn() ||
|
||||
Some(def_id) == self.tcx.lang_items().begin_panic_fn()
|
||||
}
|
||||
}
|
||||
|
||||
/// Accumulates an Rvalue or Call's effects in self.qualif.
|
||||
@ -834,7 +839,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if self.tcx.is_const_fn(def_id) {
|
||||
if self.tcx.is_const_fn(def_id) || self.is_const_panic_fn(def_id) {
|
||||
is_const_fn = Some(def_id);
|
||||
}
|
||||
}
|
||||
@ -880,8 +885,25 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
|
||||
// Const fn calls.
|
||||
if let Some(def_id) = is_const_fn {
|
||||
// check the const_panic feature gate or
|
||||
// find corresponding rustc_const_unstable feature
|
||||
if let Some(&attr::Stability {
|
||||
// FIXME: cannot allow this inside `allow_internal_unstable` because that would make
|
||||
// `panic!` insta stable in constants, since the macro is marked with the attr
|
||||
if self.is_const_panic_fn(def_id) {
|
||||
if self.mode == Mode::Fn {
|
||||
// never promote panics
|
||||
self.qualif = Qualif::NOT_CONST;
|
||||
} else if !self.tcx.sess.features_untracked().const_panic {
|
||||
// don't allow panics in constants without the feature gate
|
||||
emit_feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
"const_panic",
|
||||
self.span,
|
||||
GateIssue::Language,
|
||||
&format!("panicking in {}s is unstable", self.mode),
|
||||
);
|
||||
}
|
||||
} else if let Some(&attr::Stability {
|
||||
rustc_const_unstable: Some(attr::RustcConstUnstable {
|
||||
feature: ref feature_name
|
||||
}),
|
||||
|
@ -397,6 +397,7 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! {
|
||||
#[unstable(feature = "libstd_sys_internals",
|
||||
reason = "used by the panic! macro",
|
||||
issue = "0")]
|
||||
#[cfg_attr(not(any(stage0, test)), lang = "begin_panic")]
|
||||
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
|
||||
pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||
// Note that this should be the only allocation performed in this code path.
|
||||
|
@ -224,6 +224,9 @@ declare_features! (
|
||||
// Allows comparing raw pointers during const eval
|
||||
(active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
|
||||
|
||||
// Allows panicking during const eval (produces compile-time errors)
|
||||
(active, const_panic, "1.30.0", Some(51999), None),
|
||||
|
||||
// Allows using #[prelude_import] on glob `use` items.
|
||||
//
|
||||
// rustc internal
|
||||
|
22
src/test/ui/consts/const-eval/const_panic.rs
Normal file
22
src/test/ui/consts/const-eval/const_panic.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(const_panic)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
const Z: () = panic!("cheese");
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const Y: () = unreachable!();
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const X: () = unimplemented!();
|
||||
//~^ ERROR this constant cannot be used
|
33
src/test/ui/consts/const-eval/const_panic.stderr
Normal file
33
src/test/ui/consts/const-eval/const_panic.stderr
Normal file
@ -0,0 +1,33 @@
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic.rs:15:1
|
||||
|
|
||||
LL | const Z: () = panic!("cheese");
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:15:15
|
||||
|
|
||||
= note: #[deny(const_err)] on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic.rs:18:1
|
||||
|
|
||||
LL | const Y: () = unreachable!();
|
||||
| ^^^^^^^^^^^^^^--------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:18:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic.rs:21:1
|
||||
|
|
||||
LL | const X: () = unimplemented!();
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic.rs:21:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
22
src/test/ui/consts/const-eval/const_panic_libcore.rs
Normal file
22
src/test/ui/consts/const-eval/const_panic_libcore.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![no_std]
|
||||
#![crate_type = "lib"]
|
||||
#![feature(const_panic)]
|
||||
|
||||
const Z: () = panic!("cheese");
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const Y: () = unreachable!();
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const X: () = unimplemented!();
|
||||
//~^ ERROR this constant cannot be used
|
33
src/test/ui/consts/const-eval/const_panic_libcore.stderr
Normal file
33
src/test/ui/consts/const-eval/const_panic_libcore.stderr
Normal file
@ -0,0 +1,33 @@
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore.rs:15:1
|
||||
|
|
||||
LL | const Z: () = panic!("cheese");
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'cheese', $DIR/const_panic_libcore.rs:15:15
|
||||
|
|
||||
= note: #[deny(const_err)] on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore.rs:18:1
|
||||
|
|
||||
LL | const Y: () = unreachable!();
|
||||
| ^^^^^^^^^^^^^^--------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore.rs:18:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore.rs:21:1
|
||||
|
|
||||
LL | const X: () = unimplemented!();
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic_libcore.rs:21:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
37
src/test/ui/consts/const-eval/const_panic_libcore_main.rs
Normal file
37
src/test/ui/consts/const-eval/const_panic_libcore_main.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "bin"]
|
||||
#![feature(lang_items)]
|
||||
#![feature(panic_implementation)]
|
||||
#![feature(const_panic)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
const Z: () = panic!("cheese");
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const Y: () = unreachable!();
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
const X: () = unimplemented!();
|
||||
//~^ ERROR this constant cannot be used
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
fn eh() {}
|
||||
#[lang = "eh_unwind_resume"]
|
||||
fn eh_unwind_resume() {}
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore_main.rs:20:1
|
||||
|
|
||||
LL | const Z: () = panic!("cheese");
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:20:15
|
||||
|
|
||||
= note: #[deny(const_err)] on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore_main.rs:23:1
|
||||
|
|
||||
LL | const Y: () = unreachable!();
|
||||
| ^^^^^^^^^^^^^^--------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:23:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: this constant cannot be used
|
||||
--> $DIR/const_panic_libcore_main.rs:26:1
|
||||
|
|
||||
LL | const X: () = unimplemented!();
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
| |
|
||||
| the evaluated program panicked at 'not yet implemented', $DIR/const_panic_libcore_main.rs:26:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
20
src/test/ui/consts/const-eval/feature-gate-const_panic.rs
Normal file
20
src/test/ui/consts/const-eval/feature-gate-const_panic.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {}
|
||||
|
||||
const Z: () = panic!("cheese");
|
||||
//~^ ERROR panicking in constants is unstable
|
||||
|
||||
const Y: () = unreachable!();
|
||||
//~^ ERROR panicking in constants is unstable
|
||||
|
||||
const X: () = unimplemented!();
|
||||
//~^ ERROR panicking in constants is unstable
|
@ -0,0 +1,30 @@
|
||||
error[E0658]: panicking in constants is unstable (see issue #51999)
|
||||
--> $DIR/feature-gate-const_panic.rs:13:15
|
||||
|
|
||||
LL | const Z: () = panic!("cheese");
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_panic)] to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error[E0658]: panicking in constants is unstable (see issue #51999)
|
||||
--> $DIR/feature-gate-const_panic.rs:19:15
|
||||
|
|
||||
LL | const X: () = unimplemented!();
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_panic)] to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error[E0658]: panicking in constants is unstable (see issue #51999)
|
||||
--> $DIR/feature-gate-const_panic.rs:16:15
|
||||
|
|
||||
LL | const Y: () = unreachable!();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_panic)] to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
static S : u64 = { { panic!("foo"); 0 } };
|
||||
//~^ ERROR calls in statics are limited
|
||||
//~^ ERROR panicking in statics is unstable
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", S);
|
||||
|
@ -1,11 +1,12 @@
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
error[E0658]: panicking in statics is unstable (see issue #51999)
|
||||
--> $DIR/issue-32829.rs:11:22
|
||||
|
|
||||
LL | static S : u64 = { { panic!("foo"); 0 } };
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_panic)] to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
Loading…
Reference in New Issue
Block a user