Support safe intrinsics with fallback bodies

Turn `is_val_statically_known` into such an intrinsic to demonstrate. It is perfectly safe to call after all.
This commit is contained in:
Oli Scherer 2024-02-02 14:47:59 +00:00
parent 6b73fe2d09
commit f35a2bd401
5 changed files with 16 additions and 15 deletions

View File

@ -71,9 +71,13 @@ fn equate_intrinsic_type<'tcx>(
/// Returns the unsafety of the given intrinsic.
pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Unsafety {
let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
true => hir::Unsafety::Normal,
false => hir::Unsafety::Unsafe,
let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
tcx.fn_sig(intrinsic_id).skip_binder().unsafety()
} else {
match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
true => hir::Unsafety::Normal,
false => hir::Unsafety::Unsafe,
}
};
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
// When adding a new intrinsic to this list,
@ -117,6 +121,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
| sym::forget
| sym::black_box
| sym::variant_count
| sym::is_val_statically_known
| sym::ptr_mask
| sym::debug_assertions => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,

View File

@ -2513,9 +2513,7 @@ extern "rust-intrinsic" {
/// use std::hint::unreachable_unchecked;
/// use std::intrinsics::is_val_statically_known;
///
/// unsafe {
/// if !is_val_statically_known(0) { unreachable_unchecked(); }
/// }
/// if !is_val_statically_known(0) { unsafe { unreachable_unchecked(); } }
/// ```
///
/// This also means that the following code's behavior is unspecified; it
@ -2527,9 +2525,7 @@ extern "rust-intrinsic" {
/// # #![allow(internal_features)]
/// use std::intrinsics::is_val_statically_known;
///
/// unsafe {
/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
/// }
/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
/// ```
///
/// Unsafe code may not rely on `is_val_statically_known` returning any
@ -2544,7 +2540,7 @@ extern "rust-intrinsic" {
#[rustc_nounwind]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
false
}
@ -2564,7 +2560,7 @@ pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
#[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub(crate) const unsafe fn debug_assertions() -> bool {
pub(crate) const fn debug_assertions() -> bool {
cfg!(debug_assertions)
}

View File

@ -37,7 +37,7 @@ fn main() {
let mut saw_false = false;
for _ in 0..50 {
if unsafe { intrinsics::is_val_statically_known(0) } {
if intrinsics::is_val_statically_known(0) {
saw_true = true;
} else {
saw_false = true;

View File

@ -11,7 +11,7 @@ pub enum B {
#[inline]
pub fn _u32(a: u32) -> i32 {
if unsafe { is_val_statically_known(a) } { 1 } else { 0 }
if is_val_statically_known(a) { 1 } else { 0 }
}
// CHECK-LABEL: @_u32_true(
@ -30,7 +30,7 @@ pub fn _u32_false(a: u32) -> i32 {
#[inline]
pub fn _bool(b: bool) -> i32 {
if unsafe { is_val_statically_known(b) } { 3 } else { 2 }
if is_val_statically_known(b) { 3 } else { 2 }
}
// CHECK-LABEL: @_bool_true(

View File

@ -4,7 +4,7 @@
use std::intrinsics::is_val_statically_known;
const CONST_TEST: bool = unsafe { is_val_statically_known(0) };
const CONST_TEST: bool = is_val_statically_known(0);
fn main() {
if CONST_TEST {