Skip to content

Commit 695a306

Browse files
committed
Auto merge of #129658 - saethlin:spare-a-crumb, r=<try>
Add some track_caller info to precondition panics Currently, when you encounter a precondition check, you'll always get the caller location of the implementation of the precondition checks. But with this PR, you'll be told the location of the invalid call. Which is useful. I thought of this while looking at #129642 (comment). The changes to `tests/ui/const*` happen because the const-eval interpreter skips `#[track_caller]` frames in its backtraces. The perf implications of this are: * Increased debug binary sizes. The caller_location implementation requires that the additional data we want to display here be stored in const allocations, which are deduplicated but not across crates. There is no impact on optimized build sizes. The panic path and the caller location data get optimized out. * The compile time hit to opt-incr-patched bitmaps happens because the patch changes the line number of some function calls with precondition checks, causing us to go from 0 dirty CGUs to 1 dirty CGU. * The other compile time hits are marginal but real, and due to doing a handful of new queries. Adding more useful data isn't completely free.
2 parents c43786c + e36dc78 commit 695a306

File tree

77 files changed

+175
-207
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+175
-207
lines changed

library/core/src/alloc/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ impl Layout {
126126
#[rustc_const_stable(feature = "const_alloc_layout_unchecked", since = "1.36.0")]
127127
#[must_use]
128128
#[inline]
129+
#[track_caller]
129130
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
130131
assert_unsafe_precondition!(
131132
check_library_ub,

library/core/src/ascii/ascii_char.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ impl AsciiChar {
503503
/// something useful. It might be tightened before stabilization.)
504504
#[unstable(feature = "ascii_char", issue = "110998")]
505505
#[inline]
506+
#[track_caller]
506507
pub const unsafe fn digit_unchecked(d: u8) -> Self {
507508
assert_unsafe_precondition!(
508509
check_language_ub,

library/core/src/char/convert.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
2222
#[inline]
2323
#[must_use]
2424
#[allow(unnecessary_transmutes)]
25+
#[track_caller]
2526
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
2627
// SAFETY: the caller must guarantee that `i` is a valid char value.
2728
unsafe {

library/core/src/hint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ use crate::{intrinsics, ub_checks};
9898
#[inline]
9999
#[stable(feature = "unreachable", since = "1.27.0")]
100100
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
101-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
101+
#[track_caller]
102102
pub const unsafe fn unreachable_unchecked() -> ! {
103103
ub_checks::assert_unsafe_precondition!(
104104
check_language_ub,

library/core/src/intrinsics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2634,7 +2634,7 @@ pub const fn three_way_compare<T: Copy>(lhs: T, rhss: T) -> crate::cmp::Ordering
26342634
#[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")]
26352635
#[rustc_nounwind]
26362636
#[rustc_intrinsic]
2637-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2637+
#[track_caller]
26382638
#[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell Miri
26392639
pub const unsafe fn disjoint_bitor<T: ~const fallback::DisjointBitOr>(a: T, b: T) -> T {
26402640
// SAFETY: same preconditions as this function.

library/core/src/num/int_macros.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ macro_rules! int_impl {
555555
#[must_use = "this returns the result of the operation, \
556556
without modifying the original"]
557557
#[inline(always)]
558-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
558+
#[track_caller]
559559
pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
560560
assert_unsafe_precondition!(
561561
check_language_ub,
@@ -705,7 +705,7 @@ macro_rules! int_impl {
705705
#[must_use = "this returns the result of the operation, \
706706
without modifying the original"]
707707
#[inline(always)]
708-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
708+
#[track_caller]
709709
pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
710710
assert_unsafe_precondition!(
711711
check_language_ub,
@@ -855,7 +855,7 @@ macro_rules! int_impl {
855855
#[must_use = "this returns the result of the operation, \
856856
without modifying the original"]
857857
#[inline(always)]
858-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
858+
#[track_caller]
859859
pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
860860
assert_unsafe_precondition!(
861861
check_language_ub,
@@ -1199,7 +1199,7 @@ macro_rules! int_impl {
11991199
#[must_use = "this returns the result of the operation, \
12001200
without modifying the original"]
12011201
#[inline(always)]
1202-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1202+
#[track_caller]
12031203
pub const unsafe fn unchecked_neg(self) -> Self {
12041204
assert_unsafe_precondition!(
12051205
check_language_ub,
@@ -1327,7 +1327,7 @@ macro_rules! int_impl {
13271327
#[must_use = "this returns the result of the operation, \
13281328
without modifying the original"]
13291329
#[inline(always)]
1330-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1330+
#[track_caller]
13311331
pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
13321332
assert_unsafe_precondition!(
13331333
check_language_ub,
@@ -1448,7 +1448,7 @@ macro_rules! int_impl {
14481448
#[must_use = "this returns the result of the operation, \
14491449
without modifying the original"]
14501450
#[inline(always)]
1451-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1451+
#[track_caller]
14521452
pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
14531453
assert_unsafe_precondition!(
14541454
check_language_ub,

library/core/src/num/nonzero.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ where
388388
#[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
389389
#[must_use]
390390
#[inline]
391+
#[track_caller]
391392
pub const unsafe fn new_unchecked(n: T) -> Self {
392393
match Self::new(n) {
393394
Some(n) => n,
@@ -428,6 +429,7 @@ where
428429
#[unstable(feature = "nonzero_from_mut", issue = "106290")]
429430
#[must_use]
430431
#[inline]
432+
#[track_caller]
431433
pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self {
432434
match Self::from_mut(n) {
433435
Some(n) => n,

library/core/src/num/uint_macros.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ macro_rules! uint_impl {
601601
#[must_use = "this returns the result of the operation, \
602602
without modifying the original"]
603603
#[inline(always)]
604-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
604+
#[track_caller]
605605
pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
606606
assert_unsafe_precondition!(
607607
check_language_ub,
@@ -791,7 +791,7 @@ macro_rules! uint_impl {
791791
#[must_use = "this returns the result of the operation, \
792792
without modifying the original"]
793793
#[inline(always)]
794-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
794+
#[track_caller]
795795
pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
796796
assert_unsafe_precondition!(
797797
check_language_ub,
@@ -974,7 +974,7 @@ macro_rules! uint_impl {
974974
#[must_use = "this returns the result of the operation, \
975975
without modifying the original"]
976976
#[inline(always)]
977-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
977+
#[track_caller]
978978
pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
979979
assert_unsafe_precondition!(
980980
check_language_ub,
@@ -1588,7 +1588,7 @@ macro_rules! uint_impl {
15881588
#[must_use = "this returns the result of the operation, \
15891589
without modifying the original"]
15901590
#[inline(always)]
1591-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1591+
#[track_caller]
15921592
pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
15931593
assert_unsafe_precondition!(
15941594
check_language_ub,
@@ -1709,7 +1709,7 @@ macro_rules! uint_impl {
17091709
#[must_use = "this returns the result of the operation, \
17101710
without modifying the original"]
17111711
#[inline(always)]
1712-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1712+
#[track_caller]
17131713
pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
17141714
assert_unsafe_precondition!(
17151715
check_language_ub,

library/core/src/ops/index_range.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ impl IndexRange {
1919
/// # Safety
2020
/// - `start <= end`
2121
#[inline]
22+
#[track_caller]
2223
pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
2324
ub_checks::assert_unsafe_precondition!(
2425
check_library_ub,

library/core/src/ptr/alignment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ impl Alignment {
7373
/// It must *not* be zero.
7474
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
7575
#[inline]
76+
#[track_caller]
7677
pub const unsafe fn new_unchecked(align: usize) -> Self {
7778
assert_unsafe_precondition!(
7879
check_language_ub,

library/core/src/ptr/const_ptr.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ impl<T: ?Sized> *const T {
444444
#[must_use = "returns a new pointer rather than modifying its argument"]
445445
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
446446
#[inline(always)]
447-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
447+
#[track_caller]
448448
pub const unsafe fn offset(self, count: isize) -> *const T
449449
where
450450
T: Sized,
@@ -497,7 +497,7 @@ impl<T: ?Sized> *const T {
497497
#[inline(always)]
498498
#[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
499499
#[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
500-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
500+
#[track_caller]
501501
pub const unsafe fn byte_offset(self, count: isize) -> Self {
502502
// SAFETY: the caller must uphold the safety contract for `offset`.
503503
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
@@ -796,7 +796,7 @@ impl<T: ?Sized> *const T {
796796
#[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
797797
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
798798
#[inline]
799-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
799+
#[track_caller]
800800
pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
801801
where
802802
T: Sized,
@@ -841,7 +841,7 @@ impl<T: ?Sized> *const T {
841841
#[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
842842
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
843843
#[inline]
844-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
844+
#[track_caller]
845845
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *const U) -> usize {
846846
// SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`.
847847
unsafe { self.cast::<u8>().offset_from_unsigned(origin.cast::<u8>()) }
@@ -955,7 +955,7 @@ impl<T: ?Sized> *const T {
955955
#[must_use = "returns a new pointer rather than modifying its argument"]
956956
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
957957
#[inline(always)]
958-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
958+
#[track_caller]
959959
pub const unsafe fn add(self, count: usize) -> Self
960960
where
961961
T: Sized,
@@ -1007,7 +1007,7 @@ impl<T: ?Sized> *const T {
10071007
#[inline(always)]
10081008
#[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
10091009
#[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
1010-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1010+
#[track_caller]
10111011
pub const unsafe fn byte_add(self, count: usize) -> Self {
10121012
// SAFETY: the caller must uphold the safety contract for `add`.
10131013
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
@@ -1061,7 +1061,7 @@ impl<T: ?Sized> *const T {
10611061
#[must_use = "returns a new pointer rather than modifying its argument"]
10621062
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
10631063
#[inline(always)]
1064-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1064+
#[track_caller]
10651065
pub const unsafe fn sub(self, count: usize) -> Self
10661066
where
10671067
T: Sized,
@@ -1119,7 +1119,7 @@ impl<T: ?Sized> *const T {
11191119
#[inline(always)]
11201120
#[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
11211121
#[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
1122-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1122+
#[track_caller]
11231123
pub const unsafe fn byte_sub(self, count: usize) -> Self {
11241124
// SAFETY: the caller must uphold the safety contract for `sub`.
11251125
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
@@ -1292,7 +1292,7 @@ impl<T: ?Sized> *const T {
12921292
#[stable(feature = "pointer_methods", since = "1.26.0")]
12931293
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
12941294
#[inline]
1295-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1295+
#[track_caller]
12961296
pub const unsafe fn read(self) -> T
12971297
where
12981298
T: Sized,
@@ -1313,7 +1313,7 @@ impl<T: ?Sized> *const T {
13131313
/// [`ptr::read_volatile`]: crate::ptr::read_volatile()
13141314
#[stable(feature = "pointer_methods", since = "1.26.0")]
13151315
#[inline]
1316-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1316+
#[track_caller]
13171317
pub unsafe fn read_volatile(self) -> T
13181318
where
13191319
T: Sized,
@@ -1333,7 +1333,7 @@ impl<T: ?Sized> *const T {
13331333
#[stable(feature = "pointer_methods", since = "1.26.0")]
13341334
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
13351335
#[inline]
1336-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1336+
#[track_caller]
13371337
pub const unsafe fn read_unaligned(self) -> T
13381338
where
13391339
T: Sized,
@@ -1353,7 +1353,7 @@ impl<T: ?Sized> *const T {
13531353
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
13541354
#[stable(feature = "pointer_methods", since = "1.26.0")]
13551355
#[inline]
1356-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1356+
#[track_caller]
13571357
pub const unsafe fn copy_to(self, dest: *mut T, count: usize)
13581358
where
13591359
T: Sized,
@@ -1373,7 +1373,7 @@ impl<T: ?Sized> *const T {
13731373
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
13741374
#[stable(feature = "pointer_methods", since = "1.26.0")]
13751375
#[inline]
1376-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1376+
#[track_caller]
13771377
pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
13781378
where
13791379
T: Sized,

library/core/src/ptr/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
13771377
#[rustc_const_stable(feature = "const_swap_nonoverlapping", since = "1.88.0")]
13781378
#[rustc_diagnostic_item = "ptr_swap_nonoverlapping"]
13791379
#[rustc_allow_const_fn_unstable(const_eval_select)] // both implementations behave the same
1380+
#[track_caller]
13801381
pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
13811382
ub_checks::assert_unsafe_precondition!(
13821383
check_library_ub,
@@ -1557,6 +1558,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, bytes: NonZero<usize
15571558
#[stable(feature = "rust1", since = "1.0.0")]
15581559
#[rustc_const_stable(feature = "const_replace", since = "1.83.0")]
15591560
#[rustc_diagnostic_item = "ptr_replace"]
1561+
#[track_caller]
15601562
pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
15611563
// SAFETY: the caller must guarantee that `dst` is valid to be
15621564
// cast to a mutable reference (valid for writes, aligned, initialized),
@@ -1684,7 +1686,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
16841686
#[inline]
16851687
#[stable(feature = "rust1", since = "1.0.0")]
16861688
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
1687-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1689+
#[track_caller]
16881690
#[rustc_diagnostic_item = "ptr_read"]
16891691
pub const unsafe fn read<T>(src: *const T) -> T {
16901692
// It would be semantically correct to implement this via `copy_nonoverlapping`
@@ -1802,7 +1804,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
18021804
#[inline]
18031805
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
18041806
#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
1805-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1807+
#[track_caller]
18061808
#[rustc_diagnostic_item = "ptr_read_unaligned"]
18071809
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
18081810
let mut tmp = MaybeUninit::<T>::uninit();
@@ -1901,7 +1903,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
19011903
#[stable(feature = "rust1", since = "1.0.0")]
19021904
#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
19031905
#[rustc_diagnostic_item = "ptr_write"]
1904-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1906+
#[track_caller]
19051907
pub const unsafe fn write<T>(dst: *mut T, src: T) {
19061908
// Semantically, it would be fine for this to be implemented as a
19071909
// `copy_nonoverlapping` and appropriate drop suppression of `src`.
@@ -2005,7 +2007,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
20052007
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
20062008
#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
20072009
#[rustc_diagnostic_item = "ptr_write_unaligned"]
2008-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2010+
#[track_caller]
20092011
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
20102012
// SAFETY: the caller must guarantee that `dst` is valid for writes.
20112013
// `dst` cannot overlap `src` because the caller has mutable access
@@ -2079,7 +2081,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
20792081
/// ```
20802082
#[inline]
20812083
#[stable(feature = "volatile", since = "1.9.0")]
2082-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2084+
#[track_caller]
20832085
#[rustc_diagnostic_item = "ptr_read_volatile"]
20842086
pub unsafe fn read_volatile<T>(src: *const T) -> T {
20852087
// SAFETY: the caller must uphold the safety contract for `volatile_load`.
@@ -2160,7 +2162,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
21602162
#[inline]
21612163
#[stable(feature = "volatile", since = "1.9.0")]
21622164
#[rustc_diagnostic_item = "ptr_write_volatile"]
2163-
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2165+
#[track_caller]
21642166
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
21652167
// SAFETY: the caller must uphold the safety contract for `volatile_store`.
21662168
unsafe {

0 commit comments

Comments
 (0)