@@ -374,6 +374,7 @@ use crate::hash;
374374use crate :: intrinsics:: {
375375 self , assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping,
376376} ;
377+ use crate :: panic:: debug_assert_nounwind;
377378
378379use crate :: mem:: { self , MaybeUninit } ;
379380
@@ -1161,13 +1162,13 @@ pub const unsafe fn read<T>(src: *const T) -> T {
11611162 // Future enhancements to MIR optimizations might well allow this to return
11621163 // to the previous implementation, rather than using an intrinsic.
11631164
1165+ debug_assert_nounwind ! (
1166+ is_aligned_and_not_null( src) ,
1167+ "ptr::read requires that the pointer argument is aligned and non-null" ,
1168+ ) ;
1169+
11641170 // SAFETY: the caller must guarantee that `src` is valid for reads.
11651171 unsafe {
1166- assert_unsafe_precondition ! (
1167- "ptr::read requires that the pointer argument is aligned and non-null" ,
1168- [ T ] ( src: * const T ) => is_aligned_and_not_null( src)
1169- ) ;
1170-
11711172 #[ cfg( bootstrap) ]
11721173 {
11731174 // We are calling the intrinsics directly to avoid function calls in the
@@ -1375,14 +1376,15 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
13751376 fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
13761377 }
13771378
1379+ debug_assert_nounwind ! (
1380+ is_aligned_and_not_null( dst) ,
1381+ "ptr::write requires that the pointer argument is aligned and non-null" ,
1382+ ) ;
1383+
13781384 // SAFETY: the caller must guarantee that `dst` is valid for writes.
13791385 // `dst` cannot overlap `src` because the caller has mutable access
13801386 // to `dst` while `src` is owned by this function.
13811387 unsafe {
1382- assert_unsafe_precondition ! (
1383- "ptr::write requires that the pointer argument is aligned and non-null" ,
1384- [ T ] ( dst: * mut T ) => is_aligned_and_not_null( dst)
1385- ) ;
13861388 copy_nonoverlapping ( & src as * const T , dst, 1 ) ;
13871389 intrinsics:: forget ( src) ;
13881390 }
@@ -1544,14 +1546,13 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
15441546#[ stable( feature = "volatile" , since = "1.9.0" ) ]
15451547#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
15461548pub unsafe fn read_volatile < T > ( src : * const T ) -> T {
1549+ debug_assert_nounwind ! (
1550+ is_aligned_and_not_null( src) ,
1551+ "ptr::read_volatile requires that the pointer argument is aligned and non-null" ,
1552+ ) ;
1553+
15471554 // SAFETY: the caller must uphold the safety contract for `volatile_load`.
1548- unsafe {
1549- assert_unsafe_precondition ! (
1550- "ptr::read_volatile requires that the pointer argument is aligned and non-null" ,
1551- [ T ] ( src: * const T ) => is_aligned_and_not_null( src)
1552- ) ;
1553- intrinsics:: volatile_load ( src)
1554- }
1555+ unsafe { intrinsics:: volatile_load ( src) }
15551556}
15561557
15571558/// Performs a volatile write of a memory location with the given value without
@@ -1618,12 +1619,13 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
16181619#[ stable( feature = "volatile" , since = "1.9.0" ) ]
16191620#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
16201621pub unsafe fn write_volatile < T > ( dst : * mut T , src : T ) {
1622+ debug_assert_nounwind ! (
1623+ is_aligned_and_not_null( dst) ,
1624+ "ptr::write_volatile requires that the pointer argument is aligned and non-null" ,
1625+ ) ;
1626+
16211627 // SAFETY: the caller must uphold the safety contract for `volatile_store`.
16221628 unsafe {
1623- assert_unsafe_precondition ! (
1624- "ptr::write_volatile requires that the pointer argument is aligned and non-null" ,
1625- [ T ] ( dst: * mut T ) => is_aligned_and_not_null( dst)
1626- ) ;
16271629 intrinsics:: volatile_store ( dst, src) ;
16281630 }
16291631}
0 commit comments