about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-10 21:59:07 +0000
committerbors <bors@rust-lang.org>2021-12-10 21:59:07 +0000
commitf0448f44bcda55fd9eb71da82495ef648eedb4e4 (patch)
treed7157697f5cdcd6bf59adb15521427a212f0dbce /library/core/src
parent0b42deaccc2cbe17a68067aa5fdb76104369e1fd (diff)
parent1fca934898354160b46c17c58b67707a2dcb8988 (diff)
downloadrust-f0448f44bcda55fd9eb71da82495ef648eedb4e4.tar.gz
rust-f0448f44bcda55fd9eb71da82495ef648eedb4e4.zip
Auto merge of #91760 - matthiaskrgr:rollup-zcemh6j, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #90407 (Document all public items in `rustc_incremental`)
 - #90897 (Fix incorrect stability attributes)
 - #91105 (Fix method name reference in stream documentation)
 - #91325 (adjust const_eval_select documentation)
 - #91470 (code-cov: generate dead functions with private/default linkage)
 - #91482 (Update documentation to use `from()` to initialize `HashMap`s and `BTreeMap`s)
 - #91524 (Fix Vec::extend_from_slice docs)
 - #91575 (Fix ICE on format string of macro with secondary-label)
 - #91625 (Remove redundant [..]s)
 - #91646 (Fix documentation for `core::ready::Ready`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/future/ready.rs2
-rw-r--r--library/core/src/intrinsics.rs49
-rw-r--r--library/core/src/num/saturating.rs2
-rw-r--r--library/core/src/num/uint_macros.rs2
-rw-r--r--library/core/src/slice/raw.rs4
-rw-r--r--library/core/src/stream/mod.rs6
6 files changed, 43 insertions, 22 deletions
diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs
index cc905d288f9..48f20f90a32 100644
--- a/library/core/src/future/ready.rs
+++ b/library/core/src/future/ready.rs
@@ -2,7 +2,7 @@ use crate::future::Future;
 use crate::pin::Pin;
 use crate::task::{Context, Poll};
 
-/// Creates a future that is immediately ready with a value.
+/// A future that is immediately ready with a value.
 ///
 /// This `struct` is created by [`ready()`]. See its
 /// documentation for more.
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index edbc250eb0d..8c6a7a56966 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2070,8 +2070,8 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
     #[cfg(debug_assertions)]
     const fn compiletime_check<T>(_src: *const T, _dst: *mut T, _count: usize) {}
     #[cfg(debug_assertions)]
-    // SAFETY: runtime debug-assertions are a best-effort basis; it's fine to
-    // not do them during compile time
+    // SAFETY: As per our safety precondition, we may assume that the `abort` above is never reached.
+    // Therefore, compiletime_check and runtime_check are observably equivalent.
     unsafe {
         const_eval_select((src, dst, count), compiletime_check, runtime_check);
     }
@@ -2161,8 +2161,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
     #[cfg(debug_assertions)]
     const fn compiletime_check<T>(_src: *const T, _dst: *mut T) {}
     #[cfg(debug_assertions)]
-    // SAFETY: runtime debug-assertions are a best-effort basis; it's fine to
-    // not do them during compile time
+    // SAFETY: As per our safety precondition, we may assume that the `abort` above is never reached.
+    // Therefore, compiletime_check and runtime_check are observably equivalent.
     unsafe {
         const_eval_select((src, dst), compiletime_check, runtime_check);
     }
@@ -2273,19 +2273,40 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
 ///
 /// # Safety
 ///
-/// This intrinsic allows breaking [referential transparency] in `const fn`
-/// and is therefore `unsafe`.
+/// The two functions must behave observably equivalent. Safe code in other
+/// crates may assume that calling a `const fn` at compile-time and at run-time
+/// produces the same result. A function that produces a different result when
+/// evaluated at run-time, or has any other observable side-effects, is
+/// *unsound*.
 ///
-/// Code that uses this intrinsic must be extremely careful to ensure that
-/// `const fn`s remain referentially-transparent independently of when they
-/// are evaluated.
+/// Here is an example of how this could cause a problem:
+/// ```no_run
+/// #![feature(const_eval_select)]
+/// use std::hint::unreachable_unchecked;
+/// use std::intrinsics::const_eval_select;
 ///
-/// The Rust compiler assumes that it is sound to replace a call to a `const
-/// fn` with the result produced by evaluating it at compile-time. If
-/// evaluating the function at run-time were to produce a different result,
-/// or have any other observable side-effects, the behavior is undefined.
+/// // Crate A
+/// pub const fn inconsistent() -> i32 {
+///     fn runtime() -> i32 { 1 }
+///     const fn compiletime() -> i32 { 2 }
 ///
-/// [referential transparency]: https://en.wikipedia.org/wiki/Referential_transparency
+///     unsafe {
+//          // ⚠ This code violates the required equivalence of `compiletime`
+///         // and `runtime`.
+///         const_eval_select((), compiletime, runtime)
+///     }
+/// }
+///
+/// // Crate B
+/// const X: i32 = inconsistent();
+/// let x = inconsistent();
+/// if x != X { unsafe { unreachable_unchecked(); }}
+/// ```
+///
+/// This code causes Undefined Behavior when being run, since the
+/// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
+/// which violates the principle that a `const fn` must behave the same at
+/// compile-time and at run-time. The unsafe code in crate B is fine.
 #[unstable(
     feature = "const_eval_select",
     issue = "none",
diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs
index ba81f3f9fd6..d9b14c82e96 100644
--- a/library/core/src/num/saturating.rs
+++ b/library/core/src/num/saturating.rs
@@ -628,7 +628,7 @@ macro_rules! saturating_int_impl {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
-            #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
+            #[rustc_const_unstable(feature = "saturating_int_impl", issue = "87920")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             pub const fn reverse_bits(self) -> Self {
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index a15eabf7966..054b814b7e0 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2223,7 +2223,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
                    reason = "needs decision on wrapping behaviour")]
-        #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[rustc_const_unstable(feature = "wrapping_next_power_of_two", issue = "32463")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         pub const fn wrapping_next_power_of_two(self) -> Self {
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index d98db3f57c0..e7972838184 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -149,8 +149,8 @@ const fn debug_check_data_len<T>(data: *const T, len: usize) {
     // it is not required for safety (the safety must be guatanteed by
     // the `from_raw_parts[_mut]` caller).
     //
-    // Since the checks are not required, we ignore them in CTFE as they can't
-    // be done there (alignment does not make much sense there).
+    // As per our safety precondition, we may assume that assertion above never fails.
+    // Therefore, noop and rt_check are observably equivalent.
     unsafe {
         crate::intrinsics::const_eval_select((data,), noop, rt_check);
     }
diff --git a/library/core/src/stream/mod.rs b/library/core/src/stream/mod.rs
index 58dc8e1e5e6..b59a46d5f3a 100644
--- a/library/core/src/stream/mod.rs
+++ b/library/core/src/stream/mod.rs
@@ -114,9 +114,9 @@
 //! # Laziness
 //!
 //! Streams are *lazy*. This means that just creating a stream doesn't _do_ a
-//! whole lot. Nothing really happens until you call `next`. This is sometimes a
-//! source of confusion when creating a stream solely for its side effects. The
-//! compiler will warn us about this kind of behavior:
+//! whole lot. Nothing really happens until you call `poll_next`. This is
+//! sometimes a source of confusion when creating a stream solely for its side
+//! effects. The compiler will warn us about this kind of behavior:
 //!
 //! ```text
 //! warning: unused result that must be used: streams do nothing unless polled