diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index f0f6bfff64aaa..903c98e8317fb 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -407,9 +407,9 @@ 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::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool), - sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool), + sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)), + 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 fc6c1eab803d7..ce1876d5a2f2f 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -937,52 +937,68 @@ 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); +} - /// 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; +/// 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() } + } +} - /// 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 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")] +#[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 00398d272beeb..6c52651f0601f 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