diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 6e345b2a6fdf0..7e8a1800341b2 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -9,13 +9,22 @@ transparent_unions, auto_traits, freeze_impls, - thread_local + thread_local, + const_trait_impl )] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -24,35 +33,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize {} +pub trait Unsize: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized {} -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn {} // &T -> &U -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl, U: ?Sized> DispatchFromDyn> for Box {} +impl, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl, U: MetaSized> DispatchFromDyn> for Box {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl LegacyReceiver for &T {} -impl LegacyReceiver for &mut T {} -impl LegacyReceiver for Box {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} +impl LegacyReceiver for Box {} #[lang = "copy"] pub trait Copy {} @@ -74,9 +83,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 Copy for *const T {} -impl Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl Copy for *const T {} +impl Copy for *mut T {} impl Copy for Option {} #[lang = "sync"] @@ -94,17 +103,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 Sync for [T; N] {} #[lang = "freeze"] unsafe auto trait Freeze {} -unsafe impl Freeze for PhantomData {} -unsafe impl Freeze for *const T {} -unsafe impl Freeze for *mut T {} -unsafe impl Freeze for &T {} -unsafe impl Freeze for &mut T {} +unsafe impl Freeze for PhantomData {} +unsafe impl Freeze for *const T {} +unsafe impl Freeze for *mut T {} +unsafe impl Freeze for &T {} +unsafe impl Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -443,7 +452,7 @@ pub enum Option { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData; +pub struct PhantomData; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -546,18 +555,18 @@ pub trait Deref { #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull(pub *const T); +pub struct NonNull(pub *const T); -impl CoerceUnsized> for NonNull where T: Unsize {} -impl DispatchFromDyn> for NonNull where T: Unsize {} +impl CoerceUnsized> for NonNull where T: Unsize {} +impl DispatchFromDyn> for NonNull where T: Unsize {} -pub struct Unique { +pub struct Unique { pub pointer: NonNull, pub _marker: PhantomData, } -impl CoerceUnsized> for Unique where T: Unsize {} -impl DispatchFromDyn> for Unique where T: Unsize {} +impl CoerceUnsized> for Unique where T: Unsize {} +impl DispatchFromDyn> for Unique where T: Unsize {} #[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 5544aee9eaf16..e2c2218ed2e44 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -1,7 +1,7 @@ #![feature( no_core, lang_items, intrinsics, unboxed_closures, extern_types, decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls, - thread_local + thread_local, const_trait_impl )] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] @@ -11,8 +11,16 @@ unsafe extern "C" fn _Unwind_Resume() { intrinsics::unreachable(); } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -21,35 +29,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize {} +pub trait Unsize: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized {} -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn {} // &T -> &U -impl<'a, T: ?Sized+Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized+Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl, U: ?Sized> DispatchFromDyn> for Box {} +impl, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl, U: MetaSized> DispatchFromDyn> for Box {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl LegacyReceiver for &T {} -impl LegacyReceiver for &mut T {} -impl LegacyReceiver for Box {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} +impl LegacyReceiver for Box {} #[lang = "copy"] pub trait Copy {} @@ -70,9 +78,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 Copy for *const T {} -impl Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl Copy for *const T {} +impl Copy for *mut T {} #[lang = "sync"] pub unsafe trait Sync {} @@ -88,17 +96,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 Freeze for PhantomData {} -unsafe impl Freeze for *const T {} -unsafe impl Freeze for *mut T {} -unsafe impl Freeze for &T {} -unsafe impl Freeze for &mut T {} +unsafe impl Freeze for PhantomData {} +unsafe impl Freeze for *const T {} +unsafe impl Freeze for *mut T {} +unsafe impl Freeze for &T {} +unsafe impl Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -403,7 +411,7 @@ pub enum Option { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData; +pub struct PhantomData; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -520,18 +528,18 @@ impl Allocator for Global {} #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull(pub *const T); +pub struct NonNull(pub *const T); -impl CoerceUnsized> for NonNull where T: Unsize {} -impl DispatchFromDyn> for NonNull where T: Unsize {} +impl CoerceUnsized> for NonNull where T: Unsize {} +impl DispatchFromDyn> for NonNull where T: Unsize {} -pub struct Unique { +pub struct Unique { pub pointer: NonNull, pub _marker: PhantomData, } -impl CoerceUnsized> for Unique where T: Unsize {} -impl DispatchFromDyn> for Unique where T: Unsize {} +impl CoerceUnsized> for Unique where T: Unsize {} +impl DispatchFromDyn> for Unique where T: Unsize {} #[lang = "owned_box"] pub struct Box(Unique, A); diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs index a636d09fcae23..bfc7556faf68c 100644 --- a/compiler/rustc_data_structures/src/aligned.rs +++ b/compiler/rustc_data_structures/src/aligned.rs @@ -1,3 +1,4 @@ +use std::marker::PointeeSized; use std::ptr::Alignment; /// Returns the ABI-required minimum alignment of a type in bytes. @@ -17,7 +18,7 @@ pub const fn align_of() -> Alignment { /// example `[T]` has alignment of `T`. /// /// [`align_of::()`]: 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 865424fd6bbdc..a442652362adf 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,6 +10,7 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![deny(unsafe_op_in_unsafe_fn)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] @@ -32,6 +33,7 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] #![feature(test)] #![feature(thread_id_value)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 64c64bfa3c296..6702173e19de1 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -1,4 +1,5 @@ use std::alloc::Allocator; +use std::marker::PointeeSized; #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")] @@ -15,7 +16,7 @@ pub unsafe auto trait DynSend {} pub unsafe auto trait DynSync {} // Same with `Sync` and `Send`. -unsafe impl DynSend for &T {} +unsafe impl DynSend for &T {} macro_rules! impls_dyn_send_neg { ($([$t1: ty $(where $($generics1: tt)*)?])*) => { @@ -27,9 +28,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 where T: ?Sized] + [*const T where T: ?Sized + PointeeSized] + [*mut T where T: ?Sized + PointeeSized] + [std::ptr::NonNull where T: ?Sized + PointeeSized] [std::rc::Rc where T: ?Sized, A: Allocator] [std::rc::Weak where T: ?Sized, A: Allocator] [std::sync::MutexGuard<'_, T> where T: ?Sized] @@ -93,12 +94,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 where T: ?Sized] [std::cell::RefCell where T: ?Sized] [std::cell::UnsafeCell where T: ?Sized] - [std::ptr::NonNull where T: ?Sized] + [std::ptr::NonNull where T: ?Sized + PointeeSized] [std::rc::Rc where T: ?Sized, A: Allocator] [std::rc::Weak where T: ?Sized, A: Allocator] [std::cell::OnceCell where T] @@ -161,10 +162,10 @@ impl_dyn_sync!( [thin_vec::ThinVec where T: DynSync] ); -pub fn assert_dyn_sync() {} -pub fn assert_dyn_send() {} -pub fn assert_dyn_send_val(_t: &T) {} -pub fn assert_dyn_send_sync_val(_t: &T) {} +pub fn assert_dyn_sync() {} +pub fn assert_dyn_send() {} +pub fn assert_dyn_send_val(_t: &T) {} +pub fn assert_dyn_send_sync_val(_t: &T) {} #[derive(Copy, Clone)] pub struct FromDyn(T); @@ -204,10 +205,10 @@ impl std::ops::Deref for FromDyn { // an instance of `DynSend` and `DynSync`, since the compiler cannot infer // it automatically in some cases. (e.g. Box) #[derive(Copy, Clone)] -pub struct IntoDynSyncSend(pub T); +pub struct IntoDynSyncSend(pub T); -unsafe impl DynSend for IntoDynSyncSend {} -unsafe impl DynSync for IntoDynSyncSend {} +unsafe impl DynSend for IntoDynSyncSend {} +unsafe impl DynSync for IntoDynSyncSend {} impl std::ops::Deref for IntoDynSyncSend { type Target = T; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fd936458f1115..81bbed617e9d8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1036,6 +1036,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, "#[rustc_force_inline] forces a free function to be inlined" ), + rustc_attr!( + rustc_non_const_sized, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, + "#[rustc_non_const_sized] forces a type to not implement `const {Meta,Pointee,}Sized` for testing" + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4707daea08910..86c4462e63ef7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -235,6 +235,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 e625514e9ffa1..ff866c56f453d 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/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 6e07f0ff53c39..ce32dc037f752 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -44,7 +44,14 @@ fn associated_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + icx.lowerer().adjust_sizedness_params_and_assoc_types( + &mut bounds, + item_ty, + hir_bounds, + None, + span, + assoc_item_def_id, + ); } // `ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} @@ -334,7 +341,14 @@ fn opaque_type_bounds<'tcx>( | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { // Associated types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + icx.lowerer().adjust_sizedness_params_and_assoc_types( + &mut bounds, + item_ty, + hir_bounds, + None, + span, + opaque_def_id, + ); } //`ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 4bd89861a9e5a..4417d98fbe353 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -162,10 +162,11 @@ 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); + ItemKind::Trait(is_auto, _, _, _, self_bounds, ..) => { + is_trait = Some((is_auto, self_bounds)); + } + ItemKind::TraitAlias(_, _, self_bounds) => { + is_trait = Some((IsAuto::No, self_bounds)); } _ => {} } @@ -177,7 +178,7 @@ 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((is_auto, self_bounds)) = is_trait { let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, @@ -186,6 +187,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::List::empty(), PredicateFilter::All, ); + + // Don't add default supertraits to auto traits as it is not permitted to explicitly + // relax it in the source code. + if is_auto == IsAuto::No { + icx.lowerer().adjust_sizedness_supertraits( + &mut bounds, + tcx.types.self_param, + self_bounds, + def_id, + ); + } + predicates.extend(bounds); } @@ -211,12 +224,13 @@ 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(); // Params are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound( + icx.lowerer().adjust_sizedness_params_and_assoc_types( &mut bounds, param_ty, &[], Some((param.def_id, hir_generics.predicates)), param.span, + def_id, ); trace!(?bounds); predicates.extend(bounds); @@ -269,6 +283,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, PredicateFilter::All, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, bound_pred.bounded_ty.span); predicates.extend(bounds); } @@ -625,6 +640,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let self_param_ty = tcx.types.self_param; let mut bounds = Vec::new(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, item.span); let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter); @@ -932,6 +948,7 @@ impl<'tcx> ItemCtxt<'tcx> { bound_vars, filter, ); + self.lowerer().adjust_sizedness_predicates(&mut bounds, predicate.bounded_ty.span); } bounds @@ -1011,6 +1028,7 @@ pub(super) fn const_conditions<'tcx>( bound_vars, PredicateFilter::ConstIfConst, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, bound_pred.bounded_ty.span); } _ => {} } @@ -1031,6 +1049,7 @@ pub(super) fn const_conditions<'tcx>( ty::List::empty(), PredicateFilter::ConstIfConst, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, DUMMY_SP); } ty::ConstConditions { 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 f0dffd780bcc7..bfd6488ffad3c 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::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{HirId, 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,104 +23,264 @@ use crate::hir_ty_lowering::{ AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason, }; +#[derive(Debug, Default)] +struct CollectedBound { + constness: bool, + /// `Trait` + positive: Option, + /// `?Trait` + maybe: Option, + /// `!Trait` + negative: Option, +} + +impl CollectedBound { + /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered. + fn any(&self) -> bool { + self.positive.is_some() || self.maybe.is_some() || self.negative.is_some() + } +} + +#[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 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, SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]>) { + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let mut sized = CollectedBound::default(); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let mut meta_sized = CollectedBound::default(); + + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + let mut pointee_sized = CollectedBound::default(); + + let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); + 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; + }; + + if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) { + unbounds.push(ptr); + } + + let has_constness = matches!( + ptr.modifiers.constness, + hir::BoundConstness::Always(_) | hir::BoundConstness::Maybe(_) + ); + + let collect_into = match ptr.trait_ref.path.res { + Res::Def(DefKind::Trait, did) if did == sized_did => &mut sized, + Res::Def(DefKind::Trait, did) if did == meta_sized_did => &mut meta_sized, + Res::Def(DefKind::Trait, did) if did == pointee_sized_did => &mut pointee_sized, + _ => continue, + }; + + collect_into.constness = has_constness; + match ptr.modifiers.polarity { + hir::BoundPolarity::Maybe(_) => collect_into.maybe = Some(hir_bound.span()), + hir::BoundPolarity::Negative(_) => collect_into.negative = Some(hir_bound.span()), + hir::BoundPolarity::Positive => collect_into.positive = Some(hir_bound.span()), + } + } + }; + + 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); + } + } + } + + (CollectedSizednessBounds { sized, meta_sized, pointee_sized }, unbounds) +} + +/// Add a trait predicate for `did`. +fn add_trait_predicate<'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)); +} + +/// Add a host effect predicate for `did`. +fn add_host_effect_predicate<'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]); + let clause = ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + constness: ty::BoundConstness::Const, + }) + .upcast(tcx); + bounds.insert(1, (clause, span)); +} + +/// Remove any bounds of `did`. +fn remove_lang_item_bound<'tcx>(bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, did: DefId) { + bounds.retain(|(clause, _)| { + clause.as_trait_clause().map_or(true, |clause| clause.skip_binder().def_id() != did) + }); +} + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { - /// Add a `Sized` bound to the `bounds` if appropriate. + /// Remove `PointeeSized` predicates (sibling functions do the same for supertraits and params). /// - /// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`. - pub(crate) fn add_sized_bound( + // `PointeeSized` is a "fake bound" insofar as it is preferred that 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 adjust_sizedness_predicates( + &self, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, + span: Span, + ) { + let tcx = self.tcx(); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); + } + + /// Adds a `const MetaSized` bound to `bounds` (of a trait definition) if there are no other + /// sizedness bounds. Also removes `PointeeSized` params - see doc comment on + /// `adjust_sizedness_predicates`. + pub(crate) fn adjust_sizedness_supertraits( &self, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &'tcx [hir::GenericBound<'tcx>], - self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, - span: Span, + trait_did: LocalDefId, ) { let tcx = self.tcx(); - let sized_def_id = tcx.lang_items().sized_trait(); - let mut seen_negative_sized_bound = false; - let mut seen_positive_sized_bound = false; - - // Try to find an unbound in bounds. - let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); - 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; - }; - match ptr.modifiers.polarity { - hir::BoundPolarity::Maybe(_) => unbounds.push(ptr), - hir::BoundPolarity::Negative(_) => { - if let Some(sized_def_id) = sized_def_id - && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_negative_sized_bound = true; - } - } - hir::BoundPolarity::Positive => { - if let Some(sized_def_id) = sized_def_id - && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_positive_sized_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); - } + let span = tcx.def_span(trait_did); + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + + let trait_hir_id = tcx.local_def_id_to_hir_id(trait_did); + let trait_did = trait_did.to_def_id(); + if trait_did == pointee_sized_did { + // Never add a default supertrait to `PointeeSized`. + return; } - 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 (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span); + if !collected.any() && !tcx.sess.edition().at_least_edition_future() { + // Emit migration lint when the feature is enabled. + self.emit_implicit_const_meta_sized_supertrait_lint(trait_hir_id, span); + + // If it is not Edition Future and there are no explicit sizedness bounds then add a + // default `const MetaSized` supertrait. + add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); + add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); + } else if let Some(bound_span) = collected.sized.positive + && !collected.sized.constness + && !tcx.sess.edition().at_least_edition_future() + { + // Emit migration lint when the feature is enabled. + self.emit_sized_to_const_sized_lint(trait_hir_id, bound_span); + + // If it is not Edition Future then `Sized` is equivalent to writing `const Sized`. + add_trait_predicate(tcx, bounds, self_ty, sized_did, bound_span); + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, bound_span); } - let mut seen_sized_unbound = false; - for unbound in unbounds { - if let Some(sized_def_id) = sized_def_id - && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_sized_unbound = true; - continue; + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); + } + + /// Add a default `const Sized` bound if there are no other sizedness bounds and rewrite + /// `?Sized` to `MetaSized`. Also removes `PointeeSized` params - see doc comment on + /// `adjust_sizedness_predicates`. + pub(crate) fn adjust_sizedness_params_and_assoc_types( + &self, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, + self_ty: Ty<'tcx>, + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + span: Span, + trait_did: LocalDefId, + ) { + let tcx = self.tcx(); + + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + + let (collected, unbounds) = + collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span); + let trait_hir_id = tcx.local_def_id_to_hir_id(trait_did); + self.check_and_report_invalid_unbounds_on_param(trait_hir_id, unbounds); + + if (collected.sized.maybe.is_some() || collected.sized.negative.is_some()) + && !collected.sized.positive.is_some() + && !collected.meta_sized.any() + && !collected.pointee_sized.any() + { + // `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't + // any other explicit ones) + add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); + add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); + } else if let Some(bound_span) = collected.sized.positive + && !collected.sized.constness + && !tcx.sess.edition().at_least_edition_future() + { + // Emit migration lint when the feature is enabled. + self.emit_sized_to_const_sized_lint(trait_hir_id, bound_span); + + // Replace `Sized` with `const Sized`. + add_trait_predicate(tcx, bounds, self_ty, sized_did, bound_span); + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, bound_span); + } else if !collected.any() { + // If there are no explicit sizedness bounds then add a default `const Sized` bound. + add_trait_predicate(tcx, bounds, self_ty, sized_did, span); + + if !tcx.sess.edition().at_least_edition_future() { + self.emit_default_sized_to_const_sized_lint(trait_hir_id, span); + + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span); } - // There was a `?Trait` bound, but it was not `?Sized` - self.dcx().span_err( - unbound.span, - "relaxing a default bound only does something for `?Sized`; \ - all other traits are not bound by default", - ); } - if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound { - // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound; - // we don't need to do anything. - } else if let Some(sized_def_id) = sized_def_id { - // There was no `?Sized`, `!Sized` or explicit `Sized` bound; - // add `Sized` if it's available. - let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - bounds.insert(0, (trait_ref.upcast(tcx), span)); - } + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); } /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any. @@ -423,6 +583,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { projection_ty.bound_vars(), predicate_filter, ); + self.adjust_sizedness_predicates(bounds, constraint.span); } PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) 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 3b007c7719880..402e776fc8aff 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -5,9 +5,9 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err, }; -use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; +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 _}; @@ -15,6 +15,7 @@ use rustc_middle::ty::{ self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, suggest_constraining_type_param, }; +use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -32,6 +33,145 @@ 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. + pub(crate) fn check_and_report_invalid_unbounds_on_param( + &self, + trait_hir_id: HirId, + unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>, + ) { + let tcx = self.tcx(); + + let sized_did = tcx.require_lang_item(LangItem::Sized, None); + + 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() { + tcx.sess.create_feature_err(err, sym::more_maybe_bounds).emit(); + }; + } + + for unbound in unbounds { + let is_sized = matches!( + unbound.trait_ref.path.res, + Res::Def(DefKind::Trait, did) if did == sized_did + ); + if is_sized && !tcx.features().sized_hierarchy() { + continue; + } + + if tcx.features().sized_hierarchy() && is_sized { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + unbound.span, + |lint| { + lint.primary_message( + "`?Sized` bound relaxations are being migrated to `const MetaSized`", + ); + lint.span_suggestion( + unbound.span, + "replace `?Sized` with `const MetaSized`", + "const MetaSized", + Applicability::MachineApplicable, + ); + }, + ); + return; + } + + // There was a `?Trait` bound, but it was not `?Sized`. + self.dcx().span_err( + unbound.span, + "relaxing a default bound only does something for `?Sized`; all other traits \ + are not bound by default", + ); + } + } + + /// Emit lint adding a `const MetaSized` supertrait as part of sized hierarchy migration. + pub(crate) fn emit_implicit_const_meta_sized_supertrait_lint( + &self, + trait_hir_id: HirId, + span: Span, + ) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message( + "a `const MetaSized` supertrait is required to maintain backwards \ + compatibility", + ); + lint.span_suggestion( + span.shrink_to_hi(), + "add an explicit `const MetaSized` supertrait", + ": const MetaSized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + + /// Emit lint changing `Sized` bounds to `const MetaSized` bounds as part of sized hierarchy + /// migration. + pub(crate) fn emit_sized_to_const_sized_lint(&self, trait_hir_id: HirId, span: Span) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message("`Sized` bounds are being migrated to `const Sized`"); + lint.span_suggestion( + span, + "replace `Sized` with `const Sized`", + "const Sized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + + /// Emit lint adding `const MetaSized` bound as part of sized hierarchy migration. + pub(crate) fn emit_default_sized_to_const_sized_lint(&self, trait_hir_id: HirId, span: Span) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message("default bounds are being migrated to `const Sized`"); + lint.span_suggestion( + span.shrink_to_hi(), + "add `const Sized`", + ": const Sized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + /// 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 complain_about_missing_type_params( diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index af1107b499f4e..bcd76f732ffb1 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -436,9 +436,10 @@ fn check_specialization_on<'tcx>( // Global predicates are either always true or always false, so we // are fine to specialize on. _ if clause.is_global() => Ok(()), - // We allow specializing on explicitly marked traits with no associated + // We allow specializing on explicitly marked traits (and host effects) with no associated // items. - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) + | ty::ClauseKind::HostEffect(ty::HostEffectPredicate { trait_ref, constness: _ }) => { if matches!( trait_specialization_kind(tcx, clause), Some(TraitSpecializationKind::Marker) @@ -487,7 +488,8 @@ fn trait_specialization_kind<'tcx>( clause: ty::Clause<'tcx>, ) -> Option { match clause.kind().skip_binder() { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) + | ty::ClauseKind::HostEffect(ty::HostEffectPredicate { trait_ref, constness: _ }) => { Some(tcx.trait_def(trait_ref.def_id).specialization_kind) } ty::ClauseKind::RegionOutlives(_) @@ -495,7 +497,6 @@ fn trait_specialization_kind<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(..) - | ty::ClauseKind::HostEffect(..) => None, + | ty::ClauseKind::ConstEvaluatable(..) => None, } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d75c2853ba080..2f1afd4aec1f0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -23,7 +23,8 @@ 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, GenericArgKind, GenericArgsRef, GenericParamDefKind, - IsIdentity, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, UserSelfTy, + 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_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 592c934997c01..6c05a29c50ea5 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -97,6 +97,7 @@ declare_lint_pass! { SELF_CONSTRUCTOR_FROM_OUTER_ITEM, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SINGLE_USE_LIFETIMES, + SIZED_HIERARCHY_MIGRATION, SOFT_UNSTABLE, STABLE_FEATURES, SUPERTRAIT_ITEM_SHADOWING_DEFINITION, @@ -5125,3 +5126,41 @@ declare_lint! { reference: "issue #116558 ", }; } + +declare_lint! { + /// The `sized_hierarchy_migration` lint detects uses of the `Sized` trait which must be + /// migrated with the introduction of a hierarchy of sizedness traits. + /// + /// ### Example + /// ```rust,edition_2024,compile_fail + /// #![feature(sized_hierarchy)] + /// #![deny(sized_hierarchy_migration)] + /// + /// pub fn foo() {} + /// + /// pub trait Foo {} + /// + /// pub fn bar() {} + /// + /// pub fn qux() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// In order to preserve backwards compatibility when a hierarchy of sizedness traits is + /// introduced, various migrations are necessary: + /// + /// - `Sized` becomes `const Sized` + /// - `?Sized` becomes `const MetaSized` + /// - Traits have a `const MetaSized` supertrait + /// + /// See [RFC #3729](https://github.com/rust-lang/rfcs/pull/3729) for more details. + pub SIZED_HIERARCHY_MIGRATION, + Warn, + "new sized traits are being introduced which require migration to maintain backwards compat", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::EditionFuture), + reference: "", + }; +} diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1e6178144c921..a6dd411608b1e 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,6 +30,7 @@ #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] @@ -56,6 +57,7 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 527c18addbe12..dbf1d17769ec0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -813,6 +813,12 @@ rustc_queries! { query adt_sized_constraint(key: DefId) -> Option>> { desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) } } + query adt_meta_sized_constraint(key: DefId) -> Option>> { + desc { |tcx| "computing the `MetaSized` constraint for `{}`", tcx.def_path_str(key) } + } + query adt_pointee_sized_constraint(key: DefId) -> Option>> { + desc { |tcx| "computing the `PointeeSized` constraint for `{}`", tcx.def_path_str(key) } + } query adt_dtorck_constraint( key: DefId diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 811bd8fb4588a..d03b44d8b3d13 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -98,7 +98,7 @@ pub enum SelectionCandidate<'tcx> { /// A builtin implementation for some specific traits, used in cases /// where we cannot rely an ordinary library implementations. /// - /// The most notable examples are `sized`, `Copy` and `Clone`. This is also + /// The most notable examples are `Sized`, `Copy` and `Clone`. This is also /// used for the `DiscriminantKind` and `Pointee` trait, both of which have /// an associated type. BuiltinCandidate { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index cb245c0aec40a..399a152d3b110 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -53,6 +53,13 @@ bitflags::bitflags! { const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. const IS_UNSAFE_CELL = 1 << 9; + /// Indicates whether the type is annotated with `#[rustc_non_const_sized]`. + /// + /// Necessary to know when to add a type flag since `TyCtxt` isn't available and the + /// presence of the attribute cannot be checked. + /// FIXME(sized-hierarchy): Consider removing this when scalable vectors are implemented + /// and `def.repr.scalable` can be checked. + const HAS_NON_CONST_SIZEDNESS = 1 << 10; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -231,6 +238,17 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef> for AdtDef<'tcx> { self.sized_constraint(tcx) } + fn meta_sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { + self.meta_sized_constraint(tcx) + } + + fn pointee_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option>> { + self.pointee_sized_constraint(tcx) + } + fn is_fundamental(self) -> bool { self.is_fundamental() } @@ -277,6 +295,10 @@ impl AdtDefData { flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } + if tcx.has_attr(did, sym::rustc_non_const_sized) { + flags = flags | AdtFlags::HAS_NON_CONST_SIZEDNESS; + } + flags |= match kind { AdtKind::Enum => AdtFlags::IS_ENUM, AdtKind::Union => AdtFlags::IS_UNION, @@ -343,6 +365,12 @@ impl<'tcx> AdtDef<'tcx> { self.is_variant_list_non_exhaustive() && !self.did().is_local() } + /// Returns `true` if this type only has non-const implementations of sizedness traits. + #[inline] + pub fn has_non_const_sizedness(self) -> bool { + self.flags().contains(AdtFlags::HAS_NON_CONST_SIZEDNESS) + } + /// Returns the kind of the ADT. #[inline] pub fn adt_kind(self) -> AdtKind { @@ -628,6 +656,24 @@ impl<'tcx> AdtDef<'tcx> { pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None } } + + /// Returns a type such that `Self: MetaSized` if and only if that type is `MetaSized`, + /// or `None` if the type is always `MetaSized`. + pub fn meta_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option>> { + if self.is_struct() { tcx.adt_meta_sized_constraint(self.did()) } else { None } + } + + /// Returns a type such that `Self: PointeeSized` if and only if that type is `PointeeSized`, + /// or `None` if the type is always `PointeeSized`. + pub fn pointee_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option>> { + if self.is_struct() { tcx.adt_pointee_sized_constraint(self.did()) } else { None } + } } #[derive(Clone, Copy, Debug, HashStable)] diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 74b34afe616b9..e2c54eb949f22 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -8,7 +8,7 @@ use std::hash::Hash; use std::intrinsics; -use std::marker::DiscriminantKind; +use std::marker::{DiscriminantKind, PointeeSized}; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashMap; @@ -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 f54dd2b0040ae..af5f84f3e9c98 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -8,7 +8,7 @@ use std::assert_matches::{assert_matches, debug_assert_matches}; use std::borrow::Borrow; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; +use std::marker::{PhantomData, PointeeSized}; use std::ops::{Bound, Deref}; use std::sync::{Arc, OnceLock}; use std::{fmt, iter, mem}; @@ -714,7 +714,9 @@ bidirectional_lang_item_map! { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, @@ -2423,17 +2425,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/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index b0c442d28f0a0..3070a18f06f93 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -129,7 +129,11 @@ impl FlagComputation { } }, - &ty::Adt(_, args) => { + &ty::Adt(def, args) => { + if def.has_non_const_sizedness() { + self.add_flags(TypeFlags::HAS_NON_CONST_SIZEDNESS); + } + self.add_args(args); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6bdd0a0647d30..46be9bb0a2eb9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -50,6 +50,7 @@ pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::relate::VarianceDiagInfo; +pub use rustc_type_ir::solve::SizedTraitKind; pub use rustc_type_ir::*; use tracing::{debug, instrument}; pub use vtable::*; diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 02e316dfc3db7..99ab13819396b 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -208,6 +208,15 @@ impl<'tcx> Clause<'tcx> { } } + pub fn as_host_effect_clause(self) -> Option>> { + let clause = self.kind(); + if let ty::ClauseKind::HostEffect(host_effect_clause) = clause.skip_binder() { + Some(clause.rebind(host_effect_clause)) + } else { + None + } + } + pub fn as_projection_clause(self) -> Option>> { let clause = self.kind(); if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3ef8ecc59e402..53319ad7200e2 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1062,24 +1062,37 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); - 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_sized_pred = false; + let mut has_const_sized_pred = false; + let mut has_negative_sized_pred = false; + let mut has_meta_sized_pred = false; + let mut has_const_meta_sized_pred = false; + let mut has_pointee_sized_pred = 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. + // With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for + // `MetaSized`, and skip sizedness bounds to be added at the end. if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { match pred.polarity { ty::PredicatePolarity::Positive => { - has_sized_bound = true; + has_sized_pred = true; continue; } - ty::PredicatePolarity::Negative => has_negative_sized_bound = true, + ty::PredicatePolarity::Negative => has_negative_sized_pred = true, } + } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { + has_meta_sized_pred = true; + continue; + } else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) { + // Unexpected - `PointeeSized` is the absence of bounds. + has_pointee_sized_pred = true; + continue; } self.insert_trait_and_projection( @@ -1106,6 +1119,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ClauseKind::TypeOutlives(outlives) => { lifetimes.push(outlives.1); } + ty::ClauseKind::HostEffect(pred) => { + if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { + has_const_sized_pred = true; + } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { + has_const_meta_sized_pred = true; + } + } _ => {} } } @@ -1114,7 +1134,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut first = true; // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait - let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound; + let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_pred; for ((bound_args_and_self_ty, is_async), entry) in fn_traits { write!(self, "{}", if first { "" } else { " + " })?; @@ -1248,16 +1268,36 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { })?; } - let add_sized = has_sized_bound && (first || has_negative_sized_bound); - let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound; + let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); + let add_sized = has_sized_pred && (first || has_negative_sized_pred); + let add_maybe_sized = + has_meta_sized_pred && !has_negative_sized_pred && !using_sized_hierarchy; + // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. + has_pointee_sized_pred = has_pointee_sized_pred + || (!has_sized_pred && !has_meta_sized_pred && !has_negative_sized_pred); if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; } if add_maybe_sized { write!(self, "?")?; + } else if has_const_sized_pred && using_sized_hierarchy { + write!(self, "const ")?; } write!(self, "Sized")?; + } else if has_meta_sized_pred && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + if has_const_meta_sized_pred && using_sized_hierarchy { + write!(self, "const ")?; + } + write!(self, "MetaSized")?; + } else if has_pointee_sized_pred && 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 74a94d8278453..3293e90de0175 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -16,6 +16,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::{self as ir, BoundVar, CollectAndApply, DynKind, TypeVisitableExt, elaborate}; use tracing::instrument; use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; @@ -1783,7 +1784,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) { @@ -1886,17 +1887,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`, `MetaSized` or `PointeeSized`. /// - /// Returning true means the type is known to be 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`. - pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { + /// 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`. + #[instrument(skip(tcx), level = "debug")] + pub fn has_trivial_sizedness(self, tcx: TyCtxt<'tcx>, sizedness: SizedTraitKind) -> bool { match self.kind() { ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) @@ -1919,20 +1920,36 @@ 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 | SizedTraitKind::PointeeSized => true, + }, + + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => false, + SizedTraitKind::PointeeSized => true, + }, - 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)), + ty::Adt(def, args) => { + let constraint = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(tcx), + SizedTraitKind::MetaSized => def.meta_sized_constraint(tcx), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(tcx), + }; + + constraint.is_none_or(|ty| { + ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness) + }) + } ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, ty::Infer(ty::TyVar(_)) => false, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) + bug!("`has_trivial_sizedness` applied to unexpected type: {:?}", self) } } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c0d4130336e52..05a362359e161 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}; @@ -1189,7 +1190,8 @@ impl<'tcx> Ty<'tcx> { /// strange rules like `>::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 384a304c4a9d6..ebbb63756f301 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -5,6 +5,7 @@ pub(super) mod structural_traits; 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, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, }; @@ -146,13 +147,16 @@ where goal: Goal, ) -> Result, NoSolution>; - /// A type is `Sized` if its tail component is `Sized`. + /// A type is `Sized` if its tail component is `Sized`, a type is `MetaSized` if its tail + /// component is `MetaSized` and a type is `PointeeSized` if its tail component is + /// `PointeeSized`. /// /// 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, + sizedness: SizedTraitKind, ) -> Result, NoSolution>; /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. @@ -396,7 +400,19 @@ 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) => { + G::consider_builtin_sizedness_candidates( + self, + goal, + SizedTraitKind::PointeeSized, + ) + } Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) } @@ -805,7 +821,10 @@ where .filter(|c| { matches!( c.source, - CandidateSource::AliasBound | CandidateSource::ParamEnv(_) + CandidateSource::AliasBound + | CandidateSource::ParamEnv(_) + // Allow trivial for `const Sized` + | CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial) ) }) .map(|c| c.result) 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 a5142de2d3905..fbbcef6071898 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,9 +5,10 @@ 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::{ self as ty, Interner, Movability, Mutability, TypeFoldable, TypeFolder, TypeSuperFoldable, - Upcast as _, elaborate, + TypeVisitableExt as _, Upcast as _, elaborate, }; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; @@ -99,8 +100,9 @@ where } #[instrument(level = "trace", skip(ecx), ret)] -pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait( +pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait( ecx: &EvalCtxt<'_, D>, + sizedness: SizedTraitKind, ty: I::Ty, ) -> Result>, NoSolution> where @@ -108,8 +110,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,Pointee,}Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char + // impl {Meta,Pointee,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine, CoroutineWitness + // impl {Meta,Pointee,}Sized for Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) | ty::Int(_) @@ -130,13 +133,21 @@ 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,Pointee,}Sized for str, [T], dyn Trait + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => Err(NoSolution), + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => { + Ok(ty::Binder::dummy(vec![])) + } + }, + + // impl PointeeSized for extern type + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Err(NoSolution), + SizedTraitKind::PointeeSized => Ok(ty::Binder::dummy(vec![])), + }, + + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => Err(NoSolution), ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { @@ -145,22 +156,32 @@ 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,Pointee,}Sized for () + // impl {Meta,Pointee,}Sized for (T1, T2, .., Tn) where Tn: {Meta,Pointee,}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 where sized_constraint(Adt): 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 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,Pointee,}Sized for Adt + // where {meta,pointee,}sized_constraint(Adt): {Meta,Pointee,}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,Pointee,}Sized for Adt + // 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)])) + let crit = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(ecx.cx()), + SizedTraitKind::MetaSized => def.meta_sized_constraint(ecx.cx()), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(ecx.cx()), + }; + if let Some(crit) = crit { + Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)])) } else { Ok(ty::Binder::dummy(vec![])) } @@ -168,6 +189,38 @@ where } } +/// Returns the trait refs which need to hold for `self_ty`, with a given `sizedness` trait, to be +/// `const` - can return `Err(NoSolution)` if the given `self_ty` cannot be const. +/// +/// This only checks the conditions for constness, not the conditions for the given `sizedness` +/// trait to be implemented (see the trait goal for that), as these are orthogonal. This means that +/// the effect predicate can succeed while the trait predicate can fail - this is unintuitive but +/// allows this function to be much simpler. +// NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver and +// `ProvePredicate::try_fast_path` +#[instrument(level = "trace", skip(cx), ret)] +pub(in crate::solve) fn const_conditions_for_sizedness( + cx: I, + self_ty: I::Ty, + sizedness: SizedTraitKind, +) -> Result>, NoSolution> { + // The specific degree of sizedness is orthogonal to whether a type implements any given + // sizedness trait const-ly or not. + if self_ty.has_non_const_sizedness() { + return Err(NoSolution); + } + + match sizedness { + SizedTraitKind::Sized => { + let meta_sized_def_id = cx.require_lang_item(TraitSolverLangItem::MetaSized); + let meta_sized_trait_ref = ty::TraitRef::new(cx, meta_sized_def_id, [self_ty]); + Ok(vec![meta_sized_trait_ref]) + } + SizedTraitKind::MetaSized => Ok(vec![]), + SizedTraitKind::PointeeSized => unreachable!("`PointeeSized` is not const"), + } +} + #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait( ecx: &EvalCtxt<'_, D>, 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 0b61c368d8e8d..69accf964d085 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; @@ -44,7 +45,9 @@ where then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, ) -> Result, NoSolution> { if let Some(host_clause) = assumption.as_host_effect_clause() { - if host_clause.def_id() == goal.predicate.def_id() + let goal_did = goal.predicate.def_id(); + let host_clause_did = host_clause.def_id(); + if host_clause_did == goal_did && host_clause.constness().satisfies(goal.predicate.constness) { if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( @@ -54,7 +57,7 @@ where return Err(NoSolution); } - ecx.probe_trait_candidate(source).enter(|ecx| { + return ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); ecx.eq( goal.param_env, @@ -62,13 +65,26 @@ where assumption_trait_pred.trait_ref, )?; then(ecx) - }) - } else { - Err(NoSolution) + }); + } + + // 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_did, TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(host_clause_did, TraitSolverLangItem::Sized) + && { + let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty()); + let found_self_ty = + ecx.resolve_vars_if_possible(host_clause.self_ty().skip_binder()); + expected_self_ty == found_self_ty + } + { + return ecx.probe_trait_candidate(source).enter(then); } - } else { - Err(NoSolution) } + + Err(NoSolution) } /// Register additional assumptions for aliases corresponding to `~const` item bounds. @@ -198,11 +214,30 @@ where unreachable!("trait aliases are never const") } - fn consider_builtin_sized_candidate( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal, + fn consider_builtin_sizedness_candidates( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + sizedness: SizedTraitKind, ) -> Result, NoSolution> { - unreachable!("Sized is never const") + let cx = ecx.cx(); + + let self_ty = goal.predicate.self_ty(); + let const_conditions = + structural_traits::const_conditions_for_sizedness(cx, self_ty, sizedness)?; + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Trivial).enter(|ecx| { + ecx.add_goals( + GoalSource::AliasBoundConstCondition, + const_conditions.into_iter().map(|trait_ref| { + goal.with( + cx, + ty::Binder::dummy(trait_ref) + .to_host_effect_clause(cx, goal.predicate.constness), + ) + }), + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } 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 de6d21da0f592..6519b47058ce2 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 weak_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, Upcast as _}; use tracing::instrument; @@ -312,11 +313,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, + _sizedness: SizedTraitKind, ) -> Result, NoSolution> { - panic!("`Sized` does not have an associated type: {:?}", goal); + panic!("`Sized`/`MetaSized`/`PointeeSized` 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 b72f776e5cb48..b2baebd19b1f6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -4,7 +4,7 @@ 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, Upcast as _, elaborate, @@ -132,9 +132,9 @@ where then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, ) -> 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 - { + let goal_did = goal.predicate.def_id(); + let trait_clause_did = trait_clause.def_id(); + if trait_clause_did == goal_did && trait_clause.polarity() == goal.predicate.polarity { if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, trait_clause.skip_binder().trait_ref.args, @@ -142,7 +142,7 @@ where return Err(NoSolution); } - ecx.probe_trait_candidate(source).enter(|ecx| { + return ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq( goal.param_env, @@ -150,13 +150,26 @@ where assumption_trait_pred.trait_ref, )?; then(ecx) - }) - } else { - Err(NoSolution) + }); + } + + // 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_did, TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(trait_clause_did, TraitSolverLangItem::Sized) + && { + let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty()); + let found_self_ty = + ecx.resolve_vars_if_possible(trait_clause.self_ty().skip_binder()); + expected_self_ty == found_self_ty + } + { + return ecx.probe_trait_candidate(source).enter(then); } - } else { - Err(NoSolution) } + + Err(NoSolution) } fn consider_auto_trait_candidate( @@ -217,9 +230,10 @@ where }) } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( ecx: &mut EvalCtxt<'_, D>, goal: Goal, + sizedness: SizedTraitKind, ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); @@ -228,7 +242,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, + ) + }, ) } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 06398dd4f725b..54d0c773a844e 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -688,6 +688,10 @@ passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct .label = not a struct +passes_rustc_non_const_sized = + attribute should be applied to a struct or enum + .label = not a struct or enum + passes_rustc_pub_transparent = attribute should be applied to `#[repr(transparent)]` types .label = not a `#[repr(transparent)]` type diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9238c73cdb113..aa3b8badcce56 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -218,6 +218,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) } + [sym::rustc_non_const_sized, ..] => { + self.check_rustc_non_const_sized(span, target) + } [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target), [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target), @@ -2615,6 +2618,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + /// `#[rustc_non_const_sized]` is a testing attribute for forcing a type to only be `Sized`, + /// not `const Sized` (which almost all types implement) - it should only be applied to structs + /// or enums. This isn't equivalent to `!const Sized` or anything like that, it just means that + /// there isn't a `impl const Sized for T`, only `impl Sized for T` in the compiler. + fn check_rustc_non_const_sized(&self, span: Span, target: Target) { + match target { + Target::Struct | Target::Enum => (), + _ => { + self.dcx().emit_err(errors::RustcNonConstSized { attr_span: span }); + } + } + } + /// Checks if `#[autodiff]` is applied to an item other than a function item. fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) { debug!("check_autodiff"); diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index a72f40cd843a7..a344b1c2ec0a3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -690,6 +690,13 @@ pub(crate) struct RustcForceInline { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_rustc_non_const_sized)] +pub(crate) struct RustcNonConstSized { + #[primary_span] + pub attr_span: Span, +} + #[derive(Diagnostic)] #[diag(passes_rustc_force_inline_coro)] pub(crate) struct RustcForceInlineCoro { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 9e55914f8f2f7..83e8257f62bcf 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -155,7 +155,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if let Some(stab) = self.parent_stab { if inherit_deprecation.yes() && stab.is_unstable() { self.index.stab_map.insert(def_id, stab); - if fn_sig.is_some_and(|s| s.header.is_const()) { + let is_const = fn_sig.is_some_and(|s| s.header.is_const()) + || (self.tcx.def_kind(def_id) == DefKind::Trait + && self.tcx.is_const_trait(def_id.to_def_id())); + if is_const { self.index.const_stab_map.insert( def_id, ConstStability::unmarked(const_stability_indirect, stab), diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 34be35e36aceb..eef0dbdf20229 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), allow(sized_hierarchy_migration))] #![cfg_attr(test, feature(test))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", @@ -14,6 +15,7 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] // tidy-alphabetical-end // Allows macros to refer to this crate as `::rustc_serialize`. diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 1eefd76f92b49..f4f59993f5112 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; -use std::marker::PhantomData; +use std::marker::{PhantomData, PointeeSized}; use std::num::NonZero; use std::path; use std::rc::Rc; @@ -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 { +pub trait Encodable: PointeeSized { fn encode(&self, s: &mut S); } @@ -198,7 +198,7 @@ direct_serialize_impls! { char emit_char read_char } -impl Encodable for &T +impl Encodable for &T where T: Encodable, { diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index eaba14bbf30f5..e844fe16697a6 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,12 +10,14 @@ #![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index c5d33f090a05b..68ca925905a7e 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,6 +7,7 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. +use std::marker::PointeeSized; use std::ops::RangeInclusive; use rustc_hir::def::DefKind; @@ -157,7 +158,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 210966bed6277..b7d83a0d874f0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1303,6 +1303,7 @@ symbols! { memtag, message, meta, + meta_sized, metadata_type, min_align_of, min_align_of_val, @@ -1552,6 +1553,7 @@ symbols! { plugin_registrar, plugins, pointee, + pointee_sized, pointee_trait, pointer, pointer_like, @@ -1802,6 +1804,7 @@ symbols! { rustc_never_returns_null_ptr, rustc_never_type_options, rustc_no_mir_inline, + rustc_non_const_sized, rustc_nonnull_optimization_guaranteed, rustc_nounwind, rustc_object_lifetime_default, @@ -1949,6 +1952,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 59c93db9c8fff..fa34a23a26fb6 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 self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) + || self.tcx.is_lang_item(trait_pred.def_id(), LangItem::MetaSized) + || self.tcx.is_lang_item(trait_pred.def_id(), LangItem::PointeeSized) + { 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 98df09b6f7b01..b9e6ae7dd61e8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -11,7 +11,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::{ DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, @@ -164,17 +164,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() { @@ -331,19 +338,28 @@ 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 { + const_sized: bool, + sized: bool, + const_meta_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::>(); 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!( @@ -355,24 +371,62 @@ 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; } } + + if let Some(host_effect_clause) = p.as_host_effect_clause() { + let self_ty = host_effect_clause.self_ty().skip_binder(); + let sizedness_of = types_with_sizedness_bounds.entry(self_ty).or_default(); + if Some(host_effect_clause.def_id()) == sized_trait { + sizedness_of.const_sized = true; + continue; + } else if Some(host_effect_clause.def_id()) == meta_sized_trait { + sizedness_of.const_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.const_sized || sizedness.sized { + // Maybe a default bound, don't write anything. + } else { + pretty_predicates.push(format!("{ty}: ?Sized")); + } + } else { + if sizedness.const_sized { + // Maybe a default bound, don't write anything. + } else if sizedness.sized { + pretty_predicates.push(format!("{ty}: Sized")); + } else if sizedness.const_meta_sized { + pretty_predicates.push(format!("{ty}: const MetaSized")); + } 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(); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index bcc247ba53c2b..124a7d154da90 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -8,6 +8,7 @@ use std::fmt::Debug; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; +use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; @@ -582,6 +583,21 @@ fn try_prove_negated_where_clause<'tcx>( return false; }; + let maybe_meta_sized_self_ty = clause + .as_trait_clause() + .filter(|c| root_infcx.tcx.is_lang_item(c.def_id(), LangItem::MetaSized)) + .map(|c| c.self_ty()); + if let Some(meta_sized_self_ty) = maybe_meta_sized_self_ty + && util::sizedness_elab_opt_fast_path_from_paramenv( + root_infcx, + meta_sized_self_ty, + param_env, + ) + .is_some() + { + return false; + } + // N.B. We don't need to use intercrate mode here because we're trying to prove // the *existence* of a negative goal, not the non-existence of a positive goal. // Without this, we over-eagerly register coherence ambiguity candidates when diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 78a452439836f..b3ad7d101d883 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -7,8 +7,8 @@ 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, @@ -541,11 +541,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` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. +/// `Self: Unsize` 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) { /// Receiver: DispatchFromDyn U]> /// } @@ -565,9 +565,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; }; @@ -581,7 +582,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` 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 = { let param_env = tcx.param_env(method.def_id); @@ -599,11 +600,18 @@ fn receiver_is_dispatchable<'tcx>( ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx) }; + let meta_sized_predicate = { + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, None); + ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty]).upcast(tcx) + }; + normalize_param_env_or_error( tcx, - ty::ParamEnv::new(tcx.mk_clauses_from_iter( - param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]), - )), + ty::ParamEnv::new(tcx.mk_clauses_from_iter(param_env.caller_bounds().iter().chain([ + unsize_predicate, + meta_sized_predicate, + trait_predicate, + ]))), ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), ) }; diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 3c127416cbf7c..c9e8ee8d46544 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -3,11 +3,10 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::traits::{ ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation, }; -use rustc_middle::span_bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, TypingMode}; +use rustc_middle::ty::{self, TypeVisitableExt}; use rustc_type_ir::elaborate::elaborate; -use rustc_type_ir::solve::NoSolution; +use rustc_type_ir::solve::{NoSolution, SizedTraitKind}; use thin_vec::{ThinVec, thin_vec}; use super::SelectionContext; @@ -24,13 +23,6 @@ pub fn evaluate_host_effect_obligation<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &HostEffectObligation<'tcx>, ) -> Result>, EvaluationFailure> { - if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) { - span_bug!( - obligation.cause.span, - "should not select host obligation in old solver in intercrate mode" - ); - } - let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone()); // Force ambiguity for infer self ty. @@ -38,19 +30,25 @@ pub fn evaluate_host_effect_obligation<'tcx>( return Err(EvaluationFailure::Ambiguous); } - match evaluate_host_effect_from_bounds(selcx, obligation) { + // FIXME: during implementation of `#![feature(sized_hierarchy)]`, when evaluating a host + // effect predicate on an opaque in addr2line, running `evaluate_host_effect_from_bounds` first + // would create an opaque type which wouldn't be removed from opaque type storage and that + // would cause a delayed bug - creating a small reproduction of this has been tricky but if + // `builtin_impls` checking is moved below `evaluate_host_effect_from_item_bounds` then it will + // trigger. + match evaluate_host_effect_from_builtin_impls(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} } - match evaluate_host_effect_from_item_bounds(selcx, obligation) { + match evaluate_host_effect_from_bounds(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} } - match evaluate_host_effect_from_builtin_impls(selcx, obligation) { + match evaluate_host_effect_from_item_bounds(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} @@ -242,10 +240,49 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>( ) -> Result>, EvaluationFailure> { match selcx.tcx().as_lang_item(obligation.predicate.def_id()) { Some(LangItem::Destruct) => evaluate_host_effect_for_destruct_goal(selcx, obligation), + Some(LangItem::Sized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::Sized) + } + Some(LangItem::MetaSized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::MetaSized) + } + Some(LangItem::PointeeSized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::PointeeSized) + } _ => Err(EvaluationFailure::NoSolution), } } +// NOTE: Keep this in sync with `const_conditions_for_sizedness` in the new solver and +// `ProvePredicate::try_fast_path` +fn evaluate_host_effect_for_sizedness_goal<'tcx>( + selcx: &mut SelectionContext<'_, 'tcx>, + obligation: &HostEffectObligation<'tcx>, + sizedness: SizedTraitKind, +) -> Result>, EvaluationFailure> { + let tcx = selcx.tcx(); + let self_ty = obligation.predicate.self_ty(); + + if self_ty.has_non_const_sizedness() { + return Err(EvaluationFailure::NoSolution); + } + + match sizedness { + SizedTraitKind::Sized => { + let meta_sized_def_id = tcx.require_lang_item(LangItem::MetaSized, None); + let meta_sized_trait_ref = ty::TraitRef::new(tcx, meta_sized_def_id, [self_ty]); + let meta_sized_obligation = obligation.with( + tcx, + ty::Binder::dummy(meta_sized_trait_ref) + .to_host_effect_clause(tcx, obligation.predicate.constness), + ); + Ok(thin_vec![meta_sized_obligation]) + } + SizedTraitKind::MetaSized => Ok(thin_vec![]), + SizedTraitKind::PointeeSized => unreachable!("`PointeeSized` is not const"), + } +} + // NOTE: Keep this in sync with `const_conditions_for_destruct` in the new solver. fn evaluate_host_effect_for_destruct_goal<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e39f8e673dbac..ae9fdf7006c86 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -24,10 +24,10 @@ use super::{ }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; -use crate::traits::EvaluateConstErr; use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::traits::{EvaluateConstErr, sizedness_fast_path}; pub(crate) type PendingPredicateObligations<'tcx> = ThinVec>; @@ -329,6 +329,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { let infcx = self.selcx.infcx; + if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) { + return ProcessResult::Changed(thin_vec::thin_vec![]); + } + if obligation.predicate.has_aliases() { let mut obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index de337710b5ef7..f2713b98f0a26 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -65,8 +65,8 @@ pub use self::specialize::{ pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::{ BoundVarReplacer, PlaceholderReplacer, elaborate, expand_trait_aliases, impl_item_is_final, - supertrait_def_ids, supertraits, transitive_bounds_that_define_assoc_item, upcast_choices, - with_replaced_escaping_bound_vars, + sizedness_fast_path, supertrait_def_ids, supertraits, transitive_bounds_that_define_assoc_item, + upcast_choices, with_replaced_escaping_bound_vars, }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::outlives::env::OutlivesEnvironment; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 4f9e2e79d624c..8b16356281f5f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -1,4 +1,3 @@ -use rustc_hir::LangItem; use rustc_infer::traits::Obligation; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; @@ -7,7 +6,7 @@ use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; use rustc_span::Span; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; -use crate::traits::ObligationCtxt; +use crate::traits::{ObligationCtxt, sizedness_fast_path}; impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { type QueryResponse = (); @@ -16,15 +15,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>, ) -> Option { - // 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. - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = - key.value.predicate.kind().skip_binder() - && tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) - && trait_ref.self_ty().is_trivially_sized(tcx) - { + if sizedness_fast_path(tcx, key.value.predicate, key.param_env) { return Some(()); } 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 fc352499146eb..aea81a4d3b956 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -16,7 +16,7 @@ use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode}; use rustc_middle::{bug, span_bug}; -use rustc_type_ir::{Interner, elaborate}; +use rustc_type_ir::{Binder, Interner, elaborate}; use tracing::{debug, instrument, trace}; use super::SelectionCandidate::*; @@ -88,8 +88,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::Sized) { // Sized is never implementable by end-users, it is // always automatically computed. - let sized_conditions = self.sized_conditions(obligation); - self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); + let conditions = self.sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); + } else if tcx.is_lang_item(def_id, LangItem::MetaSized) { + // MetaSized is never implementable by end-users, it is + // always automatically computed. + let conditions = self.meta_sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); + } else if tcx.is_lang_item(def_id, LangItem::PointeeSized) { + // PointeeSized is never implementable by end-users, it is + // always automatically computed. + let conditions = self.pointee_sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Destruct) { @@ -178,8 +188,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut distinct_normalized_bounds = FxHashSet::default(); let _ = self.for_each_item_bound::( placeholder_trait_predicate.self_ty(), - |selcx, bound, idx| { - let Some(bound) = bound.as_trait_clause() else { + |selcx, clause, idx| { + let Some(bound) = clause.as_trait_clause() else { return ControlFlow::Continue(()); }; if bound.polarity() != placeholder_trait_predicate.polarity { @@ -187,6 +197,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } selcx.infcx.probe(|_| { + if selcx + .tcx() + .is_lang_item(placeholder_trait_predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_clauses( + selcx.infcx, + Binder::dummy(placeholder_trait_predicate.self_ty()), + [clause], + ) + .is_some() + { + candidates.vec.push(ProjectionCandidate(idx)); + return; + } + // We checked the polarity already match selcx.match_normalize_trait_ref( obligation, @@ -225,6 +249,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!(?stack.obligation); + if self.tcx().is_lang_item(stack.obligation.predicate.def_id(), LangItem::MetaSized) + && let Some(bound) = util::sizedness_elab_opt_fast_path_from_paramenv( + self.infcx, + stack.obligation.self_ty(), + stack.obligation.param_env, + ) + { + candidates.vec.push(ParamCandidate(bound)); + return Ok(()); + } + let bounds = stack .obligation .param_env diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4404324d5cd74..2cbf17f3af84c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -18,7 +18,7 @@ use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; -use rustc_type_ir::elaborate; +use rustc_type_ir::{Binder, elaborate}; use thin_vec::thin_vec; use tracing::{debug, instrument}; @@ -189,6 +189,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut obligations, ); + if tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_traitrefs( + self.infcx, + obligation.predicate.self_ty(), + [Binder::dummy(candidate)], + ) + .is_some() + { + return Ok(obligations); + } + obligations.extend( self.infcx .at(&obligation.cause, obligation.param_env) @@ -257,6 +268,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_def = obligation.predicate.def_id(); let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) { self.sized_conditions(obligation) + } else if tcx.is_lang_item(trait_def, LangItem::MetaSized) { + self.meta_sized_conditions(obligation) + } else if tcx.is_lang_item(trait_def, LangItem::PointeeSized) { + self.pointee_sized_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Copy) { self.copy_clone_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Clone) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e1adabbeaa662..76fdd685c0ba7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -31,7 +31,9 @@ use rustc_middle::ty::{ TypingMode, Upcast, }; use rustc_span::{Symbol, sym}; -use rustc_type_ir::elaborate; +use rustc_type_ir::solve::SizedTraitKind; +use rustc_type_ir::{Binder, elaborate}; +use thin_vec::thin_vec; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -49,7 +51,9 @@ use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt}; -use crate::traits::{EvaluateConstErr, ProjectionCacheKey, Unimplemented, effects}; +use crate::traits::{ + EvaluateConstErr, ProjectionCacheKey, Unimplemented, effects, sizedness_fast_path, +}; mod _match; mod candidate_assembly; @@ -603,6 +607,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { None => self.check_recursion_limit(&obligation, &obligation)?, } + if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) { + return Ok(EvaluatedToOk); + } + ensure_sufficient_stack(|| { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { @@ -2059,66 +2067,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx> { - use self::BuiltinImplConditions::{Ambiguous, None, Where}; - - // NOTE: binder moved to (*) - let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); - - match self_ty.kind() { - ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) - | ty::Uint(_) - | ty::Int(_) - | ty::Bool - | ty::Float(_) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::RawPtr(..) - | ty::Char - | ty::Ref(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Array(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Never - | ty::Dynamic(_, _, ty::DynStar) - | ty::Error(_) => { - // safe for everything - Where(ty::Binder::dummy(Vec::new())) - } - - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, - - ty::Tuple(tys) => Where( - obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), - ), - - ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), - - ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(self.tcx()) { - // (*) binder moved here - Where( - obligation.predicate.rebind(vec![sized_crit.instantiate(self.tcx(), args)]), - ) - } else { - Where(ty::Binder::dummy(Vec::new())) - } - } - - // FIXME(unsafe_binders): This binder needs to be squashed - ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])), - - ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, - ty::Infer(ty::TyVar(_)) => Ambiguous, + sizedness_conditions(self, obligation, SizedTraitKind::Sized) + } - // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. - ty::Bound(..) => None, + fn meta_sized_conditions( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> BuiltinImplConditions<'tcx> { + sizedness_conditions(self, obligation, SizedTraitKind::MetaSized) + } - ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); - } - } + fn pointee_sized_conditions( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> BuiltinImplConditions<'tcx> { + sizedness_conditions(self, obligation, SizedTraitKind::PointeeSized) } fn copy_clone_conditions( @@ -2685,6 +2648,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, poly_trait_ref, ); + + if self.tcx().is_lang_item(predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_traitrefs( + self.infcx, + Binder::dummy(predicate.self_ty()), + [Binder::dummy(trait_ref)], + ) + .is_some() + { + return Ok(thin_vec![]); + } + self.infcx .at(&obligation.cause, obligation.param_env) .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) @@ -2848,6 +2823,85 @@ fn rebind_coroutine_witness_types<'tcx>( ) } +fn sizedness_conditions<'cx, 'tcx>( + ctx: &mut SelectionContext<'cx, 'tcx>, + obligation: &PolyTraitObligation<'tcx>, + sizedness: SizedTraitKind, +) -> BuiltinImplConditions<'tcx> { + use self::BuiltinImplConditions::{Ambiguous, None, Where}; + + // NOTE: binder moved to (*) + let self_ty = ctx.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); + + match self_ty.kind() { + ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Float(_) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::RawPtr(..) + | ty::Char + | ty::Ref(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Array(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Never + | ty::Dynamic(_, _, ty::DynStar) + | ty::Error(_) => { + // safe for everything + Where(ty::Binder::dummy(Vec::new())) + } + + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => None, + SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())), + SizedTraitKind::PointeeSized => Where(ty::Binder::dummy(Vec::new())), + }, + + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => None, + SizedTraitKind::PointeeSized => Where(ty::Binder::dummy(Vec::new())), + }, + + ty::Tuple(tys) => { + Where(obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last]))) + } + + ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), + + ty::Adt(def, args) => { + let constraint = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(ctx.tcx()), + SizedTraitKind::MetaSized => def.meta_sized_constraint(ctx.tcx()), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(ctx.tcx()), + }; + if let Some(crit) = constraint { + // (*) binder moved here + Where(obligation.predicate.rebind(vec![crit.instantiate(ctx.tcx(), args)])) + } else { + Where(ty::Binder::dummy(Vec::new())) + } + } + + // FIXME(unsafe_binders): This binder needs to be squashed + ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])), + + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, + ty::Infer(ty::TyVar(_)) => Ambiguous, + + // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. + ty::Bound(..) => None, + + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); + } + } +} + impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList::with(self) diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 15f5cf916a48b..5117a81dcbf90 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,14 +1,17 @@ use std::collections::{BTreeMap, VecDeque}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; pub use rustc_infer::traits::util::*; use rustc_middle::bug; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::Span; +use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::{InferCtxtLike, Interner, Upcast}; use smallvec::{SmallVec, smallvec}; use tracing::debug; @@ -504,3 +507,133 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { } } } + +/// 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` predicate. This is a helper +/// function for that special-casing, intended to be used when the obligation to be proven has been +/// confirmed to be `MetaSized`, and checking whether the `param_env` contains `Sized` for the same +/// `self_ty` is all that remains to be done. +// Ideally this would be re-used by the next solver, but there is no `InferCtxtLike` implementor. +pub(crate) fn sizedness_elab_opt_fast_path_from_paramenv( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder, + param_env: I::ParamEnv, +) -> Option>> +where + I: Interner, + Infcx: InferCtxtLike, +{ + #[allow(rustc::usage_of_type_ir_inherent)] + use rustc_type_ir::inherent::*; + sizedness_elab_opt_fast_path_from_clauses(infcx, self_ty, param_env.caller_bounds().iter()) +} + +/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of clauses instead +/// of a parameter environment. +pub(crate) fn sizedness_elab_opt_fast_path_from_clauses( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder, + clauses: Trs, +) -> Option>> +where + I: Interner, + Infcx: InferCtxtLike, + Trs: IntoIterator, +{ + #[allow(rustc::usage_of_type_ir_inherent)] + use rustc_type_ir::inherent::*; + sizedness_elab_opt_fast_path_from_traitrefs( + infcx, + self_ty, + clauses + .into_iter() + .filter_map(|p| p.as_trait_clause()) + .map(|c| c.map_bound(|c| c.trait_ref)), + ) + .map(|f| f.map_bound(|f| f.upcast(infcx.cx()))) +} + +/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of trait refs instead +/// of a parameter environment. +pub(crate) fn sizedness_elab_opt_fast_path_from_traitrefs( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder, + trait_refs: TraitRefs, +) -> Option>> +where + I: Interner, + Infcx: InferCtxtLike, + TraitRefs: IntoIterator>>, +{ + trait_refs.into_iter().find(|c| { + let expected_self_ty = infcx.resolve_vars_if_possible(self_ty); + let found_self_ty = infcx.resolve_vars_if_possible(c.self_ty()); + expected_self_ty == found_self_ty + && infcx.cx().is_lang_item(c.def_id(), TraitSolverLangItem::Sized) + }) +} + +pub fn sizedness_fast_path<'tcx>( + tcx: TyCtxt<'tcx>, + predicate: ty::Predicate<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> bool { + // Proving `Sized`/`MetaSized`/`PointeeSized`, 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() + { + let sizedness = if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + Some(SizedTraitKind::Sized) + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::MetaSized) { + Some(SizedTraitKind::MetaSized) + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::PointeeSized) { + Some(SizedTraitKind::PointeeSized) + } else { + None + }; + + if let Some(sizedness) = sizedness + && trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) + { + debug!("fast path -- trivial sizedness"); + return true; + } + + if matches!(sizedness, Some(SizedTraitKind::MetaSized)) { + let has_sized_in_param_env = param_env + .caller_bounds() + .iter() + .rev() // sizedness predicates are normally at the end for diagnostics reasons + .filter_map(|p| p.as_trait_clause()) + .any(|c| { + trait_ref.self_ty() == c.skip_binder().self_ty() + && tcx.is_lang_item(c.def_id(), LangItem::Sized) + }); + if has_sized_in_param_env { + debug!("fast path -- metasized paramenv"); + return true; + } + } + } + + // Likewise, determining if a sizedness trait is implemented const-ly is a trivial + // determination that can happen in the fast path. + // + // NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver, + // `const_conditions_for_sizedness` in the new solver. + if let ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(host_pred)) = + predicate.kind().skip_binder() + { + let is_sizedness = tcx.is_lang_item(host_pred.def_id(), LangItem::Sized) + || tcx.is_lang_item(host_pred.def_id(), LangItem::MetaSized); + + if is_sizedness && !host_pred.self_ty().has_non_const_sizedness() { + debug!("fast path -- host effect"); + return true; + } + } + + false +} diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 4a889abfc28f1..e86507335cc5f 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,11 +6,11 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Upcast}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, - Unimplemented, + Unimplemented, sizedness_fast_path, }; use tracing::debug; @@ -34,6 +34,13 @@ pub(crate) fn codegen_select_candidate<'tcx>( let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let mut selcx = SelectionContext::new(&infcx); + if sizedness_fast_path(tcx, trait_ref.upcast(tcx), param_env) { + return Ok(&*tcx.arena.alloc(ImplSource::Builtin( + ty::solve::BuiltinImplSource::Trivial, + Default::default(), + ))); + } + let obligation_cause = ObligationCause::dummy(); let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref); diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index c9ad096c6e9d0..819b8e3231ce2 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -5,6 +5,7 @@ use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::CanonicalPredicateGoal; use rustc_trait_selection::traits::{ EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode, + sizedness_fast_path, }; use tracing::debug; @@ -23,6 +24,10 @@ fn evaluate_obligation<'tcx>( debug!("evaluate_obligation: goal={:#?}", goal); let ParamEnvAnd { param_env, value: predicate } = goal; + if sizedness_fast_path(tcx, predicate, param_env) { + return Ok(EvaluationResult::EvaluatedToOk); + } + let mut selcx = SelectionContext::with_query_mode(infcx, TraitQueryMode::Canonical); let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9dc4f11e456e2..04f1370629533 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,17 +6,24 @@ use rustc_index::bit_set::DenseBitSet; 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; +/// Returns `Some(ty)` if the type might not or does not implement the given `sizedness` trait +/// (`Sized`, `MetaSized` or `PointeeSized`). #[instrument(level = "debug", skip(tcx), ret)] -fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option> { +fn sizedness_constraint_for_ty<'tcx>( + tcx: TyCtxt<'tcx>, + sizedness: SizedTraitKind, + ty: Ty<'tcx>, +) -> Option> { match ty.kind() { - // these are always sized + // Always `Sized`, `MetaSized` or `PointeeSized` ty::Bool | ty::Char | ty::Int(..) @@ -34,31 +41,51 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option 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` and `PointeeSized` + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => None, + }, - // these can be sized or unsized. + // Maybe `Sized`, `MetaSized` or `PointeeSized` 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) + } + + ty::Foreign(..) => match sizedness { + // Never `MetaSized` or `Sized` + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Some(ty), + // Always `PointeeSized` + SizedTraitKind::PointeeSized => None, + }, + + // 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) => { + let constraint = match sizedness { + SizedTraitKind::Sized => adt.sized_constraint(tcx), + SizedTraitKind::MetaSized => adt.meta_sized_constraint(tcx), + SizedTraitKind::PointeeSized => adt.pointee_sized_constraint(tcx), + }; + constraint.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`") } } } @@ -77,12 +104,47 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { /// Calculates the `Sized` constraint. /// /// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type +/// - 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 #[instrument(level = "debug", skip(tcx), ret)] fn adt_sized_constraint<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, +) -> Option>> { + adt_sizedness_constraint(tcx, SizedTraitKind::Sized, def_id) +} + +/// Calculates the `MetaSized` constraint. +/// +/// In fact, 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_meta_sized_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Option>> { + adt_sizedness_constraint(tcx, SizedTraitKind::MetaSized, def_id) +} + +/// Calculates the `PointeeSized` constraint. +/// +/// In fact, there is only one option for the types in the constraint: a type parameter or +/// projection whose sizedness can't be known. +#[instrument(level = "debug", skip(tcx), ret)] +fn adt_pointee_sized_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Option>> { + adt_sizedness_constraint(tcx, SizedTraitKind::PointeeSized, def_id) +} + +#[instrument(level = "debug", skip(tcx), ret)] +fn adt_sizedness_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + sizedness: SizedTraitKind, + def_id: DefId, ) -> Option>> { if let Some(def_id) = def_id.as_local() { if let ty::Representability::Infinite(_) = tcx.representability(def_id) { @@ -92,21 +154,26 @@ 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,Pointee,}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, None); + let lang_item = match sizedness { + SizedTraitKind::Sized => LangItem::Sized, + SizedTraitKind::MetaSized => LangItem::MetaSized, + SizedTraitKind::PointeeSized => LangItem::PointeeSized, + }; + let sizedness_trait_def_id = tcx.require_lang_item(lang_item, None); 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 }) }) { @@ -316,6 +383,8 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { asyncness, adt_sized_constraint, + adt_meta_sized_constraint, + adt_pointee_sized_constraint, param_env, param_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 b11bcff1d8bbb..f417b5ee82e8d 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 _}; @@ -79,20 +80,57 @@ pub fn elaborate>( ) -> Elaborator { let mut elaborator = Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All }; - elaborator.extend_deduped(obligations); + elaborator.extend_deduped(None, obligations); elaborator } impl> Elaborator { - fn extend_deduped(&mut self, obligations: impl IntoIterator) { + /// Adds `obligations` to the stack. `current_clause` is the clause which was elaborated to + /// produce these obligations. + fn extend_deduped( + &mut self, + current_clause: Option, + obligations: impl IntoIterator, + ) { // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some // cases. One common case is when people define // `trait Sized: Sized { }` rather than `trait Sized { }`. self.stack.extend( - obligations.into_iter().filter(|o| { - self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind())) - }), + obligations + .into_iter() + .filter(|o| self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind()))) + .filter(|o| { + let Some(current_clause) = current_clause else { + return true; + }; + let Some(next_clause) = o.predicate().as_clause() else { + return true; + }; + + let current_did = match current_clause.kind().skip_binder() { + ty::ClauseKind::Trait(data) => data.def_id(), + ty::ClauseKind::HostEffect(data) => data.def_id(), + _ => return true, + }; + let next_did = match next_clause.kind().skip_binder() { + ty::ClauseKind::Trait(data) => data.def_id(), + ty::ClauseKind::HostEffect(data) => data.def_id(), + _ => return true, + }; + + // 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.cx.is_lang_item(current_did, TraitSolverLangItem::Sized) { + !self.cx.is_lang_item(next_did, TraitSolverLangItem::MetaSized) + } else { + true + } + }), ); } @@ -132,12 +170,14 @@ impl> Elaborator { // Get predicates implied by the trait, or only super predicates if we only care about self predicates. match self.mode { Filter::All => self.extend_deduped( + Some(clause), cx.explicit_implied_predicates_of(data.def_id()) .iter_identity() .enumerate() .map(map_to_child_clause), ), Filter::OnlySelf => self.extend_deduped( + Some(clause), cx.explicit_super_predicates_of(data.def_id()) .iter_identity() .enumerate() @@ -147,6 +187,7 @@ impl> Elaborator { } // `T: ~const Trait` implies `T: ~const Supertrait`. ty::ClauseKind::HostEffect(data) => self.extend_deduped( + Some(clause), cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { elaboratable.child( trait_ref @@ -177,6 +218,7 @@ impl> Elaborator { let mut components = smallvec![]; push_outlives_components(cx, ty_max, &mut components); self.extend_deduped( + Some(clause), components .into_iter() .filter_map(|component| elaborate_component_to_clause(cx, component, r_min)) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6a2498242feeb..0673f969fe271 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -126,5 +126,8 @@ bitflags::bitflags! { /// Does this have any binders with bound vars (e.g. that need to be anonymized)? const HAS_BINDER_VARS = 1 << 23; + + /// Does this type only have non-const implementations of sizedness traits? + const HAS_NON_CONST_SIZEDNESS = 1 << 24; } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index d4134bdf3a782..4854d79d43fea 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -559,6 +559,8 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { fn all_field_tys(self, interner: I) -> ty::EarlyBinder>; fn sized_constraint(self, interner: I) -> Option>; + fn meta_sized_constraint(self, interner: I) -> Option>; + fn pointee_sized_constraint(self, interner: I) -> Option>; 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 65f7cdf8f922b..283a6f2758105 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -31,7 +31,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 3aec4804b2799..8ac529d2cbd1e 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -309,3 +309,14 @@ pub enum AdtDestructorKind { NotConst, Const, } + +/// Which sizedness trait - `Sized`, `MetaSized` or `PointeeSized`? +#[derive(Copy, Clone, Debug)] +pub enum SizedTraitKind { + /// `Sized` trait + Sized, + /// `MetaSized` trait + MetaSized, + /// `PointeeSized` trait + PointeeSized, +} diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 2285e0e75de04..d8d81257ab615 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -342,6 +342,11 @@ pub trait TypeVisitableExt: TypeVisitable { self.has_type_flags(TypeFlags::HAS_BOUND_VARS) } + /// Returns `true` if this type only has non-const implementations of sizedness traits. + fn has_non_const_sizedness(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_NON_CONST_SIZEDNESS) + } + /// Indicates whether this value still has parameters/placeholders/inference variables /// which could be replaced later, in a way that would change the results of `impl` /// specialization. diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index e0ac0bfc5289f..27fa9d05f0f0e 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 for the ability to explicitly duplicate an object. @@ -248,7 +250,7 @@ impl_use_cloned! { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsClone { +pub struct AssertParamIsClone { _field: crate::marker::PhantomData, } #[doc(hidden)] @@ -258,7 +260,7 @@ pub struct AssertParamIsClone { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsCopy { +pub struct AssertParamIsCopy { _field: crate::marker::PhantomData, } @@ -495,6 +497,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)*) => { $( @@ -525,7 +529,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for *const T { + impl Clone for *const T { #[inline(always)] fn clone(&self) -> Self { *self @@ -533,7 +537,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for *mut T { + impl Clone for *mut T { #[inline(always)] fn clone(&self) -> Self { *self @@ -542,7 +546,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for &T { + impl Clone for &T { #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { @@ -552,5 +556,5 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl !Clone for &mut T {} + impl !Clone for &mut T {} } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 0b0dbf723b658..7328b73ab25a1 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,6 +247,37 @@ use crate::ops::ControlFlow; append_const_msg )] #[rustc_diagnostic_item = "PartialEq"] +#[cfg(not(bootstrap))] // FIXME(sized_hierarchy): needs bootstrap updated +pub trait PartialEq: PointeeSized { + /// Tests for `self` and `other` values to be equal, and is used by `==`. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "cmp_partialeq_eq"] + fn eq(&self, other: &Rhs) -> bool; + + /// Tests for `!=`. The default implementation is almost always sufficient, + /// and should not be overridden without very good reason. + #[inline] + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "cmp_partialeq_ne"] + fn ne(&self, other: &Rhs) -> bool { + !self.eq(other) + } +} + +#[allow(missing_docs)] +#[lang = "eq"] +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = "==")] +#[doc(alias = "!=")] +#[rustc_on_unimplemented( + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} == {Rhs}`", + append_const_msg +)] +#[rustc_diagnostic_item = "PartialEq"] +#[cfg(bootstrap)] // FIXME(sized_hierarchy): needs bootstrap updated pub trait PartialEq { /// Tests for `self` and `other` values to be equal, and is used by `==`. #[must_use] @@ -332,7 +364,7 @@ pub macro PartialEq($item:item) { #[doc(alias = "!=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Eq"] -pub trait Eq: PartialEq { +pub trait Eq: PartialEq + 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 +393,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 { +pub struct AssertParamIsEq { _field: crate::marker::PhantomData, } @@ -954,7 +986,7 @@ impl Clone for Reverse { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -pub trait Ord: Eq + PartialOrd { +pub trait Ord: Eq + PartialOrd + PointeeSized { /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression @@ -1337,7 +1369,8 @@ pub macro Ord($item:item) { append_const_msg )] #[rustc_diagnostic_item = "PartialOrd"] -pub trait PartialOrd: PartialEq { +#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +pub trait PartialOrd: PartialEq + PointeeSized { /// This method returns an ordering between `self` and `other` values if one exists. /// /// # Examples @@ -1481,7 +1514,7 @@ pub trait PartialOrd: PartialEq { } } -fn default_chaining_impl( +fn default_chaining_impl( lhs: &T, rhs: &U, p: impl FnOnce(Ordering) -> bool, @@ -1803,6 +1836,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 { @@ -2019,7 +2053,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&B> for &A + impl PartialEq<&B> for &A where A: PartialEq, { @@ -2033,7 +2067,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&B> for &A + impl PartialOrd<&B> for &A where A: PartialOrd, { @@ -2059,7 +2093,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &A + impl Ord for &A where A: Ord, { @@ -2069,12 +2103,12 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Eq for &A where A: Eq {} + impl Eq for &A where A: Eq {} // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&mut B> for &mut A + impl PartialEq<&mut B> for &mut A where A: PartialEq, { @@ -2088,7 +2122,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&mut B> for &mut A + impl PartialOrd<&mut B> for &mut A where A: PartialOrd, { @@ -2114,7 +2148,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &mut A + impl Ord for &mut A where A: Ord, { @@ -2124,10 +2158,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Eq for &mut A where A: Eq {} + impl Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&mut B> for &A + impl PartialEq<&mut B> for &A where A: PartialEq, { @@ -2142,7 +2176,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&B> for &mut A + impl PartialEq<&B> for &mut A where A: PartialEq, { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e1b10e1074d27..ca823a31e89c4 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(x: T) -> T { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AsRef"] -pub trait AsRef { +pub trait AsRef: 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 { /// `&mut Vec`, 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 { +pub trait AsMut: 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; @@ -695,7 +696,7 @@ pub trait TryFrom: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef for &T +impl AsRef for &T where T: AsRef, { @@ -707,7 +708,7 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef for &mut T +impl AsRef for &mut T where T: AsRef, { @@ -727,7 +728,7 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl AsMut for &mut T +impl AsMut for &mut T where T: AsMut, { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 30fd2d7815f51..64baa591bdcb0 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, mem, result, str}; @@ -898,7 +898,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 @@ -1015,7 +1015,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 @@ -1091,7 +1091,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; @@ -1150,7 +1150,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; @@ -1205,7 +1205,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; @@ -1260,7 +1260,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; @@ -1319,7 +1319,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; @@ -1370,7 +1370,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; @@ -1421,7 +1421,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; @@ -2694,11 +2694,11 @@ macro_rules! fmt_refs { ($($tr:ident),*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - impl $tr for &T { + impl $tr for &T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] - impl $tr for &mut T { + impl $tr for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } )* @@ -2820,7 +2820,7 @@ impl Display for char { } #[stable(feature = "rust1", since = "1.0.0")] -impl Pointer for *const T { +impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { if <::Metadata as core::unit::IsUnit>::is_unit() { pointer_fmt_inner(self.expose_provenance(), f) @@ -2865,21 +2865,21 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul } #[stable(feature = "rust1", since = "1.0.0")] -impl Pointer for *mut T { +impl 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 Pointer for &T { +impl 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 Pointer for &mut T { +impl Pointer for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(&**self as *const T), f) } @@ -2888,13 +2888,13 @@ impl Pointer for &mut T { // Implementation of Display/Debug for various core types #[stable(feature = "rust1", since = "1.0.0")] -impl Debug for *const T { +impl Debug for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Debug for *mut T { +impl 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 f7b874b26bb74..efda64791d403 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 Hash for &T { + impl Hash for &T { #[inline] fn hash(&self, state: &mut H) { (**self).hash(state); @@ -949,7 +949,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Hash for &mut T { + impl Hash for &mut T { #[inline] fn hash(&self, state: &mut H) { (**self).hash(state); @@ -957,7 +957,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Hash for *const T { + impl Hash for *const T { #[inline] fn hash(&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 Hash for *mut T { + impl Hash for *mut T { #[inline] fn hash(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 81e59a1f349ec..4cb42b8ff48af 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -64,7 +64,7 @@ )] #![allow(missing_docs)] -use crate::marker::{DiscriminantKind, Tuple}; +use crate::marker::{DiscriminantKind, PointeeSized, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; @@ -3615,10 +3615,10 @@ pub const fn aggregate_raw_ptr, D, M>(data: pub trait AggregateRawPtr { type Metadata: Copy; } -impl AggregateRawPtr<*const T> for *const P { +impl AggregateRawPtr<*const T> for *const P { type Metadata =

::Metadata; } -impl AggregateRawPtr<*mut T> for *mut P { +impl AggregateRawPtr<*mut T> for *mut P { type Metadata =

::Metadata; } @@ -3629,7 +3629,9 @@ impl AggregateRawPtr<*mut T> for *mut P { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn ptr_metadata + ?Sized, M>(ptr: *const P) -> M; +pub const fn ptr_metadata + ?Sized + PointeeSized, M>( + ptr: *const P, +) -> M; // Some functions are defined here because they accidentally got made // available in this module on stable. See . diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 68011310d2cad..3a6b953cf2a98 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -92,15 +92,15 @@ pub unsafe auto trait Send { } #[stable(feature = "rust1", since = "1.0.0")] -impl !Send for *const T {} +impl !Send for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl !Send for *mut T {} +impl !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 Send for &T {} +unsafe impl Send for &T {} /// Types with a constant size known at compile time. /// @@ -151,10 +151,54 @@ unsafe impl Send for &T {} #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] #[rustc_coinductive] -pub trait Sized { +#[cfg_attr(not(bootstrap), const_trait)] +#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "sized_hierarchy", issue = "none"))] +pub trait Sized: MetaSized { // Empty. } +/// Types with a size that can be determined from pointer metadata. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[cfg_attr(not(bootstrap), 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] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[rustc_do_not_implement_via_object] +#[rustc_coinductive] +#[cfg_attr(not(bootstrap), const_trait)] +#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "sized_hierarchy", issue = "none"))] +pub trait MetaSized: PointeeSized { + // Empty +} + +#[cfg(bootstrap)] +#[unstable(feature = "sized_hierarchy", issue = "none")] +impl MetaSized for T {} + +/// Types that may or may not have a size. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[cfg_attr(not(bootstrap), 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] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[rustc_do_not_implement_via_object] +#[rustc_coinductive] +pub trait PointeeSized { + // Empty +} + +#[cfg(bootstrap)] +#[unstable(feature = "sized_hierarchy", issue = "none")] +impl PointeeSized for T {} + /// Types that can be "unsized" to a dynamically-sized type. /// /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and @@ -191,7 +235,7 @@ pub trait Sized { #[lang = "unsize"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Unsize { +pub trait Unsize: PointeeSized { // Empty. } @@ -228,7 +272,7 @@ marker_impls! { (), {T, const N: usize} [T; N], {T} [T], - {T: ?Sized} &T, + {T: ?Sized + PointeeSized} &T, } /// Types whose values can be duplicated simply by copying bits. @@ -441,8 +485,8 @@ marker_impls! { isize, i8, i16, i32, i64, i128, f16, f32, f64, f128, bool, char, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, } @@ -451,7 +495,7 @@ impl Copy for ! {} /// Shared references can be copied, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] -impl Copy for &T {} +impl Copy for &T {} /// Marker trait for the types that are allowed in union fields and unsafe /// binder types. @@ -635,9 +679,9 @@ pub unsafe auto trait Sync { } #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for *const T {} +impl !Sync for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for *mut T {} +impl !Sync for *mut T {} /// Zero-sized type used to mark things that "act like" they own a `T`. /// @@ -774,57 +818,57 @@ impl !Sync for *mut T {} /// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct PhantomData; +pub struct PhantomData; #[stable(feature = "rust1", since = "1.0.0")] -impl Hash for PhantomData { +impl Hash for PhantomData { #[inline] fn hash(&self, _: &mut H) {} } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for PhantomData { +impl cmp::PartialEq for PhantomData { fn eq(&self, _other: &PhantomData) -> bool { true } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for PhantomData {} +impl cmp::Eq for PhantomData {} #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialOrd for PhantomData { +impl cmp::PartialOrd for PhantomData { fn partial_cmp(&self, _other: &PhantomData) -> Option { Option::Some(cmp::Ordering::Equal) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Ord for PhantomData { +impl cmp::Ord for PhantomData { fn cmp(&self, _other: &PhantomData) -> cmp::Ordering { cmp::Ordering::Equal } } #[stable(feature = "rust1", since = "1.0.0")] -impl Copy for PhantomData {} +impl Copy for PhantomData {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for PhantomData { +impl Clone for PhantomData { fn clone(&self) -> Self { Self } } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for PhantomData { +impl Default for PhantomData { fn default() -> Self { Self } } #[unstable(feature = "structural_match", issue = "31434")] -impl StructuralPartialEq for PhantomData {} +impl StructuralPartialEq for PhantomData {} /// Compiler-internal trait used to indicate the type of enum discriminants. /// @@ -867,15 +911,15 @@ pub trait DiscriminantKind { pub unsafe auto trait Freeze {} #[unstable(feature = "freeze", issue = "121675")] -impl !Freeze for UnsafeCell {} +impl !Freeze for UnsafeCell {} marker_impls! { #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for - {T: ?Sized} PhantomData, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: ?Sized + PointeeSized} PhantomData, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, + {T: ?Sized + PointeeSized} &T, + {T: ?Sized + PointeeSized} &mut T, } /// Types that do not require any pinning guarantees. @@ -963,15 +1007,15 @@ impl !Unpin for PhantomPinned {} marker_impls! { #[stable(feature = "pin", since = "1.33.0")] Unpin for - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: ?Sized + PointeeSized} &T, + {T: ?Sized + PointeeSized} &mut T, } marker_impls! { #[stable(feature = "pin_raw", since = "1.38.0")] Unpin for - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + 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 e74f5443ac2d8..f5fa5c4e0ef0c 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,8 @@ impl 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 { +#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +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 +296,7 @@ impl 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 DerefPure for &T {} @@ -366,7 +369,7 @@ unsafe impl 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 +396,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 LegacyReceiver for &T {} +impl LegacyReceiver for &T {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl LegacyReceiver for &mut T {} +impl LegacyReceiver for &mut T {} diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index d2a07197f6f6a..2080b05d053fd 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,67 @@ use crate::marker::Unsize; /// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "coerce_unsized", issue = "18598")] #[lang = "coerce_unsized"] -pub trait CoerceUnsized { +pub trait CoerceUnsized { // Empty. } // &mut T -> &mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + 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: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} +impl<'a, 'b: 'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> + CoerceUnsized<&'a U> for &'b mut T +{ +} // &mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> CoerceUnsized<*mut U> + for &'a mut T +{ +} // &mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for &'a mut T +{ +} // &T -> &U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> + CoerceUnsized<&'a U> for &'b T +{ +} // &T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for &'a T +{ +} // *mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl, U: ?Sized + PointeeSized> CoerceUnsized<*mut U> + for *mut T +{ +} // *mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} +impl, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for *mut T +{ +} // *const T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} +impl, U: ?Sized + 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 +149,25 @@ pub trait DispatchFromDyn { // &T -> &U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> DispatchFromDyn<&'a U> + for &'a T +{ +} // &mut T -> &mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize, U: ?Sized + PointeeSized> DispatchFromDyn<&'a mut U> + for &'a mut T +{ +} // *const T -> *const U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl, U: ?Sized + PointeeSized> DispatchFromDyn<*const U> + for *const T +{ +} // *mut T -> *mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} +impl, U: ?Sized + PointeeSized> DispatchFromDyn<*mut U> + for *mut T +{ +} diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs index 8d867a269a21a..2405995e97b49 100644 --- a/library/core/src/prelude/mod.rs +++ b/library/core/src/prelude/mod.rs @@ -92,4 +92,8 @@ pub mod rust_future { #[stable(feature = "prelude_2024", since = "1.85.0")] #[doc(no_inline)] pub use crate::future::{Future, IntoFuture}; + + #[unstable(feature = "prelude_next", issue = "none")] + #[doc(no_inline)] + pub use crate::marker::{MetaSized, PointeeSized}; } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 7d0839aff3f73..c2ca6dbc51c20 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 *const T { +impl *const T { /// Returns `true` if the pointer is null. /// /// Note that unsized types have many possible null pointers, as only the @@ -120,7 +120,7 @@ impl *const T { #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *const U where - U: ?Sized, + U: ?Sized + PointeeSized, { from_raw_parts::(self as *const (), metadata(meta)) } @@ -1677,7 +1677,7 @@ impl *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 PartialEq for *const T { +impl PartialEq for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*const T) -> bool { @@ -1687,11 +1687,11 @@ impl PartialEq for *const T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *const T {} +impl 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 Ord for *const T { +impl Ord for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*const T) -> Ordering { @@ -1707,7 +1707,7 @@ impl 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 PartialOrd for *const T { +impl PartialOrd for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*const T) -> Option { diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 9c5da306e27a7..c511830b73a98 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; +pub trait Thin = Pointee + PointeeSized; /// Extracts the metadata component of a pointer. /// @@ -96,7 +96,7 @@ pub trait Thin = Pointee; /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` #[inline] -pub const fn metadata(ptr: *const T) -> ::Metadata { +pub const fn metadata(ptr: *const T) -> ::Metadata { ptr_metadata(ptr) } @@ -109,7 +109,7 @@ pub const fn metadata(ptr: *const T) -> ::Metadata { /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts( +pub const fn from_raw_parts( data_pointer: *const impl Thin, metadata: ::Metadata, ) -> *const T { @@ -122,7 +122,7 @@ pub const fn from_raw_parts( /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts_mut( +pub const fn from_raw_parts_mut( data_pointer: *mut impl Thin, metadata: ::Metadata, ) -> *mut T { @@ -152,7 +152,7 @@ pub const fn from_raw_parts_mut( /// 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 { +pub struct DynMetadata { _vtable_ptr: NonNull, _phantom: crate::marker::PhantomData, } @@ -165,7 +165,7 @@ unsafe extern "C" { type VTable; } -impl DynMetadata { +impl DynMetadata { /// 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 DynMetadata { } } -unsafe impl Send for DynMetadata {} -unsafe impl Sync for DynMetadata {} +unsafe impl Send for DynMetadata {} +unsafe impl Sync for DynMetadata {} -impl fmt::Debug for DynMetadata { +impl fmt::Debug for DynMetadata { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish() } @@ -217,27 +217,27 @@ impl fmt::Debug for DynMetadata { // Manual impls needed to avoid `Dyn: $Trait` bounds. -impl Unpin for DynMetadata {} +impl Unpin for DynMetadata {} -impl Copy for DynMetadata {} +impl Copy for DynMetadata {} -impl Clone for DynMetadata { +impl Clone for DynMetadata { #[inline] fn clone(&self) -> Self { *self } } -impl Eq for DynMetadata {} +impl Eq for DynMetadata {} -impl PartialEq for DynMetadata { +impl PartialEq for DynMetadata { #[inline] fn eq(&self, other: &Self) -> bool { crate::ptr::eq::(self.vtable_ptr(), other.vtable_ptr()) } } -impl Ord for DynMetadata { +impl Ord for DynMetadata { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> crate::cmp::Ordering { @@ -245,14 +245,14 @@ impl Ord for DynMetadata { } } -impl PartialOrd for DynMetadata { +impl PartialOrd for DynMetadata { #[inline] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Hash for DynMetadata { +impl Hash for DynMetadata { #[inline] fn hash(&self, hasher: &mut H) { crate::ptr::hash::(self.vtable_ptr(), hasher) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ea53da78d3bd2..1c0e80ddb6d35 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -396,7 +396,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::{fmt, hash, intrinsics, ub_checks}; @@ -520,7 +520,7 @@ mod mut_ptr; #[lang = "drop_in_place"] #[allow(unconditional_recursion)] #[rustc_diagnostic_item = "ptr_drop_in_place"] -pub unsafe fn drop_in_place(to_drop: *mut T) { +pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. @@ -549,7 +549,7 @@ pub unsafe fn drop_in_place(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() -> *const T { +pub const fn null() -> *const T { from_raw_parts(without_provenance::<()>(0), ()) } @@ -574,7 +574,7 @@ pub const fn null() -> *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() -> *mut T { +pub const fn null_mut() -> *mut T { from_raw_parts_mut(without_provenance_mut::<()>(0), ()) } @@ -792,7 +792,7 @@ pub fn with_exposed_provenance_mut(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(r: &T) -> *const T { +pub const fn from_ref(r: &T) -> *const T { r } @@ -842,7 +842,7 @@ pub const fn from_ref(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(r: &mut T) -> *mut T { +pub const fn from_mut(r: &mut T) -> *mut T { r } @@ -2067,7 +2067,7 @@ pub(crate) unsafe fn align_offset(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(a: *const T, b: *const T) -> bool { +pub fn eq(a: *const T, b: *const T) -> bool { a == b } @@ -2091,7 +2091,10 @@ pub fn eq(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(p: *const T, q: *const U) -> bool { +pub fn addr_eq( + p: *const T, + q: *const U, +) -> bool { (p as *const ()) == (q as *const ()) } @@ -2174,7 +2177,7 @@ pub fn fn_addr_eq(f: T, g: U) -> bool { /// assert_eq!(actual, expected); /// ``` #[stable(feature = "ptr_hash", since = "1.35.0")] -pub fn hash(hashee: *const T, into: &mut S) { +pub fn hash(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 b960a3d86bef0..f55657fd7a234 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 *mut T { +impl *mut T { /// Returns `true` if the pointer is null. /// /// Note that unsized types have many possible null pointers, as only the @@ -101,7 +102,7 @@ impl *mut T { #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *mut U where - U: ?Sized, + U: ?Sized + PointeeSized, { from_raw_parts_mut::(self as *mut (), metadata(meta)) } @@ -2094,7 +2095,7 @@ impl *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 PartialEq for *mut T { +impl PartialEq for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*mut T) -> bool { @@ -2104,11 +2105,11 @@ impl PartialEq for *mut T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *mut T {} +impl 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 Ord for *mut T { +impl Ord for *mut T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*mut T) -> Ordering { @@ -2124,7 +2125,7 @@ impl 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 PartialOrd for *mut T { +impl PartialOrd for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*mut T) -> Option { diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c769ba673c61e..73117f051c6d7 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 { +pub struct NonNull { // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to // this is banned by . pointer: *const T, @@ -76,12 +76,12 @@ pub struct NonNull { /// `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 !Send for NonNull {} +impl !Send for NonNull {} /// `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 !Sync for NonNull {} +impl !Sync for NonNull {} impl NonNull { /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. @@ -189,7 +189,7 @@ impl NonNull { } } -impl NonNull { +impl NonNull { /// Creates a new `NonNull`. /// /// # Safety @@ -1572,7 +1572,7 @@ impl NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl Clone for NonNull { +impl Clone for NonNull { #[inline(always)] fn clone(&self) -> Self { *self @@ -1580,39 +1580,45 @@ impl Clone for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl Copy for NonNull {} +impl Copy for NonNull {} #[unstable(feature = "coerce_unsized", issue = "18598")] -impl CoerceUnsized> for NonNull where T: Unsize {} +impl CoerceUnsized> for NonNull where + T: Unsize +{ +} #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl DispatchFromDyn> for NonNull where T: Unsize {} +impl DispatchFromDyn> for NonNull where + T: Unsize +{ +} #[stable(feature = "pin", since = "1.33.0")] -unsafe impl PinCoerceUnsized for NonNull {} +unsafe impl PinCoerceUnsized for NonNull {} #[unstable(feature = "pointer_like_trait", issue = "none")] impl core::marker::PointerLike for NonNull {} #[stable(feature = "nonnull", since = "1.25.0")] -impl fmt::Debug for NonNull { +impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl fmt::Pointer for NonNull { +impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl Eq for NonNull {} +impl Eq for NonNull {} #[stable(feature = "nonnull", since = "1.25.0")] -impl PartialEq for NonNull { +impl PartialEq for NonNull { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &Self) -> bool { @@ -1621,7 +1627,7 @@ impl PartialEq for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl Ord for NonNull { +impl Ord for NonNull { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> Ordering { @@ -1630,7 +1636,7 @@ impl Ord for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl PartialOrd for NonNull { +impl PartialOrd for NonNull { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &Self) -> Option { @@ -1639,7 +1645,7 @@ impl PartialOrd for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl hash::Hash for NonNull { +impl hash::Hash for NonNull { #[inline] fn hash(&self, state: &mut H) { self.as_ptr().hash(state) @@ -1647,7 +1653,7 @@ impl hash::Hash for NonNull { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From> for NonNull { +impl From> for NonNull { #[inline] fn from(unique: Unique) -> Self { unique.as_non_null_ptr() @@ -1655,7 +1661,7 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&mut T> for NonNull { +impl From<&mut T> for NonNull { /// Converts a `&mut T` to a `NonNull`. /// /// This conversion is safe and infallible since references cannot be null. @@ -1666,7 +1672,7 @@ impl From<&mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&T> for NonNull { +impl From<&T> for NonNull { /// Converts a `&T` to a `NonNull`. /// /// 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 4810ebe01f9bb..10870a858e2e1 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 { +pub struct Unique { pointer: NonNull, // 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 { /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. #[unstable(feature = "ptr_internals", issue = "none")] -unsafe impl Send for Unique {} +unsafe impl Send for Unique {} /// `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 Sync for Unique {} +unsafe impl Sync for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] impl Unique { @@ -78,7 +78,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl Unique { +impl Unique { /// Creates a new `Unique`. /// /// # Safety @@ -151,7 +151,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl Clone for Unique { +impl Clone for Unique { #[inline] fn clone(&self) -> Self { *self @@ -159,33 +159,39 @@ impl Clone for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl Copy for Unique {} +impl Copy for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] -impl CoerceUnsized> for Unique where T: Unsize {} +impl CoerceUnsized> for Unique where + T: Unsize +{ +} #[unstable(feature = "ptr_internals", issue = "none")] -impl DispatchFromDyn> for Unique where T: Unsize {} +impl DispatchFromDyn> for Unique where + T: Unsize +{ +} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for Unique {} +unsafe impl PinCoerceUnsized for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] -impl fmt::Debug for Unique { +impl fmt::Debug for Unique { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl fmt::Pointer for Unique { +impl fmt::Pointer for Unique { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl From<&mut T> for Unique { +impl From<&mut T> for Unique { /// Converts a `&mut T` to a `Unique`. /// /// This conversion is infallible since references cannot be null. @@ -196,7 +202,7 @@ impl From<&mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From> for Unique { +impl From> for Unique { /// Converts a `NonNull` to a `Unique`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index d754bb9034300..f12241a8bfc16 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::{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,)+): ?Sized + 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,)+): ?Sized + 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,)+): ?Sized + PointeeSized { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option { @@ -103,7 +103,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,)+): ?Sized + PointeeSized { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index cd57e06ae04a3..3bde8c1facdab 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -557,7 +557,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 e973b89b2375b..e1cff4e5a676b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -273,7 +273,14 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean let predicates = cx.tcx.predicates_of(did); let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); let generics = filter_non_trait_generics(did, generics); - let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); + let (generics, mut supertrait_bounds) = separate_supertrait_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 } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de6dc088176ff..4cdc9a587cffd 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; @@ -900,6 +900,10 @@ fn clean_ty_generics<'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 } @@ -1499,6 +1503,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 @@ -2333,6 +2344,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 41943b94d1e21..e09505a6851b1 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -138,11 +138,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 5f80aded9d0b4..3f805d8392371 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1290,11 +1290,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 62ba3012643ce..f8eb1601e3c0f 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 @@ -389,9 +389,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::>()[..] && 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 f686cc912ddb0..5d4366396299d 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 55ca875edcee6..44f6b3ff8b8c7 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 03f5ca31f5f07..c710f29d40656 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -1,14 +1,23 @@ //@ignore-target: apple #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] #![allow(clippy::missing_safety_doc)] #[link(name = "c")] extern "C" {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 2718217313ff9..c25196f3da10c 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:36:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs index 78d4f87ed0de6..a1e37eb08d7f4 100644 --- a/src/tools/lint-docs/src/groups.rs +++ b/src/tools/lint-docs/src/groups.rs @@ -17,6 +17,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[ ("rust-2018-compatibility", "Lints used to transition code from the 2015 edition to 2018"), ("rust-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"), ("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"), + ( + "edition-future-compatibility", + "Lints used to transition code from the 2024 edition to the future edition", + ), ( "refining-impl-trait", "Detects refinement of `impl Trait` return types by trait implementations", diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 0258a76c3e703..690f668637d6c 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -5,7 +5,7 @@ use libffi::high::call as ffi; use libffi::low::CodePtr; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_middle::mir::interpret::Pointer; -use rustc_middle::ty::{self as ty, IntTy, UintTy}; +use rustc_middle::ty::{self as ty, inherent::SliceLike, IntTy, UintTy}; use rustc_span::Symbol; use crate::*; 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 eebedf842ef5e..c8c9ff2f1e459 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 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(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub unsafe fn drop_in_place(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | trying to retag from for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location | this error occurs as part of retag at ALLOC[0x0..0x1] 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 75efa5ff806ce..20f39da6b4de0 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(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +LL | pub unsafe fn drop_in_place(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = 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/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs index 5b5eeb29f0f41..5a5ed1f442368 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -9,16 +9,22 @@ //@ [loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@ [loongarch64] needs-llvm-components: loongarch -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![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"] +#[const_trait] +pub trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +#[const_trait] +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 e159a3576850e..7e176b17648ee 100644 --- a/tests/assembly/s390x-vector-abi.rs +++ b/tests/assembly/s390x-vector-abi.rs @@ -11,16 +11,23 @@ //@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector //@[z13_no_vector] needs-llvm-components: systemz -#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![feature(no_core, lang_items, repr_simd, s390x_target_feature, const_trait_impl)] #![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"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 bed515915b85d..cd5afcbab39be 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -14,13 +14,21 @@ //@ [M68K] compile-flags: --target=m68k-unknown-linux-gnu //@ [M68K] needs-llvm-components: m68k -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_std] #![no_core] #![crate_type = "lib"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "drop_in_place"] fn drop_in_place(_: *mut T) {} diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 03aa847650823..a5c13354774cf 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -26,6 +26,7 @@ f16, f128, asm_experimental_arch, + const_trait_impl, unboxed_closures )] #![allow(unused, improper_ctypes_definitions, internal_features)] @@ -40,13 +41,21 @@ macro_rules! impl_marker_trait { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl LegacyReceiver for &T {} -impl LegacyReceiver for &mut T {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} #[lang = "copy"] pub trait Copy: Sized {} @@ -68,14 +77,14 @@ impl_marker_trait!( f16, f32, f64, f128, ] ); -impl<'a, T: ?Sized> Copy for &'a T {} -impl Copy for *const T {} -impl Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl Copy for *const T {} +impl Copy for *mut T {} impl Copy for [T; N] {} #[lang = "phantom_data"] -pub struct PhantomData; -impl Copy for PhantomData {} +pub struct PhantomData; +impl Copy for PhantomData {} pub enum Option { None, @@ -91,17 +100,17 @@ impl Copy for Result {} #[lang = "manually_drop"] #[repr(transparent)] -pub struct ManuallyDrop { +pub struct ManuallyDrop { value: T, } -impl Copy for ManuallyDrop {} +impl Copy for ManuallyDrop {} #[lang = "unsafe_cell"] #[repr(transparent)] -pub struct UnsafeCell { +pub struct UnsafeCell { value: T, } -impl !Freeze for UnsafeCell {} +impl !Freeze for UnsafeCell {} #[lang = "tuple_trait"] pub trait Tuple {} @@ -177,15 +186,15 @@ pub trait Fn: FnMut { #[lang = "dispatch_from_dyn"] trait DispatchFromDyn {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} #[lang = "unsize"] -trait Unsize {} +trait Unsize: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized {} +pub trait CoerceUnsized {} -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize, 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 b348b4acc2486..4c1c792d87b1a 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -3,7 +3,7 @@ // rust-lang/rust#90405 // Ensure implicit panic calls are collected -#![feature(lang_items)] +#![feature(lang_items, const_trait_impl)] #![feature(no_core)] #![crate_type = "lib"] #![no_core] @@ -30,8 +30,16 @@ fn panic_div_overflow() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 837bf6134b01c..4ea66ece09167 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -12,12 +12,20 @@ //@[x86-32-nosse] compile-flags: --target i586-unknown-linux-gnu //@[x86-32-nosse] needs-llvm-components: x86 -#![feature(no_core, lang_items, rustc_attrs, repr_simd)] +#![feature(no_core, lang_items, const_trait_impl, rustc_attrs, repr_simd)] #![no_core] #![crate_type = "lib"] #[lang = "sized"] -trait Sized {} +#[const_trait] +trait Sized: MetaSized {} + +#[lang = "meta_sized"] +#[const_trait] +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 7177a960432a6..2cf5fa9fac6ab 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 { +struct Dst { 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 018ad5454fc23..909444fbe16d1 100644 --- a/tests/codegen/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs @@ -4,13 +4,21 @@ // Emscripten has its own unique implementation of catch_unwind (in `codegen_emcc_try`), // make sure it generates something reasonable. -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 0fc9ae96720e4..2f787a7456ae4 100644 --- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs @@ -3,13 +3,21 @@ // Emscripten catch_unwind using wasm exceptions -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 17d8879630094..76fa7cd444734 100644 --- a/tests/codegen/terminating-catchpad.rs +++ b/tests/codegen/terminating-catchpad.rs @@ -10,13 +10,21 @@ // - `catchpad ... [ptr null]` on Wasm (otherwise LLVM gets confused) // - `catchpad ... [ptr null, i32 64, ptr null]` on Windows (otherwise we catch SEH exceptions) -#![feature(no_core, lang_items, rustc_attrs)] +#![feature(no_core, lang_items, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 0d9c7757883f7..44f50aecf3858 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: arm //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 4c7b2856e2e45..2ef9b89c75e11 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 ffc11d1faef8c..ce416e1ea4f0a 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 c869ca7e2b825..32044df962206 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 19b23ee47ba84..54d404cad1c62 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 b420f67ca9b70..e446fa26770d4 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, abi_vectorcall)] +#![feature(no_core, lang_items, abi_vectorcall, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 2697d3cbcd68e..bb77ac4c96639 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -1,9 +1,18 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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/107362.rs b/tests/crashes/107362.rs index 8d55d611eb133..71373508e2519 100644 --- a/tests/crashes/107362.rs +++ b/tests/crashes/107362.rs @@ -1,7 +1,9 @@ //@ known-bug: #107362 //@ 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: Functor; } @@ -18,20 +20,20 @@ impl Functor for Vec { pub struct Compose(F1::With>) where - F1: Functor + ?Sized, - F2: Functor + ?Sized; + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized; impl Functor for Compose where - F1: Functor + ?Sized, - F2: Functor + ?Sized + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized, { type With = F1::With> ; } pub enum Value where - F: Functor + ?Sized, + F: Functor + std::marker::PointeeSized, { SignedInt(*mut F::With), Array(*mut Value, ()>>), diff --git a/tests/crashes/120033.rs b/tests/crashes/120033.rs index f1502978dc511..7584f98ec9060 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 { - type Bar; +pub trait Foo { + type Bar; } pub struct Bar {} diff --git a/tests/crashes/79409.rs b/tests/crashes/79409.rs deleted file mode 100644 index 98b5f60633627..0000000000000 --- a/tests/crashes/79409.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #79409 - -#![feature(extern_types)] -#![feature(unsized_locals)] - -extern { - type Device; -} - -unsafe fn make_device() -> Box { - Box::from_raw(0 as *mut _) -} - -fn main() { - let d: Device = unsafe { *make_device() }; -} diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index cb8716d90b07f..7b2185954b860 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(); diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index 44faf3a4ed9ad..e8fa01c5b4cfb 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -7,7 +7,7 @@ #![crate_type = "lib"] #![feature(rustc_attrs)] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![feature(isa_attribute)] #![no_core] @@ -22,8 +22,16 @@ macro_rules! asm { }; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 a0d803ab81374..f87f69390cd38 100644 --- a/tests/run-make/amdgpu-kd/foo.rs +++ b/tests/run-make/amdgpu-kd/foo.rs @@ -1,11 +1,20 @@ #![allow(internal_features)] #![feature(no_core, lang_items, abi_gpu_kernel)] +#![feature(const_trait_impl)] #![no_core] #![no_std] // This is needed because of #![no_core]: +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 1f1116b9bfd17..be02af89b0771 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -1,4 +1,4 @@ -#![feature(no_core, intrinsics, lang_items)] +#![feature(no_core, intrinsics, lang_items, const_trait_impl)] #![crate_type = "rlib"] #![no_core] @@ -6,8 +6,16 @@ extern "rust-intrinsic" { fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 2f97fc1ed95ab..a9c92a85f039e 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -3,6 +3,7 @@ //! The function [`delay()`] is removed, as it is not necessary to trigger the //! wrong behavior and would require some additional lang items. #![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![no_main] #![allow(internal_features)] @@ -24,14 +25,22 @@ pub fn main() -> ! { // FIXME: replace with proper minicore once available (#130693) mod minicore { + #[lang = "pointee_sized"] + pub trait PointeeSized {} + + #[lang = "meta_sized"] + #[const_trait] + pub trait MetaSized: PointeeSized {} + #[lang = "sized"] - pub trait Sized {} + #[const_trait] + pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} impl Copy for u32 {} impl Copy for &u32 {} - impl Copy for *mut T {} + impl Copy for *mut T {} pub mod ptr { #[inline] 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 cd1ef8cb351ff..cda3c058d141d 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -1,4 +1,4 @@ -#![feature(no_core, lang_items, freeze_impls)] +#![feature(no_core, lang_items, freeze_impls, const_trait_impl)] #![crate_type = "rlib"] #![no_core] @@ -9,8 +9,16 @@ 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"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs index 9ea8eb8cf8831..d9ef4ec45e339 100644 --- a/tests/run-make/simd-ffi/simd.rs +++ b/tests/run-make/simd-ffi/simd.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] // we can compile to a variety of platforms, because we don't need // cross-compiled standard libraries. -#![feature(no_core, auto_traits)] +#![feature(no_core, auto_traits, const_trait_impl)] #![no_core] #![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)] @@ -52,8 +52,16 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { unsafe { integer(a, b) } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 22939e87912c1..945e6dfed5088 100644 --- a/tests/run-make/target-specs/foo.rs +++ b/tests/run-make/target-specs/foo.rs @@ -1,11 +1,19 @@ -#![feature(lang_items, no_core, auto_traits)] +#![feature(lang_items, no_core, auto_traits, const_trait_impl)] #![no_core] #[lang = "copy"] trait Copy {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 f94f7338480bb..5cfb21da0d1d2 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -1,8 +1,17 @@ #![feature(no_core, auto_traits, lang_items, arbitrary_self_types)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} @@ -15,8 +24,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 0]" -//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 1]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[22, 0]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[24, 1]" // FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91 // is "$.index[?(@.inner.impl.is_synthetic==true)].span" null pub struct Foo; diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index a1f0ebd11b636..90f1f0415c220 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -1,4 +1,5 @@ #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![no_core] @@ -6,8 +7,16 @@ //@ set impl_i32 = "$.index[?(@.docs=='Only core can do this')].id" +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 18ac37280c0ef..d6c5c4bcdf6b3 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -3,10 +3,19 @@ #![deny(warnings)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 cc13cc0fe531b..4e90fe59212f8 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:20: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:20:1 | LL | / /// ```{class="} LL | | /// main; diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs index 17fa3ccfe3e89..1886d653ce4bb 100644 --- a/tests/rustdoc-ui/target-feature-stability.rs +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -12,10 +12,19 @@ #![crate_type = "lib"] #![feature(no_core, lang_items)] #![feature(arm_target_feature)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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/cfg_doc_reexport.rs b/tests/rustdoc/cfg_doc_reexport.rs index 44ec366328413..5da4b87adca0f 100644 --- a/tests/rustdoc/cfg_doc_reexport.rs +++ b/tests/rustdoc/cfg_doc_reexport.rs @@ -1,11 +1,20 @@ #![feature(doc_cfg)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![crate_name = "foo"] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} //@ has 'foo/index.html' //@ has - '//dt/*[@class="stab portability"]' 'foobar' diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/cross-crate-primitive-doc.rs index 0ffde5b0f2d80..5a02776b24681 100644 --- a/tests/rustdoc/cross-crate-primitive-doc.rs +++ b/tests/rustdoc/cross-crate-primitive-doc.rs @@ -3,10 +3,19 @@ //@ only-linux #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} extern crate primitive_doc; diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc/file-creation-111249.rs index a6522d682f191..bd0e12dde1088 100644 --- a/tests/rustdoc/file-creation-111249.rs +++ b/tests/rustdoc/file-creation-111249.rs @@ -1,10 +1,22 @@ // https://github.com/rust-lang/rust/issues/111249 #![crate_name = "foo"] #![feature(no_core)] +#![feature(const_trait_impl, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +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 bee3d8e65097a..66371e8c827cf 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 c050929db9682..7a79c6dcc1a48 100644 --- a/tests/rustdoc/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc/intra-doc/auxiliary/my-core.rs @@ -1,4 +1,5 @@ #![feature(no_core, lang_items, rustdoc_internals, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type="rlib"] @@ -13,8 +14,16 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 198ac8e43e088..41a678d52cd0b 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 { +pub trait G: 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 79825643b98ce..63a26e847addc 100644 --- a/tests/rustdoc/intra-doc/no-doc-primitive.rs +++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs @@ -2,6 +2,7 @@ #![deny(rustdoc::broken_intra_doc_links)] #![feature(no_core, lang_items, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type = "rlib"] @@ -10,8 +11,16 @@ //@ has no_doc_primitive/index.html //! A [`char`] and its [`char::len_utf8`]. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 a9e71c58be359..93a9967383e5a 100644 --- a/tests/rustdoc/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc/intra-doc/prim-methods-local.rs @@ -1,5 +1,6 @@ #![deny(rustdoc::broken_intra_doc_links)] #![feature(no_core, lang_items, rustc_attrs, rustdoc_internals)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type = "rlib"] @@ -19,8 +20,16 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 d5bfd570d547d..062d74513e1e4 100644 --- a/tests/rustdoc/intra-doc/prim-self.rs +++ b/tests/rustdoc/intra-doc/prim-self.rs @@ -5,6 +5,7 @@ #![feature(no_core)] #![feature(rustdoc_internals)] #![feature(inherent_associated_types)] +#![feature(const_trait_impl)] #![feature(lang_items)] #![no_core] @@ -37,5 +38,13 @@ impl S { pub fn f() {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 dcdcbfb7ec157..bf125050970ff 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 @@ -1,4 +1,5 @@ #![feature(doc_notable_trait)] +#![feature(const_trait_impl)] #![feature(lang_items)] #![feature(no_core)] #![no_core] @@ -11,8 +12,16 @@ impl Box { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[doc(notable_trait)] pub trait FakeIterator {} diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs index 61060b3ff7c74..67bc38ffa7d59 100644 --- a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs +++ b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs @@ -1,13 +1,22 @@ // Regression test for . #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 0d2ee89415d4a..00e5f281441db 100644 --- a/tests/rustdoc/safe-intrinsic.rs +++ b/tests/rustdoc/safe-intrinsic.rs @@ -1,12 +1,21 @@ #![feature(intrinsics)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![feature(rustc_attrs)] #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} //@ has 'foo/fn.abort.html' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' diff --git a/tests/ui/amdgpu-require-explicit-cpu.rs b/tests/ui/amdgpu-require-explicit-cpu.rs index 46778a1094fab..b3e7fd305f520 100644 --- a/tests/ui/amdgpu-require-explicit-cpu.rs +++ b/tests/ui/amdgpu-require-explicit-cpu.rs @@ -8,10 +8,18 @@ //@[cpu] compile-flags: -Ctarget-cpu=gfx900 //@[cpu] build-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index a718eb23bed59..5dd263656edb7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -7,13 +7,13 @@ trait Trait { } fn take( +//~^ ERROR implementation of `Project` is not general enough _: impl Trait< < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, K = { () } >, ) {} -//~^^^^^^ ERROR implementation of `Project` is not general enough -//~^^^^ ERROR higher-ranked subtype error +//~^^^ ERROR higher-ranked subtype error //~| ERROR higher-ranked subtype error trait Project { type Out; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 967814c9c3d9d..061e955756399 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:13:13 | LL | K = { () } | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:13:13 | LL | K = { () } | ^^^^^^ diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index bdfcbed71e9a6..742847e7d04ab 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -4,9 +4,12 @@ error: rustc_dump_predicates LL | trait Trait: Iterator | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: , constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: , constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(>, polarity:Positive), bound_vars: [] } @@ -16,12 +19,16 @@ error: rustc_dump_predicates LL | type Assoc: std::ops::Deref | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: , constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: , constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(

, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref:

, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(

, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<>::Assoc<()> as std::marker::Copy>, polarity:Positive), bound_vars: [] } @@ -33,6 +40,7 @@ LL | type Assoc: std::ops::Deref | = note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(Projection, AliasTy { args: [Self/#0, T/#1, P/#2], def_id: DefId(..), .. })], def_id: DefId(..), .. }, Term::Ty(())), bound_vars: [] } = note: Binder { value: TraitPredicate(<>::Assoc

as std::ops::Deref>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <>::Assoc

as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<>::Assoc

as std::marker::Sized>, polarity:Positive), bound_vars: [] } error: aborting due to 3 previous errors diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 81af030fe5568..0c4f337ba57b8 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -1,5 +1,6 @@ fn server() -> impl { //~^ ERROR at least one trait must be specified + //~| ERROR type annotations needed ().map2(|| "") } diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 90672cd83d7cf..3e95fab441ade 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -5,7 +5,7 @@ LL | fn server() -> impl { | ^^^^ error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-78720.rs:13:12 + --> $DIR/issue-78720.rs:14:12 | LL | _func: F, | ^ @@ -22,8 +22,14 @@ help: you might be missing a type parameter LL | struct Map2 { | +++ +error[E0282]: type annotations needed + --> $DIR/issue-78720.rs:1:16 + | +LL | fn server() -> impl { + | ^^^^ cannot infer type + error[E0308]: mismatched types - --> $DIR/issue-78720.rs:7:39 + --> $DIR/issue-78720.rs:8:39 | LL | fn map2(self, f: F) -> Map2 {} | ^^ expected `Map2`, found `()` @@ -32,7 +38,7 @@ LL | fn map2(self, f: F) -> Map2 {} found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-78720.rs:7:16 + --> $DIR/issue-78720.rs:8:16 | LL | fn map2(self, f: F) -> Map2 {} | ^^^^ doesn't have a size known at compile-time @@ -47,7 +53,7 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn map2(&self, f: F) -> Map2 {} | + -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0308, E0412. +Some errors have detailed explanations: E0277, E0282, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 955f917ee3328..2b94fd9027f35 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -7,8 +7,16 @@ //@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" //@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" -#![feature(lang_items, no_core, auto_traits)] +#![feature(lang_items, no_core, auto_traits, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 83a8b6b3ef6a2..a9045840173e7 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +//~ ERROR overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` //@ build-fail #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index f7a3e2df3dbaa..74d98fde285bb 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index fb0ccb4fdcd72..8e6715ac3c7e5 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -1,4 +1,6 @@ #![crate_type="lib"] +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] struct S; //~^ ERROR type parameter `N` is never used @@ -25,3 +27,4 @@ type C = (); type D = (); //~^ 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 67b704d8bc725..fa12eb35feff0 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:3:10 + --> $DIR/unused-type-param-suggestion.rs:5:10 | LL | struct S; | ^ unused type parameter @@ -8,7 +8,7 @@ LL | struct S; = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:9:10 + --> $DIR/unused-type-param-suggestion.rs:11:10 | LL | struct T; | ^ unused type parameter @@ -16,7 +16,7 @@ LL | struct T; = help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData` error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:13:8 + --> $DIR/unused-type-param-suggestion.rs:15:8 | LL | type A = (); | ^ unused type parameter @@ -25,7 +25,7 @@ LL | type A = (); = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:19:8 + --> $DIR/unused-type-param-suggestion.rs:21:8 | LL | type B = (); | ^ unused type parameter @@ -33,7 +33,7 @@ LL | type B = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:22:8 + --> $DIR/unused-type-param-suggestion.rs:24:8 | LL | type C = (); | ^ unused type parameter @@ -41,12 +41,13 @@ LL | type C = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:25:8 + --> $DIR/unused-type-param-suggestion.rs:27:8 | LL | type D = (); | ^ 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 598904d3c4453..1dac8f8c62b40 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 constant -const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR constant +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 { min_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 4c0252123a4d3..ea55399f618b1 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]: evaluation of constant value failed - --> $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) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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]: evaluation of constant value failed - --> $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:49 | LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout + | ---------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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::min_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 806ade51a997f..a58227522f328 100644 --- a/tests/ui/debuginfo/dwarf-versions.rs +++ b/tests/ui/debuginfo/dwarf-versions.rs @@ -27,12 +27,20 @@ //@ compile-flags: -g --target x86_64-unknown-linux-gnu --crate-type cdylib //@ needs-llvm-components: x86 -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![no_std] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 cd3eec9f1f7b8..21a2a20a64451 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() {} +fn assert_send() {} fn main() { assert_send::() diff --git a/tests/ui/extern/extern-type-diag-not-similar.stderr b/tests/ui/extern/extern-type-diag-not-similar.stderr index 3547f9b3ff613..f85ff1eead64b 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` 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() {} +LL | fn assert_send() {} | ^^^^ 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 2df0cd4c923c1..b273dcea7228f 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() {} -fn assert_send() {} +fn assert_sync() {} +fn assert_send() {} fn main() { assert_sync::(); diff --git a/tests/ui/extern/extern-types-not-sync-send.rs b/tests/ui/extern/extern-types-not-sync-send.rs index ba82caced7a4e..3cac1aabea99e 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() {} -fn assert_send() {} +fn assert_sync() {} +fn assert_send() {} fn main() { assert_sync::(); diff --git a/tests/ui/extern/extern-types-not-sync-send.stderr b/tests/ui/extern/extern-types-not-sync-send.stderr index 7865ddeda34f5..56bdd5be7cff3 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` 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() {} - | ^^^^ required by this bound in `assert_sync` +LL | fn assert_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` 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() {} - | ^^^^ required by this bound in `assert_send` +LL | fn assert_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 78dbee77b9c4b..080ed91a632a6 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 { +struct Bar { 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 399a5828ff3b2..3ff51b9b6b0df 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 0000000000000..040dc0d1f6756 --- /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 `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 8e5911228b2e4..15777d456c264 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 { +struct Bar { x: u8, tail: T, } -fn assert_thin() { +fn assert_thin() { 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 44300b1051412..07cb1efa80130 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() {} +fn assert_foo() {} -fn use_foo(x: &dyn Foo) { +fn use_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 94a222a7e7e01..46cdc24e08328 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::>(); //~^ ERROR the size for values of type + //~| ERROR the size for values of type assert_sized::>>(); //~^ 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 a587d4dda55c8..43dd9800d6d30 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() {} | ++++++++ +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-unsized.rs:28:20 + | +LL | assert_sized::>(); + | ^^^^^^ 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 { + | ^ 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::>>(); | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_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::>>(); + | ^^^^^^^^^^^ 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 { + | ^ 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/extern-types-unsizing-79409.rs b/tests/ui/extern/extern-types-unsizing-79409.rs new file mode 100644 index 0000000000000..b53e205bee5dd --- /dev/null +++ b/tests/ui/extern/extern-types-unsizing-79409.rs @@ -0,0 +1,21 @@ +#![feature(extern_types)] +#![feature(unsized_locals)] +//~^ WARN the feature `unsized_locals` is incomplete + +// Regression test for #79409 + +extern "C" { + type Device; +} + +unsafe fn make_device() -> Box { +//~^ 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 +} diff --git a/tests/ui/extern/extern-types-unsizing-79409.stderr b/tests/ui/extern/extern-types-unsizing-79409.stderr new file mode 100644 index 0000000000000..afc8ccf607b7e --- /dev/null +++ b/tests/ui/extern/extern-types-unsizing-79409.stderr @@ -0,0 +1,60 @@ +warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/extern-types-unsizing-79409.rs:2:12 + | +LL | #![feature(unsized_locals)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #48055 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/extern-types-unsizing-79409.rs:11:28 + | +LL | unsafe fn make_device() -> Box { + | ^^^^^^^^^^^ 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/extern-types-unsizing-79409.rs:13: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::::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/extern-types-unsizing-79409.rs:13: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 + --> $DIR/extern-types-unsizing-79409.rs:19: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 4 previous errors; 1 warning emitted + +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 0000000000000..363a70f736dd6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -0,0 +1,30 @@ +#![allow(sized_hierarchy_migration)] +#![feature(extern_types)] +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn needs_pointeesized() {} +fn needs_metasized() {} +fn needs_sized() {} + +fn main() { + needs_pointeesized::(); + needs_metasized::(); + needs_sized::(); + + needs_pointeesized::(); + needs_metasized::(); + needs_sized::(); +//~^ ERROR the size for values of type `str` cannot be known at compilation time + + extern "C" { + type Foo; + } + + needs_pointeesized::(); + needs_metasized::(); +//~^ ERROR the size for values of type `main::Foo` cannot be known + needs_sized::(); +//~^ 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 0000000000000..f1cbf2047adba --- /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:18:19 + | +LL | needs_sized::(); + | ^^^ 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:9:19 + | +LL | fn needs_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:26:23 + | +LL | needs_metasized::(); + | ^^^ 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:8:23 + | +LL | fn needs_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:28:19 + | +LL | needs_sized::(); + | ^^^ 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:9:19 + | +LL | fn needs_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 b4025080034ab..0d1c00e4e3582 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 @@ -10,8 +10,16 @@ //@ [BADTARGET] needs-llvm-components: x86 #![crate_type = "lib"] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/lang-items/issue-83471.rs b/tests/ui/lang-items/issue-83471.rs index 6be345ac50765..5e7554b3e64e0 100644 --- a/tests/ui/lang-items/issue-83471.rs +++ b/tests/ui/lang-items/issue-83471.rs @@ -1,12 +1,22 @@ // Regression test for the ICE reported in issue #83471. #![crate_type="lib"] -#![feature(no_core)] +#![feature(no_core, const_trait_impl)] #![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] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] //~^ ERROR: lang items are subject to change [E0658] -trait Sized {} +#[const_trait] +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 244b2efeaf1e0..ef5f77369434b 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:25: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:16: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:21: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:25: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:21: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:31: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 7b805e8b0cdb6..6d5a5435ab965 100644 --- a/tests/ui/lang-items/issue-87573.rs +++ b/tests/ui/lang-items/issue-87573.rs @@ -1,14 +1,22 @@ // Regression test for #87573, ensures that duplicate lang items or invalid generics // for lang items doesn't cause ICE. -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![crate_type = "lib"] pub static STATIC_BOOL: bool = true; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 7085bb8c339d4..3a7e3c9bdc53c 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:28: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:34: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 0f982df61e8e7..1bb3e282c319c 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -1,11 +1,19 @@ // Checks that declaring a lang item with the wrong number of generic arguments errors rather than // crashing (issue #83474, #83893, #87573, part of #9307, #79559). -#![feature(lang_items, no_core)] +#![feature(lang_items, no_core, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait MyPointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MyMetaSized: MyPointeeSized {} + #[lang = "sized"] -trait MySized {} +#[const_trait] +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 3de67d6594035..9062289a49cfc 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:18: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:22: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:26: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:30:1 | LL | #[lang = "phantom_data"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | struct MyPhantomData; | ------ 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:36: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:42: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:32:22 | LL | struct MyPhantomData; | ^ unused type parameter @@ -60,7 +60,7 @@ LL | struct MyPhantomData; = 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:32:25 | LL | struct MyPhantomData; | ^ unused type parameter @@ -69,7 +69,7 @@ LL | struct MyPhantomData; = 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:52:7 | LL | r + a; | - ^ - {integer} 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 9b634ee8ee3e4..76ed8a79e698a 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 @@ -1,11 +1,19 @@ //@ error-pattern: requires `copy` lang_item -#![feature(lang_items, no_core)] +#![feature(lang_items, no_core, const_trait_impl)] #![no_core] #![no_main] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized { } +#[const_trait] +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 3dc7716ecd2a6..26701e7a66ad1 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:14:5 + --> $DIR/missing-copy-lang-item-issue-19660.rs:22: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 cd7361255eb91..e02c50921ba94 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:81:38 | LL | fn start(_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 1a5905ab8e602..1ba43af06f7b4 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:95:52 | LL | fn start(_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 c61ace3cd628e..5c868ea7d02fa 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:88:52 | LL | fn start(_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 ef943d6b3dba1..3c5ccfb31e2c7 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:67:1 | LL | fn start(_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 00395a05d33f7..082a07026601d 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:74:20 | LL | fn start(_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 193f25bab05b1..32896ed12dbfc 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:60:20 | LL | fn start(_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 56b787d2ae38f..a5850a156bb4b 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:21:1 | LL | fn start() -> 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 2672efe51c9aa..9eeead57ca2b4 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:35:83 | LL | fn start(_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 98814dcd24a7c..cd97d7160bc5c 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:28:1 | LL | fn start(_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 5bb99e2adc88f..64298ba09e30d 100644 --- a/tests/ui/lang-items/start_lang_item_args.rs +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -2,13 +2,19 @@ //@ revisions: missing_all_args missing_sigpipe_arg missing_ret start_ret too_many_args //@ revisions: main_ty main_args main_ret argc argv_inner_ptr argv sigpipe -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] #[lang = "copy"] pub trait Copy {} #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} +#[lang = "meta_sized"] +#[const_trait] +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 e0a8496dba99b..fd33c64992bfd 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:102:80 | LL | fn start(_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 4437b0fdcfb18..05958ec9921eb 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:40:87 | LL | fn start(_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 8570d96fc6219..8a216a526e663 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:47:1 | LL | / fn start( 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 18cd4c9704056..46256697eb3b4 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 @@ -2,12 +2,22 @@ //@ check-fail #![feature(lang_items, no_core)] +#![feature(const_trait_impl)] #![no_core] #[lang = "copy"] pub trait Copy {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 6214e3f8bc79a..92d2e2409e38c 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:23: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 c9b1e0a4b9ec3..91ea0c49dc028 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -3,14 +3,17 @@ //! This used to ICE in layout computation, because `::B` fails to normalize //! due to the unconstrained param on the impl. -#![feature(rustc_attrs)] +#![allow(sized_hierarchy_migration)] +#![feature(rustc_attrs, sized_hierarchy)] #![crate_type = "lib"] +use std::marker::PointeeSized; + trait A { const B: usize; } -impl A for u8 { //~ ERROR: the type parameter `C` is not constrained +impl A for u8 { //~ ERROR: the type parameter `C` is not constrained const B: usize = 42; } diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 615c131eb9045..7e9005c5501d3 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -1,11 +1,11 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-param-ice-137308.rs:13:6 + --> $DIR/unconstrained-param-ice-137308.rs:16:6 | -LL | impl A for u8 { +LL | impl A for u8 { | ^ unconstrained type parameter error: the type has an unknown layout - --> $DIR/unconstrained-param-ice-137308.rs:18:1 + --> $DIR/unconstrained-param-ice-137308.rs:21:1 | LL | struct S([u8; ::B]); | ^^^^^^^^ diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index c2fc345fa2ba2..96168ebeaa165 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 diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index a09e76705156e..536f88085ded3 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -1,5 +1,5 @@ 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 diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 2e0bdb151e180..f9eb0dde13920 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,5 +1,7 @@ -#![feature(extern_types)] +#![allow(sized_hierarchy_migration)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::offset_of; struct Alpha { @@ -26,7 +28,7 @@ struct Gamma { z: Extern, } -struct Delta { +struct Delta { 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 714bf7a0266c6..f86d1b0657e47 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:38: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:39: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:40: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:42: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:47:5 | LL | offset_of!(Delta, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -44,7 +44,7 @@ LL | offset_of!(Delta, 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:48:5 | LL | offset_of!(Delta, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,21 +53,21 @@ LL | offset_of!(Delta, 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:46:5 | LL | offset_of!(Delta, 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:7: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:52:5 | LL | fn generic_with_maybe_sized() -> usize { | - this type parameter needs to be `Sized` @@ -82,7 +82,7 @@ LL + fn generic_with_maybe_sized() -> 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:56: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 0b8308ba753aa..c9414b2764203 100644 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -1,7 +1,7 @@ //@ compile-flags:-C panic=abort #![feature(lang_items)] -#![feature(no_core)] +#![feature(no_core, const_trait_impl)] #![no_core] #![no_main] @@ -11,5 +11,13 @@ fn panic() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +trait Sized: MetaSized {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 9436441ecc6a7..8c4d457a5f4c7 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -1,8 +1,16 @@ -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang="sized"] -pub trait Sized {} +#[lang = "sized"] +#[const_trait] +pub trait Sized: MetaSized {} + +#[lang = "meta_sized"] +#[const_trait] +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 cb7b858e54dc8..39159e6e8517c 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:140:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:140:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58: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:149:18 | LL | use bar::baz; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:165:20 + --> $DIR/privacy1.rs:173:20 | LL | use self::foo::i::A; | ^ private module | note: the module `i` is defined here - --> $DIR/privacy1.rs:170:9 + --> $DIR/privacy1.rs:178:9 | LL | mod i { | ^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:104:16 + --> $DIR/privacy1.rs:112:16 | LL | ::bar::baz::A::foo(); | ^^^ - struct `A` is not publicly re-exported @@ -56,13 +56,13 @@ LL | ::bar::baz::A::foo(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:105:16 + --> $DIR/privacy1.rs:113:16 | LL | ::bar::baz::A::bar(); | ^^^ - struct `A` is not publicly re-exported @@ -70,13 +70,13 @@ LL | ::bar::baz::A::bar(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:107:16 + --> $DIR/privacy1.rs:115:16 | LL | ::bar::baz::A.foo2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -84,13 +84,13 @@ LL | ::bar::baz::A.foo2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:108:16 + --> $DIR/privacy1.rs:116:16 | LL | ::bar::baz::A.bar2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -98,13 +98,13 @@ LL | ::bar::baz::A.bar2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:112:16 + --> $DIR/privacy1.rs:120:16 | LL | ::bar::B::foo(); | ^ --- associated function `foo` is not publicly re-exported @@ -112,31 +112,31 @@ LL | ::bar::B::foo(); | private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:40:5 + --> $DIR/privacy1.rs:48:5 | LL | trait B { | ^^^^^^^ error[E0603]: function `epriv` is private - --> $DIR/privacy1.rs:118:20 + --> $DIR/privacy1.rs:126:20 | LL | ::bar::epriv(); | ^^^^^ private function | note: the function `epriv` is defined here - --> $DIR/privacy1.rs:65:9 + --> $DIR/privacy1.rs:73:9 | LL | fn epriv(); | ^^^^^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:127:16 + --> $DIR/privacy1.rs:135:16 | LL | ::bar::baz::foo(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ @@ -147,13 +147,13 @@ LL + bar::foo(); | error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:128:16 + --> $DIR/privacy1.rs:136:16 | LL | ::bar::baz::bar(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ @@ -164,19 +164,19 @@ LL + bar::bar(); | error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:157:17 + --> $DIR/privacy1.rs:165:17 | LL | impl ::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:48:5 | LL | trait B { | ^^^^^^^ error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:77:23 + --> $DIR/privacy1.rs:85: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:103: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:19 + --> $DIR/privacy1.rs:110:19 | LL | fn bar() {} | -------- private associated function defined here @@ -203,7 +203,7 @@ LL | ::bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:105:24 + --> $DIR/privacy1.rs:113:24 | LL | fn bar() {} | -------- private associated function defined here @@ -212,7 +212,7 @@ LL | ::bar::baz::A::bar(); | ^^^ private associated function error[E0624]: method `bar2` is private - --> $DIR/privacy1.rs:108:23 + --> $DIR/privacy1.rs:116:23 | LL | fn bar2(&self) {} | -------------- private method defined here diff --git a/tests/ui/privacy/privacy4.rs b/tests/ui/privacy/privacy4.rs index 7341c7752bbf7..4573227f9c3b6 100644 --- a/tests/ui/privacy/privacy4.rs +++ b/tests/ui/privacy/privacy4.rs @@ -1,7 +1,9 @@ -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} +#[lang = "sized"] #[const_trait] pub trait Sized: MetaSized {} +#[lang = "meta_sized"] #[const_trait] 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 4aa3ae964c0ca..eeefd85645c7d 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/auxiliary/migration-no-feat-dep.rs b/tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs new file mode 100644 index 0000000000000..198d903ad414f --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs @@ -0,0 +1,6 @@ +//@ compile-flags: -Zunstable-options +//@ edition: future +#![feature(const_trait_impl, sized_hierarchy)] + +pub fn needs_const_sized() { unimplemented!() } +pub fn needs_const_metasized() { unimplemented!() } 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 0000000000000..eecd353214844 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs @@ -0,0 +1,27 @@ +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait ConstSizedTr {} + +impl ConstSizedTr for T {} + +pub trait SizedTr {} + +impl SizedTr for T {} + +pub trait NegSizedTr {} + +impl NegSizedTr for T {} + +pub trait ConstMetaSizedTr {} + +impl ConstMetaSizedTr for T {} + +pub trait MetaSizedTr {} + +impl MetaSizedTr for T {} + +pub trait PointeeSizedTr: PointeeSized {} + +impl 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 0000000000000..3314b0f356f53 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs @@ -0,0 +1,7 @@ +pub trait SizedTr {} + +impl SizedTr for T {} + +pub trait NegSizedTr {} + +impl NegSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/const-bound.rs b/tests/ui/sized-hierarchy/const-bound.rs new file mode 100644 index 0000000000000..f9f1fd2ce938a --- /dev/null +++ b/tests/ui/sized-hierarchy/const-bound.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(const_trait_impl)] + +// This test can fail because of the implicit const bounds/supertraits. + +pub struct Bar; + +#[const_trait] +pub trait Foo {} + +impl const Foo for Bar {} + +pub const fn bar() {} diff --git a/tests/ui/sized-hierarchy/constness.rs b/tests/ui/sized-hierarchy/constness.rs new file mode 100644 index 0000000000000..05694852d9eef --- /dev/null +++ b/tests/ui/sized-hierarchy/constness.rs @@ -0,0 +1,38 @@ +//@ compile-flags: -Zunstable-options +//@ edition: future +#![allow(internal_features)] +#![feature(rustc_attrs, const_trait_impl, sized_hierarchy)] + +#[rustc_non_const_sized] +struct NotConstSized; + +#[rustc_non_const_sized] +struct NotConstMetaSized([u8]); + +impl NotConstMetaSized { + fn new() -> &'static Self { unimplemented!() } +} + +const fn size_of() { unimplemented!() } +const fn size_of_val(_t: &T) { unimplemented!() } + +fn main() { + let _ = const { size_of::() }; +//~^ ERROR the trait bound `NotConstSized: const Sized` is not satisfied + let _ = size_of::(); + + let _ = const { size_of::() }; +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + let _ = size_of::(); +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + let v = NotConstSized; + let _ = const { size_of_val(&v) }; +//~^ ERROR attempt to use a non-constant value in a constant + let _ = size_of_val(&v); + + let v = NotConstMetaSized::new(); + let _ = const { size_of_val(v) }; +//~^ ERROR attempt to use a non-constant value in a constant + let _ = size_of_val(v); +} diff --git a/tests/ui/sized-hierarchy/constness.stderr b/tests/ui/sized-hierarchy/constness.stderr new file mode 100644 index 0000000000000..9234380e9a46a --- /dev/null +++ b/tests/ui/sized-hierarchy/constness.stderr @@ -0,0 +1,76 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/constness.rs:30:34 + | +LL | let _ = const { size_of_val(&v) }; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - let v = NotConstSized; +LL + const v: /* Type */ = NotConstSized; + | + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/constness.rs:35:33 + | +LL | let _ = const { size_of_val(v) }; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - let v = NotConstSized; +LL + const v: /* Type */ = NotConstSized; + | + +error[E0277]: the trait bound `NotConstSized: const Sized` is not satisfied + --> $DIR/constness.rs:20:31 + | +LL | let _ = const { size_of::() }; + | ^^^^^^^^^^^^^ + | +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of() { unimplemented!() } + | ^^^^^^ required by this bound in `size_of` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/constness.rs:24:31 + | +LL | let _ = const { size_of::() }; + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `NotConstMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `NotConstMetaSized` + --> $DIR/constness.rs:10:8 + | +LL | struct NotConstMetaSized([u8]); + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of() { unimplemented!() } + | ^^^^^^^^^^^^ required by this bound in `size_of` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/constness.rs:26:23 + | +LL | let _ = size_of::(); + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `NotConstMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `NotConstMetaSized` + --> $DIR/constness.rs:10:8 + | +LL | struct NotConstMetaSized([u8]); + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of() { unimplemented!() } + | ^^^^^^^^^^^^ required by this bound in `size_of` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0435. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs new file mode 100644 index 0000000000000..9e01f995ce8ff --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -0,0 +1,52 @@ +//@ check-fail +//@ compile-flags: -Zunstable-options +//@ edition: future +#![allow(sized_hierarchy_migration)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn bare() {} + + +fn sized() {} + +fn neg_sized() {} + + +fn metasized() {} + +fn neg_metasized() {} +//~^ ERROR relaxing a default bound only does something for `?Sized` + + +fn pointeesized() { } + +fn neg_pointeesized() { } +//~^ ERROR relaxing a default bound only does something for `?Sized` + + +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::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + sized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + metasized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + pointeesized::(); +} diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr new file mode 100644 index 0000000000000..510109a2d5770 --- /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:19:21 + | +LL | fn neg_metasized() {} + | ^^^^^^^^^^ + +error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/default-bound.rs:25:24 + | +LL | fn neg_pointeesized() { } + | ^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/default-bound.rs:32: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:9:9 + | +LL | fn bare() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `bare` +help: consider relaxing the implicit `Sized` restriction + | +LL | fn bare() {} + | ++++++++ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/default-bound.rs:34: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:12:13 + | +LL | fn 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:45:12 + | +LL | bare::(); + | ^^^ 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:9:9 + | +LL | fn bare() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `bare` +help: consider relaxing the implicit `Sized` restriction + | +LL | fn bare() {} + | ++++++++ + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/default-bound.rs:47:13 + | +LL | sized::(); + | ^^^ 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:12:13 + | +LL | fn sized() {} + | ^^^^^ required by this bound in `sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/default-bound.rs:49:17 + | +LL | metasized::(); + | ^^^ 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:17:17 + | +LL | fn 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 0000000000000..e545431bb9cc3 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -0,0 +1,62 @@ +//@ check-fail +#![allow(sized_hierarchy_migration)] +#![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() {} +fn requires_metasized() {} +fn requires_pointeesized() {} + +fn with_sized_supertrait() { + requires_sized::(); + requires_metasized::(); + requires_pointeesized::(); +} + +fn with_metasized_supertrait() { + requires_sized::(); + //~^ ERROR the size for values of type `T` cannot be known at compilation time + requires_metasized::(); + requires_pointeesized::(); +} + +// It isn't really possible to write this one.. +fn with_pointeesized_supertrait() { + requires_sized::(); + //~^ ERROR the size for values of type `T` cannot be known + requires_metasized::(); + //~^ ERROR the size for values of type `T` cannot be known + requires_pointeesized::(); +} + +// `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() { +//~^ ERROR the size for values of type `T` cannot be known + requires_sized::(); + //~^ ERROR the size for values of type `T` cannot be known + requires_metasized::(); + //~^ ERROR the size for values of type `T` cannot be known + requires_pointeesized::(); +} + +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 0000000000000..8fcd58a56f990 --- /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:9: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:14: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:20: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:53:38 + | +LL | fn with_bare_trait() { + | ^^^^ doesn't have a known size + | +note: required by a bound in `Bare` + --> $DIR/default-supertrait.rs:23: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() { + | ++++++++++++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:36:22 + | +LL | fn with_metasized_supertrait() { + | - this type parameter needs to be `Sized` +LL | requires_sized::(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:25:22 + | +LL | fn requires_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:44:22 + | +LL | fn with_pointeesized_supertrait() { + | - this type parameter needs to be `Sized` +LL | requires_sized::(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:25:22 + | +LL | fn requires_sized() {} + | ^^^^^ required by this bound in `requires_sized` + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:46:26 + | +LL | requires_metasized::(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:26:26 + | +LL | fn requires_metasized() {} + | ^^^^^^^^^ required by this bound in `requires_metasized` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_pointeesized_supertrait() { + | ++++++++++++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:55:22 + | +LL | fn with_bare_trait() { + | - this type parameter needs to be `Sized` +LL | +LL | requires_sized::(); + | ^ doesn't have a size known at compile-time + | +note: required by a bound in `requires_sized` + --> $DIR/default-supertrait.rs:25:22 + | +LL | fn requires_sized() {} + | ^^^^^ required by this bound in `requires_sized` + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:57:26 + | +LL | requires_metasized::(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:26:26 + | +LL | fn requires_metasized() {} + | ^^^^^^^^^ required by this bound in `requires_metasized` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_bare_trait() { + | ++++++++++++++++++++++++ + +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/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs new file mode 100644 index 0000000000000..3bf11c85bee07 --- /dev/null +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -0,0 +1,21 @@ +//@ check-pass +#![allow(sized_hierarchy_migration)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; + +pub fn hash(_: *const T) { + unimplemented!(); +} + +unsafe extern "C" { + type Foo; +} + +fn get() -> *const Foo { + unimplemented!() +} + +fn main() { + hash::(get()); +} diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs new file mode 100644 index 0000000000000..1ad87c5163056 --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.rs @@ -0,0 +1,312 @@ +//@ check-fail +//@ compile-flags: -Zunstable-options +//@ edition: future + +#![allow(incomplete_features, internal_features)] +#![allow(sized_hierarchy_migration)] +#![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() { } +fn takes_sized(_t: T) { } + +fn needs_metasized() { } +fn takes_metasized(_t: T) { } + +fn needs_pointeesized() { } +fn takes_pointeesized(_t: T) { } + +fn main() { + // `bool` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `char` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `i8` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `i16` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `i32` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `i64` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `i128` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `u8` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `u16` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `u32` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `u64` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `u128` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `f16` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `f32` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `f64` + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // `*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:: u8>(foo); + takes_metasized:: u8>(foo); + takes_pointeesized:: 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::(); + needs_metasized::(); + needs_pointeesized::(); + + // `str` + needs_sized::(); + //~^ ERROR the size for values of type `str` cannot be known at compilation time + needs_metasized::(); + needs_pointeesized::(); + + // `[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::(); + //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time + needs_metasized::(); + needs_pointeesized::(); + + // `extern type` + unsafe extern "C" { + type Foo; + } + needs_sized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::(); + + // 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::(); + needs_metasized::(); + needs_pointeesized::(); + + // struct w/ all fields sized + struct StructAllFieldsSized { x: u32, y: u32 } + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::(); + + // struct w/ last fields metasized + struct StructLastFieldMetaSized { x: u32, y: [u8] } + needs_sized::(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::(); + needs_pointeesized::(); + + // struct w/ last fields unsized + struct StructLastFieldUnsized { x: u32, y: Foo } + needs_sized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::(); + + // enum w/ no fields + enum EnumEmpty {} + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // enum w/ all variant fields sized + enum EnumAllFieldsSized { Qux { x: u32, y: u32 } } + needs_sized::(); + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + needs_metasized::(); + needs_pointeesized::(); + + // 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::(); + needs_metasized::(); + needs_pointeesized::(); +} diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr new file mode 100644 index 0000000000000..720987757544f --- /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:242: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:250: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, y: Foo } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:286: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:293: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, y: Foo } } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:300: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:307: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 } } + | ++++ + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/impls.rs:162:19 + | +LL | needs_sized::(); + | ^^^ 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:15:19 + | +LL | fn needs_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:168: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:15:19 + | +LL | fn needs_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:174:19 + | +LL | needs_sized::(); + | ^^^^^^^^^ 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:15:19 + | +LL | fn needs_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:183:19 + | +LL | needs_sized::(); + | ^^^ 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:15:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:185:23 + | +LL | needs_metasized::(); + | ^^^ 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:18:23 + | +LL | fn needs_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:200: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:202: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:204: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:208: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:210: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:210: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:18:23 + | +LL | fn needs_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:213: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:217: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:15:19 + | +LL | fn needs_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:223: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:15:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:225: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:18:23 + | +LL | fn needs_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:244:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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:242:12 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:15:19 + | +LL | fn needs_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:252:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ 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:250:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:15:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:254:23 + | +LL | needs_metasized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ 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:250:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:18:23 + | +LL | fn needs_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:260:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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:259:12 + | +LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:15:19 + | +LL | fn needs_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:267:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ 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:266:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:15:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:269:23 + | +LL | needs_metasized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ 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:266:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:18:23 + | +LL | fn needs_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/migration-no-feat.rs b/tests/ui/sized-hierarchy/migration-no-feat.rs new file mode 100644 index 0000000000000..3683622284759 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration-no-feat.rs @@ -0,0 +1,48 @@ +//@ aux-build:migration-no-feat-dep.rs +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ edition: 2024 + +#![feature(const_trait_impl)] + +extern crate migration_no_feat_dep; +use migration_no_feat_dep::{needs_const_metasized, needs_const_sized}; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds without the `sized_hierarchy` +// feature work as expected with a migrated crate. + +pub fn relaxed_bound_migration() { + needs_const_metasized::() +} + + +pub fn default_sized_to_const_sized() { + needs_const_sized::() +} + +pub fn sized_to_const_sized() { + needs_const_sized::() +} + + +pub trait ImplicitSupertrait { + fn check() { + needs_const_metasized::() + } +} + +pub trait SizedToConstSized: Sized { + fn check() { + needs_const_sized::() + } +} + +pub trait AssocType { + type Foo: Sized; + type Bar: ?Sized; + + fn check() { + needs_const_sized::(); + needs_const_metasized::(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.fixed b/tests/ui/sized-hierarchy/migration.fixed new file mode 100644 index 0000000000000..f2b62276cebf4 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.fixed @@ -0,0 +1,71 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib +//@ edition: 2024 +//@ run-rustfix + +#![deny(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::MetaSized; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds trigger edition migration lints. + +pub fn needs_const_sized() { unimplemented!() } +pub fn needs_const_metasized() { unimplemented!() } + + +pub fn relaxed_bound_migration() { +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_metasized::() +} + + +pub fn default_sized_to_const_sized() { +//~^ ERROR default bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::() +} + +pub fn sized_to_const_sized() { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::() +} + + +pub trait ImplicitSupertrait: const MetaSized { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_metasized::() + } +} + +pub trait SizedToConstSized: const Sized { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_sized::() + } +} + +pub trait AssocType: const MetaSized { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Foo: const Sized; +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Bar: const MetaSized; +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + + fn check() { + needs_const_sized::(); + needs_const_metasized::(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.rs b/tests/ui/sized-hierarchy/migration.rs new file mode 100644 index 0000000000000..3ab0acceace95 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.rs @@ -0,0 +1,71 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib +//@ edition: 2024 +//@ run-rustfix + +#![deny(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::MetaSized; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds trigger edition migration lints. + +pub fn needs_const_sized() { unimplemented!() } +pub fn needs_const_metasized() { unimplemented!() } + + +pub fn relaxed_bound_migration() { +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_metasized::() +} + + +pub fn default_sized_to_const_sized() { +//~^ ERROR default bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::() +} + +pub fn sized_to_const_sized() { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::() +} + + +pub trait ImplicitSupertrait { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_metasized::() + } +} + +pub trait SizedToConstSized: Sized { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_sized::() + } +} + +pub trait AssocType { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Foo: Sized; +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Bar: ?Sized; +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + + fn check() { + needs_const_sized::(); + needs_const_metasized::(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.stderr b/tests/ui/sized-hierarchy/migration.stderr new file mode 100644 index 0000000000000..b35f871246bfe --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.stderr @@ -0,0 +1,99 @@ +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:17:35 + | +LL | pub fn relaxed_bound_migration() { + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see +note: the lint level is defined here + --> $DIR/migration.rs:6:9 + | +LL | #![deny(sized_hierarchy_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: default bounds are being migrated to `const Sized` + --> $DIR/migration.rs:24:37 + | +LL | pub fn default_sized_to_const_sized() { + | ^- help: add `const Sized`: `: const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:30:32 + | +LL | pub fn sized_to_const_sized() { + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: a `const MetaSized` supertrait is required to maintain backwards compatibility + --> $DIR/migration.rs:37:1 + | +LL | pub trait ImplicitSupertrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: add an explicit `const MetaSized` supertrait: `: const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:45:30 + | +LL | pub trait SizedToConstSized: Sized { + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: a `const MetaSized` supertrait is required to maintain backwards compatibility + --> $DIR/migration.rs:53:1 + | +LL | pub trait AssocType { + | ^^^^^^^^^^^^^^^^^^^- help: add an explicit `const MetaSized` supertrait: `: const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:56:15 + | +LL | type Foo: Sized; + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:56:15 + | +LL | type Foo: Sized; + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:61:15 + | +LL | type Bar: ?Sized; + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:61:15 + | +LL | type Bar: ?Sized; + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + diff --git a/tests/ui/sized-hierarchy/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs new file mode 100644 index 0000000000000..b4f07baa1f998 --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs @@ -0,0 +1,29 @@ +//@ check-pass +#![allow(sized_hierarchy_migration)] +#![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> for Foo<'a, T> + where + T: for<'c> Bar<'c>, + >::Foo: PartialEq<>::Foo>, +{ + fn eq(&self, _: &Foo<'b, T>) -> bool { + loop {} + } +} + +fn main() { } diff --git a/tests/ui/sized-hierarchy/prelude.e2024.stderr b/tests/ui/sized-hierarchy/prelude.e2024.stderr new file mode 100644 index 0000000000000..e405456a59f30 --- /dev/null +++ b/tests/ui/sized-hierarchy/prelude.e2024.stderr @@ -0,0 +1,25 @@ +error[E0405]: cannot find trait `MetaSized` in this scope + --> $DIR/prelude.rs:11:21 + | +LL | pub fn metasized() {} + | ^^^^^^^^^ not found in this scope + | +help: consider importing this trait + | +LL + use std::marker::MetaSized; + | + +error[E0405]: cannot find trait `PointeeSized` in this scope + --> $DIR/prelude.rs:13:24 + | +LL | pub fn pointeesized() {} + | ^^^^^^^^^^^^ not found in this scope + | +help: consider importing this trait + | +LL + use std::marker::PointeeSized; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/sized-hierarchy/prelude.rs b/tests/ui/sized-hierarchy/prelude.rs new file mode 100644 index 0000000000000..e9084135af90e --- /dev/null +++ b/tests/ui/sized-hierarchy/prelude.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[e2024] check-fail +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future +//@[future] check-pass +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] + +pub fn metasized() {} +//[e2024]~^ ERROR cannot find trait `MetaSized` in this scope +pub fn pointeesized() {} +//[e2024]~^ ERROR cannot find trait `PointeeSized` in this scope diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr new file mode 100644 index 0000000000000..e805e15961975 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + | +LL | impl ConstSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + | +LL | impl SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:28:1 + | +LL | impl NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl NegSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:31:1 + | +LL | impl ConstMetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstMetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:34:1 + | +LL | impl MetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl 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:37:1 + | +LL | impl PointeeSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl PointeeSizedTr for T + where T: ?Sized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr new file mode 100644 index 0000000000000..e805e15961975 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + | +LL | impl ConstSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + | +LL | impl SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:28:1 + | +LL | impl NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl NegSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:31:1 + | +LL | impl ConstMetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstMetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:34:1 + | +LL | impl MetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl 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:37:1 + | +LL | impl PointeeSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl PointeeSizedTr for T + where T: ?Sized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. 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 0000000000000..f69104fcee7c2 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -0,0 +1,38 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future + +extern crate pretty_print_dep; +use pretty_print_dep::{ + ConstSizedTr, SizedTr, NegSizedTr, ConstMetaSizedTr, 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); + +impl ConstSizedTr for X {} +//~^ ERROR conflicting implementations of trait `ConstSizedTr` for type `X<_>` + +impl SizedTr for X {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl NegSizedTr for X {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl ConstMetaSizedTr for X {} +//~^ ERROR conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + +impl MetaSizedTr for X {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl PointeeSizedTr for X {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` 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 0000000000000..d5800be582805 --- /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); + +impl SizedTr for X {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl NegSizedTr for X {} +//~^ 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 0000000000000..1d50f0145fe9a --- /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 SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat.rs:18:1 + | +LL | impl NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl 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 0000000000000..955108a20744b --- /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 { + if true { + let x = foo(); + let y: Box = 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 0000000000000..bbe19870937ee --- /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 = 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` to `Box` + +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 0000000000000..85ad722ac98d4 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -0,0 +1,63 @@ +//@ compile-flags: --crate-type=lib +#![allow(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait Tr: PointeeSized {} +impl Tr for u32 {} + +pub fn sized() -> Box { + if true { + let x = sized(); + let y: Box = x; + } + Box::new(1u32) +} + +pub fn const_sized() -> Box { + if true { + let x = const_sized(); + let y: Box = x; + } + Box::new(1u32) +} + +pub fn neg_sized() -> Box { + if true { + let x = neg_sized(); + let y: Box = x; +//~^ ERROR: the size for values of type `impl Tr + const MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn metasized() -> Box { + if true { + let x = metasized(); + let y: Box = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn const_metasized() -> Box { + if true { + let x = const_metasized(); + let y: Box = x; +//~^ ERROR: the size for values of type `impl Tr + const MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn pointeesized() -> Box { +//~^ 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 = 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 0000000000000..07261931c7e92 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -0,0 +1,68 @@ +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:53:26 + | +LL | pub fn pointeesized() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 + const MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:29:30 + | +LL | let y: Box = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + const MetaSized` + = note: required for the cast from `Box` to `Box` + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:38:30 + | +LL | let y: Box = 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` to `Box` + +error[E0277]: the size for values of type `impl Tr + const MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:47:30 + | +LL | let y: Box = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + const MetaSized` + = note: required for the cast from `Box` to `Box` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:56: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:58:30 + | +LL | let y: Box = 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` to `Box` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:58:30 + | +LL | let y: Box = 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` to `Box` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print.e2024.stderr b/tests/ui/sized-hierarchy/pretty-print.e2024.stderr new file mode 100644 index 0000000000000..7d851188214f4 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.e2024.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:23:1 + | +LL | impl ConstSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:26:1 + | +LL | impl SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:29:1 + | +LL | impl pretty_print_dep::NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl NegSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:32:1 + | +LL | impl ConstMetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstMetaSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:35:1 + | +LL | impl MetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl MetaSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:38:1 + | +LL | impl PointeeSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl PointeeSizedTr for T + where T: PointeeSized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print.future.stderr b/tests/ui/sized-hierarchy/pretty-print.future.stderr new file mode 100644 index 0000000000000..7d851188214f4 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.future.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:23:1 + | +LL | impl ConstSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:26:1 + | +LL | impl SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:29:1 + | +LL | impl pretty_print_dep::NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl NegSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:32:1 + | +LL | impl ConstMetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl ConstMetaSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:35:1 + | +LL | impl MetaSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl MetaSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:38:1 + | +LL | impl PointeeSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl PointeeSizedTr for T + where T: PointeeSized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs new file mode 100644 index 0000000000000..091a731ac769a --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -0,0 +1,39 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future +#![allow(sized_hierarchy_migration)] +#![feature(const_trait_impl, 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::{ConstSizedTr, SizedTr, ConstMetaSizedTr, MetaSizedTr, PointeeSizedTr}; + +struct X(T); + +impl ConstSizedTr for X {} +//~^ ERROR conflicting implementations of trait `ConstSizedTr` for type `X<_>` + +impl SizedTr for X {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl pretty_print_dep::NegSizedTr for X {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl ConstMetaSizedTr for X {} +//~^ ERROR conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + +impl MetaSizedTr for X {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl PointeeSizedTr for X {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/specialisation.rs b/tests/ui/sized-hierarchy/specialisation.rs new file mode 100644 index 0000000000000..8a18eee9674b6 --- /dev/null +++ b/tests/ui/sized-hierarchy/specialisation.rs @@ -0,0 +1,32 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![no_std] +#![allow(internal_features)] +#![feature(rustc_attrs, min_specialization)] + +// Confirm that specialisation w/ sizedness host effect predicates works. + +pub trait Iterator { + type Item; +} + +#[rustc_unsafe_specialization_marker] +pub trait MoreSpecificThanIterator: Iterator {} + +pub trait Tr { + fn foo(); +} + +impl Tr for Iter + where + Iter: Iterator, +{ + default fn foo() {} +} + +impl Tr for Iter + where + Iter: MoreSpecificThanIterator, +{ + fn foo() {} +} diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index 9205d4052ad48..bdfacf7e9bf65 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -7,12 +7,21 @@ //@ [basic] compile-flags: -Z stack-protector=basic #![crate_type = "lib"] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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 2a9aadfcb83b5..b863e8c17594e 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); +struct Check(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 6304499148526..4640ceae81167 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_5CheckNtB_11ForeignTypeE) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs index 8b60820cc9b68..eac6590c5eb7e 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs @@ -1,11 +1,19 @@ //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib //@ needs-llvm-components: x86 //@ build-pass -#![feature(no_core, lang_items, x87_target_feature)] +#![feature(no_core, lang_items, x87_target_feature, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[target_feature(enable = "x87")] pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs index e34faf5a983c3..b54055b1d6996 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs @@ -2,8 +2,16 @@ //@ needs-llvm-components: x86 //@ compile-flags: -Ctarget-feature=-x87 //@ build-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 315ec983a19a5..3b6d3695c1228 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -6,16 +6,26 @@ //@ build-pass #![no_core] #![crate_type = "rlib"] -#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)] +#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api, const_trait_impl)] #![stable(feature = "test", since = "1.0.0")] // Tests vetting "feature hierarchies" in the cases where we impose them. // Supporting minimal rust core code +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +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.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs index 215e64979f736..45ecf83924e64 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs @@ -1,11 +1,19 @@ //! Ensure ABI-incompatible features cannot be enabled via `#[target_feature]`. //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv -#![feature(no_core, lang_items, riscv_target_feature)] +#![feature(no_core, lang_items, riscv_target_feature, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr index bfe767e5ffb07..4c2ef450c3915 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.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.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:18:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ 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 0000000000000..2692cf802f2d4 --- /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-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs index 81f138b175f29..757bdc7f0a1b2 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs @@ -6,8 +6,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs index 7242bcc85bfd1..0ec96559d7859 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs @@ -4,8 +4,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs index 7eebcf05dc0f4..06cf7b4c41d84 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs @@ -5,8 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs index f277a309cd698..c7e7d1d0f131a 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs @@ -8,5 +8,11 @@ #![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 {} diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index 6bb6f8aaffb6f..62e2da63a3dbd 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -1,11 +1,19 @@ //! Ensure "forbidden" target features cannot be enabled via `#[target_feature]`. //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 f8ea0c0e793fb..bcce824f5ef5c 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:18: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 e848ffde018e2..bb54e81c6287f 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -2,12 +2,20 @@ //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv //@ check-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![allow(unexpected_cfgs)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +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 cf85c5212289c..fdeb8fa11c978 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -5,8 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: unsound because it changes the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index 245841eb0395c..ed6c4e6175b3b 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -5,8 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: unsound because it changes the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} 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 28d026c1a9a2d..232b2e6235f32 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 @@ -5,8 +5,16 @@ //@ build-pass //@error-pattern: must be enabled -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index 17c13826ce9e6..5212b9b6b0757 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -11,10 +11,18 @@ //@ [three] compile-flags: -C target-feature=+paca,+pacg,-paca //@ [four] build-pass //@ [four] compile-flags: -C target-feature=-paca,+pacg -C target-feature=+paca -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +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 0473ca319b8f0..4f048c5354aea 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -5,11 +5,19 @@ //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together //@[pacg] compile-flags: -Ctarget-feature=+pacg //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +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 0e31dea24ea4d..6eda0729b6b0a 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:28:1 + --> $DIR/tied-features-no-implication.rs:36: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 157b50bb0d329..443f677974c05 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -5,11 +5,19 @@ //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together //@[pacg] compile-flags: -Ctarget-feature=+pacg //@[pacg] error-pattern: the name `foo` is defined multiple times -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +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 8c2391113d719..bc62adf4842d3 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() {} +fn test() {} fn main() { test::(); diff --git a/tests/ui/traits/cache-reached-depth-ice.stderr b/tests/ui/traits/cache-reached-depth-ice.stderr index e84ebc91ae169..fd76dc92dfbd7 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(, 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() {} - | ---- predicate +LL | fn test() {} + | ---- predicate ... LL | test::(); | ^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 08d7817548d7c..37a48da789387 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -12,20 +12,29 @@ 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"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} + #[lang = "copy"] pub trait Copy {} impl Copy for bool {} impl Copy for u8 {} -impl Copy for &T {} +impl Copy for &T {} #[lang = "add"] #[const_trait] @@ -106,17 +115,17 @@ pub trait Tuple {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl LegacyReceiver for &T {} +impl LegacyReceiver for &T {} -impl LegacyReceiver for &mut T {} +impl LegacyReceiver for &mut T {} #[lang = "receiver"] pub trait Receiver { #[lang = "receiver_target"] - type Target: ?Sized; + type Target: MetaSized; } -impl Receiver for T { +impl Receiver for T { type Target = ::Target; } @@ -162,15 +171,15 @@ fn panic_fmt() {} #[lang = "index"] #[const_trait] -pub trait Index { - type Output: ?Sized; +pub trait Index { + type Output: MetaSized; fn index(&self, index: Idx) -> &Self::Output; } #[const_trait] -pub unsafe trait SliceIndex { - type Output: ?Sized; +pub unsafe trait SliceIndex { + type Output: MetaSized; fn index(self, slice: &T) -> &Self::Output; } @@ -199,23 +208,23 @@ where } #[lang = "unsize"] -pub trait Unsize {} +pub trait Unsize: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized {} +pub trait CoerceUnsized {} -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize, 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 const Deref for &T { +impl const Deref for &T { type Target = T; fn deref(&self) -> &T { @@ -223,7 +232,7 @@ impl const Deref for &T { } } -impl const Deref for &mut T { +impl const Deref for &mut T { type Target = T; fn deref(&self) -> &T { @@ -307,14 +316,14 @@ fn from_str(s: &str) -> Result { #[lang = "eq"] #[const_trait] -pub trait PartialEq { +pub trait PartialEq: PointeeSized { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } } -impl const PartialEq<&B> for &A +impl const PartialEq<&B> for &A where A: ~const PartialEq, { @@ -357,7 +366,7 @@ impl

Pin

{ } } -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 +381,7 @@ impl Pin

{ } } -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 +427,7 @@ impl Clone for RefCell { } } -struct RefCell { +struct RefCell { borrow: UnsafeCell<()>, value: UnsafeCell, } @@ -427,7 +436,7 @@ impl RefCell { loop {} } } -impl RefCell { +impl RefCell { fn borrow(&self) -> Ref<'_, T> { loop {} } @@ -435,16 +444,16 @@ impl RefCell { #[lang = "unsafe_cell"] #[repr(transparent)] -struct UnsafeCell { +struct UnsafeCell { value: T, } -struct Ref<'b, T: ?Sized + 'b> { +struct Ref<'b, T: PointeeSized + 'b> { value: *const T, borrow: &'b UnsafeCell<()>, } -impl Deref for Ref<'_, T> { +impl Deref for Ref<'_, T> { type Target = T; #[inline] diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs index aaab8e819a39c..a8d178b949e8e 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +#![allow(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] const fn maybe_const_maybe() {} //~^ ERROR `~const` trait not allowed with `?` trait polarity modifier diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr index 18e4d160f5f46..cf02ddcc1325f 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr @@ -1,5 +1,5 @@ error: `~const` trait not allowed with `?` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:38 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:4:38 | LL | const fn maybe_const_maybe() {} | ------ ^ @@ -7,7 +7,7 @@ LL | const fn maybe_const_maybe() {} | there is not a well-defined meaning for a `~const ?` trait error: `const` trait not allowed with `?` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:7:25 | LL | fn const_maybe() {} | ----- ^ @@ -15,7 +15,7 @@ LL | fn const_maybe() {} | there is not a well-defined meaning for a `const ?` trait error: `~const` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:10:41 | LL | const fn maybe_const_negative() {} | ------ ^ @@ -23,7 +23,7 @@ LL | const fn maybe_const_negative() {} | there is not a well-defined meaning for a `~const !` trait error: `const` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:14:28 | LL | fn const_negative() {} | ----- ^ @@ -31,13 +31,13 @@ LL | fn const_negative() {} | there is not a well-defined meaning for a `const !` trait error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:10:41 | LL | const fn maybe_const_negative() {} | ^ error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:14:28 | LL | fn const_negative() {} | ^ diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.rs b/tests/ui/traits/issue-85360-eval-obligation-ice.rs index 931879a672262..bef84dabe70e9 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.rs +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.rs @@ -8,9 +8,11 @@ use core::marker::PhantomData; fn main() { test::>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) + //~^^ ERROR evaluate(Binder { value: HostEffectPredicate { trait_ref: > as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) test::>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) + //~^^ ERROR evaluate(Binder { value: HostEffectPredicate { trait_ref: > as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) } #[rustc_evaluate_where_clauses] diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr index d2b00a45a4f15..fee397ae36fd3 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr @@ -7,8 +7,26 @@ LL | test::>>(make()); LL | fn test(_: T) {} | ----- predicate +error: evaluate(Binder { value: HostEffectPredicate { trait_ref: > as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) + --> $DIR/issue-85360-eval-obligation-ice.rs:9:5 + | +LL | test::>>(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn test(_: T) {} + | ----- predicate + error: evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) - --> $DIR/issue-85360-eval-obligation-ice.rs:12:5 + --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 + | +LL | test::>>(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn test(_: T) {} + | ----- predicate + +error: evaluate(Binder { value: HostEffectPredicate { trait_ref: > as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) + --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 | LL | test::>>(make()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,5 +34,5 @@ LL | test::>>(make()); LL | fn test(_: T) {} | ----- predicate -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index 920f8add50795..2f454cfb062d9 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -1,6 +1,8 @@ //@ revisions: with without //@ compile-flags: -Znext-solver -#![feature(rustc_attrs)] +#![allow(sized_hierarchy_migration)] +#![feature(rustc_attrs, sized_hierarchy)] +use std::marker::PointeeSized; // This test is incredibly subtle. At its core the goal is to get a coinductive cycle, // which, depending on its root goal, either holds or errors. We achieve this by getting @@ -17,20 +19,20 @@ // test for that. #[rustc_coinductive] -trait Trait {} -struct A(*const T); -struct B(*const T); +trait Trait: PointeeSized {} +struct A(*const T); +struct B(*const T); -trait IncompleteGuidance {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} +trait IncompleteGuidance: PointeeSized {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} -trait ImplGuidance {} -impl ImplGuidance for T {} -impl ImplGuidance for T {} +trait ImplGuidance: PointeeSized {} +impl ImplGuidance for T {} +impl ImplGuidance for T {} -impl Trait for A +impl Trait for A where T: IncompleteGuidance, A: Trait, @@ -39,17 +41,24 @@ where { } -trait ToU8 {} +trait ToU8: PointeeSized {} impl ToU8 for () {} -impl Trait for B +impl Trait for B where T: ImplGuidance, A: Trait, { } -fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} +fn impls_trait() +where + T: PointeeSized + Trait, + U: PointeeSized, + V: PointeeSized, + D: PointeeSized +{ +} fn with_bound() where diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr index 9114bcadac0c0..0eaa7d805e72c 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr @@ -1,25 +1,28 @@ error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:74:19 | LL | impls_trait::, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` | = help: the trait `Trait` is implemented for `A` note: required for `A` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:35:74 | -LL | impl Trait for A - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl Trait for A + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A: Trait, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:56:23 | -LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait() + | ----------- required by a bound in this function +LL | where +LL | T: PointeeSized + Trait, + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr index 9114bcadac0c0..0eaa7d805e72c 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr @@ -1,25 +1,28 @@ error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:74:19 | LL | impls_trait::, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` | = help: the trait `Trait` is implemented for `A` note: required for `A` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:35:74 | -LL | impl Trait for A - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl Trait for A + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A: Trait, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:56:23 | -LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait() + | ----------- required by a bound in this function +LL | where +LL | T: PointeeSized + Trait, + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error 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 74a0a90885da5..be8bc846c048a 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,30 @@ error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` LL | Self::Assoc: A, | ^^^^ +error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: MetaSized` + --> $DIR/normalize-param-env-2.rs:24:22 + | +LL | Self::Assoc: A, + | ^^^^ + | +note: required by a bound in `A` + --> $DIR/normalize-param-env-2.rs:9:1 + | +LL | trait A { + | ^^^^^^^^^^ required by this bound in `A` + +error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: const MetaSized` + --> $DIR/normalize-param-env-2.rs:24:22 + | +LL | Self::Assoc: A, + | ^^^^ + | +note: required by a bound in `A` + --> $DIR/normalize-param-env-2.rs:9:1 + | +LL | trait A { + | ^^^^^^^^^^ required by this bound in `A` + error[E0275]: overflow evaluating the requirement `<() as A>::Assoc well-formed` --> $DIR/normalize-param-env-2.rs:24:22 | @@ -46,6 +70,6 @@ LL | where LL | Self::Assoc: A, | ^^^^ required by this bound in `A::f` -error: aborting due to 5 previous errors +error: aborting due to 7 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 e91a48f62aec3..bb46d53165266 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,30 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` LL | ::Assoc: Trait, | ^^^^^ +error[E0275]: overflow evaluating the requirement `::Assoc: MetaSized` + --> $DIR/normalize-param-env-4.rs:19:26 + | +LL | ::Assoc: Trait, + | ^^^^^ + | +note: required by a bound in `Trait` + --> $DIR/normalize-param-env-4.rs:7:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ required by this bound in `Trait` + +error[E0275]: overflow evaluating the requirement `::Assoc: const MetaSized` + --> $DIR/normalize-param-env-4.rs:19:26 + | +LL | ::Assoc: Trait, + | ^^^^^ + | +note: required by a bound in `Trait` + --> $DIR/normalize-param-env-4.rs:7:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ required by this bound in `Trait` + error[E0275]: overflow evaluating the requirement `::Assoc well-formed` --> $DIR/normalize-param-env-4.rs:19:26 | @@ -22,6 +46,6 @@ note: required by a bound in `impls_trait` LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` -error: aborting due to 3 previous errors +error: aborting due to 5 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 533891bf830d2..09c0244ec9540 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` where clause. +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait {} +use std::marker::PointeeSized; -impl Trait for T {} +trait Trait: PointeeSized {} + +impl 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 0fd16c5d0ee04..9f2df2238d15f 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/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 4d1cacb189083..41c89dfdb7827 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -1,11 +1,15 @@ //@ check-pass +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait {} +use std::marker::PointeeSized; -impl Trait for i32 {} +trait Trait {} + +impl Trait for i32 {} fn produce() -> impl for Trait { 16 diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr index 34c56068c5cc5..2d5f382c184cf 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:5: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 28785ae3dea14..5a47f1dcb5908 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,23 @@ +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete +use std::marker::PointeeSized; + trait Foo: for Bar {} -trait Bar { +trait Bar: PointeeSized { fn method(&self) {} } -fn needs_bar(x: &(impl Bar + ?Sized)) { +fn needs_bar(x: &(impl Bar + PointeeSized)) { x.method(); } impl Foo for () {} -impl Bar for () {} +impl Bar 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 43b69d0b50e48..eb24fcf5f98df 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:3: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:23 + --> $DIR/supertrait-dyn-compatibility.rs:23:23 | 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 - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -25,14 +25,14 @@ LL | trait Foo: for Bar {} = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:19:12 + --> $DIR/supertrait-dyn-compatibility.rs:23:12 | 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 - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -41,14 +41,14 @@ LL | trait Foo: for Bar {} = help: only type `()` implements `Foo`; consider using it directly instead. error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:22:5 + --> $DIR/supertrait-dyn-compatibility.rs:26:5 | LL | needs_bar(x); | ^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...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 3e5854ea1c85e..4e929937054fe 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:8: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 3e5854ea1c85e..4e929937054fe 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:8: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 2066887ea5966..6b91e1052e504 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,23 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![allow(sized_hierarchy_migration)] +#![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 Id for T { +impl Id for T { type Output = T; } -trait Everyone {} -impl Everyone for T {} +trait Everyone: PointeeSized {} +impl Everyone for T {} fn hello() where for ::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 0224e5763e0b4..586a76dcf3167 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:8: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 0224e5763e0b4..586a76dcf3167 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:8: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 5334118e9ac7d..b6763b252d31c 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,19 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -pub trait Foo { - type Bar: ?Sized; +use std::marker::PointeeSized; + +pub trait Foo { + type Bar: PointeeSized; } impl Foo for () { - type Bar = K; + type Bar = K; } pub fn f(a: T1, b: T2) diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 87f9c241e402b..3cf5ca2d7772a 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -1,12 +1,16 @@ // Need a different module so we try to build the mir for `test` // before analyzing `mod foo`. +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] mod foo { + use std::marker::PointeeSized; + pub trait Callable { fn call(); } - impl Callable for () { + impl Callable for () { //~^ ERROR the type parameter `V` is not constrained by the impl trait, self type, or predicates fn call() {} } diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e8e569ba625ee..7f4342410a06a 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/resolve-impl-before-constrain-check.rs:9:10 + --> $DIR/resolve-impl-before-constrain-check.rs:13:10 | -LL | impl Callable for () { +LL | impl Callable for () { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 2bb389c6ec161..251adc85c80c1 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:14:6 + --> $DIR/unconstrained-projection-normalization-2.rs:17:6 | -LL | impl Every for Thing { +LL | impl Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2bb389c6ec161..251adc85c80c1 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:14:6 + --> $DIR/unconstrained-projection-normalization-2.rs:17:6 | -LL | impl Every for Thing { +LL | impl Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.rs b/tests/ui/traits/unconstrained-projection-normalization-2.rs index 6b584c436c606..112c2e29b3e25 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.rs +++ b/tests/ui/traits/unconstrained-projection-normalization-2.rs @@ -5,13 +5,16 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] +use std::marker::PointeeSized; struct Thing; pub trait Every { type Assoc; } -impl Every for Thing { +impl Every for Thing { //~^ ERROR the type parameter `T` is not constrained type Assoc = T; } diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index 991f0e8ba666e..434327976af10 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:13:6 + --> $DIR/unconstrained-projection-normalization.rs:16:6 | -LL | impl Every for Thing { +LL | impl Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index 991f0e8ba666e..434327976af10 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:13:6 + --> $DIR/unconstrained-projection-normalization.rs:16:6 | -LL | impl Every for Thing { +LL | impl Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization.rs b/tests/ui/traits/unconstrained-projection-normalization.rs index fa4ab7fec4c2f..55fad7c14f5b7 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.rs +++ b/tests/ui/traits/unconstrained-projection-normalization.rs @@ -4,13 +4,16 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] +use std::marker::PointeeSized; struct Thing; pub trait Every { type Assoc; } -impl Every for Thing { +impl Every for Thing { //~^ ERROR the type parameter `T` is not constrained type Assoc = T; }