about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/macros/mod.rs3
-rw-r--r--library/core/src/macros/panic.md30
-rw-r--r--library/core/src/marker.rs10
-rw-r--r--library/core/src/net/ip_addr.rs8
-rw-r--r--library/core/src/num/f32.rs20
-rw-r--r--library/core/src/num/f64.rs20
-rw-r--r--library/core/src/ops/drop.rs10
-rw-r--r--library/core/src/panic/panic_info.rs15
-rw-r--r--library/core/src/panicking.rs37
-rw-r--r--library/core/src/time.rs8
10 files changed, 127 insertions, 34 deletions
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 14cc523b0c1..46628bcea00 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -849,7 +849,8 @@ pub(crate) mod builtin {
     /// assert_eq!(display, debug);
     /// ```
     ///
-    /// For more information, see the documentation in [`std::fmt`].
+    /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html)
+    /// for details of the macro argument syntax, and further information.
     ///
     /// [`Display`]: crate::fmt::Display
     /// [`Debug`]: crate::fmt::Debug
diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md
index 8b549e187ba..60100c2655a 100644
--- a/library/core/src/macros/panic.md
+++ b/library/core/src/macros/panic.md
@@ -8,8 +8,8 @@ tests. `panic!` is closely tied with the `unwrap` method of both
 [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call
 `panic!` when they are set to [`None`] or [`Err`] variants.
 
-When using `panic!()` you can specify a string payload, that is built using
-the [`format!`] syntax. That payload is used when injecting the panic into
+When using `panic!()` you can specify a string payload that is built using
+[formatting syntax]. That payload is used when injecting the panic into
 the calling Rust thread, causing the thread to panic entirely.
 
 The behavior of the default `std` hook, i.e. the code that runs directly
@@ -18,6 +18,7 @@ after the panic is invoked, is to print the message payload to
 call. You can override the panic hook using [`std::panic::set_hook()`].
 Inside the hook a panic can be accessed as a `&dyn Any + Send`,
 which contains either a `&str` or `String` for regular `panic!()` invocations.
+(Whether a particular invocation contains the payload at type `&str` or `String` is unspecified and can change.)
 To panic with a value of another other type, [`panic_any`] can be used.
 
 See also the macro [`compile_error!`], for raising errors during compilation.
@@ -55,7 +56,7 @@ For more detailed information about error handling check out the [book] or the
 [`panic_any`]: ../std/panic/fn.panic_any.html
 [`Box`]: ../std/boxed/struct.Box.html
 [`Any`]: crate::any::Any
-[`format!`]: ../std/macro.format.html
+[`format!` syntax]: ../std/fmt/index.html
 [book]: ../book/ch09-00-error-handling.html
 [`std::result`]: ../std/result/index.html
 
@@ -64,6 +65,29 @@ For more detailed information about error handling check out the [book] or the
 If the main thread panics it will terminate all your threads and end your
 program with code `101`.
 
+# Editions
+
+Behavior of the panic macros changed over editions.
+
+## 2021 and later
+
+In Rust 2021 and later, `panic!` always requires a format string and
+the applicable format arguments, and is the same in `core` and `std`.
+Use [`std::panic::panic_any(x)`](../std/panic/fn.panic_any.html) to
+panic with an arbitrary payload.
+
+## 2018 and 2015
+
+In Rust Editions prior to 2021, `std::panic!(x)` with a single
+argument directly uses that argument as a payload.
+This is true even if the argument is a string literal.
+For example, `panic!("problem: {reason}")` panics with a
+payload of literally `"problem: {reason}"` (a `&'static str`).
+
+`core::panic!(x)` with a single argument requires that `x` be `&str`,
+but otherwise behaves like `std::panic!`. In particular, the string
+need not be a literal, and is not interpreted as a format string.
+
 # Examples
 
 ```should_panic
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index aec287226a0..5ec751e5168 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -76,11 +76,8 @@ macro marker_impls {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "Send")]
 #[rustc_on_unimplemented(
-    on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
     message = "`{Self}` cannot be sent between threads safely",
-    label = "`{Self}` cannot be sent between threads safely",
-    note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
-            <https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
+    label = "`{Self}` cannot be sent between threads safely"
 )]
 pub unsafe auto trait Send {
     // empty.
@@ -631,11 +628,8 @@ impl<T: ?Sized> Copy for &T {}
         any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"),
         note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
     ),
-    on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
     message = "`{Self}` cannot be shared between threads safely",
-    label = "`{Self}` cannot be shared between threads safely",
-    note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
-            <https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
+    label = "`{Self}` cannot be shared between threads safely"
 )]
 pub unsafe auto trait Sync {
     // FIXME(estebank): once support to add notes in `rustc_on_unimplemented`
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 56460c75eba..6a36dfec098 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1856,13 +1856,7 @@ impl fmt::Display for Ipv6Addr {
         if f.precision().is_none() && f.width().is_none() {
             let segments = self.segments();
 
-            // Special case for :: and ::1; otherwise they get written with the
-            // IPv4 formatter
-            if self.is_unspecified() {
-                f.write_str("::")
-            } else if self.is_loopback() {
-                f.write_str("::1")
-            } else if let Some(ipv4) = self.to_ipv4_mapped() {
+            if let Some(ipv4) = self.to_ipv4_mapped() {
                 write!(f, "::ffff:{}", ipv4)
             } else {
                 #[derive(Copy, Clone, Default)]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index d050d21c8c5..3144db19707 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -277,6 +277,14 @@ pub mod consts {
     #[stable(feature = "tau_constant", since = "1.47.0")]
     pub const TAU: f32 = 6.28318530717958647692528676655900577_f32;
 
+    /// The golden ratio (φ)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const PHI: f32 = 1.618033988749894848204586834365638118_f32;
+
+    /// The Euler-Mascheroni constant (γ)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const EGAMMA: f32 = 0.577215664901532860606512090082402431_f32;
+
     /// π/2
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
@@ -301,6 +309,10 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
 
+    /// 1/sqrt(π)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32;
+
     /// 2/π
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
@@ -317,6 +329,14 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
 
+    /// sqrt(3)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const SQRT_3: f32 = 1.732050807568877293527446341505872367_f32;
+
+    /// 1/sqrt(3)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const FRAC_1_SQRT_3: f32 = 0.577350269189625764509148780501957456_f32;
+
     /// Euler's number (e)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f32 = 2.71828182845904523536028747135266250_f32;
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index d9a738191f7..20833defc41 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -277,6 +277,14 @@ pub mod consts {
     #[stable(feature = "tau_constant", since = "1.47.0")]
     pub const TAU: f64 = 6.28318530717958647692528676655900577_f64;
 
+    /// The golden ratio (φ)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const PHI: f64 = 1.618033988749894848204586834365638118_f64;
+
+    /// The Euler-Mascheroni constant (γ)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const EGAMMA: f64 = 0.577215664901532860606512090082402431_f64;
+
     /// π/2
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
@@ -301,6 +309,10 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
 
+    /// 1/sqrt(π)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const FRAC_1_SQRT_PI: f64 = 0.564189583547756286948079451560772586_f64;
+
     /// 2/π
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
@@ -317,6 +329,14 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64;
 
+    /// sqrt(3)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const SQRT_3: f64 = 1.732050807568877293527446341505872367_f64;
+
+    /// 1/sqrt(3)
+    #[unstable(feature = "more_float_constants", issue = "103883")]
+    pub const FRAC_1_SQRT_3: f64 = 0.577350269189625764509148780501957456_f64;
+
     /// Euler's number (e)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f64 = 2.71828182845904523536028747135266250_f64;
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index 9ebf426be95..21c23dabfc2 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -217,8 +217,13 @@ pub trait Drop {
     ///
     /// # Panics
     ///
-    /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
-    /// in a `drop` implementation will likely abort.
+    /// Implementations should generally avoid [`panic!`]ing, because `drop()` may itself be called
+    /// during unwinding due to a panic, and if the `drop()` panics in that situation (a “double
+    /// panic”), this will likely abort the program. It is possible to check [`panicking()`] first,
+    /// which may be desirable for a `Drop` implementation that is reporting a bug of the kind
+    /// “you didn't finish using this before it was dropped”; but most types should simply clean up
+    /// their owned allocations or other resources and return normally from `drop()`, regardless of
+    /// what state they are in.
     ///
     /// Note that even if this panics, the value is considered to be dropped;
     /// you must not cause `drop` to be called again. This is normally automatically
@@ -227,6 +232,7 @@ pub trait Drop {
     ///
     /// [E0040]: ../../error_codes/E0040.html
     /// [`panic!`]: crate::panic!
+    /// [`panicking()`]: ../../std/thread/fn.panicking.html
     /// [`mem::drop`]: drop
     /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs
index c7f04f11ef6..c77e9675a6a 100644
--- a/library/core/src/panic/panic_info.rs
+++ b/library/core/src/panic/panic_info.rs
@@ -28,6 +28,7 @@ pub struct PanicInfo<'a> {
     message: Option<&'a fmt::Arguments<'a>>,
     location: &'a Location<'a>,
     can_unwind: bool,
+    force_no_backtrace: bool,
 }
 
 impl<'a> PanicInfo<'a> {
@@ -42,9 +43,10 @@ impl<'a> PanicInfo<'a> {
         message: Option<&'a fmt::Arguments<'a>>,
         location: &'a Location<'a>,
         can_unwind: bool,
+        force_no_backtrace: bool,
     ) -> Self {
         struct NoPayload;
-        PanicInfo { location, message, payload: &NoPayload, can_unwind }
+        PanicInfo { location, message, payload: &NoPayload, can_unwind, force_no_backtrace }
     }
 
     #[unstable(
@@ -141,6 +143,17 @@ impl<'a> PanicInfo<'a> {
     pub fn can_unwind(&self) -> bool {
         self.can_unwind
     }
+
+    #[unstable(
+        feature = "panic_internals",
+        reason = "internal details of the implementation of the `panic!` and related macros",
+        issue = "none"
+    )]
+    #[doc(hidden)]
+    #[inline]
+    pub fn force_no_backtrace(&self) -> bool {
+        self.force_no_backtrace
+    }
 }
 
 #[stable(feature = "panic_hook_display", since = "1.26.0")]
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index ab6aa0df428..281f8c1e166 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -61,7 +61,12 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
         fn panic_impl(pi: &PanicInfo<'_>) -> !;
     }
 
-    let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true);
+    let pi = PanicInfo::internal_constructor(
+        Some(&fmt),
+        Location::caller(),
+        /* can_unwind */ true,
+        /* force_no_backtrace */ false,
+    );
 
     // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
     unsafe { panic_impl(&pi) }
@@ -77,7 +82,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
 // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
 // which causes a "panic in a function that cannot unwind".
 #[rustc_nounwind]
-pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! {
+pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
         super::intrinsics::abort()
     }
@@ -90,7 +95,12 @@ pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! {
     }
 
     // PanicInfo with the `can_unwind` flag set to false forces an abort.
-    let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false);
+    let pi = PanicInfo::internal_constructor(
+        Some(&fmt),
+        Location::caller(),
+        /* can_unwind */ false,
+        force_no_backtrace,
+    );
 
     // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
     unsafe { panic_impl(&pi) }
@@ -123,7 +133,15 @@ pub const fn panic(expr: &'static str) -> ! {
 #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics
 #[rustc_nounwind]
 pub fn panic_nounwind(expr: &'static str) -> ! {
-    panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]));
+    panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false);
+}
+
+/// Like `panic_nounwind`, but also inhibits showing a backtrace.
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[rustc_nounwind]
+pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! {
+    panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true);
 }
 
 #[inline]
@@ -172,9 +190,12 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
         super::intrinsics::abort()
     }
 
-    panic_nounwind_fmt(format_args!(
-        "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}"
-    ))
+    panic_nounwind_fmt(
+        format_args!(
+            "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}"
+        ),
+        /* force_no_backtrace */ false,
+    )
 }
 
 /// Panic because we cannot unwind out of a function.
@@ -205,7 +226,7 @@ fn panic_cannot_unwind() -> ! {
 #[rustc_nounwind]
 fn panic_in_cleanup() -> ! {
     // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
-    panic_nounwind("panic in a destructor during cleanup")
+    panic_nounwind_nobacktrace("panic in a destructor during cleanup")
 }
 
 /// This function is used instead of panic_fmt in const eval.
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index b08d5782ab6..1e8d28979e6 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -656,10 +656,10 @@ impl Duration {
     #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
     pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
         if rhs != 0 {
-            let secs = self.secs / (rhs as u64);
-            let carry = self.secs - secs * (rhs as u64);
-            let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
-            let nanos = self.nanos.0 / rhs + (extra_nanos as u32);
+            let (secs, extra_secs) = (self.secs / (rhs as u64), self.secs % (rhs as u64));
+            let (mut nanos, extra_nanos) = (self.nanos.0 / rhs, self.nanos.0 % rhs);
+            nanos +=
+                ((extra_secs * (NANOS_PER_SEC as u64) + extra_nanos as u64) / (rhs as u64)) as u32;
             debug_assert!(nanos < NANOS_PER_SEC);
             Some(Duration::new(secs, nanos))
         } else {