diff options
| author | bors <bors@rust-lang.org> | 2025-06-17 15:08:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-06-17 15:08:50 +0000 |
| commit | 86d0aef80403f095d8bbabf44d9fdecfcd45f076 (patch) | |
| tree | 5188883db34cd10db6dc7fb22c9d62a801800b1b | |
| parent | 55d436467c351b56253deeba209ae2553d1c243f (diff) | |
| parent | a31e1f12d9c0fa1b8f5d19aa989f0e2236de3bb8 (diff) | |
| download | rust-86d0aef80403f095d8bbabf44d9fdecfcd45f076.tar.gz rust-86d0aef80403f095d8bbabf44d9fdecfcd45f076.zip | |
Auto merge of #137944 - davidtwco:sized-hierarchy, r=oli-obk
Sized Hierarchy: Part I This patch implements the non-const parts of rust-lang/rfcs#3729. It introduces two new traits to the standard library, `MetaSized` and `PointeeSized`. See the RFC for the rationale behind these traits and to discuss whether this change makes sense in the abstract. These traits are unstable (as is their constness), so users cannot refer to them without opting-in to `feature(sized_hierarchy)`. These traits are not behind `cfg`s as this would make implementation unfeasible, there would simply be too many `cfg`s required to add the necessary bounds everywhere. So, like `Sized`, these traits are automatically implemented by the compiler. RFC 3729 describes changes which are necessary to preserve backwards compatibility given the introduction of these traits, which are implemented and as follows: - `?Sized` is rewritten as `MetaSized` - `MetaSized` is added as a default supertrait for all traits w/out an explicit sizedness supertrait already. There are no edition migrations implemented in this, as these are primarily required for the constness parts of the RFC and prior to stabilisation of this (and so will come in follow-up PRs alongside the const parts). All diagnostic output should remain the same (showing `?Sized` even if the compiler sees `MetaSized`) unless the `sized_hierarchy` feature is enabled. Due to the use of unstable extern types in the standard library and rustc, some bounds in both projects have had to be relaxed already - this is unfortunate but unavoidable so that these extern types can continue to be used where they were before. Performing these relaxations in the standard library and rustc are desirable longer-term anyway, but some bounds are not as relaxed as they ideally would be due to the inability to relax `Deref::Target` (this will be investigated separately). It is hoped that this is implemented such that it could be merged and these traits could exist "under the hood" without that being observable to the user (other than in any performance impact this has on the compiler, etc). Some details might leak through due to the standard library relaxations, but this has not been observed in test output. **Notes:** - Any commits starting with "upstream:" can be ignored, as these correspond to other upstream PRs that this is based on which have yet to be merged. - This best reviewed commit-by-commit. I've attempted to make the implementation easy to follow and keep similar changes and test output updates together. - Each commit has a short description describing its purpose. - This patch is large but it's primarily in the test suite. - I've worked on the performance of this patch and a few optimisations are implemented so that the performance impact is neutral-to-minor. - `PointeeSized` is a different name from the RFC just to make it more obvious that it is different from `std::ptr::Pointee` but all the names are yet to be bikeshed anyway. - `@nikomatsakis` has confirmed [that this can proceed as an experiment from the t-lang side](https://rust-lang.zulipchat.com/#narrow/channel/435869-project-goals/topic/SVE.20and.20SME.20on.20AArch64.20.28goals.23270.29/near/506196491) - FCP in https://github.com/rust-lang/rust/pull/137944#issuecomment-2912207485 Fixes rust-lang/rust#79409. r? `@ghost` (I'll discuss this with relevant teams to find a reviewer)
290 files changed, 4167 insertions, 1021 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 012e4dbc3ec..524ebde1c74 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -14,8 +14,14 @@ #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -24,35 +30,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized<T> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn<T> {} // &T -> &U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: MetaSized + Unsize<U>, U: MetaSized> DispatchFromDyn<Box<U>> for Box<T> {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} -impl<T: ?Sized> LegacyReceiver for Box<T> {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} +impl<T: MetaSized> LegacyReceiver for Box<T> {} #[lang = "copy"] pub trait Copy {} @@ -74,9 +80,9 @@ impl Copy for isize {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} impl<T: Copy> Copy for Option<T> {} #[lang = "sync"] @@ -94,17 +100,17 @@ unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} unsafe impl Sync for f32 {} -unsafe impl<'a, T: ?Sized> Sync for &'a T {} +unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl<T: Sync, const N: usize> Sync for [T; N] {} #[lang = "freeze"] unsafe auto trait Freeze {} -unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} -unsafe impl<T: ?Sized> Freeze for *const T {} -unsafe impl<T: ?Sized> Freeze for *mut T {} -unsafe impl<T: ?Sized> Freeze for &T {} -unsafe impl<T: ?Sized> Freeze for &mut T {} +unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {} +unsafe impl<T: PointeeSized> Freeze for *const T {} +unsafe impl<T: PointeeSized> Freeze for *mut T {} +unsafe impl<T: PointeeSized> Freeze for &T {} +unsafe impl<T: PointeeSized> Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -443,7 +449,7 @@ pub enum Option<T> { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: PointeeSized>; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -564,18 +570,18 @@ pub trait Deref { #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull<T: ?Sized>(pub *const T); +pub struct NonNull<T: PointeeSized>(pub *const T); -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -pub struct Unique<T: ?Sized> { +pub struct Unique<T: PointeeSized> { pub pointer: NonNull<T>, pub _marker: PhantomData<T>, } -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} #[lang = "global_alloc_ty"] pub struct Global; diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index aca1f0080ef..9dfb12be243 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -19,8 +19,14 @@ unsafe extern "C" fn _Unwind_Resume() { intrinsics::unreachable(); } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -29,35 +35,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized<T> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn<T> {} // &T -> &U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: MetaSized + Unsize<U>, U: MetaSized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} -impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} +impl<T: MetaSized> LegacyReceiver for Box<T> {} #[lang = "receiver"] trait Receiver {} @@ -84,9 +90,9 @@ impl Copy for i128 {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} #[lang = "sync"] pub unsafe trait Sync {} @@ -102,17 +108,17 @@ unsafe impl Sync for i16 {} unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} -unsafe impl<'a, T: ?Sized> Sync for &'a T {} +unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl Sync for [u8; 16] {} #[lang = "freeze"] unsafe auto trait Freeze {} -unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} -unsafe impl<T: ?Sized> Freeze for *const T {} -unsafe impl<T: ?Sized> Freeze for *mut T {} -unsafe impl<T: ?Sized> Freeze for &T {} -unsafe impl<T: ?Sized> Freeze for &mut T {} +unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {} +unsafe impl<T: PointeeSized> Freeze for *const T {} +unsafe impl<T: PointeeSized> Freeze for *mut T {} +unsafe impl<T: PointeeSized> Freeze for &T {} +unsafe impl<T: PointeeSized> Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -456,7 +462,7 @@ pub enum Option<T> { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: PointeeSized>; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -576,18 +582,18 @@ impl Allocator for Global {} #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull<T: ?Sized>(pub *const T); +pub struct NonNull<T: PointeeSized>(pub *const T); -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -pub struct Unique<T: ?Sized> { +pub struct Unique<T: PointeeSized> { pub pointer: NonNull<T>, pub _marker: PhantomData<T>, } -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} #[lang = "owned_box"] pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A); diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs index a636d09fcae..111740e5509 100644 --- a/compiler/rustc_data_structures/src/aligned.rs +++ b/compiler/rustc_data_structures/src/aligned.rs @@ -1,5 +1,7 @@ use std::ptr::Alignment; +use rustc_serialize::PointeeSized; + /// Returns the ABI-required minimum alignment of a type in bytes. /// /// This is equivalent to [`align_of`], but also works for some unsized @@ -17,7 +19,7 @@ pub const fn align_of<T: ?Sized + Aligned>() -> Alignment { /// example `[T]` has alignment of `T`. /// /// [`align_of::<Self>()`]: align_of -pub unsafe trait Aligned { +pub unsafe trait Aligned: PointeeSized { /// Alignment of `Self`. const ALIGN: Alignment; } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index eb3817a80a7..0431182e9e2 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -12,6 +12,7 @@ #![allow(rustc::potential_query_instability)] #![cfg_attr(bootstrap, feature(cfg_match))] #![cfg_attr(not(bootstrap), feature(cfg_select))] +#![cfg_attr(not(bootstrap), feature(sized_hierarchy))] #![deny(unsafe_op_in_unsafe_fn)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] @@ -43,6 +44,9 @@ use std::fmt; pub use atomic_ref::AtomicRef; pub use ena::{snapshot_vec, undo_log, unify}; pub use rustc_index::static_assert_size; +// re-exported for `rustc_smir` +// FIXME(sized_hierarchy): remove with `cfg(bootstrap)`, see `rustc_serialize/src/lib.rs` +pub use rustc_serialize::PointeeSized; pub mod aligned; pub mod base_n; diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index e0df1b232e1..4846bc997f1 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -1,5 +1,7 @@ use std::alloc::Allocator; +use rustc_serialize::PointeeSized; + #[diagnostic::on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")] // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()` @@ -15,7 +17,7 @@ pub unsafe auto trait DynSend {} pub unsafe auto trait DynSync {} // Same with `Sync` and `Send`. -unsafe impl<T: DynSync + ?Sized> DynSend for &T {} +unsafe impl<T: DynSync + ?Sized + PointeeSized> DynSend for &T {} macro_rules! impls_dyn_send_neg { ($([$t1: ty $(where $($generics1: tt)*)?])*) => { @@ -27,9 +29,9 @@ macro_rules! impls_dyn_send_neg { impls_dyn_send_neg!( [std::env::Args] [std::env::ArgsOs] - [*const T where T: ?Sized] - [*mut T where T: ?Sized] - [std::ptr::NonNull<T> where T: ?Sized] + [*const T where T: ?Sized + PointeeSized] + [*mut T where T: ?Sized + PointeeSized] + [std::ptr::NonNull<T> where T: ?Sized + PointeeSized] [std::rc::Rc<T, A> where T: ?Sized, A: Allocator] [std::rc::Weak<T, A> where T: ?Sized, A: Allocator] [std::sync::MutexGuard<'_, T> where T: ?Sized] @@ -100,12 +102,12 @@ macro_rules! impls_dyn_sync_neg { impls_dyn_sync_neg!( [std::env::Args] [std::env::ArgsOs] - [*const T where T: ?Sized] - [*mut T where T: ?Sized] + [*const T where T: ?Sized + PointeeSized] + [*mut T where T: ?Sized + PointeeSized] [std::cell::Cell<T> where T: ?Sized] [std::cell::RefCell<T> where T: ?Sized] [std::cell::UnsafeCell<T> where T: ?Sized] - [std::ptr::NonNull<T> where T: ?Sized] + [std::ptr::NonNull<T> where T: ?Sized + PointeeSized] [std::rc::Rc<T, A> where T: ?Sized, A: Allocator] [std::rc::Weak<T, A> where T: ?Sized, A: Allocator] [std::cell::OnceCell<T> where T] @@ -175,10 +177,10 @@ impl_dyn_sync!( [thin_vec::ThinVec<T> where T: DynSync] ); -pub fn assert_dyn_sync<T: ?Sized + DynSync>() {} -pub fn assert_dyn_send<T: ?Sized + DynSend>() {} -pub fn assert_dyn_send_val<T: ?Sized + DynSend>(_t: &T) {} -pub fn assert_dyn_send_sync_val<T: ?Sized + DynSync + DynSend>(_t: &T) {} +pub fn assert_dyn_sync<T: ?Sized + PointeeSized + DynSync>() {} +pub fn assert_dyn_send<T: ?Sized + PointeeSized + DynSend>() {} +pub fn assert_dyn_send_val<T: ?Sized + PointeeSized + DynSend>(_t: &T) {} +pub fn assert_dyn_send_sync_val<T: ?Sized + PointeeSized + DynSync + DynSend>(_t: &T) {} #[derive(Copy, Clone)] pub struct FromDyn<T>(T); @@ -231,10 +233,10 @@ impl<T> std::ops::DerefMut for FromDyn<T> { // an instance of `DynSend` and `DynSync`, since the compiler cannot infer // it automatically in some cases. (e.g. Box<dyn Send / Sync>) #[derive(Copy, Clone)] -pub struct IntoDynSyncSend<T: ?Sized>(pub T); +pub struct IntoDynSyncSend<T: ?Sized + PointeeSized>(pub T); -unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {} -unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {} +unsafe impl<T: ?Sized + PointeeSized + Send> DynSend for IntoDynSyncSend<T> {} +unsafe impl<T: ?Sized + PointeeSized + Sync> DynSync for IntoDynSyncSend<T> {} impl<T> std::ops::Deref for IntoDynSyncSend<T> { type Target = T; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index bd6ea850147..5e42b919f9d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -237,6 +237,8 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), + /// Introduces a hierarchy of `Sized` traits (RFC 3729). + (unstable, sized_hierarchy, "CURRENT_RUSTC_VERSION", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Added for testing unstable lints; perma-unstable. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 21d36ed54cd..3a08e5ae336 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -165,6 +165,8 @@ pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> { language_item_table! { // Variant name, Name, Getter method name, Target Generic requirements; Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0); + MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0); + PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0); Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index c5c7e6b2aa7..5b8aa28102c 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -76,6 +76,7 @@ pub use check::{check_abi, check_abi_fn_ptr, check_custom_abi}; use rustc_abi::{ExternAbi, VariantIdx}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err}; +use rustc_hir::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::DenseBitSet; @@ -331,7 +332,7 @@ fn bounds_from_generic_predicates<'tcx>( ty::ClauseKind::Trait(trait_predicate) => { let entry = types.entry(trait_predicate.self_ty()).or_default(); let def_id = trait_predicate.def_id(); - if !tcx.is_default_trait(def_id) { + if !tcx.is_default_trait(def_id) && !tcx.is_lang_item(def_id, LangItem::Sized) { // Do not add that restriction to the list if it is a positive requirement. entry.push(trait_predicate.def_id()); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b8dc01cbc03..20d0e87b7a7 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1258,6 +1258,11 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant debug!(?item.owner_id); let def_id = item.owner_id.def_id; + if tcx.is_lang_item(def_id.into(), LangItem::PointeeSized) { + // `PointeeSized` is removed during lowering. + return Ok(()); + } + let trait_def = tcx.trait_def(def_id); if trait_def.is_marker || matches!(trait_def.specialization_kind, TraitSpecializationKind::Marker) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 5f1cdeddc19..53c44cdc411 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -44,6 +44,14 @@ fn associated_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sizedness_bounds( + &mut bounds, + item_ty, + hir_bounds, + None, + None, + span, + ); icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span); } // `ConstIfConst` is only interested in `~const` bounds. @@ -333,6 +341,14 @@ fn opaque_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sizedness_bounds( + &mut bounds, + item_ty, + hir_bounds, + None, + None, + span, + ); icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span); } //`ConstIfConst` is only interested in `~const` bounds. diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ce0f83d0ec2..c337765c5fe 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -162,7 +162,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen .map(|t| ty::Binder::dummy(t.instantiate_identity())); } } - ItemKind::Trait(_, _, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, _, self_bounds) => { is_trait = Some((self_bounds, item.span)); @@ -183,21 +182,29 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the explicit where-clauses, but to get the full set of predicates // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. - if let Some(self_bounds) = is_trait { + if let Some((self_bounds, span)) = is_trait { let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, - self_bounds.0, + self_bounds, &mut bounds, ty::List::empty(), PredicateFilter::All, ); + icx.lowerer().add_sizedness_bounds( + &mut bounds, + tcx.types.self_param, + self_bounds, + None, + Some(def_id), + span, + ); icx.lowerer().add_default_super_traits( def_id, &mut bounds, - self_bounds.0, + self_bounds, hir_generics, - self_bounds.1, + span, ); predicates.extend(bounds); } @@ -224,6 +231,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let param_ty = icx.lowerer().lower_ty_param(param.hir_id); let mut bounds = Vec::new(); // Implicit bounds are added to type params unless a `?Trait` bound is found + icx.lowerer().add_sizedness_bounds( + &mut bounds, + param_ty, + &[], + Some((param.def_id, hir_generics.predicates)), + None, + param.span, + ); icx.lowerer().add_default_traits( &mut bounds, param_ty, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 106420faa4c..ea1dfdfd806 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -4,15 +4,15 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; -use rustc_hir::AmbigArg; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{AmbigArg, LangItem, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, }; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw}; use rustc_trait_selection::traits; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -23,23 +23,213 @@ use crate::hir_ty_lowering::{ AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason, }; +#[derive(Debug, Default)] +struct CollectedBound { + /// `Trait` + positive: bool, + /// `?Trait` + maybe: bool, + /// `!Trait` + negative: bool, +} + +impl CollectedBound { + /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered. + fn any(&self) -> bool { + self.positive || self.maybe || self.negative + } +} + +#[derive(Debug)] +struct CollectedSizednessBounds { + // Collected `Sized` bounds + sized: CollectedBound, + // Collected `MetaSized` bounds + meta_sized: CollectedBound, + // Collected `PointeeSized` bounds + pointee_sized: CollectedBound, +} + +impl CollectedSizednessBounds { + /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered for `Sized`, + /// `MetaSized` or `PointeeSized`. + fn any(&self) -> bool { + self.sized.any() || self.meta_sized.any() || self.pointee_sized.any() + } +} + +fn search_bounds_for<'tcx>( + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + mut f: impl FnMut(&'tcx PolyTraitRef<'tcx>), +) { + let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| { + for hir_bound in hir_bounds { + let hir::GenericBound::Trait(ptr) = hir_bound else { + continue; + }; + + f(ptr) + } + }; + + search_bounds(hir_bounds); + if let Some((self_ty, where_clause)) = self_ty_where_predicates { + for clause in where_clause { + if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind + && pred.is_param_bound(self_ty.to_def_id()) + { + search_bounds(pred.bounds); + } + } + } +} + +fn collect_unbounds<'tcx>( + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, +) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> { + let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); + search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| { + if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) { + unbounds.push(ptr); + } + }); + unbounds +} + +fn collect_bounds<'a, 'tcx>( + hir_bounds: &'a [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + target_did: DefId, +) -> CollectedBound { + let mut collect_into = CollectedBound::default(); + search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| { + if !matches!(ptr.trait_ref.path.res, Res::Def(DefKind::Trait, did) if did == target_did) { + return; + } + + match ptr.modifiers.polarity { + hir::BoundPolarity::Maybe(_) => collect_into.maybe = true, + hir::BoundPolarity::Negative(_) => collect_into.negative = true, + hir::BoundPolarity::Positive => collect_into.positive = true, + } + }); + collect_into +} + +fn collect_sizedness_bounds<'tcx>( + tcx: TyCtxt<'tcx>, + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + span: Span, +) -> CollectedSizednessBounds { + let sized_did = tcx.require_lang_item(LangItem::Sized, span); + let sized = collect_bounds(hir_bounds, self_ty_where_predicates, sized_did); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span); + let meta_sized = collect_bounds(hir_bounds, self_ty_where_predicates, meta_sized_did); + + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span); + let pointee_sized = collect_bounds(hir_bounds, self_ty_where_predicates, pointee_sized_did); + + CollectedSizednessBounds { sized, meta_sized, pointee_sized } +} + +/// Add a trait bound for `did`. +fn add_trait_bound<'tcx>( + tcx: TyCtxt<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, + self_ty: Ty<'tcx>, + did: DefId, + span: Span, +) { + let trait_ref = ty::TraitRef::new(tcx, did, [self_ty]); + // Preferable to put sizedness obligations first, since we report better errors for `Sized` + // ambiguity. + bounds.insert(0, (trait_ref.upcast(tcx), span)); +} + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { - pub(crate) fn add_default_traits( + /// Skip `PointeeSized` bounds. + /// + /// `PointeeSized` is a "fake bound" insofar as anywhere a `PointeeSized` bound exists, there + /// is actually the absence of any bounds. This avoids limitations around non-global where + /// clauses being preferred over item bounds (where `PointeeSized` bounds would be + /// proven) - which can result in errors when a `PointeeSized` supertrait/bound/predicate is + /// added to some items. + pub(crate) fn should_skip_sizedness_bound<'hir>( + &self, + bound: &'hir hir::GenericBound<'tcx>, + ) -> bool { + bound + .trait_ref() + .and_then(|tr| tr.trait_def_id()) + .map(|did| self.tcx().is_lang_item(did, LangItem::PointeeSized)) + .unwrap_or(false) + } + + /// Adds sizedness bounds to a trait, trait alias, parameter, opaque type or associated type. + /// + /// - On parameters, opaque type and associated types, add default `Sized` bound if no explicit + /// sizedness bounds are present. + /// - On traits and trait aliases, add default `MetaSized` supertrait if no explicit sizedness + /// bounds are present. + /// - On parameters, opaque type, associated types and trait aliases, add a `MetaSized` bound if + /// a `?Sized` bound is present. + pub(crate) fn add_sizedness_bounds( &self, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, - hir_bounds: &[hir::GenericBound<'tcx>], + hir_bounds: &'tcx [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + trait_did: Option<LocalDefId>, span: Span, ) { - self.add_default_traits_with_filter( - bounds, - self_ty, - hir_bounds, - self_ty_where_predicates, - span, - |_| true, - ); + let tcx = self.tcx(); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span); + + // If adding sizedness bounds to a trait, then there are some relevant early exits + if let Some(trait_did) = trait_did { + let trait_did = trait_did.to_def_id(); + // Never add a default supertrait to `PointeeSized`. + if trait_did == pointee_sized_did { + return; + } + // Don't add default sizedness supertraits to auto traits because it isn't possible to + // relax an automatically added supertrait on the defn itself. + if tcx.trait_is_auto(trait_did) { + return; + } + } else { + // Report invalid unbounds on sizedness-bounded generic parameters. + let unbounds = collect_unbounds(hir_bounds, self_ty_where_predicates); + self.check_and_report_invalid_unbounds_on_param(unbounds); + } + + let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span); + if (collected.sized.maybe || collected.sized.negative) + && !collected.sized.positive + && !collected.meta_sized.any() + && !collected.pointee_sized.any() + { + // `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any + // other explicit ones) - this can happen for trait aliases as well as bounds. + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + } else if !collected.any() { + if trait_did.is_some() { + // If there are no explicit sizedness bounds on a trait then add a default + // `MetaSized` supertrait. + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + } else { + // If there are no explicit sizedness bounds on a parameter then add a default + // `Sized` bound. + let sized_did = tcx.require_lang_item(LangItem::Sized, span); + add_trait_bound(tcx, bounds, self_ty, sized_did, span); + } + } } /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds @@ -146,13 +336,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if !self.requires_default_supertraits(trait_bounds, trait_generics) { let self_ty_where_predicates = (parent, trait_item.generics.predicates); - self.add_default_traits_with_filter( + self.add_default_traits( bounds, tcx.types.self_param, &[], Some(self_ty_where_predicates), trait_item.span, - |tr| tr != hir::LangItem::Sized, ); } } @@ -174,41 +363,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias)); if self.requires_default_supertraits(hir_bounds, hir_generics) { let self_ty_where_predicates = (trait_def_id, hir_generics.predicates); - self.add_default_traits_with_filter( + self.add_default_traits( bounds, self.tcx().types.self_param, hir_bounds, Some(self_ty_where_predicates), span, - |default_trait| default_trait != hir::LangItem::Sized, ); } } - pub(crate) fn add_default_traits_with_filter( + pub(crate) fn add_default_traits( &self, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &[hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, - f: impl Fn(hir::LangItem) -> bool, ) { - self.tcx().default_traits().iter().filter(|&&default_trait| f(default_trait)).for_each( - |default_trait| { - self.add_default_trait( - *default_trait, - bounds, - self_ty, - hir_bounds, - self_ty_where_predicates, - span, - ); - }, - ); + self.tcx().default_traits().iter().for_each(|default_trait| { + self.add_default_trait( + *default_trait, + bounds, + self_ty, + hir_bounds, + self_ty_where_predicates, + span, + ); + }); } - /// Add a `Sized` or `experimental_default_bounds` bounds to the `bounds` if appropriate. + /// Add a `experimental_default_bounds` bound to the `bounds` if appropriate. /// /// Doesn't add the bound if the HIR bounds contain any of `Trait`, `?Trait` or `!Trait`. pub(crate) fn add_default_trait( @@ -220,7 +405,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, ) { - let trait_id = self.tcx().lang_items().get(trait_); + let tcx = self.tcx(); + let trait_id = tcx.lang_items().get(trait_); if let Some(trait_id) = trait_id && self.do_not_provide_default_trait_bound( trait_id, @@ -228,11 +414,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty_where_predicates, ) { - // There was no `?Trait` or `!Trait` bound; - // add `Trait` if it's available. - let trait_ref = ty::TraitRef::new(self.tcx(), trait_id, [self_ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - bounds.insert(0, (trait_ref.upcast(self.tcx()), span)); + add_trait_bound(tcx, bounds, self_ty, trait_id, span); } } @@ -242,90 +424,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_bounds: &'a [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, ) -> bool { - let tcx = self.tcx(); - let mut seen_negative_bound = false; - let mut seen_positive_bound = false; - - // Try to find an unbound in bounds. - let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); - let mut search_bounds = |hir_bounds: &'a [hir::GenericBound<'tcx>]| { - for hir_bound in hir_bounds { - let hir::GenericBound::Trait(ptr) = hir_bound else { - continue; - }; - match ptr.modifiers.polarity { - hir::BoundPolarity::Maybe(_) => unbounds.push(ptr), - hir::BoundPolarity::Negative(_) => { - if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) { - seen_negative_bound = true; - } - } - hir::BoundPolarity::Positive => { - if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) { - seen_positive_bound = true; - } - } - } - } - }; - search_bounds(hir_bounds); - if let Some((self_ty, where_clause)) = self_ty_where_predicates { - for clause in where_clause { - if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind - && pred.is_param_bound(self_ty.to_def_id()) - { - search_bounds(pred.bounds); - } - } - } - - let mut unique_bounds = FxIndexSet::default(); - let mut seen_repeat = false; - for unbound in &unbounds { - if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res { - seen_repeat |= !unique_bounds.insert(unbound_def_id); - } - } - if unbounds.len() > 1 { - let err = errors::MultipleRelaxedDefaultBounds { - spans: unbounds.iter().map(|ptr| ptr.span).collect(), - }; - if seen_repeat { - self.dcx().emit_err(err); - } else if !tcx.features().more_maybe_bounds() { - self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit(); - }; - } - - let mut seen_unbound = false; - for unbound in unbounds { - let unbound_def_id = unbound.trait_ref.trait_def_id(); - if unbound_def_id == Some(trait_def_id) { - seen_unbound = true; - } - let emit_relax_err = || { - let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds { - true => "`?Sized` and `experimental_default_bounds`", - false => "`?Sized`", - }; - // There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`. - self.dcx().span_err( - unbound.span, - format!( - "relaxing a default bound only does something for {}; \ - all other traits are not bound by default", - unbound_traits - ), - ); - }; - match unbound_def_id { - Some(def_id) if !tcx.is_default_trait(def_id) => emit_relax_err(), - None => emit_relax_err(), - _ => {} - } - } - - !(seen_unbound || seen_negative_bound || seen_positive_bound) + let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id); + !collected.any() } /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any. @@ -361,6 +461,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 'tcx: 'hir, { for hir_bound in hir_bounds { + if self.should_skip_sizedness_bound(hir_bound) { + continue; + } + // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`, // we skip over any traits that don't define the given associated type. if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index c7cdf1d5bd2..05465b47a26 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -61,14 +61,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ast_bounds: Vec<_> = hir_bounds.iter().map(|&trait_ref| hir::GenericBound::Trait(trait_ref)).collect(); - self.add_default_traits_with_filter( - &mut user_written_bounds, - dummy_self, - &ast_bounds, - None, - span, - |tr| tr != hir::LangItem::Sized, - ); + self.add_default_traits(&mut user_written_bounds, dummy_self, &ast_bounds, None, span); let (elaborated_trait_bounds, elaborated_projection_bounds) = traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 45fee0fa402..1cda6dff21e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -8,7 +8,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, HirId}; +use rustc_hir::{self as hir, HirId, LangItem, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::fast_reject::{TreatParams, simplify_type}; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -34,6 +34,57 @@ use crate::fluent_generated as fluent; use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer}; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { + /// Check for multiple relaxed default bounds and relaxed bounds of non-sizedness traits. + pub(crate) fn check_and_report_invalid_unbounds_on_param( + &self, + unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>, + ) { + let tcx = self.tcx(); + + let sized_did = tcx.require_lang_item(LangItem::Sized, DUMMY_SP); + + let mut unique_bounds = FxIndexSet::default(); + let mut seen_repeat = false; + for unbound in &unbounds { + if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res { + seen_repeat |= !unique_bounds.insert(unbound_def_id); + } + } + + if unbounds.len() > 1 { + let err = errors::MultipleRelaxedDefaultBounds { + spans: unbounds.iter().map(|ptr| ptr.span).collect(), + }; + + if seen_repeat { + tcx.dcx().emit_err(err); + } else if !tcx.features().more_maybe_bounds() { + tcx.sess.create_feature_err(err, sym::more_maybe_bounds).emit(); + }; + } + + for unbound in unbounds { + if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res + && ((did == sized_did) || tcx.is_default_trait(did)) + { + continue; + } + + let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds { + true => "`?Sized` and `experimental_default_bounds`", + false => "`?Sized`", + }; + self.dcx().span_err( + unbound.span, + format!( + "relaxing a default bound only does something for {}; all other traits are \ + not bound by default", + unbound_traits + ), + ); + } + } + /// On missing type parameters, emit an E0393 error and provide a structured suggestion using /// the type parameter's name as a placeholder. pub(crate) fn report_missing_type_params( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index a43449a8f99..2df19cb21d5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -22,8 +22,9 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferResult}; use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, Ty, TyCtxt, - TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, UserSelfTy, + self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, + UserSelfTy, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -439,7 +440,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || {}, ); // Sized types have static alignment, and so do slices. - if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) { + if tail.has_trivial_sizedness(self.tcx, SizedTraitKind::Sized) + || matches!(tail.kind(), ty::Slice(..)) + { // Nothing else is required here. } else { // We can't be sure, let's required full `Sized`. diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index dea7c8ac708..3cc55eaa0f2 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -46,7 +46,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .tcx .explicit_super_predicates_of(def_id) .iter_identity_copied() - .filter_map(|(pred, _)| pred.as_trait_clause()); + .filter_map(|(pred, _)| pred.as_trait_clause()) + .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized)); if direct_super_traits_iter.count() > 1 { cx.emit_span_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 667361b3ca0..6cb1d8c5fc4 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -28,6 +28,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(not(bootstrap), feature(sized_hierarchy))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 9ed1f10455a..4d914c42cfc 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -328,6 +328,14 @@ impl Key for (DefId, SimplifiedType) { } } +impl Key for (DefId, ty::SizedTraitKind) { + type Cache<V> = DefaultCache<Self, V>; + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for GenericArgsRef<'tcx> { type Cache<V> = DefaultCache<Self, V>; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 63312eff490..930d9fba433 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -137,8 +137,8 @@ use crate::ty::layout::ValidityRequirement; use crate::ty::print::{PrintTraitRefExt, describe_as_module}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{ - self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt, - TyCtxtFeed, + self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, SizedTraitKind, Ty, + TyCtxt, TyCtxtFeed, }; use crate::{dep_graph, mir, thir}; @@ -910,9 +910,10 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - - query adt_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { - desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) } + query adt_sizedness_constraint( + key: (DefId, SizedTraitKind) + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } } query adt_dtorck_constraint( diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index d92b4f9c06b..6d5a3abf665 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -229,8 +229,12 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> { ) } - fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { - self.sized_constraint(tcx) + fn sizedness_constraint( + self, + tcx: TyCtxt<'tcx>, + sizedness: ty::SizedTraitKind, + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + self.sizedness_constraint(tcx, sizedness) } fn is_fundamental(self) -> bool { @@ -634,10 +638,15 @@ impl<'tcx> AdtDef<'tcx> { tcx.adt_async_destructor(self.did()) } - /// Returns a type such that `Self: Sized` if and only if that type is `Sized`, - /// or `None` if the type is always sized. - pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { - if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None } + /// If this ADT is a struct, returns a type such that `Self: {Meta,Pointee,}Sized` if and only + /// if that type is `{Meta,Pointee,}Sized`, or `None` if this ADT is always + /// `{Meta,Pointee,}Sized`. + pub fn sizedness_constraint( + self, + tcx: TyCtxt<'tcx>, + sizedness: ty::SizedTraitKind, + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + if self.is_struct() { tcx.adt_sizedness_constraint((self.did(), sizedness)) } else { None } } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index e0f70737add..3d7965f6cfe 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -13,7 +13,7 @@ use std::marker::DiscriminantKind; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::LocalDefId; -use rustc_serialize::{Decodable, Encodable}; +use rustc_serialize::{Decodable, Encodable, PointeeSized}; use rustc_span::source_map::Spanned; use rustc_span::{Span, SpanDecoder, SpanEncoder}; @@ -96,7 +96,7 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate /// /// `Decodable` can still be implemented in cases where `Decodable` is required /// by a trait bound. -pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> { +pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized { fn decode(d: &mut D) -> &'tcx Self; } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fe4dd8d080b..f1395c242f2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -43,6 +43,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::cache::WithDepNode; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; +use rustc_serialize::PointeeSized; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; @@ -774,7 +775,9 @@ bidirectional_lang_item_map! { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, @@ -1616,16 +1619,17 @@ impl<'tcx> TyCtxt<'tcx> { self.reserve_and_set_memory_dedup(alloc, salt) } + /// Traits added on all bounds by default, excluding `Sized` which is treated separately. pub fn default_traits(self) -> &'static [rustc_hir::LangItem] { - match self.sess.opts.unstable_opts.experimental_default_bounds { - true => &[ - LangItem::Sized, + if self.sess.opts.unstable_opts.experimental_default_bounds { + &[ LangItem::DefaultTrait1, LangItem::DefaultTrait2, LangItem::DefaultTrait3, LangItem::DefaultTrait4, - ], - false => &[LangItem::Sized], + ] + } else { + &[] } } @@ -2538,17 +2542,17 @@ impl<'tcx> TyCtxt<'tcx> { // this type just holds a pointer to it, but it still effectively owns it. It // impls `Borrow` so that it can be looked up using the original // (non-arena-memory-owning) types. -struct InternedInSet<'tcx, T: ?Sized>(&'tcx T); +struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T); -impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> { fn clone(&self) -> Self { InternedInSet(self.0) } } -impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {} +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {} -impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> { fn into_pointer(&self) -> *const () { self.0 as *const _ as *const () } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0402d098822..97408e31854 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -60,6 +60,7 @@ pub use rustc_type_ir::fast_reject::DeepRejectCtxt; )] use rustc_type_ir::inherent; pub use rustc_type_ir::relate::VarianceDiagInfo; +pub use rustc_type_ir::solve::SizedTraitKind; pub use rustc_type_ir::*; #[allow(hidden_glob_reexports, unused_imports)] use rustc_type_ir::{InferCtxtLike, Interner}; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 673a89a8134..c10277c75a7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1069,24 +1069,35 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); + let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_sized_bound = false; let mut has_negative_sized_bound = false; - let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_meta_sized_bound = false; for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => { - // Don't print `+ Sized`, but rather `+ ?Sized` if absent. - if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { - match pred.polarity { + // With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for + // `MetaSized`, and skip sizedness bounds to be added at the end. + match tcx.as_lang_item(pred.def_id()) { + Some(LangItem::Sized) => match pred.polarity { ty::PredicatePolarity::Positive => { has_sized_bound = true; continue; } ty::PredicatePolarity::Negative => has_negative_sized_bound = true, + }, + Some(LangItem::MetaSized) => { + has_meta_sized_bound = true; + continue; + } + Some(LangItem::PointeeSized) => { + bug!("`PointeeSized` is removed during lowering"); } + _ => (), } self.insert_trait_and_projection( @@ -1255,8 +1266,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { })?; } + let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); let add_sized = has_sized_bound && (first || has_negative_sized_bound); - let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound; + let add_maybe_sized = + has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy; + // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. + let has_pointee_sized_bound = + !has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound; if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; @@ -1265,6 +1281,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { write!(self, "?")?; } write!(self, "Sized")?; + } else if has_meta_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "MetaSized")?; + } else if has_pointee_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "PointeeSized")?; } if !with_forced_trimmed_paths() { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index cbf545c01c5..58829f72a72 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -15,6 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension}; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, TypeVisitableExt, elaborate}; use tracing::instrument; @@ -1677,7 +1678,7 @@ impl<'tcx> Ty<'tcx> { let Some(pointee_ty) = self.builtin_deref(true) else { bug!("Type {self:?} is not a pointer or reference type") }; - if pointee_ty.is_trivially_sized(tcx) { + if pointee_ty.has_trivial_sizedness(tcx, SizedTraitKind::Sized) { tcx.types.unit } else { match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) { @@ -1778,17 +1779,17 @@ impl<'tcx> Ty<'tcx> { } } - /// Fast path helper for testing if a type is `Sized`. + /// Fast path helper for testing if a type is `Sized` or `MetaSized`. /// - /// Returning true means the type is known to implement `Sized`. Returning `false` means - /// nothing -- could be sized, might not be. + /// Returning true means the type is known to implement the sizedness trait. Returning `false` + /// means nothing -- could be sized, might not be. /// /// Note that we could never rely on the fact that a type such as `[_]` is trivially `!Sized` /// because we could be in a type environment with a bound such as `[_]: Copy`. A function with /// such a bound obviously never can be called, but that doesn't mean it shouldn't typecheck. /// This is why this method doesn't return `Option<bool>`. #[instrument(skip(tcx), level = "debug")] - pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { + pub fn has_trivial_sizedness(self, tcx: TyCtxt<'tcx>, sizedness: SizedTraitKind) -> bool { match self.kind() { ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) @@ -1811,13 +1812,20 @@ impl<'tcx> Ty<'tcx> { | ty::Error(_) | ty::Dynamic(_, _, ty::DynStar) => true, - ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false, + ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { + SizedTraitKind::Sized => false, + SizedTraitKind::MetaSized => true, + }, + + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => false, + }, - ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.is_trivially_sized(tcx)), + ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)), ty::Adt(def, args) => def - .sized_constraint(tcx) - .is_none_or(|ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)), + .sizedness_constraint(tcx, sizedness) + .is_none_or(|ty| ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)), ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 461d92f8006..51f57e71ce9 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -16,6 +16,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension}; use rustc_session::Limit; use rustc_span::sym; +use rustc_type_ir::solve::SizedTraitKind; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -1132,7 +1133,8 @@ impl<'tcx> Ty<'tcx> { /// strange rules like `<T as Foo<'static>>::Bar: Sized` that /// actually carry lifetime requirements. pub fn is_sized(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { - self.is_trivially_sized(tcx) || tcx.is_sized_raw(typing_env.as_query_input(self)) + self.has_trivial_sizedness(tcx, SizedTraitKind::Sized) + || tcx.is_sized_raw(typing_env.as_query_input(self)) } /// Checks whether values of this type `T` implement the `Freeze` diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 0c267feefbe..a300558c0c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -8,6 +8,7 @@ use std::ops::ControlFlow; use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor, TypingMode, Upcast as _, elaborate, @@ -203,13 +204,15 @@ where goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution>; - /// A type is `Sized` if its tail component is `Sized`. + /// A type is `Sized` if its tail component is `Sized` and a type is `MetaSized` if its tail + /// component is `MetaSized`. /// /// These components are given by built-in rules from - /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. - fn consider_builtin_sized_candidate( + /// [`structural_traits::instantiate_constituent_tys_for_sizedness_trait`]. + fn consider_builtin_sizedness_candidates( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution>; /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. @@ -466,7 +469,15 @@ where G::consider_trait_alias_candidate(self, goal) } else { match cx.as_lang_item(trait_def_id) { - Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal), + Some(TraitSolverLangItem::Sized) => { + G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::Sized) + } + Some(TraitSolverLangItem::MetaSized) => { + G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::MetaSized) + } + Some(TraitSolverLangItem::PointeeSized) => { + unreachable!("`PointeeSized` is removed during lowering"); + } Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 4a2a7761f7f..f39d3226009 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -5,6 +5,7 @@ use derive_where::derive_where; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{ self as ty, FallibleTypeFolder, Interner, Movability, Mutability, TypeFoldable, @@ -104,8 +105,9 @@ where } #[instrument(level = "trace", skip(ecx), ret)] -pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<D, I>( +pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait<D, I>( ecx: &EvalCtxt<'_, D>, + sizedness: SizedTraitKind, ty: I::Ty, ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution> where @@ -113,8 +115,9 @@ where I: Interner, { match ty.kind() { - // impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, ! - // impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure + // impl {Meta,}Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char + // impl {Meta,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine, CoroutineWitness + // impl {Meta,}Sized for Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) | ty::Int(_) @@ -135,13 +138,16 @@ where | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), - ty::Str - | ty::Slice(_) - | ty::Dynamic(..) - | ty::Foreign(..) - | ty::Alias(..) - | ty::Param(_) - | ty::Placeholder(..) => Err(NoSolution), + // impl {Meta,}Sized for str, [T], dyn Trait + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => Err(NoSolution), + SizedTraitKind::MetaSized => Ok(ty::Binder::dummy(vec![])), + }, + + // impl {} for extern type + ty::Foreign(..) => Err(NoSolution), + + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => Err(NoSolution), ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { @@ -150,22 +156,27 @@ where ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), - // impl Sized for () - // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 + // impl {Meta,}Sized for () + // impl {Meta,}Sized for (T1, T2, .., Tn) where Tn: {Meta,}Sized if n >= 1 ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))), - // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized - // `sized_constraint(Adt)` is the deepest struct trail that can be determined - // by the definition of `Adt`, independent of the generic args. - // impl Sized for Adt<Args...> if sized_constraint(Adt) == None - // As a performance optimization, `sized_constraint(Adt)` can return `None` - // if the ADTs definition implies that it is sized by for all possible args. + // impl {Meta,}Sized for Adt<Args...> + // where {meta,pointee,}sized_constraint(Adt)<Args...>: {Meta,}Sized + // + // `{meta,pointee,}sized_constraint(Adt)` is the deepest struct trail that can be + // determined by the definition of `Adt`, independent of the generic args. + // + // impl {Meta,}Sized for Adt<Args...> + // if {meta,pointee,}sized_constraint(Adt) == None + // + // As a performance optimization, `{meta,pointee,}sized_constraint(Adt)` can return `None` + // if the ADTs definition implies that it is {meta,}sized by for all possible args. // In this case, the builtin impl will have no nested subgoals. This is a - // "best effort" optimization and `sized_constraint` may return `Some`, even - // if the ADT is sized for all possible args. + // "best effort" optimization and `{meta,pointee,}sized_constraint` may return `Some`, + // even if the ADT is {meta,pointee,}sized for all possible args. ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(ecx.cx()) { - Ok(ty::Binder::dummy(vec![sized_crit.instantiate(ecx.cx(), args)])) + if let Some(crit) = def.sizedness_constraint(ecx.cx(), sizedness) { + Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)])) } else { Ok(ty::Binder::dummy(vec![])) } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 8413c2abbb9..1690c908d12 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -4,6 +4,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{self as ty, Interner, elaborate}; use tracing::instrument; @@ -198,11 +199,12 @@ where unreachable!("trait aliases are never const") } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal<I, Self>, + _sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { - unreachable!("Sized is never const") + unreachable!("Sized/MetaSized is never const") } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 2fddc0044cb..d51c87fe68e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,6 +6,7 @@ mod opaque_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{self as ty, Interner, NormalizesTo, PredicateKind, Upcast as _}; use tracing::instrument; @@ -413,11 +414,12 @@ where panic!("trait aliases do not have associated types: {:?}", goal); } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( _ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + _sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { - panic!("`Sized` does not have an associated type: {:?}", goal); + panic!("`Sized`/`MetaSized` does not have an associated type: {:?}", goal); } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 110c67a8e21..8ee116b090d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -4,9 +4,9 @@ use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::solve::CanonicalResponse; +use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind}; use rustc_type_ir::{ - self as ty, Interner, Movability, TraitPredicate, TypeVisitableExt as _, TypingMode, + self as ty, Interner, Movability, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, }; use tracing::{debug, instrument, trace}; @@ -131,9 +131,11 @@ where assumption: I::Clause, ) -> Result<(), NoSolution> { if let Some(trait_clause) = assumption.as_trait_clause() { - if trait_clause.def_id() == goal.predicate.def_id() - && trait_clause.polarity() == goal.predicate.polarity - { + if trait_clause.polarity() != goal.predicate.polarity { + return Err(NoSolution); + } + + if trait_clause.def_id() == goal.predicate.def_id() { if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, trait_clause.skip_binder().trait_ref.args, @@ -141,6 +143,17 @@ where return Ok(()); } } + + // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so + // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds + // are syntactic sugar for a lack of bounds so don't need this. + if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized) + { + let meta_sized_clause = + trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id()); + return Self::fast_reject_assumption(ecx, goal, meta_sized_clause); + } } Err(NoSolution) @@ -154,6 +167,17 @@ where ) -> QueryResult<I> { let trait_clause = assumption.as_trait_clause().unwrap(); + // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so + // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds + // are syntactic sugar for a lack of bounds so don't need this. + if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized) + { + let meta_sized_clause = + trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id()); + return Self::match_assumption(ecx, goal, meta_sized_clause, then); + } + let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?; @@ -245,9 +269,10 @@ where }) } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); @@ -256,7 +281,11 @@ where ecx.probe_and_evaluate_goal_for_constituent_tys( CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial), goal, - structural_traits::instantiate_constituent_tys_for_sized_trait, + |ecx, ty| { + structural_traits::instantiate_constituent_tys_for_sizedness_trait( + ecx, sizedness, ty, + ) + }, ) } @@ -812,6 +841,25 @@ where } } +/// Small helper function to change the `def_id` of a trait predicate - this is not normally +/// something that you want to do, as different traits will require different args and so making +/// it easy to change the trait is something of a footgun, but it is useful in the narrow +/// circumstance of changing from `MetaSized` to `Sized`, which happens as part of the lazy +/// elaboration of sizedness candidates. +#[inline(always)] +fn trait_predicate_with_def_id<I: Interner>( + cx: I, + clause: ty::Binder<I, ty::TraitPredicate<I>>, + did: I::DefId, +) -> I::Clause { + clause + .map_bound(|c| TraitPredicate { + trait_ref: TraitRef::new_from_args(cx, did, c.trait_ref.args), + polarity: c.polarity, + }) + .upcast(cx) +} + impl<D, I> EvalCtxt<'_, D> where D: SolverDelegate<Interner = I>, diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 34be35e36ac..656ecfcab36 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::internal)] +#![cfg_attr(not(bootstrap), feature(sized_hierarchy))] #![cfg_attr(test, feature(test))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", @@ -27,3 +28,19 @@ mod serialize; pub mod int_overflow; pub mod leb128; pub mod opaque; + +// This has nothing to do with `rustc_serialize` but it is convenient to define it in one place +// for the rest of the compiler so that `cfg(bootstrap)` doesn't need to be littered throughout +// the compiler wherever `PointeeSized` would be used. `rustc_serialize` happens to be the deepest +// crate in the crate graph which uses `PointeeSized`. +// +// When bootstrap bumps, remove both the `cfg(not(bootstrap))` and `cfg(bootstrap)` lines below +// and just import `std::marker::PointeeSized` whereever this item was used. + +#[cfg(not(bootstrap))] +pub use std::marker::PointeeSized; + +#[cfg(bootstrap)] +pub trait PointeeSized {} +#[cfg(bootstrap)] +impl<T: ?Sized> PointeeSized for T {} diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 1eefd76f92b..8940d10696d 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -142,7 +142,7 @@ pub trait Decoder { /// `rustc_metadata::rmeta::Lazy`. /// * `TyEncodable` should be used for types that are only serialized in crate /// metadata or the incremental cache. This is most types in `rustc_middle`. -pub trait Encodable<S: Encoder> { +pub trait Encodable<S: Encoder>: crate::PointeeSized { fn encode(&self, s: &mut S); } @@ -198,7 +198,7 @@ direct_serialize_impls! { char emit_char read_char } -impl<S: Encoder, T: ?Sized> Encodable<S> for &T +impl<S: Encoder, T: ?Sized + crate::PointeeSized> Encodable<S> for &T where T: Encodable<S>, { diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 771ff98d58d..63623cfad72 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -9,6 +9,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] +#![cfg_attr(not(bootstrap), feature(sized_hierarchy))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index b5003baaf63..64fe181c26d 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,6 +9,7 @@ use std::ops::RangeInclusive; +use rustc_data_structures::PointeeSized; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; @@ -158,7 +159,7 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { } /// Trait used to convert between an internal MIR type to a Stable MIR type. -pub trait Stable<'cx> { +pub trait Stable<'cx>: PointeeSized { /// The stable representation of the type implementing Stable. type T; /// Converts an object to the equivalent Stable MIR representation. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cb9ccf4cc3f..baadff16120 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1355,6 +1355,7 @@ symbols! { memtag, message, meta, + meta_sized, metadata_type, min_const_fn, min_const_generics, @@ -1613,6 +1614,7 @@ symbols! { plugin_registrar, plugins, pointee, + pointee_sized, pointee_trait, pointer, pointer_like, @@ -2016,6 +2018,7 @@ symbols! { size_of, size_of_val, sized, + sized_hierarchy, skip, slice, slice_from_raw_parts, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 275b580d794..39f115ce0cd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -199,7 +199,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. - if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) { + if matches!( + self.tcx.as_lang_item(trait_pred.def_id()), + Some(LangItem::Sized | LangItem::MetaSized) + ) { match self.tainted_by_errors() { None => { let err = self.emit_inference_failure_err( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 78f9287b407..d4cc1ceb280 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, AmbigArg, LangItem}; +use rustc_hir::{self as hir, AmbigArg}; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{ DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode, @@ -160,17 +160,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .collect(); - // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics - // with more relevant type information and hide redundant E0282 errors. - errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) - if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => - { - 1 + // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last. + // This lets us display diagnostics with more relevant type information and hide redundant + // E0282 errors. + errors.sort_by_key(|e| { + let maybe_sizedness_did = match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred.def_id()), + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => Some(pred.def_id()), + _ => None, + }; + + match e.obligation.predicate.kind().skip_binder() { + _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => 1, + _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => 2, + _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => 3, + ty::PredicateKind::Coerce(_) => 4, + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 5, + _ => 0, } - ty::PredicateKind::Coerce(_) => 2, - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, - _ => 0, }); for (index, error) in errors.iter().enumerate() { @@ -327,19 +334,26 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); let mut w = "impl".to_owned(); - let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); + #[derive(Debug, Default)] + struct SizednessFound { + sized: bool, + meta_sized: bool, + } - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxIndexSet::default(); - let sized_trait = tcx.lang_items().sized_trait(); + let mut types_with_sizedness_bounds = FxIndexMap::<_, SizednessFound>::default(); + + let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::<Vec<_>>(); if !arg_names.is_empty() { - types_without_default_bounds.extend(args.types()); w.push('<'); w.push_str(&arg_names.join(", ")); w.push('>'); + + for ty in args.types() { + // `PointeeSized` params might have no predicates. + types_with_sizedness_bounds.insert(ty, SizednessFound::default()); + } } write!( @@ -351,24 +365,47 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti ) .unwrap(); - // The predicates will contain default bounds like `T: Sized`. We need to - // remove these bounds, and add `T: ?Sized` to any untouched type parameters. let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = - Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); + let mut pretty_predicates = Vec::with_capacity(predicates.len()); + + let sized_trait = tcx.lang_items().sized_trait(); + let meta_sized_trait = tcx.lang_items().meta_sized_trait(); for (p, _) in predicates { - if let Some(poly_trait_ref) = p.as_trait_clause() { - if Some(poly_trait_ref.def_id()) == sized_trait { - // FIXME(#120456) - is `swap_remove` correct? - types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); + // Accumulate the sizedness bounds for each self ty. + if let Some(trait_clause) = p.as_trait_clause() { + let self_ty = trait_clause.self_ty().skip_binder(); + let sizedness_of = types_with_sizedness_bounds.entry(self_ty).or_default(); + if Some(trait_clause.def_id()) == sized_trait { + sizedness_of.sized = true; + continue; + } else if Some(trait_clause.def_id()) == meta_sized_trait { + sizedness_of.meta_sized = true; continue; } } + pretty_predicates.push(p.to_string()); } - pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); + for (ty, sizedness) in types_with_sizedness_bounds { + if !tcx.features().sized_hierarchy() { + if sizedness.sized { + // Maybe a default bound, don't write anything. + } else { + pretty_predicates.push(format!("{ty}: ?Sized")); + } + } else { + if sizedness.sized { + // Maybe a default bound, don't write anything. + pretty_predicates.push(format!("{ty}: Sized")); + } else if sizedness.meta_sized { + pretty_predicates.push(format!("{ty}: MetaSized")); + } else { + pretty_predicates.push(format!("{ty}: PointeeSized")); + } + } + } if !pretty_predicates.is_empty() { write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); @@ -519,7 +556,7 @@ fn attempt_dyn_to_enum_suggestion( let Some(impl_type) = tcx.type_of(*impl_id).no_bound_vars() else { return None }; // Obviously unsized impl types won't be usable in an enum. - // Note: this doesn't use `Ty::is_trivially_sized` because that function + // Note: this doesn't use `Ty::has_trivial_sizedness` because that function // defaults to assuming that things are *not* sized, whereas we want to // fall back to assuming that things may be sized. match impl_type.kind() { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 69a0c0809b5..b247c2c2968 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -12,7 +12,7 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::Certainty; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode, + self, SizedTraitKind, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode, }; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; @@ -79,7 +79,14 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< Some(LangItem::Sized) if self .resolve_vars_if_possible(trait_pred.self_ty().skip_binder()) - .is_trivially_sized(self.0.tcx) => + .has_trivial_sizedness(self.0.tcx, SizedTraitKind::Sized) => + { + return Some(Certainty::Yes); + } + Some(LangItem::MetaSized) + if self + .resolve_vars_if_possible(trait_pred.self_ty().skip_binder()) + .has_trivial_sizedness(self.0.tcx, SizedTraitKind::MetaSized) => { return Some(Certainty::Yes); } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 93c7dae9c5b..81893cdcc7e 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -462,6 +462,7 @@ fn impl_intersection_has_negative_obligation( let param_env = infcx.resolve_vars_if_possible(param_env); util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args)) + .elaborate_sized() .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env)) } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 47d207e8d41..ee30956295a 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -7,15 +7,15 @@ use std::ops::ControlFlow; use rustc_errors::FatalError; -use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast, elaborate, }; -use rustc_span::Span; +use rustc_span::{DUMMY_SP, Span}; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -543,11 +543,11 @@ fn receiver_for_self_ty<'tcx>( /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in /// a new check that `Trait` is dyn-compatible, creating a cycle. /// Instead, we emulate a placeholder by introducing a new type parameter `U` such that -/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. +/// `Self: Unsize<U>` and `U: Trait + MetaSized`, and use `U` in place of `dyn Trait`. /// /// Written as a chalk-style query: /// ```ignore (not-rust) -/// forall (U: Trait + ?Sized) { +/// forall (U: Trait + MetaSized) { /// if (Self: Unsize<U>) { /// Receiver: DispatchFromDyn<Receiver[Self => U]> /// } @@ -567,9 +567,10 @@ fn receiver_is_dispatchable<'tcx>( ) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); - let traits = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()); - let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else { - debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits"); + let (Some(unsize_did), Some(dispatch_from_dyn_did)) = + (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()) + else { + debug!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits"); return false; }; @@ -583,7 +584,7 @@ fn receiver_is_dispatchable<'tcx>( receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id); // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of - // its supertraits) added to caller bounds. `U: ?Sized` is already implied here. + // its supertraits) added to caller bounds. `U: MetaSized` is already implied here. let param_env = { // N.B. We generally want to emulate the construction of the `unnormalized_param_env` // in the param-env query here. The fact that we don't just start with the clauses @@ -612,6 +613,12 @@ fn receiver_is_dispatchable<'tcx>( let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args); predicates.push(trait_predicate.upcast(tcx)); + let meta_sized_predicate = { + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, DUMMY_SP); + ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty]).upcast(tcx) + }; + predicates.push(meta_sized_predicate); + normalize_param_env_or_error( tcx, ty::ParamEnv::new(tcx.mk_clauses(&predicates)), diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 97ecf9702e6..81ce58a93fa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind}; use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate}; +use rustc_middle::ty::{self, SizedTraitKind, Ty, TypeVisitableExt, TypingMode, elaborate}; use rustc_middle::{bug, span_bug}; use tracing::{debug, instrument, trace}; @@ -87,7 +87,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.vec.push(BuiltinCandidate { has_nested: false }); } Some(LangItem::Sized) => { - self.assemble_builtin_sized_candidate(obligation, &mut candidates); + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::Sized, + ); + } + Some(LangItem::MetaSized) => { + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::MetaSized, + ); + } + Some(LangItem::PointeeSized) => { + bug!("`PointeeSized` is removed during lowering"); } Some(LangItem::Unsize) => { self.assemble_candidates_for_unsizing(obligation, &mut candidates); @@ -201,6 +215,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } selcx.infcx.probe(|_| { + let bound = util::lazily_elaborate_sizedness_candidate( + selcx.infcx, + obligation, + bound, + ); + // We checked the polarity already match selcx.match_normalize_trait_ref( obligation, @@ -245,14 +265,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .caller_bounds() .iter() .filter_map(|p| p.as_trait_clause()) - // Micro-optimization: filter out predicates relating to different traits. - .filter(|p| p.def_id() == stack.obligation.predicate.def_id()) + // Micro-optimization: filter out predicates with different polarities. .filter(|p| p.polarity() == stack.obligation.predicate.polarity()); let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx()); let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args; // Keep only those bounds which may apply, and propagate overflow if it occurs. for bound in bounds { + let bound = + util::lazily_elaborate_sizedness_candidate(self.infcx, stack.obligation, bound); + + // Micro-optimization: filter out predicates relating to different traits. + if bound.def_id() != stack.obligation.predicate.def_id() { + continue; + } + let bound_trait_ref = bound.map_bound(|t| t.trait_ref); if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) { continue; @@ -1086,15 +1113,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - /// Assembles the trait which are built-in to the language itself: - /// `Copy`, `Clone` and `Sized`. + /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself. #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_sized_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, + sizedness: SizedTraitKind, ) { - match self.sized_conditions(obligation) { + match self.sizedness_conditions(obligation, sizedness) { BuiltinImplConditions::Where(nested) => { candidates .vec diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 786afd7cf48..80f71c78993 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -14,7 +14,9 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, Upcast, elaborate}; +use rustc_middle::ty::{ + self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate, +}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use thin_vec::thin_vec; @@ -164,10 +166,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) .break_value() .expect("expected to index into clause that exists"); - let candidate = candidate_predicate + let candidate_predicate = candidate_predicate .as_trait_clause() - .expect("projection candidate is not a trait predicate") - .map_bound(|t| t.trait_ref); + .expect("projection candidate is not a trait predicate"); + let candidate_predicate = + util::lazily_elaborate_sizedness_candidate(self.infcx, obligation, candidate_predicate); + + let candidate = candidate_predicate.map_bound(|t| t.trait_ref); let candidate = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, @@ -224,6 +229,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> PredicateObligations<'tcx> { debug!(?obligation, ?param, "confirm_param_candidate"); + let param = util::lazily_elaborate_sizedness_candidate( + self.infcx, + obligation, + param.upcast(self.infcx.tcx), + ) + .map_bound(|p| p.trait_ref); + // During evaluation, we already checked that this // where-clause trait-ref could be unified with the obligation // trait-ref. Repeat that unification now without any @@ -251,7 +263,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let obligations = if has_nested { let trait_def = obligation.predicate.def_id(); let conditions = match tcx.as_lang_item(trait_def) { - Some(LangItem::Sized) => self.sized_conditions(obligation), + Some(LangItem::Sized) => { + self.sizedness_conditions(obligation, SizedTraitKind::Sized) + } + Some(LangItem::MetaSized) => { + self.sizedness_conditions(obligation, SizedTraitKind::MetaSized) + } + Some(LangItem::PointeeSized) => { + bug!("`PointeeSized` is removing during lowering"); + } Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation), Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation), other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1b9b68fa980..9c0ccb26e53 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, - TypeVisitableExt, TypingMode, Upcast, elaborate, + self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt, + TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate, }; use rustc_span::{Symbol, sym}; use tracing::{debug, instrument, trace}; @@ -2094,9 +2094,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } impl<'tcx> SelectionContext<'_, 'tcx> { - fn sized_conditions( + fn sizedness_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, + sizedness: SizedTraitKind, ) -> BuiltinImplConditions<'tcx> { use self::BuiltinImplConditions::{Ambiguous, None, Where}; @@ -2126,7 +2127,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Where(ty::Binder::dummy(Vec::new())) } - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => None, + SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())), + }, + + ty::Foreign(..) => None, ty::Tuple(tys) => Where( obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), @@ -2135,11 +2141,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(self.tcx()) { + if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) { // (*) binder moved here - Where( - obligation.predicate.rebind(vec![sized_crit.instantiate(self.tcx(), args)]), - ) + Where(obligation.predicate.rebind(vec![crit.instantiate(self.tcx(), args)])) } else { Where(ty::Binder::dummy(Vec::new())) } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 0723aebd5d2..a05bae53566 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -4,10 +4,13 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::PolyTraitObligation; pub use rustc_infer::traits::util::*; use rustc_middle::bug; +use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, PolyTraitPredicate, SizedTraitKind, TraitPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; pub use rustc_next_trait_solver::placeholder::BoundVarReplacer; use rustc_span::Span; @@ -362,15 +365,19 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { } pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>) -> bool { - // Proving `Sized` very often on "obviously sized" types like `&T`, accounts for about 60% - // percentage of the predicates we have to prove. No need to canonicalize and all that for - // such cases. + // Proving `Sized`/`MetaSized`, very often on "obviously sized" types like + // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to + // canonicalize and all that for such cases. if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = predicate.kind().skip_binder() { - if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) - && trait_ref.self_ty().is_trivially_sized(tcx) - { + let sizedness = match tcx.as_lang_item(trait_ref.def_id()) { + Some(LangItem::Sized) => SizedTraitKind::Sized, + Some(LangItem::MetaSized) => SizedTraitKind::MetaSized, + _ => return false, + }; + + if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) { debug!("fast path -- trivial sizedness"); return true; } @@ -378,3 +385,39 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc false } + +/// To improve performance, sizedness traits are not elaborated and so special-casing is required +/// in the trait solver to find a `Sized` candidate for a `MetaSized` obligation. Returns the +/// predicate to used in the candidate for such a `obligation`, given a `candidate`. +pub(crate) fn lazily_elaborate_sizedness_candidate<'tcx>( + infcx: &InferCtxt<'tcx>, + obligation: &PolyTraitObligation<'tcx>, + candidate: PolyTraitPredicate<'tcx>, +) -> PolyTraitPredicate<'tcx> { + if !infcx.tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized) + || !infcx.tcx.is_lang_item(candidate.def_id(), LangItem::Sized) + { + return candidate; + } + + if obligation.predicate.polarity() != candidate.polarity() { + return candidate; + } + + let drcx = DeepRejectCtxt::relate_rigid_rigid(infcx.tcx); + if !drcx.args_may_unify( + obligation.predicate.skip_binder().trait_ref.args, + candidate.skip_binder().trait_ref.args, + ) { + return candidate; + } + + candidate.map_bound(|c| TraitPredicate { + trait_ref: TraitRef::new_from_args( + infcx.tcx, + obligation.predicate.def_id(), + c.trait_ref.args, + ), + polarity: c.polarity, + }) +} diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 416865e861e..d4e6a23f0eb 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -567,6 +567,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { def_id: DefId, args: GenericArgsRef<'tcx>, ) -> PredicateObligations<'tcx> { + // PERF: `Sized`'s predicates include `MetaSized`, but both are compiler implemented marker + // traits, so `MetaSized` will always be WF if `Sized` is WF and vice-versa. Determining + // the nominal obligations of `Sized` would in-effect just elaborate `MetaSized` and make + // the compiler do a bunch of work needlessly. + if self.tcx().is_lang_item(def_id, LangItem::Sized) { + return Default::default(); + } + let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 11becea998c..d996ee2b60a 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -1,23 +1,29 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions, + self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, + fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_trait_selection::traits; use tracing::instrument; +/// If `ty` implements the given `sizedness` trait, returns `None`. Otherwise, returns the type +/// that must implement the given `sizedness` for `ty` to implement it. #[instrument(level = "debug", skip(tcx), ret)] -fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { +fn sizedness_constraint_for_ty<'tcx>( + tcx: TyCtxt<'tcx>, + sizedness: SizedTraitKind, + ty: Ty<'tcx>, +) -> Option<Ty<'tcx>> { match ty.kind() { - // these are always sized + // Always `Sized` or `MetaSized` ty::Bool | ty::Char | ty::Int(..) @@ -35,31 +41,40 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<' | ty::Never | ty::Dynamic(_, _, ty::DynStar) => None, - // these are never sized - ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => Some(ty), - - ty::Pat(ty, _) => sized_constraint_for_ty(tcx, *ty), - - ty::Tuple(tys) => tys.last().and_then(|&ty| sized_constraint_for_ty(tcx, ty)), - - // recursive case - ty::Adt(adt, args) => adt.sized_constraint(tcx).and_then(|intermediate| { - let ty = intermediate.instantiate(tcx, args); - sized_constraint_for_ty(tcx, ty) - }), + ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { + // Never `Sized` + SizedTraitKind::Sized => Some(ty), + // Always `MetaSized` + SizedTraitKind::MetaSized => None, + }, - // these can be sized or unsized. + // Maybe `Sized` or `MetaSized` ty::Param(..) | ty::Alias(..) | ty::Error(_) => Some(ty), // We cannot instantiate the binder, so just return the *original* type back, // but only if the inner type has a sized constraint. Thus we skip the binder, // but don't actually use the result from `sized_constraint_for_ty`. ty::UnsafeBinder(inner_ty) => { - sized_constraint_for_ty(tcx, inner_ty.skip_binder()).map(|_| ty) + sizedness_constraint_for_ty(tcx, sizedness, inner_ty.skip_binder()).map(|_| ty) + } + + // Never `MetaSized` or `Sized` + ty::Foreign(..) => Some(ty), + + // Recursive cases + ty::Pat(ty, _) => sizedness_constraint_for_ty(tcx, sizedness, *ty), + + ty::Tuple(tys) => { + tys.last().and_then(|&ty| sizedness_constraint_for_ty(tcx, sizedness, ty)) } + ty::Adt(adt, args) => adt.sizedness_constraint(tcx, sizedness).and_then(|intermediate| { + let ty = intermediate.instantiate(tcx, args); + sizedness_constraint_for_ty(tcx, sizedness, ty) + }), + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { - bug!("unexpected type `{ty:?}` in sized_constraint_for_ty") + bug!("unexpected type `{ty:?}` in `sizedness_constraint_for_ty`") } } } @@ -75,15 +90,22 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { } } -/// Calculates the `Sized` constraint. +/// Returns the type of the last field of a struct ("the constraint") which must implement the +/// `sizedness` trait for the whole ADT to be considered to implement that `sizedness` trait. +/// `def_id` is assumed to be the `AdtDef` of a struct and will panic otherwise. +/// +/// For `Sized`, there are only a few options for the types in the constraint: +/// - an meta-sized type (str, slices, trait objects, etc) +/// - an pointee-sized type (extern types) +/// - a type parameter or projection whose sizedness can't be known /// -/// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type +/// For `MetaSized`, there are only a few options for the types in the constraint: +/// - an pointee-sized type (extern types) /// - a type parameter or projection whose sizedness can't be known #[instrument(level = "debug", skip(tcx), ret)] -fn adt_sized_constraint<'tcx>( +fn adt_sizedness_constraint<'tcx>( tcx: TyCtxt<'tcx>, - def_id: DefId, + (def_id, sizedness): (DefId, SizedTraitKind), ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { if let Some(def_id) = def_id.as_local() { if let ty::Representability::Infinite(_) = tcx.representability(def_id) { @@ -93,21 +115,21 @@ fn adt_sized_constraint<'tcx>( let def = tcx.adt_def(def_id); if !def.is_struct() { - bug!("`adt_sized_constraint` called on non-struct type: {def:?}"); + bug!("`adt_sizedness_constraint` called on non-struct type: {def:?}"); } let tail_def = def.non_enum_variant().tail_opt()?; let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); - let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; + let constraint_ty = sizedness_constraint_for_ty(tcx, sizedness, tail_ty)?; - // perf hack: if there is a `constraint_ty: Sized` bound, then we know + // perf hack: if there is a `constraint_ty: {Meta,}Sized` bound, then we know // that the type is sized and do not need to check it on the impl. - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP); + let sizedness_trait_def_id = sizedness.require_lang_item(tcx); let predicates = tcx.predicates_of(def.did()).predicates; if predicates.iter().any(|(p, _)| { p.as_trait_clause().is_some_and(|trait_pred| { - trait_pred.def_id() == sized_trait_def_id + trait_pred.def_id() == sizedness_trait_def_id && trait_pred.self_ty().skip_binder() == constraint_ty }) }) { @@ -369,7 +391,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { asyncness, - adt_sized_constraint, + adt_sizedness_constraint, param_env, typing_env_normalized_for_post_analysis, defaultness, diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index b11bcff1d8b..852949d707b 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -4,6 +4,7 @@ use smallvec::smallvec; use crate::data_structures::HashSet; use crate::inherent::*; +use crate::lang_items::TraitSolverLangItem; use crate::outlives::{Component, push_outlives_components}; use crate::{self as ty, Interner, Upcast as _}; @@ -18,6 +19,7 @@ pub struct Elaborator<I: Interner, O> { stack: Vec<O>, visited: HashSet<ty::Binder<I, ty::PredicateKind<I>>>, mode: Filter, + elaborate_sized: ElaborateSized, } enum Filter { @@ -25,6 +27,12 @@ enum Filter { OnlySelf, } +#[derive(Eq, PartialEq)] +enum ElaborateSized { + Yes, + No, +} + /// Describes how to elaborate an obligation into a sub-obligation. pub trait Elaboratable<I: Interner> { fn predicate(&self) -> I::Predicate; @@ -77,13 +85,19 @@ pub fn elaborate<I: Interner, O: Elaboratable<I>>( cx: I, obligations: impl IntoIterator<Item = O>, ) -> Elaborator<I, O> { - let mut elaborator = - Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All }; + let mut elaborator = Elaborator { + cx, + stack: Vec::new(), + visited: HashSet::default(), + mode: Filter::All, + elaborate_sized: ElaborateSized::No, + }; elaborator.extend_deduped(obligations); elaborator } impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { + /// Adds `obligations` to the stack. fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) { // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some @@ -103,6 +117,13 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { self } + /// Start elaborating `Sized` - reqd during coherence checking, normally skipped to improve + /// compiler performance. + pub fn elaborate_sized(mut self) -> Self { + self.elaborate_sized = ElaborateSized::Yes; + self + } + fn elaborate(&mut self, elaboratable: &O) { let cx = self.cx; @@ -111,6 +132,19 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { return; }; + // PERF(sized-hierarchy): To avoid iterating over sizedness supertraits in + // parameter environments, as an optimisation, sizedness supertraits aren't + // elaborated, so check if a `Sized` obligation is being elaborated to a + // `MetaSized` obligation and emit it. Candidate assembly and confirmation + // are modified to check for the `Sized` subtrait when a `MetaSized` obligation + // is present. + if self.elaborate_sized == ElaborateSized::No + && let Some(did) = clause.as_trait_clause().map(|c| c.def_id()) + && self.cx.is_lang_item(did, TraitSolverLangItem::Sized) + { + return; + } + let bound_clause = clause.kind(); match bound_clause.skip_binder() { ty::ClauseKind::Trait(data) => { diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 436ab9f80b6..608efc7515c 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability; use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; -use crate::solve::AdtDestructorKind; +use crate::solve::{AdtDestructorKind, SizedTraitKind}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; @@ -571,7 +571,11 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq { // FIXME: perhaps use `all_fields` and expose `FieldDef`. fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>; - fn sized_constraint(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>; + fn sizedness_constraint( + self, + interner: I, + sizedness: SizedTraitKind, + ) -> Option<ty::EarlyBinder<I, I::Ty>>; fn is_fundamental(self) -> bool; diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 699dd82fb22..3ee6e07b7a5 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -30,7 +30,9 @@ pub enum TraitSolverLangItem { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index ba777c7c59a..bbbeaa29f84 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -8,6 +8,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use crate::lang_items::TraitSolverLangItem; use crate::search_graph::PathKind; use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; @@ -366,3 +367,24 @@ pub enum AdtDestructorKind { NotConst, Const, } + +/// Which sizedness trait - `Sized`, `MetaSized`? `PointeeSized` is omitted as it is removed during +/// lowering. +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub enum SizedTraitKind { + /// `Sized` trait + Sized, + /// `MetaSized` trait + MetaSized, +} + +impl SizedTraitKind { + /// Returns `DefId` of corresponding language item. + pub fn require_lang_item<I: Interner>(self, cx: I) -> I::DefId { + cx.require_lang_item(match self { + SizedTraitKind::Sized => TraitSolverLangItem::Sized, + SizedTraitKind::MetaSized => TraitSolverLangItem::MetaSized, + }) + } +} diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 2c0662c9629..57de507a73e 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,6 +36,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::marker::PointeeSized; + mod uninit; /// A common trait that allows explicit creation of a duplicate value. @@ -283,7 +285,7 @@ impl_use_cloned! { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsClone<T: Clone + ?Sized> { +pub struct AssertParamIsClone<T: Clone + PointeeSized> { _field: crate::marker::PhantomData<T>, } #[doc(hidden)] @@ -293,7 +295,7 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsCopy<T: Copy + ?Sized> { +pub struct AssertParamIsCopy<T: Copy + PointeeSized> { _field: crate::marker::PhantomData<T>, } @@ -530,6 +532,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr { /// are implemented in `traits::SelectionContext::copy_clone_conditions()` /// in `rustc_trait_selection`. mod impls { + use crate::marker::PointeeSized; + macro_rules! impl_clone { ($($t:ty)*) => { $( @@ -560,7 +564,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for *const T { + impl<T: PointeeSized> Clone for *const T { #[inline(always)] fn clone(&self) -> Self { *self @@ -568,7 +572,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for *mut T { + impl<T: PointeeSized> Clone for *mut T { #[inline(always)] fn clone(&self) -> Self { *self @@ -577,7 +581,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for &T { + impl<T: PointeeSized> Clone for &T { #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { @@ -587,5 +591,5 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> !Clone for &mut T {} + impl<T: PointeeSized> !Clone for &mut T {} } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index c315131f413..5cb1a148477 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,6 +29,7 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; use self::Ordering::*; +use crate::marker::PointeeSized; use crate::ops::ControlFlow; /// Trait for comparisons using the equality operator. @@ -246,7 +247,7 @@ use crate::ops::ControlFlow; append_const_msg )] #[rustc_diagnostic_item = "PartialEq"] -pub trait PartialEq<Rhs: ?Sized = Self> { +pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized { /// Tests for `self` and `other` values to be equal, and is used by `==`. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -332,7 +333,7 @@ pub macro PartialEq($item:item) { #[doc(alias = "!=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Eq"] -pub trait Eq: PartialEq<Self> { +pub trait Eq: PartialEq<Self> + PointeeSized { // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a // type implements `Eq` itself. The current deriving infrastructure means doing this assertion // without using a method on this trait is nearly impossible. @@ -361,7 +362,7 @@ pub macro Eq($item:item) { #[doc(hidden)] #[allow(missing_debug_implementations)] #[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")] -pub struct AssertParamIsEq<T: Eq + ?Sized> { +pub struct AssertParamIsEq<T: Eq + PointeeSized> { _field: crate::marker::PhantomData<T>, } @@ -954,7 +955,7 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -pub trait Ord: Eq + PartialOrd<Self> { +pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression @@ -1337,7 +1338,8 @@ pub macro Ord($item:item) { append_const_msg )] #[rustc_diagnostic_item = "PartialOrd"] -pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { +#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized { /// This method returns an ordering between `self` and `other` values if one exists. /// /// # Examples @@ -1481,7 +1483,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { } } -fn default_chaining_impl<T: ?Sized, U: ?Sized>( +fn default_chaining_impl<T: PointeeSized, U: PointeeSized>( lhs: &T, rhs: &U, p: impl FnOnce(Ordering) -> bool, @@ -1803,6 +1805,7 @@ where mod impls { use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::hint::unreachable_unchecked; + use crate::marker::PointeeSized; use crate::ops::ControlFlow::{self, Break, Continue}; macro_rules! partial_eq_impl { @@ -2015,7 +2018,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A + impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &A where A: PartialEq<B>, { @@ -2029,7 +2032,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A + impl<A: PointeeSized, B: PointeeSized> PartialOrd<&B> for &A where A: PartialOrd<B>, { @@ -2071,7 +2074,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Ord for &A + impl<A: PointeeSized> Ord for &A where A: Ord, { @@ -2081,12 +2084,12 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Eq for &A where A: Eq {} + impl<A: PointeeSized> Eq for &A where A: Eq {} // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A + impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &mut A where A: PartialEq<B>, { @@ -2100,7 +2103,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A + impl<A: PointeeSized, B: PointeeSized> PartialOrd<&mut B> for &mut A where A: PartialOrd<B>, { @@ -2142,7 +2145,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Ord for &mut A + impl<A: PointeeSized> Ord for &mut A where A: Ord, { @@ -2152,10 +2155,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Eq for &mut A where A: Eq {} + impl<A: PointeeSized> Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A + impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &A where A: PartialEq<B>, { @@ -2170,7 +2173,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A + impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &mut A where A: PartialEq<B>, { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index d86dc24fb57..7132e712ec5 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -38,6 +38,7 @@ use crate::error::Error; use crate::fmt; use crate::hash::{Hash, Hasher}; +use crate::marker::PointeeSized; mod num; @@ -215,7 +216,7 @@ pub const fn identity<T>(x: T) -> T { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AsRef"] -pub trait AsRef<T: ?Sized> { +pub trait AsRef<T: PointeeSized>: PointeeSized { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_ref(&self) -> &T; @@ -366,7 +367,7 @@ pub trait AsRef<T: ?Sized> { /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AsMut"] -pub trait AsMut<T: ?Sized> { +pub trait AsMut<T: PointeeSized>: PointeeSized { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_mut(&mut self) -> &mut T; @@ -701,7 +702,7 @@ pub trait TryFrom<T>: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsRef<U> for &T +impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &T where T: AsRef<U>, { @@ -713,7 +714,7 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T +impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &mut T where T: AsRef<U>, { @@ -733,7 +734,7 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T +impl<T: PointeeSized, U: PointeeSized> AsMut<U> for &mut T where T: AsMut<U>, { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 145e581d1fb..c20b3d4817f 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -4,7 +4,7 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell}; use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; -use crate::marker::PhantomData; +use crate::marker::{PhantomData, PointeeSized}; use crate::num::fmt as numfmt; use crate::ops::Deref; use crate::{iter, result, str}; @@ -864,7 +864,7 @@ impl Display for Arguments<'_> { #[doc(alias = "{:?}")] #[rustc_diagnostic_item = "Debug"] #[rustc_trivial_field_reads] -pub trait Debug { +pub trait Debug: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples @@ -995,7 +995,7 @@ pub use macros::Debug; #[doc(alias = "{}")] #[rustc_diagnostic_item = "Display"] #[stable(feature = "rust1", since = "1.0.0")] -pub trait Display { +pub trait Display: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples @@ -1071,7 +1071,7 @@ pub trait Display { /// assert_eq!(format!("l as octal is: {l:#06o}"), "l as octal is: 0o0011"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait Octal { +pub trait Octal: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1130,7 +1130,7 @@ pub trait Octal { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait Binary { +pub trait Binary: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1185,7 +1185,7 @@ pub trait Binary { /// assert_eq!(format!("l as hex is: {l:#010x}"), "l as hex is: 0x00000009"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait LowerHex { +pub trait LowerHex: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1240,7 +1240,7 @@ pub trait LowerHex { /// assert_eq!(format!("l as hex is: {l:#010X}"), "l as hex is: 0x7FFFFFFF"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait UpperHex { +pub trait UpperHex: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1299,7 +1299,7 @@ pub trait UpperHex { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Pointer"] -pub trait Pointer { +pub trait Pointer: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1350,7 +1350,7 @@ pub trait Pointer { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait LowerExp { +pub trait LowerExp: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1401,7 +1401,7 @@ pub trait LowerExp { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait UpperExp { +pub trait UpperExp: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -2646,11 +2646,11 @@ macro_rules! fmt_refs { ($($tr:ident),*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + $tr> $tr for &T { + impl<T: PointeeSized + $tr> $tr for &T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + $tr> $tr for &mut T { + impl<T: PointeeSized + $tr> $tr for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } )* @@ -2772,7 +2772,7 @@ impl Display for char { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for *const T { +impl<T: PointeeSized> Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { if <<T as core::ptr::Pointee>::Metadata as core::unit::IsUnit>::is_unit() { pointer_fmt_inner(self.expose_provenance(), f) @@ -2817,21 +2817,21 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for *mut T { +impl<T: PointeeSized> Pointer for *mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(*self as *const T), f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for &T { +impl<T: PointeeSized> Pointer for &T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(*self as *const T), f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for &mut T { +impl<T: PointeeSized> Pointer for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(&**self as *const T), f) } @@ -2840,13 +2840,13 @@ impl<T: ?Sized> Pointer for &mut T { // Implementation of Display/Debug for various core types #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Debug for *const T { +impl<T: PointeeSized> Debug for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Debug for *mut T { +impl<T: PointeeSized> Debug for *mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) } diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index f7b874b26bb..efda64791d4 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -183,7 +183,7 @@ mod sip; /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Hash"] -pub trait Hash { +pub trait Hash: marker::PointeeSized { /// Feeds this value into the given [`Hasher`]. /// /// # Examples @@ -941,7 +941,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + Hash> Hash for &T { + impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); @@ -949,7 +949,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + Hash> Hash for &mut T { + impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &mut T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); @@ -957,7 +957,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Hash for *const T { + impl<T: ?Sized + marker::PointeeSized> Hash for *const T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); @@ -967,7 +967,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Hash for *mut T { + impl<T: ?Sized + marker::PointeeSized> Hash for *mut T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); diff --git a/library/core/src/intrinsics/bounds.rs b/library/core/src/intrinsics/bounds.rs index 046e191212c..353908598d4 100644 --- a/library/core/src/intrinsics/bounds.rs +++ b/library/core/src/intrinsics/bounds.rs @@ -1,39 +1,41 @@ //! Various traits used to restrict intrinsics to not-completely-wrong types. +use crate::marker::PointeeSized; + /// Types with a built-in dereference operator in runtime MIR, /// aka references and raw pointers. /// /// # Safety /// Must actually *be* such a type. pub unsafe trait BuiltinDeref: Sized { - type Pointee: ?Sized; + type Pointee: PointeeSized; } -unsafe impl<T: ?Sized> BuiltinDeref for &mut T { +unsafe impl<T: PointeeSized> BuiltinDeref for &mut T { type Pointee = T; } -unsafe impl<T: ?Sized> BuiltinDeref for &T { +unsafe impl<T: PointeeSized> BuiltinDeref for &T { type Pointee = T; } -unsafe impl<T: ?Sized> BuiltinDeref for *mut T { +unsafe impl<T: PointeeSized> BuiltinDeref for *mut T { type Pointee = T; } -unsafe impl<T: ?Sized> BuiltinDeref for *const T { +unsafe impl<T: PointeeSized> BuiltinDeref for *const T { type Pointee = T; } -pub trait ChangePointee<U: ?Sized>: BuiltinDeref { +pub trait ChangePointee<U: PointeeSized>: BuiltinDeref { type Output; } -impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a mut T { +impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a mut T { type Output = &'a mut U; } -impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a T { +impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a T { type Output = &'a U; } -impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *mut T { +impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *mut T { type Output = *mut U; } -impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *const T { +impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *const T { type Output = *const U; } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index e0e80fc9b41..b5c3e91d046 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -54,7 +54,7 @@ )] #![allow(missing_docs)] -use crate::marker::{ConstParamTy, DiscriminantKind, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; use crate::ptr; mod bounds; @@ -2740,7 +2740,7 @@ where #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(ptr: *const P) -> M; +pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + PointeeSized, M>(ptr: *const P) -> M; /// This is an accidentally-stable alias to [`ptr::copy_nonoverlapping`]; use that instead. // Note (intentionally not in the doc comment): `ptr::copy_nonoverlapping` adds some extra diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 9991b76cd0a..0cc5640941a 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -93,15 +93,15 @@ pub unsafe auto trait Send { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Send for *const T {} +impl<T: PointeeSized> !Send for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Send for *mut T {} +impl<T: PointeeSized> !Send for *mut T {} // Most instances arise automatically, but this instance is needed to link up `T: Sync` with // `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would // otherwise exist). #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Sync + ?Sized> Send for &T {} +unsafe impl<T: Sync + PointeeSized> Send for &T {} /// Types with a constant size known at compile time. /// @@ -151,11 +151,48 @@ unsafe impl<T: Sync + ?Sized> Send for &T {} #[rustc_specialization_trait] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] +// `Sized` being coinductive, despite having supertraits, is okay as there are no user-written impls, +// and we know that the supertraits are always implemented if the subtrait is just by looking at +// the builtin impls. #[rustc_coinductive] -pub trait Sized { +pub trait Sized: MetaSized { // Empty. } +/// Types with a size that can be determined from pointer metadata. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[lang = "meta_sized"] +#[diagnostic::on_unimplemented( + message = "the size for values of type `{Self}` cannot be known", + label = "doesn't have a known size" +)] +#[fundamental] +#[rustc_specialization_trait] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +// `MetaSized` being coinductive, despite having supertraits, is okay for the same reasons as +// `Sized` above. +#[rustc_coinductive] +pub trait MetaSized: PointeeSized { + // Empty +} + +/// Types that may or may not have a size. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[lang = "pointee_sized"] +#[diagnostic::on_unimplemented( + message = "values of type `{Self}` may or may not have a size", + label = "may or may not have a known size" +)] +#[fundamental] +#[rustc_specialization_trait] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +#[rustc_coinductive] +pub trait PointeeSized { + // Empty +} + /// Types that can be "unsized" to a dynamically-sized type. /// /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and @@ -192,7 +229,7 @@ pub trait Sized { #[lang = "unsize"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Unsize<T: ?Sized> { +pub trait Unsize<T: PointeeSized>: PointeeSized { // Empty. } @@ -229,7 +266,7 @@ marker_impls! { (), {T, const N: usize} [T; N], {T} [T], - {T: ?Sized} &T, + {T: PointeeSized} &T, } /// Types whose values can be duplicated simply by copying bits. @@ -442,8 +479,8 @@ marker_impls! { isize, i8, i16, i32, i64, i128, f16, f32, f64, f128, bool, char, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: PointeeSized} *const T, + {T: PointeeSized} *mut T, } @@ -452,7 +489,7 @@ impl Copy for ! {} /// Shared references can be copied, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Copy for &T {} +impl<T: PointeeSized> Copy for &T {} /// Marker trait for the types that are allowed in union fields and unsafe /// binder types. @@ -636,9 +673,9 @@ pub unsafe auto trait Sync { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Sync for *const T {} +impl<T: PointeeSized> !Sync for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Sync for *mut T {} +impl<T: PointeeSized> !Sync for *mut T {} /// Zero-sized type used to mark things that "act like" they own a `T`. /// @@ -775,57 +812,57 @@ impl<T: ?Sized> !Sync for *mut T {} /// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: PointeeSized>; #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Hash for PhantomData<T> { +impl<T: PointeeSized> Hash for PhantomData<T> { #[inline] fn hash<H: Hasher>(&self, _: &mut H) {} } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::PartialEq for PhantomData<T> { +impl<T: PointeeSized> cmp::PartialEq for PhantomData<T> { fn eq(&self, _other: &PhantomData<T>) -> bool { true } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::Eq for PhantomData<T> {} +impl<T: PointeeSized> cmp::Eq for PhantomData<T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::PartialOrd for PhantomData<T> { +impl<T: PointeeSized> cmp::PartialOrd for PhantomData<T> { fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<cmp::Ordering> { Option::Some(cmp::Ordering::Equal) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::Ord for PhantomData<T> { +impl<T: PointeeSized> cmp::Ord for PhantomData<T> { fn cmp(&self, _other: &PhantomData<T>) -> cmp::Ordering { cmp::Ordering::Equal } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Copy for PhantomData<T> {} +impl<T: PointeeSized> Copy for PhantomData<T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Clone for PhantomData<T> { +impl<T: PointeeSized> Clone for PhantomData<T> { fn clone(&self) -> Self { Self } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Default for PhantomData<T> { +impl<T: PointeeSized> Default for PhantomData<T> { fn default() -> Self { Self } } #[unstable(feature = "structural_match", issue = "31434")] -impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {} +impl<T: PointeeSized> StructuralPartialEq for PhantomData<T> {} /// Compiler-internal trait used to indicate the type of enum discriminants. /// @@ -868,15 +905,15 @@ pub trait DiscriminantKind { pub unsafe auto trait Freeze {} #[unstable(feature = "freeze", issue = "121675")] -impl<T: ?Sized> !Freeze for UnsafeCell<T> {} +impl<T: PointeeSized> !Freeze for UnsafeCell<T> {} marker_impls! { #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for - {T: ?Sized} PhantomData<T>, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: PointeeSized} PhantomData<T>, + {T: PointeeSized} *const T, + {T: PointeeSized} *mut T, + {T: PointeeSized} &T, + {T: PointeeSized} &mut T, } /// Used to determine whether a type contains any `UnsafePinned` (or `PhantomPinned`) internally, @@ -991,15 +1028,15 @@ impl !UnsafeUnpin for PhantomPinned {} marker_impls! { #[stable(feature = "pin", since = "1.33.0")] Unpin for - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: PointeeSized} &T, + {T: PointeeSized} &mut T, } marker_impls! { #[stable(feature = "pin_raw", since = "1.38.0")] Unpin for - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: PointeeSized} *const T, + {T: PointeeSized} *mut T, } /// A marker for types that can be dropped. diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index e74f5443ac2..9d9d18095bc 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -1,3 +1,5 @@ +use crate::marker::PointeeSized; + /// Used for immutable dereferencing operations, like `*v`. /// /// In addition to being used for explicit dereferencing operations with the @@ -135,7 +137,7 @@ #[rustc_diagnostic_item = "Deref"] #[const_trait] #[rustc_const_unstable(feature = "const_deref", issue = "88955")] -pub trait Deref { +pub trait Deref: PointeeSized { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "deref_target"] @@ -267,7 +269,7 @@ impl<T: ?Sized> const Deref for &mut T { #[stable(feature = "rust1", since = "1.0.0")] #[const_trait] #[rustc_const_unstable(feature = "const_deref", issue = "88955")] -pub trait DerefMut: ~const Deref { +pub trait DerefMut: ~const Deref + PointeeSized { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "deref_mut_method"] @@ -293,7 +295,7 @@ impl<T: ?Sized> const DerefMut for &mut T { /// unchanged. #[unstable(feature = "deref_pure_trait", issue = "87121")] #[lang = "deref_pure"] -pub unsafe trait DerefPure {} +pub unsafe trait DerefPure: PointeeSized {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl<T: ?Sized> DerefPure for &T {} @@ -366,7 +368,7 @@ unsafe impl<T: ?Sized> DerefPure for &mut T {} /// ``` #[lang = "receiver"] #[unstable(feature = "arbitrary_self_types", issue = "44874")] -pub trait Receiver { +pub trait Receiver: PointeeSized { /// The target type on which the method may be called. #[rustc_diagnostic_item = "receiver_target"] #[lang = "receiver_target"] @@ -393,12 +395,12 @@ where #[lang = "legacy_receiver"] #[unstable(feature = "legacy_receiver_trait", issue = "none")] #[doc(hidden)] -pub trait LegacyReceiver { +pub trait LegacyReceiver: PointeeSized { // Empty. } #[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl<T: ?Sized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &T {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index d2a07197f6f..f0781ee01fd 100644 --- a/library/core/src/ops/unsize.rs +++ b/library/core/src/ops/unsize.rs @@ -1,4 +1,4 @@ -use crate::marker::Unsize; +use crate::marker::{PointeeSized, Unsize}; /// Trait that indicates that this is a pointer or a wrapper for one, /// where unsizing can be performed on the pointee. @@ -33,40 +33,40 @@ use crate::marker::Unsize; /// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "coerce_unsized", issue = "18598")] #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> { +pub trait CoerceUnsized<T: PointeeSized> { // Empty. } // &mut T -> &mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} // &mut T -> &U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {} // &mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {} // &mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {} // &T -> &U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} // &T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {} // *mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} // *mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {} // *const T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {} /// `DispatchFromDyn` is used in the implementation of dyn-compatibility[^1] checks (specifically /// allowing arbitrary self types), to guarantee that a method's receiver type can be dispatched on. @@ -122,13 +122,13 @@ pub trait DispatchFromDyn<T> { // &T -> &U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 9366cb36c6e..800eb74babb 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -4,7 +4,7 @@ use crate::intrinsics::const_eval_select; use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; -impl<T: ?Sized> *const T { +impl<T: PointeeSized> *const T { #[doc = include_str!("docs/is_null.md")] /// /// # Examples @@ -129,7 +129,7 @@ impl<T: ?Sized> *const T { #[inline] pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U where - U: ?Sized, + U: PointeeSized, { from_raw_parts::<U>(self as *const (), metadata(meta)) } @@ -1586,7 +1586,7 @@ impl<T, const N: usize> *const [T; N] { /// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialEq for *const T { +impl<T: PointeeSized> PartialEq for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*const T) -> bool { @@ -1596,11 +1596,11 @@ impl<T: ?Sized> PartialEq for *const T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Eq for *const T {} +impl<T: PointeeSized> Eq for *const T {} /// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Ord for *const T { +impl<T: PointeeSized> Ord for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*const T) -> Ordering { @@ -1616,7 +1616,7 @@ impl<T: ?Sized> Ord for *const T { /// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialOrd for *const T { +impl<T: PointeeSized> PartialOrd for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 9c5da306e27..0deac3621e8 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -3,7 +3,7 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::intrinsics::{aggregate_raw_ptr, ptr_metadata}; -use crate::marker::Freeze; +use crate::marker::{Freeze, PointeeSized}; use crate::ptr::NonNull; /// Provides the pointer metadata type of any pointed-to type. @@ -55,7 +55,7 @@ use crate::ptr::NonNull; #[lang = "pointee_trait"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Pointee { +pub trait Pointee: PointeeSized { /// The type for metadata in pointers and references to `Self`. #[lang = "metadata_type"] // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` @@ -81,7 +81,7 @@ pub trait Pointee { /// ``` #[unstable(feature = "ptr_metadata", issue = "81513")] // NOTE: don’t stabilize this before trait aliases are stable in the language? -pub trait Thin = Pointee<Metadata = ()>; +pub trait Thin = Pointee<Metadata = ()> + PointeeSized; /// Extracts the metadata component of a pointer. /// @@ -96,7 +96,7 @@ pub trait Thin = Pointee<Metadata = ()>; /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` #[inline] -pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata { +pub const fn metadata<T: PointeeSized>(ptr: *const T) -> <T as Pointee>::Metadata { ptr_metadata(ptr) } @@ -109,7 +109,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata { /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts<T: ?Sized>( +pub const fn from_raw_parts<T: PointeeSized>( data_pointer: *const impl Thin, metadata: <T as Pointee>::Metadata, ) -> *const T { @@ -122,7 +122,7 @@ pub const fn from_raw_parts<T: ?Sized>( /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts_mut<T: ?Sized>( +pub const fn from_raw_parts_mut<T: PointeeSized>( data_pointer: *mut impl Thin, metadata: <T as Pointee>::Metadata, ) -> *mut T { @@ -152,7 +152,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>( /// duplicated in multiple codegen units), and pointers to vtables of *different* types/traits can /// compare equal (since identical vtables can be deduplicated within a codegen unit). #[lang = "dyn_metadata"] -pub struct DynMetadata<Dyn: ?Sized> { +pub struct DynMetadata<Dyn: PointeeSized> { _vtable_ptr: NonNull<VTable>, _phantom: crate::marker::PhantomData<Dyn>, } @@ -165,7 +165,7 @@ unsafe extern "C" { type VTable; } -impl<Dyn: ?Sized> DynMetadata<Dyn> { +impl<Dyn: PointeeSized> DynMetadata<Dyn> { /// When `DynMetadata` appears as the metadata field of a wide pointer, the rustc_middle layout /// computation does magic and the resulting layout is *not* a `FieldsShape::Aggregate`, instead /// it is a `FieldsShape::Primitive`. This means that the same type can have different layout @@ -206,10 +206,10 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> { } } -unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {} -unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {} +unsafe impl<Dyn: PointeeSized> Send for DynMetadata<Dyn> {} +unsafe impl<Dyn: PointeeSized> Sync for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> fmt::Debug for DynMetadata<Dyn> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish() } @@ -217,27 +217,27 @@ impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> { // Manual impls needed to avoid `Dyn: $Trait` bounds. -impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {} +impl<Dyn: PointeeSized> Unpin for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {} +impl<Dyn: PointeeSized> Copy for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> Clone for DynMetadata<Dyn> { #[inline] fn clone(&self) -> Self { *self } } -impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {} +impl<Dyn: PointeeSized> Eq for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> PartialEq for DynMetadata<Dyn> { #[inline] fn eq(&self, other: &Self) -> bool { crate::ptr::eq::<VTable>(self.vtable_ptr(), other.vtable_ptr()) } } -impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> Ord for DynMetadata<Dyn> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> crate::cmp::Ordering { @@ -245,14 +245,14 @@ impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> { } } -impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> PartialOrd for DynMetadata<Dyn> { #[inline] fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> { Some(self.cmp(other)) } } -impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> { +impl<Dyn: PointeeSized> Hash for DynMetadata<Dyn> { #[inline] fn hash<H: Hasher>(&self, hasher: &mut H) { crate::ptr::hash::<VTable, _>(self.vtable_ptr(), hasher) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 81bf6778b05..fe8c6f83034 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -398,7 +398,7 @@ use crate::cmp::Ordering; use crate::intrinsics::const_eval_select; -use crate::marker::FnPtr; +use crate::marker::{FnPtr, PointeeSized}; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::{fmt, hash, intrinsics, ub_checks}; @@ -796,7 +796,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) { #[lang = "drop_in_place"] #[allow(unconditional_recursion)] #[rustc_diagnostic_item = "ptr_drop_in_place"] -pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { +pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. @@ -825,7 +825,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] #[rustc_diagnostic_item = "ptr_null"] -pub const fn null<T: ?Sized + Thin>() -> *const T { +pub const fn null<T: PointeeSized + Thin>() -> *const T { from_raw_parts(without_provenance::<()>(0), ()) } @@ -850,7 +850,7 @@ pub const fn null<T: ?Sized + Thin>() -> *const T { #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] #[rustc_diagnostic_item = "ptr_null_mut"] -pub const fn null_mut<T: ?Sized + Thin>() -> *mut T { +pub const fn null_mut<T: PointeeSized + Thin>() -> *mut T { from_raw_parts_mut(without_provenance_mut::<()>(0), ()) } @@ -1068,7 +1068,7 @@ pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T { #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_never_returns_null_ptr] #[rustc_diagnostic_item = "ptr_from_ref"] -pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { +pub const fn from_ref<T: PointeeSized>(r: &T) -> *const T { r } @@ -1118,7 +1118,7 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { #[stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_never_returns_null_ptr] -pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T { +pub const fn from_mut<T: PointeeSized>(r: &mut T) -> *mut T { r } @@ -2419,7 +2419,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize { #[must_use = "pointer comparison produces a value"] #[rustc_diagnostic_item = "ptr_eq"] #[allow(ambiguous_wide_pointer_comparisons)] // it's actually clear here -pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { +pub fn eq<T: PointeeSized>(a: *const T, b: *const T) -> bool { a == b } @@ -2443,7 +2443,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { #[stable(feature = "ptr_addr_eq", since = "1.76.0")] #[inline(always)] #[must_use = "pointer comparison produces a value"] -pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { +pub fn addr_eq<T: PointeeSized, U: PointeeSized>(p: *const T, q: *const U) -> bool { (p as *const ()) == (q as *const ()) } @@ -2526,7 +2526,7 @@ pub fn fn_addr_eq<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool { /// assert_eq!(actual, expected); /// ``` #[stable(feature = "ptr_hash", since = "1.35.0")] -pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) { +pub fn hash<T: PointeeSized, S: hash::Hasher>(hashee: *const T, into: &mut S) { use crate::hash::Hash; hashee.hash(into); } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index efe1031b79c..6b436184f20 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1,10 +1,11 @@ use super::*; use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::intrinsics::const_eval_select; +use crate::marker::PointeeSized; use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; -impl<T: ?Sized> *mut T { +impl<T: PointeeSized> *mut T { #[doc = include_str!("docs/is_null.md")] /// /// # Examples @@ -110,7 +111,7 @@ impl<T: ?Sized> *mut T { #[inline] pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U where - U: ?Sized, + U: PointeeSized, { from_raw_parts_mut::<U>(self as *mut (), metadata(meta)) } @@ -2006,7 +2007,7 @@ impl<T, const N: usize> *mut [T; N] { /// Pointer equality is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialEq for *mut T { +impl<T: PointeeSized> PartialEq for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*mut T) -> bool { @@ -2016,11 +2017,11 @@ impl<T: ?Sized> PartialEq for *mut T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Eq for *mut T {} +impl<T: PointeeSized> Eq for *mut T {} /// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Ord for *mut T { +impl<T: PointeeSized> Ord for *mut T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*mut T) -> Ordering { @@ -2036,7 +2037,7 @@ impl<T: ?Sized> Ord for *mut T { /// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialOrd for *mut T { +impl<T: PointeeSized> PartialOrd for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 1fae5b83902..e2244941893 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1,5 +1,5 @@ use crate::cmp::Ordering; -use crate::marker::Unsize; +use crate::marker::{PointeeSized, Unsize}; use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::ops::{CoerceUnsized, DispatchFromDyn}; @@ -67,7 +67,7 @@ use crate::{fmt, hash, intrinsics, mem, ptr}; #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonNull"] -pub struct NonNull<T: ?Sized> { +pub struct NonNull<T: PointeeSized> { // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to // this is banned by <https://github.com/rust-lang/compiler-team/issues/807>. pointer: *const T, @@ -76,12 +76,12 @@ pub struct NonNull<T: ?Sized> { /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> !Send for NonNull<T> {} +impl<T: PointeeSized> !Send for NonNull<T> {} /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> !Sync for NonNull<T> {} +impl<T: PointeeSized> !Sync for NonNull<T> {} impl<T: Sized> NonNull<T> { /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. @@ -190,7 +190,7 @@ impl<T: Sized> NonNull<T> { } } -impl<T: ?Sized> NonNull<T> { +impl<T: PointeeSized> NonNull<T> { /// Creates a new `NonNull`. /// /// # Safety @@ -1604,7 +1604,7 @@ impl<T> NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Clone for NonNull<T> { +impl<T: PointeeSized> Clone for NonNull<T> { #[inline(always)] fn clone(&self) -> Self { *self @@ -1612,39 +1612,39 @@ impl<T: ?Sized> Clone for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Copy for NonNull<T> {} +impl<T: PointeeSized> Copy for NonNull<T> {} #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} #[stable(feature = "pin", since = "1.33.0")] -unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {} +unsafe impl<T: PointeeSized> PinCoerceUnsized for NonNull<T> {} #[unstable(feature = "pointer_like_trait", issue = "none")] impl<T> core::marker::PointerLike for NonNull<T> {} #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> fmt::Debug for NonNull<T> { +impl<T: PointeeSized> fmt::Debug for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> fmt::Pointer for NonNull<T> { +impl<T: PointeeSized> fmt::Pointer for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Eq for NonNull<T> {} +impl<T: PointeeSized> Eq for NonNull<T> {} #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> PartialEq for NonNull<T> { +impl<T: PointeeSized> PartialEq for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &Self) -> bool { @@ -1653,7 +1653,7 @@ impl<T: ?Sized> PartialEq for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Ord for NonNull<T> { +impl<T: PointeeSized> Ord for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> Ordering { @@ -1662,7 +1662,7 @@ impl<T: ?Sized> Ord for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> PartialOrd for NonNull<T> { +impl<T: PointeeSized> PartialOrd for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &Self) -> Option<Ordering> { @@ -1671,7 +1671,7 @@ impl<T: ?Sized> PartialOrd for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> hash::Hash for NonNull<T> { +impl<T: PointeeSized> hash::Hash for NonNull<T> { #[inline] fn hash<H: hash::Hasher>(&self, state: &mut H) { self.as_ptr().hash(state) @@ -1679,7 +1679,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<Unique<T>> for NonNull<T> { +impl<T: PointeeSized> From<Unique<T>> for NonNull<T> { #[inline] fn from(unique: Unique<T>) -> Self { unique.as_non_null_ptr() @@ -1687,7 +1687,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> From<&mut T> for NonNull<T> { +impl<T: PointeeSized> From<&mut T> for NonNull<T> { /// Converts a `&mut T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. @@ -1698,7 +1698,7 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> From<&T> for NonNull<T> { +impl<T: PointeeSized> From<&T> for NonNull<T> { /// Converts a `&T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index d688ce2a07a..c069314ff7d 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -1,5 +1,5 @@ use crate::fmt; -use crate::marker::{PhantomData, Unsize}; +use crate::marker::{PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::pin::PinCoerceUnsized; use crate::ptr::NonNull; @@ -34,7 +34,7 @@ use crate::ptr::NonNull; #[repr(transparent)] // Lang item used experimentally by Miri to define the semantics of `Unique`. #[lang = "ptr_unique"] -pub struct Unique<T: ?Sized> { +pub struct Unique<T: PointeeSized> { pointer: NonNull<T>, // NOTE: this marker has no consequences for variance, but is necessary // for dropck to understand that we logically own a `T`. @@ -49,14 +49,14 @@ pub struct Unique<T: ?Sized> { /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. #[unstable(feature = "ptr_internals", issue = "none")] -unsafe impl<T: Send + ?Sized> Send for Unique<T> {} +unsafe impl<T: Send + PointeeSized> Send for Unique<T> {} /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. #[unstable(feature = "ptr_internals", issue = "none")] -unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {} +unsafe impl<T: Sync + PointeeSized> Sync for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] impl<T: Sized> Unique<T> { @@ -78,7 +78,7 @@ impl<T: Sized> Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Unique<T> { +impl<T: PointeeSized> Unique<T> { /// Creates a new `Unique`. /// /// # Safety @@ -157,7 +157,7 @@ impl<T: ?Sized> Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Clone for Unique<T> { +impl<T: PointeeSized> Clone for Unique<T> { #[inline] fn clone(&self) -> Self { *self @@ -165,33 +165,33 @@ impl<T: ?Sized> Clone for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Copy for Unique<T> {} +impl<T: PointeeSized> Copy for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl<T: ?Sized> PinCoerceUnsized for Unique<T> {} +unsafe impl<T: PointeeSized> PinCoerceUnsized for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> fmt::Debug for Unique<T> { +impl<T: PointeeSized> fmt::Debug for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> fmt::Pointer for Unique<T> { +impl<T: PointeeSized> fmt::Pointer for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<&mut T> for Unique<T> { +impl<T: PointeeSized> From<&mut T> for Unique<T> { /// Converts a `&mut T` to a `Unique<T>`. /// /// This conversion is infallible since references cannot be null. @@ -202,7 +202,7 @@ impl<T: ?Sized> From<&mut T> for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<NonNull<T>> for Unique<T> { +impl<T: PointeeSized> From<NonNull<T>> for Unique<T> { /// Converts a `NonNull<T>` to a `Unique<T>`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 02eb805ece1..3ff55792431 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,7 +1,7 @@ // See core/src/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; -use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; +use crate::marker::{ConstParamTy_, PointeeSized, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{self, Break, Continue}; // Recursive macro for implementing n-ary tuple functions and operations @@ -25,7 +25,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: PartialEq),+> PartialEq for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): PointeeSized { #[inline] fn eq(&self, other: &($($T,)+)) -> bool { @@ -43,7 +43,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: Eq),+> Eq for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): PointeeSized {} } @@ -73,7 +73,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): PointeeSized { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { @@ -119,7 +119,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: Ord),+> Ord for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): PointeeSized { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs index 67b09599d9d..0e915b92697 100644 --- a/library/rtstartup/rsbegin.rs +++ b/library/rtstartup/rsbegin.rs @@ -21,8 +21,21 @@ #![allow(internal_features)] #![warn(unreachable_pub)] +#[cfg(not(bootstrap))] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[cfg(not(bootstrap))] +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[cfg(bootstrap)] +#[lang = "sized"] +pub trait Sized {} +#[cfg(not(bootstrap))] #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} + #[lang = "sync"] auto trait Sync {} #[lang = "copy"] @@ -30,14 +43,25 @@ trait Copy {} #[lang = "freeze"] auto trait Freeze {} +#[cfg(bootstrap)] impl<T: ?Sized> Copy for *mut T {} +#[cfg(not(bootstrap))] +impl<T: PointeeSized> Copy for *mut T {} +#[cfg(bootstrap)] #[lang = "drop_in_place"] #[inline] #[allow(unconditional_recursion)] pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { drop_in_place(to_drop); } +#[cfg(not(bootstrap))] +#[lang = "drop_in_place"] +#[inline] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) { + drop_in_place(to_drop); +} // Frame unwind info registration // diff --git a/library/rtstartup/rsend.rs b/library/rtstartup/rsend.rs index a6f7d103356..75f9212695d 100644 --- a/library/rtstartup/rsend.rs +++ b/library/rtstartup/rsend.rs @@ -8,8 +8,21 @@ #![allow(internal_features)] #![warn(unreachable_pub)] +#[cfg(not(bootstrap))] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[cfg(not(bootstrap))] +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[cfg(bootstrap)] +#[lang = "sized"] +pub trait Sized {} +#[cfg(not(bootstrap))] #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} + #[lang = "sync"] trait Sync {} impl<T> Sync for T {} @@ -18,14 +31,25 @@ trait Copy {} #[lang = "freeze"] auto trait Freeze {} +#[cfg(bootstrap)] impl<T: ?Sized> Copy for *mut T {} +#[cfg(not(bootstrap))] +impl<T: PointeeSized> Copy for *mut T {} +#[cfg(bootstrap)] #[lang = "drop_in_place"] #[inline] #[allow(unconditional_recursion)] pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { drop_in_place(to_drop); } +#[cfg(not(bootstrap))] +#[lang = "drop_in_place"] +#[inline] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) { + drop_in_place(to_drop); +} #[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))] pub mod eh_frames { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f9f82b80041..419839067f9 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2574,7 +2574,7 @@ fn prepare_cargo_test( // by `Cargo::new` and that actually makes things go wrong. if builder.kind != Kind::Miri { let mut dylib_paths = builder.rustc_lib_paths(compiler); - dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, target))); + dylib_paths.push(builder.sysroot_target_libdir(compiler, target)); helpers::add_dylib_path(dylib_paths, &mut cargo); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 237efaefada..0088e851d39 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -589,7 +589,7 @@ impl ErrorIndex { let compiler = builder.compiler_for(builder.top_stage, host, host); let mut cmd = command(builder.ensure(ErrorIndex { compiler }).tool_path); let mut dylib_paths = builder.rustc_lib_paths(compiler); - dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, compiler.host))); + dylib_paths.push(builder.sysroot_target_libdir(compiler, compiler.host)); add_dylib_path(dylib_paths, &mut cmd); cmd } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9b5491310b4..dcd499d5f0d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -265,13 +265,27 @@ pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { .collect(); let generics = clean_ty_generics(cx, did); - let (generics, supertrait_bounds) = separate_self_bounds(generics); + let (generics, mut supertrait_bounds) = separate_self_bounds(generics); + + supertrait_bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } } fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { let generics = clean_ty_generics(cx, did); - let (generics, bounds) = separate_self_bounds(generics); + let (generics, mut bounds) = separate_self_bounds(generics); + + bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + clean::TraitAlias { generics, bounds } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index db4bcdaeb6c..d77bdf09d01 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,9 +39,9 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; -use rustc_hir::PredicateOrigin; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; +use rustc_hir::{LangItem, PredicateOrigin}; use rustc_hir_analysis::hir_ty_lowering::FeedConstTy; use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty}; use rustc_middle::metadata::Reexport; @@ -886,6 +886,10 @@ fn clean_ty_generics_inner<'tcx>( if b.is_sized_bound(cx) { has_sized = true; false + } else if b.is_meta_sized_bound(cx) { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + false } else { true } @@ -1448,6 +1452,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } _ => true, }); + + bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + // Our Sized/?Sized bound didn't get handled when creating the generics // because we didn't actually get our whole set of bounds until just now // (some of them may have come from the trait). If we do have a sized @@ -2276,6 +2287,12 @@ fn clean_middle_opaque_bounds<'tcx>( _ => return None, }; + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + if cx.tcx.is_lang_item(trait_ref.def_id(), LangItem::MetaSized) { + return None; + } + if let Some(sized) = cx.tcx.lang_items().sized_trait() && trait_ref.def_id() == sized { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 40efa997868..f813e6c5517 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -135,11 +135,17 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi // don't actually know the set of associated types right here so that // should be handled when cleaning associated types. generics.where_predicates.retain(|pred| { - if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred - && bounds.iter().any(|b| b.is_sized_bound(cx)) - { + let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred else { + return true; + }; + + if bounds.iter().any(|b| b.is_sized_bound(cx)) { sized_params.insert(*param); false + } else if bounds.iter().any(|b| b.is_meta_sized_bound(cx)) { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + false } else { true } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 58e05bd1e85..2d9670a3d10 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1289,11 +1289,19 @@ impl GenericBound { } pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { + self.is_bounded_by_lang_item(cx, LangItem::Sized) + } + + pub(crate) fn is_meta_sized_bound(&self, cx: &DocContext<'_>) -> bool { + self.is_bounded_by_lang_item(cx, LangItem::MetaSized) + } + + fn is_bounded_by_lang_item(&self, cx: &DocContext<'_>, lang_item: LangItem) -> bool { if let GenericBound::TraitBound( PolyTrait { ref trait_, .. }, rustc_hir::TraitBoundModifiers::NONE, ) = *self - && Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() + && cx.tcx.is_lang_item(trait_.def_id(), lang_item) { return true; } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index fdccf1fb33d..769526d131b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -388,9 +388,11 @@ fn check_other_call_arg<'tcx>( && let (input, n_refs) = peel_middle_ty_refs(*input) && let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input) && let Some(sized_def_id) = cx.tcx.lang_items().sized_trait() + && let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait() && let [trait_predicate] = trait_predicates .iter() .filter(|trait_predicate| trait_predicate.def_id() != sized_def_id) + .filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id) .collect::<Vec<_>>()[..] && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 2efb55b9880..8d2f8029112 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -174,6 +174,7 @@ fn needless_borrow_count<'tcx>( ) -> usize { let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait(); let sized_trait_def_id = cx.tcx.lang_items().sized_trait(); + let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait(); let drop_trait_def_id = cx.tcx.lang_items().drop_trait(); let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder(); @@ -209,6 +210,7 @@ fn needless_borrow_count<'tcx>( .all(|trait_def_id| { Some(trait_def_id) == destruct_trait_def_id || Some(trait_def_id) == sized_trait_def_id + || Some(trait_def_id) == meta_sized_trait_def_id || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id) }) { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 95623467b81..9aede1dec93 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -116,13 +116,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ]; let sized_trait = need!(cx.tcx.lang_items().sized_trait()); + let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait()); let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. match pred.kind().no_bound_vars() { - Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred), + Some(ty::ClauseKind::Trait(pred)) + if pred.def_id() != sized_trait && pred.def_id() != meta_sized_trait + => Some(pred), _ => None, } }) diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs index 40f40f7ea09..5c13d862276 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -7,8 +7,14 @@ #[link(name = "c")] unsafe extern "C" {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index 2718217313f..175dd075408 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:27:19 + --> tests/ui/def_id_nocore.rs:33:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index acf258f4eed..030c2e36721 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -72,7 +72,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Functions with no declared return type (i.e., the default return) // have the output_type `Tuple([])`. - ty::Tuple(t_list) if t_list.is_empty() => { + ty::Tuple(t_list) if (*t_list).deref().is_empty() => { unsafe { ffi::call::<()>(ptr, libffi_args.as_slice()) }; return interp_ok(ImmTy::uninit(dest.layout)); } diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr index 32446a8e1ce..ec578db2d0a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at ALLOC[0x0..0x1] +LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at ALLOC[0x0..0x1] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index 1a8509a0b13..72aeb0fdf8e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/assembly/nvptx-c-abi-arg-v7.rs b/tests/assembly/nvptx-c-abi-arg-v7.rs index 27b64b58f04..be98b167470 100644 --- a/tests/assembly/nvptx-c-abi-arg-v7.rs +++ b/tests/assembly/nvptx-c-abi-arg-v7.rs @@ -10,8 +10,12 @@ #![feature(abi_ptx, lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/nvptx-c-abi-ret-v7.rs b/tests/assembly/nvptx-c-abi-ret-v7.rs index 56ab182fcce..c68c71c872c 100644 --- a/tests/assembly/nvptx-c-abi-ret-v7.rs +++ b/tests/assembly/nvptx-c-abi-ret-v7.rs @@ -10,8 +10,12 @@ #![feature(abi_ptx, lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs b/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs index b3bfc66a5a5..f245b4460f2 100644 --- a/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs +++ b/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs @@ -20,8 +20,12 @@ #![feature(abi_ptx, lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs index 5b5eeb29f0f..4f3673ccfc3 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -13,12 +13,16 @@ #![crate_type = "lib"] #![no_std] #![no_core] - // FIXME: Migrate these code after PR #130693 is landed. -// vvvvv core + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/s390x-vector-abi.rs b/tests/assembly/s390x-vector-abi.rs index e159a357685..fcf42664034 100644 --- a/tests/assembly/s390x-vector-abi.rs +++ b/tests/assembly/s390x-vector-abi.rs @@ -15,12 +15,17 @@ #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] - // Cases where vector feature is disabled are rejected. // See tests/ui/simd-abi-checks-s390x.rs for test for them. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs index bed515915b8..2abe8687d8b 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -19,8 +19,14 @@ #![no_core] #![crate_type = "lib"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "drop_in_place"] fn drop_in_place<T>(_: *mut T) {} diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 941c4abed46..db11549382f 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -39,13 +39,19 @@ macro_rules! impl_marker_trait { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} #[lang = "copy"] pub trait Copy: Sized {} @@ -67,14 +73,14 @@ impl_marker_trait!( f16, f32, f64, f128, ] ); -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} impl<T: Copy, const N: usize> Copy for [T; N] {} #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; -impl<T: ?Sized> Copy for PhantomData<T> {} +pub struct PhantomData<T: PointeeSized>; +impl<T: PointeeSized> Copy for PhantomData<T> {} pub enum Option<T> { None, @@ -90,17 +96,17 @@ impl<T: Copy, E: Copy> Copy for Result<T, E> {} #[lang = "manually_drop"] #[repr(transparent)] -pub struct ManuallyDrop<T: ?Sized> { +pub struct ManuallyDrop<T: PointeeSized> { value: T, } -impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {} +impl<T: Copy + PointeeSized> Copy for ManuallyDrop<T> {} #[lang = "unsafe_cell"] #[repr(transparent)] -pub struct UnsafeCell<T: ?Sized> { +pub struct UnsafeCell<T: PointeeSized> { value: T, } -impl<T: ?Sized> !Freeze for UnsafeCell<T> {} +impl<T: PointeeSized> !Freeze for UnsafeCell<T> {} #[lang = "tuple_trait"] pub trait Tuple {} @@ -176,15 +182,15 @@ pub trait Fn<Args: Tuple>: FnMut<Args> { #[lang = "dispatch_from_dyn"] trait DispatchFromDyn<T> {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} #[lang = "unsize"] -trait Unsize<T: ?Sized> {} +trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> {} +pub trait CoerceUnsized<T: PointeeSized> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} #[lang = "drop"] trait Drop { diff --git a/tests/codegen-units/item-collection/implicit-panic-call.rs b/tests/codegen-units/item-collection/implicit-panic-call.rs index 6d3a17d8d4a..612132f056b 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -28,8 +28,14 @@ fn panic_div_overflow() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs index 90757e601af..68d2acfb527 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -17,7 +17,13 @@ #![crate_type = "lib"] #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +trait PointeeSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/dst-offset.rs b/tests/codegen/dst-offset.rs index 7177a960432..2cf5fa9fac6 100644 --- a/tests/codegen/dst-offset.rs +++ b/tests/codegen/dst-offset.rs @@ -3,8 +3,9 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 #![crate_type = "lib"] -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::ptr::addr_of; // Hack to get the correct type for usize @@ -12,7 +13,7 @@ use std::ptr::addr_of; #[no_mangle] pub fn helper(_: usize) {} -struct Dst<T: ?Sized> { +struct Dst<T: PointeeSized> { x: u32, y: u8, z: T, diff --git a/tests/codegen/emscripten-catch-unwind-js-eh.rs b/tests/codegen/emscripten-catch-unwind-js-eh.rs index 3ab4b5c9c63..f43869cf218 100644 --- a/tests/codegen/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs @@ -9,8 +9,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs index d0571e4df08..b0750d52268 100644 --- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs @@ -8,8 +8,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/terminating-catchpad.rs b/tests/codegen/terminating-catchpad.rs index 17d88796300..a2ec19871d1 100644 --- a/tests/codegen/terminating-catchpad.rs +++ b/tests/codegen/terminating-catchpad.rs @@ -15,8 +15,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} unsafe extern "C-unwind" { safe fn unwinds(); diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index 0d9c7757883..ecace722e0d 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `aapcs` and // `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 4c7b2856e2e..7df46813ed1 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `fastcall` and // `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index ffc11d1faef..cc06ee12549 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind` // extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index c869ca7e2b8..69bfaf80b4b 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `sysv64` and // `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index 19b23ee47ba..05f6b8b70e1 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `thiscall` and // `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index b420f67ca9b..d001a16b32a 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, abi_vectorcall)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `vectorcall` and // `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute. diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index 2697d3cbcd6..257f00b54e4 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `win64` and // `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/crashes/120033.rs b/tests/crashes/120033.rs index f1502978dc5..7584f98ec90 100644 --- a/tests/crashes/120033.rs +++ b/tests/crashes/120033.rs @@ -1,8 +1,10 @@ //@ known-bug: #120033 #![feature(non_lifetime_binders)] +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] // added to keep parameters unconstrained -pub trait Foo<T: ?Sized> { - type Bar<K: ?Sized>; +pub trait Foo<T: std::marker::PointeeSized> { + type Bar<K: std::marker::PointeeSized>; } pub struct Bar<T: ?AutoTrait> {} diff --git a/tests/debuginfo/recursive-type-with-gat.rs b/tests/debuginfo/recursive-type-with-gat.rs index b8a67d8d24b..a4a1736ef5f 100644 --- a/tests/debuginfo/recursive-type-with-gat.rs +++ b/tests/debuginfo/recursive-type-with-gat.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Cdebuginfo=2 +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] // added to keep parameters unconstrained -pub trait Functor +pub trait Functor: std::marker::PointeeSized { type With<T>: Functor; } @@ -17,20 +19,20 @@ impl<T> Functor for Vec<T> { pub struct Compose<F1, F2, T>(F1::With<F2::With<T>>) where - F1: Functor + ?Sized, - F2: Functor + ?Sized; + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized; impl<F1, F2, T> Functor for Compose<F1, F2, T> where - F1: Functor + ?Sized, - F2: Functor + ?Sized + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized, { type With<T2> = F1::With<F2::With<T2>> ; } pub enum Value<F> where - F: Functor + ?Sized, + F: Functor + std::marker::PointeeSized, { SignedInt(*mut F::With<i64>), Array(*mut Value<Compose<F, Vec<()>, ()>>), diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index 7141ddb0d7e..50b56441cca 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -30,7 +30,7 @@ trait TraitVisibility { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail6")] pub trait TraitVisibility { } @@ -43,7 +43,7 @@ trait TraitUnsafety { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] unsafe trait TraitUnsafety { } @@ -57,7 +57,7 @@ trait TraitAddMethod { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub trait TraitAddMethod { fn method(); @@ -74,7 +74,7 @@ trait TraitChangeMethodName { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitChangeMethodName { fn methodChanged(); @@ -559,7 +559,7 @@ trait TraitAddBuiltinBoundToMethodTypeParameter { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddBuiltinBoundToMethodTypeParameter { #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] @@ -827,7 +827,7 @@ trait TraitAddAssociatedConstant { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddAssociatedConstant { const Value: u32; diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index a5003a8d432..8faf6806b90 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs @@ -34,7 +34,7 @@ impl ChangeMethodNameTrait for Foo { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub trait ChangeMethodNameTrait { #[rustc_clean(cfg="cfail3")] diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index 44faf3a4ed9..fe2aaffa2a0 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -22,8 +22,14 @@ macro_rules! asm { }; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/amdgpu-kd/foo.rs b/tests/run-make/amdgpu-kd/foo.rs index a0d803ab813..a097e9211a7 100644 --- a/tests/run-make/amdgpu-kd/foo.rs +++ b/tests/run-make/amdgpu-kd/foo.rs @@ -4,8 +4,14 @@ #![no_std] // This is needed because of #![no_core]: +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] extern "gpu-kernel" fn kernel() {} diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index e8bbd420cc4..f5c3b360ee8 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -16,8 +16,14 @@ pub enum AtomicOrdering { #[rustc_intrinsic] unsafe fn atomic_xadd<T, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} #[lang = "freeze"] diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index c91cd695cee..07fda1f3f4a 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -24,14 +24,20 @@ pub fn main() -> ! { // FIXME: replace with proper minicore once available (#130693) mod minicore { + #[lang = "pointee_sized"] + pub trait PointeeSized {} + + #[lang = "meta_sized"] + pub trait MetaSized: PointeeSized {} + #[lang = "sized"] - pub trait Sized {} + pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} impl Copy for u32 {} impl Copy for &u32 {} - impl<T: ?Sized> Copy for *mut T {} + impl<T: PointeeSized> Copy for *mut T {} pub mod ptr { #[inline] diff --git a/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs b/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs index c31cf27f9ae..dbccf8cea03 100644 --- a/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs +++ b/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs @@ -2,8 +2,12 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] pub fn hello() {} diff --git a/tests/run-make/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs index cd1ef8cb351..fd6f8357030 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -9,8 +9,14 @@ pub static mut STATIC_MUT_BOOL: bool = true; const CONST_BOOL: bool = true; pub static CONST_BOOL_REF: &'static bool = &CONST_BOOL; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/raw-dylib-cross-compilation/lib.rs b/tests/run-make/raw-dylib-cross-compilation/lib.rs index d3b7fd23ca8..8d53ac04485 100644 --- a/tests/run-make/raw-dylib-cross-compilation/lib.rs +++ b/tests/run-make/raw-dylib-cross-compilation/lib.rs @@ -4,8 +4,12 @@ #![crate_type = "lib"] // This is needed because of #![no_core]: +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[link(name = "extern_1", kind = "raw-dylib")] extern "C" { diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs index 9ea8eb8cf88..1cd961ff87e 100644 --- a/tests/run-make/simd-ffi/simd.rs +++ b/tests/run-make/simd-ffi/simd.rs @@ -52,8 +52,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { unsafe { integer(a, b) } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/run-make/target-specs/foo.rs b/tests/run-make/target-specs/foo.rs index 22939e87912..aead76dff87 100644 --- a/tests/run-make/target-specs/foo.rs +++ b/tests/run-make/target-specs/foo.rs @@ -4,8 +4,14 @@ #[lang = "copy"] trait Copy {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "freeze"] auto trait Freeze {} diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index 5440301f965..104c4891502 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -1,8 +1,14 @@ #![feature(no_core, auto_traits, lang_items, arbitrary_self_types)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} @@ -15,8 +21,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 1]" -//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 2]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[19, 1]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[21, 2]" //@ is "$.index[?(@.docs=='has span')].inner.impl.is_synthetic" false //@ is "$.index[?(@.inner.impl.is_synthetic==true)].span" null //@ is "$.index[?(@.inner.impl.is_synthetic==true)].inner.impl.for.resolved_path.path" '"Foo"' diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index a1f0ebd11b6..2bdbb868626 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -6,8 +6,14 @@ //@ set impl_i32 = "$.index[?(@.docs=='Only core can do this')].id" +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} /// Only core can do this impl i32 { diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs index 18ac37280c0..32ba331527d 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -5,8 +5,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} /// ```{class="} /// main; diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index cc13cc0fe53..fbe3df5d9d3 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -1,5 +1,5 @@ error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 | LL | / /// ```{class="} LL | | /// main; @@ -17,7 +17,7 @@ LL | #![deny(warnings)] = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 | LL | / /// ```{class="} LL | | /// main; diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs index 17fa3ccfe3e..77512987219 100644 --- a/tests/rustdoc-ui/target-feature-stability.rs +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -14,8 +14,14 @@ #![feature(arm_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} // `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. #[target_feature(enable = "fp-armv8")] diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc/file-creation-111249.rs index a6522d682f1..7a075a1583f 100644 --- a/tests/rustdoc/file-creation-111249.rs +++ b/tests/rustdoc/file-creation-111249.rs @@ -1,10 +1,20 @@ // https://github.com/rust-lang/rust/issues/111249 #![crate_name = "foo"] #![feature(no_core)] +#![feature(lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + //@ files "foo" "['all.html', 'visible', 'index.html', 'sidebar-items.js', 'hidden', \ -// 'struct.Bar.html']" +// 'struct.Bar.html', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/visible" "['trait.Foo.html', 'index.html', 'sidebar-items.js']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" diff --git a/tests/rustdoc/foreigntype.rs b/tests/rustdoc/foreigntype.rs index bee3d8e6509..66371e8c827 100644 --- a/tests/rustdoc/foreigntype.rs +++ b/tests/rustdoc/foreigntype.rs @@ -10,7 +10,7 @@ impl ExtType { pub fn do_something(&self) {} } -pub trait Trait {} +pub trait Trait: std::marker::PointeeSized {} //@ has foreigntype/trait.Trait.html '//a[@class="foreigntype"]' 'ExtType' impl Trait for ExtType {} diff --git a/tests/rustdoc/intra-doc/auxiliary/my-core.rs b/tests/rustdoc/intra-doc/auxiliary/my-core.rs index c050929db96..a33b0582b31 100644 --- a/tests/rustdoc/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc/intra-doc/auxiliary/my-core.rs @@ -13,8 +13,14 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/extern-type.rs b/tests/rustdoc/intra-doc/extern-type.rs index 198ac8e43e0..41a678d52cd 100644 --- a/tests/rustdoc/intra-doc/extern-type.rs +++ b/tests/rustdoc/intra-doc/extern-type.rs @@ -4,11 +4,11 @@ extern { pub type ExternType; } -pub trait T { +pub trait T: std::marker::PointeeSized { fn test(&self) {} } -pub trait G<N> { +pub trait G<N>: std::marker::PointeeSized { fn g(&self, n: N) {} } diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc/intra-doc/no-doc-primitive.rs index 79825643b98..9ce43e26aa1 100644 --- a/tests/rustdoc/intra-doc/no-doc-primitive.rs +++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs @@ -10,8 +10,14 @@ //@ has no_doc_primitive/index.html //! A [`char`] and its [`char::len_utf8`]. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} impl char { pub fn len_utf8(self) -> usize { diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc/intra-doc/prim-methods-local.rs index a9e71c58be3..f6aa1ed2156 100644 --- a/tests/rustdoc/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc/intra-doc/prim-methods-local.rs @@ -19,8 +19,14 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc/intra-doc/prim-self.rs index d5bfd570d54..21368fab993 100644 --- a/tests/rustdoc/intra-doc/prim-self.rs +++ b/tests/rustdoc/intra-doc/prim-self.rs @@ -37,5 +37,11 @@ impl S { pub fn f() {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs index dcdcbfb7ec1..cd4d76baca1 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs +++ b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs @@ -11,8 +11,14 @@ impl<T> Box<T> { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[doc(notable_trait)] pub trait FakeIterator {} diff --git a/tests/rustdoc/primitive/cross-crate-primitive-doc.rs b/tests/rustdoc/primitive/cross-crate-primitive-doc.rs index 0ffde5b0f2d..3c159d57f13 100644 --- a/tests/rustdoc/primitive/cross-crate-primitive-doc.rs +++ b/tests/rustdoc/primitive/cross-crate-primitive-doc.rs @@ -5,8 +5,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} extern crate primitive_doc; diff --git a/tests/rustdoc/reexport/cfg_doc_reexport.rs b/tests/rustdoc/reexport/cfg_doc_reexport.rs index 44ec3663284..2c3b3110fb7 100644 --- a/tests/rustdoc/reexport/cfg_doc_reexport.rs +++ b/tests/rustdoc/reexport/cfg_doc_reexport.rs @@ -4,8 +4,14 @@ #![crate_name = "foo"] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ has 'foo/index.html' //@ has - '//dt/*[@class="stab portability"]' 'foobar' diff --git a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs index 61060b3ff7c..8f0a5806b09 100644 --- a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs +++ b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs @@ -3,11 +3,17 @@ #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \ -// 'visible']" +// 'visible', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" //@ files "foo/visible" "['index.html', 'sidebar-items.js', 'trait.Foo.html']" diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs index 0d2ee89415d..a40116894a8 100644 --- a/tests/rustdoc/safe-intrinsic.rs +++ b/tests/rustdoc/safe-intrinsic.rs @@ -5,8 +5,14 @@ #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ has 'foo/fn.abort.html' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' diff --git a/tests/ui/abi/fixed_x18.rs b/tests/ui/abi/fixed_x18.rs index d64b845e5bd..09d16303033 100644 --- a/tests/ui/abi/fixed_x18.rs +++ b/tests/ui/abi/fixed_x18.rs @@ -20,7 +20,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} //~? ERROR the `-Zfixed-x18` flag is not supported on the ` diff --git a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs index 74882fb5c55..b3bd0666ab2 100644 --- a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs +++ b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs @@ -7,8 +7,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] pub fn foo() {} diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index bdfcbed71e9..99139761d7c 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -4,6 +4,7 @@ error: rustc_dump_predicates LL | trait Trait<T>: Iterator<Item: Copy> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } @@ -16,6 +17,7 @@ error: rustc_dump_predicates LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } diff --git a/tests/ui/attributes/export/lang-item.rs b/tests/ui/attributes/export/lang-item.rs index b923b41a957..92ca1d742e1 100644 --- a/tests/ui/attributes/export/lang-item.rs +++ b/tests/ui/attributes/export/lang-item.rs @@ -3,6 +3,14 @@ #![crate_type = "sdylib"] #![no_core] +#[lang = "pointee_sized"] +//~^ ERROR lang items are not allowed in stable dylibs +pub trait PointeeSized {} + +#[lang = "meta_sized"] +//~^ ERROR lang items are not allowed in stable dylibs +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] //~^ ERROR lang items are not allowed in stable dylibs trait Sized {} diff --git a/tests/ui/attributes/export/lang-item.stderr b/tests/ui/attributes/export/lang-item.stderr index 8c0741bdb6f..211c0b9b07b 100644 --- a/tests/ui/attributes/export/lang-item.stderr +++ b/tests/ui/attributes/export/lang-item.stderr @@ -1,8 +1,20 @@ error: lang items are not allowed in stable dylibs --> $DIR/lang-item.rs:6:1 | +LL | #[lang = "pointee_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: lang items are not allowed in stable dylibs + --> $DIR/lang-item.rs:10:1 + | +LL | #[lang = "meta_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: lang items are not allowed in stable dylibs + --> $DIR/lang-item.rs:14:1 + | LL | #[lang = "sized"] | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 3 previous errors diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 194bcaa307f..6428b8c5247 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -9,7 +9,13 @@ #![feature(lang_items, no_core, auto_traits)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //~? ERROR differs from LLVM target's diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index fb0ccb4fdcd..b8ae4f6b56b 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -25,3 +25,4 @@ type C<N: Sized> = (); type D<N: ?Sized> = (); //~^ ERROR type parameter `N` is never used //~| HELP consider removing `N` +//~| HELP if you intended `N` to be a const parameter diff --git a/tests/ui/const-generics/unused-type-param-suggestion.stderr b/tests/ui/const-generics/unused-type-param-suggestion.stderr index 67b704d8bc7..a7aa477ab31 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -47,6 +47,7 @@ LL | type D<N: ?Sized> = (); | ^ unused type parameter | = help: consider removing `N` or referring to it in the body of the type alias + = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error: aborting due to 6 previous errors diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs index 423ff37baef..2372d1c3e3d 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -7,7 +7,9 @@ extern "C" { type Opaque; } -const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR layout -const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR layout +const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; +//~^ ERROR the size for values of type `Opaque` cannot be known +const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; +//~^ ERROR the size for values of type `Opaque` cannot be known fn main() {} diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index c78626bdefc..6d6bc157771 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -1,15 +1,27 @@ -error[E0080]: `extern type` does not have known layout - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_SIZE` failed here + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | | + | required by a bound introduced by this call + | + = help: the trait `MetaSized` is not implemented for `Opaque` +note: required by a bound in `std::intrinsics::size_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL -error[E0080]: `extern type` does not have known layout - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:32 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45 | LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_ALIGN` failed here + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | | + | required by a bound introduced by this call + | + = help: the trait `MetaSized` is not implemented for `Opaque` +note: required by a bound in `std::intrinsics::align_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/debuginfo/dwarf-versions.rs b/tests/ui/debuginfo/dwarf-versions.rs index 8f731f10ead..ccf33542960 100644 --- a/tests/ui/debuginfo/dwarf-versions.rs +++ b/tests/ui/debuginfo/dwarf-versions.rs @@ -29,8 +29,14 @@ #![no_core] #![no_std] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/extern/extern-type-diag-not-similar.rs b/tests/ui/extern/extern-type-diag-not-similar.rs index cd3eec9f1f7..21a2a20a644 100644 --- a/tests/ui/extern/extern-type-diag-not-similar.rs +++ b/tests/ui/extern/extern-type-diag-not-similar.rs @@ -3,7 +3,10 @@ // Two extern types shouldn't really be considered similar just // because they are both extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; + extern "C" { type ShouldNotBeMentioned; } @@ -14,7 +17,7 @@ extern "C" { unsafe impl Send for ShouldNotBeMentioned {} -fn assert_send<T: Send + ?Sized>() {} +fn assert_send<T: Send + PointeeSized>() {} fn main() { assert_send::<Foo>() diff --git a/tests/ui/extern/extern-type-diag-not-similar.stderr b/tests/ui/extern/extern-type-diag-not-similar.stderr index 3547f9b3ff6..f85ff1eead6 100644 --- a/tests/ui/extern/extern-type-diag-not-similar.stderr +++ b/tests/ui/extern/extern-type-diag-not-similar.stderr @@ -1,14 +1,14 @@ error[E0277]: `Foo` cannot be sent between threads safely - --> $DIR/extern-type-diag-not-similar.rs:20:19 + --> $DIR/extern-type-diag-not-similar.rs:23:19 | LL | assert_send::<Foo>() | ^^^ `Foo` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Foo` note: required by a bound in `assert_send` - --> $DIR/extern-type-diag-not-similar.rs:17:19 + --> $DIR/extern-type-diag-not-similar.rs:20:19 | -LL | fn assert_send<T: Send + ?Sized>() {} +LL | fn assert_send<T: Send + PointeeSized>() {} | ^^^^ required by this bound in `assert_send` error: aborting due to 1 previous error diff --git a/tests/ui/extern/extern-types-manual-sync-send.rs b/tests/ui/extern/extern-types-manual-sync-send.rs index 2df0cd4c923..b273dcea722 100644 --- a/tests/ui/extern/extern-types-manual-sync-send.rs +++ b/tests/ui/extern/extern-types-manual-sync-send.rs @@ -1,7 +1,9 @@ //@ run-pass // Test that unsafe impl for Sync/Send can be provided for extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; extern "C" { type A; @@ -10,8 +12,8 @@ extern "C" { unsafe impl Sync for A {} unsafe impl Send for A {} -fn assert_sync<T: ?Sized + Sync>() {} -fn assert_send<T: ?Sized + Send>() {} +fn assert_sync<T: PointeeSized + Sync>() {} +fn assert_send<T: PointeeSized + Send>() {} fn main() { assert_sync::<A>(); diff --git a/tests/ui/extern/extern-types-not-sync-send.rs b/tests/ui/extern/extern-types-not-sync-send.rs index ba82caced7a..3cac1aabea9 100644 --- a/tests/ui/extern/extern-types-not-sync-send.rs +++ b/tests/ui/extern/extern-types-not-sync-send.rs @@ -1,13 +1,15 @@ // Make sure extern types are !Sync and !Send. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; extern "C" { type A; } -fn assert_sync<T: ?Sized + Sync>() {} -fn assert_send<T: ?Sized + Send>() {} +fn assert_sync<T: PointeeSized + Sync>() {} +fn assert_send<T: PointeeSized + Send>() {} fn main() { assert_sync::<A>(); diff --git a/tests/ui/extern/extern-types-not-sync-send.stderr b/tests/ui/extern/extern-types-not-sync-send.stderr index 7865ddeda34..56bdd5be7cf 100644 --- a/tests/ui/extern/extern-types-not-sync-send.stderr +++ b/tests/ui/extern/extern-types-not-sync-send.stderr @@ -1,28 +1,28 @@ error[E0277]: `A` cannot be shared between threads safely - --> $DIR/extern-types-not-sync-send.rs:13:19 + --> $DIR/extern-types-not-sync-send.rs:15:19 | LL | assert_sync::<A>(); | ^ `A` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `A` note: required by a bound in `assert_sync` - --> $DIR/extern-types-not-sync-send.rs:9:28 + --> $DIR/extern-types-not-sync-send.rs:11:34 | -LL | fn assert_sync<T: ?Sized + Sync>() {} - | ^^^^ required by this bound in `assert_sync` +LL | fn assert_sync<T: PointeeSized + Sync>() {} + | ^^^^ required by this bound in `assert_sync` error[E0277]: `A` cannot be sent between threads safely - --> $DIR/extern-types-not-sync-send.rs:16:19 + --> $DIR/extern-types-not-sync-send.rs:18:19 | LL | assert_send::<A>(); | ^ `A` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `A` note: required by a bound in `assert_send` - --> $DIR/extern-types-not-sync-send.rs:10:28 + --> $DIR/extern-types-not-sync-send.rs:12:34 | -LL | fn assert_send<T: ?Sized + Send>() {} - | ^^^^ required by this bound in `assert_send` +LL | fn assert_send<T: PointeeSized + Send>() {} + | ^^^^ required by this bound in `assert_send` error: aborting due to 2 previous errors diff --git a/tests/ui/extern/extern-types-pointer-cast.rs b/tests/ui/extern/extern-types-pointer-cast.rs index 78dbee77b9c..080ed91a632 100644 --- a/tests/ui/extern/extern-types-pointer-cast.rs +++ b/tests/ui/extern/extern-types-pointer-cast.rs @@ -2,7 +2,8 @@ #![allow(dead_code)] // Test that pointers to extern types can be cast from/to usize, // despite being !Sized. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; extern "C" { type A; @@ -13,7 +14,7 @@ struct Foo { tail: A, } -struct Bar<T: ?Sized> { +struct Bar<T: PointeeSized> { x: u8, tail: T, } diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index 399a5828ff3..3ff51b9b6b0 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,8 +1,4 @@ -//@ run-fail -//@ check-run-results -//@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" -//@ revisions: size align +//@ check-fail #![feature(extern_types)] use std::mem::{align_of_val, size_of_val}; @@ -14,10 +10,8 @@ extern "C" { fn main() { let x: &A = unsafe { &*(1usize as *const A) }; - // These don't have a dynamic size, so this should panic. - if cfg!(size) { - assert_eq!(size_of_val(x), 0); - } else { - assert_eq!(align_of_val(x), 1); - } + size_of_val(x); + //~^ ERROR the size for values of type `A` cannot be known + align_of_val(x); + //~^ ERROR the size for values of type `A` cannot be known } diff --git a/tests/ui/extern/extern-types-size_of_val.stderr b/tests/ui/extern/extern-types-size_of_val.stderr new file mode 100644 index 00000000000..8678c6c3d60 --- /dev/null +++ b/tests/ui/extern/extern-types-size_of_val.stderr @@ -0,0 +1,39 @@ +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-size_of_val.rs:13:17 + | +LL | size_of_val(x); + | ----------- ^ the trait `MetaSized` is not implemented for `A` + | | + | required by a bound introduced by this call + | + = note: the trait bound `A: MetaSized` is not satisfied +note: required by a bound in `std::mem::size_of_val` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | size_of_val(&x); + | + +LL | size_of_val(&mut x); + | ++++ + +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-size_of_val.rs:15:18 + | +LL | align_of_val(x); + | ------------ ^ the trait `MetaSized` is not implemented for `A` + | | + | required by a bound introduced by this call + | + = note: the trait bound `A: MetaSized` is not satisfied +note: required by a bound in `std::mem::align_of_val` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | align_of_val(&x); + | + +LL | align_of_val(&mut x); + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/extern-types-thin-pointer.rs b/tests/ui/extern/extern-types-thin-pointer.rs index 8e5911228b2..15777d456c2 100644 --- a/tests/ui/extern/extern-types-thin-pointer.rs +++ b/tests/ui/extern/extern-types-thin-pointer.rs @@ -2,8 +2,9 @@ #![allow(dead_code)] // Test that pointers and references to extern types are thin, ie they have the same size and // alignment as a pointer to (). -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::{align_of, size_of}; extern "C" { @@ -15,12 +16,12 @@ struct Foo { tail: A, } -struct Bar<T: ?Sized> { +struct Bar<T: PointeeSized> { x: u8, tail: T, } -fn assert_thin<T: ?Sized>() { +fn assert_thin<T: PointeeSized>() { assert_eq!(size_of::<*const T>(), size_of::<*const ()>()); assert_eq!(align_of::<*const T>(), align_of::<*const ()>()); diff --git a/tests/ui/extern/extern-types-trait-impl.rs b/tests/ui/extern/extern-types-trait-impl.rs index 44300b10514..07cb1efa801 100644 --- a/tests/ui/extern/extern-types-trait-impl.rs +++ b/tests/ui/extern/extern-types-trait-impl.rs @@ -1,13 +1,14 @@ //@ run-pass #![allow(dead_code)] // Test that traits can be implemented for extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; extern "C" { type A; } -trait Foo { +trait Foo: PointeeSized { fn foo(&self) {} } @@ -15,9 +16,9 @@ impl Foo for A { fn foo(&self) {} } -fn assert_foo<T: ?Sized + Foo>() {} +fn assert_foo<T: PointeeSized + Foo>() {} -fn use_foo<T: ?Sized + Foo>(x: &dyn Foo) { +fn use_foo<T: PointeeSized + Foo>(x: &dyn Foo) { x.foo(); } diff --git a/tests/ui/extern/extern-types-unsized.rs b/tests/ui/extern/extern-types-unsized.rs index 94a222a7e7e..46cdc24e083 100644 --- a/tests/ui/extern/extern-types-unsized.rs +++ b/tests/ui/extern/extern-types-unsized.rs @@ -27,7 +27,9 @@ fn main() { assert_sized::<Bar<A>>(); //~^ ERROR the size for values of type + //~| ERROR the size for values of type assert_sized::<Bar<Bar<A>>>(); //~^ ERROR the size for values of type + //~| ERROR the size for values of type } diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr index a587d4dda55..43dd9800d6d 100644 --- a/tests/ui/extern/extern-types-unsized.stderr +++ b/tests/ui/extern/extern-types-unsized.stderr @@ -59,8 +59,21 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-unsized.rs:28:20 + | +LL | assert_sized::<Bar<A>>(); + | ^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `A` +note: required by a bound in `Bar` + --> $DIR/extern-types-unsized.rs:14:12 + | +LL | struct Bar<T: ?Sized> { + | ^ required by this bound in `Bar` + error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:31:20 + --> $DIR/extern-types-unsized.rs:32:20 | LL | assert_sized::<Bar<Bar<A>>>(); | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ -error: aborting due to 4 previous errors +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-unsized.rs:32:20 + | +LL | assert_sized::<Bar<Bar<A>>>(); + | ^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `A` +note: required by a bound in `Bar` + --> $DIR/extern-types-unsized.rs:14:12 + | +LL | struct Bar<T: ?Sized> { + | ^ required by this bound in `Bar` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/unsized-extern-derefmove.rs b/tests/ui/extern/unsized-extern-derefmove.rs index 4ec9e53f49d..c02375266ab 100644 --- a/tests/ui/extern/unsized-extern-derefmove.rs +++ b/tests/ui/extern/unsized-extern-derefmove.rs @@ -1,15 +1,20 @@ -//! Regression test for #79409 - #![feature(extern_types)] -unsafe extern "C" { +// Regression test for #79409 + +extern "C" { type Device; } unsafe fn make_device() -> Box<Device> { +//~^ ERROR the size for values of type `Device` cannot be known Box::from_raw(0 as *mut _) +//~^ ERROR the size for values of type `Device` cannot be known +//~| ERROR the size for values of type `Device` cannot be known } fn main() { - let d: Device = unsafe { *make_device() }; //~ERROR the size for values of type `Device` cannot be known at compilation time + let d: Device = unsafe { *make_device() }; +//~^ ERROR the size for values of type `Device` cannot be known +//~| ERROR the size for values of type `Device` cannot be known } diff --git a/tests/ui/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr index c43184d94e1..d6be76a9d62 100644 --- a/tests/ui/extern/unsized-extern-derefmove.stderr +++ b/tests/ui/extern/unsized-extern-derefmove.stderr @@ -1,5 +1,43 @@ +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/unsized-extern-derefmove.rs:9:28 + | +LL | unsafe fn make_device() -> Box<Device> { + | ^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/unsized-extern-derefmove.rs:11:19 + | +LL | Box::from_raw(0 as *mut _) + | ------------- ^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Device` + | | + | required by a bound introduced by this call + | + = note: the trait bound `Device: MetaSized` is not satisfied +note: required by a bound in `Box::<T>::from_raw` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +help: consider borrowing here + | +LL | Box::from_raw(&0 as *mut _) + | + +LL | Box::from_raw(&mut 0 as *mut _) + | ++++ + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/unsized-extern-derefmove.rs:11:5 + | +LL | Box::from_raw(0 as *mut _) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + error[E0277]: the size for values of type `Device` cannot be known at compilation time - --> $DIR/unsized-extern-derefmove.rs:14:9 + --> $DIR/unsized-extern-derefmove.rs:17:9 | LL | let d: Device = unsafe { *make_device() }; | ^ doesn't have a size known at compile-time @@ -11,6 +49,16 @@ help: consider borrowing here LL | let d: &Device = unsafe { *make_device() }; | + -error: aborting due to 1 previous error +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/unsized-extern-derefmove.rs:17:31 + | +LL | let d: Device = unsafe { *make_device() }; + | ^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs new file mode 100644 index 00000000000..33688c2e2ce --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -0,0 +1,29 @@ +#![feature(extern_types)] +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn needs_pointeesized<T: PointeeSized>() {} +fn needs_metasized<T: MetaSized>() {} +fn needs_sized<T: Sized>() {} + +fn main() { + needs_pointeesized::<u8>(); + needs_metasized::<u8>(); + needs_sized::<u8>(); + + needs_pointeesized::<str>(); + needs_metasized::<str>(); + needs_sized::<str>(); +//~^ ERROR the size for values of type `str` cannot be known at compilation time + + extern "C" { + type Foo; + } + + needs_pointeesized::<Foo>(); + needs_metasized::<Foo>(); +//~^ ERROR the size for values of type `main::Foo` cannot be known + needs_sized::<Foo>(); +//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time +} diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr new file mode 100644 index 00000000000..6a35fcfb0e8 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -0,0 +1,42 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/feature-gate-sized-hierarchy.rs:17:19 + | +LL | needs_sized::<str>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by a bound in `needs_sized` + --> $DIR/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized<T: Sized>() {} + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/feature-gate-sized-hierarchy.rs:25:23 + | +LL | needs_metasized::<Foo>(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `main::Foo` +note: required by a bound in `needs_metasized` + --> $DIR/feature-gate-sized-hierarchy.rs:7:23 + | +LL | fn needs_metasized<T: MetaSized>() {} + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/feature-gate-sized-hierarchy.rs:27:19 + | +LL | needs_sized::<Foo>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by a bound in `needs_sized` + --> $DIR/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized<T: Sized>() {} + | ^^^^^ required by this bound in `needs_sized` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs index 2a39d579c51..bb23f9fe5c6 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs @@ -13,8 +13,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //[BADFLAGS]~? ERROR incorrect value `leaf` for unstable option `branch-protection` //[BADFLAGSPC]~? ERROR incorrect value `pc` for unstable option `branch-protection` diff --git a/tests/ui/lang-items/issue-83471.rs b/tests/ui/lang-items/issue-83471.rs index 6be345ac507..f3ce9f25c13 100644 --- a/tests/ui/lang-items/issue-83471.rs +++ b/tests/ui/lang-items/issue-83471.rs @@ -4,9 +4,17 @@ #![feature(no_core)] #![no_core] +#[lang = "pointee_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] //~^ ERROR: lang items are subject to change [E0658] -trait Sized {} +trait Sized: MetaSized {} #[lang = "fn"] //~^ ERROR: lang items are subject to change [E0658] diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 244b2efeaf1..e913c0bf10f 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found built-in attribute `export_name` - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ not a type @@ -7,6 +7,24 @@ LL | fn call(export_name); error[E0658]: lang items are subject to change --> $DIR/issue-83471.rs:7:1 | +LL | #[lang = "pointee_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: lang items are subject to change + --> $DIR/issue-83471.rs:11:1 + | +LL | #[lang = "meta_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: lang items are subject to change + --> $DIR/issue-83471.rs:15:1 + | LL | #[lang = "sized"] | ^^^^^^^^^^^^^^^^^ | @@ -14,7 +32,7 @@ LL | #[lang = "sized"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: lang items are subject to change - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -23,7 +41,7 @@ LL | #[lang = "fn"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: anonymous parameters are deprecated and will be removed in the next edition - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` @@ -33,7 +51,7 @@ LL | fn call(export_name); = note: `#[warn(anonymous_parameters)]` on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -42,12 +60,12 @@ LL | trait Fn { | - this trait has 0 generic arguments error[E0425]: cannot find function `a` in this scope - --> $DIR/issue-83471.rs:21:5 + --> $DIR/issue-83471.rs:29:5 | LL | a() | ^ not found in this scope -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted Some errors have detailed explanations: E0425, E0573, E0658, E0718. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/lang-items/issue-87573.rs b/tests/ui/lang-items/issue-87573.rs index 7b805e8b0cd..97146df0ba7 100644 --- a/tests/ui/lang-items/issue-87573.rs +++ b/tests/ui/lang-items/issue-87573.rs @@ -7,8 +7,14 @@ pub static STATIC_BOOL: bool = true; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/ui/lang-items/issue-87573.stderr b/tests/ui/lang-items/issue-87573.stderr index 7085bb8c339..07f4f5d8ac8 100644 --- a/tests/ui/lang-items/issue-87573.stderr +++ b/tests/ui/lang-items/issue-87573.stderr @@ -1,5 +1,5 @@ error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/issue-87573.rs:20:1 + --> $DIR/issue-87573.rs:26:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn drop_fn() { | - this function has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/issue-87573.rs:26:1 + --> $DIR/issue-87573.rs:32:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 25a4ff283ba..168e22ad7db 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -4,8 +4,14 @@ #![feature(lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +pub trait MyPointeeSized {} + +#[lang = "meta_sized"] +pub trait MyMetaSized: MyPointeeSized {} + #[lang = "sized"] -trait MySized {} +trait MySized: MyMetaSized {} #[lang = "add"] trait MyAdd<'a, T> {} diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index c82bdb00fd1..0b3088add61 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -1,5 +1,5 @@ error[E0718]: `add` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:10:1 + --> $DIR/lang-item-generic-requirements.rs:16:1 | LL | #[lang = "add"] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | trait MyAdd<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:14:1 + --> $DIR/lang-item-generic-requirements.rs:20:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | fn my_ptr_drop() {} | - this function has 0 generic arguments error[E0718]: `index` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:18:1 + --> $DIR/lang-item-generic-requirements.rs:24:1 | LL | #[lang = "index"] | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | trait MyIndex<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `phantom_data` lang item must be applied to a struct with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:22:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "phantom_data"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` lang item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:28:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:34:1 + --> $DIR/lang-item-generic-requirements.rs:40:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments error[E0392]: type parameter `T` is never used - --> $DIR/lang-item-generic-requirements.rs:24:22 + --> $DIR/lang-item-generic-requirements.rs:30:22 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -60,7 +60,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0392]: type parameter `U` is never used - --> $DIR/lang-item-generic-requirements.rs:24:25 + --> $DIR/lang-item-generic-requirements.rs:30:25 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -69,7 +69,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead error[E0369]: cannot add `{integer}` to `{integer}` - --> $DIR/lang-item-generic-requirements.rs:44:7 + --> $DIR/lang-item-generic-requirements.rs:50:7 | LL | r + a; | - ^ - {integer} @@ -77,13 +77,13 @@ LL | r + a; | {integer} error[E0608]: cannot index into a value of type `[{integer}; 5]` - --> $DIR/lang-item-generic-requirements.rs:52:16 + --> $DIR/lang-item-generic-requirements.rs:58:16 | LL | let _ = arr[2]; | ^^^ error[E0308]: mismatched types - --> $DIR/lang-item-generic-requirements.rs:59:17 + --> $DIR/lang-item-generic-requirements.rs:65:17 | LL | let _: () = Foo; | -- ^^^ expected `()`, found `Foo` @@ -91,7 +91,7 @@ LL | let _: () = Foo; | expected due to this error: requires `copy` lang_item - --> $DIR/lang-item-generic-requirements.rs:50:16 + --> $DIR/lang-item-generic-requirements.rs:56:16 | LL | let arr = [0; 5]; | ^ diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs index f92a00e602c..35d5d079c68 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs @@ -2,8 +2,14 @@ #![no_core] #![no_main] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized { } +trait Sized: MetaSized { } struct S; diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr index 9b25b1db292..7b9541f734f 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr @@ -1,5 +1,5 @@ error: requires `copy` lang_item - --> $DIR/missing-copy-lang-item-issue-19660.rs:12:5 + --> $DIR/missing-copy-lang-item-issue-19660.rs:18:5 | LL | argc | ^^^^ diff --git a/tests/ui/lang-items/start_lang_item_args.argc.stderr b/tests/ui/lang-items/start_lang_item_args.argc.stderr index cd7361255eb..82fd374a1c5 100644 --- a/tests/ui/lang-items/start_lang_item_args.argc.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argc.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:75:38 + --> $DIR/start_lang_item_args.rs:79:38 | LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^ expected `isize`, found `i8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv.stderr b/tests/ui/lang-items/start_lang_item_args.argv.stderr index 1a5905ab8e6..6095f8fa532 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:89:52 + --> $DIR/start_lang_item_args.rs:93:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize { | ^^ expected `*const *const u8`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr index c61ace3cd62..2a295c8990b 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:82:52 + --> $DIR/start_lang_item_args.rs:86:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^ expected `u8`, found `usize` diff --git a/tests/ui/lang-items/start_lang_item_args.main_args.stderr b/tests/ui/lang-items/start_lang_item_args.main_args.stderr index ef943d6b3db..027fd16d410 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:61:1 + --> $DIR/start_lang_item_args.rs:65:1 | LL | fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr index 00395a05d33..0f295d350d1 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:68:20 + --> $DIR/start_lang_item_args.rs:72:20 | LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | - ^^^^^^^^^^^ expected type parameter `T`, found `u16` diff --git a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr index 193f25bab05..6e462c8b1a7 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:54:20 + --> $DIR/start_lang_item_args.rs:58:20 | LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^ expected fn pointer, found `u64` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr index 56b787d2ae3..90fa5e0d575 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:15:1 + --> $DIR/start_lang_item_args.rs:19:1 | LL | fn start<T>() -> isize { | ^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr index 2672efe51c9..879917cc800 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:29:83 + --> $DIR/start_lang_item_args.rs:33:83 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} | ^ expected `isize`, found `()` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr index 98814dcd24a..d756909d735 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:22:1 + --> $DIR/start_lang_item_args.rs:26:1 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.rs b/tests/ui/lang-items/start_lang_item_args.rs index 5bb99e2adc8..1da761545a8 100644 --- a/tests/ui/lang-items/start_lang_item_args.rs +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -8,7 +8,11 @@ #[lang = "copy"] pub trait Copy {} #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[cfg(missing_all_args)] #[lang = "start"] diff --git a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr index e0a8496dba9..ba1dd4b4f79 100644 --- a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr +++ b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:96:80 + --> $DIR/start_lang_item_args.rs:100:80 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize { | ^^^ expected `u8`, found `i64` diff --git a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr index 4437b0fdcfb..a11867997d3 100644 --- a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:34:87 + --> $DIR/start_lang_item_args.rs:38:87 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 { | ^^ expected `isize`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr index 8570d96fc62..ecccf8c74bc 100644 --- a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:41:1 + --> $DIR/start_lang_item_args.rs:45:1 | LL | / fn start<T>( LL | | diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.rs b/tests/ui/lang-items/start_lang_item_with_target_feature.rs index 18cd4c97040..19036819d3d 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.rs +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.rs @@ -6,8 +6,15 @@ #[lang = "copy"] pub trait Copy {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "start"] #[target_feature(enable = "avx2")] diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr index 6214e3f8bc7..ce0b1d75574 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr @@ -1,5 +1,5 @@ error: `start` lang item function is not allowed to have `#[target_feature]` - --> $DIR/start_lang_item_with_target_feature.rs:13:1 + --> $DIR/start_lang_item_with_target_feature.rs:20:1 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index c9b1e0a4b9e..03b7e759960 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -15,4 +15,6 @@ impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained } #[rustc_layout(debug)] -struct S([u8; <u8 as A>::B]); //~ ERROR: the type has an unknown layout +struct S([u8; <u8 as A>::B]); +//~^ ERROR: the type has an unknown layout +//~| ERROR: type annotations needed diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 615c131eb90..82cd1217c49 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -4,12 +4,19 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self LL | impl<C: ?Sized> A for u8 { | ^ unconstrained type parameter +error[E0282]: type annotations needed + --> $DIR/unconstrained-param-ice-137308.rs:18:16 + | +LL | struct S([u8; <u8 as A>::B]); + | ^^ cannot infer type for type parameter `C` + error: the type has an unknown layout --> $DIR/unconstrained-param-ice-137308.rs:18:1 | LL | struct S([u8; <u8 as A>::B]); | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index c2fc345fa2b..76c6fc5e7b9 100644 --- a/tests/ui/nll/issue-50716.rs +++ b/tests/ui/nll/issue-50716.rs @@ -1,4 +1,3 @@ -// // Regression test for the issue #50716: NLL ignores lifetimes bounds // derived from `Sized` requirements @@ -6,7 +5,7 @@ trait A { type X: ?Sized; } -fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) +fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR where for<'b> &'b T: A, <&'static T as A>::X: Sized diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index a09e7670515..edd7fd765da 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -1,5 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/issue-50716.rs:8:27 + | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected trait `<<&'a T as A>::X as MetaSized>` + found trait `<<&'static T as A>::X as MetaSized>` +note: the lifetime `'a` as defined here... + --> $DIR/issue-50716.rs:8:8 + | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | ^^ + = note: ...does not necessarily outlive the static lifetime + error: lifetime may not live long enough - --> $DIR/issue-50716.rs:14:14 + --> $DIR/issue-50716.rs:13:14 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) | -- lifetime `'a` defined here @@ -7,5 +22,6 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) LL | let _x = *s; | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 2e0bdb151e1..575a66fe302 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,5 +1,6 @@ -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::offset_of; struct Alpha { @@ -26,7 +27,7 @@ struct Gamma { z: Extern, } -struct Delta<T: ?Sized> { +struct Delta<T: PointeeSized> { x: u8, y: u16, z: T, diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 714bf7a0266..0953e86e222 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:36:5 + --> $DIR/offset-of-dst-field.rs:37:5 | LL | offset_of!(Alpha, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,7 +8,7 @@ LL | offset_of!(Alpha, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:37:5 + --> $DIR/offset-of-dst-field.rs:38:5 | LL | offset_of!(Beta, z); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -17,7 +17,7 @@ LL | offset_of!(Beta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:38:5 + --> $DIR/offset-of-dst-field.rs:39:5 | LL | offset_of!(Gamma, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -26,7 +26,7 @@ LL | offset_of!(Gamma, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:40:5 + --> $DIR/offset-of-dst-field.rs:41:5 | LL | offset_of!((u8, dyn Trait), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -35,7 +35,7 @@ LL | offset_of!((u8, dyn Trait), 1); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:45:5 + --> $DIR/offset-of-dst-field.rs:46:5 | LL | offset_of!(Delta<Extern>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -44,7 +44,7 @@ LL | offset_of!(Delta<Extern>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:46:5 + --> $DIR/offset-of-dst-field.rs:47:5 | LL | offset_of!(Delta<dyn Trait>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,21 +53,21 @@ LL | offset_of!(Delta<dyn Trait>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:44:5 + --> $DIR/offset-of-dst-field.rs:45:5 | LL | offset_of!(Delta<Alpha>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `Alpha` - --> $DIR/offset-of-dst-field.rs:5:8 + --> $DIR/offset-of-dst-field.rs:6:8 | LL | struct Alpha { | ^^^^^ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:50:5 + --> $DIR/offset-of-dst-field.rs:51:5 | LL | fn generic_with_maybe_sized<T: ?Sized>() -> usize { | - this type parameter needs to be `Sized` @@ -82,7 +82,7 @@ LL + fn generic_with_maybe_sized<T>() -> usize { | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:54:16 + --> $DIR/offset-of-dst-field.rs:55:16 | LL | offset_of!(([u8], u8), 1); | ^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs index 0b8308ba753..618ac7d88dd 100644 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -11,5 +11,11 @@ fn panic() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 6cd12b80782..16aacd81289 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -1,8 +1,14 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang="sized"] -pub trait Sized {} +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 1f2f4a92c48..98750cee610 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -1,54 +1,54 @@ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:141:18 + --> $DIR/privacy1.rs:147:18 | LL | use bar::baz; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:165:20 + --> $DIR/privacy1.rs:171:20 | LL | use self::foo::i::A; | ^ private module | note: the module `i` is defined here - --> $DIR/privacy1.rs:170:9 + --> $DIR/privacy1.rs:176:9 | LL | mod i { | ^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:104:21 + --> $DIR/privacy1.rs:110:21 | LL | crate::bar::baz::A::foo(); | ^^^ - struct `A` is not publicly re-exported @@ -56,13 +56,13 @@ LL | crate::bar::baz::A::foo(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:105:21 + --> $DIR/privacy1.rs:111:21 | LL | crate::bar::baz::A::bar(); | ^^^ - struct `A` is not publicly re-exported @@ -70,13 +70,13 @@ LL | crate::bar::baz::A::bar(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:107:21 + --> $DIR/privacy1.rs:113:21 | LL | crate::bar::baz::A.foo2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -84,13 +84,13 @@ LL | crate::bar::baz::A.foo2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:108:21 + --> $DIR/privacy1.rs:114:21 | LL | crate::bar::baz::A.bar2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -98,13 +98,13 @@ LL | crate::bar::baz::A.bar2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:112:21 + --> $DIR/privacy1.rs:118:21 | LL | crate::bar::B::foo(); | ^ --- associated function `foo` is not publicly re-exported @@ -112,31 +112,31 @@ LL | crate::bar::B::foo(); | private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:40:5 + --> $DIR/privacy1.rs:46:5 | LL | trait B { | ^^^^^^^ error[E0603]: function `epriv` is private - --> $DIR/privacy1.rs:118:25 + --> $DIR/privacy1.rs:124:25 | LL | crate::bar::epriv(); | ^^^^^ private function | note: the function `epriv` is defined here - --> $DIR/privacy1.rs:65:9 + --> $DIR/privacy1.rs:71:9 | LL | fn epriv(); | ^^^^^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:127:21 + --> $DIR/privacy1.rs:133:21 | LL | crate::bar::baz::foo(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -147,13 +147,13 @@ LL + bar::foo(); | error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:128:21 + --> $DIR/privacy1.rs:134:21 | LL | crate::bar::baz::bar(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -164,19 +164,19 @@ LL + bar::bar(); | error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:157:22 + --> $DIR/privacy1.rs:163:22 | LL | impl crate::bar::B for f32 { fn foo() -> f32 { 1.0 } } | ^ private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:40:5 + --> $DIR/privacy1.rs:46:5 | LL | trait B { | ^^^^^^^ error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:77:23 + --> $DIR/privacy1.rs:83:23 | LL | fn bar() {} | -------- private associated function defined here @@ -185,7 +185,7 @@ LL | self::baz::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:95:13 + --> $DIR/privacy1.rs:101:13 | LL | fn bar() {} | -------- private associated function defined here @@ -194,7 +194,7 @@ LL | bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:102:24 + --> $DIR/privacy1.rs:108:24 | LL | fn bar() {} | -------- private associated function defined here @@ -203,7 +203,7 @@ LL | crate::bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:105:29 + --> $DIR/privacy1.rs:111:29 | LL | fn bar() {} | -------- private associated function defined here @@ -212,7 +212,7 @@ LL | crate::bar::baz::A::bar(); | ^^^ private associated function error[E0624]: method `bar2` is private - --> $DIR/privacy1.rs:108:28 + --> $DIR/privacy1.rs:114:28 | LL | fn bar2(&self) {} | -------------- private method defined here diff --git a/tests/ui/privacy/privacy4.rs b/tests/ui/privacy/privacy4.rs index 7341c7752bb..6091613271f 100644 --- a/tests/ui/privacy/privacy4.rs +++ b/tests/ui/privacy/privacy4.rs @@ -1,7 +1,9 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} +#[lang = "sized"] pub trait Sized: MetaSized {} +#[lang = "meta_sized"] pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} // Test to make sure that private items imported through globs remain private diff --git a/tests/ui/privacy/privacy4.stderr b/tests/ui/privacy/privacy4.stderr index 4aa3ae964c0..eeefd85645c 100644 --- a/tests/ui/privacy/privacy4.stderr +++ b/tests/ui/privacy/privacy4.stderr @@ -1,11 +1,11 @@ error[E0603]: module `glob` is private - --> $DIR/privacy4.rs:21:14 + --> $DIR/privacy4.rs:23:14 | LL | use bar::glob::gpriv; | ^^^^ private module | note: the module `glob` is defined here - --> $DIR/privacy4.rs:13:5 + --> $DIR/privacy4.rs:15:5 | LL | mod glob { | ^^^^^^^^ diff --git a/tests/ui/sized-hierarchy/alias-bounds.rs b/tests/ui/sized-hierarchy/alias-bounds.rs new file mode 100644 index 00000000000..87b4bab11b7 --- /dev/null +++ b/tests/ui/sized-hierarchy/alias-bounds.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PointeeSized, MetaSized}; + +trait Id: PointeeSized { + type This: PointeeSized; +} + +impl<T: PointeeSized> Id for T { + type This = T; +} + +fn requires_metasized<T: MetaSized>() {} + +fn foo<T>() +where + T: PointeeSized, + <T as Id>::This: Sized +{ + // `T: Sized` from where bounds (`T: PointeeSized` removes any default bounds and + // `<T as Id>::This: Sized` normalizes to `T: Sized`). This should trivially satisfy + // `T: MetaSized`. + requires_metasized::<T>(); +} diff --git a/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs new file mode 100644 index 00000000000..a7d18d90368 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs @@ -0,0 +1,19 @@ +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait SizedTr {} + +impl<T: Sized> SizedTr for T {} + +pub trait NegSizedTr {} + +impl<T: ?Sized> NegSizedTr for T {} + +pub trait MetaSizedTr {} + +impl<T: MetaSized> MetaSizedTr for T {} + +pub trait PointeeSizedTr: PointeeSized {} + +impl<T: PointeeSized> PointeeSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs b/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs new file mode 100644 index 00000000000..3314b0f356f --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs @@ -0,0 +1,7 @@ +pub trait SizedTr {} + +impl<T: Sized> SizedTr for T {} + +pub trait NegSizedTr {} + +impl<T: ?Sized> NegSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs new file mode 100644 index 00000000000..12b2eb2b5c1 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -0,0 +1,49 @@ +//@ check-fail +#![feature(extern_types, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn bare<T>() {} + + +fn sized<T: Sized>() {} + +fn neg_sized<T: ?Sized>() {} + + +fn metasized<T: MetaSized>() {} + +fn neg_metasized<T: ?MetaSized>() {} +//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + + +fn pointeesized<T: PointeeSized>() { } + +fn neg_pointeesized<T: ?PointeeSized>() { } +//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + + +fn main() { + // Functions which should have a `T: Sized` bound - check for an error given a non-Sized type: + + bare::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + sized::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + metasized::<[u8]>(); + pointeesized::<[u8]>(); + + // Functions which should have a `T: MetaSized` bound - check for an error given a + // non-MetaSized type: + unsafe extern "C" { + type Foo; + } + + bare::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + sized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + metasized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + pointeesized::<Foo>(); +} diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr new file mode 100644 index 00000000000..22f0fa29d3e --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -0,0 +1,88 @@ +error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/default-bound.rs:16:21 + | +LL | fn neg_metasized<T: ?MetaSized>() {} + | ^^^^^^^^^^ + +error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/default-bound.rs:22:24 + | +LL | fn neg_pointeesized<T: ?PointeeSized>() { } + | ^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/default-bound.rs:29:12 + | +LL | bare::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `bare` + --> $DIR/default-bound.rs:6:9 + | +LL | fn bare<T>() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `bare` +help: consider relaxing the implicit `Sized` restriction + | +LL | fn bare<T: ?Sized>() {} + | ++++++++ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/default-bound.rs:31:13 + | +LL | sized::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `sized` + --> $DIR/default-bound.rs:9:13 + | +LL | fn sized<T: Sized>() {} + | ^^^^^ required by this bound in `sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/default-bound.rs:42:12 + | +LL | bare::<Foo>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by an implicit `Sized` bound in `bare` + --> $DIR/default-bound.rs:6:9 + | +LL | fn bare<T>() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `bare` +help: consider relaxing the implicit `Sized` restriction + | +LL | fn bare<T: ?Sized>() {} + | ++++++++ + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/default-bound.rs:44:13 + | +LL | sized::<Foo>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by a bound in `sized` + --> $DIR/default-bound.rs:9:13 + | +LL | fn sized<T: Sized>() {} + | ^^^^^ required by this bound in `sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/default-bound.rs:46:17 + | +LL | metasized::<Foo>(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `main::Foo` +note: required by a bound in `metasized` + --> $DIR/default-bound.rs:14:17 + | +LL | fn metasized<T: MetaSized>() {} + | ^^^^^^^^^ required by this bound in `metasized` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs new file mode 100644 index 00000000000..b25acf9e6ea --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -0,0 +1,61 @@ +//@ check-fail +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +trait Sized_: Sized { } + +trait NegSized: ?Sized { } +//~^ ERROR `?Trait` is not permitted in supertraits + +trait MetaSized_: MetaSized { } + +trait NegMetaSized: ?MetaSized { } +//~^ ERROR `?Trait` is not permitted in supertraits + + +trait PointeeSized_: PointeeSized { } + +trait NegPointeeSized: ?PointeeSized { } +//~^ ERROR `?Trait` is not permitted in supertraits + +trait Bare {} + +fn requires_sized<T: Sized>() {} +fn requires_metasized<T: MetaSized>() {} +fn requires_pointeesized<T: PointeeSized>() {} + +fn with_sized_supertrait<T: PointeeSized + Sized_>() { + requires_sized::<T>(); + requires_metasized::<T>(); + requires_pointeesized::<T>(); +} + +fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() { + requires_sized::<T>(); + //~^ ERROR the size for values of type `T` cannot be known at compilation time + requires_metasized::<T>(); + requires_pointeesized::<T>(); +} + +// It isn't really possible to write this one.. +fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() { + requires_sized::<T>(); + //~^ ERROR the size for values of type `T` cannot be known + requires_metasized::<T>(); + //~^ ERROR the size for values of type `T` cannot be known + requires_pointeesized::<T>(); +} + +// `T` won't inherit the `const MetaSized` implicit supertrait of `Bare`, so there is an error on +// the bound, which is expected. +fn with_bare_trait<T: PointeeSized + Bare>() { +//~^ ERROR the size for values of type `T` cannot be known + requires_sized::<T>(); + //~^ ERROR the size for values of type `T` cannot be known + requires_metasized::<T>(); + //~^ ERROR the size for values of type `T` cannot be known + requires_pointeesized::<T>(); +} + +fn main() { } diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr new file mode 100644 index 00000000000..de23936b900 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -0,0 +1,125 @@ +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:8:17 + | +LL | trait NegSized: ?Sized { } + | ^^^^^^ + | + = note: traits are `?Sized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:13:21 + | +LL | trait NegMetaSized: ?MetaSized { } + | ^^^^^^^^^^ + | + = note: traits are `?MetaSized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:19:24 + | +LL | trait NegPointeeSized: ?PointeeSized { } + | ^^^^^^^^^^^^^ + | + = note: traits are `?PointeeSized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:52:38 + | +LL | fn with_bare_trait<T: PointeeSized + Bare>() { + | ^^^^ doesn't have a known size + | +note: required by a bound in `Bare` + --> $DIR/default-supertrait.rs:22:1 + | +LL | trait Bare {} + | ^^^^^^^^^^^^^ required by this bound in `Bare` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() { + | ++++++++++++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:35:22 + | +LL | fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() { + | - this type parameter needs to be `Sized` +LL | requires_sized::<T>(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:24:22 + | +LL | fn requires_sized<T: Sized>() {} + | ^^^^^ required by this bound in `requires_sized` + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:43:22 + | +LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() { + | - this type parameter needs to be `Sized` +LL | requires_sized::<T>(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:24:22 + | +LL | fn requires_sized<T: Sized>() {} + | ^^^^^ required by this bound in `requires_sized` + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:45:26 + | +LL | requires_metasized::<T>(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:25:26 + | +LL | fn requires_metasized<T: MetaSized>() {} + | ^^^^^^^^^ required by this bound in `requires_metasized` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::marker::MetaSized>() { + | ++++++++++++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:54:22 + | +LL | fn with_bare_trait<T: PointeeSized + Bare>() { + | - this type parameter needs to be `Sized` +LL | +LL | requires_sized::<T>(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:24:22 + | +LL | fn requires_sized<T: Sized>() {} + | ^^^^^ required by this bound in `requires_sized` + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:56:26 + | +LL | requires_metasized::<T>(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:25:26 + | +LL | fn requires_metasized<T: MetaSized>() {} + | ^^^^^^^^^ required by this bound in `requires_metasized` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() { + | ++++++++++++++++++++++++ + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0277, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs b/tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs new file mode 100644 index 00000000000..d59227beae8 --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PhantomData, MetaSized, PointeeSized}; + +struct Foo<'a, T: PointeeSized>(*mut &'a (), T); + +fn requires_metasized<'a, T: MetaSized>(f: &'a T) {} + +fn foo<'a, T: PointeeSized>(f: &Foo<'a, T>) +where + Foo<'a, T>: Sized +{ + requires_metasized(f); +} diff --git a/tests/ui/sized-hierarchy/elaboration-opt-regions.rs b/tests/ui/sized-hierarchy/elaboration-opt-regions.rs new file mode 100644 index 00000000000..66e600f3dc9 --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-opt-regions.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PhantomData, MetaSized, PointeeSized}; + +struct Foo<'a, T: PointeeSized>(PhantomData<&'a T>, T); + +fn requires_metasized<T: MetaSized>() {} + +fn foo<'a, T: 'a + PointeeSized>() +where + Foo<'a, T>: Sized +{ + requires_metasized::<Foo<'_, T>>(); +} diff --git a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs new file mode 100644 index 00000000000..70a84aabf2c --- /dev/null +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -0,0 +1,20 @@ +//@ check-pass +#![feature(extern_types, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub fn hash<T: PointeeSized>(_: *const T) { + unimplemented!(); +} + +unsafe extern "C" { + type Foo; +} + +fn get() -> *const Foo { + unimplemented!() +} + +fn main() { + hash::<Foo>(get()); +} diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs new file mode 100644 index 00000000000..46697e47c4b --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.rs @@ -0,0 +1,310 @@ +//@ check-fail +//@ edition: 2024 + +#![allow(incomplete_features, internal_features)] +#![feature(sized_hierarchy)] +#![feature(coroutines, dyn_star, extern_types, f16, never_type, unsized_fn_params)] + +use std::fmt::Debug; +use std::marker::{MetaSized, PointeeSized}; + +// This test checks that `Sized` and `MetaSized` are automatically implemented appropriately. + +fn needs_sized<T: Sized>() { } +fn takes_sized<T: Sized>(_t: T) { } + +fn needs_metasized<T: MetaSized>() { } +fn takes_metasized<T: MetaSized>(_t: T) { } + +fn needs_pointeesized<T: PointeeSized>() { } +fn takes_pointeesized<T: PointeeSized>(_t: T) { } + +fn main() { + // `bool` + needs_sized::<bool>(); + needs_metasized::<bool>(); + needs_pointeesized::<bool>(); + + // `char` + needs_sized::<char>(); + needs_metasized::<char>(); + needs_pointeesized::<char>(); + + // `i8` + needs_sized::<i8>(); + needs_metasized::<i8>(); + needs_pointeesized::<i8>(); + + // `i16` + needs_sized::<i16>(); + needs_metasized::<i16>(); + needs_pointeesized::<i16>(); + + // `i32` + needs_sized::<i32>(); + needs_metasized::<i32>(); + needs_pointeesized::<i32>(); + + // `i64` + needs_sized::<i64>(); + needs_metasized::<i64>(); + needs_pointeesized::<i64>(); + + // `i128` + needs_sized::<i128>(); + needs_metasized::<i128>(); + needs_pointeesized::<i128>(); + + // `u8` + needs_sized::<u8>(); + needs_metasized::<u8>(); + needs_pointeesized::<u8>(); + + // `u16` + needs_sized::<u16>(); + needs_metasized::<u16>(); + needs_pointeesized::<u16>(); + + // `u32` + needs_sized::<u32>(); + needs_metasized::<u32>(); + needs_pointeesized::<u32>(); + + // `u64` + needs_sized::<u64>(); + needs_metasized::<u64>(); + needs_pointeesized::<u64>(); + + // `u128` + needs_sized::<u128>(); + needs_metasized::<u128>(); + needs_pointeesized::<u128>(); + + // `f16` + needs_sized::<f16>(); + needs_metasized::<f16>(); + needs_pointeesized::<f16>(); + + // `f32` + needs_sized::<f32>(); + needs_metasized::<f32>(); + needs_pointeesized::<f32>(); + + // `f64` + needs_sized::<f64>(); + needs_metasized::<f64>(); + needs_pointeesized::<f64>(); + + // `*const` + needs_sized::<*const u8>(); + needs_metasized::<*const u8>(); + needs_pointeesized::<*const u8>(); + + // `*mut` + needs_sized::<*mut u8>(); + needs_metasized::<*mut u8>(); + needs_pointeesized::<*mut u8>(); + + // `&` + needs_sized::<&u8>(); + needs_metasized::<&u8>(); + needs_pointeesized::<&u8>(); + + // `&mut` + needs_sized::<&mut u8>(); + needs_metasized::<&mut u8>(); + needs_pointeesized::<&mut u8>(); + + // fn-def + fn foo(x: u8) -> u8 { x } + takes_sized(foo); + takes_metasized(foo); + takes_pointeesized(foo); + + // fn-ptr + takes_sized::<fn(u8) -> u8>(foo); + takes_metasized::<fn(u8) -> u8>(foo); + takes_pointeesized::<fn(u8) -> u8>(foo); + + // `[T; x]` + needs_sized::<[u8; 1]>(); + needs_metasized::<[u8; 1]>(); + needs_pointeesized::<[u8; 1]>(); + + // `|a| { a }` + takes_sized(|a| { a }); + takes_metasized(|a| { a }); + takes_pointeesized(|a| { a }); + + // `async |a| { a }` + takes_sized(async |a| { a }); + takes_metasized(async |a| { a }); + takes_pointeesized(async |a| { a }); + + // `|a| { yield a }` + takes_sized(#[coroutine] |a| { yield a }); + takes_metasized(#[coroutine] |a| { yield a }); + takes_pointeesized(#[coroutine] |a| { yield a }); + + // `!` + needs_sized::<!>(); + needs_metasized::<!>(); + needs_pointeesized::<!>(); + + // `dyn*` + needs_sized::<dyn* Debug>(); + needs_metasized::<dyn* Debug>(); + needs_pointeesized::<dyn* Debug>(); + + // `str` + needs_sized::<str>(); + //~^ ERROR the size for values of type `str` cannot be known at compilation time + needs_metasized::<str>(); + needs_pointeesized::<str>(); + + // `[T]` + needs_sized::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<[u8]>(); + needs_pointeesized::<[u8]>(); + + // `dyn Debug` + needs_sized::<dyn Debug>(); + //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time + needs_metasized::<dyn Debug>(); + needs_pointeesized::<dyn Debug>(); + + // `extern type` + unsafe extern "C" { + type Foo; + } + needs_sized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<Foo>(); + + // empty tuple + needs_sized::<()>(); + needs_metasized::<()>(); + needs_pointeesized::<()>(); + + // tuple w/ all elements sized + needs_sized::<(u32, u32)>(); + needs_metasized::<(u32, u32)>(); + needs_pointeesized::<(u32, u32)>(); + + // tuple w/ all elements metasized + needs_sized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_pointeesized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + // tuple w/ all elements pointeesized + needs_sized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + //~| ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + + // tuple w/ last element metasized + needs_sized::<(u32, [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<(u32, [u8])>(); + needs_pointeesized::<(u32, [u8])>(); + + // tuple w/ last element pointeesized + needs_sized::<(u32, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<(u32, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<(u32, Foo)>(); + + // struct w/ no fields + struct StructEmpty {} + needs_sized::<StructEmpty>(); + needs_metasized::<StructEmpty>(); + needs_pointeesized::<StructEmpty>(); + + // struct w/ all fields sized + struct StructAllFieldsSized { x: u32, y: u32 } + needs_sized::<StructAllFieldsSized>(); + needs_metasized::<StructAllFieldsSized>(); + needs_pointeesized::<StructAllFieldsSized>(); + + // struct w/ all fields metasized + struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<StructAllFieldsMetaSized>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<StructAllFieldsMetaSized>(); + needs_pointeesized::<StructAllFieldsMetaSized>(); + + // struct w/ all fields unsized + struct StructAllFieldsUnsized { x: Foo, y: Foo } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<StructAllFieldsUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<StructAllFieldsUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<StructAllFieldsUnsized>(); + + // struct w/ last fields metasized + struct StructLastFieldMetaSized { x: u32, y: [u8] } + needs_sized::<StructLastFieldMetaSized>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<StructLastFieldMetaSized>(); + needs_pointeesized::<StructLastFieldMetaSized>(); + + // struct w/ last fields unsized + struct StructLastFieldUnsized { x: u32, y: Foo } + needs_sized::<StructLastFieldUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<StructLastFieldUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<StructLastFieldUnsized>(); + + // enum w/ no fields + enum EnumEmpty {} + needs_sized::<EnumEmpty>(); + needs_metasized::<EnumEmpty>(); + needs_pointeesized::<EnumEmpty>(); + + // enum w/ all variant fields sized + enum EnumAllFieldsSized { Qux { x: u32, y: u32 } } + needs_sized::<StructAllFieldsSized>(); + needs_metasized::<StructAllFieldsSized>(); + needs_pointeesized::<StructAllFieldsSized>(); + + // enum w/ all variant fields metasized + enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<EnumAllFieldsMetaSized>(); + needs_metasized::<EnumAllFieldsMetaSized>(); + needs_pointeesized::<EnumAllFieldsMetaSized>(); + + // enum w/ all variant fields unsized + enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<EnumAllFieldsUnsized>(); + needs_metasized::<EnumAllFieldsUnsized>(); + needs_pointeesized::<EnumAllFieldsUnsized>(); + + // enum w/ last variant fields metasized + enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<EnumLastFieldMetaSized>(); + needs_metasized::<EnumLastFieldMetaSized>(); + needs_pointeesized::<EnumLastFieldMetaSized>(); + + // enum w/ last variant fields unsized + enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<EnumLastFieldUnsized>(); + needs_metasized::<EnumLastFieldUnsized>(); + needs_pointeesized::<EnumLastFieldUnsized>(); +} diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr new file mode 100644 index 00000000000..eebe4e0d706 --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -0,0 +1,394 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:240:42 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsMetaSized { x: &[u8], y: [u8] } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:248:40 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsUnsized { x: &Foo, y: Foo } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | struct StructAllFieldsUnsized { x: Box<Foo>, y: Foo } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:284:44 + | +LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsMetaSized { Qux { x: &[u8], y: [u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:291:42 + | +LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsUnsized { Qux { x: &Foo, y: Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumAllFieldsUnsized { Qux { x: Box<Foo>, y: Foo } } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:298:52 + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: &[u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:305:50 + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: &Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Box<Foo> } } + | ++++ + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/impls.rs:160:19 + | +LL | needs_sized::<str>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:166:19 + | +LL | needs_sized::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/impls.rs:172:19 + | +LL | needs_sized::<dyn Debug>(); + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:181:19 + | +LL | needs_sized::<Foo>(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:183:23 + | +LL | needs_metasized::<Foo>(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `main::Foo` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized<T: MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:198:19 + | +LL | needs_sized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:200:23 + | +LL | needs_metasized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:202:26 + | +LL | needs_pointeesized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:206:19 + | +LL | needs_sized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:208:23 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:208:23 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = note: required because it appears within the type `(main::Foo, main::Foo)` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized<T: MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:211:26 + | +LL | needs_pointeesized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:215:19 + | +LL | needs_sized::<(u32, [u8])>(); + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(u32, [u8])`, the trait `Sized` is not implemented for `[u8]` + = note: required because it appears within the type `(u32, [u8])` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:221:19 + | +LL | needs_sized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(u32, main::Foo)`, the trait `Sized` is not implemented for `main::Foo` + = note: required because it appears within the type `(u32, main::Foo)` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:223:23 + | +LL | needs_metasized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = note: required because it appears within the type `(u32, main::Foo)` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized<T: MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:242:19 + | +LL | needs_sized::<StructAllFieldsMetaSized>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `StructAllFieldsMetaSized` + --> $DIR/impls.rs:240:12 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:250:19 + | +LL | needs_sized::<StructAllFieldsUnsized>(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo` +note: required because it appears within the type `StructAllFieldsUnsized` + --> $DIR/impls.rs:248:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:252:23 + | +LL | needs_metasized::<StructAllFieldsUnsized>(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo` +note: required because it appears within the type `StructAllFieldsUnsized` + --> $DIR/impls.rs:248:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized<T: MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:258:19 + | +LL | needs_sized::<StructLastFieldMetaSized>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `StructLastFieldMetaSized` + --> $DIR/impls.rs:257:12 + | +LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:265:19 + | +LL | needs_sized::<StructLastFieldUnsized>(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo` +note: required because it appears within the type `StructLastFieldUnsized` + --> $DIR/impls.rs:264:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized<T: Sized>() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:267:23 + | +LL | needs_metasized::<StructLastFieldUnsized>(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo` +note: required because it appears within the type `StructLastFieldUnsized` + --> $DIR/impls.rs:264:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized<T: MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error: aborting due to 27 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/overflow.current.stderr b/tests/ui/sized-hierarchy/overflow.current.stderr new file mode 100644 index 00000000000..e90548aa78c --- /dev/null +++ b/tests/ui/sized-hierarchy/overflow.current.stderr @@ -0,0 +1,45 @@ +error[E0275]: overflow evaluating the requirement `Element: MetaSized` + --> $DIR/overflow.rs:16:16 + | +LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required for `Box<Element>` to implement `ParseTokens` + --> $DIR/overflow.rs:12:31 + | +LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { + | - ^^^^^^^^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here + = note: 1 redundant requirement hidden + = note: required for `Box<Box<Element>>` to implement `ParseTokens` + +error[E0275]: overflow evaluating the requirement `Box<Element>: ParseTokens` + --> $DIR/overflow.rs:18:22 + | +LL | impl ParseTokens for Element { + | ^^^^^^^ + | +note: required for `Box<Box<Element>>` to implement `ParseTokens` + --> $DIR/overflow.rs:12:31 + | +LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { + | ----------- ^^^^^^^^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here +note: required because it appears within the type `Element` + --> $DIR/overflow.rs:16:8 + | +LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output); + | ^^^^^^^ +note: required by a bound in `ParseTokens` + --> $DIR/overflow.rs:9:1 + | +LL | / trait ParseTokens { +LL | | type Output; +LL | | } + | |_^ required by this bound in `ParseTokens` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/sized-hierarchy/overflow.rs b/tests/ui/sized-hierarchy/overflow.rs new file mode 100644 index 00000000000..e1af4885e53 --- /dev/null +++ b/tests/ui/sized-hierarchy/overflow.rs @@ -0,0 +1,21 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] check-pass +//@[next] compile-flags: -Znext-solver + +use std::marker::PhantomData; + +trait ParseTokens { + type Output; +} +impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { + type Output = (); +} + +struct Element(<Box<Box<Element>> as ParseTokens>::Output); +//[current]~^ ERROR overflow evaluating +impl ParseTokens for Element { +//[current]~^ ERROR overflow evaluating + type Output = (); +} diff --git a/tests/ui/sized-hierarchy/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs new file mode 100644 index 00000000000..4bf486890bf --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs @@ -0,0 +1,28 @@ +//@ check-pass +#![feature(sized_hierarchy)] + +// This is a reduction of some code in `library/core/src/cmp.rs` that would ICE if a default +// `Pointee` bound is added - motivating the current status quo of `PointeeSized` being syntactic +// sugar for an absense of any bounds whatsoever. + +use std::marker::PhantomData; + +pub trait Bar<'a> { + type Foo; +} + +pub struct Foo<'a, T: Bar<'a>> { + phantom: PhantomData<&'a T>, +} + +impl<'a, 'b, T> PartialEq<Foo<'b, T>> for Foo<'a, T> + where + T: for<'c> Bar<'c>, + <T as Bar<'a>>::Foo: PartialEq<<T as Bar<'b>>::Foo>, +{ + fn eq(&self, _: &Foo<'b, T>) -> bool { + loop {} + } +} + +fn main() { } diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs new file mode 100644 index 00000000000..0412ff651ce --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -0,0 +1,26 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, NegSizedTr, MetaSizedTr, PointeeSizedTr}; + +// Test that printing the sizedness trait bounds in the conflicting impl error without enabling +// `sized_hierarchy` will continue to print `?Sized`, even if the dependency is compiled with +// `sized_hierarchy`. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl<T: ?Sized> MetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl<T: ?Sized> PointeeSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr new file mode 100644 index 00000000000..cb9bfd178f8 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr @@ -0,0 +1,42 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:16:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:19:1 + | +LL | impl<T: ?Sized> NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + | +LL | impl<T: ?Sized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + | +LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: ?Sized; + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat.rs new file mode 100644 index 00000000000..d5800be5828 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat.rs @@ -0,0 +1,19 @@ +//@ aux-build:pretty-print-no-feat-dep.rs +//@ compile-flags: --crate-type=lib + +extern crate pretty_print_no_feat_dep; +use pretty_print_no_feat_dep::{SizedTr, NegSizedTr}; + +// Test that printing the sizedness trait bounds in the conflicting impl error without enabling +// `sized_hierarchy` will continue to print `?Sized`. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr new file mode 100644 index 00000000000..1d50f0145fe --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr @@ -0,0 +1,22 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat.rs:15:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat.rs:18:1 + | +LL | impl<T: ?Sized> NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl<T> NegSizedTr for T + where T: ?Sized; + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs new file mode 100644 index 00000000000..955108a2074 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --crate-type=lib + +pub trait Tr {} +impl Tr for u32 {} + +pub fn foo() -> Box<impl Tr + ?Sized> { + if true { + let x = foo(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + ?Sized` cannot be known + } + Box::new(1u32) +} diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr new file mode 100644 index 00000000000..bbe19870937 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `impl Tr + ?Sized` cannot be known at compilation time + --> $DIR/pretty-print-opaque-no-feat.rs:9:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + ?Sized` + = note: required for the cast from `Box<impl Tr + ?Sized>` to `Box<dyn Tr>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs new file mode 100644 index 00000000000..2aceee23a01 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -0,0 +1,45 @@ +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait Tr: PointeeSized {} +impl Tr for u32 {} + +pub fn sized() -> Box<impl Tr + Sized> { + if true { + let x = sized(); + let y: Box<dyn Tr> = x; + } + Box::new(1u32) +} + +pub fn neg_sized() -> Box<impl Tr + ?Sized> { + if true { + let x = neg_sized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn metasized() -> Box<impl Tr + MetaSized> { + if true { + let x = metasized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn pointeesized() -> Box<impl Tr + PointeeSized> { +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + if true { + let x = pointeesized(); +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known +//~| ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + } + Box::new(1u32) +} diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr new file mode 100644 index 00000000000..ecf4d912be8 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -0,0 +1,59 @@ +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:35:26 + | +LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:20:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:29:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:38:17 + | +LL | let x = pointeesized(); + | ^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:40:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + PointeeSized` + = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:40:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` + = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs new file mode 100644 index 00000000000..0908e76490c --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -0,0 +1,28 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +// Test that printing the sizedness trait bounds in the conflicting impl error with +// `sized_hierarchy` enabled prints all of the appropriate bounds. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +use std::marker::{MetaSized, PointeeSized}; + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, MetaSizedTr, PointeeSizedTr}; + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl<T: MetaSized> MetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl<T: PointeeSized> PointeeSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print.stderr b/tests/ui/sized-hierarchy/pretty-print.stderr new file mode 100644 index 00000000000..3602c804945 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.stderr @@ -0,0 +1,43 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:18:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T + where T: Sized; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:21:1 + | +LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:24:1 + | +LL | impl<T: MetaSized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:27:1 + | +LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: PointeeSized; + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/trait-aliases.rs b/tests/ui/sized-hierarchy/trait-aliases.rs new file mode 100644 index 00000000000..ffec302adaa --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-aliases.rs @@ -0,0 +1,9 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(trait_alias)] + +// Checks that `?Sized` in a trait alias doesn't trigger an ICE. + +use std::ops::{Index, IndexMut}; + +pub trait SlicePrereq<T> = ?Sized + IndexMut<usize, Output = <[T] as Index<usize>>::Output>; diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index dc61e35a089..a635976c842 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -11,8 +11,15 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} diff --git a/tests/ui/symbol-names/foreign-types.rs b/tests/ui/symbol-names/foreign-types.rs index 2a9aadfcb83..b863e8c1759 100644 --- a/tests/ui/symbol-names/foreign-types.rs +++ b/tests/ui/symbol-names/foreign-types.rs @@ -2,13 +2,16 @@ //@ compile-flags: -C symbol-mangling-version=v0 #![feature(extern_types)] +#![feature(sized_hierarchy)] #![feature(rustc_attrs)] +use std::marker::PointeeSized; + extern "C" { type ForeignType; } -struct Check<T: ?Sized>(T); +struct Check<T: PointeeSized>(T); #[rustc_symbol_name] //~^ ERROR symbol-name(_RMCs diff --git a/tests/ui/symbol-names/foreign-types.stderr b/tests/ui/symbol-names/foreign-types.stderr index 63044991485..4640ceae811 100644 --- a/tests/ui/symbol-names/foreign-types.stderr +++ b/tests/ui/symbol-names/foreign-types.stderr @@ -1,17 +1,17 @@ error: symbol-name(_RMCsCRATE_HASH_13foreign_typesINtB<REF>_5CheckNtB<REF>_11ForeignTypeE) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<foreign_types[fcdd87e190ad88e3]::Check<foreign_types[fcdd87e190ad88e3]::ForeignType>>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<foreign_types::Check<foreign_types::ForeignType>>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-cpu/explicit-target-cpu.rs b/tests/ui/target-cpu/explicit-target-cpu.rs index cd4c2384bc1..e4ae73b513b 100644 --- a/tests/ui/target-cpu/explicit-target-cpu.rs +++ b/tests/ui/target-cpu/explicit-target-cpu.rs @@ -29,6 +29,12 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang="sized"] trait Sized {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs index 270874a9f58..41d5de89ae6 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs @@ -5,8 +5,14 @@ #![no_core] #![deny(aarch64_softfloat_neon)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "neon")] //~^ERROR: enabling the `neon` target feature on the current target is unsound diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr index bf745291a5a..a8a7063daeb 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr @@ -1,5 +1,5 @@ error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:17:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:17:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr index 49c5479275f..1b9b8e0a789 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/abi-incompatible-target-feature-attribute.rs:15:90 + --> $DIR/abi-incompatible-target-feature-attribute.rs:21:90 | LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs index a8733440759..c07b6c448e9 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs @@ -9,6 +9,12 @@ #![feature(no_core, lang_items, riscv_target_feature, x87_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr index 81471fd7e30..e1409497232 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr @@ -1,5 +1,5 @@ error: target feature `soft-float` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/abi-incompatible-target-feature-attribute.rs:15:32 + --> $DIR/abi-incompatible-target-feature-attribute.rs:21:32 | LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index 68e1d3b9ddc..302cceccf69 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -11,6 +11,12 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} #[lang = "freeze"] diff --git a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs index 0013d033b9c..876134002ed 100644 --- a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN unstable feature specified for `-Ctarget-feature`: `x87` diff --git a/tests/ui/target-feature/abi-required-target-feature-attribute.rs b/tests/ui/target-feature/abi-required-target-feature-attribute.rs index 95723c57f94..5eb9e85f85f 100644 --- a/tests/ui/target-feature/abi-required-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-required-target-feature-attribute.rs @@ -6,8 +6,14 @@ #![feature(no_core, lang_items, x87_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "x87")] pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs index 98723e99c36..89736afe718 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs @@ -20,6 +20,12 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 315ec983a19..ccf32a35f72 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -12,10 +12,18 @@ // Tests vetting "feature hierarchies" in the cases where we impose them. // Supporting minimal rust core code +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} + impl Copy for bool {} #[stable(feature = "test", since = "1.0.0")] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs index 215e64979f7..e96e17a4212 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "d")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr index 84d27463b38..9406c3bbfdc 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute-e-d.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute-e-d.rs:16:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs index d74f4a1d4b1..70075b1bb78 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs @@ -4,6 +4,12 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr index af0e53f34f2..8c98d847e17 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr @@ -1,5 +1,5 @@ error: target feature `zfinx` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs:16:18 | LL | #[target_feature(enable = "zdinx")] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs new file mode 100644 index 00000000000..2692cf802f2 --- /dev/null +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs @@ -0,0 +1,20 @@ +//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib +//@ needs-llvm-components: x86 +//@ check-pass +#![feature(no_core, lang_items)] +#![no_core] +#![allow(unexpected_cfgs)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this +// complains about the missing macro rather than showing the error... but that's good enough. +#[cfg(not(target_feature = "x87"))] +compile_error!("the x87 feature *should* be exposed in `cfg`"); diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index 6bb6f8aaffb..a59747ec80f 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "forced-atomics")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr index f8ea0c0e793..65814e8edcf 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `forced-atomics` cannot be enabled with `#[target_feature]`: unsound because it changes the ABI of atomic operations - --> $DIR/forbidden-target-feature-attribute.rs:10:18 + --> $DIR/forbidden-target-feature-attribute.rs:16:18 | LL | #[target_feature(enable = "forced-atomics")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs index e848ffde018..c21eb63257a 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -6,8 +6,14 @@ #![no_core] #![allow(unexpected_cfgs)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} // The compile_error macro does not exist, so if the `cfg` evaluates to `true` this // complains about the missing macro rather than showing the error... but that's good enough. diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs index d394dbe7b15..4d4d833caab 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `forced-atomics` cannot be disabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index a04d7e34753..6e3e60e0409 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `forced-atomics` cannot be enabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs index be6cd2b6faf..fcb8c382741 100644 --- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs +++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs @@ -7,7 +7,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index ce1dc3224a1..e9de4561ced 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -14,8 +14,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} fn main() {} diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 63a1d77dae9..6c6e9e06b6e 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -6,8 +6,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // In this test, demonstrate that +paca and +pacg both result in the tied feature error if there // isn't something causing an error. diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr index 4ff42d31e94..8b034c098d0 100644 --- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr +++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `foo` is defined multiple times - --> $DIR/tied-features-no-implication.rs:27:1 + --> $DIR/tied-features-no-implication.rs:33:1 | LL | fn foo() {} | -------- previous definition of the value `foo` here diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 1625f71431a..5e38d5329f3 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -7,8 +7,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // Can't use `compile_error!` here without `core`/`std` but requiring these makes this test only // work if you have libcore built in the sysroot for `aarch64-unknown-linux-gnu`. Can't run this diff --git a/tests/ui/traits/cache-reached-depth-ice.rs b/tests/ui/traits/cache-reached-depth-ice.rs index 8c2391113d7..bc62adf4842 100644 --- a/tests/ui/traits/cache-reached-depth-ice.rs +++ b/tests/ui/traits/cache-reached-depth-ice.rs @@ -1,4 +1,5 @@ -#![feature(rustc_attrs)] +#![feature(rustc_attrs, sized_hierarchy)] +use std::marker::PointeeSized; // Test for a particular corner case where the evaluation // cache can get out of date. The problem here is that @@ -37,7 +38,7 @@ struct C { } #[rustc_evaluate_where_clauses] -fn test<X: ?Sized + Send>() {} +fn test<X: PointeeSized + Send>() {} fn main() { test::<A>(); diff --git a/tests/ui/traits/cache-reached-depth-ice.stderr b/tests/ui/traits/cache-reached-depth-ice.stderr index e84ebc91ae1..fd76dc92dfb 100644 --- a/tests/ui/traits/cache-reached-depth-ice.stderr +++ b/tests/ui/traits/cache-reached-depth-ice.stderr @@ -1,8 +1,8 @@ error: evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) - --> $DIR/cache-reached-depth-ice.rs:43:5 + --> $DIR/cache-reached-depth-ice.rs:44:5 | -LL | fn test<X: ?Sized + Send>() {} - | ---- predicate +LL | fn test<X: PointeeSized + Send>() {} + | ---- predicate ... LL | test::<A>(); | ^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 08d7817548d..073337b2ac6 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -12,20 +12,27 @@ fundamental, marker_trait_attr, const_trait_impl, - const_destruct + const_destruct, )] #![allow(internal_features, incomplete_features)] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} + #[lang = "copy"] pub trait Copy {} impl Copy for bool {} impl Copy for u8 {} -impl<T: ?Sized> Copy for &T {} +impl<T: PointeeSized> Copy for &T {} #[lang = "add"] #[const_trait] @@ -106,17 +113,17 @@ pub trait Tuple {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} #[lang = "receiver"] pub trait Receiver { #[lang = "receiver_target"] - type Target: ?Sized; + type Target: MetaSized; } -impl<T: Deref + ?Sized> Receiver for T { +impl<T: Deref + MetaSized> Receiver for T { type Target = <T as Deref>::Target; } @@ -162,15 +169,15 @@ fn panic_fmt() {} #[lang = "index"] #[const_trait] -pub trait Index<Idx: ?Sized> { - type Output: ?Sized; +pub trait Index<Idx: PointeeSized> { + type Output: MetaSized; fn index(&self, index: Idx) -> &Self::Output; } #[const_trait] -pub unsafe trait SliceIndex<T: ?Sized> { - type Output: ?Sized; +pub unsafe trait SliceIndex<T: PointeeSized> { + type Output: MetaSized; fn index(self, slice: &T) -> &Self::Output; } @@ -199,23 +206,23 @@ where } #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> {} +pub trait CoerceUnsized<T: PointeeSized> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} #[lang = "deref"] #[const_trait] pub trait Deref { #[lang = "deref_target"] - type Target: ?Sized; + type Target: MetaSized; fn deref(&self) -> &Self::Target; } -impl<T: ?Sized> const Deref for &T { +impl<T: MetaSized> const Deref for &T { type Target = T; fn deref(&self) -> &T { @@ -223,7 +230,7 @@ impl<T: ?Sized> const Deref for &T { } } -impl<T: ?Sized> const Deref for &mut T { +impl<T: MetaSized> const Deref for &mut T { type Target = T; fn deref(&self) -> &T { @@ -307,14 +314,14 @@ fn from_str(s: &str) -> Result<bool, ()> { #[lang = "eq"] #[const_trait] -pub trait PartialEq<Rhs: ?Sized = Self> { +pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } } -impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A +impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A where A: ~const PartialEq<B>, { @@ -357,7 +364,7 @@ impl<P> Pin<P> { } } -impl<'a, T: ?Sized> Pin<&'a T> { +impl<'a, T: PointeeSized> Pin<&'a T> { const fn get_ref(self) -> &'a T { self.pointer } @@ -372,7 +379,7 @@ impl<P: Deref> Pin<P> { } } -impl<'a, T: ?Sized> Pin<&'a mut T> { +impl<'a, T: PointeeSized> Pin<&'a mut T> { const unsafe fn get_unchecked_mut(self) -> &'a mut T { self.pointer } @@ -418,7 +425,7 @@ impl<T: Clone> Clone for RefCell<T> { } } -struct RefCell<T: ?Sized> { +struct RefCell<T: PointeeSized> { borrow: UnsafeCell<()>, value: UnsafeCell<T>, } @@ -427,7 +434,7 @@ impl<T> RefCell<T> { loop {} } } -impl<T: ?Sized> RefCell<T> { +impl<T: PointeeSized> RefCell<T> { fn borrow(&self) -> Ref<'_, T> { loop {} } @@ -435,16 +442,16 @@ impl<T: ?Sized> RefCell<T> { #[lang = "unsafe_cell"] #[repr(transparent)] -struct UnsafeCell<T: ?Sized> { +struct UnsafeCell<T: PointeeSized> { value: T, } -struct Ref<'b, T: ?Sized + 'b> { +struct Ref<'b, T: PointeeSized + 'b> { value: *const T, borrow: &'b UnsafeCell<()>, } -impl<T: ?Sized> Deref for Ref<'_, T> { +impl<T: MetaSized> Deref for Ref<'_, T> { type Target = T; #[inline] diff --git a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs index 3818456d3a6..745b6ee9bc5 100644 --- a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs +++ b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs @@ -5,8 +5,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "default_trait1"] auto trait DefaultTrait1 {} diff --git a/tests/ui/traits/default_auto_traits/default-bounds.rs b/tests/ui/traits/default_auto_traits/default-bounds.rs index 64733a40034..8535f82fc01 100644 --- a/tests/ui/traits/default_auto_traits/default-bounds.rs +++ b/tests/ui/traits/default_auto_traits/default-bounds.rs @@ -11,8 +11,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/ui/traits/default_auto_traits/default-bounds.stderr b/tests/ui/traits/default_auto_traits/default-bounds.stderr index 10fdcc43417..318fc57fc9c 100644 --- a/tests/ui/traits/default_auto_traits/default-bounds.stderr +++ b/tests/ui/traits/default_auto_traits/default-bounds.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Forbidden: SyncDrop` is not satisfied - --> $DIR/default-bounds.rs:37:9 + --> $DIR/default-bounds.rs:43:9 | LL | bar(Forbidden); | --- ^^^^^^^^^ the trait `SyncDrop` is not implemented for `Forbidden` @@ -7,13 +7,13 @@ LL | bar(Forbidden); | required by a bound introduced by this call | note: required by a bound in `bar` - --> $DIR/default-bounds.rs:33:8 + --> $DIR/default-bounds.rs:39:8 | LL | fn bar<T: Leak>(_: T) {} | ^ required by this bound in `bar` error[E0277]: the trait bound `Forbidden: Leak` is not satisfied - --> $DIR/default-bounds.rs:37:9 + --> $DIR/default-bounds.rs:43:9 | LL | bar(Forbidden); | --- ^^^^^^^^^ the trait `Leak` is not implemented for `Forbidden` @@ -21,7 +21,7 @@ LL | bar(Forbidden); | required by a bound introduced by this call | note: required by a bound in `bar` - --> $DIR/default-bounds.rs:33:11 + --> $DIR/default-bounds.rs:39:11 | LL | fn bar<T: Leak>(_: T) {} | ^^^^ required by this bound in `bar` diff --git a/tests/ui/traits/default_auto_traits/extern-types.current.stderr b/tests/ui/traits/default_auto_traits/extern-types.current.stderr index e1bd99b900f..593204382e3 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.current.stderr +++ b/tests/ui/traits/default_auto_traits/extern-types.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied - --> $DIR/extern-types.rs:44:13 + --> $DIR/extern-types.rs:50:13 | LL | foo(x); | --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque` @@ -7,9 +7,9 @@ LL | foo(x); | required by a bound introduced by this call | note: required by a bound in `foo` - --> $DIR/extern-types.rs:20:8 + --> $DIR/extern-types.rs:26:8 | -LL | fn foo<T: ?Sized>(_: &T) {} +LL | fn foo<T: PointeeSized>(_: &T) {} | ^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/traits/default_auto_traits/extern-types.next.stderr b/tests/ui/traits/default_auto_traits/extern-types.next.stderr index e1bd99b900f..593204382e3 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.next.stderr +++ b/tests/ui/traits/default_auto_traits/extern-types.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied - --> $DIR/extern-types.rs:44:13 + --> $DIR/extern-types.rs:50:13 | LL | foo(x); | --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque` @@ -7,9 +7,9 @@ LL | foo(x); | required by a bound introduced by this call | note: required by a bound in `foo` - --> $DIR/extern-types.rs:20:8 + --> $DIR/extern-types.rs:26:8 | -LL | fn foo<T: ?Sized>(_: &T) {} +LL | fn foo<T: PointeeSized>(_: &T) {} | ^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/traits/default_auto_traits/extern-types.rs b/tests/ui/traits/default_auto_traits/extern-types.rs index 822d4c0637f..df106d83171 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.rs +++ b/tests/ui/traits/default_auto_traits/extern-types.rs @@ -7,8 +7,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} @@ -17,7 +23,7 @@ pub trait Copy {} auto trait Leak {} // implicit T: Leak here -fn foo<T: ?Sized>(_: &T) {} +fn foo<T: PointeeSized>(_: &T) {} mod extern_leak { use crate::*; diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs index 49f2faba146..5069cd256b2 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs @@ -12,8 +12,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr index b7ffb66e60b..48745e40268 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:53:25 + --> $DIR/maybe-bounds-in-dyn-traits.rs:59:25 | LL | let _: &dyn Trait = &NonLeakS; | ^^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` @@ -7,13 +7,13 @@ LL | let _: &dyn Trait = &NonLeakS; = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak` error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:58:7 + --> $DIR/maybe-bounds-in-dyn-traits.rs:64:7 | LL | x.leak_foo(); | ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait` | note: required by a bound in `Trait::leak_foo` - --> $DIR/maybe-bounds-in-dyn-traits.rs:45:5 + --> $DIR/maybe-bounds-in-dyn-traits.rs:51:5 | LL | fn leak_foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs index 4cb38bc8e79..b3801baaf70 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs @@ -14,8 +14,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "legacy_receiver"] trait LegacyReceiver {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr index 3dd8418b100..bc797c9d976 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:61:22 + --> $DIR/maybe-bounds-in-traits.rs:67:22 | LL | type Leak2 = NonLeakS; | ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` | note: required by a bound in `Test3::Leak2` - --> $DIR/maybe-bounds-in-traits.rs:61:9 + --> $DIR/maybe-bounds-in-traits.rs:67:9 | LL | type Leak2 = NonLeakS; | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2` error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:49:29 + --> $DIR/maybe-bounds-in-traits.rs:55:29 | LL | type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak; | ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self` | note: required by a bound in `TestBase1` - --> $DIR/maybe-bounds-in-traits.rs:45:21 + --> $DIR/maybe-bounds-in-traits.rs:51:21 | LL | trait TestBase1<T: ?Sized> {} | ^ required by this bound in `TestBase1` @@ -27,7 +27,7 @@ LL | trait Test1<T>: Leak { | ++++++ error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/maybe-bounds-in-traits.rs:99:31 + --> $DIR/maybe-bounds-in-traits.rs:105:31 | LL | fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} | ^^^^^^^^^ @@ -38,13 +38,13 @@ LL | fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>` error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:86:43 + --> $DIR/maybe-bounds-in-traits.rs:92:43 | LL | const CNonLeak: usize = size_of::<Self>() where Self: ?Leak; | ^^^^ the trait `Leak` is not implemented for `Self` | note: required by a bound in `size_of` - --> $DIR/maybe-bounds-in-traits.rs:80:22 + --> $DIR/maybe-bounds-in-traits.rs:86:22 | LL | const fn size_of<T: ?Sized>() -> usize { | ^ required by this bound in `size_of` @@ -54,13 +54,13 @@ LL | trait Trait: Leak { | ++++++ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:109:18 + --> $DIR/maybe-bounds-in-traits.rs:115:18 | LL | NonLeakS.leak_foo(); | ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` | note: required by a bound in `methods::Trait::leak_foo` - --> $DIR/maybe-bounds-in-traits.rs:95:9 + --> $DIR/maybe-bounds-in-traits.rs:101:9 | LL | fn leak_foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr index dd9393fae85..d99a4cbd378 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr @@ -1,20 +1,5 @@ -error[E0308]: mismatched types - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 - | -LL | (MyType<'a, T>,): Sized, - | ^^^^^ lifetime mismatch - | - = note: expected trait `<MyType<'a, T> as Sized>` - found trait `<MyType<'static, T> as Sized>` -note: the lifetime `'a` as defined here... - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 - | -LL | fn foo<'a, T: ?Sized>() - | ^^ - = note: ...does not necessarily outlive the static lifetime - error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here @@ -22,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>() LL | is_sized::<(MyType<'a, T>,)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr index 05861877d41..d99a4cbd378 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr @@ -1,18 +1,5 @@ -error[E0478]: lifetime bound not satisfied - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 - | -LL | (MyType<'a, T>,): Sized, - | ^^^^^ - | -note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 - | -LL | fn foo<'a, T: ?Sized>() - | ^^ - = note: but lifetime parameter must outlive the static lifetime - error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here @@ -20,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>() LL | is_sized::<(MyType<'a, T>,)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0478`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs index ae7a6c9bba3..6ddc0628dd1 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs @@ -11,8 +11,6 @@ fn is_sized<T>() {} fn foo<'a, T: ?Sized>() where (MyType<'a, T>,): Sized, - //[current]~^ ERROR mismatched types - //[next]~^^ ERROR lifetime bound not satisfied MyType<'static, T>: Sized, { // Preferring the builtin `Sized` impl of tuples diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr index 8901805a20f..1eb445f4848 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -12,6 +12,13 @@ LL | impl<T: Bound, U> Trait<U> for T { | ----- ^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required by a bound in `Bound` + --> $DIR/normalizes-to-is-not-productive.rs:8:1 + | +LL | / trait Bound { +LL | | fn method(); +LL | | } + | |_^ required by this bound in `Bound` error[E0277]: the trait bound `Foo: Bound` is not satisfied --> $DIR/normalizes-to-is-not-productive.rs:47:19 diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index d179c805962..8d8909625ff 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -19,6 +19,23 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>` LL | Self::Assoc: A<T>, | ^^^^ +error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized` + --> $DIR/normalize-param-env-2.rs:24:22 + | +LL | Self::Assoc: A<T>, + | ^^^^ + | +note: required by a bound in `A` + --> $DIR/normalize-param-env-2.rs:9:1 + | +LL | / trait A<T> { +LL | | type Assoc; +LL | | +LL | | fn f() +... | +LL | | } + | |_^ required by this bound in `A` + error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed` --> $DIR/normalize-param-env-2.rs:24:22 | @@ -46,6 +63,6 @@ LL | where LL | Self::Assoc: A<T>, | ^^^^ required by this bound in `A::f` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index f5fd9ce9864..9f7f74f9466 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,6 +4,20 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait` LL | <T as Trait>::Assoc: Trait, | ^^^^^ -error: aborting due to 1 previous error +error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized` + --> $DIR/normalize-param-env-4.rs:19:26 + | +LL | <T as Trait>::Assoc: Trait, + | ^^^^^ + | +note: required by a bound in `Trait` + --> $DIR/normalize-param-env-4.rs:7:1 + | +LL | / trait Trait { +LL | | type Assoc; +LL | | } + | |_^ required by this bound in `Trait` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/non_lifetime_binders/basic.rs b/tests/ui/traits/non_lifetime_binders/basic.rs index 533891bf830..09c0244ec95 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.rs +++ b/tests/ui/traits/non_lifetime_binders/basic.rs @@ -1,12 +1,15 @@ //@ check-pass // Basic test that show's we can successfully typeck a `for<T>` where clause. +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait {} +use std::marker::PointeeSized; -impl<T: ?Sized> Trait for T {} +trait Trait: PointeeSized {} + +impl<T: PointeeSized> Trait for T {} fn foo() where diff --git a/tests/ui/traits/non_lifetime_binders/basic.stderr b/tests/ui/traits/non_lifetime_binders/basic.stderr index 0fd16c5d0ee..9f2df2238d1 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.stderr +++ b/tests/ui/traits/non_lifetime_binders/basic.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:4:12 + --> $DIR/basic.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs index 74c23a59bee..22044c2e662 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs @@ -1,11 +1,14 @@ // Make sure not to construct predicates with escaping bound vars in `diagnostic_hir_wf_check`. // Regression test for <https://github.com/rust-lang/rust/issues/139330>. +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait A<T: ?Sized> {} -impl<T: ?Sized> A<T> for () {} +use std::marker::PointeeSized; + +trait A<T: PointeeSized> {} +impl<T: PointeeSized> A<T> for () {} trait B {} struct W<T: B>(T); diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr index df99f4a67ab..8270fbeef0f 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/diagnostic-hir-wf-check.rs:4:12 + --> $DIR/diagnostic-hir-wf-check.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,24 +8,24 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:12 + --> $DIR/diagnostic-hir-wf-check.rs:16:12 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:42 + --> $DIR/diagnostic-hir-wf-check.rs:16:42 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | - ^^ the trait `B` is not implemented for `()` @@ -33,29 +33,29 @@ LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:40 + --> $DIR/diagnostic-hir-wf-check.rs:16:40 | LL | fn b() -> (W<()>, impl for<C> A<C>) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W<T: B>(T); | ^ required by this bound in `W` diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 4d1cacb1890..1364f63a373 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -1,11 +1,14 @@ //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait<T: ?Sized> {} +use std::marker::PointeeSized; -impl<T: ?Sized> Trait<T> for i32 {} +trait Trait<T: PointeeSized> {} + +impl<T: PointeeSized> Trait<T> for i32 {} fn produce() -> impl for<T> Trait<T> { 16 diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr index 34c56068c5c..c8396c38548 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-rpit.rs:3:12 + --> $DIR/on-rpit.rs:4:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs index 96345732f0f..aab5479334e 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs @@ -1,19 +1,22 @@ +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete +use std::marker::PointeeSized; + trait Foo: for<T> Bar<T> {} -trait Bar<T: ?Sized> { +trait Bar<T: PointeeSized>: PointeeSized { fn method(&self) {} } -fn needs_bar(x: &(impl Bar<i32> + ?Sized)) { +fn needs_bar(x: &(impl Bar<i32> + PointeeSized)) { x.method(); } impl Foo for () {} -impl<T: ?Sized> Bar<T> for () {} +impl<T: PointeeSized> Bar<T> for () {} fn main() { let x: &dyn Foo = &(); diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr index aead19c4527..b32915ff549 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-dyn-compatibility.rs:1:12 + --> $DIR/supertrait-dyn-compatibility.rs:2:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,14 +8,14 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:19:17 + --> $DIR/supertrait-dyn-compatibility.rs:22:17 | LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:7:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr index 3e5854ea1c8..6551253d2e9 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr index 3e5854ea1c8..6551253d2e9 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs index 2066887ea59..d900bd429e6 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs @@ -3,19 +3,22 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Id { - type Output: ?Sized; +use std::marker::PointeeSized; + +trait Id: PointeeSized { + type Output: PointeeSized; } -impl<T: ?Sized> Id for T { +impl<T: PointeeSized> Id for T { type Output = T; } -trait Everyone {} -impl<T: ?Sized> Everyone for T {} +trait Everyone: PointeeSized {} +impl<T: PointeeSized> Everyone for T {} fn hello() where for<T> <T as Id>::Output: Everyone {} diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr index 0224e5763e0..fecdc860f8e 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr index 0224e5763e0..fecdc860f8e 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs index 5334118e9ac..04e34531f4d 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs @@ -3,15 +3,18 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -pub trait Foo<T: ?Sized> { - type Bar<K: ?Sized>: ?Sized; +use std::marker::PointeeSized; + +pub trait Foo<T: PointeeSized> { + type Bar<K: PointeeSized>: PointeeSized; } impl Foo<usize> for () { - type Bar<K: ?Sized> = K; + type Bar<K: PointeeSized> = K; } pub fn f<T1, T2>(a: T1, b: T2) diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs index eadee6b711e..b4e8e3a8aad 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.rs +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs @@ -1,12 +1,15 @@ +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Other<U: ?Sized> {} +use std::marker::PointeeSized; -impl<U: ?Sized> Other<U> for U {} +trait Other<U: PointeeSized>: PointeeSized {} + +impl<U: PointeeSized> Other<U> for U {} #[rustfmt::skip] -fn foo<U: ?Sized>() +fn foo<U: PointeeSized>() where for<T> T: Other<U> {} diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr index ecc97e283be..b997e7379e2 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/universe-error1.rs:1:12 + --> $DIR/universe-error1.rs:2:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,15 +8,15 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `T: Other<_>` is not satisfied - --> $DIR/universe-error1.rs:14:11 + --> $DIR/universe-error1.rs:17:11 | LL | foo::<_>(); | ^ the trait `Other<_>` is not implemented for `T` | note: required by a bound in `foo` - --> $DIR/universe-error1.rs:11:15 + --> $DIR/universe-error1.rs:14:15 | -LL | fn foo<U: ?Sized>() +LL | fn foo<U: PointeeSized>() | --- required by a bound in this function LL | where LL | for<T> T: Other<U> {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 87f9c241e40..50d1a874551 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -15,6 +15,7 @@ use foo::*; fn test() -> impl Sized { <() as Callable>::call() +//~^ ERROR: type annotations needed } fn main() {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e8e569ba625..13fbfdb855c 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -4,6 +4,13 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self LL | impl<V: ?Sized> Callable for () { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/resolve-impl-before-constrain-check.rs:17:6 + | +LL | <() as Callable>::call() + | ^^ cannot infer type for type parameter `V` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2bb389c6ec1..3eacab33e46 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -4,6 +4,13 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<T: ?Sized> Every for Thing { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/unconstrained-projection-normalization-2.rs:19:11 + | +LL | fn foo(_: <Thing as Every>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for associated type `<Thing as Every>::Assoc` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.rs b/tests/ui/traits/unconstrained-projection-normalization-2.rs index 6b584c436c6..9d95c73eea7 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.rs +++ b/tests/ui/traits/unconstrained-projection-normalization-2.rs @@ -17,5 +17,6 @@ impl<T: ?Sized> Every for Thing { } fn foo(_: <Thing as Every>::Assoc) {} +//[next]~^ ERROR: type annotations needed fn main() {} |
