Skip to content

Commit f35a2bd

Browse files
committed
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.
1 parent 6b73fe2 commit f35a2bd

File tree

5 files changed

+16
-15
lines changed

5 files changed

+16
-15
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/intrinsic.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ fn equate_intrinsic_type<'tcx>(
7171

7272
/// Returns the unsafety of the given intrinsic.
7373
pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Unsafety {
74-
let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
75-
true => hir::Unsafety::Normal,
76-
false => hir::Unsafety::Unsafe,
74+
let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
75+
tcx.fn_sig(intrinsic_id).skip_binder().unsafety()
76+
} else {
77+
match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
78+
true => hir::Unsafety::Normal,
79+
false => hir::Unsafety::Unsafe,
80+
}
7781
};
7882
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
7983
// When adding a new intrinsic to this list,
@@ -117,6 +121,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
117121
| sym::forget
118122
| sym::black_box
119123
| sym::variant_count
124+
| sym::is_val_statically_known
120125
| sym::ptr_mask
121126
| sym::debug_assertions => hir::Unsafety::Normal,
122127
_ => hir::Unsafety::Unsafe,

Diff for: library/core/src/intrinsics.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -2513,9 +2513,7 @@ extern "rust-intrinsic" {
25132513
/// use std::hint::unreachable_unchecked;
25142514
/// use std::intrinsics::is_val_statically_known;
25152515
///
2516-
/// unsafe {
2517-
/// if !is_val_statically_known(0) { unreachable_unchecked(); }
2518-
/// }
2516+
/// if !is_val_statically_known(0) { unsafe { unreachable_unchecked(); } }
25192517
/// ```
25202518
///
25212519
/// This also means that the following code's behavior is unspecified; it
@@ -2527,9 +2525,7 @@ extern "rust-intrinsic" {
25272525
/// # #![allow(internal_features)]
25282526
/// use std::intrinsics::is_val_statically_known;
25292527
///
2530-
/// unsafe {
2531-
/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
2532-
/// }
2528+
/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
25332529
/// ```
25342530
///
25352531
/// Unsafe code may not rely on `is_val_statically_known` returning any
@@ -2544,7 +2540,7 @@ extern "rust-intrinsic" {
25442540
#[rustc_nounwind]
25452541
#[unstable(feature = "core_intrinsics", issue = "none")]
25462542
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
2547-
pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
2543+
pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
25482544
false
25492545
}
25502546

@@ -2564,7 +2560,7 @@ pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
25642560
#[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
25652561
#[unstable(feature = "core_intrinsics", issue = "none")]
25662562
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
2567-
pub(crate) const unsafe fn debug_assertions() -> bool {
2563+
pub(crate) const fn debug_assertions() -> bool {
25682564
cfg!(debug_assertions)
25692565
}
25702566

Diff for: src/tools/miri/tests/pass/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
let mut saw_false = false;
3838

3939
for _ in 0..50 {
40-
if unsafe { intrinsics::is_val_statically_known(0) } {
40+
if intrinsics::is_val_statically_known(0) {
4141
saw_true = true;
4242
} else {
4343
saw_false = true;

Diff for: tests/codegen/is_val_statically_known.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub enum B {
1111

1212
#[inline]
1313
pub fn _u32(a: u32) -> i32 {
14-
if unsafe { is_val_statically_known(a) } { 1 } else { 0 }
14+
if is_val_statically_known(a) { 1 } else { 0 }
1515
}
1616

1717
// CHECK-LABEL: @_u32_true(
@@ -30,7 +30,7 @@ pub fn _u32_false(a: u32) -> i32 {
3030

3131
#[inline]
3232
pub fn _bool(b: bool) -> i32 {
33-
if unsafe { is_val_statically_known(b) } { 3 } else { 2 }
33+
if is_val_statically_known(b) { 3 } else { 2 }
3434
}
3535

3636
// CHECK-LABEL: @_bool_true(

Diff for: tests/ui/consts/is_val_statically_known.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use std::intrinsics::is_val_statically_known;
66

7-
const CONST_TEST: bool = unsafe { is_val_statically_known(0) };
7+
const CONST_TEST: bool = is_val_statically_known(0);
88

99
fn main() {
1010
if CONST_TEST {

0 commit comments

Comments
 (0)