diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 4d051a370c065..28b23bd37485a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -448,9 +448,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some((msg, span)) = type_def { err.span_label(span, msg); } - for note in notes { - // If it has a custom `#[rustc_on_unimplemented]` note, let's display it - err.note(note); + // `#[rustc_on_unimplemented]` notes for derivable traits (e.g. `Debug`'s + // "add `#[derive(Debug)]` to `X` or manually `impl Debug for X`") duplicate + // the `consider annotating X with #[derive(..)]` suggestion that + // `suggest_derive` emits below, so skip them when that suggestion will be + // shown. We keep the note otherwise (e.g. when a field isn't `Debug`, so + // the derive can't be suggested) to avoid leaving the diagnostic without + // actionable guidance. + let derive_suggestion_will_be_shown = main_trait_predicate + == leaf_trait_predicate + && self.can_suggest_derive(&obligation, leaf_trait_predicate); + if !derive_suggestion_will_be_shown { + for note in notes { + // If it has a custom `#[rustc_on_unimplemented]` note, let's display + // it. + err.note(note); + } } if let Some(s) = parent_label { let body = obligation.cause.body_id; diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 52f099e77255b..e2dc87061348e 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -204,12 +204,12 @@ impl Global { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces fn alloc_impl_runtime(layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), + 0 => Ok(layout.dangling_ptr().cast_slice(0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { alloc_zeroed(layout) } else { alloc(layout) }; let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, size)) + Ok(ptr.cast_slice(size)) }, } } @@ -261,7 +261,7 @@ impl Global { if zeroed { raw_ptr.add(old_size).write_bytes(0, new_size - old_size); } - Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + Ok(ptr.cast_slice(new_size)) }, // SAFETY: because `new_layout.size()` must be greater than or equal to `old_size`, @@ -297,7 +297,7 @@ impl Global { // SAFETY: conditions must be upheld by the caller 0 => unsafe { self.deallocate(ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) + Ok(new_layout.dangling_ptr().cast_slice(0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller @@ -307,7 +307,7 @@ impl Global { let raw_ptr = realloc_nonnull(ptr, old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + Ok(ptr.cast_slice(new_size)) }, // SAFETY: because `new_size` must be smaller than or equal to `old_layout.size()`, @@ -388,7 +388,7 @@ impl Global { #[rustc_const_unstable(feature = "const_heap", issue = "79597")] const fn alloc_impl_const(layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), + 0 => Ok(layout.dangling_ptr().cast_slice(0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); @@ -397,7 +397,7 @@ impl Global { // SAFETY: the pointer returned by `const_allocate` is valid to write to. ptr.write_bytes(0, size); } - Ok(NonNull::slice_from_raw_parts(ptr, size)) + Ok(ptr.cast_slice(size)) }, } } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index d91b35c1f6077..5a900db9d1ce8 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -226,9 +226,7 @@ impl VecDeque { /// `range` must lie inside `0..self.capacity()`. #[inline] unsafe fn buffer_range(&self, range: Range) -> *mut [T] { - unsafe { - ptr::slice_from_raw_parts_mut(self.ptr().add(range.start), range.end - range.start) - } + unsafe { self.ptr().add(range.start).cast_slice(range.end - range.start) } } /// Returns `true` if the buffer is at full capacity. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 5fe5464ab2cdd..f66dc648f809b 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -73,6 +73,7 @@ // Lints: #![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![warn(deprecated_in_future)] #![warn(missing_debug_implementations)] #![warn(missing_docs)] @@ -140,6 +141,7 @@ #![feature(pattern)] #![feature(pin_coerce_unsized_trait)] #![feature(ptr_alignment_type)] +#![feature(ptr_cast_slice)] #![feature(ptr_internals)] #![feature(ptr_metadata)] #![feature(rev_into_inner)] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 0309d63cce06d..2f7d26c7a9724 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -244,7 +244,7 @@ impl RawVec { let me = ManuallyDrop::new(self); unsafe { - let slice = ptr::slice_from_raw_parts_mut(me.ptr() as *mut MaybeUninit, len); + let slice = me.ptr().cast::>().cast_slice(len); Box::from_raw_in(slice, ptr::read(&me.inner.alloc)) } } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2491489517688..523c9b8b15858 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1160,10 +1160,7 @@ impl Rc<[T]> { Rc::from_ptr(Rc::allocate_for_layout( Layout::array::(len).unwrap(), |layout| Global.allocate_zeroed(layout), - |mem| { - ptr::slice_from_raw_parts_mut(mem.cast::(), len) - as *mut RcInner<[mem::MaybeUninit]> - }, + |mem| mem.cast::().cast_slice(len) as *mut RcInner<[mem::MaybeUninit]>, )) } } @@ -1231,10 +1228,7 @@ impl Rc<[T], A> { Rc::allocate_for_layout( Layout::array::(len).unwrap(), |layout| alloc.allocate_zeroed(layout), - |mem| { - ptr::slice_from_raw_parts_mut(mem.cast::(), len) - as *mut RcInner<[mem::MaybeUninit]> - }, + |mem| mem.cast::().cast_slice(len) as *mut RcInner<[mem::MaybeUninit]>, ), alloc, ) @@ -2327,7 +2321,7 @@ impl Rc<[T]> { Self::allocate_for_layout( Layout::array::(len).unwrap(), |layout| Global.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcInner<[T]>, + |mem| mem.cast::().cast_slice(len) as *mut RcInner<[T]>, ) } } @@ -2404,7 +2398,7 @@ impl Rc<[T], A> { Rc::<[T]>::allocate_for_layout( Layout::array::(len).unwrap(), |layout| alloc.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcInner<[T]>, + |mem| mem.cast::().cast_slice(len) as *mut RcInner<[T]>, ) } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 597d26d3239ad..4a9878d8e249d 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1306,10 +1306,7 @@ impl Arc<[T]> { Arc::from_ptr(Arc::allocate_for_layout( Layout::array::(len).unwrap(), |layout| Global.allocate_zeroed(layout), - |mem| { - ptr::slice_from_raw_parts_mut(mem as *mut T, len) - as *mut ArcInner<[mem::MaybeUninit]> - }, + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, )) } } @@ -1378,10 +1375,7 @@ impl Arc<[T], A> { Arc::allocate_for_layout( Layout::array::(len).unwrap(), |layout| alloc.allocate_zeroed(layout), - |mem| { - ptr::slice_from_raw_parts_mut(mem.cast::(), len) - as *mut ArcInner<[mem::MaybeUninit]> - }, + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[mem::MaybeUninit]>, ), alloc, ) @@ -2272,7 +2266,7 @@ impl Arc<[T]> { Self::allocate_for_layout( Layout::array::(len).unwrap(), |layout| Global.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut ArcInner<[T]>, + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, ) } } @@ -2351,7 +2345,7 @@ impl Arc<[T], A> { Arc::allocate_for_layout( Layout::array::(len).unwrap(), |layout| alloc.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut ArcInner<[T]>, + |mem| mem.cast::().cast_slice(len) as *mut ArcInner<[T]>, ) } } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 9a6bfa823f2a5..d12dea20b33cb 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -232,7 +232,7 @@ impl Drop for Drain<'_, T, A> { // invalidate raw pointers to it which some unsafe code might rely on. let vec_ptr = vec.as_mut().as_mut_ptr(); let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr); - let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len); + let to_drop = vec_ptr.add(drop_offset).cast_slice(drop_len); ptr::drop_in_place(to_drop); } } diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index c8cc758ac15c4..5c3d598cdef0c 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -1,5 +1,5 @@ use core::marker::PhantomData; -use core::ptr::{self, NonNull, drop_in_place}; +use core::ptr::NonNull; use crate::alloc::Global; use crate::raw_vec::RawVec; @@ -20,9 +20,7 @@ impl InPlaceDrop { impl Drop for InPlaceDrop { #[inline] fn drop(&mut self) { - unsafe { - ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.inner, self.len())); - } + unsafe { self.inner.cast_slice(self.len()).drop_in_place() } } } @@ -42,7 +40,7 @@ impl Drop for InPlaceDstDataSrcBufDrop { unsafe { let _drop_allocation = RawVec::::from_nonnull_in(self.ptr.cast::(), self.src_cap, Global); - drop_in_place(core::ptr::slice_from_raw_parts_mut::(self.ptr.as_ptr(), self.len)); + self.ptr.as_ptr().cast_slice(self.len).drop_in_place(); }; } } diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 9c4b24b2731b1..97e4912596b94 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -115,7 +115,7 @@ impl IntoIter { } fn as_raw_mut_slice(&mut self) -> *mut [T] { - ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len()) + self.ptr.as_ptr().cast_slice(self.len()) } /// Drops remaining elements and relinquishes the backing allocation. @@ -282,7 +282,7 @@ impl Iterator for IntoIter { #[inline] fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { let step_size = self.len().min(n); - let to_drop = ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), step_size); + let to_drop = self.ptr.as_ptr().cast_slice(step_size); if T::IS_ZST { // See `next` for why we sub `end` here. self.end = self.end.wrapping_byte_sub(step_size); @@ -457,9 +457,9 @@ impl DoubleEndedIterator for IntoIter { } let to_drop = if T::IS_ZST { // ZST may cause unalignment - ptr::slice_from_raw_parts_mut(ptr::NonNull::::dangling().as_ptr(), step_size) + ptr::NonNull::::dangling().as_ptr().cast_slice(step_size) } else { - ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size) + self.end.cast::().cast_mut().cast_slice(step_size) }; // SAFETY: same as for advance_by() unsafe { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d2b7837d98fa6..130f72b0ee485 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1830,7 +1830,7 @@ impl Vec { return; } let remaining_len = self.len - len; - let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len); + let s = self.as_mut_ptr().add(len).cast_slice(remaining_len); self.len = len; ptr::drop_in_place(s); } @@ -4289,7 +4289,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { // use drop for [T] // use a raw slice to refer to the elements of the vector as weakest necessary type; // could avoid questions of validity in certain cases - ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) + self.as_mut_ptr().cast_slice(self.len).drop_in_place() } // RawVec handles deallocation } diff --git a/library/alloctests/benches/lib.rs b/library/alloctests/benches/lib.rs index b7e09fc2e162b..2be7a24d2de7b 100644 --- a/library/alloctests/benches/lib.rs +++ b/library/alloctests/benches/lib.rs @@ -7,6 +7,7 @@ #![feature(strict_provenance_lints)] #![feature(test)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] extern crate test; diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 936d60fdad73b..db643ccb7a4e6 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -36,6 +36,7 @@ #![feature(iter_next_chunk)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(ptr_alignment_type)] +#![feature(ptr_cast_slice)] #![feature(ptr_internals)] #![feature(rev_into_inner)] #![feature(sized_type_properties)] diff --git a/library/alloctests/tests/arc.rs b/library/alloctests/tests/arc.rs index a56204187c0a0..4b4d1787ace63 100644 --- a/library/alloctests/tests/arc.rs +++ b/library/alloctests/tests/arc.rs @@ -107,7 +107,7 @@ fn eq_unsized() { fn eq_unsized_slice() { let a: Arc<[()]> = Arc::new([(); 3]); let ptr: *const () = Arc::into_raw(a.clone()).cast(); - let b: Arc<[()]> = unsafe { Arc::from_raw(core::ptr::slice_from_raw_parts(ptr, 42)) }; + let b: Arc<[()]> = unsafe { Arc::from_raw(ptr.cast_slice(42)) }; assert!(a == a); assert!(!(a != a)); assert!(a != b); diff --git a/library/alloctests/tests/boxed.rs b/library/alloctests/tests/boxed.rs index 83fd1ef7449a3..c73b7109fb387 100644 --- a/library/alloctests/tests/boxed.rs +++ b/library/alloctests/tests/boxed.rs @@ -47,9 +47,9 @@ fn box_clone_from_ptr_stability() { for size in (0..8).map(|i| 2usize.pow(i)) { let control = vec![Dummy { _data: 42 }; size].into_boxed_slice(); let mut copy = vec![Dummy { _data: 84 }; size].into_boxed_slice(); - let copy_raw = copy.as_ptr() as usize; + let copy_raw = copy.as_ptr(); copy.clone_from(&control); - assert_eq!(copy.as_ptr() as usize, copy_raw); + assert_eq!(copy.as_ptr(), copy_raw); } } @@ -104,7 +104,7 @@ pub struct ConstAllocator; unsafe impl Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), + 0 => Ok(layout.dangling_ptr().cast_slice(0)), _ => unsafe { let ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8])) diff --git a/library/alloctests/tests/heap.rs b/library/alloctests/tests/heap.rs index 246b341eeb387..8eb562622c0a4 100644 --- a/library/alloctests/tests/heap.rs +++ b/library/alloctests/tests/heap.rs @@ -25,7 +25,7 @@ fn check_overalign_requests(allocator: T) { .collect(); for &ptr in &pointers { assert_eq!( - (ptr.as_non_null_ptr().as_ptr() as usize) % align, + ptr.as_non_null_ptr().as_ptr().addr() % align, 0, "Got a pointer less aligned than requested" ) diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 699a5010282b0..b7c3e39c992b0 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -41,8 +41,10 @@ #![feature(macro_metavar_expr_concat)] #![feature(vec_peek_mut)] #![feature(vec_try_remove)] +#![feature(ptr_cast_slice)] #![allow(internal_features)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] extern crate alloc; diff --git a/library/alloctests/tests/rc.rs b/library/alloctests/tests/rc.rs index 5be0e8f339119..0417206d713ef 100644 --- a/library/alloctests/tests/rc.rs +++ b/library/alloctests/tests/rc.rs @@ -108,7 +108,7 @@ fn eq_unsized() { fn eq_unsized_slice() { let a: Rc<[()]> = Rc::new([(); 3]); let ptr: *const () = Rc::into_raw(a.clone()).cast(); - let b: Rc<[()]> = unsafe { Rc::from_raw(core::ptr::slice_from_raw_parts(ptr, 42)) }; + let b: Rc<[()]> = unsafe { Rc::from_raw(ptr.cast_slice(42)) }; assert!(a == a); assert!(!(a != a)); assert!(a != b); diff --git a/library/alloctests/tests/sort/tests.rs b/library/alloctests/tests/sort/tests.rs index 09b76773d6b24..ec4c4fa619ddf 100644 --- a/library/alloctests/tests/sort/tests.rs +++ b/library/alloctests/tests/sort/tests.rs @@ -746,7 +746,7 @@ fn self_cmp( pattern_fn(len).into_iter().map(|val| type_into_fn(val)).collect::>(); let comparison_fn = |a: &T, b: &T| { - assert_ne!(a as *const T as usize, b as *const T as usize); + assert_ne!(a as *const T, b as *const T); a.cmp(b) }; diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index d85d2e44cd2ba..ccf9b8095b290 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -1110,7 +1110,7 @@ fn test_into_iter_zst() { struct AlignedZstWithDrop([u64; 0]); impl Drop for AlignedZstWithDrop { fn drop(&mut self) { - let addr = self as *mut _ as usize; + let addr = (self as *mut Self).addr(); assert!(hint::black_box(addr) % align_of::() == 0); } } @@ -1356,10 +1356,10 @@ fn overaligned_allocations() { for i in 0..0x1000 { v.reserve_exact(i); assert!(v[0].0 == 273); - assert!(v.as_ptr() as usize & 0xff == 0); + assert!(v.as_ptr().addr() & 0xff == 0); v.shrink_to_fit(); assert!(v[0].0 == 273); - assert!(v.as_ptr() as usize & 0xff == 0); + assert!(v.as_ptr().addr() & 0xff == 0); } } @@ -2569,12 +2569,12 @@ fn test_box_zero_allocator() { } else { unsafe { std::alloc::alloc(layout) } }; - Ok(NonNull::slice_from_raw_parts(NonNull::new(ptr).ok_or(AllocError)?, layout.size())) + Ok(NonNull::new(ptr).ok_or(AllocError)?.cast_slice(layout.size())) } unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { if layout.size() == 0 { - let addr = ptr.as_ptr() as usize; + let addr = ptr.as_ptr().addr(); let mut state = self.state.borrow_mut(); std::println!("freeing {addr}"); assert!(state.0.remove(&addr), "ZST free that wasn't allocated"); diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index 5d96de5cbcb6b..bcda315f7a4a0 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs @@ -218,10 +218,8 @@ impl Drop for Buffer { // SAFETY: our invariant guarantees that N elements starting from // `self.start` are initialized. We drop them here. unsafe { - let initialized_part: *mut [T] = crate::ptr::slice_from_raw_parts_mut( - self.buffer_mut_ptr().add(self.start).cast(), - N, - ); + let initialized_part: *mut [T] = + self.buffer_mut_ptr().add(self.start).cast::().cast_slice(N); ptr::drop_in_place(initialized_part); } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index acc758a75e77b..9d9837c846de3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -80,6 +80,7 @@ #![deny(rust_2021_incompatible_or_patterns)] #![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![warn(deprecated_in_future)] #![warn(missing_debug_implementations)] #![warn(missing_docs)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8b7b08bf82317..0a7f9b920364a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -183,6 +183,7 @@ impl *const T { /// [`with_exposed_provenance`]: with_exposed_provenance #[inline(always)] #[stable(feature = "exposed_provenance", since = "1.84.0")] + #[expect(lossy_provenance_casts, reason = "this *is* the replacement")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -1400,11 +1401,11 @@ impl *const T { /// /// ```rust /// #![feature(ptr_cast_slice)] + /// /// // create a slice pointer when starting out with a pointer to the first element /// let x = [5, 6, 7]; - /// let raw_pointer = x.as_ptr(); - /// let slice = raw_pointer.cast_slice(3); - /// assert_eq!(unsafe { &*slice }[2], 7); + /// let raw_slice = x.as_ptr().cast_slice(3); + /// assert_eq!(unsafe { &*raw_slice }[2], 7); /// ``` /// /// You must ensure that the pointer is valid and not null before dereferencing diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ff2c18d685b65..593011edecf27 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -2618,21 +2618,21 @@ impl Ord for F { #[stable(feature = "fnptr_impls", since = "1.4.0")] impl hash::Hash for F { fn hash(&self, state: &mut HH) { - state.write_usize(self.addr() as _) + state.write_usize(self.addr().addr()) } } #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Pointer for F { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::pointer_fmt_inner(self.addr() as _, f) + fmt::pointer_fmt_inner(self.addr().addr(), f) } } #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Debug for F { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::pointer_fmt_inner(self.addr() as _, f) + fmt::pointer_fmt_inner(self.addr().addr(), f) } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 98b70a77fad7b..4b68d96aeae68 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -174,6 +174,7 @@ impl *mut T { /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut #[inline(always)] #[stable(feature = "exposed_provenance", since = "1.84.0")] + #[expect(lossy_provenance_casts, reason = "this *is* the replacement")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -1675,13 +1676,13 @@ impl *mut T { /// #![feature(ptr_cast_slice)] /// /// let x = &mut [5, 6, 7]; - /// let slice = x.as_mut_ptr().cast_slice(3); + /// let raw_mut_slice = x.as_mut_ptr().cast_slice(3); /// /// unsafe { - /// (*slice)[2] = 99; // assign a value at an index in the slice + /// (*raw_mut_slice)[2] = 99; // assign a value at an index in the slice /// }; /// - /// assert_eq!(unsafe { &*slice }[2], 99); + /// assert_eq!(unsafe { &*raw_mut_slice }[2], 99); /// ``` /// /// You must ensure that the pointer is valid and not null before dereferencing @@ -1701,6 +1702,7 @@ impl *mut T { slice_from_raw_parts_mut(self, len) } } + impl *mut MaybeUninit { /// Casts from a maybe-uninitialized type to its initialized version. /// diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index b9b42c1efe05a..f165e235611b8 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1444,7 +1444,7 @@ impl NonNull<[T]> { #[inline] pub const fn slice_from_raw_parts(data: NonNull, len: usize) -> Self { // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null - unsafe { Self::new_unchecked(super::slice_from_raw_parts_mut(data.as_ptr(), len)) } + unsafe { Self::new_unchecked(data.as_ptr().cast_slice(len)) } } /// Returns the length of a non-null raw slice. diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 3b5cec22b69ea..096c847c3b8e2 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -5,7 +5,7 @@ use crate::cmp::Ordering; use crate::intrinsics::unchecked_sub; use crate::slice::SliceIndex; use crate::ub_checks::assert_unsafe_precondition; -use crate::{ops, ptr, range}; +use crate::{ops, range}; /// Implements ordering of strings. /// @@ -209,7 +209,7 @@ unsafe impl const SliceIndex for ops::Range { // which satisfies all the conditions for `add`. unsafe { let new_len = unchecked_sub(self.end, self.start); - ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str + slice.as_ptr().add(self.start).cast_slice(new_len) as *const str } } #[inline] @@ -230,7 +230,7 @@ unsafe impl const SliceIndex for ops::Range { // SAFETY: see comments for `get_unchecked`. unsafe { let new_len = unchecked_sub(self.end, self.start); - ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str + slice.as_mut_ptr().add(self.start).cast_slice(new_len) as *mut str } } #[inline] @@ -314,7 +314,7 @@ unsafe impl const SliceIndex for range::Range { // which satisfies all the conditions for `add`. unsafe { let new_len = unchecked_sub(self.end, self.start); - ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str + slice.as_ptr().add(self.start).cast_slice(new_len) as *const str } } #[inline] @@ -335,7 +335,7 @@ unsafe impl const SliceIndex for range::Range { // SAFETY: see comments for `get_unchecked`. unsafe { let new_len = unchecked_sub(self.end, self.start); - ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str + slice.as_mut_ptr().add(self.start).cast_slice(new_len) as *mut str } } #[inline] diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index 877017f682c97..43372005ad5f3 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs @@ -318,7 +318,7 @@ fn test_encode_utf8() { let mut buf = [0; char::MAX_LEN_UTF8]; let ptr = buf.as_ptr(); let s = input.encode_utf8(&mut buf); - assert_eq!(s.as_ptr() as usize, ptr as usize); + assert_eq!(s.as_ptr(), ptr); assert!(str::from_utf8(s.as_bytes()).is_ok()); assert_eq!(s.as_bytes(), expect); } @@ -335,7 +335,7 @@ fn test_encode_utf16() { let mut buf = [0; 2]; let ptr = buf.as_mut_ptr(); let b = input.encode_utf16(&mut buf); - assert_eq!(b.as_mut_ptr() as usize, ptr as usize); + assert_eq!(b.as_mut_ptr(), ptr); assert_eq!(b, expect); } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 89e8d5d8185ee..aa6aa1478bd70 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -129,6 +129,7 @@ // tidy-alphabetical-end #![allow(internal_features)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] /// Version of `assert_matches` that ignores fancy runtime printing in const context and uses structural equality. diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 93f9454d71378..9dbaf6690c81c 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -384,7 +384,7 @@ fn align_offset_stride_one() { #[test] fn align_offset_various_strides() { unsafe fn test_stride(ptr: *const T, align: usize) -> bool { - let numptr = ptr as usize; + let numptr = ptr.addr(); let mut expected = usize::MAX; // Naive but definitely correct way to find the *first* aligned element of stride::. for el in 0..align { diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 2bb62f36bb0e6..a4db7304fff90 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -1886,7 +1886,7 @@ fn test_align_to_empty_mid() { type Chunk = u32; for offset in 0..4 { let (_, mid, _) = unsafe { bytes[offset..offset + 1].align_to::() }; - assert_eq!(mid.as_ptr() as usize % align_of::(), 0); + assert_eq!(mid.as_ptr().addr() % align_of::(), 0); } } diff --git a/library/coretests/tests/waker.rs b/library/coretests/tests/waker.rs index 4889b8959ece4..be8b07b8ad009 100644 --- a/library/coretests/tests/waker.rs +++ b/library/coretests/tests/waker.rs @@ -5,16 +5,16 @@ use std::task::{RawWaker, RawWakerVTable, Waker}; fn test_waker_getters() { let raw_waker = RawWaker::new(ptr::without_provenance_mut(42usize), &WAKER_VTABLE); let waker = unsafe { Waker::from_raw(raw_waker) }; - assert_eq!(waker.data() as usize, 42); + assert_eq!(waker.data().addr(), 42); assert!(ptr::eq(waker.vtable(), &WAKER_VTABLE)); let waker2 = waker.clone(); - assert_eq!(waker2.data() as usize, 43); + assert_eq!(waker2.data().addr(), 43); assert!(ptr::eq(waker2.vtable(), &WAKER_VTABLE)); } static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( - |data| RawWaker::new(ptr::without_provenance_mut(data as usize + 1), &WAKER_VTABLE), + |data| RawWaker::new(ptr::without_provenance_mut(data.addr() + 1), &WAKER_VTABLE), |_| {}, |_| {}, |_| {}, diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index ed0322e2cf5d0..7a576e083df7c 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -142,7 +142,7 @@ impl System { #[inline] fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), + 0 => Ok(layout.dangling_ptr().cast_slice(0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { @@ -151,7 +151,7 @@ impl System { GlobalAlloc::alloc(self, layout) }; let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, size)) + Ok(ptr.cast_slice(size)) }, } } @@ -187,7 +187,7 @@ impl System { if zeroed { raw_ptr.add(old_size).write_bytes(0, new_size - old_size); } - Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + Ok(ptr.cast_slice(new_size)) }, // SAFETY: because `new_layout.size()` must be greater than or equal to `old_size`, @@ -266,7 +266,7 @@ unsafe impl Allocator for System { // SAFETY: conditions must be upheld by the caller 0 => unsafe { Allocator::deallocate(self, ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) + Ok(new_layout.dangling_ptr().cast_slice(0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller @@ -276,7 +276,7 @@ unsafe impl Allocator for System { let raw_ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, new_size)) + Ok(ptr.cast_slice(new_size)) }, // SAFETY: because `new_size` must be smaller than or equal to `old_layout.size()`, diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 150ce9c1b9a96..a4a5e8561dfcf 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -220,14 +220,13 @@ impl fmt::Debug for VarsOs { /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn var>(key: K) -> Result { - _var(key.as_ref()) -} - -fn _var(key: &OsStr) -> Result { - match var_os(key) { - Some(s) => s.into_string().map_err(VarError::NotUnicode), - None => Err(VarError::NotPresent), + fn inner(key: &OsStr) -> Result { + env_imp::getenv(key) + .ok_or(VarError::NotPresent)? + .into_string() + .map_err(VarError::NotUnicode) } + inner(key.as_ref()) } /// Fetches the environment variable `key` from the current process, returning @@ -257,11 +256,7 @@ fn _var(key: &OsStr) -> Result { #[must_use] #[stable(feature = "env", since = "1.0.0")] pub fn var_os>(key: K) -> Option { - _var_os(key.as_ref()) -} - -fn _var_os(key: &OsStr) -> Option { - env_imp::getenv(key) + env_imp::getenv(key.as_ref()) } /// The error type for operations interacting with environment variables. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 9c47f0ea35e8f..7f18d526559b6 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -246,6 +246,7 @@ #![allow(unused_lifetimes)] #![allow(internal_features)] #![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] #![allow(rustdoc::redundant_explicit_links)] #![warn(rustdoc::unescaped_backticks)] @@ -366,6 +367,7 @@ #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_as_uninit)] +#![feature(ptr_cast_slice)] #![feature(ptr_mask)] #![feature(random)] #![feature(raw_os_error_ty)] @@ -715,7 +717,13 @@ pub mod alloc; mod panicking; #[path = "../../backtrace/src/lib.rs"] -#[allow(dead_code, unused_attributes, fuzzy_provenance_casts, unsafe_op_in_unsafe_fn)] +#[allow( + dead_code, + unused_attributes, + fuzzy_provenance_casts, + lossy_provenance_casts, + unsafe_op_in_unsafe_fn +)] mod backtrace_rs; #[stable(feature = "cfg_select", since = "1.95.0")] diff --git a/library/std/src/net/test.rs b/library/std/src/net/test.rs index 68cbf7b669232..5002bb5c8e083 100644 --- a/library/std/src/net/test.rs +++ b/library/std/src/net/test.rs @@ -4,9 +4,6 @@ use crate::env; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; use crate::sync::atomic::{AtomicUsize, Ordering}; -static PORT: AtomicUsize = AtomicUsize::new(0); -const BASE_PORT: u16 = 19600; - /// A localhost address whose port will be picked automatically by the OS. pub const LOCALHOST_IP4: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 0)); @@ -14,16 +11,6 @@ pub const LOCALHOST_IP4: SocketAddr = pub const LOCALHOST_IP6: SocketAddr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 0, 0, 0)); -pub fn next_test_ip4() -> SocketAddr { - let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + BASE_PORT; - SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port)) -} - -pub fn next_test_ip6() -> SocketAddr { - let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + BASE_PORT; - SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0)) -} - pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { SocketAddr::V4(SocketAddrV4::new(a, p)) } diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs index 0638b36c54f9d..ede0240fbda57 100644 --- a/library/std/src/net/udp/tests.rs +++ b/library/std/src/net/udp/tests.rs @@ -1,15 +1,10 @@ use crate::io::ErrorKind; -use crate::net::test::{compare_ignore_zoneid, next_test_ip4, next_test_ip6}; +use crate::net::test::{LOCALHOST_IP4, LOCALHOST_IP6, compare_ignore_zoneid}; use crate::net::*; use crate::sync::mpsc::channel; use crate::thread; use crate::time::{Duration, Instant}; -fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) { - f(next_test_ip4(), next_test_ip4()); - f(next_test_ip6(), next_test_ip6()); -} - macro_rules! t { ($e:expr) => { match $e { @@ -19,6 +14,11 @@ macro_rules! t { }; } +fn each_ip(f: &mut dyn FnMut(UdpSocket, UdpSocket)) { + f(t!(UdpSocket::bind(LOCALHOST_IP4)), t!(UdpSocket::bind(LOCALHOST_IP4))); + f(t!(UdpSocket::bind(LOCALHOST_IP6)), t!(UdpSocket::bind(LOCALHOST_IP6))); +} + #[test] fn bind_error() { match UdpSocket::bind("1.1.1.1:9999") { @@ -30,18 +30,19 @@ fn bind_error() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // no threads fn socket_smoke_test_ip4() { - each_ip(&mut |server_ip, client_ip| { + each_ip(&mut |server, client| { + let server_ip = t!(server.local_addr()); + let client_ip = t!(client.local_addr()); + let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); let _t = thread::spawn(move || { - let client = t!(UdpSocket::bind(&client_ip)); rx1.recv().unwrap(); t!(client.send_to(&[99], &server_ip)); tx2.send(()).unwrap(); }); - let server = t!(UdpSocket::bind(&server_ip)); tx1.send(()).unwrap(); let mut buf = [0]; let (nread, src) = t!(server.recv_from(&mut buf)); @@ -53,29 +54,28 @@ fn socket_smoke_test_ip4() { } #[test] -fn socket_name() { - each_ip(&mut |addr, _| { - let server = t!(UdpSocket::bind(&addr)); - assert_eq!(addr, t!(server.local_addr())); - }) -} +fn socket_and_peer_name() { + each_ip(&mut |sock1, sock2| { + let addr1 = t!(sock1.local_addr()); + let addr2 = t!(sock2.local_addr()); -#[test] -fn socket_peer() { - each_ip(&mut |addr1, addr2| { - let server = t!(UdpSocket::bind(&addr1)); - assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); - t!(server.connect(&addr2)); - assert_eq!(addr2, t!(server.peer_addr())); + assert_eq!(sock1.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); + assert!(addr1.ip() == LOCALHOST_IP4.ip() || addr1.ip() == LOCALHOST_IP6.ip()); + + t!(sock1.connect(addr2)); + t!(sock2.connect(addr1)); + + assert_eq!(addr2, t!(sock1.peer_addr())); + assert_eq!(addr1, t!(sock2.peer_addr())); }) } #[test] #[cfg_attr(target_os = "wasi", ignore)] // no threads fn udp_clone_smoke() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); + each_ip(&mut |sock1, sock2| { + let addr1 = t!(sock1.local_addr()); + let addr2 = t!(sock2.local_addr()); let _t = thread::spawn(move || { let mut buf = [0, 0]; @@ -107,9 +107,9 @@ fn udp_clone_smoke() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // no threads fn udp_clone_two_read() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); + each_ip(&mut |sock1, sock2| { + let addr1 = t!(sock1.local_addr()); + let (tx1, rx) = channel(); let tx2 = tx1.clone(); @@ -140,9 +140,8 @@ fn udp_clone_two_read() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // no threads fn udp_clone_two_write() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); + each_ip(&mut |sock1, sock2| { + let addr2 = t!(sock2.local_addr()); let (tx, rx) = channel(); let (serv_tx, serv_rx) = channel(); @@ -177,9 +176,9 @@ fn udp_clone_two_write() { #[test] fn debug() { let name = if cfg!(windows) { "socket" } else { "fd" }; - let socket_addr = next_test_ip4(); - let udpsock = t!(UdpSocket::bind(&socket_addr)); + let udpsock = t!(UdpSocket::bind(LOCALHOST_IP4)); + let socket_addr = t!(udpsock.local_addr()); let udpsock_inner = udpsock.0.socket().as_raw(); let compare = format!("UdpSocket {{ addr: {socket_addr:?}, {name}: {udpsock_inner:?} }}"); assert_eq!(format!("{udpsock:?}"), compare); @@ -195,9 +194,7 @@ fn debug() { #[cfg_attr(target_os = "wasi", ignore)] // timeout not supported #[test] fn timeouts() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); + let stream = t!(UdpSocket::bind(LOCALHOST_IP4)); let dur = Duration::new(15410, 0); assert_eq!(None, t!(stream.read_timeout())); @@ -220,9 +217,7 @@ fn timeouts() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // timeout not supported fn test_read_timeout() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); + let stream = t!(UdpSocket::bind(LOCALHOST_IP4)); t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); let mut buf = [0; 10]; @@ -245,9 +240,8 @@ fn test_read_timeout() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // timeout not supported fn test_read_with_timeout() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); + let stream = t!(UdpSocket::bind(LOCALHOST_IP4)); + let addr = t!(stream.local_addr()); t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); t!(stream.send_to(b"hello world", &addr)); @@ -275,9 +269,7 @@ fn test_read_with_timeout() { // when passed zero Durations #[test] fn test_timeout_zero_duration() { - let addr = next_test_ip4(); - - let socket = t!(UdpSocket::bind(&addr)); + let socket = t!(UdpSocket::bind(LOCALHOST_IP4)); let result = socket.set_write_timeout(Some(Duration::new(0, 0))); let err = result.unwrap_err(); @@ -290,9 +282,8 @@ fn test_timeout_zero_duration() { #[test] fn connect_send_recv() { - let addr = next_test_ip4(); - - let socket = t!(UdpSocket::bind(&addr)); + let socket = t!(UdpSocket::bind(LOCALHOST_IP4)); + let addr = t!(socket.local_addr()); t!(socket.connect(addr)); t!(socket.send(b"hello world")); @@ -305,8 +296,8 @@ fn connect_send_recv() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // peek not supported fn connect_send_peek_recv() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); + each_ip(&mut |socket, _| { + let addr = t!(socket.local_addr()); t!(socket.connect(addr)); t!(socket.send(b"hello world")); @@ -328,8 +319,8 @@ fn connect_send_peek_recv() { #[test] #[cfg_attr(target_os = "wasi", ignore)] // peek_from not supported fn peek_from() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); + each_ip(&mut |socket, _| { + let addr = t!(socket.local_addr()); t!(socket.send_to(b"hello world", &addr)); for _ in 1..3 { @@ -350,9 +341,7 @@ fn peek_from() { fn ttl() { let ttl = 100; - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); + let stream = t!(UdpSocket::bind(LOCALHOST_IP4)); t!(stream.set_ttl(ttl)); assert_eq!(ttl, t!(stream.ttl())); @@ -360,8 +349,8 @@ fn ttl() { #[test] fn set_nonblocking() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); + each_ip(&mut |socket, _| { + let addr = t!(socket.local_addr()); t!(socket.set_nonblocking(true)); t!(socket.set_nonblocking(false)); diff --git a/library/std/src/os/net/linux_ext/tests.rs b/library/std/src/os/net/linux_ext/tests.rs index 0758b426ccc59..02839ee6a2aad 100644 --- a/library/std/src/os/net/linux_ext/tests.rs +++ b/library/std/src/os/net/linux_ext/tests.rs @@ -1,6 +1,6 @@ #[test] fn quickack() { - use crate::net::test::next_test_ip4; + use crate::net::test::LOCALHOST_IP4; use crate::net::{TcpListener, TcpStream}; use crate::os::net::linux_ext::tcp::TcpStreamExt; @@ -13,8 +13,8 @@ fn quickack() { }; } - let addr = next_test_ip4(); - let _listener = t!(TcpListener::bind(&addr)); + let listener = t!(TcpListener::bind(LOCALHOST_IP4)); + let addr = t!(listener.local_addr()); let stream = t!(TcpStream::connect(&("localhost", addr.port()))); @@ -29,7 +29,7 @@ fn quickack() { #[test] #[cfg(target_os = "linux")] fn deferaccept() { - use crate::net::test::next_test_ip4; + use crate::net::test::LOCALHOST_IP4; use crate::net::{TcpListener, TcpStream}; use crate::os::net::linux_ext::tcp::TcpStreamExt; use crate::time::Duration; @@ -43,10 +43,11 @@ fn deferaccept() { }; } - let addr = next_test_ip4(); let one = Duration::from_secs(1u64); let zero = Duration::from_secs(0u64); - let _listener = t!(TcpListener::bind(&addr)); + + let listener = t!(TcpListener::bind(LOCALHOST_IP4)); + let addr = t!(listener.local_addr()); let stream = t!(TcpStream::connect(&("localhost", addr.port()))); stream.set_deferaccept(one).expect("set_deferaccept failed"); assert_eq!(stream.deferaccept().unwrap(), one); diff --git a/library/std/src/sync/mpmc/select.rs b/library/std/src/sync/mpmc/select.rs index 56a83fee2e119..ff537aa686157 100644 --- a/library/std/src/sync/mpmc/select.rs +++ b/library/std/src/sync/mpmc/select.rs @@ -22,7 +22,7 @@ impl Operation { /// and is alive for the entire duration of a blocking operation. #[inline] pub fn hook(r: &mut T) -> Operation { - let val = r as *mut T as usize; + let val = (r as *mut T).addr(); // Make sure that the pointer address doesn't equal the numerical representation of // `Selected::{Waiting, Aborted, Disconnected}`. assert!(val > 2); diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index c743462501922..4f645e16fbb6f 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -25,7 +25,7 @@ impl Default for ZeroToken { impl fmt::Debug for ZeroToken { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&(self.0 as usize), f) + fmt::Debug::fmt(&self.0.addr(), f) } } diff --git a/library/std/src/sys/args/sgx.rs b/library/std/src/sys/args/sgx.rs index 6ff94f5681b6f..9403059e7c607 100644 --- a/library/std/src/sys/args/sgx.rs +++ b/library/std/src/sys/args/sgx.rs @@ -1,4 +1,5 @@ -#![allow(fuzzy_provenance_casts)] // FIXME: this module systematically confuses pointers and integers +// FIXME: this module systematically confuses pointers and integers +#![allow(fuzzy_provenance_casts, lossy_provenance_casts)] use crate::ffi::OsString; use crate::num::NonZero; diff --git a/library/std/src/sys/env/sgx.rs b/library/std/src/sys/env/sgx.rs index 09090ec7cf0dd..0c19fcc848f4d 100644 --- a/library/std/src/sys/env/sgx.rs +++ b/library/std/src/sys/env/sgx.rs @@ -1,4 +1,5 @@ -#![allow(fuzzy_provenance_casts)] // FIXME: this module systematically confuses pointers and integers +// FIXME: this module systematically confuses pointers and integers +#![allow(fuzzy_provenance_casts, lossy_provenance_casts)] pub use super::common::Env; use crate::collections::HashMap; diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index c2694316249a3..f4115ca6124a7 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -151,7 +151,7 @@ unsafe impl UserSafe for [T] { let elem_size = size_of::(); assert_eq!(size % elem_size, 0); let len = size / elem_size; - ptr::slice_from_raw_parts_mut(ptr as _, len) + ptr.cast::().cast_slice(len) } } diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 2b284cc40b94b..7b2c8e5a8024a 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -3,7 +3,8 @@ //! This module contains the facade (aka platform-specific) implementations of //! OS level functionality for Fortanix SGX. #![deny(unsafe_op_in_unsafe_fn)] -#![allow(fuzzy_provenance_casts)] // FIXME: this entire module systematically confuses pointers and integers +// FIXME: this entire module systematically confuses pointers and integers +#![allow(fuzzy_provenance_casts, lossy_provenance_casts)] use crate::io; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 528bc2be2244a..e0c4fa579275a 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -27,11 +27,13 @@ pub struct Command { env: CommandEnv, } -#[derive(Copy, Clone, Debug)] +#[derive(Debug)] pub enum Stdio { Inherit, Null, MakePipe, + #[allow(dead_code)] // This variant exists only for the Debug impl + InheritFile(File), } impl Command { @@ -120,6 +122,7 @@ impl Command { ) } .map(Some), + Stdio::InheritFile(_) => Err(unsupported()?), Stdio::Inherit => Ok(None), } } @@ -135,6 +138,7 @@ impl Command { ) } .map(Some), + Stdio::InheritFile(_) => Err(unsupported()?), Stdio::Inherit => Ok(None), Stdio::MakePipe => unsupported(), } @@ -153,7 +157,7 @@ pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec, Vec } // Setup Stdout - let stdout = command.stdout.unwrap_or(Stdio::MakePipe); + let stdout = command.stdout.take().unwrap_or(Stdio::MakePipe); let stdout = Command::create_pipe(stdout)?; if let Some(con) = stdout { cmd.stdout_init(con) @@ -162,7 +166,7 @@ pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec, Vec }; // Setup Stderr - let stderr = command.stderr.unwrap_or(Stdio::MakePipe); + let stderr = command.stderr.take().unwrap_or(Stdio::MakePipe); let stderr = Command::create_pipe(stderr)?; if let Some(con) = stderr { cmd.stderr_init(con) @@ -171,7 +175,7 @@ pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec, Vec }; // Setup Stdin - let stdin = command.stdin.unwrap_or(Stdio::Null); + let stdin = command.stdin.take().unwrap_or(Stdio::Null); let stdin = Command::create_stdin(stdin)?; if let Some(con) = stdin { cmd.stdin_init(con) @@ -217,25 +221,19 @@ impl From for Stdio { impl From for Stdio { fn from(_: io::Stdout) -> Stdio { - // FIXME: This is wrong. - // Instead, the Stdio we have here should be a unit struct. - panic!("unsupported") + Stdio::Inherit } } impl From for Stdio { fn from(_: io::Stderr) -> Stdio { - // FIXME: This is wrong. - // Instead, the Stdio we have here should be a unit struct. - panic!("unsupported") + Stdio::Inherit } } impl From for Stdio { - fn from(_file: File) -> Stdio { - // FIXME: This is wrong. - // Instead, the Stdio we have here should be a unit struct. - panic!("unsupported") + fn from(file: File) -> Stdio { + Stdio::InheritFile(file) } } @@ -642,7 +640,7 @@ mod uefi_command_internal { } if let Some((ptr, len)) = self.args { - let _ = unsafe { Box::from_raw(crate::ptr::slice_from_raw_parts_mut(ptr, len)) }; + let _ = unsafe { Box::from_raw(ptr.cast_slice(len)) }; } } } diff --git a/library/std/src/sys/thread_local/key/tests.rs b/library/std/src/sys/thread_local/key/tests.rs index c7d2c8e6301ef..5e5243d9835ed 100644 --- a/library/std/src/sys/thread_local/key/tests.rs +++ b/library/std/src/sys/thread_local/key/tests.rs @@ -18,8 +18,8 @@ fn smoke() { assert!(get(k2).is_null()); set(k1, ptr::without_provenance_mut(1)); set(k2, ptr::without_provenance_mut(2)); - assert_eq!(get(k1) as usize, 1); - assert_eq!(get(k2) as usize, 2); + assert_eq!(get(k1).addr(), 1); + assert_eq!(get(k2).addr(), 2); } } diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 4b934c039a36f..78b6f7c35e8db 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -152,11 +152,11 @@ where { let (tx, rx) = channel(); - let x: Box<_> = Box::new(1); - let x_in_parent = (&*x) as *const i32 as usize; + let x: Box = Box::new(1); + let x_in_parent = (&raw const *x).addr(); spawnfn(Box::new(move || { - let x_in_child = (&*x) as *const i32 as usize; + let x_in_child = (&raw const *x).addr(); tx.send(x_in_child).unwrap(); })); diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index c5875e88fd3c4..8b303fe1c87d9 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -36,24 +36,28 @@ + } + } + } -+ scope 13 (inlined slice_from_raw_parts_mut::) { -+ scope 14 (inlined std::ptr::from_raw_parts_mut::<[A], A>) { ++ scope 13 (inlined std::ptr::mut_ptr::::cast_slice) { ++ scope 14 (inlined slice_from_raw_parts_mut::) { ++ scope 15 (inlined std::ptr::from_raw_parts_mut::<[A], A>) { ++ } + } + } -+ scope 15 (inlined drop_in_place::<[A]>) { -+ let mut _13: &mut [A]; -+ scope 16 (inlined std::ptr::drop_glue::<[A]> - shim(Some([A]))) { -+ let mut _14: usize; -+ let mut _15: *mut A; -+ let mut _16: bool; ++ scope 16 (inlined std::ptr::mut_ptr::::drop_in_place) { ++ scope 17 (inlined drop_in_place::<[A]>) { ++ let mut _13: &mut [A]; ++ scope 18 (inlined std::ptr::drop_glue::<[A]> - shim(Some([A]))) { ++ let mut _14: usize; ++ let mut _15: *mut A; ++ let mut _16: bool; ++ } + } + } + } + } + } -+ scope 17 (inlined drop_in_place::>) { ++ scope 19 (inlined drop_in_place::>) { + let mut _17: &mut std::option::Option; -+ scope 18 (inlined std::ptr::drop_glue::> - shim(Some(Option))) { ++ scope 20 (inlined std::ptr::drop_glue::> - shim(Some(Option))) { + let mut _18: isize; + let mut _19: isize; + } diff --git a/tests/ui/derives/debug/derives-span-Debug.stderr b/tests/ui/derives/debug/derives-span-Debug.stderr index e4a2560db4512..0f322e37b05c3 100644 --- a/tests/ui/derives/debug/derives-span-Debug.stderr +++ b/tests/ui/derives/debug/derives-span-Debug.stderr @@ -7,7 +7,6 @@ LL | #[derive(Debug)] LL | x: Error, | ^^^^^^^^ the trait `Debug` is not implemented for `Error` | - = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` help: consider annotating `Error` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -23,7 +22,6 @@ LL | #[derive(Debug)] LL | Error, | ^^^^^ the trait `Debug` is not implemented for `Error` | - = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` help: consider annotating `Error` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -39,7 +37,6 @@ LL | struct Struct { LL | x: Error, | ^^^^^^^^ the trait `Debug` is not implemented for `Error` | - = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` help: consider annotating `Error` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -55,7 +52,6 @@ LL | struct TupleStruct( LL | Error, | ^^^^^ the trait `Debug` is not implemented for `Error` | - = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` help: consider annotating `Error` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/derives/redundant-derive-note-on-unimplemented.rs b/tests/ui/derives/redundant-derive-note-on-unimplemented.rs new file mode 100644 index 0000000000000..f708d3a48359c --- /dev/null +++ b/tests/ui/derives/redundant-derive-note-on-unimplemented.rs @@ -0,0 +1,15 @@ +// Regression test for the redundant `note: add `#[derive(Debug)]` to `X` or manually +// `impl Debug for X`` that was emitted alongside the `consider annotating X with +// `#[derive(Debug)]`` suggestion. When the derive suggestion is shown, the note is +// redundant and should be suppressed. +// +// See https://github.com/rust-lang/rust/issues/157118 + +#[derive(Debug)] +struct S(T); + +struct X; + +fn main() { + println!("{:?}", S(X)); //~ ERROR `X` doesn't implement `Debug` +} diff --git a/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr new file mode 100644 index 0000000000000..dcb1639593a58 --- /dev/null +++ b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr @@ -0,0 +1,31 @@ +error[E0277]: `X` doesn't implement `Debug` + --> $DIR/redundant-derive-note-on-unimplemented.rs:14:22 + | +LL | println!("{:?}", S(X)); + | ---- ^^^^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | | + | required by this formatting parameter + | + = help: the trait `Debug` is not implemented for `X` +help: the trait `Debug` is implemented for `S` + --> $DIR/redundant-derive-note-on-unimplemented.rs:8:10 + | +LL | #[derive(Debug)] + | ^^^^^ +note: required for `S` to implement `Debug` + --> $DIR/redundant-derive-note-on-unimplemented.rs:9:8 + | +LL | #[derive(Debug)] + | ----- in this derive macro expansion +LL | struct S(T); + | ^ - type parameter would need to implement `Debug` + = help: consider manually implementing `Debug` to avoid undesired bounds +help: consider annotating `X` with `#[derive(Debug)]` + | +LL + #[derive(Debug)] +LL | struct X; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/fmt/format-args-argument-span.stderr b/tests/ui/fmt/format-args-argument-span.stderr index a486abe821b74..76fc178bb3d44 100644 --- a/tests/ui/fmt/format-args-argument-span.stderr +++ b/tests/ui/fmt/format-args-argument-span.stderr @@ -25,7 +25,6 @@ LL | println!("{x} {x:?} {x}"); | ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `DisplayOnly` - = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -41,7 +40,6 @@ LL | println!("{x} {x:?} {x}", x = DisplayOnly); | required by this formatting parameter | = help: the trait `Debug` is not implemented for `DisplayOnly` - = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/fmt/non-source-literals.stderr b/tests/ui/fmt/non-source-literals.stderr index 953a4a64fd8dc..39dc35653618f 100644 --- a/tests/ui/fmt/non-source-literals.stderr +++ b/tests/ui/fmt/non-source-literals.stderr @@ -31,7 +31,6 @@ LL | let _ = format!(concat!("{:", "?}"), NonDebug); | ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `NonDebug` - = note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug` help: consider annotating `NonDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -45,7 +44,6 @@ LL | let _ = format!(concat!("{", "0", ":?}"), NonDebug); | ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `NonDebug` - = note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug` help: consider annotating `NonDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr index 23bc9dc0f844e..ce63a69b927c5 100644 --- a/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -4,7 +4,6 @@ error[E0277]: `Foo` doesn't implement `Debug` LL | a.unwrap(); | ^^^^^^ the trait `Debug` is not implemented for `Foo` | - = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` note: required by a bound in `Result::::unwrap` --> $SRC_DIR/core/src/result.rs:LL:COL help: consider annotating `Foo` with `#[derive(Debug)]` diff --git a/tests/ui/modules/issue-107649.stderr b/tests/ui/modules/issue-107649.stderr index 40dda93ad015c..d41fcced9be4a 100644 --- a/tests/ui/modules/issue-107649.stderr +++ b/tests/ui/modules/issue-107649.stderr @@ -4,7 +4,6 @@ error[E0277]: `Dummy` doesn't implement `Debug` 105 | dbg!(lib::Dummy); | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Dummy` | - = note: add `#[derive(Debug)]` to `Dummy` or manually `impl Debug for Dummy` help: consider annotating `Dummy` with `#[derive(Debug)]` --> $DIR/auxiliary/dummy_lib.rs:2:1 | diff --git a/tests/ui/on-unimplemented/no-debug.stderr b/tests/ui/on-unimplemented/no-debug.stderr index 3c3b8d2e20541..c078e0fd42531 100644 --- a/tests/ui/on-unimplemented/no-debug.stderr +++ b/tests/ui/on-unimplemented/no-debug.stderr @@ -7,7 +7,6 @@ LL | println!("{:?} {:?}", Foo, Bar); | required by this formatting parameter | = help: the trait `Debug` is not implemented for `Foo` - = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` help: consider annotating `Foo` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index 4cdeb184bd915..f8699f9e55e24 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -4,7 +4,6 @@ error[E0277]: `NotDebug` doesn't implement `Debug` LL | let _: NotDebug = dbg!(NotDebug); | ^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `NotDebug` | - = note: add `#[derive(Debug)]` to `NotDebug` or manually `impl Debug for NotDebug` help: consider annotating `NotDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/span/issue-71363.stderr b/tests/ui/span/issue-71363.stderr index d2f780bdbcb43..96c45d285e8d0 100644 --- a/tests/ui/span/issue-71363.stderr +++ b/tests/ui/span/issue-71363.stderr @@ -18,7 +18,6 @@ error[E0277]: `MyError` doesn't implement `Debug` 4 | impl std::error::Error for MyError {} | ^^^^^^^ the trait `Debug` is not implemented for `MyError` | - = note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError` note: required by a bound in `std::error::Error` --> $SRC_DIR/core/src/error.rs:LL:COL help: consider annotating `MyError` with `#[derive(Debug)]` diff --git a/tests/ui/suggestions/derive-macro-missing-bounds.stderr b/tests/ui/suggestions/derive-macro-missing-bounds.stderr index b28f39ced542d..0d05bd9d91bbf 100644 --- a/tests/ui/suggestions/derive-macro-missing-bounds.stderr +++ b/tests/ui/suggestions/derive-macro-missing-bounds.stderr @@ -6,7 +6,6 @@ LL | #[derive(Debug)] LL | struct Outer(Inner); | ^^^^^^^^ the trait `Debug` is not implemented for `a::Inner` | - = note: add `#[derive(Debug)]` to `a::Inner` or manually `impl Debug for a::Inner` help: consider annotating `a::Inner` with `#[derive(Debug)]` | LL + #[derive(Debug)]