Skip to content

Commit 7e02fd8

Browse files
committed
Auto merge of rust-lang#115303 - matthiaskrgr:rollup-iohs8a5, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#109660 (Document that SystemTime does not count leap seconds) - rust-lang#114238 (Fix implementation of `Duration::checked_div`) - rust-lang#114512 (std/tests: disable ancillary tests on freebsd since the feature itsel…) - rust-lang#114919 (style-guide: Add guidance for defining formatting for specific macros) - rust-lang#115278 (tell people what to do when removing an error code) - rust-lang#115280 (avoid triple-backtrace due to panic-during-cleanup) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 41cb42a + 32053f7 commit 7e02fd8

File tree

17 files changed

+134
-39
lines changed

17 files changed

+134
-39
lines changed

compiler/rustc_error_codes/src/error_codes.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ E0793: include_str!("./error_codes/E0793.md"),
516516
E0794: include_str!("./error_codes/E0794.md"),
517517
}
518518

519-
// Undocumented removed error codes. Note that many removed error codes are documented.
519+
// Undocumented removed error codes. Note that many removed error codes are kept in the list above
520+
// and marked as no-longer emitted with a note in the markdown file (see E0001 for an example).
520521
// E0006, // merged with E0005
521522
// E0008, // cannot bind by-move into a pattern guard
522523
// E0019, // merged into E0015

library/alloc/src/alloc.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,10 @@ pub mod __alloc_error_handler {
408408
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
409409
panic!("memory allocation of {size} bytes failed")
410410
} else {
411-
core::panicking::panic_nounwind_fmt(format_args!(
412-
"memory allocation of {size} bytes failed"
413-
))
411+
core::panicking::panic_nounwind_fmt(
412+
format_args!("memory allocation of {size} bytes failed"),
413+
/* force_no_backtrace */ false,
414+
)
414415
}
415416
}
416417
}

library/core/src/panic/panic_info.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct PanicInfo<'a> {
2828
message: Option<&'a fmt::Arguments<'a>>,
2929
location: &'a Location<'a>,
3030
can_unwind: bool,
31+
force_no_backtrace: bool,
3132
}
3233

3334
impl<'a> PanicInfo<'a> {
@@ -42,9 +43,10 @@ impl<'a> PanicInfo<'a> {
4243
message: Option<&'a fmt::Arguments<'a>>,
4344
location: &'a Location<'a>,
4445
can_unwind: bool,
46+
force_no_backtrace: bool,
4547
) -> Self {
4648
struct NoPayload;
47-
PanicInfo { location, message, payload: &NoPayload, can_unwind }
49+
PanicInfo { location, message, payload: &NoPayload, can_unwind, force_no_backtrace }
4850
}
4951

5052
#[unstable(
@@ -141,6 +143,17 @@ impl<'a> PanicInfo<'a> {
141143
pub fn can_unwind(&self) -> bool {
142144
self.can_unwind
143145
}
146+
147+
#[unstable(
148+
feature = "panic_internals",
149+
reason = "internal details of the implementation of the `panic!` and related macros",
150+
issue = "none"
151+
)]
152+
#[doc(hidden)]
153+
#[inline]
154+
pub fn force_no_backtrace(&self) -> bool {
155+
self.force_no_backtrace
156+
}
144157
}
145158

146159
#[stable(feature = "panic_hook_display", since = "1.26.0")]

library/core/src/panicking.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
6161
fn panic_impl(pi: &PanicInfo<'_>) -> !;
6262
}
6363

64-
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true);
64+
let pi = PanicInfo::internal_constructor(
65+
Some(&fmt),
66+
Location::caller(),
67+
/* can_unwind */ true,
68+
/* force_no_backtrace */ false,
69+
);
6570

6671
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
6772
unsafe { panic_impl(&pi) }
@@ -77,7 +82,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
7782
// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
7883
// which causes a "panic in a function that cannot unwind".
7984
#[rustc_nounwind]
80-
pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! {
85+
pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
8186
if cfg!(feature = "panic_immediate_abort") {
8287
super::intrinsics::abort()
8388
}
@@ -90,7 +95,12 @@ pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! {
9095
}
9196

9297
// PanicInfo with the `can_unwind` flag set to false forces an abort.
93-
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false);
98+
let pi = PanicInfo::internal_constructor(
99+
Some(&fmt),
100+
Location::caller(),
101+
/* can_unwind */ false,
102+
force_no_backtrace,
103+
);
94104

95105
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
96106
unsafe { panic_impl(&pi) }
@@ -123,7 +133,15 @@ pub const fn panic(expr: &'static str) -> ! {
123133
#[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics
124134
#[rustc_nounwind]
125135
pub fn panic_nounwind(expr: &'static str) -> ! {
126-
panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]));
136+
panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false);
137+
}
138+
139+
/// Like `panic_nounwind`, but also inhibits showing a backtrace.
140+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
141+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
142+
#[rustc_nounwind]
143+
pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! {
144+
panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true);
127145
}
128146

129147
#[inline]
@@ -172,9 +190,12 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
172190
super::intrinsics::abort()
173191
}
174192

175-
panic_nounwind_fmt(format_args!(
176-
"misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}"
177-
))
193+
panic_nounwind_fmt(
194+
format_args!(
195+
"misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}"
196+
),
197+
/* force_no_backtrace */ false,
198+
)
178199
}
179200

180201
/// Panic because we cannot unwind out of a function.
@@ -205,7 +226,7 @@ fn panic_cannot_unwind() -> ! {
205226
#[rustc_nounwind]
206227
fn panic_in_cleanup() -> ! {
207228
// Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
208-
panic_nounwind("panic in a destructor during cleanup")
229+
panic_nounwind_nobacktrace("panic in a destructor during cleanup")
209230
}
210231

211232
/// This function is used instead of panic_fmt in const eval.

library/core/src/time.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,10 @@ impl Duration {
656656
#[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
657657
pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
658658
if rhs != 0 {
659-
let secs = self.secs / (rhs as u64);
660-
let carry = self.secs - secs * (rhs as u64);
661-
let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
662-
let nanos = self.nanos.0 / rhs + (extra_nanos as u32);
659+
let (secs, extra_secs) = (self.secs / (rhs as u64), self.secs % (rhs as u64));
660+
let (mut nanos, extra_nanos) = (self.nanos.0 / rhs, self.nanos.0 % rhs);
661+
nanos +=
662+
((extra_secs * (NANOS_PER_SEC as u64) + extra_nanos as u64) / (rhs as u64)) as u32;
663663
debug_assert!(nanos < NANOS_PER_SEC);
664664
Some(Duration::new(secs, nanos))
665665
} else {

library/core/tests/time.rs

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ fn saturating_mul() {
170170
fn div() {
171171
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
172172
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
173+
assert_eq!(Duration::new(1, 1) / 7, Duration::new(0, 142_857_143));
173174
assert_eq!(Duration::new(99, 999_999_000) / 100, Duration::new(0, 999_999_990));
174175
}
175176

library/std/src/os/unix/net/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ fn test_send_vectored_fds_unix_stream() {
662662
}
663663
}
664664

665-
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
665+
#[cfg(any(target_os = "android", target_os = "linux"))]
666666
#[test]
667667
#[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
668668
fn test_send_vectored_with_ancillary_to_unix_datagram() {

library/std/src/panicking.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ fn default_hook(info: &PanicInfo<'_>) {
246246
pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path::Path>) {
247247
// If this is a double panic, make sure that we print a backtrace
248248
// for this panic. Otherwise only print it if logging is enabled.
249-
let backtrace = if panic_count::get_count() >= 2 {
249+
let backtrace = if info.force_no_backtrace() {
250+
None
251+
} else if panic_count::get_count() >= 2 {
250252
BacktraceStyle::full()
251253
} else {
252254
crate::panic::get_backtrace_style()
@@ -294,7 +296,7 @@ pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path
294296
}
295297
}
296298
}
297-
// If backtraces aren't supported, do nothing.
299+
// If backtraces aren't supported or are forced-off, do nothing.
298300
None => {}
299301
}
300302
};
@@ -615,14 +617,23 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
615617
let loc = info.location().unwrap(); // The current implementation always returns Some
616618
let msg = info.message().unwrap(); // The current implementation always returns Some
617619
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
620+
// FIXME: can we just pass `info` along rather than taking it apart here, only to have
621+
// `rust_panic_with_hook` construct a new `PanicInfo`?
618622
if let Some(msg) = msg.as_str() {
619-
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind());
623+
rust_panic_with_hook(
624+
&mut StrPanicPayload(msg),
625+
info.message(),
626+
loc,
627+
info.can_unwind(),
628+
info.force_no_backtrace(),
629+
);
620630
} else {
621631
rust_panic_with_hook(
622632
&mut PanicPayload::new(msg),
623633
info.message(),
624634
loc,
625635
info.can_unwind(),
636+
info.force_no_backtrace(),
626637
);
627638
}
628639
})
@@ -647,7 +658,13 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
647658

648659
let loc = Location::caller();
649660
return crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
650-
rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc, true)
661+
rust_panic_with_hook(
662+
&mut PanicPayload::new(msg),
663+
None,
664+
loc,
665+
/* can_unwind */ true,
666+
/* force_no_backtrace */ false,
667+
)
651668
});
652669

653670
struct PanicPayload<A> {
@@ -693,6 +710,7 @@ fn rust_panic_with_hook(
693710
message: Option<&fmt::Arguments<'_>>,
694711
location: &Location<'_>,
695712
can_unwind: bool,
713+
force_no_backtrace: bool,
696714
) -> ! {
697715
let must_abort = panic_count::increase(true);
698716

@@ -707,14 +725,20 @@ fn rust_panic_with_hook(
707725
panic_count::MustAbort::AlwaysAbort => {
708726
// Unfortunately, this does not print a backtrace, because creating
709727
// a `Backtrace` will allocate, which we must to avoid here.
710-
let panicinfo = PanicInfo::internal_constructor(message, location, can_unwind);
728+
let panicinfo = PanicInfo::internal_constructor(
729+
message,
730+
location,
731+
can_unwind,
732+
force_no_backtrace,
733+
);
711734
rtprintpanic!("{panicinfo}\npanicked after panic::always_abort(), aborting.\n");
712735
}
713736
}
714737
crate::sys::abort_internal();
715738
}
716739

717-
let mut info = PanicInfo::internal_constructor(message, location, can_unwind);
740+
let mut info =
741+
PanicInfo::internal_constructor(message, location, can_unwind, force_no_backtrace);
718742
let hook = HOOK.read().unwrap_or_else(PoisonError::into_inner);
719743
match *hook {
720744
// Some platforms (like wasm) know that printing to stderr won't ever actually

library/std/src/time.rs

+24
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ pub struct Instant(time::Instant);
176176
/// The size of a `SystemTime` struct may vary depending on the target operating
177177
/// system.
178178
///
179+
/// A `SystemTime` does not count leap seconds.
180+
/// `SystemTime::now()`'s behaviour around a leap second
181+
/// is the same as the operating system's wall clock.
182+
/// The precise behaviour near a leap second
183+
/// (e.g. whether the clock appears to run slow or fast, or stop, or jump)
184+
/// depends on platform and configuration,
185+
/// so should not be relied on.
186+
///
179187
/// Example:
180188
///
181189
/// ```no_run
@@ -461,13 +469,21 @@ impl fmt::Debug for Instant {
461469
impl SystemTime {
462470
/// An anchor in time which can be used to create new `SystemTime` instances or
463471
/// learn about where in time a `SystemTime` lies.
472+
//
473+
// NOTE! this documentation is duplicated, here and in std::time::UNIX_EPOCH.
474+
// The two copies are not quite identical, because of the difference in naming.
464475
///
465476
/// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
466477
/// respect to the system clock. Using `duration_since` on an existing
467478
/// `SystemTime` instance can tell how far away from this point in time a
468479
/// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
469480
/// `SystemTime` instance to represent another fixed point in time.
470481
///
482+
/// `duration_since(UNIX_EPOCH).unwrap().as_secs()` returns
483+
/// the number of non-leap seconds since the start of 1970 UTC.
484+
/// This is a POSIX `time_t` (as a `u64`),
485+
/// and is the same time representation as used in many Internet protocols.
486+
///
471487
/// # Examples
472488
///
473489
/// ```no_run
@@ -617,13 +633,21 @@ impl fmt::Debug for SystemTime {
617633

618634
/// An anchor in time which can be used to create new `SystemTime` instances or
619635
/// learn about where in time a `SystemTime` lies.
636+
//
637+
// NOTE! this documentation is duplicated, here and in SystemTime::UNIX_EPOCH.
638+
// The two copies are not quite identical, because of the difference in naming.
620639
///
621640
/// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
622641
/// respect to the system clock. Using `duration_since` on an existing
623642
/// [`SystemTime`] instance can tell how far away from this point in time a
624643
/// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
625644
/// [`SystemTime`] instance to represent another fixed point in time.
626645
///
646+
/// `duration_since(UNIX_EPOCH).unwrap().as_secs()` returns
647+
/// the number of non-leap seconds since the start of 1970 UTC.
648+
/// This is a POSIX `time_t` (as a `u64`),
649+
/// and is the same time representation as used in many Internet protocols.
650+
///
627651
/// # Examples
628652
///
629653
/// ```no_run

src/doc/style-guide/src/expressions.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,12 @@ constructs. For example, a macro use `foo!(a, b, c)` can be parsed like a
400400
function call (ignoring the `!`), so format it using the rules for function
401401
calls.
402402

403-
### Special case macros
403+
The style guide defines specific formatting for particular macros in the
404+
language or standard library. The style guide does not define formatting for
405+
any third-party macros, even if similar to those in the language or standard
406+
library.
407+
408+
### Format string macros
404409

405410
For macros which take a format string, if all other arguments are *small*,
406411
format the arguments before the format string on a single line if they fit, and

src/tools/miri/tests/fail/panic/double_panic.stderr

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ second
66
stack backtrace:
77
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
88
panic in a destructor during cleanup
9-
stack backtrace:
109
thread caused non-unwinding panic. aborting.
1110
error: abnormal termination: the program aborted execution
1211
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
@@ -19,7 +18,7 @@ LL | ABORT();
1918
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
2019
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
2120
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
22-
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
21+
= note: inside `core::panicking::panic_nounwind_nobacktrace` at RUSTLIB/core/src/panicking.rs:LL:CC
2322
= note: inside `core::panicking::panic_in_cleanup` at RUSTLIB/core/src/panicking.rs:LL:CC
2423
note: inside `main`
2524
--> $DIR/double_panic.rs:LL:CC

src/tools/tidy/src/error_codes.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,12 @@ fn check_error_codes_used(
354354

355355
for code in error_codes {
356356
if !found_codes.contains(code) && !no_longer_emitted.contains(code) {
357-
errors.push(format!("Error code `{code}` exists, but is not emitted by the compiler!"))
357+
errors.push(format!(
358+
"Error code `{code}` exists, but is not emitted by the compiler!\n\
359+
Please mark the code as no longer emitted by adding the following note to the top of the `EXXXX.md` file:\n\
360+
`#### Note: this error code is no longer emitted by the compiler`\n\
361+
Also, do not forget to mark doctests that no longer apply as `ignore (error is no longer emitted)`."
362+
));
358363
}
359364

360365
if found_codes.contains(code) && no_longer_emitted.contains(code) {

tests/ui/backtrace.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fn runtest(me: &str) {
9494
#[cfg(not(panic = "abort"))]
9595
{
9696
// Make sure a stack trace is printed
97-
let p = template(me).arg("double-fail").spawn().unwrap();
97+
let p = template(me).arg("double-fail").env("RUST_BACKTRACE","0").spawn().unwrap();
9898
let out = p.wait_with_output().unwrap();
9999
assert!(!out.status.success());
100100
let s = str::from_utf8(&out.stderr).unwrap();
@@ -106,18 +106,18 @@ fn runtest(me: &str) {
106106
contains_verbose_expected(s, "double"),
107107
"bad output3: {}", s
108108
);
109+
// Make sure it's only one stack trace.
110+
assert_eq!(s.split("stack backtrace").count(), 2);
109111

110112
// Make sure a stack trace isn't printed too many times
111-
//
112-
// Currently it is printed 3 times ("once", "twice" and "panic in a destructor during
113-
// cleanup") but in the future the last one may be removed.
113+
// even with RUST_BACKTRACE=1. It should be printed twice.
114114
let p = template(me).arg("double-fail")
115115
.env("RUST_BACKTRACE", "1").spawn().unwrap();
116116
let out = p.wait_with_output().unwrap();
117117
assert!(!out.status.success());
118118
let s = str::from_utf8(&out.stderr).unwrap();
119119
let mut i = 0;
120-
for _ in 0..3 {
120+
for _ in 0..2 {
121121
i += s[i + 10..].find("stack backtrace").unwrap() + 10;
122122
}
123123
assert!(s[i + 10..].find("stack backtrace").is_none(),

0 commit comments

Comments
 (0)