|
55 | 55 | #![allow(missing_docs)]
|
56 | 56 |
|
57 | 57 | use crate::marker::DiscriminantKind;
|
58 |
| -#[cfg(not(bootstrap))] |
59 | 58 | use crate::marker::Tuple;
|
60 | 59 | use crate::mem;
|
61 | 60 |
|
@@ -2175,66 +2174,6 @@ extern "rust-intrinsic" {
|
2175 | 2174 | /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
|
2176 | 2175 | /// which violates the principle that a `const fn` must behave the same at
|
2177 | 2176 | /// compile-time and at run-time. The unsafe code in crate B is fine.
|
2178 |
| - #[cfg(bootstrap)] |
2179 |
| - #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] |
2180 |
| - pub fn const_eval_select<ARG, F, G, RET>(arg: ARG, called_in_const: F, called_at_rt: G) -> RET |
2181 |
| - where |
2182 |
| - G: FnOnce<ARG, Output = RET>, |
2183 |
| - F: FnOnce<ARG, Output = RET>; |
2184 |
| - |
2185 |
| - /// Selects which function to call depending on the context. |
2186 |
| - /// |
2187 |
| - /// If this function is evaluated at compile-time, then a call to this |
2188 |
| - /// intrinsic will be replaced with a call to `called_in_const`. It gets |
2189 |
| - /// replaced with a call to `called_at_rt` otherwise. |
2190 |
| - /// |
2191 |
| - /// # Type Requirements |
2192 |
| - /// |
2193 |
| - /// The two functions must be both function items. They cannot be function |
2194 |
| - /// pointers or closures. The first function must be a `const fn`. |
2195 |
| - /// |
2196 |
| - /// `arg` will be the tupled arguments that will be passed to either one of |
2197 |
| - /// the two functions, therefore, both functions must accept the same type of |
2198 |
| - /// arguments. Both functions must return RET. |
2199 |
| - /// |
2200 |
| - /// # Safety |
2201 |
| - /// |
2202 |
| - /// The two functions must behave observably equivalent. Safe code in other |
2203 |
| - /// crates may assume that calling a `const fn` at compile-time and at run-time |
2204 |
| - /// produces the same result. A function that produces a different result when |
2205 |
| - /// evaluated at run-time, or has any other observable side-effects, is |
2206 |
| - /// *unsound*. |
2207 |
| - /// |
2208 |
| - /// Here is an example of how this could cause a problem: |
2209 |
| - /// ```no_run |
2210 |
| - /// #![feature(const_eval_select)] |
2211 |
| - /// #![feature(core_intrinsics)] |
2212 |
| - /// use std::hint::unreachable_unchecked; |
2213 |
| - /// use std::intrinsics::const_eval_select; |
2214 |
| - /// |
2215 |
| - /// // Crate A |
2216 |
| - /// pub const fn inconsistent() -> i32 { |
2217 |
| - /// fn runtime() -> i32 { 1 } |
2218 |
| - /// const fn compiletime() -> i32 { 2 } |
2219 |
| - /// |
2220 |
| - /// unsafe { |
2221 |
| - // // ⚠ This code violates the required equivalence of `compiletime` |
2222 |
| - /// // and `runtime`. |
2223 |
| - /// const_eval_select((), compiletime, runtime) |
2224 |
| - /// } |
2225 |
| - /// } |
2226 |
| - /// |
2227 |
| - /// // Crate B |
2228 |
| - /// const X: i32 = inconsistent(); |
2229 |
| - /// let x = inconsistent(); |
2230 |
| - /// if x != X { unsafe { unreachable_unchecked(); }} |
2231 |
| - /// ``` |
2232 |
| - /// |
2233 |
| - /// This code causes Undefined Behavior when being run, since the |
2234 |
| - /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, |
2235 |
| - /// which violates the principle that a `const fn` must behave the same at |
2236 |
| - /// compile-time and at run-time. The unsafe code in crate B is fine. |
2237 |
| - #[cfg(not(bootstrap))] |
2238 | 2177 | #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
2239 | 2178 | pub fn const_eval_select<ARG: Tuple, F, G, RET>(
|
2240 | 2179 | arg: ARG,
|
|
0 commit comments