@@ -2221,3 +2221,74 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
22212221 // SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
22222222 unsafe { write_bytes ( dst, val, count) }
22232223}
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