Skip to content

Commit eece58a

Browse files
committed
Auto merge of #71707 - Dylan-DPC:rollup-hk8itvo, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #71205 (rustc: fix check_attr() for methods, closures and foreign functions) - #71540 (Suggest deref when coercing `ty::Ref` to `ty::RawPtr`) - #71655 (Miri: better document and fix dynamic const pattern soundness checks) - #71672 (document missing stable counterparts of intrinsics) - #71692 (Add clarification on std::cfg macro docs v. #[cfg] attribute) Failed merges: r? @ghost
2 parents bf45975 + 8f6eabf commit eece58a

37 files changed

+630
-66
lines changed

src/libcore/intrinsics.rs

+84-12
Original file line numberDiff line numberDiff line change
@@ -782,36 +782,43 @@ extern "rust-intrinsic" {
782782
/// characteristics.
783783
///
784784
/// The `locality` argument must be a constant integer and is a temporal locality specifier
785-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
785+
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
786+
///
787+
/// This intrinsic does not have a stable counterpart.
786788
pub fn prefetch_read_data<T>(data: *const T, locality: i32);
787789
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
788790
/// if supported; otherwise, it is a no-op.
789791
/// Prefetches have no effect on the behavior of the program but can change its performance
790792
/// characteristics.
791793
///
792794
/// The `locality` argument must be a constant integer and is a temporal locality specifier
793-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
795+
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
796+
///
797+
/// This intrinsic does not have a stable counterpart.
794798
pub fn prefetch_write_data<T>(data: *const T, locality: i32);
795799
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
796800
/// if supported; otherwise, it is a no-op.
797801
/// Prefetches have no effect on the behavior of the program but can change its performance
798802
/// characteristics.
799803
///
800804
/// The `locality` argument must be a constant integer and is a temporal locality specifier
801-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
805+
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
806+
///
807+
/// This intrinsic does not have a stable counterpart.
802808
pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
803809
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
804810
/// if supported; otherwise, it is a no-op.
805811
/// Prefetches have no effect on the behavior of the program but can change its performance
806812
/// characteristics.
807813
///
808814
/// The `locality` argument must be a constant integer and is a temporal locality specifier
809-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
815+
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
816+
///
817+
/// This intrinsic does not have a stable counterpart.
810818
pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
811819
}
812820

813821
extern "rust-intrinsic" {
814-
815822
/// An atomic fence.
816823
///
817824
/// The stabilized version of this intrinsic is available in
@@ -905,12 +912,14 @@ extern "rust-intrinsic" {
905912
/// that `rustc_peek(potentially_uninitialized)` would actually
906913
/// double-check that dataflow did indeed compute that it is
907914
/// uninitialized at that point in the control flow.
915+
///
916+
/// This intrinsic should not be used outside of the compiler.
908917
pub fn rustc_peek<T>(_: T) -> T;
909918

910919
/// Aborts the execution of the process.
911920
///
912921
/// The stabilized version of this intrinsic is
913-
/// [`std::process::abort`](../../std/process/fn.abort.html)
922+
/// [`std::process::abort`](../../std/process/fn.abort.html).
914923
pub fn abort() -> !;
915924

916925
/// Tells LLVM that this point in the code is not reachable, enabling
@@ -932,21 +941,29 @@ extern "rust-intrinsic" {
932941
/// with optimization of surrounding code and reduce performance. It should
933942
/// not be used if the invariant can be discovered by the optimizer on its
934943
/// own, or if it does not enable any significant optimizations.
944+
///
945+
/// This intrinsic does not have a stable counterpart.
935946
pub fn assume(b: bool);
936947

937948
/// Hints to the compiler that branch condition is likely to be true.
938949
/// Returns the value passed to it.
939950
///
940951
/// Any use other than with `if` statements will probably not have an effect.
952+
///
953+
/// This intrinsic does not have a stable counterpart.
941954
pub fn likely(b: bool) -> bool;
942955

943956
/// Hints to the compiler that branch condition is likely to be false.
944957
/// Returns the value passed to it.
945958
///
946959
/// Any use other than with `if` statements will probably not have an effect.
960+
///
961+
/// This intrinsic does not have a stable counterpart.
947962
pub fn unlikely(b: bool) -> bool;
948963

949964
/// Executes a breakpoint trap, for inspection by a debugger.
965+
///
966+
/// This intrinsic does not have a stable counterpart.
950967
pub fn breakpoint();
951968

952969
/// The size of a type in bytes.
@@ -973,6 +990,9 @@ extern "rust-intrinsic" {
973990
/// [`std::mem::align_of`](../../std/mem/fn.align_of.html).
974991
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
975992
pub fn min_align_of<T>() -> usize;
993+
/// The prefered alignment of a type.
994+
///
995+
/// This intrinsic does not have a stable counterpart.
976996
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "none")]
977997
pub fn pref_align_of<T>() -> usize;
978998

@@ -981,6 +1001,10 @@ extern "rust-intrinsic" {
9811001
/// The stabilized version of this intrinsic is
9821002
/// [`std::mem::size_of_val`](../../std/mem/fn.size_of_val.html).
9831003
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
1004+
/// The required alignment of the referenced value.
1005+
///
1006+
/// The stabilized version of this intrinsic is
1007+
/// [`std::mem::align_of_val`](../../std/mem/fn.align_of_val.html).
9841008
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
9851009

9861010
/// Gets a static string slice containing the name of a type.
@@ -1001,22 +1025,33 @@ extern "rust-intrinsic" {
10011025

10021026
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
10031027
/// This will statically either panic, or do nothing.
1028+
///
1029+
/// This intrinsic does not have a stable counterpart.
10041030
pub fn assert_inhabited<T>();
10051031

10061032
/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
10071033
/// zero-initialization: This will statically either panic, or do nothing.
1034+
///
1035+
/// This intrinsic does not have a stable counterpart.
10081036
pub fn assert_zero_valid<T>();
10091037

10101038
/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
10111039
/// bit patterns: This will statically either panic, or do nothing.
1040+
///
1041+
/// This intrinsic does not have a stable counterpart.
10121042
pub fn assert_uninit_valid<T>();
10131043

10141044
/// Gets a reference to a static `Location` indicating where it was called.
1045+
///
1046+
/// Consider using [`std::panic::Location::caller`](../../std/panic/struct.Location.html#method.caller)
1047+
/// instead.
10151048
#[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
10161049
pub fn caller_location() -> &'static crate::panic::Location<'static>;
10171050

10181051
/// Moves a value out of scope without running drop glue.
1019-
/// This exists solely for `mem::forget_unsized`; normal `forget` uses `ManuallyDrop` instead.
1052+
///
1053+
/// This exists solely for [`mem::forget_unsized`](../../std/mem/fn.forget_unsized.html);
1054+
/// normal `forget` uses `ManuallyDrop` instead.
10201055
pub fn forget<T: ?Sized>(_: T);
10211056

10221057
/// Reinterprets the bits of a value of one type as another type.
@@ -1300,20 +1335,26 @@ extern "rust-intrinsic" {
13001335
///
13011336
/// The volatile parameter is set to `true`, so it will not be optimized out
13021337
/// unless size is equal to zero.
1338+
///
1339+
/// This intrinsic does not have a stable counterpart.
13031340
pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
13041341
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
13051342
/// a size of `count` * `size_of::<T>()` and an alignment of
13061343
/// `min_align_of::<T>()`
13071344
///
13081345
/// The volatile parameter is set to `true`, so it will not be optimized out
13091346
/// unless size is equal to zero.
1347+
///
1348+
/// This intrinsic does not have a stable counterpart.
13101349
pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
13111350
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
13121351
/// size of `count` * `size_of::<T>()` and an alignment of
13131352
/// `min_align_of::<T>()`.
13141353
///
13151354
/// The volatile parameter is set to `true`, so it will not be optimized out
13161355
/// unless size is equal to zero.
1356+
///
1357+
/// This intrinsic does not have a stable counterpart.
13171358
pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
13181359

13191360
/// Performs a volatile load from the `src` pointer.
@@ -1329,9 +1370,13 @@ extern "rust-intrinsic" {
13291370

13301371
/// Performs a volatile load from the `src` pointer
13311372
/// The pointer is not required to be aligned.
1373+
///
1374+
/// This intrinsic does not have a stable counterpart.
13321375
pub fn unaligned_volatile_load<T>(src: *const T) -> T;
13331376
/// Performs a volatile store to the `dst` pointer.
13341377
/// The pointer is not required to be aligned.
1378+
///
1379+
/// This intrinsic does not have a stable counterpart.
13351380
pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);
13361381

13371382
/// Returns the square root of an `f32`
@@ -1539,8 +1584,12 @@ extern "rust-intrinsic" {
15391584
pub fn rintf64(x: f64) -> f64;
15401585

15411586
/// Returns the nearest integer to an `f32`.
1587+
///
1588+
/// This intrinsic does not have a stable counterpart.
15421589
pub fn nearbyintf32(x: f32) -> f32;
15431590
/// Returns the nearest integer to an `f64`.
1591+
///
1592+
/// This intrinsic does not have a stable counterpart.
15441593
pub fn nearbyintf64(x: f64) -> f64;
15451594

15461595
/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
@@ -1556,28 +1605,39 @@ extern "rust-intrinsic" {
15561605

15571606
/// Float addition that allows optimizations based on algebraic rules.
15581607
/// May assume inputs are finite.
1608+
///
1609+
/// This intrinsic does not have a stable counterpart.
15591610
pub fn fadd_fast<T: Copy>(a: T, b: T) -> T;
15601611

15611612
/// Float subtraction that allows optimizations based on algebraic rules.
15621613
/// May assume inputs are finite.
1614+
///
1615+
/// This intrinsic does not have a stable counterpart.
15631616
pub fn fsub_fast<T: Copy>(a: T, b: T) -> T;
15641617

15651618
/// Float multiplication that allows optimizations based on algebraic rules.
15661619
/// May assume inputs are finite.
1620+
///
1621+
/// This intrinsic does not have a stable counterpart.
15671622
pub fn fmul_fast<T: Copy>(a: T, b: T) -> T;
15681623

15691624
/// Float division that allows optimizations based on algebraic rules.
15701625
/// May assume inputs are finite.
1626+
///
1627+
/// This intrinsic does not have a stable counterpart.
15711628
pub fn fdiv_fast<T: Copy>(a: T, b: T) -> T;
15721629

15731630
/// Float remainder that allows optimizations based on algebraic rules.
15741631
/// May assume inputs are finite.
1632+
///
1633+
/// This intrinsic does not have a stable counterpart.
15751634
pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
15761635

15771636
/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
15781637
/// (<https://github.com/rust-lang/rust/issues/10184>)
15791638
///
1580-
/// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
1639+
/// Stabilized as [`f32::to_int_unchecked`](../../std/primitive.f32.html#method.to_int_unchecked)
1640+
/// and [`f64::to_int_unchecked`](../../std/primitive.f64.html#method.to_int_unchecked).
15811641
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
15821642

15831643
/// Returns the number of bits set in an integer type `T`
@@ -1623,6 +1683,8 @@ extern "rust-intrinsic" {
16231683
/// Like `ctlz`, but extra-unsafe as it returns `undef` when
16241684
/// given an `x` with value `0`.
16251685
///
1686+
/// This intrinsic does not have a stable counterpart.
1687+
///
16261688
/// # Examples
16271689
///
16281690
/// ```
@@ -1672,6 +1734,8 @@ extern "rust-intrinsic" {
16721734
/// Like `cttz`, but extra-unsafe as it returns `undef` when
16731735
/// given an `x` with value `0`.
16741736
///
1737+
/// This intrinsic does not have a stable counterpart.
1738+
///
16751739
/// # Examples
16761740
///
16771741
/// ```
@@ -1728,20 +1792,22 @@ extern "rust-intrinsic" {
17281792

17291793
/// Performs an exact division, resulting in undefined behavior where
17301794
/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
1795+
///
1796+
/// This intrinsic does not have a stable counterpart.
17311797
pub fn exact_div<T: Copy>(x: T, y: T) -> T;
17321798

17331799
/// Performs an unchecked division, resulting in undefined behavior
17341800
/// where y = 0 or x = `T::MIN` and y = -1
17351801
///
1736-
/// The stabilized versions of this intrinsic are available on the integer
1802+
/// Safe wrappers for this intrinsic are available on the integer
17371803
/// primitives via the `checked_div` method. For example,
17381804
/// [`std::u32::checked_div`](../../std/primitive.u32.html#method.checked_div)
17391805
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
17401806
pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
17411807
/// Returns the remainder of an unchecked division, resulting in
17421808
/// undefined behavior where y = 0 or x = `T::MIN` and y = -1
17431809
///
1744-
/// The stabilized versions of this intrinsic are available on the integer
1810+
/// Safe wrappers for this intrinsic are available on the integer
17451811
/// primitives via the `checked_rem` method. For example,
17461812
/// [`std::u32::checked_rem`](../../std/primitive.u32.html#method.checked_rem)
17471813
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
@@ -1750,32 +1816,38 @@ extern "rust-intrinsic" {
17501816
/// Performs an unchecked left shift, resulting in undefined behavior when
17511817
/// y < 0 or y >= N, where N is the width of T in bits.
17521818
///
1753-
/// The stabilized versions of this intrinsic are available on the integer
1819+
/// Safe wrappers for this intrinsic are available on the integer
17541820
/// primitives via the `checked_shl` method. For example,
17551821
/// [`std::u32::checked_shl`](../../std/primitive.u32.html#method.checked_shl)
17561822
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
17571823
pub fn unchecked_shl<T: Copy>(x: T, y: T) -> T;
17581824
/// Performs an unchecked right shift, resulting in undefined behavior when
17591825
/// y < 0 or y >= N, where N is the width of T in bits.
17601826
///
1761-
/// The stabilized versions of this intrinsic are available on the integer
1827+
/// Safe wrappers for this intrinsic are available on the integer
17621828
/// primitives via the `checked_shr` method. For example,
17631829
/// [`std::u32::checked_shr`](../../std/primitive.u32.html#method.checked_shr)
17641830
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
17651831
pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;
17661832

17671833
/// Returns the result of an unchecked addition, resulting in
17681834
/// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
1835+
///
1836+
/// This intrinsic does not have a stable counterpart.
17691837
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
17701838
pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
17711839

17721840
/// Returns the result of an unchecked subtraction, resulting in
17731841
/// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
1842+
///
1843+
/// This intrinsic does not have a stable counterpart.
17741844
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
17751845
pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
17761846

17771847
/// Returns the result of an unchecked multiplication, resulting in
17781848
/// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
1849+
///
1850+
/// This intrinsic does not have a stable counterpart.
17791851
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
17801852
pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
17811853

src/libcore/macros/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,10 @@ pub(crate) mod builtin {
11591159
/// The syntax given to this macro is the same syntax as the [`cfg`]
11601160
/// attribute.
11611161
///
1162+
/// `cfg!`, unlike `#[cfg]`, does not remove any code and only evaluates to true or false. For
1163+
/// example, all blocks in an if/else expression need to be valid when `cfg!` is used for
1164+
/// the condition, regardless of what `cfg!` is evaluating.
1165+
///
11621166
/// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
11631167
///
11641168
/// # Examples

src/libcore/panic.rs

+2
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ impl<'a> Location<'a> {
228228
/// assert_ne!(this_location.line(), another_location.line());
229229
/// assert_ne!(this_location.column(), another_location.column());
230230
/// ```
231+
// FIXME: When stabilizing this method, please also update the documentation
232+
// of `intrinsics::caller_location`.
231233
#[unstable(
232234
feature = "track_caller",
233235
reason = "uses #[track_caller] which is not yet stable",

src/librustc_mir/const_eval/eval_queries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ fn validate_and_turn_into_const<'tcx>(
193193
mplace.into(),
194194
path,
195195
&mut ref_tracking,
196-
/*may_ref_to_static*/ is_static,
196+
/*may_ref_to_static*/ ecx.memory.extra.can_access_statics,
197197
)?;
198198
}
199199
}

src/librustc_mir/const_eval/machine.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
9999

100100
#[derive(Copy, Clone, Debug)]
101101
pub struct MemoryExtra {
102-
/// Whether this machine may read from statics
102+
/// We need to make sure consts never point to anything mutable, even recursively. That is
103+
/// relied on for pattern matching on consts with references.
104+
/// To achieve this, two pieces have to work together:
105+
/// * Interning makes everything outside of statics immutable.
106+
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
107+
/// This boolean here controls the second part.
103108
pub(super) can_access_statics: bool,
104109
}
105110

@@ -337,6 +342,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
337342
} else if static_def_id.is_some() {
338343
// Machine configuration does not allow us to read statics
339344
// (e.g., `const` initializer).
345+
// See const_eval::machine::MemoryExtra::can_access_statics for why
346+
// this check is so important: if we could read statics, we could read pointers
347+
// to mutable allocations *inside* statics. These allocations are not themselves
348+
// statics, so pointers to them can get around the check in `validity.rs`.
340349
Err(ConstEvalErrKind::ConstAccessesStatic.into())
341350
} else {
342351
// Immutable global, this read is fine.

src/librustc_mir/interpret/memory.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
453453
// thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID,
454454
// and the other one is maps to `GlobalAlloc::Memory`, this is returned by
455455
// `const_eval_raw` and it is the "resolved" ID.
456-
// The resolved ID is never used by the interpreted progrma, it is hidden.
456+
// The resolved ID is never used by the interpreted program, it is hidden.
457+
// This is relied upon for soundness of const-patterns; a pointer to the resolved
458+
// ID would "sidestep" the checks that make sure consts do not point to statics!
457459
// The `GlobalAlloc::Memory` branch here is still reachable though; when a static
458460
// contains a reference to memory that was created during its evaluation (i.e., not
459461
// to another static), those inner references only exist in "resolved" form.

0 commit comments

Comments
 (0)