@@ -2221,3 +2221,74 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
2221
2221
// SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
2222
2222
unsafe { write_bytes ( dst, val, count) }
2223
2223
}
2224
+
2225
+ /// Selects which function to call depending on the context.
2226
+ ///
2227
+ /// If this function is evaluated at compile-time, then a call to this
2228
+ /// intrinsic will be replaced with a call to `called_in_const`. It gets
2229
+ /// replaced with a call to `called_at_rt` otherwise.
2230
+ ///
2231
+ /// # Type Requirements
2232
+ ///
2233
+ /// The two functions must be both function items. They cannot be function
2234
+ /// pointers or closures.
2235
+ ///
2236
+ /// `arg` will be the arguments that will be passed to either one of the
2237
+ /// two functions, therefore, both functions must accept the same type of
2238
+ /// arguments. Both functions must return RET.
2239
+ ///
2240
+ /// # Safety
2241
+ ///
2242
+ /// This intrinsic allows breaking [referential transparency] in `const fn`
2243
+ /// and is therefore `unsafe`.
2244
+ ///
2245
+ /// Code that uses this intrinsic must be extremely careful to ensure that
2246
+ /// `const fn`s remain referentially-transparent independently of when they
2247
+ /// are evaluated.
2248
+ ///
2249
+ /// The Rust compiler assumes that it is sound to replace a call to a `const
2250
+ /// fn` with the result produced by evaluating it at compile-time. If
2251
+ /// evaluating the function at run-time were to produce a different result,
2252
+ /// or have any other observable side-effects, the behavior is undefined.
2253
+ ///
2254
+ /// [referential transparency]: https://en.wikipedia.org/wiki/Referential_transparency
2255
+ #[ cfg( not( bootstrap) ) ]
2256
+ #[ unstable(
2257
+ feature = "const_eval_select" ,
2258
+ issue = "none" ,
2259
+ reason = "const_eval_select will never be stable"
2260
+ ) ]
2261
+ #[ rustc_const_unstable( feature = "const_eval_select" , issue = "none" ) ]
2262
+ #[ lang = "const_eval_select" ]
2263
+ #[ rustc_do_not_const_check]
2264
+ pub const unsafe fn const_eval_select < ARG , F , G , RET > (
2265
+ arg : ARG ,
2266
+ _called_in_const : F ,
2267
+ called_at_rt : G ,
2268
+ ) -> RET
2269
+ where
2270
+ F : ~const FnOnce < ARG , Output = RET > ,
2271
+ G : FnOnce < ARG , Output = RET > + ~const Drop ,
2272
+ {
2273
+ called_at_rt. call_once ( arg)
2274
+ }
2275
+
2276
+ #[ cfg( not( bootstrap) ) ]
2277
+ #[ unstable(
2278
+ feature = "const_eval_select" ,
2279
+ issue = "none" ,
2280
+ reason = "const_eval_select will never be stable"
2281
+ ) ]
2282
+ #[ rustc_const_unstable( feature = "const_eval_select" , issue = "none" ) ]
2283
+ #[ lang = "const_eval_select_ct" ]
2284
+ pub const unsafe fn const_eval_select_ct < ARG , F , G , RET > (
2285
+ arg : ARG ,
2286
+ called_in_const : F ,
2287
+ _called_at_rt : G ,
2288
+ ) -> RET
2289
+ where
2290
+ F : ~const FnOnce < ARG , Output = RET > ,
2291
+ G : FnOnce < ARG , Output = RET > + ~const Drop ,
2292
+ {
2293
+ called_in_const. call_once ( arg)
2294
+ }
0 commit comments