implement #[panic_implementation]
This commit is contained in:
parent
3575be60ea
commit
e44ad61a2d
22 changed files with 379 additions and 18 deletions
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
/// Entry point of thread panic, for details, see std::macros
|
||||
#[cfg(stage0)]
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
|
@ -28,6 +29,27 @@ macro_rules! panic {
|
|||
});
|
||||
}
|
||||
|
||||
/// Entry point of thread panic, for details, see std::macros
|
||||
#[cfg(not(stage0))]
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
macro_rules! panic {
|
||||
() => (
|
||||
panic!("explicit panic")
|
||||
);
|
||||
($msg:expr) => ({
|
||||
$crate::panicking::panic_payload($msg, &(file!(), line!(), __rust_unstable_column!()))
|
||||
});
|
||||
($msg:expr,) => (
|
||||
panic!($msg)
|
||||
);
|
||||
($fmt:expr, $($arg:tt)+) => ({
|
||||
$crate::panicking::panic_fmt(format_args!($fmt, $($arg)*),
|
||||
&(file!(), line!(), __rust_unstable_column!()))
|
||||
});
|
||||
}
|
||||
|
||||
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
|
||||
///
|
||||
/// On panic, this macro will print the values of the expressions with their
|
||||
|
|
|
@ -35,6 +35,7 @@ use fmt;
|
|||
///
|
||||
/// panic!("Normal panic");
|
||||
/// ```
|
||||
#[cfg_attr(not(stage0), lang = "panic_info")]
|
||||
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct PanicInfo<'a> {
|
||||
|
@ -53,7 +54,8 @@ impl<'a> PanicInfo<'a> {
|
|||
pub fn internal_constructor(message: Option<&'a fmt::Arguments<'a>>,
|
||||
location: Location<'a>)
|
||||
-> Self {
|
||||
PanicInfo { payload: &(), location, message }
|
||||
struct NoPayload;
|
||||
PanicInfo { payload: &NoPayload, location, message }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -121,7 +123,7 @@ impl<'a> PanicInfo<'a> {
|
|||
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||
pub fn location(&self) -> Option<&Location> {
|
||||
// NOTE: If this is changed to sometimes return None,
|
||||
// deal with that case in std::panicking::default_hook.
|
||||
// deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
|
||||
Some(&self.location)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,33 @@
|
|||
and related macros",
|
||||
issue = "0")]
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
use any::Any;
|
||||
use fmt;
|
||||
#[cfg(not(stage0))]
|
||||
use panic::{Location, PanicInfo};
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
|
||||
extern "C" {
|
||||
#[lang = "panic_impl"]
|
||||
fn panic_impl(pi: &PanicInfo) -> !;
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)]
|
||||
pub fn panic_payload<M>(msg: M, file_line_col: &(&'static str, u32, u32)) -> !
|
||||
where
|
||||
M: Any + Send,
|
||||
{
|
||||
let (file, line, col) = *file_line_col;
|
||||
let mut pi = PanicInfo::internal_constructor(
|
||||
None,
|
||||
Location::internal_constructor(file, line, col),
|
||||
);
|
||||
pi.set_payload(&msg);
|
||||
unsafe { panic_impl(&pi) }
|
||||
}
|
||||
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang = "panic"]
|
||||
|
@ -59,6 +85,7 @@ fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
|
|||
len, index), file_line_col)
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)]
|
||||
pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||
#[allow(improper_ctypes)]
|
||||
|
@ -70,3 +97,16 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32))
|
|||
let (file, line, col) = *file_line_col;
|
||||
unsafe { panic_impl(fmt, file, line, col) }
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)]
|
||||
pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||
struct NoPayload;
|
||||
|
||||
let (file, line, col) = *file_line_col;
|
||||
let pi = PanicInfo::internal_constructor(
|
||||
Some(&fmt),
|
||||
Location::internal_constructor(file, line, col),
|
||||
);
|
||||
unsafe { panic_impl(&pi) }
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
|||
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
|
||||
id: ast::NodeId,
|
||||
attrs: &[ast::Attribute]) -> bool {
|
||||
if attr::contains_name(attrs, "lang") {
|
||||
if attr::contains_name(attrs, "lang") || attr::contains_name(attrs, "panic_implementation") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -185,6 +185,8 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
|
|||
if let Some(value) = attribute.value_str() {
|
||||
return Some((value, attribute.span));
|
||||
}
|
||||
} else if attribute.check_name("panic_implementation") {
|
||||
return Some((Symbol::intern("panic_impl"), attribute.span))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +301,8 @@ language_item_table! {
|
|||
// lang item, but do not have it defined.
|
||||
PanicFnLangItem, "panic", panic_fn;
|
||||
PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn;
|
||||
PanicFmtLangItem, "panic_fmt", panic_fmt;
|
||||
PanicInfoLangItem, "panic_info", panic_info;
|
||||
PanicImplLangItem, "panic_impl", panic_impl;
|
||||
|
||||
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
|
||||
BoxFreeFnLangItem, "box_free", box_free_fn;
|
||||
|
|
|
@ -148,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
|||
) }
|
||||
|
||||
weak_lang_items! {
|
||||
panic_fmt, PanicFmtLangItem, rust_begin_unwind;
|
||||
panic_impl, PanicImplLangItem, rust_begin_unwind;
|
||||
eh_personality, EhPersonalityLangItem, rust_eh_personality;
|
||||
eh_unwind_resume, EhUnwindResumeLangItem, rust_eh_unwind_resume;
|
||||
oom, OomLangItem, rust_oom;
|
||||
|
|
|
@ -96,7 +96,7 @@ use rustc::middle::region;
|
|||
use rustc::mir::interpret::{GlobalId};
|
||||
use rustc::ty::subst::{UnpackedKind, Subst, Substs};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
|
||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::maps::Providers;
|
||||
|
@ -1129,6 +1129,48 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
// Check that a function marked as `#[panic_implementation]` has signature `fn(&PanicInfo) -> !`
|
||||
if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
|
||||
if panic_impl_did == fn_hir_id.owner_def_id() {
|
||||
if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
|
||||
if ret_ty.sty != ty::TyNever {
|
||||
fcx.tcx.sess.span_err(
|
||||
decl.output.span(),
|
||||
"return type should be `!`",
|
||||
);
|
||||
}
|
||||
|
||||
let inputs = fn_sig.inputs();
|
||||
let span = fcx.tcx.hir.span(fn_id);
|
||||
if inputs.len() == 1 {
|
||||
let arg_is_panic_info = match inputs[0].sty {
|
||||
ty::TyRef(region, ty::TypeAndMut { ty, mutbl }) => match ty.sty {
|
||||
ty::TyAdt(ref adt, _) => {
|
||||
adt.did == panic_info_did &&
|
||||
mutbl == hir::Mutability::MutImmutable &&
|
||||
*region != RegionKind::ReStatic
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !arg_is_panic_info {
|
||||
fcx.tcx.sess.span_err(
|
||||
decl.inputs[0].span,
|
||||
"argument should be `&PanicInfo`",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
fcx.tcx.sess.span_err(span, "function should have one argument");
|
||||
}
|
||||
} else {
|
||||
fcx.tcx.sess.err("language item required, but not found: `panic_info`");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(fcx, gen_ty)
|
||||
}
|
||||
|
||||
|
|
|
@ -317,6 +317,8 @@
|
|||
#![cfg_attr(windows, feature(used))]
|
||||
#![feature(doc_alias)]
|
||||
#![feature(float_internals)]
|
||||
#![feature(panic_info_message)]
|
||||
#![cfg_attr(not(stage0), feature(panic_implementation))]
|
||||
|
||||
#![default_lib_allocator]
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ fn default_hook(info: &PanicInfo) {
|
|||
|
||||
let location = info.location().unwrap(); // The current implementation always returns Some
|
||||
|
||||
let msg = match info.payload().downcast_ref::<&'static str>() {
|
||||
let msg = match info.payload().downcast_ref::<&str>() {
|
||||
Some(s) => *s,
|
||||
None => match info.payload().downcast_ref::<String>() {
|
||||
Some(s) => &s[..],
|
||||
|
@ -319,6 +319,7 @@ pub fn panicking() -> bool {
|
|||
|
||||
/// Entry point of panic from the libcore crate.
|
||||
#[cfg(not(test))]
|
||||
#[cfg(stage0)]
|
||||
#[lang = "panic_fmt"]
|
||||
#[unwind(allowed)]
|
||||
pub extern fn rust_begin_panic(msg: fmt::Arguments,
|
||||
|
@ -328,12 +329,22 @@ pub extern fn rust_begin_panic(msg: fmt::Arguments,
|
|||
begin_panic_fmt(&msg, &(file, line, col))
|
||||
}
|
||||
|
||||
/// Entry point of panic from the libcore crate.
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(stage0))]
|
||||
#[panic_implementation]
|
||||
#[unwind(allowed)]
|
||||
pub fn rust_begin_panic(info: &PanicInfo) -> ! {
|
||||
continue_panic_fmt(&info)
|
||||
}
|
||||
|
||||
/// The entry point for panicking with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
/// site as much as possible (so that `panic!()` has as low an impact
|
||||
/// on (e.g.) the inlining of other functions as possible), by moving
|
||||
/// the actual formatting into this shared place.
|
||||
#[cfg(stage0)]
|
||||
#[unstable(feature = "libstd_sys_internals",
|
||||
reason = "used by the panic! macro",
|
||||
issue = "0")]
|
||||
|
@ -381,12 +392,92 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments,
|
|||
}
|
||||
}
|
||||
|
||||
/// The entry point for panicking with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
/// site as much as possible (so that `panic!()` has as low an impact
|
||||
/// on (e.g.) the inlining of other functions as possible), by moving
|
||||
/// the actual formatting into this shared place.
|
||||
#[cfg(not(stage0))]
|
||||
#[unstable(feature = "libstd_sys_internals",
|
||||
reason = "used by the panic! macro",
|
||||
issue = "0")]
|
||||
#[inline(never)] #[cold]
|
||||
pub fn begin_panic_fmt(msg: &fmt::Arguments,
|
||||
file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||
let (file, line, col) = *file_line_col;
|
||||
let info = PanicInfo::internal_constructor(
|
||||
Some(msg),
|
||||
Location::internal_constructor(file, line, col),
|
||||
);
|
||||
continue_panic_fmt(&info)
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn continue_panic_fmt(info: &PanicInfo) -> ! {
|
||||
use fmt::Write;
|
||||
|
||||
// We do two allocations here, unfortunately. But (a) they're
|
||||
// required with the current scheme, and (b) we don't handle
|
||||
// panic + OOM properly anyway (see comment in begin_panic
|
||||
// below).
|
||||
|
||||
let loc = info.location().unwrap(); // The current implementation always returns Some
|
||||
let file_line_col = (loc.file(), loc.line(), loc.column());
|
||||
rust_panic_with_hook(
|
||||
&mut PanicPayload::new(info.payload(), info.message()),
|
||||
info.message(),
|
||||
&file_line_col);
|
||||
|
||||
struct PanicPayload<'a> {
|
||||
payload: &'a (Any + Send),
|
||||
msg: Option<&'a fmt::Arguments<'a>>,
|
||||
string: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> PanicPayload<'a> {
|
||||
fn new(payload: &'a (Any + Send), msg: Option<&'a fmt::Arguments<'a>>) -> PanicPayload<'a> {
|
||||
PanicPayload { payload, msg, string: None }
|
||||
}
|
||||
|
||||
|
||||
fn fill(&mut self) -> Option<&mut String> {
|
||||
if let Some(msg) = self.msg.take() {
|
||||
Some(self.string.get_or_insert_with(|| {
|
||||
let mut s = String::new();
|
||||
drop(s.write_fmt(*msg));
|
||||
s
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
|
||||
fn box_me_up(&mut self) -> *mut (Any + Send) {
|
||||
if let Some(string) = self.fill() {
|
||||
let contents = mem::replace(string, String::new());
|
||||
Box::into_raw(Box::new(contents))
|
||||
} else {
|
||||
// We can't go from &(Any+Send) to Box<Any+Send> so the payload is lost here
|
||||
struct NoPayload;
|
||||
Box::into_raw(Box::new(NoPayload))
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&mut self) -> &(Any + Send) {
|
||||
self.payload
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the entry point of panicking for panic!() and assert!().
|
||||
#[unstable(feature = "libstd_sys_internals",
|
||||
reason = "used by the panic! macro",
|
||||
issue = "0")]
|
||||
#[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)) -> ! {
|
||||
pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&str, u32, u32)) -> ! {
|
||||
// Note that this should be the only allocation performed in this code path.
|
||||
// Currently this means that panic!() on OOM will invoke this code path,
|
||||
// but then again we're not really ready for panic on OOM anyway. If
|
||||
|
@ -431,7 +522,7 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
|
|||
/// abort or unwind.
|
||||
fn rust_panic_with_hook(payload: &mut BoxMeUp,
|
||||
message: Option<&fmt::Arguments>,
|
||||
file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||
file_line_col: &(&str, u32, u32)) -> ! {
|
||||
let (file, line, col) = *file_line_col;
|
||||
|
||||
let panics = update_panic_count(1);
|
||||
|
|
|
@ -475,6 +475,9 @@ declare_features! (
|
|||
|
||||
// 'a: { break 'a; }
|
||||
(active, label_break_value, "1.28.0", Some(48594), None),
|
||||
|
||||
// #[panic_implementation]
|
||||
(active, panic_implementation, "1.28.0", Some(44489), None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
|
@ -1069,6 +1072,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
|||
"attribute is currently unstable",
|
||||
cfg_fn!(wasm_custom_section))),
|
||||
|
||||
// RFC 2070
|
||||
("panic_implementation", Normal, Gated(Stability::Unstable,
|
||||
"panic_implementation",
|
||||
"#[panic_implementation] is an unstable feature",
|
||||
cfg_fn!(panic_implementation))),
|
||||
|
||||
// Crate level attributes
|
||||
("crate_name", CrateLevel, Ungated),
|
||||
("crate_type", CrateLevel, Ungated),
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
fn panic_fmt() -> ! {
|
||||
//~^ ERROR: duplicate lang item found: `panic_fmt`.
|
||||
use std::panic::PanicInfo;
|
||||
|
||||
#[lang = "panic_impl"]
|
||||
fn panic_impl(info: &PanicInfo) -> ! {
|
||||
//~^ ERROR: duplicate lang item found: `panic_impl`.
|
||||
loop {}
|
||||
}
|
||||
|
||||
|
|
21
src/test/compile-fail/feature-gate-panic-implementation.rs
Normal file
21
src/test/compile-fail/feature-gate-panic-implementation.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_implementation] //~ ERROR #[panic_implementation] is an unstable feature (see issue #44489)
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
|
@ -21,4 +21,4 @@ fn main() {
|
|||
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
#[lang = "panic_impl"] fn panic_impl() -> ! { loop {} }
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![feature(panic_implementation)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic(
|
||||
info: PanicInfo, //~ ERROR argument should be `&PanicInfo`
|
||||
) -> () //~ ERROR return type should be `!`
|
||||
{
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![feature(panic_implementation)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic(
|
||||
info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo`
|
||||
) -> !
|
||||
{
|
||||
loop {}
|
||||
}
|
|
@ -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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![feature(panic_implementation)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic() -> ! { //~ ERROR function should have one argument
|
||||
loop {}
|
||||
}
|
28
src/test/compile-fail/panic-implementation-duplicate.rs
Normal file
28
src/test/compile-fail/panic-implementation-duplicate.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![feature(lang_items)]
|
||||
#![feature(panic_implementation)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "panic_impl"]
|
||||
fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`.
|
||||
loop {}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// 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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
// error-pattern: language item required, but not found: `panic_info`
|
||||
|
||||
#![feature(lang_items)]
|
||||
#![feature(no_core)]
|
||||
#![feature(panic_implementation)]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
#[panic_implementation]
|
||||
fn panic() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
|
@ -15,8 +15,10 @@
|
|||
#![no_std]
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
fn panic_fmt() {}
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[lang = "panic_impl"]
|
||||
fn panic_impl(info: &PanicInfo) -> ! { loop {} }
|
||||
#[lang = "eh_personality"]
|
||||
fn eh_personality() {}
|
||||
#[lang = "eh_unwind_resume"]
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
// aux-build:weak-lang-items.rs
|
||||
// error-pattern: language item required, but not found: `panic_fmt`
|
||||
// error-pattern: language item required, but not found: `panic_impl`
|
||||
// error-pattern: language item required, but not found: `eh_personality`
|
||||
// ignore-wasm32-bare compiled with panic=abort, personality not required
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
#[lang = "panic_impl"]
|
||||
struct Foo; //~ ERROR E0152
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0152]: duplicate lang item found: `panic_fmt`.
|
||||
error[E0152]: duplicate lang item found: `panic_impl`.
|
||||
--> $DIR/E0152.rs:14:1
|
||||
|
|
||||
LL | struct Foo; //~ ERROR E0152
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue