From 6a671bdbf1c0b68af05dd34595e4c10d6fe3abe7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 16 Feb 2024 17:29:34 +0000 Subject: [PATCH 1/2] Give the `assume` intrinsic a fallback body --- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- library/core/src/intrinsics.rs | 36 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index f0f6bfff64aaa..fcc0ec69d5e6f 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -407,7 +407,7 @@ pub fn check_intrinsic_type( } sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)), - sym::assume => (0, 0, vec![tcx.types.bool], Ty::new_unit(tcx)), + sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)), sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool), sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool), diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index fc6c1eab803d7..7b73396afc688 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -937,20 +937,30 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn unreachable() -> !; - /// Informs the optimizer that a condition is always true. - /// If the condition is false, the behavior is undefined. - /// - /// No code is generated for this intrinsic, but the optimizer will try - /// to preserve it (and its condition) between passes, which may interfere - /// with optimization of surrounding code and reduce performance. It should - /// not be used if the invariant can be discovered by the optimizer on its - /// own, or if it does not enable any significant optimizations. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_stable(feature = "const_assume", since = "1.77.0")] - #[rustc_nounwind] - pub fn assume(b: bool); +} + +/// Informs the optimizer that a condition is always true. +/// If the condition is false, the behavior is undefined. +/// +/// No code is generated for this intrinsic, but the optimizer will try +/// to preserve it (and its condition) between passes, which may interfere +/// with optimization of surrounding code and reduce performance. It should +/// not be used if the invariant can be discovered by the optimizer on its +/// own, or if it does not enable any significant optimizations. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_const_stable(feature = "const_assume", since = "1.77.0")] +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[cfg_attr(not(bootstrap), rustc_intrinsic)] +pub const unsafe fn assume(b: bool) { + if !b { + // SAFETY: the caller must guarantee the argument is never `false` + unsafe { unreachable() } + } +} +extern "rust-intrinsic" { /// Hints to the compiler that branch condition is likely to be true. /// Returns the value passed to it. /// From dd40a80102950a06d0467a2e7d7203ee85911470 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 16 Feb 2024 17:45:46 +0000 Subject: [PATCH 2/2] Give the (`un`)`likely` intrinsics fallback bodies --- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 +- library/core/src/intrinsics.rs | 68 ++++++++++--------- .../ui/intrinsics/safe-intrinsic-mismatch.rs | 8 +-- .../intrinsics/safe-intrinsic-mismatch.stderr | 21 +++--- tests/ui/reify-intrinsic.rs | 5 +- tests/ui/reify-intrinsic.stderr | 11 ++- 6 files changed, 61 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index fcc0ec69d5e6f..903c98e8317fb 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -408,8 +408,8 @@ pub fn check_intrinsic_type( sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)), sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)), - sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool), - sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool), + sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool), + sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool), sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), sym::write_via_move => { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7b73396afc688..ce1876d5a2f2f 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -960,39 +960,45 @@ pub const unsafe fn assume(b: bool) { } } -extern "rust-intrinsic" { - /// Hints to the compiler that branch condition is likely to be true. - /// Returns the value passed to it. - /// - /// Any use other than with `if` statements will probably not have an effect. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_likely", issue = "none")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn likely(b: bool) -> bool; +/// Hints to the compiler that branch condition is likely to be true. +/// Returns the value passed to it. +/// +/// Any use other than with `if` statements will probably not have an effect. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_const_unstable(feature = "const_likely", issue = "none")] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[rustc_nounwind] +pub const fn likely(b: bool) -> bool { + b +} - /// Hints to the compiler that branch condition is likely to be false. - /// Returns the value passed to it. - /// - /// Any use other than with `if` statements will probably not have an effect. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_likely", issue = "none")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn unlikely(b: bool) -> bool; +/// Hints to the compiler that branch condition is likely to be false. +/// Returns the value passed to it. +/// +/// Any use other than with `if` statements will probably not have an effect. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_const_unstable(feature = "const_likely", issue = "none")] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[rustc_nounwind] +pub const fn unlikely(b: bool) -> bool { + b +} +extern "rust-intrinsic" { /// Executes a breakpoint trap, for inspection by a debugger. /// /// This intrinsic does not have a stable counterpart. diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs index fcd6612f1259d..23cd5f1083534 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs @@ -5,12 +5,12 @@ extern "rust-intrinsic" { fn size_of() -> usize; //~ ERROR intrinsic safety mismatch //~^ ERROR intrinsic safety mismatch - - #[rustc_safe_intrinsic] - fn assume(b: bool); //~ ERROR intrinsic safety mismatch - //~^ ERROR intrinsic safety mismatch } +#[rustc_intrinsic] +const fn assume(_b: bool) {} //~ ERROR intrinsic safety mismatch +//~| ERROR intrinsic has wrong type + #[rustc_intrinsic] const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} //~^ ERROR intrinsic safety mismatch diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr index 0b579121ac18e..2e0812d6472b6 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr @@ -4,12 +4,6 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler LL | fn size_of() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` - --> $DIR/safe-intrinsic-mismatch.rs:10:5 - | -LL | fn assume(b: bool); - | ^^^^^^^^^^^^^^^^^^ - error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` --> $DIR/safe-intrinsic-mismatch.rs:6:5 | @@ -19,12 +13,19 @@ LL | fn size_of() -> usize; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` - --> $DIR/safe-intrinsic-mismatch.rs:10:5 + --> $DIR/safe-intrinsic-mismatch.rs:11:1 | -LL | fn assume(b: bool); - | ^^^^^^^^^^^^^^^^^^ +LL | const fn assume(_b: bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: intrinsic has wrong type + --> $DIR/safe-intrinsic-mismatch.rs:11:16 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | const fn assume(_b: bool) {} + | ^ expected unsafe fn, found normal fn + | + = note: expected signature `unsafe fn(_)` + found signature `fn(_)` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate` --> $DIR/safe-intrinsic-mismatch.rs:15:1 diff --git a/tests/ui/reify-intrinsic.rs b/tests/ui/reify-intrinsic.rs index 9eb2f724017ed..d8a268bd33a81 100644 --- a/tests/ui/reify-intrinsic.rs +++ b/tests/ui/reify-intrinsic.rs @@ -13,10 +13,9 @@ fn b() { } fn c() { - let _ = [ - std::intrinsics::likely, + let _: [unsafe extern "rust-intrinsic" fn(bool) -> bool; 2] = [ + std::intrinsics::likely, //~ ERROR cannot coerce std::intrinsics::unlikely, - //~^ ERROR cannot coerce ]; } diff --git a/tests/ui/reify-intrinsic.stderr b/tests/ui/reify-intrinsic.stderr index 310b6c224e0e7..0119a1a6650d0 100644 --- a/tests/ui/reify-intrinsic.stderr +++ b/tests/ui/reify-intrinsic.stderr @@ -16,14 +16,13 @@ LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: cannot coerce intrinsics to function pointers - --> $DIR/reify-intrinsic.rs:18:9 + --> $DIR/reify-intrinsic.rs:17:9 | -LL | std::intrinsics::unlikely, - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers +LL | std::intrinsics::likely, + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers | - = note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}` - found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}` - = note: different fn items have unique types, even if their signatures are the same + = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(_) -> _` + found fn item `fn(_) -> _ {likely}` error: aborting due to 3 previous errors