Skip to content

Allow panicking with string literal messages inside constants #52011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
@@ -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) => {
2 changes: 2 additions & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
@@ -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;
12 changes: 10 additions & 2 deletions src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
@@ -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()),
}
}
6 changes: 5 additions & 1 deletion src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
@@ -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,
95 changes: 81 additions & 14 deletions src/librustc_mir/interpret/const_eval.rs
Original file line number Diff line number Diff line change
@@ -5,21 +5,22 @@ 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,
Scalar, AllocId, Allocation, ConstValue,
};
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")
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have that same code in miri...^^


/// Project to a field of a (variant of a) const
pub fn const_field<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -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>> {
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
@@ -230,7 +230,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
// FIXME: implement
=> {},

| Panic
| Panic { .. }
| BoundsCheck{..}
| Overflow(_)
| OverflowNeg
26 changes: 24 additions & 2 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
@@ -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
}),
1 change: 1 addition & 0 deletions src/libstd/panicking.rs
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/consts/const-eval/const_panic.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 33 additions & 0 deletions src/test/ui/consts/const-eval/const_panic.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/consts/const-eval/const_panic_libcore.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 33 additions & 0 deletions src/test/ui/consts/const-eval/const_panic_libcore.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 37 additions & 0 deletions src/test/ui/consts/const-eval/const_panic_libcore_main.rs
Original file line number Diff line number Diff line change
@@ -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 {}
}
33 changes: 33 additions & 0 deletions src/test/ui/consts/const-eval/const_panic_libcore_main.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions src/test/ui/consts/const-eval/feature-gate-const_panic.rs
Original file line number Diff line number Diff line change
@@ -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
30 changes: 30 additions & 0 deletions src/test/ui/consts/const-eval/feature-gate-const_panic.stderr
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-32829.rs
Original file line number Diff line number Diff line change
@@ -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);
5 changes: 3 additions & 2 deletions src/test/ui/issues/issue-32829.stderr
Original file line number Diff line number Diff line change
@@ -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`.