@@ -2515,6 +2515,8 @@ extern "rust-intrinsic" {
25152515     /// intrinsic will be replaced with a call to `called_in_const`. It gets 
25162516     /// replaced with a call to `called_at_rt` otherwise. 
25172517     /// 
2518+      /// This function is safe to call, but note the stability concerns below. 
2519+      /// 
25182520     /// # Type Requirements 
25192521     /// 
25202522     /// The two functions must be both function items. They cannot be function 
@@ -2524,13 +2526,15 @@ extern "rust-intrinsic" {
25242526     /// the two functions, therefore, both functions must accept the same type of 
25252527     /// arguments. Both functions must return RET. 
25262528     /// 
2527-      /// # Safety  
2529+      /// # Stability concerns  
25282530     /// 
2529-      /// The two functions must behave observably equivalent. Safe code in other 
2530-      /// crates may assume that calling a `const fn` at compile-time and at run-time 
2531-      /// produces the same result. A function that produces a different result when 
2532-      /// evaluated at run-time, or has any other observable side-effects, is 
2533-      /// *unsound*. 
2531+      /// Rust has not yet decided that `const fn` are allowed to tell whether 
2532+      /// they run at compile-time or at runtime. Therefore, when using this 
2533+      /// intrinsic anywhere that can be reached from stable, it is crucial that 
2534+      /// the end-to-end behavior of the stable `const fn` is the same for both 
2535+      /// modes of execution. (Here, Undefined Behavior is considerd "the same" 
2536+      /// as any other behavior, so if the function exhibits UB at runtime then 
2537+      /// it may do whatever it wants at compile-time.) 
25342538     /// 
25352539     /// Here is an example of how this could cause a problem: 
25362540     /// ```no_run 
@@ -2540,29 +2544,26 @@ extern "rust-intrinsic" {
25402544     /// use std::hint::unreachable_unchecked; 
25412545     /// use std::intrinsics::const_eval_select; 
25422546     /// 
2543-      /// // Crate A  
2547+      /// // Standard library  
25442548     /// pub const fn inconsistent() -> i32 { 
25452549     ///     fn runtime() -> i32 { 1 } 
25462550     ///     const fn compiletime() -> i32 { 2 } 
25472551     /// 
2548-      ///     unsafe { 
2549-      //          // ⚠ This code violates the required equivalence of `compiletime` 
2550-     ///         // and `runtime`. 
2551-      ///         const_eval_select((), compiletime, runtime) 
2552-      ///     } 
2552+      //      // ⚠ This code violates the required equivalence of `compiletime` 
2553+     ///     // and `runtime`. 
2554+      ///     const_eval_select((), compiletime, runtime) 
25532555     /// } 
25542556     /// 
2555-      /// // Crate B  
2557+      /// // User Crate  
25562558     /// const X: i32 = inconsistent(); 
25572559     /// let x = inconsistent(); 
2558-      /// if x != X { unsafe { unreachable_unchecked(); }}  
2560+      /// assert_eq!(x, X);  
25592561     /// ``` 
25602562     /// 
2561-      /// This code causes Undefined Behavior when being run, since the 
2562-      /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, 
2563-      /// which violates the principle that a `const fn` must behave the same at 
2564-      /// compile-time and at run-time. The unsafe code in crate B is fine. 
2563+      /// Currently such an assertion would always succeed; until Rust decides 
2564+      /// otherwise, that principle should not be violated. 
25652565     #[ rustc_const_unstable( feature = "const_eval_select" ,  issue = "none" ) ]  
2566+     #[ cfg_attr( not( bootstrap) ,  rustc_safe_intrinsic) ]  
25662567    pub  fn  const_eval_select < ARG :  Tuple ,  F ,  G ,  RET > ( 
25672568        arg :  ARG , 
25682569        called_in_const :  F , 
0 commit comments