Skip to content

Commit ec64817

Browse files
committed
Auto merge of #126277 - jieyouxu:rollup-qn4o157, r=jieyouxu
Rollup of 7 pull requests Successful merges: - #115974 (Split core's PanicInfo and std's PanicInfo) - #125659 (Remove usage of `isize` in example) - #125669 (CI: Update riscv64gc-linux job to Ubuntu 22.04, rename to riscv64gc-gnu) - #125684 (Account for existing bindings when suggesting `pin!()`) - #126055 (Expand list of trait implementers in E0277 when calling rustc with --verbose) - #126174 (Migrate `tests/run-make/prefer-dylib` to `rmake.rs`) - #126256 (Add {{target}} substitution to compiletest) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3ea5e23 + bc5bd47 commit ec64817

File tree

26 files changed

+529
-353
lines changed

26 files changed

+529
-353
lines changed

compiler/rustc_driver_impl/src/lib.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use std::ffi::OsString;
5252
use std::fmt::Write as _;
5353
use std::fs::{self, File};
5454
use std::io::{self, IsTerminal, Read, Write};
55-
use std::panic::{self, catch_unwind, PanicInfo};
55+
use std::panic::{self, catch_unwind, PanicHookInfo};
5656
use std::path::PathBuf;
5757
use std::process::{self, Command, Stdio};
5858
use std::str;
@@ -1366,11 +1366,10 @@ pub fn install_ice_hook(
13661366
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
13671367
let using_internal_features_hook = using_internal_features.clone();
13681368
panic::update_hook(Box::new(
1369-
move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static),
1370-
info: &PanicInfo<'_>| {
1369+
move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static),
1370+
info: &PanicHookInfo<'_>| {
13711371
// Lock stderr to prevent interleaving of concurrent panics.
13721372
let _guard = io::stderr().lock();
1373-
13741373
// If the error was caused by a broken pipe then this is not a bug.
13751374
// Write the error and return immediately. See #98700.
13761375
#[cfg(windows)]
@@ -1431,7 +1430,7 @@ pub fn install_ice_hook(
14311430
/// When `install_ice_hook` is called, this function will be called as the panic
14321431
/// hook.
14331432
fn report_ice(
1434-
info: &panic::PanicInfo<'_>,
1433+
info: &panic::PanicHookInfo<'_>,
14351434
bug_report_url: &str,
14361435
extra_info: fn(&DiagCtxt),
14371436
using_internal_features: &AtomicBool,

compiler/rustc_hir_typeck/src/method/suggest.rs

+60-8
Original file line numberDiff line numberDiff line change
@@ -3360,14 +3360,66 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33603360
.source_map()
33613361
.indentation_before(rcvr.span)
33623362
.unwrap_or_else(|| " ".to_string());
3363-
err.multipart_suggestion(
3364-
"consider pinning the expression",
3365-
vec![
3366-
(rcvr.span.shrink_to_lo(), format!("let mut pinned = std::pin::pin!(")),
3367-
(rcvr.span.shrink_to_hi(), format!(");\n{indent}pinned.{pin_call}()")),
3368-
],
3369-
Applicability::MaybeIncorrect,
3370-
);
3363+
let mut expr = rcvr;
3364+
while let Node::Expr(call_expr) = self.tcx.parent_hir_node(expr.hir_id)
3365+
&& let hir::ExprKind::MethodCall(hir::PathSegment { .. }, ..) =
3366+
call_expr.kind
3367+
{
3368+
expr = call_expr;
3369+
}
3370+
match self.tcx.parent_hir_node(expr.hir_id) {
3371+
Node::LetStmt(stmt)
3372+
if let Some(init) = stmt.init
3373+
&& let Ok(code) =
3374+
self.tcx.sess.source_map().span_to_snippet(rcvr.span) =>
3375+
{
3376+
// We need to take care to account for the existing binding when we
3377+
// suggest the code.
3378+
err.multipart_suggestion(
3379+
"consider pinning the expression",
3380+
vec![
3381+
(
3382+
stmt.span.shrink_to_lo(),
3383+
format!(
3384+
"let mut pinned = std::pin::pin!({code});\n{indent}"
3385+
),
3386+
),
3387+
(
3388+
init.span.until(rcvr.span.shrink_to_hi()),
3389+
format!("pinned.{pin_call}()"),
3390+
),
3391+
],
3392+
Applicability::MaybeIncorrect,
3393+
);
3394+
}
3395+
Node::Block(_) | Node::Stmt(_) => {
3396+
// There's no binding, so we can provide a slightly nicer looking
3397+
// suggestion.
3398+
err.multipart_suggestion(
3399+
"consider pinning the expression",
3400+
vec![
3401+
(
3402+
rcvr.span.shrink_to_lo(),
3403+
format!("let mut pinned = std::pin::pin!("),
3404+
),
3405+
(
3406+
rcvr.span.shrink_to_hi(),
3407+
format!(");\n{indent}pinned.{pin_call}()"),
3408+
),
3409+
],
3410+
Applicability::MaybeIncorrect,
3411+
);
3412+
}
3413+
_ => {
3414+
// We don't quite know what the users' code looks like, so we don't
3415+
// provide a pinning suggestion.
3416+
err.span_help(
3417+
rcvr.span,
3418+
"consider pinning the expression with `std::pin::pin!()` and \
3419+
assigning that to a new binding",
3420+
);
3421+
}
3422+
}
33713423
// We don't care about the other suggestions.
33723424
alt_rcvr_sugg = true;
33733425
}

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ declare_lint! {
142142
/// ```rust,compile_fail
143143
/// #![deny(box_pointers)]
144144
/// struct Foo {
145-
/// x: Box<isize>,
145+
/// x: Box<i32>,
146146
/// }
147147
/// ```
148148
///

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2069,12 +2069,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20692069
})
20702070
.collect();
20712071

2072-
let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
2072+
let end = if candidates.len() <= 9 || self.tcx.sess.opts.verbose {
2073+
candidates.len()
2074+
} else {
2075+
8
2076+
};
20732077
err.help(format!(
20742078
"the following {other}types implement trait `{}`:{}{}",
20752079
trait_ref.print_trait_sugared(),
20762080
candidates[..end].join(""),
2077-
if candidates.len() > 9 {
2081+
if candidates.len() > 9 && !self.tcx.sess.opts.verbose {
20782082
format!("\nand {} others", candidates.len() - 8)
20792083
} else {
20802084
String::new()

library/core/src/error.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ The following are the primary interfaces of the panic system and the
1717
responsibilities they cover:
1818

1919
* [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
20-
* [`PanicInfo`] (Reporting)
21-
* [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting)
20+
* [`set_hook`], [`take_hook`], and [`PanicHookInfo`] (Reporting)
21+
* [`#[panic_handler]`][panic-handler] and [`PanicInfo`] (Reporting in no_std)
2222
* [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
2323

2424
The following are the primary interfaces of the error system and the
@@ -125,6 +125,7 @@ expect-as-precondition style error messages remember to focus on the word
125125
should be available and executable by the current user".
126126

127127
[`panic_any`]: ../../std/panic/fn.panic_any.html
128+
[`PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html
128129
[`PanicInfo`]: crate::panic::PanicInfo
129130
[`catch_unwind`]: ../../std/panic/fn.catch_unwind.html
130131
[`resume_unwind`]: ../../std/panic/fn.resume_unwind.html

library/core/src/panic.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub macro unreachable_2021 {
144144
/// use.
145145
#[unstable(feature = "std_internals", issue = "none")]
146146
#[doc(hidden)]
147-
pub unsafe trait PanicPayload {
147+
pub unsafe trait PanicPayload: crate::fmt::Display {
148148
/// Take full ownership of the contents.
149149
/// The return type is actually `Box<dyn Any + Send>`, but we cannot use `Box` in core.
150150
///
@@ -157,4 +157,9 @@ pub unsafe trait PanicPayload {
157157

158158
/// Just borrow the contents.
159159
fn get(&mut self) -> &(dyn Any + Send);
160+
161+
/// Try to borrow the contents as `&str`, if possible without doing any allocations.
162+
fn as_str(&mut self) -> Option<&str> {
163+
None
164+
}
160165
}

library/core/src/panic/location.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use crate::fmt;
22

33
/// A struct containing information about the location of a panic.
44
///
5-
/// This structure is created by [`PanicInfo::location()`].
5+
/// This structure is created by [`PanicHookInfo::location()`] and [`PanicInfo::location()`].
66
///
77
/// [`PanicInfo::location()`]: crate::panic::PanicInfo::location
8+
/// [`PanicHookInfo::location()`]: ../../std/panic/struct.PanicHookInfo.html#method.location
89
///
910
/// # Examples
1011
///

library/core/src/panic/panic_info.rs

+28-78
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,40 @@
1-
use crate::any::Any;
21
use crate::fmt;
32
use crate::panic::Location;
43

54
/// A struct providing information about a panic.
65
///
7-
/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
8-
/// function.
6+
/// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`.
97
///
10-
/// [`set_hook`]: ../../std/panic/fn.set_hook.html
8+
/// For the type used by the panic hook mechanism in `std`, see [`std::panic::PanicHookInfo`].
119
///
12-
/// # Examples
13-
///
14-
/// ```should_panic
15-
/// use std::panic;
16-
///
17-
/// panic::set_hook(Box::new(|panic_info| {
18-
/// println!("panic occurred: {panic_info}");
19-
/// }));
20-
///
21-
/// panic!("critical system failure");
22-
/// ```
10+
/// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html
2311
#[lang = "panic_info"]
2412
#[stable(feature = "panic_hooks", since = "1.10.0")]
2513
#[derive(Debug)]
2614
pub struct PanicInfo<'a> {
27-
payload: &'a (dyn Any + Send),
28-
message: Option<&'a fmt::Arguments<'a>>,
15+
message: fmt::Arguments<'a>,
2916
location: &'a Location<'a>,
3017
can_unwind: bool,
3118
force_no_backtrace: bool,
3219
}
3320

3421
impl<'a> PanicInfo<'a> {
35-
#[unstable(
36-
feature = "panic_internals",
37-
reason = "internal details of the implementation of the `panic!` and related macros",
38-
issue = "none"
39-
)]
40-
#[doc(hidden)]
4122
#[inline]
42-
pub fn internal_constructor(
43-
message: Option<&'a fmt::Arguments<'a>>,
23+
pub(crate) fn new(
24+
message: fmt::Arguments<'a>,
4425
location: &'a Location<'a>,
4526
can_unwind: bool,
4627
force_no_backtrace: bool,
4728
) -> Self {
48-
struct NoPayload;
49-
PanicInfo { location, message, payload: &NoPayload, can_unwind, force_no_backtrace }
50-
}
51-
52-
#[unstable(
53-
feature = "panic_internals",
54-
reason = "internal details of the implementation of the `panic!` and related macros",
55-
issue = "none"
56-
)]
57-
#[doc(hidden)]
58-
#[inline]
59-
pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
60-
self.payload = info;
61-
}
62-
63-
/// Returns the payload associated with the panic.
64-
///
65-
/// This will commonly, but not always, be a `&'static str` or [`String`].
66-
///
67-
/// [`String`]: ../../std/string/struct.String.html
68-
///
69-
/// # Examples
70-
///
71-
/// ```should_panic
72-
/// use std::panic;
73-
///
74-
/// panic::set_hook(Box::new(|panic_info| {
75-
/// if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
76-
/// println!("panic occurred: {s:?}");
77-
/// } else {
78-
/// println!("panic occurred");
79-
/// }
80-
/// }));
81-
///
82-
/// panic!("Normal panic");
83-
/// ```
84-
#[must_use]
85-
#[stable(feature = "panic_hooks", since = "1.10.0")]
86-
pub fn payload(&self) -> &(dyn Any + Send) {
87-
self.payload
29+
PanicInfo { location, message, can_unwind, force_no_backtrace }
8830
}
8931

9032
/// If the `panic!` macro from the `core` crate (not from `std`)
9133
/// was used with a formatting string and some additional arguments,
9234
/// returns that message ready to be used for example with [`fmt::write`]
9335
#[must_use]
9436
#[unstable(feature = "panic_info_message", issue = "66745")]
95-
pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
37+
pub fn message(&self) -> fmt::Arguments<'_> {
9638
self.message
9739
}
9840

@@ -128,6 +70,24 @@ impl<'a> PanicInfo<'a> {
12870
Some(&self.location)
12971
}
13072

73+
/// Returns the payload associated with the panic.
74+
///
75+
/// On `core::panic::PanicInfo`, this method never returns anything useful.
76+
/// It only exists because of compatibility with [`std::panic::PanicHookInfo`],
77+
/// which used to be the same type.
78+
///
79+
/// See [`std::panic::PanicHookInfo::payload`].
80+
///
81+
/// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html
82+
/// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload
83+
#[deprecated(since = "1.77.0", note = "this never returns anything useful")]
84+
#[stable(feature = "panic_hooks", since = "1.10.0")]
85+
#[allow(deprecated, deprecated_in_future)]
86+
pub fn payload(&self) -> &(dyn crate::any::Any + Send) {
87+
struct NoPayload;
88+
&NoPayload
89+
}
90+
13191
/// Returns whether the panic handler is allowed to unwind the stack from
13292
/// the point where the panic occurred.
13393
///
@@ -161,18 +121,8 @@ impl fmt::Display for PanicInfo<'_> {
161121
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
162122
formatter.write_str("panicked at ")?;
163123
self.location.fmt(formatter)?;
164-
formatter.write_str(":")?;
165-
if let Some(message) = self.message {
166-
formatter.write_str("\n")?;
167-
formatter.write_fmt(*message)?;
168-
} else if let Some(payload) = self.payload.downcast_ref::<&'static str>() {
169-
formatter.write_str("\n")?;
170-
formatter.write_str(payload)?;
171-
}
172-
// NOTE: we cannot use downcast_ref::<String>() here
173-
// since String is not available in core!
174-
// The payload is a String when `std::panic!` is called with multiple arguments,
175-
// but in that case the message is also available.
124+
formatter.write_str(":\n")?;
125+
formatter.write_fmt(self.message)?;
176126
Ok(())
177127
}
178128
}

library/core/src/panicking.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
//! Panic support for core
22
//!
3-
//! The core library cannot define panicking, but it does *declare* panicking. This
4-
//! means that the functions inside of core are allowed to panic, but to be
3+
//! In core, panicking is always done with a message, resulting in a `core::panic::PanicInfo`
4+
//! containing a `fmt::Arguments`. In std, however, panicking can be done with panic_any, which
5+
//! throws a `Box<dyn Any>` containing any type of value. Because of this,
6+
//! `std::panic::PanicHookInfo` is a different type, which contains a `&dyn Any` instead of a
7+
//! `fmt::Arguments`. std's panic handler will convert the `fmt::Arguments` to a `&dyn Any`
8+
//! containing either a `&'static str` or `String` containing the formatted message.
9+
//!
10+
//! The core library cannot define any panic handler, but it can invoke it.
11+
//! This means that the functions inside of core are allowed to panic, but to be
512
//! useful an upstream crate must define panicking for core to use. The current
613
//! interface for panicking is:
714
//!
@@ -10,11 +17,6 @@
1017
//! # { loop {} }
1118
//! ```
1219
//!
13-
//! This definition allows for panicking with any general message, but it does not
14-
//! allow for failing with a `Box<Any>` value. (`PanicInfo` just contains a `&(dyn Any + Send)`,
15-
//! for which we fill in a dummy value in `PanicInfo::internal_constructor`.)
16-
//! The reason for this is that core is not allowed to allocate.
17-
//!
1820
//! This module contains a few other panicking functions, but these are just the
1921
//! necessary lang items for the compiler. All panics are funneled through this
2022
//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
@@ -61,8 +63,8 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
6163
fn panic_impl(pi: &PanicInfo<'_>) -> !;
6264
}
6365

64-
let pi = PanicInfo::internal_constructor(
65-
Some(&fmt),
66+
let pi = PanicInfo::new(
67+
fmt,
6668
Location::caller(),
6769
/* can_unwind */ true,
6870
/* force_no_backtrace */ false,
@@ -99,8 +101,8 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
99101
}
100102

101103
// PanicInfo with the `can_unwind` flag set to false forces an abort.
102-
let pi = PanicInfo::internal_constructor(
103-
Some(&fmt),
104+
let pi = PanicInfo::new(
105+
fmt,
104106
Location::caller(),
105107
/* can_unwind */ false,
106108
force_no_backtrace,

0 commit comments

Comments
 (0)