Skip to content

Commit 7fb3c29

Browse files
authored
Rollup merge of #86308 - bstrie:intrinsafe, r=JohnTitor
Docs: clarify that certain intrinsics are not unsafe As determined by the hardcoded list at https://github.com/rust-lang/rust/blob/003b8eadd7a476c51956fe447894532d6e21937e/compiler/rustc_typeck/src/check/intrinsic.rs#L59-L92
2 parents fb736d9 + 16168dd commit 7fb3c29

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

compiler/rustc_typeck/src/check/intrinsic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ fn equate_intrinsic_type<'tcx>(
6565
/// Returns the unsafety of the given intrinsic.
6666
pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
6767
match intrinsic {
68+
// When adding a new intrinsic to this list,
69+
// it's usually worth updating that intrinsic's documentation
70+
// to note that it's safe to call, since
71+
// safe extern fns are otherwise unprecedented.
6872
sym::abort
6973
| sym::size_of
7074
| sym::min_align_of

library/core/src/intrinsics.rs

+165
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,11 @@ extern "rust-intrinsic" {
712712

713713
/// Aborts the execution of the process.
714714
///
715+
/// Note that, unlike most intrinsics, this is safe to call;
716+
/// it does not require an `unsafe` block.
717+
/// Therefore, implementations must not require the user to uphold
718+
/// any safety invariants.
719+
///
715720
/// A more user-friendly and stable version of this operation is
716721
/// [`std::process::abort`](../../std/process/fn.abort.html).
717722
pub fn abort() -> !;
@@ -745,6 +750,11 @@ extern "rust-intrinsic" {
745750
///
746751
/// Any use other than with `if` statements will probably not have an effect.
747752
///
753+
/// Note that, unlike most intrinsics, this is safe to call;
754+
/// it does not require an `unsafe` block.
755+
/// Therefore, implementations must not require the user to uphold
756+
/// any safety invariants.
757+
///
748758
/// This intrinsic does not have a stable counterpart.
749759
#[rustc_const_unstable(feature = "const_likely", issue = "none")]
750760
pub fn likely(b: bool) -> bool;
@@ -754,6 +764,11 @@ extern "rust-intrinsic" {
754764
///
755765
/// Any use other than with `if` statements will probably not have an effect.
756766
///
767+
/// Note that, unlike most intrinsics, this is safe to call;
768+
/// it does not require an `unsafe` block.
769+
/// Therefore, implementations must not require the user to uphold
770+
/// any safety invariants.
771+
///
757772
/// This intrinsic does not have a stable counterpart.
758773
#[rustc_const_unstable(feature = "const_likely", issue = "none")]
759774
pub fn unlikely(b: bool) -> bool;
@@ -765,6 +780,11 @@ extern "rust-intrinsic" {
765780

766781
/// The size of a type in bytes.
767782
///
783+
/// Note that, unlike most intrinsics, this is safe to call;
784+
/// it does not require an `unsafe` block.
785+
/// Therefore, implementations must not require the user to uphold
786+
/// any safety invariants.
787+
///
768788
/// More specifically, this is the offset in bytes between successive
769789
/// items of the same type, including alignment padding.
770790
///
@@ -774,6 +794,11 @@ extern "rust-intrinsic" {
774794

775795
/// The minimum alignment of a type.
776796
///
797+
/// Note that, unlike most intrinsics, this is safe to call;
798+
/// it does not require an `unsafe` block.
799+
/// Therefore, implementations must not require the user to uphold
800+
/// any safety invariants.
801+
///
777802
/// The stabilized version of this intrinsic is [`core::mem::align_of`].
778803
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
779804
pub fn min_align_of<T>() -> usize;
@@ -796,6 +821,11 @@ extern "rust-intrinsic" {
796821

797822
/// Gets a static string slice containing the name of a type.
798823
///
824+
/// Note that, unlike most intrinsics, this is safe to call;
825+
/// it does not require an `unsafe` block.
826+
/// Therefore, implementations must not require the user to uphold
827+
/// any safety invariants.
828+
///
799829
/// The stabilized version of this intrinsic is [`core::any::type_name`].
800830
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
801831
pub fn type_name<T: ?Sized>() -> &'static str;
@@ -804,6 +834,11 @@ extern "rust-intrinsic" {
804834
/// function will return the same value for a type regardless of whichever
805835
/// crate it is invoked in.
806836
///
837+
/// Note that, unlike most intrinsics, this is safe to call;
838+
/// it does not require an `unsafe` block.
839+
/// Therefore, implementations must not require the user to uphold
840+
/// any safety invariants.
841+
///
807842
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
808843
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
809844
pub fn type_id<T: ?Sized + 'static>() -> u64;
@@ -829,6 +864,11 @@ extern "rust-intrinsic" {
829864

830865
/// Gets a reference to a static `Location` indicating where it was called.
831866
///
867+
/// Note that, unlike most intrinsics, this is safe to call;
868+
/// it does not require an `unsafe` block.
869+
/// Therefore, implementations must not require the user to uphold
870+
/// any safety invariants.
871+
///
832872
/// Consider using [`core::panic::Location::caller`] instead.
833873
#[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
834874
pub fn caller_location() -> &'static crate::panic::Location<'static>;
@@ -837,6 +877,11 @@ extern "rust-intrinsic" {
837877
///
838878
/// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
839879
/// `ManuallyDrop` instead.
880+
///
881+
/// Note that, unlike most intrinsics, this is safe to call;
882+
/// it does not require an `unsafe` block.
883+
/// Therefore, implementations must not require the user to uphold
884+
/// any safety invariants.
840885
#[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
841886
pub fn forget<T: ?Sized>(_: T);
842887

@@ -1090,6 +1135,11 @@ extern "rust-intrinsic" {
10901135
/// If the actual type neither requires drop glue nor implements
10911136
/// `Copy`, then the return value of this function is unspecified.
10921137
///
1138+
/// Note that, unlike most intrinsics, this is safe to call;
1139+
/// it does not require an `unsafe` block.
1140+
/// Therefore, implementations must not require the user to uphold
1141+
/// any safety invariants.
1142+
///
10931143
/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
10941144
#[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
10951145
pub fn needs_drop<T>() -> bool;
@@ -1310,21 +1360,41 @@ extern "rust-intrinsic" {
13101360

13111361
/// Returns the minimum of two `f32` values.
13121362
///
1363+
/// Note that, unlike most intrinsics, this is safe to call;
1364+
/// it does not require an `unsafe` block.
1365+
/// Therefore, implementations must not require the user to uphold
1366+
/// any safety invariants.
1367+
///
13131368
/// The stabilized version of this intrinsic is
13141369
/// [`f32::min`]
13151370
pub fn minnumf32(x: f32, y: f32) -> f32;
13161371
/// Returns the minimum of two `f64` values.
13171372
///
1373+
/// Note that, unlike most intrinsics, this is safe to call;
1374+
/// it does not require an `unsafe` block.
1375+
/// Therefore, implementations must not require the user to uphold
1376+
/// any safety invariants.
1377+
///
13181378
/// The stabilized version of this intrinsic is
13191379
/// [`f64::min`]
13201380
pub fn minnumf64(x: f64, y: f64) -> f64;
13211381
/// Returns the maximum of two `f32` values.
13221382
///
1383+
/// Note that, unlike most intrinsics, this is safe to call;
1384+
/// it does not require an `unsafe` block.
1385+
/// Therefore, implementations must not require the user to uphold
1386+
/// any safety invariants.
1387+
///
13231388
/// The stabilized version of this intrinsic is
13241389
/// [`f32::max`]
13251390
pub fn maxnumf32(x: f32, y: f32) -> f32;
13261391
/// Returns the maximum of two `f64` values.
13271392
///
1393+
/// Note that, unlike most intrinsics, this is safe to call;
1394+
/// it does not require an `unsafe` block.
1395+
/// Therefore, implementations must not require the user to uphold
1396+
/// any safety invariants.
1397+
///
13281398
/// The stabilized version of this intrinsic is
13291399
/// [`f64::max`]
13301400
pub fn maxnumf64(x: f64, y: f64) -> f64;
@@ -1438,6 +1508,11 @@ extern "rust-intrinsic" {
14381508

14391509
/// Returns the number of bits set in an integer type `T`
14401510
///
1511+
/// Note that, unlike most intrinsics, this is safe to call;
1512+
/// it does not require an `unsafe` block.
1513+
/// Therefore, implementations must not require the user to uphold
1514+
/// any safety invariants.
1515+
///
14411516
/// The stabilized versions of this intrinsic are available on the integer
14421517
/// primitives via the `count_ones` method. For example,
14431518
/// [`u32::count_ones`]
@@ -1446,6 +1521,11 @@ extern "rust-intrinsic" {
14461521

14471522
/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
14481523
///
1524+
/// Note that, unlike most intrinsics, this is safe to call;
1525+
/// it does not require an `unsafe` block.
1526+
/// Therefore, implementations must not require the user to uphold
1527+
/// any safety invariants.
1528+
///
14491529
/// The stabilized versions of this intrinsic are available on the integer
14501530
/// primitives via the `leading_zeros` method. For example,
14511531
/// [`u32::leading_zeros`]
@@ -1497,6 +1577,11 @@ extern "rust-intrinsic" {
14971577

14981578
/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
14991579
///
1580+
/// Note that, unlike most intrinsics, this is safe to call;
1581+
/// it does not require an `unsafe` block.
1582+
/// Therefore, implementations must not require the user to uphold
1583+
/// any safety invariants.
1584+
///
15001585
/// The stabilized versions of this intrinsic are available on the integer
15011586
/// primitives via the `trailing_zeros` method. For example,
15021587
/// [`u32::trailing_zeros`]
@@ -1548,6 +1633,11 @@ extern "rust-intrinsic" {
15481633

15491634
/// Reverses the bytes in an integer type `T`.
15501635
///
1636+
/// Note that, unlike most intrinsics, this is safe to call;
1637+
/// it does not require an `unsafe` block.
1638+
/// Therefore, implementations must not require the user to uphold
1639+
/// any safety invariants.
1640+
///
15511641
/// The stabilized versions of this intrinsic are available on the integer
15521642
/// primitives via the `swap_bytes` method. For example,
15531643
/// [`u32::swap_bytes`]
@@ -1556,6 +1646,11 @@ extern "rust-intrinsic" {
15561646

15571647
/// Reverses the bits in an integer type `T`.
15581648
///
1649+
/// Note that, unlike most intrinsics, this is safe to call;
1650+
/// it does not require an `unsafe` block.
1651+
/// Therefore, implementations must not require the user to uphold
1652+
/// any safety invariants.
1653+
///
15591654
/// The stabilized versions of this intrinsic are available on the integer
15601655
/// primitives via the `reverse_bits` method. For example,
15611656
/// [`u32::reverse_bits`]
@@ -1564,6 +1659,11 @@ extern "rust-intrinsic" {
15641659

15651660
/// Performs checked integer addition.
15661661
///
1662+
/// Note that, unlike most intrinsics, this is safe to call;
1663+
/// it does not require an `unsafe` block.
1664+
/// Therefore, implementations must not require the user to uphold
1665+
/// any safety invariants.
1666+
///
15671667
/// The stabilized versions of this intrinsic are available on the integer
15681668
/// primitives via the `overflowing_add` method. For example,
15691669
/// [`u32::overflowing_add`]
@@ -1572,6 +1672,11 @@ extern "rust-intrinsic" {
15721672

15731673
/// Performs checked integer subtraction
15741674
///
1675+
/// Note that, unlike most intrinsics, this is safe to call;
1676+
/// it does not require an `unsafe` block.
1677+
/// Therefore, implementations must not require the user to uphold
1678+
/// any safety invariants.
1679+
///
15751680
/// The stabilized versions of this intrinsic are available on the integer
15761681
/// primitives via the `overflowing_sub` method. For example,
15771682
/// [`u32::overflowing_sub`]
@@ -1580,6 +1685,11 @@ extern "rust-intrinsic" {
15801685

15811686
/// Performs checked integer multiplication
15821687
///
1688+
/// Note that, unlike most intrinsics, this is safe to call;
1689+
/// it does not require an `unsafe` block.
1690+
/// Therefore, implementations must not require the user to uphold
1691+
/// any safety invariants.
1692+
///
15831693
/// The stabilized versions of this intrinsic are available on the integer
15841694
/// primitives via the `overflowing_mul` method. For example,
15851695
/// [`u32::overflowing_mul`]
@@ -1649,6 +1759,11 @@ extern "rust-intrinsic" {
16491759

16501760
/// Performs rotate left.
16511761
///
1762+
/// Note that, unlike most intrinsics, this is safe to call;
1763+
/// it does not require an `unsafe` block.
1764+
/// Therefore, implementations must not require the user to uphold
1765+
/// any safety invariants.
1766+
///
16521767
/// The stabilized versions of this intrinsic are available on the integer
16531768
/// primitives via the `rotate_left` method. For example,
16541769
/// [`u32::rotate_left`]
@@ -1657,6 +1772,11 @@ extern "rust-intrinsic" {
16571772

16581773
/// Performs rotate right.
16591774
///
1775+
/// Note that, unlike most intrinsics, this is safe to call;
1776+
/// it does not require an `unsafe` block.
1777+
/// Therefore, implementations must not require the user to uphold
1778+
/// any safety invariants.
1779+
///
16601780
/// The stabilized versions of this intrinsic are available on the integer
16611781
/// primitives via the `rotate_right` method. For example,
16621782
/// [`u32::rotate_right`]
@@ -1665,20 +1785,35 @@ extern "rust-intrinsic" {
16651785

16661786
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
16671787
///
1788+
/// Note that, unlike most intrinsics, this is safe to call;
1789+
/// it does not require an `unsafe` block.
1790+
/// Therefore, implementations must not require the user to uphold
1791+
/// any safety invariants.
1792+
///
16681793
/// The stabilized versions of this intrinsic are available on the integer
16691794
/// primitives via the `wrapping_add` method. For example,
16701795
/// [`u32::wrapping_add`]
16711796
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
16721797
pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
16731798
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
16741799
///
1800+
/// Note that, unlike most intrinsics, this is safe to call;
1801+
/// it does not require an `unsafe` block.
1802+
/// Therefore, implementations must not require the user to uphold
1803+
/// any safety invariants.
1804+
///
16751805
/// The stabilized versions of this intrinsic are available on the integer
16761806
/// primitives via the `wrapping_sub` method. For example,
16771807
/// [`u32::wrapping_sub`]
16781808
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
16791809
pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
16801810
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
16811811
///
1812+
/// Note that, unlike most intrinsics, this is safe to call;
1813+
/// it does not require an `unsafe` block.
1814+
/// Therefore, implementations must not require the user to uphold
1815+
/// any safety invariants.
1816+
///
16821817
/// The stabilized versions of this intrinsic are available on the integer
16831818
/// primitives via the `wrapping_mul` method. For example,
16841819
/// [`u32::wrapping_mul`]
@@ -1687,13 +1822,23 @@ extern "rust-intrinsic" {
16871822

16881823
/// Computes `a + b`, saturating at numeric bounds.
16891824
///
1825+
/// Note that, unlike most intrinsics, this is safe to call;
1826+
/// it does not require an `unsafe` block.
1827+
/// Therefore, implementations must not require the user to uphold
1828+
/// any safety invariants.
1829+
///
16901830
/// The stabilized versions of this intrinsic are available on the integer
16911831
/// primitives via the `saturating_add` method. For example,
16921832
/// [`u32::saturating_add`]
16931833
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
16941834
pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
16951835
/// Computes `a - b`, saturating at numeric bounds.
16961836
///
1837+
/// Note that, unlike most intrinsics, this is safe to call;
1838+
/// it does not require an `unsafe` block.
1839+
/// Therefore, implementations must not require the user to uphold
1840+
/// any safety invariants.
1841+
///
16971842
/// The stabilized versions of this intrinsic are available on the integer
16981843
/// primitives via the `saturating_sub` method. For example,
16991844
/// [`u32::saturating_sub`]
@@ -1703,13 +1848,23 @@ extern "rust-intrinsic" {
17031848
/// Returns the value of the discriminant for the variant in 'v';
17041849
/// if `T` has no discriminant, returns `0`.
17051850
///
1851+
/// Note that, unlike most intrinsics, this is safe to call;
1852+
/// it does not require an `unsafe` block.
1853+
/// Therefore, implementations must not require the user to uphold
1854+
/// any safety invariants.
1855+
///
17061856
/// The stabilized version of this intrinsic is [`core::mem::discriminant`].
17071857
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
17081858
pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
17091859

17101860
/// Returns the number of variants of the type `T` cast to a `usize`;
17111861
/// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
17121862
///
1863+
/// Note that, unlike most intrinsics, this is safe to call;
1864+
/// it does not require an `unsafe` block.
1865+
/// Therefore, implementations must not require the user to uphold
1866+
/// any safety invariants.
1867+
///
17131868
/// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
17141869
#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
17151870
pub fn variant_count<T>() -> usize;
@@ -1732,10 +1887,20 @@ extern "rust-intrinsic" {
17321887
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
17331888

17341889
/// See documentation of `<*const T>::guaranteed_eq` for details.
1890+
///
1891+
/// Note that, unlike most intrinsics, this is safe to call;
1892+
/// it does not require an `unsafe` block.
1893+
/// Therefore, implementations must not require the user to uphold
1894+
/// any safety invariants.
17351895
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
17361896
pub fn ptr_guaranteed_eq<T>(ptr: *const T, other: *const T) -> bool;
17371897

17381898
/// See documentation of `<*const T>::guaranteed_ne` for details.
1899+
///
1900+
/// Note that, unlike most intrinsics, this is safe to call;
1901+
/// it does not require an `unsafe` block.
1902+
/// Therefore, implementations must not require the user to uphold
1903+
/// any safety invariants.
17391904
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
17401905
pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
17411906

0 commit comments

Comments
 (0)