diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 6e345b2a6fdf..b1cf0661c16e 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -14,8 +14,14 @@ #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -24,35 +30,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize {} +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 +80,9 @@ impl Copy for isize {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl 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 +100,17 @@ unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} unsafe impl Sync for f32 {} -unsafe impl<'a, T: ?Sized> Sync for &'a T {} +unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl 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 +449,7 @@ pub enum Option { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData; +pub struct PhantomData; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -546,18 +552,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 c554a87b8256..73d5230edf77 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -11,8 +11,14 @@ unsafe extern "C" fn _Unwind_Resume() { intrinsics::unreachable(); } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -21,35 +27,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 = "receiver"] trait Receiver { @@ -74,9 +80,9 @@ impl Copy for isize {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl 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 {} @@ -92,17 +98,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 {} @@ -447,7 +453,7 @@ pub enum Option { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData; +pub struct PhantomData; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -564,18 +570,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 a636d09fcae2..bfc7556faf68 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 865424fd6bbd..6ca9f78e1a14 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -32,6 +32,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 e0df1b232e13..2be9ba292f97 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; #[diagnostic::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] @@ -100,12 +101,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] @@ -175,10 +176,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); @@ -231,10 +232,10 @@ impl std::ops::DerefMut 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/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1a011dfff3f7..abf58464c3cf 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -237,6 +237,8 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), + /// Introduces a hierarchy of `Sized` traits (RFC 3729). + (unstable, sized_hierarchy, "CURRENT_RUSTC_VERSION", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Added for testing unstable lints; perma-unstable. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 21d36ed54cdf..3a08e5ae3365 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -165,6 +165,8 @@ pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> { language_item_table! { // Variant name, Name, Getter method name, Target Generic requirements; Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0); + MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0); + PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0); Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index fad8abf5fae8..dba9b5cc6c4c 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -76,6 +76,7 @@ pub use check::{check_abi, check_abi_fn_ptr}; use rustc_abi::{ExternAbi, VariantIdx}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err}; +use rustc_hir::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::DenseBitSet; @@ -331,7 +332,7 @@ fn bounds_from_generic_predicates<'tcx>( ty::ClauseKind::Trait(trait_predicate) => { let entry = types.entry(trait_predicate.self_ty()).or_default(); let def_id = trait_predicate.def_id(); - if !tcx.is_default_trait(def_id) { + if !tcx.is_default_trait(def_id) && !tcx.is_lang_item(def_id, LangItem::Sized) { // Do not add that restriction to the list if it is a positive requirement. entry.push(trait_predicate.def_id()); } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 279b1e82a716..2789115c7e63 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -44,6 +44,14 @@ fn associated_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sizedness_bounds( + &mut bounds, + item_ty, + hir_bounds, + None, + None, + span, + ); icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span); } // `ConstIfConst` is only interested in `~const` bounds. @@ -333,6 +341,14 @@ fn opaque_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sizedness_bounds( + &mut bounds, + item_ty, + hir_bounds, + None, + None, + span, + ); icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span); } //`ConstIfConst` is only interested in `~const` bounds. diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ce0f83d0ec28..5ee60157f23f 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -162,9 +162,10 @@ 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) => { + ItemKind::Trait(_, _, _, _, self_bounds, ..) => { + is_trait = Some((self_bounds, item.span)); + } + ItemKind::TraitAlias(_, _, self_bounds) => { is_trait = Some((self_bounds, item.span)); } _ => {} @@ -183,21 +184,29 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the explicit where-clauses, but to get the full set of predicates // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. - if let Some(self_bounds) = is_trait { + if let Some((self_bounds, span)) = is_trait { let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, - self_bounds.0, + self_bounds, &mut bounds, ty::List::empty(), PredicateFilter::All, ); + icx.lowerer().add_sizedness_bounds( + &mut bounds, + tcx.types.self_param, + self_bounds, + None, + Some(def_id), + span, + ); icx.lowerer().add_default_super_traits( def_id, &mut bounds, - self_bounds.0, + self_bounds, hir_generics, - self_bounds.1, + span, ); predicates.extend(bounds); } @@ -224,6 +233,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let param_ty = icx.lowerer().lower_ty_param(param.hir_id); let mut bounds = Vec::new(); // Implicit bounds are added to type params unless a `?Trait` bound is found + icx.lowerer().add_sizedness_bounds( + &mut bounds, + param_ty, + &[], + Some((param.def_id, hir_generics.predicates)), + None, + param.span, + ); icx.lowerer().add_default_traits( &mut bounds, param_ty, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index bf91eb1b8fda..5371cf7909db 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -6,13 +6,13 @@ use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{AmbigArg, HirId}; +use rustc_hir::{AmbigArg, 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,23 +23,213 @@ use crate::hir_ty_lowering::{ AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason, }; +#[derive(Debug, Default)] +struct CollectedBound { + /// `Trait` + positive: bool, + /// `?Trait` + maybe: bool, + /// `!Trait` + negative: bool, +} + +impl CollectedBound { + /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered. + fn any(&self) -> bool { + self.positive || self.maybe || self.negative + } +} + +#[derive(Debug)] +struct CollectedSizednessBounds { + // Collected `Sized` bounds + sized: CollectedBound, + // Collected `MetaSized` bounds + meta_sized: CollectedBound, + // Collected `PointeeSized` bounds + pointee_sized: CollectedBound, +} + +impl CollectedSizednessBounds { + /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered for `Sized`, + /// `MetaSized` or `PointeeSized`. + fn any(&self) -> bool { + self.sized.any() || self.meta_sized.any() || self.pointee_sized.any() + } +} + +fn search_bounds_for<'tcx>( + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + mut f: impl FnMut(&'tcx PolyTraitRef<'tcx>), +) { + let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| { + for hir_bound in hir_bounds { + let hir::GenericBound::Trait(ptr) = hir_bound else { + continue; + }; + + f(ptr) + } + }; + + search_bounds(hir_bounds); + if let Some((self_ty, where_clause)) = self_ty_where_predicates { + for clause in where_clause { + if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind + && pred.is_param_bound(self_ty.to_def_id()) + { + search_bounds(pred.bounds); + } + } + } +} + +fn collect_unbounds<'tcx>( + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, +) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> { + let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); + search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| { + if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) { + unbounds.push(ptr); + } + }); + unbounds +} + +fn collect_bounds<'a, 'tcx>( + hir_bounds: &'a [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + target_did: DefId, +) -> CollectedBound { + let mut collect_into = CollectedBound::default(); + search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| { + if !matches!(ptr.trait_ref.path.res, Res::Def(DefKind::Trait, did) if did == target_did) { + return; + } + + match ptr.modifiers.polarity { + hir::BoundPolarity::Maybe(_) => collect_into.maybe = true, + hir::BoundPolarity::Negative(_) => collect_into.negative = true, + hir::BoundPolarity::Positive => collect_into.positive = true, + } + }); + collect_into +} + +fn collect_sizedness_bounds<'tcx>( + tcx: TyCtxt<'tcx>, + hir_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + span: Span, +) -> CollectedSizednessBounds { + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let sized = collect_bounds(hir_bounds, self_ty_where_predicates, sized_did); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let meta_sized = collect_bounds(hir_bounds, self_ty_where_predicates, meta_sized_did); + + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + let pointee_sized = collect_bounds(hir_bounds, self_ty_where_predicates, pointee_sized_did); + + CollectedSizednessBounds { sized, meta_sized, pointee_sized } +} + +/// Add a trait bound for `did`. +fn add_trait_bound<'tcx>( + tcx: TyCtxt<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, + self_ty: Ty<'tcx>, + did: DefId, + span: Span, +) { + let trait_ref = ty::TraitRef::new(tcx, did, [self_ty]); + // Preferable to put sizedness obligations first, since we report better errors for `Sized` + // ambiguity. + bounds.insert(0, (trait_ref.upcast(tcx), span)); +} + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { - pub(crate) fn add_default_traits( + /// Skip `PointeeSized` bounds. + /// + /// `PointeeSized` is a "fake bound" insofar as anywhere a `PointeeSized` bound exists, there + /// is actually the absence of any bounds. This avoids limitations around non-global where + /// clauses being preferred over item bounds (where `PointeeSized` bounds would be + /// proven) - which can result in errors when a `PointeeSized` supertrait/bound/predicate is + /// added to some items. + pub(crate) fn should_skip_sizedness_bound<'hir>( + &self, + bound: &'hir hir::GenericBound<'tcx>, + ) -> bool { + bound + .trait_ref() + .and_then(|tr| tr.trait_def_id()) + .map(|did| self.tcx().is_lang_item(did, LangItem::PointeeSized)) + .unwrap_or(false) + } + + /// Adds sizedness bounds to a trait, trait alias, parameter, opaque type or associated type. + /// + /// - On parameters, opaque type and associated types, add default `Sized` bound if no explicit + /// sizedness bounds are present. + /// - On traits and trait aliases, add default `MetaSized` supertrait if no explicit sizedness + /// bounds are present. + /// - On parameters, opaque type, associated types and trait aliases, add a `MetaSized` bound if + /// a `?Sized` bound is present. + pub(crate) fn add_sizedness_bounds( &self, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, - hir_bounds: &[hir::GenericBound<'tcx>], + hir_bounds: &'tcx [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + trait_did: Option, span: Span, ) { - self.add_default_traits_with_filter( - bounds, - self_ty, - hir_bounds, - self_ty_where_predicates, - span, - |_| true, - ); + let tcx = self.tcx(); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + + // If adding sizedness bounds to a trait, then there are some relevant early exits + if let Some(trait_did) = trait_did { + let trait_did = trait_did.to_def_id(); + // Never add a default supertrait to `PointeeSized`. + if trait_did == pointee_sized_did { + return; + } + // Don't add default sizedness supertraits to auto traits because it isn't possible to + // relax an automatically added supertrait on the defn itself. + if tcx.trait_is_auto(trait_did) { + return; + } + } else { + // Report invalid unbounds on sizedness-bounded generic parameters. + let unbounds = collect_unbounds(hir_bounds, self_ty_where_predicates); + self.check_and_report_invalid_unbounds_on_param(unbounds); + } + + let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span); + if (collected.sized.maybe || collected.sized.negative) + && !collected.sized.positive + && !collected.meta_sized.any() + && !collected.pointee_sized.any() + { + // `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any + // other explicit ones) - this can happen for trait aliases as well as bounds. + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + } else if !collected.any() { + if trait_did.is_some() { + // If there are no explicit sizedness bounds on a trait then add a default + // `MetaSized` supertrait. + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + } else { + // If there are no explicit sizedness bounds on a parameter then add a default + // `Sized` bound. + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + add_trait_bound(tcx, bounds, self_ty, sized_did, span); + } + } } /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds @@ -146,13 +336,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if !self.requires_default_supertraits(trait_bounds, trait_generics) { let self_ty_where_predicates = (parent, trait_item.generics.predicates); - self.add_default_traits_with_filter( + self.add_default_traits( bounds, tcx.types.self_param, &[], Some(self_ty_where_predicates), trait_item.span, - |tr| tr != hir::LangItem::Sized, ); } } @@ -174,41 +363,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias)); if self.requires_default_supertraits(hir_bounds, hir_generics) { let self_ty_where_predicates = (trait_def_id, hir_generics.predicates); - self.add_default_traits_with_filter( + self.add_default_traits( bounds, self.tcx().types.self_param, hir_bounds, Some(self_ty_where_predicates), span, - |default_trait| default_trait != hir::LangItem::Sized, ); } } - pub(crate) fn add_default_traits_with_filter( + pub(crate) fn add_default_traits( &self, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &[hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, - f: impl Fn(hir::LangItem) -> bool, ) { - self.tcx().default_traits().iter().filter(|&&default_trait| f(default_trait)).for_each( - |default_trait| { - self.add_default_trait( - *default_trait, - bounds, - self_ty, - hir_bounds, - self_ty_where_predicates, - span, - ); - }, - ); + self.tcx().default_traits().iter().for_each(|default_trait| { + self.add_default_trait( + *default_trait, + bounds, + self_ty, + hir_bounds, + self_ty_where_predicates, + span, + ); + }); } - /// Add a `Sized` or `experimental_default_bounds` bounds to the `bounds` if appropriate. + /// Add a `experimental_default_bounds` bound to the `bounds` if appropriate. /// /// Doesn't add the bound if the HIR bounds contain any of `Trait`, `?Trait` or `!Trait`. pub(crate) fn add_default_trait( @@ -220,7 +405,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, ) { - let trait_id = self.tcx().lang_items().get(trait_); + let tcx = self.tcx(); + let trait_id = tcx.lang_items().get(trait_); if let Some(trait_id) = trait_id && self.do_not_provide_default_trait_bound( trait_id, @@ -228,11 +414,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty_where_predicates, ) { - // There was no `?Trait` or `!Trait` bound; - // add `Trait` if it's available. - let trait_ref = ty::TraitRef::new(self.tcx(), trait_id, [self_ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - bounds.insert(0, (trait_ref.upcast(self.tcx()), span)); + add_trait_bound(tcx, bounds, self_ty, trait_id, span); } } @@ -242,90 +424,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_bounds: &'a [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, ) -> bool { - let tcx = self.tcx(); - let mut seen_negative_bound = false; - let mut seen_positive_bound = false; - - // Try to find an unbound in bounds. - let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); - let mut search_bounds = |hir_bounds: &'a [hir::GenericBound<'tcx>]| { - for hir_bound in hir_bounds { - let hir::GenericBound::Trait(ptr) = hir_bound else { - continue; - }; - match ptr.modifiers.polarity { - hir::BoundPolarity::Maybe(_) => unbounds.push(ptr), - hir::BoundPolarity::Negative(_) => { - if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) { - seen_negative_bound = true; - } - } - hir::BoundPolarity::Positive => { - if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) { - seen_positive_bound = true; - } - } - } - } - }; - search_bounds(hir_bounds); - if let Some((self_ty, where_clause)) = self_ty_where_predicates { - for clause in where_clause { - if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind - && pred.is_param_bound(self_ty.to_def_id()) - { - search_bounds(pred.bounds); - } - } - } - - let mut unique_bounds = FxIndexSet::default(); - let mut seen_repeat = false; - for unbound in &unbounds { - if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res { - seen_repeat |= !unique_bounds.insert(unbound_def_id); - } - } - if unbounds.len() > 1 { - let err = errors::MultipleRelaxedDefaultBounds { - spans: unbounds.iter().map(|ptr| ptr.span).collect(), - }; - if seen_repeat { - self.dcx().emit_err(err); - } else if !tcx.features().more_maybe_bounds() { - self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit(); - }; - } - - let mut seen_unbound = false; - for unbound in unbounds { - let unbound_def_id = unbound.trait_ref.trait_def_id(); - if unbound_def_id == Some(trait_def_id) { - seen_unbound = true; - } - let emit_relax_err = || { - let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds { - true => "`?Sized` and `experimental_default_bounds`", - false => "`?Sized`", - }; - // There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`. - tcx.dcx().span_err( - unbound.span, - format!( - "relaxing a default bound only does something for {}; \ - all other traits are not bound by default", - unbound_traits - ), - ); - }; - match unbound_def_id { - Some(def_id) if !tcx.is_default_trait(def_id) => emit_relax_err(), - None => emit_relax_err(), - _ => {} - } - } - - !(seen_unbound || seen_negative_bound || seen_positive_bound) + let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id); + !collected.any() } /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any. @@ -361,6 +461,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 'tcx: 'hir, { for hir_bound in hir_bounds { + if self.should_skip_sizedness_bound(hir_bound) { + continue; + } + // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`, // we skip over any traits that don't define the given associated type. if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 88f745892048..223a885e1cd8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -61,14 +61,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ast_bounds: Vec<_> = hir_bounds.iter().map(|&trait_ref| hir::GenericBound::Trait(trait_ref)).collect(); - self.add_default_traits_with_filter( - &mut user_written_bounds, - dummy_self, - &ast_bounds, - None, - span, - |tr| tr != hir::LangItem::Sized, - ); + self.add_default_traits(&mut user_written_bounds, dummy_self, &ast_bounds, None, span); let (elaborated_trait_bounds, elaborated_projection_bounds) = traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 3759a224ff75..a74d1fc1be06 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, LangItem, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::fast_reject::{TreatParams, simplify_type}; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -32,6 +32,57 @@ use crate::fluent_generated as fluent; use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer}; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { + /// Check for multiple relaxed default bounds and relaxed bounds of non-sizedness traits. + pub(crate) fn check_and_report_invalid_unbounds_on_param( + &self, + unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>, + ) { + let tcx = self.tcx(); + + let sized_did = tcx.require_lang_item(LangItem::Sized, 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 { + if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res + && ((did == sized_did) || tcx.is_default_trait(did)) + { + continue; + } + + let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds { + true => "`?Sized` and `experimental_default_bounds`", + false => "`?Sized`", + }; + self.dcx().span_err( + unbound.span, + format!( + "relaxing a default bound only does something for {}; all other traits are \ + not bound by default", + unbound_traits + ), + ); + } + } + /// On missing type parameters, emit an E0393 error and provide a structured suggestion using /// the type parameter's name as a placeholder. pub(crate) fn complain_about_missing_type_params( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 362c7d8efac0..384803d8fd7f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -22,8 +22,9 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferResult}; use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, Ty, TyCtxt, - TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, UserSelfTy, + self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, + UserSelfTy, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -439,7 +440,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || {}, ); // Sized types have static alignment, and so do slices. - if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) { + if tail.has_trivial_sizedness(self.tcx, SizedTraitKind::Sized) + || matches!(tail.kind(), ty::Slice(..)) + { // Nothing else is required here. } else { // We can't be sure, let's required full `Sized`. diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index dea7c8ac7087..3cc55eaa0f2c 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -46,7 +46,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .tcx .explicit_super_predicates_of(def_id) .iter_identity_copied() - .filter_map(|(pred, _)| pred.as_trait_clause()); + .filter_map(|(pred, _)| pred.as_trait_clause()) + .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized)); if direct_super_traits_iter.count() > 1 { cx.emit_span_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 711036865bbd..4c2aec1e2a4c 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -55,6 +55,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/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 9ed1f10455ad..4d914c42cfc6 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -328,6 +328,14 @@ impl Key for (DefId, SimplifiedType) { } } +impl Key for (DefId, ty::SizedTraitKind) { + type Cache = DefaultCache; + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for GenericArgsRef<'tcx> { type Cache = DefaultCache; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 88f4c4ae4d36..28d0b7d957a9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -81,8 +81,8 @@ use crate::ty::layout::ValidityRequirement; use crate::ty::print::{PrintTraitRefExt, describe_as_module}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{ - self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt, - TyCtxtFeed, + self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, SizedTraitKind, Ty, + TyCtxt, TyCtxtFeed, }; use crate::{dep_graph, mir, thir}; @@ -845,9 +845,10 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - - query adt_sized_constraint(key: DefId) -> Option>> { - desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) } + query adt_sizedness_constraint( + key: (DefId, SizedTraitKind) + ) -> Option>> { + desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } } query adt_dtorck_constraint( diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index d92b4f9c06be..6d5a3abf665b 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -229,8 +229,12 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef> for AdtDef<'tcx> { ) } - fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { - self.sized_constraint(tcx) + fn sizedness_constraint( + self, + tcx: TyCtxt<'tcx>, + sizedness: ty::SizedTraitKind, + ) -> Option>> { + self.sizedness_constraint(tcx, sizedness) } fn is_fundamental(self) -> bool { @@ -634,10 +638,15 @@ impl<'tcx> AdtDef<'tcx> { tcx.adt_async_destructor(self.did()) } - /// Returns a type such that `Self: Sized` if and only if that type is `Sized`, - /// or `None` if the type is always sized. - pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { - if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None } + /// If this ADT is a struct, returns a type such that `Self: {Meta,Pointee,}Sized` if and only + /// if that type is `{Meta,Pointee,}Sized`, or `None` if this ADT is always + /// `{Meta,Pointee,}Sized`. + pub fn sizedness_constraint( + self, + tcx: TyCtxt<'tcx>, + sizedness: ty::SizedTraitKind, + ) -> Option>> { + if self.is_struct() { tcx.adt_sizedness_constraint((self.did(), sizedness)) } else { None } } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 5ff87959a800..8bb7ac6eaf1f 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 0f7f8527088c..5c6fcbc1f711 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -10,7 +10,7 @@ use std::cmp::Ordering; use std::env::VarError; use std::ffi::OsStr; 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}; @@ -755,7 +755,9 @@ bidirectional_lang_item_map! { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, @@ -1583,16 +1585,17 @@ impl<'tcx> TyCtxt<'tcx> { self.reserve_and_set_memory_dedup(alloc, salt) } + /// Traits added on all bounds by default, excluding `Sized` which is treated separately. pub fn default_traits(self) -> &'static [rustc_hir::LangItem] { - match self.sess.opts.unstable_opts.experimental_default_bounds { - true => &[ - LangItem::Sized, + if self.sess.opts.unstable_opts.experimental_default_bounds { + &[ LangItem::DefaultTrait1, LangItem::DefaultTrait2, LangItem::DefaultTrait3, LangItem::DefaultTrait4, - ], - false => &[LangItem::Sized], + ] + } else { + &[] } } @@ -2509,17 +2512,17 @@ impl<'tcx> TyCtxt<'tcx> { // this type just holds a pointer to it, but it still effectively owns it. It // impls `Borrow` so that it can be looked up using the original // (non-arena-memory-owning) types. -struct InternedInSet<'tcx, T: ?Sized>(&'tcx T); +struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T); -impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> { fn clone(&self) -> Self { InternedInSet(self.0) } } -impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {} +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {} -impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> { fn into_pointer(&self) -> *const () { self.0 as *const _ as *const () } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2f4c03f0953d..781170d3109a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -52,6 +52,7 @@ use rustc_span::hygiene::MacroKind; use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::data_structures::DelayedSet; 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/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index af90c2fb95da..a4f4d7fd1fe8 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1069,16 +1069,20 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); + let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_sized_bound = false; let mut has_negative_sized_bound = false; - let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_meta_sized_bound = false; + let mut has_pointee_sized_bound = false; for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => { - // Don't print `+ Sized`, but rather `+ ?Sized` if absent. + // 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 => { @@ -1087,6 +1091,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } ty::PredicatePolarity::Negative => has_negative_sized_bound = true, } + } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { + has_meta_sized_bound = true; + continue; + } else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) { + // Unexpected - `PointeeSized` is the absence of bounds. + has_pointee_sized_bound = true; + continue; } self.insert_trait_and_projection( @@ -1255,8 +1266,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { })?; } + let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); let add_sized = has_sized_bound && (first || has_negative_sized_bound); - let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound; + let add_maybe_sized = + has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy; + // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. + has_pointee_sized_bound = has_pointee_sized_bound + || (!has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound); if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; @@ -1265,6 +1281,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { write!(self, "?")?; } write!(self, "Sized")?; + } else if has_meta_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "MetaSized")?; + } else if has_pointee_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "PointeeSized")?; } if !with_forced_trimmed_paths() { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2165cf186bd5..a83a08c24a9f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -15,6 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension}; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, TypeVisitableExt, elaborate}; use tracing::instrument; @@ -1675,7 +1676,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) { @@ -1776,17 +1777,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 implement `Sized`. Returning `false` means - /// nothing -- could be sized, might not be. + /// Returning true means the type is known to implement the sizedness trait. Returning `false` + /// means nothing -- could be sized, might not be. /// /// Note that we could never rely on the fact that a type such as `[_]` is trivially `!Sized` /// because we could be in a type environment with a bound such as `[_]: Copy`. A function with /// such a bound obviously never can be called, but that doesn't mean it shouldn't typecheck. /// This is why this method doesn't return `Option`. #[instrument(skip(tcx), level = "debug")] - pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { + pub fn has_trivial_sizedness(self, tcx: TyCtxt<'tcx>, sizedness: SizedTraitKind) -> bool { match self.kind() { ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) @@ -1809,13 +1810,21 @@ 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)), + .sizedness_constraint(tcx, sizedness) + .is_none_or(|ty| ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)), ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6fe5927c29fc..449d9cabe1b8 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}; @@ -1166,7 +1167,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 101129a231e7..5ffaa162d168 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, }; @@ -151,13 +152,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`. @@ -414,7 +418,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) } 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 b16f74cd8e43..60cc48bead57 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -5,6 +5,7 @@ use derive_where::derive_where; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{ self as ty, FallibleTypeFolder, Interner, Movability, Mutability, TypeFoldable, @@ -104,8 +105,9 @@ where } #[instrument(level = "trace", skip(ecx), ret)] -pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait( +pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait( ecx: &EvalCtxt<'_, D>, + sizedness: SizedTraitKind, ty: I::Ty, ) -> Result>, NoSolution> where @@ -113,8 +115,9 @@ where I: Interner, { match ty.kind() { - // impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, ! - // impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure + // impl {Meta,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(_) @@ -135,13 +138,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(_)) => { @@ -150,22 +161,27 @@ where ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), - // impl Sized for () - // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 + // impl {Meta,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)])) + if let Some(crit) = def.sizedness_constraint(ecx.cx(), sizedness) { + Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)])) } else { Ok(ty::Binder::dummy(vec![])) } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 5edc777262b8..d65c8089ac02 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -4,6 +4,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{self as ty, Interner, elaborate}; use tracing::instrument; @@ -198,11 +199,12 @@ where unreachable!("trait aliases are never const") } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, + _sizedness: SizedTraitKind, ) -> Result, NoSolution> { - unreachable!("Sized is never const") + unreachable!("Sized/MetaSized/PointeeSized is never const") } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 400b4ce1200c..0ad07c8a029e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,6 +6,7 @@ mod opaque_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{self as ty, Interner, NormalizesTo, PredicateKind, Upcast as _}; use tracing::instrument; @@ -383,11 +384,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 d19249df387c..f5e541331b01 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, @@ -133,9 +133,14 @@ 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.polarity() != goal.predicate.polarity { + return Err(NoSolution); + } + + if trait_clause_did == goal_did { if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, trait_clause.skip_binder().trait_ref.args, @@ -143,7 +148,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, @@ -151,13 +156,29 @@ 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 trait_ref = trait_clause + .self_ty() + .map_bound(|ty| ty::TraitRef::new(ecx.cx(), goal_did, [ty])); + return Self::probe_and_match_goal_against_assumption( + ecx, + source, + goal, + trait_ref.upcast(ecx.cx()), + then, + ); } - } else { - Err(NoSolution) } + + Err(NoSolution) } fn consider_auto_trait_candidate( @@ -241,9 +262,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); @@ -252,7 +274,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_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 34be35e36ace..806d880b19c5 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,6 +14,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 1eefd76f92b4..f4f59993f511 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 771ff98d58d5..067adda791de 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -15,6 +15,7 @@ )] #![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 b5003baaf633..26de9b0a4960 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; @@ -158,7 +159,7 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { } /// Trait used to convert between an internal MIR type to a Stable MIR type. -pub trait Stable<'cx> { +pub trait Stable<'cx>: PointeeSized { /// The stable representation of the type implementing Stable. type T; /// Converts an object to the equivalent Stable MIR representation. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3912c7dc7d69..76f21084ef35 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1322,6 +1322,7 @@ symbols! { memtag, message, meta, + meta_sized, metadata_type, min_align_of, min_align_of_val, @@ -1577,6 +1578,7 @@ symbols! { plugin_registrar, plugins, pointee, + pointee_sized, pointee_trait, pointer, pointer_like, @@ -1979,6 +1981,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 275b580d7945..ceb337535577 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 78f9287b407b..d4cc1ceb2800 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, AmbigArg, LangItem}; +use rustc_hir::{self as hir, AmbigArg}; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{ DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode, @@ -160,17 +160,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .collect(); - // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics - // with more relevant type information and hide redundant E0282 errors. - errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) - if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => - { - 1 + // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last. + // This lets us display diagnostics with more relevant type information and hide redundant + // E0282 errors. + errors.sort_by_key(|e| { + let maybe_sizedness_did = match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred.def_id()), + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => Some(pred.def_id()), + _ => None, + }; + + match e.obligation.predicate.kind().skip_binder() { + _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => 1, + _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => 2, + _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => 3, + ty::PredicateKind::Coerce(_) => 4, + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 5, + _ => 0, } - ty::PredicateKind::Coerce(_) => 2, - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, - _ => 0, }); for (index, error) in errors.iter().enumerate() { @@ -327,19 +334,26 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); let mut w = "impl".to_owned(); - let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); + #[derive(Debug, Default)] + struct SizednessFound { + sized: bool, + meta_sized: bool, + } - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxIndexSet::default(); - let sized_trait = tcx.lang_items().sized_trait(); + let mut types_with_sizedness_bounds = FxIndexMap::<_, SizednessFound>::default(); + + let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::>(); if !arg_names.is_empty() { - types_without_default_bounds.extend(args.types()); w.push('<'); w.push_str(&arg_names.join(", ")); w.push('>'); + + for ty in args.types() { + // `PointeeSized` params might have no predicates. + types_with_sizedness_bounds.insert(ty, SizednessFound::default()); + } } write!( @@ -351,24 +365,47 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti ) .unwrap(); - // The predicates will contain default bounds like `T: Sized`. We need to - // remove these bounds, and add `T: ?Sized` to any untouched type parameters. let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = - Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); + let mut pretty_predicates = Vec::with_capacity(predicates.len()); + + let sized_trait = tcx.lang_items().sized_trait(); + let meta_sized_trait = tcx.lang_items().meta_sized_trait(); for (p, _) in predicates { - if let Some(poly_trait_ref) = p.as_trait_clause() { - if Some(poly_trait_ref.def_id()) == sized_trait { - // FIXME(#120456) - is `swap_remove` correct? - types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); + // Accumulate the sizedness bounds for each self ty. + if let Some(trait_clause) = p.as_trait_clause() { + let self_ty = trait_clause.self_ty().skip_binder(); + let sizedness_of = types_with_sizedness_bounds.entry(self_ty).or_default(); + if Some(trait_clause.def_id()) == sized_trait { + sizedness_of.sized = true; + continue; + } else if Some(trait_clause.def_id()) == meta_sized_trait { + sizedness_of.meta_sized = true; continue; } } + pretty_predicates.push(p.to_string()); } - pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); + for (ty, sizedness) in types_with_sizedness_bounds { + if !tcx.features().sized_hierarchy() { + if sizedness.sized { + // Maybe a default bound, don't write anything. + } else { + pretty_predicates.push(format!("{ty}: ?Sized")); + } + } else { + if sizedness.sized { + // Maybe a default bound, don't write anything. + pretty_predicates.push(format!("{ty}: Sized")); + } else if sizedness.meta_sized { + pretty_predicates.push(format!("{ty}: MetaSized")); + } else { + pretty_predicates.push(format!("{ty}: PointeeSized")); + } + } + } if !pretty_predicates.is_empty() { write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); @@ -519,7 +556,7 @@ fn attempt_dyn_to_enum_suggestion( let Some(impl_type) = tcx.type_of(*impl_id).no_bound_vars() else { return None }; // Obviously unsized impl types won't be usable in an enum. - // Note: this doesn't use `Ty::is_trivially_sized` because that function + // Note: this doesn't use `Ty::has_trivial_sizedness` because that function // defaults to assuming that things are *not* sized, whereas we want to // fall back to assuming that things may be sized. match impl_type.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 220a847cc230..2aa678a673d9 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, @@ -543,11 +543,11 @@ fn receiver_for_self_ty<'tcx>( /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in /// a new check that `Trait` is dyn-compatible, creating a cycle. /// Instead, we emulate a placeholder by introducing a new type parameter `U` such that -/// `Self: Unsize` 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]> /// } @@ -567,9 +567,10 @@ fn receiver_is_dispatchable<'tcx>( ) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); - let traits = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()); - let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else { - debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits"); + let (Some(unsize_did), Some(dispatch_from_dyn_did)) = + (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()) + else { + debug!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits"); return false; }; @@ -583,7 +584,7 @@ fn receiver_is_dispatchable<'tcx>( receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id); // create a modified param env, with `Self: Unsize` and `U: Trait` (and all of - // its supertraits) added to caller bounds. `U: ?Sized` is already implied here. + // its supertraits) added to caller bounds. `U: MetaSized` is already implied here. let param_env = { // N.B. We generally want to emulate the construction of the `unnormalized_param_env` // in the param-env query here. The fact that we don't just start with the clauses @@ -612,6 +613,12 @@ fn receiver_is_dispatchable<'tcx>( let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args); predicates.push(trait_predicate.upcast(tcx)); + let meta_sized_predicate = { + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, None); + ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty]).upcast(tcx) + }; + predicates.push(meta_sized_predicate); + normalize_param_env_or_error( tcx, ty::ParamEnv::new(tcx.mk_clauses(&predicates)), diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 10a2ba049d85..65d6faee14c1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate}; +use rustc_middle::ty::{self, SizedTraitKind, Ty, TypeVisitableExt, TypingMode, elaborate}; use rustc_middle::{bug, span_bug}; use tracing::{debug, instrument, trace}; @@ -82,7 +82,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `Pointee` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); } else if tcx.is_lang_item(def_id, LangItem::Sized) { - self.assemble_builtin_sized_candidate(obligation, &mut candidates); + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::Sized, + ); + } else if tcx.is_lang_item(def_id, LangItem::MetaSized) { + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::MetaSized, + ); + } else if tcx.is_lang_item(def_id, LangItem::PointeeSized) { + self.assemble_builtin_sized_candidate( + obligation, + &mut candidates, + SizedTraitKind::PointeeSized, + ); } 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) { @@ -171,8 +187,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 { @@ -180,6 +196,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } selcx.infcx.probe(|_| { + if util::unelaborated_sizedness_candidate(selcx.infcx, obligation, [bound]) + .is_some() + { + // As `ProjectionCandidate` takes an index and not a predicate, a + // "corrected" `: MetaSized` candidate cannot be created, + // so instead keep the index of the `: Sized` predicate and + // correct for this in confirmation. + candidates.vec.push(ProjectionCandidate(idx)); + return; + } + // We checked the polarity already match selcx.match_normalize_trait_ref( obligation, @@ -218,6 +245,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!(?stack.obligation); + if let Some(bound) = + util::unelaborated_sizedness_candidate_from_obligation(self.infcx, stack.obligation) + { + candidates.vec.push(ParamCandidate(bound)); + return Ok(()); + } + let bounds = stack .obligation .param_env @@ -1059,15 +1093,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - /// Assembles the trait which are built-in to the language itself: - /// `Copy`, `Clone` and `Sized`. + /// Assembles the `Sized`, `MetaSized` and `PointeeSized` traits which are built-in to the + /// language itself. #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_sized_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, + sizedness: SizedTraitKind, ) { - match self.sized_conditions(obligation) { + match self.sizedness_conditions(obligation, sizedness) { BuiltinImplConditions::Where(nested) => { candidates .vec diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 94190cd3ae33..11298cd632ea 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -15,7 +15,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast, elaborate}; +use rustc_middle::ty::{self, GenericArgsRef, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use thin_vec::thin_vec; @@ -170,6 +170,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .expect("projection candidate is not a trait predicate") .map_bound(|t| t.trait_ref); + // During candidate assembly, if a unelaborated sizedness candidate would have been added, + // then the index of the `: Sized` predicate that satisfied this + // `: MetaSized` obligation was used - this means the candidate won't match + // the obligation below, so exit early. + if util::unelaborated_sizedness_candidate( + self.infcx, + obligation, + [candidate.upcast(self.infcx.tcx)], + ) + .is_some() + { + return Ok(PredicateObligations::new()); + } + let candidate = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, HigherRankedType, @@ -252,7 +266,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let obligations = if has_nested { let trait_def = obligation.predicate.def_id(); let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) { - self.sized_conditions(obligation) + self.sizedness_conditions(obligation, SizedTraitKind::Sized) + } else if tcx.is_lang_item(trait_def, LangItem::MetaSized) { + self.sizedness_conditions(obligation, SizedTraitKind::MetaSized) + } else if tcx.is_lang_item(trait_def, LangItem::PointeeSized) { + self.sizedness_conditions(obligation, SizedTraitKind::PointeeSized) } 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 4ce37db42800..f822dd3599d6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, - TypingMode, Upcast, elaborate, + self, GenericArgsRef, PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, TypingMode, Upcast, elaborate, }; use rustc_span::{Symbol, sym}; use tracing::{debug, instrument, trace}; @@ -2069,9 +2069,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } impl<'tcx> SelectionContext<'_, 'tcx> { - fn sized_conditions( + fn sizedness_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, + sizedness: SizedTraitKind, ) -> BuiltinImplConditions<'tcx> { use self::BuiltinImplConditions::{Ambiguous, None, Where}; @@ -2101,7 +2102,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Where(ty::Binder::dummy(Vec::new())) } - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => None, + SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())), + 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])), @@ -2110,11 +2120,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(self.tcx()) { + if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) { // (*) binder moved here - Where( - obligation.predicate.rebind(vec![sized_crit.instantiate(self.tcx(), args)]), - ) + Where(obligation.predicate.rebind(vec![crit.instantiate(self.tcx(), args)])) } else { Where(ty::Binder::dummy(Vec::new())) } @@ -2698,6 +2706,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, poly_trait_ref, ); + self.infcx .at(&obligation.cause, obligation.param_env) .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 035fd38c48aa..6d303d605bbf 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -4,10 +4,12 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::PolyTraitObligation; pub use rustc_infer::traits::util::*; use rustc_middle::bug; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, PolyTraitPredicate, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::Span; use smallvec::{SmallVec, smallvec}; @@ -507,15 +509,23 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { } pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>) -> bool { - // Proving `Sized` very often on "obviously sized" types like `&T`, accounts for about 60% - // percentage of the predicates we have to prove. No need to canonicalize and all that for - // such cases. + // Proving `Sized`/`MetaSized`/`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() { - if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) - && trait_ref.self_ty().is_trivially_sized(tcx) - { + let sizedness = if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + SizedTraitKind::Sized + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::MetaSized) { + SizedTraitKind::MetaSized + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::PointeeSized) { + SizedTraitKind::PointeeSized + } else { + return false; + }; + + if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) { debug!("fast path -- trivial sizedness"); return true; } @@ -523,3 +533,48 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc false } + +/// To improve performance, sizedness traits are not elaborated and so special-casing is required +/// in the trait solver to find a `Sized` candidate for a `MetaSized` obligation. Returns the +/// predicate to used in the candidate for such a `obligation`, given `candidates`. +pub(crate) fn unelaborated_sizedness_candidate<'tcx>( + infcx: &InferCtxt<'tcx>, + obligation: &PolyTraitObligation<'tcx>, + candidates: impl IntoIterator>, +) -> Option> { + use crate::infer::InferCtxtExt; + if !infcx.tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized) { + return None; + } + + let has = candidates.into_iter().any(|c| { + if !infcx.tcx.is_lang_item(c.def_id(), LangItem::Sized) { + return false; + } + + let expected_self_ty = obligation.self_ty(); + let found_self_ty = c.self_ty(); + obligation.predicate.polarity() == c.polarity() + && expected_self_ty.bound_vars() == found_self_ty.bound_vars() + && { + let expected_self_ty = + infcx.tcx.instantiate_bound_regions_with_erased(expected_self_ty); + let found_self_ty = infcx.tcx.instantiate_bound_regions_with_erased(found_self_ty); + infcx.can_eq(obligation.param_env, expected_self_ty, found_self_ty) + } + }); + + if has { Some(obligation.predicate) } else { None } +} + +/// See `unelaborated_sizedness_candidate`, but uses `Obligation::param_env` as `candidates`. +pub(crate) fn unelaborated_sizedness_candidate_from_obligation<'tcx>( + infcx: &InferCtxt<'tcx>, + obligation: &PolyTraitObligation<'tcx>, +) -> Option> { + unelaborated_sizedness_candidate( + infcx, + obligation, + obligation.param_env.caller_bounds().iter().filter_map(|c| c.as_trait_clause()), + ) +} diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 08d3b92e9b5e..88f35ef8f88b 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -567,6 +567,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { def_id: DefId, args: GenericArgsRef<'tcx>, ) -> PredicateObligations<'tcx> { + // PERF: `Sized`'s predicates include `MetaSized`, but both are compiler implemented marker + // traits, so `MetaSized` will always be WF if `Sized` is WF and vice-versa. Determining + // the nominal obligations of `Sized` would in-effect just elaborate `MetaSized` and make + // the compiler do a bunch of work needlessly. + if self.tcx().is_lang_item(def_id, LangItem::Sized) { + return Default::default(); + } + let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 31d69eef5ecf..2837bfcd3424 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -1,23 +1,29 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions, + self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, + fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_trait_selection::traits; use tracing::instrument; +/// If `ty` implements the given `sizedness` trait, returns `None`. Otherwise, returns the type +/// that must implement the given `sizedness` for `ty` to implement it. #[instrument(level = "debug", skip(tcx), ret)] -fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option> { +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(..) @@ -35,31 +41,44 @@ 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) => adt.sizedness_constraint(tcx, sizedness).and_then(|intermediate| { + let ty = intermediate.instantiate(tcx, args); + sizedness_constraint_for_ty(tcx, sizedness, ty) + }), + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { - bug!("unexpected type `{ty:?}` in sized_constraint_for_ty") + bug!("unexpected type `{ty:?}` in `sizedness_constraint_for_ty`") } } } @@ -75,15 +94,25 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { } } -/// Calculates the `Sized` constraint. +/// Returns the type of the last field of a struct ("the constraint") which must implement the +/// `sizedness` trait for the whole ADT to be considered to implement that `sizedness` trait. +/// `def_id` is assumed to be the `AdtDef` of a struct and will panic otherwise. +/// +/// For `Sized`, there are only a few options for the types in the constraint: +/// - an meta-sized type (str, slices, trait objects, etc) +/// - an pointee-sized type (extern types) +/// - a type parameter or projection whose sizedness can't be known +/// +/// For `MetaSized`, there are only a few options for the types in the constraint: +/// - an pointee-sized type (extern types) +/// - a type parameter or projection whose sizedness can't be known /// -/// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type +/// For `PointeeSized`, 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_sized_constraint<'tcx>( +fn adt_sizedness_constraint<'tcx>( tcx: TyCtxt<'tcx>, - def_id: DefId, + (def_id, sizedness): (DefId, SizedTraitKind), ) -> Option>> { if let Some(def_id) = def_id.as_local() { if let ty::Representability::Infinite(_) = tcx.representability(def_id) { @@ -93,21 +122,21 @@ fn adt_sized_constraint<'tcx>( let def = tcx.adt_def(def_id); if !def.is_struct() { - bug!("`adt_sized_constraint` called on non-struct type: {def:?}"); + bug!("`adt_sizedness_constraint` called on non-struct type: {def:?}"); } let tail_def = def.non_enum_variant().tail_opt()?; let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); - let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; + let constraint_ty = sizedness_constraint_for_ty(tcx, sizedness, tail_ty)?; - // perf hack: if there is a `constraint_ty: Sized` bound, then we know + // perf hack: if there is a `constraint_ty: {Meta,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 sizedness_trait_def_id = sizedness.require_lang_item(tcx); let predicates = tcx.predicates_of(def.did()).predicates; if predicates.iter().any(|(p, _)| { p.as_trait_clause().is_some_and(|trait_pred| { - trait_pred.def_id() == sized_trait_def_id + trait_pred.def_id() == sizedness_trait_def_id && trait_pred.self_ty().skip_binder() == constraint_ty }) }) { @@ -371,7 +400,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { asyncness, - adt_sized_constraint, + adt_sizedness_constraint, param_env, 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 b11bcff1d8bb..68fc603e15df 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,55 @@ 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(), + _ => return true, + }; + let next_did = match next_clause.kind().skip_binder() { + ty::ClauseKind::Trait(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 +168,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 +185,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 +216,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/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index e6e6466766be..5f904ca28a95 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability; use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; -use crate::solve::AdtDestructorKind; +use crate::solve::{AdtDestructorKind, SizedTraitKind}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; @@ -545,7 +545,11 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { // FIXME: perhaps use `all_fields` and expose `FieldDef`. fn all_field_tys(self, interner: I) -> ty::EarlyBinder>; - fn sized_constraint(self, interner: I) -> Option>; + fn sizedness_constraint( + self, + interner: I, + sizedness: SizedTraitKind, + ) -> 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 699dd82fb22c..3ee6e07b7a5e 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -30,7 +30,9 @@ pub enum TraitSolverLangItem { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 4e9b87fdf74d..ee1d0c065afb 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -8,6 +8,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use crate::lang_items::TraitSolverLangItem; use crate::search_graph::PathKind; use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; @@ -312,3 +313,26 @@ pub enum AdtDestructorKind { NotConst, Const, } + +/// Which sizedness trait - `Sized`, `MetaSized` or `PointeeSized`? +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub enum SizedTraitKind { + /// `Sized` trait + Sized, + /// `MetaSized` trait + MetaSized, + /// `PointeeSized` trait + PointeeSized, +} + +impl SizedTraitKind { + /// Returns `DefId` of corresponding language item. + pub fn require_lang_item(self, cx: I) -> I::DefId { + cx.require_lang_item(match self { + SizedTraitKind::Sized => TraitSolverLangItem::Sized, + SizedTraitKind::MetaSized => TraitSolverLangItem::MetaSized, + SizedTraitKind::PointeeSized => TraitSolverLangItem::PointeeSized, + }) + } +} diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index c237ac84cf40..629f15c93ce2 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 c315131f4136..d10da88a89ab 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 { @@ -2015,7 +2049,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&B> for &A + impl PartialEq<&B> for &A where A: PartialEq, { @@ -2029,7 +2063,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&B> for &A + impl PartialOrd<&B> for &A where A: PartialOrd, { @@ -2071,7 +2105,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &A + impl Ord for &A where A: Ord, { @@ -2081,12 +2115,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, { @@ -2100,7 +2134,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, { @@ -2142,7 +2176,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &mut A + impl Ord for &mut A where A: Ord, { @@ -2152,10 +2186,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, { @@ -2170,7 +2204,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 e1b10e1074d2..ca823a31e89c 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 4f7f8a5b84dd..13ddcc87979c 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -4,7 +4,7 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell}; use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; -use crate::marker::PhantomData; +use crate::marker::{PhantomData, PointeeSized}; use crate::num::fmt as numfmt; use crate::ops::Deref; use crate::{iter, result, str}; @@ -864,7 +864,7 @@ impl Display for Arguments<'_> { #[doc(alias = "{:?}")] #[rustc_diagnostic_item = "Debug"] #[rustc_trivial_field_reads] -pub trait Debug { +pub trait Debug: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples @@ -981,7 +981,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 @@ -1057,7 +1057,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; @@ -1116,7 +1116,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; @@ -1171,7 +1171,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; @@ -1226,7 +1226,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; @@ -1285,7 +1285,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; @@ -1336,7 +1336,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; @@ -1387,7 +1387,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; @@ -2632,11 +2632,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) } } )* @@ -2758,7 +2758,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) @@ -2803,21 +2803,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) } @@ -2826,13 +2826,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 f7b874b26bb7..efda64791d40 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 c5d5bc000f1c..54e7ea1cba2d 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -61,7 +61,7 @@ )] #![allow(missing_docs)] -use crate::marker::{DiscriminantKind, Tuple}; +use crate::marker::{DiscriminantKind, PointeeSized, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; @@ -3612,10 +3612,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; } @@ -3626,7 +3626,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 9dc20beda6c6..c56c4bc2094f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -93,15 +93,15 @@ pub unsafe auto trait Send { } #[stable(feature = "rust1", since = "1.0.0")] -impl !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. /// @@ -152,10 +152,50 @@ unsafe impl Send for &T {} #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] #[rustc_coinductive] -pub trait Sized { +pub trait Sized: MetaSized { // Empty. } +/// Types with a size that can be determined from pointer metadata. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[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] +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 @@ -192,7 +232,7 @@ pub trait Sized { #[lang = "unsize"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Unsize { +pub trait Unsize: PointeeSized { // Empty. } @@ -229,7 +269,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. @@ -442,8 +482,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, } @@ -452,7 +492,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. @@ -636,9 +676,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`. /// @@ -775,57 +815,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. /// @@ -868,15 +908,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, } /// Used to determine whether a type contains any `UnsafePinned` (or `PhantomPinned`) internally, @@ -992,15 +1032,15 @@ impl !UnsafeUnpin 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 e74f5443ac2d..f9fca460347c 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 { +#[cfg_attr(bootstrap, allow(multiple_supertrait_upcastable))] +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 d2a07197f6f6..2080b05d053f 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/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 5234fb83eb67..3a9056a24d91 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)) } @@ -1679,7 +1679,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 { @@ -1689,11 +1689,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 { @@ -1709,7 +1709,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 9c5da306e27a..c511830b73a9 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 445c789a7de2..a603d05da85a 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::num::NonZero; use crate::{fmt, hash, intrinsics, ub_checks}; @@ -521,7 +521,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. @@ -550,7 +550,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), ()) } @@ -575,7 +575,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), ()) } @@ -793,7 +793,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 } @@ -843,7 +843,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 } @@ -2107,7 +2107,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 } @@ -2131,7 +2131,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 ()) } @@ -2214,7 +2217,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 31b8d3b572c0..6a6f5392b89d 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)) } @@ -2097,7 +2098,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 { @@ -2107,11 +2108,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 { @@ -2127,7 +2128,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 0864cc457b65..a62f56ee4db4 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 @@ -1573,7 +1573,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 @@ -1581,39 +1581,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 { @@ -1622,7 +1628,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 { @@ -1631,7 +1637,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 { @@ -1640,7 +1646,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) @@ -1648,7 +1654,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() @@ -1656,7 +1662,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. @@ -1667,7 +1673,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 d688ce2a07a6..1b8a65312f1d 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 @@ -157,7 +157,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl Clone for Unique { +impl Clone for Unique { #[inline] fn clone(&self) -> Self { *self @@ -165,33 +165,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. @@ -202,7 +208,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 02eb805ece12..2c1b8abb6964 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,7 +1,7 @@ // See core/src/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; -use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; +use crate::marker::{ConstParamTy_, PointeeSized, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{self, Break, Continue}; // Recursive macro for implementing n-ary tuple functions and operations @@ -25,7 +25,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: PartialEq),+> PartialEq for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?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 { @@ -119,7 +119,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: Ord),+> Ord for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?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 ac568eab2e8a..8d462bdc300f 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -566,7 +566,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 55a116a018a8..6fe0c66219b3 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -267,14 +267,28 @@ pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { 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_self_bounds(generics); + let (generics, mut supertrait_bounds) = separate_self_bounds(generics); + + supertrait_bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } } fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { let predicates = cx.tcx.predicates_of(did); let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); - let (generics, bounds) = separate_self_bounds(generics); + let (generics, mut bounds) = separate_self_bounds(generics); + + bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + clean::TraitAlias { generics, bounds } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 622a410837b5..530f6492c537 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; @@ -906,6 +906,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 } @@ -1472,6 +1476,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 @@ -2303,6 +2314,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 41943b94d1e2..e09505a6851b 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 bbe11bf56af3..5cb154f5556e 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1276,11 +1276,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 87bb8d46a1d6..c44a84dc77c9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -388,9 +388,11 @@ fn check_other_call_arg<'tcx>( && let (input, n_refs) = peel_middle_ty_refs(*input) && let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input) && let Some(sized_def_id) = cx.tcx.lang_items().sized_trait() + && let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait() && let [trait_predicate] = trait_predicates .iter() .filter(|trait_predicate| trait_predicate.def_id() != sized_def_id) + .filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id) .collect::>()[..] && 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 e579dd5947d7..d28682ad2739 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 275d710c76a9..918334ec576b 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 40f40f7ea096..5c13d8622767 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -7,8 +7,14 @@ #[link(name = "c")] unsafe extern "C" {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index 2718217313ff..175dd0754081 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:27:19 + --> tests/ui/def_id_nocore.rs:33:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 0258a76c3e70..690f668637d6 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 eebedf842ef5..c8c9ff2f1e45 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 75efa5ff806c..20f39da6b4de 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 5b5eeb29f0f4..4f3673ccfc3b 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -13,12 +13,16 @@ #![crate_type = "lib"] #![no_std] #![no_core] - // FIXME: Migrate these code after PR #130693 is landed. -// vvvvv core + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/s390x-vector-abi.rs b/tests/assembly/s390x-vector-abi.rs index e159a3576850..fcf42664034c 100644 --- a/tests/assembly/s390x-vector-abi.rs +++ b/tests/assembly/s390x-vector-abi.rs @@ -15,12 +15,17 @@ #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] - // Cases where vector feature is disabled are rejected. // See tests/ui/simd-abi-checks-s390x.rs for test for them. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs index bed515915b85..2abe8687d8b2 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -19,8 +19,14 @@ #![no_core] #![crate_type = "lib"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "drop_in_place"] fn drop_in_place(_: *mut T) {} diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 941c4abed467..db11549382fc 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -39,13 +39,19 @@ macro_rules! impl_marker_trait { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl LegacyReceiver for &T {} -impl LegacyReceiver for &mut T {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} #[lang = "copy"] pub trait Copy: Sized {} @@ -67,14 +73,14 @@ impl_marker_trait!( f16, f32, f64, f128, ] ); -impl<'a, T: ?Sized> Copy for &'a T {} -impl 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, @@ -90,17 +96,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 {} @@ -176,15 +182,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 b348b4acc248..3f368bed88e5 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -30,8 +30,14 @@ fn panic_div_overflow() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs index 837bf6134b01..21b5eff4f489 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -17,7 +17,13 @@ #![crate_type = "lib"] #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +trait PointeeSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/dst-offset.rs b/tests/codegen/dst-offset.rs index 7177a960432a..2cf5fa9fac6a 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 3ab4b5c9c631..f43869cf2189 100644 --- a/tests/codegen/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs @@ -9,8 +9,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs index d0571e4df081..b0750d52268a 100644 --- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs @@ -8,8 +8,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/terminating-catchpad.rs b/tests/codegen/terminating-catchpad.rs index 17d887963009..a2ec19871d1f 100644 --- a/tests/codegen/terminating-catchpad.rs +++ b/tests/codegen/terminating-catchpad.rs @@ -15,8 +15,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} unsafe extern "C-unwind" { safe fn unwinds(); diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index 0d9c7757883f..ecace722e0db 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `aapcs` and // `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 4c7b2856e2e4..7df46813ed1d 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `fastcall` and // `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index ffc11d1faef8..cc06ee125495 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind` // extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index c869ca7e2b82..69bfaf80b4be 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `sysv64` and // `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index 19b23ee47ba8..05f6b8b70e17 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `thiscall` and // `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index b420f67ca9b7..d001a16b32a1 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, abi_vectorcall)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `vectorcall` and // `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute. diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index 2697d3cbcd68..257f00b54e4d 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `win64` and // `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/crashes/120033.rs b/tests/crashes/120033.rs index f1502978dc51..7584f98ec906 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 98b5f6063362..000000000000 --- 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/debuginfo/recursive-type-with-gat.rs b/tests/debuginfo/recursive-type-with-gat.rs index b8a67d8d24b4..a4a1736ef5f2 100644 --- a/tests/debuginfo/recursive-type-with-gat.rs +++ b/tests/debuginfo/recursive-type-with-gat.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Cdebuginfo=2 +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] // added to keep parameters unconstrained -pub trait Functor +pub trait Functor: std::marker::PointeeSized { type With: Functor; } @@ -17,20 +19,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/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index cb8716d90b07..4ff48fec744f 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -30,7 +30,7 @@ trait TraitVisibility { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail6")] pub trait TraitVisibility { } @@ -43,7 +43,7 @@ trait TraitUnsafety { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] unsafe trait TraitUnsafety { } @@ -57,7 +57,7 @@ trait TraitAddMethod { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub trait TraitAddMethod { fn method(); @@ -74,7 +74,7 @@ trait TraitChangeMethodName { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitChangeMethodName { fn methodChanged(); @@ -559,7 +559,7 @@ trait TraitAddBuiltinBoundToMethodTypeParameter { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddBuiltinBoundToMethodTypeParameter { #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] @@ -827,7 +827,7 @@ trait TraitAddAssociatedConstant { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddAssociatedConstant { const Value: u32; diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index a5003a8d4326..8faf6806b90b 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs @@ -34,7 +34,7 @@ impl ChangeMethodNameTrait for Foo { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub trait ChangeMethodNameTrait { #[rustc_clean(cfg="cfail3")] diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index 44faf3a4ed9a..fe2aaffa2a09 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -22,8 +22,14 @@ macro_rules! asm { }; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/amdgpu-kd/foo.rs b/tests/run-make/amdgpu-kd/foo.rs index a0d803ab8137..a097e9211a79 100644 --- a/tests/run-make/amdgpu-kd/foo.rs +++ b/tests/run-make/amdgpu-kd/foo.rs @@ -4,8 +4,14 @@ #![no_std] // This is needed because of #![no_core]: +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] extern "gpu-kernel" fn kernel() {} diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index b49c5044f31d..e98eaf7903ef 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -5,8 +5,14 @@ #[rustc_intrinsic] unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} #[lang = "freeze"] diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index c91cd695ceea..07fda1f3f4a3 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -24,14 +24,20 @@ pub fn main() -> ! { // FIXME: replace with proper minicore once available (#130693) mod minicore { + #[lang = "pointee_sized"] + pub trait PointeeSized {} + + #[lang = "meta_sized"] + pub trait MetaSized: PointeeSized {} + #[lang = "sized"] - pub trait Sized {} + pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} impl Copy for u32 {} impl Copy for &u32 {} - impl 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 cd1ef8cb351f..fd6f83570300 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -9,8 +9,14 @@ pub static mut STATIC_MUT_BOOL: bool = true; const CONST_BOOL: bool = true; pub static CONST_BOOL_REF: &'static bool = &CONST_BOOL; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs index 9ea8eb8cf883..1cd961ff87e7 100644 --- a/tests/run-make/simd-ffi/simd.rs +++ b/tests/run-make/simd-ffi/simd.rs @@ -52,8 +52,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { unsafe { integer(a, b) } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/run-make/target-specs/foo.rs b/tests/run-make/target-specs/foo.rs index 22939e87912c..aead76dff87c 100644 --- a/tests/run-make/target-specs/foo.rs +++ b/tests/run-make/target-specs/foo.rs @@ -4,8 +4,14 @@ #[lang = "copy"] trait Copy {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "freeze"] auto trait Freeze {} diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index 5440301f9650..104c4891502d 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -1,8 +1,14 @@ #![feature(no_core, auto_traits, lang_items, arbitrary_self_types)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} @@ -15,8 +21,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 1]" -//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 2]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[19, 1]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[21, 2]" //@ is "$.index[?(@.docs=='has span')].inner.impl.is_synthetic" false //@ is "$.index[?(@.inner.impl.is_synthetic==true)].span" null //@ is "$.index[?(@.inner.impl.is_synthetic==true)].inner.impl.for.resolved_path.path" '"Foo"' diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index a1f0ebd11b63..2bdbb8686268 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -6,8 +6,14 @@ //@ set impl_i32 = "$.index[?(@.docs=='Only core can do this')].id" +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} /// Only core can do this impl i32 { diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs index 18ac37280c0e..32ba331527da 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -5,8 +5,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} /// ```{class="} /// main; diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index cc13cc0fe531..fbe3df5d9d3d 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -1,5 +1,5 @@ error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 | LL | / /// ```{class="} LL | | /// main; @@ -17,7 +17,7 @@ LL | #![deny(warnings)] = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 | LL | / /// ```{class="} LL | | /// main; diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs index 17fa3ccfe3e8..775129872198 100644 --- a/tests/rustdoc-ui/target-feature-stability.rs +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -14,8 +14,14 @@ #![feature(arm_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} // `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. #[target_feature(enable = "fp-armv8")] diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/cfg_doc_reexport.rs index 44ec36632841..2c3b3110fb72 100644 --- a/tests/rustdoc/cfg_doc_reexport.rs +++ b/tests/rustdoc/cfg_doc_reexport.rs @@ -4,8 +4,14 @@ #![crate_name = "foo"] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ has 'foo/index.html' //@ has - '//dt/*[@class="stab portability"]' 'foobar' diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/cross-crate-primitive-doc.rs index 0ffde5b0f2d8..3c159d57f13f 100644 --- a/tests/rustdoc/cross-crate-primitive-doc.rs +++ b/tests/rustdoc/cross-crate-primitive-doc.rs @@ -5,8 +5,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} extern crate primitive_doc; diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc/file-creation-111249.rs index a6522d682f19..7a075a1583f3 100644 --- a/tests/rustdoc/file-creation-111249.rs +++ b/tests/rustdoc/file-creation-111249.rs @@ -1,10 +1,20 @@ // https://github.com/rust-lang/rust/issues/111249 #![crate_name = "foo"] #![feature(no_core)] +#![feature(lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + //@ files "foo" "['all.html', 'visible', 'index.html', 'sidebar-items.js', 'hidden', \ -// 'struct.Bar.html']" +// 'struct.Bar.html', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/visible" "['trait.Foo.html', 'index.html', 'sidebar-items.js']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" diff --git a/tests/rustdoc/foreigntype.rs b/tests/rustdoc/foreigntype.rs index bee3d8e65097..66371e8c827c 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 c050929db968..a33b0582b31a 100644 --- a/tests/rustdoc/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc/intra-doc/auxiliary/my-core.rs @@ -13,8 +13,14 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/extern-type.rs b/tests/rustdoc/intra-doc/extern-type.rs index 198ac8e43e08..41a678d52cd0 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 79825643b98c..9ce43e26aa19 100644 --- a/tests/rustdoc/intra-doc/no-doc-primitive.rs +++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs @@ -10,8 +10,14 @@ //@ has no_doc_primitive/index.html //! A [`char`] and its [`char::len_utf8`]. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} impl char { pub fn len_utf8(self) -> usize { diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc/intra-doc/prim-methods-local.rs index a9e71c58be35..f6aa1ed21565 100644 --- a/tests/rustdoc/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc/intra-doc/prim-methods-local.rs @@ -19,8 +19,14 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc/intra-doc/prim-self.rs index d5bfd570d547..21368fab9935 100644 --- a/tests/rustdoc/intra-doc/prim-self.rs +++ b/tests/rustdoc/intra-doc/prim-self.rs @@ -37,5 +37,11 @@ impl S { pub fn f() {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs index dcdcbfb7ec15..cd4d76baca1f 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs +++ b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs @@ -11,8 +11,14 @@ impl Box { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[doc(notable_trait)] pub trait FakeIterator {} diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs index 61060b3ff7c7..8f0a5806b091 100644 --- a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs +++ b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs @@ -3,11 +3,17 @@ #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \ -// 'visible']" +// 'visible', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" //@ files "foo/visible" "['index.html', 'sidebar-items.js', 'trait.Foo.html']" diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs index 0d2ee89415d4..a40116894a84 100644 --- a/tests/rustdoc/safe-intrinsic.rs +++ b/tests/rustdoc/safe-intrinsic.rs @@ -5,8 +5,14 @@ #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //@ has 'foo/fn.abort.html' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' diff --git a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs index 74882fb5c55c..b3bd0666ab21 100644 --- a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs +++ b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs @@ -7,8 +7,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] pub fn foo() {} diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index bdfcbed71e9a..99139761d7cc 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -4,6 +4,7 @@ error: rustc_dump_predicates LL | trait Trait: Iterator | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(, polarity:Positive), 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: [] } @@ -16,6 +17,7 @@ error: rustc_dump_predicates LL | type Assoc: std::ops::Deref | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(, polarity:Positive), 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: [] } diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 194bcaa307f2..6428b8c5247b 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -9,7 +9,13 @@ #![feature(lang_items, no_core, auto_traits)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //~? ERROR differs from LLVM target's diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index fb0ccb4fdcd7..b8ae4f6b56b7 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -25,3 +25,4 @@ type C = (); 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 67b704d8bc72..a7aa477ab31a 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -47,6 +47,7 @@ LL | type D = (); | ^ 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 598904d3c445..1dac8f8c62b4 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 4c0252123a4d..ea55399f618b 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 8f731f10ead4..ccf33542960f 100644 --- a/tests/ui/debuginfo/dwarf-versions.rs +++ b/tests/ui/debuginfo/dwarf-versions.rs @@ -29,8 +29,14 @@ #![no_core] #![no_std] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/extern/extern-type-diag-not-similar.rs b/tests/ui/extern/extern-type-diag-not-similar.rs index cd3eec9f1f7b..21a2a20a6445 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 3547f9b3ff61..f85ff1eead64 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 2df0cd4c923c..b273dcea7228 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 ba82caced7a4..3cac1aabea99 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 7865ddeda34f..56bdd5be7cff 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 78dbee77b9c4..080ed91a632a 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 399a5828ff3b..3ff51b9b6b0d 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 000000000000..040dc0d1f675 --- /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 8e5911228b2e..15777d456c26 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 44300b105141..07cb1efa8013 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 94a222a7e7e0..46cdc24e0832 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 a587d4dda55c..43dd9800d6d3 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 000000000000..b53e205bee5d --- /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 000000000000..afc8ccf607b7 --- /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 000000000000..33688c2e2ce0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -0,0 +1,29 @@ +#![feature(extern_types)] +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn needs_pointeesized() {} +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 000000000000..6a35fcfb0e8e --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -0,0 +1,42 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/feature-gate-sized-hierarchy.rs:17:19 + | +LL | needs_sized::(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by a bound in `needs_sized` + --> $DIR/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized() {} + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/feature-gate-sized-hierarchy.rs:25:23 + | +LL | needs_metasized::(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `main::Foo` +note: required by a bound in `needs_metasized` + --> $DIR/feature-gate-sized-hierarchy.rs:7:23 + | +LL | fn needs_metasized() {} + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/feature-gate-sized-hierarchy.rs:27:19 + | +LL | needs_sized::(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by a bound in `needs_sized` + --> $DIR/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized() {} + | ^^^^^ 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 2a39d579c51f..bb23f9fe5c67 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs @@ -13,8 +13,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} //[BADFLAGS]~? ERROR incorrect value `leaf` for unstable option `branch-protection` //[BADFLAGSPC]~? ERROR incorrect value `pc` for unstable option `branch-protection` diff --git a/tests/ui/lang-items/issue-83471.rs b/tests/ui/lang-items/issue-83471.rs index 6be345ac5076..f3ce9f25c136 100644 --- a/tests/ui/lang-items/issue-83471.rs +++ b/tests/ui/lang-items/issue-83471.rs @@ -4,9 +4,17 @@ #![feature(no_core)] #![no_core] +#[lang = "pointee_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] //~^ ERROR: lang items are subject to change [E0658] -trait Sized {} +trait Sized: MetaSized {} #[lang = "fn"] //~^ ERROR: lang items are subject to change [E0658] diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 244b2efeaf1e..e913c0bf10fd 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found built-in attribute `export_name` - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ not a type @@ -7,6 +7,24 @@ LL | fn call(export_name); error[E0658]: lang items are subject to change --> $DIR/issue-83471.rs:7:1 | +LL | #[lang = "pointee_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: lang items are subject to change + --> $DIR/issue-83471.rs:11:1 + | +LL | #[lang = "meta_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: lang items are subject to change + --> $DIR/issue-83471.rs:15:1 + | LL | #[lang = "sized"] | ^^^^^^^^^^^^^^^^^ | @@ -14,7 +32,7 @@ LL | #[lang = "sized"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: lang items are subject to change - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -23,7 +41,7 @@ LL | #[lang = "fn"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: anonymous parameters are deprecated and will be removed in the next edition - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` @@ -33,7 +51,7 @@ LL | fn call(export_name); = note: `#[warn(anonymous_parameters)]` on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -42,12 +60,12 @@ LL | trait Fn { | - this trait has 0 generic arguments error[E0425]: cannot find function `a` in this scope - --> $DIR/issue-83471.rs:21:5 + --> $DIR/issue-83471.rs:29:5 | LL | a() | ^ not found in this scope -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted Some errors have detailed explanations: E0425, E0573, E0658, E0718. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/lang-items/issue-87573.rs b/tests/ui/lang-items/issue-87573.rs index 7b805e8b0cdb..97146df0ba76 100644 --- a/tests/ui/lang-items/issue-87573.rs +++ b/tests/ui/lang-items/issue-87573.rs @@ -7,8 +7,14 @@ pub static STATIC_BOOL: bool = true; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/ui/lang-items/issue-87573.stderr b/tests/ui/lang-items/issue-87573.stderr index 7085bb8c339d..07f4f5d8ac86 100644 --- a/tests/ui/lang-items/issue-87573.stderr +++ b/tests/ui/lang-items/issue-87573.stderr @@ -1,5 +1,5 @@ error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/issue-87573.rs:20:1 + --> $DIR/issue-87573.rs:26:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn drop_fn() { | - this function has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/issue-87573.rs:26:1 + --> $DIR/issue-87573.rs:32:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 90ed5f3f0efd..c866501393d1 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -4,8 +4,14 @@ #![feature(lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +pub trait MyPointeeSized {} + +#[lang = "meta_sized"] +pub trait MyMetaSized: MyPointeeSized {} + #[lang = "sized"] -trait MySized {} +trait MySized: MyMetaSized {} #[lang = "add"] trait MyAdd<'a, T> {} diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 3de67d659403..aa67a9ca9214 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -1,5 +1,5 @@ error[E0718]: `add` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:10:1 + --> $DIR/lang-item-generic-requirements.rs:16:1 | LL | #[lang = "add"] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | trait MyAdd<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:14:1 + --> $DIR/lang-item-generic-requirements.rs:20:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | fn my_ptr_drop() {} | - this function has 0 generic arguments error[E0718]: `index` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:18:1 + --> $DIR/lang-item-generic-requirements.rs:24:1 | LL | #[lang = "index"] | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | trait MyIndex<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `phantom_data` lang item must be applied to a struct with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:22:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "phantom_data"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | struct MyPhantomData; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` lang item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:28:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:34:1 + --> $DIR/lang-item-generic-requirements.rs:40:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments error[E0392]: type parameter `T` is never used - --> $DIR/lang-item-generic-requirements.rs:24:22 + --> $DIR/lang-item-generic-requirements.rs:30:22 | LL | struct MyPhantomData; | ^ 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:30: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:50: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 f92a00e602cf..35d5d079c689 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs @@ -2,8 +2,14 @@ #![no_core] #![no_main] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized { } +trait Sized: MetaSized { } struct S; diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr index 9b25b1db292f..7b9541f734fa 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr @@ -1,5 +1,5 @@ error: requires `copy` lang_item - --> $DIR/missing-copy-lang-item-issue-19660.rs:12:5 + --> $DIR/missing-copy-lang-item-issue-19660.rs:18:5 | LL | argc | ^^^^ diff --git a/tests/ui/lang-items/start_lang_item_args.argc.stderr b/tests/ui/lang-items/start_lang_item_args.argc.stderr index cd7361255eb9..82fd374a1c5b 100644 --- a/tests/ui/lang-items/start_lang_item_args.argc.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argc.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:75:38 + --> $DIR/start_lang_item_args.rs:79:38 | LL | fn start(_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 1a5905ab8e60..6095f8fa5329 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:89:52 + --> $DIR/start_lang_item_args.rs:93:52 | LL | fn start(_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 c61ace3cd628..2a295c8990b3 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:82:52 + --> $DIR/start_lang_item_args.rs:86:52 | LL | fn start(_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 ef943d6b3dba..027fd16d4104 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:61:1 + --> $DIR/start_lang_item_args.rs:65:1 | LL | fn start(_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 00395a05d33f..0f295d350d1b 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:68:20 + --> $DIR/start_lang_item_args.rs:72:20 | LL | fn start(_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 193f25bab05b..6e462c8b1a7c 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:54:20 + --> $DIR/start_lang_item_args.rs:58:20 | LL | fn start(_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 56b787d2ae38..90fa5e0d575f 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:15:1 + --> $DIR/start_lang_item_args.rs:19:1 | LL | fn start() -> 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 2672efe51c9a..879917cc8006 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:29:83 + --> $DIR/start_lang_item_args.rs:33:83 | LL | fn start(_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 98814dcd24a7..d756909d7354 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:22:1 + --> $DIR/start_lang_item_args.rs:26:1 | LL | fn start(_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 5bb99e2adc88..1da761545a8f 100644 --- a/tests/ui/lang-items/start_lang_item_args.rs +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -8,7 +8,11 @@ #[lang = "copy"] pub trait Copy {} #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[cfg(missing_all_args)] #[lang = "start"] diff --git a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr index e0a8496dba99..ba1dd4b4f793 100644 --- a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr +++ b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:96:80 + --> $DIR/start_lang_item_args.rs:100:80 | LL | fn start(_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 4437b0fdcfb1..a11867997d39 100644 --- a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:34:87 + --> $DIR/start_lang_item_args.rs:38:87 | LL | fn start(_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 8570d96fc621..ecccf8c74bc3 100644 --- a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:41:1 + --> $DIR/start_lang_item_args.rs:45:1 | LL | / fn start( 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 18cd4c970405..19036819d3d8 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.rs +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.rs @@ -6,8 +6,15 @@ #[lang = "copy"] pub trait Copy {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "start"] #[target_feature(enable = "avx2")] diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr index 6214e3f8bc79..ce0b1d755744 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr @@ -1,5 +1,5 @@ error: `start` lang item function is not allowed to have `#[target_feature]` - --> $DIR/start_lang_item_with_target_feature.rs:13:1 + --> $DIR/start_lang_item_with_target_feature.rs:20:1 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index c9b1e0a4b9ec..03b7e7599601 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -15,4 +15,6 @@ impl A for u8 { //~ ERROR: the type parameter `C` is not constrained } #[rustc_layout(debug)] -struct S([u8; ::B]); //~ ERROR: the type has an unknown layout +struct S([u8; ::B]); +//~^ ERROR: the type has an unknown layout +//~| ERROR: type annotations needed diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 615c131eb904..82cd1217c490 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -4,12 +4,19 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self LL | impl A for u8 { | ^ unconstrained type parameter +error[E0282]: type annotations needed + --> $DIR/unconstrained-param-ice-137308.rs:18:16 + | +LL | struct S([u8; ::B]); + | ^^ cannot infer type for type parameter `C` + error: the type has an unknown layout --> $DIR/unconstrained-param-ice-137308.rs:18:1 | LL | struct S([u8; ::B]); | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index c2fc345fa2ba..96168ebeaa16 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 a09e76705156..536f88085ded 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 2e0bdb151e18..575a66fe302c 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,5 +1,6 @@ -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::offset_of; struct Alpha { @@ -26,7 +27,7 @@ struct Gamma { z: Extern, } -struct Delta { +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 714bf7a0266c..0953e86e222e 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:36:5 + --> $DIR/offset-of-dst-field.rs:37:5 | LL | offset_of!(Alpha, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,7 +8,7 @@ LL | offset_of!(Alpha, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:37:5 + --> $DIR/offset-of-dst-field.rs:38:5 | LL | offset_of!(Beta, z); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -17,7 +17,7 @@ LL | offset_of!(Beta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:38:5 + --> $DIR/offset-of-dst-field.rs:39:5 | LL | offset_of!(Gamma, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -26,7 +26,7 @@ LL | offset_of!(Gamma, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:40:5 + --> $DIR/offset-of-dst-field.rs:41:5 | LL | offset_of!((u8, dyn Trait), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -35,7 +35,7 @@ LL | offset_of!((u8, dyn Trait), 1); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:45:5 + --> $DIR/offset-of-dst-field.rs:46:5 | LL | offset_of!(Delta, 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:47: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:45: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:6:8 | LL | struct Alpha { | ^^^^^ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:50:5 + --> $DIR/offset-of-dst-field.rs:51:5 | LL | fn generic_with_maybe_sized() -> 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:55:16 | LL | offset_of!(([u8], u8), 1); | ^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs index 0b8308ba753a..618ac7d88ddf 100644 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -11,5 +11,11 @@ fn panic() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 9436441ecc6a..8ec2befcd0b3 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -1,8 +1,14 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang="sized"] -pub trait Sized {} +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index cb7b858e54dc..2cbdbb3ff951 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -1,54 +1,54 @@ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:141:18 + --> $DIR/privacy1.rs:147:18 | LL | use bar::baz; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:165:20 + --> $DIR/privacy1.rs:171:20 | LL | use self::foo::i::A; | ^ private module | note: the module `i` is defined here - --> $DIR/privacy1.rs:170:9 + --> $DIR/privacy1.rs:176:9 | LL | mod i { | ^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:104:16 + --> $DIR/privacy1.rs:110: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:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:105:16 + --> $DIR/privacy1.rs:111: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:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:107:16 + --> $DIR/privacy1.rs:113: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:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:108:16 + --> $DIR/privacy1.rs:114: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:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:112:16 + --> $DIR/privacy1.rs:118: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:46:5 | LL | trait B { | ^^^^^^^ error[E0603]: function `epriv` is private - --> $DIR/privacy1.rs:118:20 + --> $DIR/privacy1.rs:124:20 | LL | ::bar::epriv(); | ^^^^^ private function | note: the function `epriv` is defined here - --> $DIR/privacy1.rs:65:9 + --> $DIR/privacy1.rs:71:9 | LL | fn epriv(); | ^^^^^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:127:16 + --> $DIR/privacy1.rs:133:16 | LL | ::bar::baz::foo(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -147,13 +147,13 @@ LL + bar::foo(); | error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:128:16 + --> $DIR/privacy1.rs:134:16 | LL | ::bar::baz::bar(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -164,19 +164,19 @@ LL + bar::bar(); | error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:157:17 + --> $DIR/privacy1.rs:163: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:46:5 | LL | trait B { | ^^^^^^^ error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:77:23 + --> $DIR/privacy1.rs:83:23 | LL | fn bar() {} | -------- private associated function defined here @@ -185,7 +185,7 @@ LL | self::baz::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:95:13 + --> $DIR/privacy1.rs:101:13 | LL | fn bar() {} | -------- private associated function defined here @@ -194,7 +194,7 @@ LL | bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:102:19 + --> $DIR/privacy1.rs:108: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:111: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:114:23 | LL | fn bar2(&self) {} | -------------- private method defined here diff --git a/tests/ui/privacy/privacy4.rs b/tests/ui/privacy/privacy4.rs index 7341c7752bbf..6091613271fd 100644 --- a/tests/ui/privacy/privacy4.rs +++ b/tests/ui/privacy/privacy4.rs @@ -1,7 +1,9 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} +#[lang = "sized"] pub trait Sized: MetaSized {} +#[lang = "meta_sized"] pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} // Test to make sure that private items imported through globs remain private diff --git a/tests/ui/privacy/privacy4.stderr b/tests/ui/privacy/privacy4.stderr index 4aa3ae964c0c..eeefd85645c7 100644 --- a/tests/ui/privacy/privacy4.stderr +++ b/tests/ui/privacy/privacy4.stderr @@ -1,11 +1,11 @@ error[E0603]: module `glob` is private - --> $DIR/privacy4.rs:21:14 + --> $DIR/privacy4.rs:23:14 | LL | use bar::glob::gpriv; | ^^^^ private module | note: the module `glob` is defined here - --> $DIR/privacy4.rs:13:5 + --> $DIR/privacy4.rs:15:5 | LL | mod glob { | ^^^^^^^^ diff --git a/tests/ui/sized-hierarchy/alias-bounds.rs b/tests/ui/sized-hierarchy/alias-bounds.rs new file mode 100644 index 000000000000..87b4bab11b74 --- /dev/null +++ b/tests/ui/sized-hierarchy/alias-bounds.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PointeeSized, MetaSized}; + +trait Id: PointeeSized { + type This: PointeeSized; +} + +impl Id for T { + type This = T; +} + +fn requires_metasized() {} + +fn foo() +where + T: PointeeSized, + ::This: Sized +{ + // `T: Sized` from where bounds (`T: PointeeSized` removes any default bounds and + // `::This: Sized` normalizes to `T: Sized`). This should trivially satisfy + // `T: MetaSized`. + requires_metasized::(); +} diff --git a/tests/ui/sized-hierarchy/auxiliary/generic-const-exprs-dep.rs b/tests/ui/sized-hierarchy/auxiliary/generic-const-exprs-dep.rs new file mode 100644 index 000000000000..9748edc1d581 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/generic-const-exprs-dep.rs @@ -0,0 +1,13 @@ +#![feature(generic_const_exprs)] + +pub trait Tr { + fn foo(bar: PCS) { unimplemented!(); } +} + +pub struct Foo; + +pub const M: usize = 4; + +impl Tr for Foo +{ +} 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 000000000000..a7d18d903685 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs @@ -0,0 +1,19 @@ +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait SizedTr {} + +impl SizedTr for T {} + +pub trait NegSizedTr {} + +impl NegSizedTr 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 000000000000..3314b0f356f5 --- /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/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs new file mode 100644 index 000000000000..12b2eb2b5c1b --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -0,0 +1,49 @@ +//@ check-fail +#![feature(extern_types, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn bare() {} + + +fn sized() {} + +fn neg_sized() {} + + +fn metasized() {} + +fn neg_metasized() {} +//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + + +fn pointeesized() { } + +fn neg_pointeesized() { } +//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + + +fn main() { + // Functions which should have a `T: Sized` bound - check for an error given a non-Sized type: + + bare::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + sized::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + metasized::<[u8]>(); + pointeesized::<[u8]>(); + + // Functions which should have a `T: MetaSized` bound - check for an error given a + // non-MetaSized type: + unsafe extern "C" { + type Foo; + } + + bare::(); + //~^ 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 000000000000..22f0fa29d3e2 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -0,0 +1,88 @@ +error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/default-bound.rs:16:21 + | +LL | fn neg_metasized() {} + | ^^^^^^^^^^ + +error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/default-bound.rs:22:24 + | +LL | fn neg_pointeesized() { } + | ^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/default-bound.rs:29:12 + | +LL | bare::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `bare` + --> $DIR/default-bound.rs:6:9 + | +LL | fn bare() {} + | ^ 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:31:13 + | +LL | sized::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `sized` + --> $DIR/default-bound.rs:9:13 + | +LL | fn sized() {} + | ^^^^^ required by this bound in `sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/default-bound.rs:42:12 + | +LL | bare::(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by an implicit `Sized` bound in `bare` + --> $DIR/default-bound.rs:6:9 + | +LL | fn bare() {} + | ^ 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:44: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:9: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:46: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:14: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 000000000000..b25acf9e6ea4 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -0,0 +1,61 @@ +//@ check-fail +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +trait Sized_: Sized { } + +trait NegSized: ?Sized { } +//~^ ERROR `?Trait` is not permitted in supertraits + +trait MetaSized_: MetaSized { } + +trait NegMetaSized: ?MetaSized { } +//~^ ERROR `?Trait` is not permitted in supertraits + + +trait PointeeSized_: PointeeSized { } + +trait NegPointeeSized: ?PointeeSized { } +//~^ ERROR `?Trait` is not permitted in supertraits + +trait Bare {} + +fn requires_sized() {} +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 000000000000..de23936b900b --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -0,0 +1,125 @@ +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:8:17 + | +LL | trait NegSized: ?Sized { } + | ^^^^^^ + | + = note: traits are `?Sized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:13:21 + | +LL | trait NegMetaSized: ?MetaSized { } + | ^^^^^^^^^^ + | + = note: traits are `?MetaSized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/default-supertrait.rs:19:24 + | +LL | trait NegPointeeSized: ?PointeeSized { } + | ^^^^^^^^^^^^^ + | + = note: traits are `?PointeeSized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0277]: the size for values of type `T` cannot be known + --> $DIR/default-supertrait.rs:52:38 + | +LL | fn with_bare_trait() { + | ^^^^ doesn't have a known size + | +note: required by a bound in `Bare` + --> $DIR/default-supertrait.rs:22:1 + | +LL | trait Bare {} + | ^^^^^^^^^^^^^ required by this bound in `Bare` +help: consider further restricting type parameter `T` with unstable trait `MetaSized` + | +LL | fn with_bare_trait() { + | ++++++++++++++++++++++++ + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/default-supertrait.rs:35:22 + | +LL | fn with_metasized_supertrait() { + | - 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:24: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:43: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:24: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:45:26 + | +LL | requires_metasized::(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:25: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:54: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:24: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:56:26 + | +LL | requires_metasized::(); + | ^ doesn't have a known size + | +note: required by a bound in `requires_metasized` + --> $DIR/default-supertrait.rs:25: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/elaboration-opt-regions-1.rs b/tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs new file mode 100644 index 000000000000..d43883c2c05c --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-opt-regions-1.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PhantomData, MetaSized, PointeeSized}; + +struct Foo<'a, T: PointeeSized>(*mut &'a (), T); + +fn requires_metasized<'a, T: MetaSized>(f: &T) {} + +fn foo<'a, T: PointeeSized>(f: &Foo<'a, T>) +where + Foo<'a, T>: Sized +{ + requires_metasized(f); +} diff --git a/tests/ui/sized-hierarchy/elaboration-opt-regions.rs b/tests/ui/sized-hierarchy/elaboration-opt-regions.rs new file mode 100644 index 000000000000..66e600f3dc96 --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-opt-regions.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] + +use std::marker::{PhantomData, MetaSized, PointeeSized}; + +struct Foo<'a, T: PointeeSized>(PhantomData<&'a T>, T); + +fn requires_metasized() {} + +fn foo<'a, T: 'a + PointeeSized>() +where + Foo<'a, T>: Sized +{ + requires_metasized::>(); +} 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 000000000000..70a84aabf2cf --- /dev/null +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -0,0 +1,20 @@ +//@ check-pass +#![feature(extern_types, sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub fn hash(_: *const T) { + unimplemented!(); +} + +unsafe extern "C" { + type Foo; +} + +fn get() -> *const Foo { + unimplemented!() +} + +fn main() { + hash::(get()); +} diff --git a/tests/ui/sized-hierarchy/generic-const-exprs.rs b/tests/ui/sized-hierarchy/generic-const-exprs.rs new file mode 100644 index 000000000000..f6a1583f0975 --- /dev/null +++ b/tests/ui/sized-hierarchy/generic-const-exprs.rs @@ -0,0 +1,25 @@ +//@ aux-build:generic-const-exprs-dep.rs +//@ compile-flags: --crate-type=lib +//@ failure-status: 101 +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ rustc-env:RUST_BACKTRACE=0 + +extern crate generic_const_exprs_dep; +use generic_const_exprs_dep::{Tr, Foo}; + +pub fn build(bar: ()) { + Foo::foo(bar) +} + +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported +//~? ERROR Encountered anon const with inference variable args but no error reported diff --git a/tests/ui/sized-hierarchy/generic-const-exprs.stderr b/tests/ui/sized-hierarchy/generic-const-exprs.stderr new file mode 100644 index 000000000000..1394d680d5bf --- /dev/null +++ b/tests/ui/sized-hierarchy/generic-const-exprs.stderr @@ -0,0 +1,31 @@ +error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = error: internal compiler error: Encountered anon const with inference variable args but no error reported + | + = note: delayed at compiler/rustc_trait_selection/src/traits/mod.rs:596:27 - disabled backtrace + = query stack during panic: +end of query stack diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs new file mode 100644 index 000000000000..46697e47c4bf --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.rs @@ -0,0 +1,310 @@ +//@ check-fail +//@ edition: 2024 + +#![allow(incomplete_features, internal_features)] +#![feature(sized_hierarchy)] +#![feature(coroutines, dyn_star, extern_types, f16, never_type, unsized_fn_params)] + +use std::fmt::Debug; +use std::marker::{MetaSized, PointeeSized}; + +// This test checks that `Sized` and `MetaSized` are automatically implemented appropriately. + +fn needs_sized() { } +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 000000000000..eebe4e0d706a --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -0,0 +1,394 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:240:42 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsMetaSized { x: &[u8], y: [u8] } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:248:40 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsUnsized { x: &Foo, y: Foo } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | struct StructAllFieldsUnsized { x: Box, y: Foo } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:284:44 + | +LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsMetaSized { Qux { x: &[u8], y: [u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:291:42 + | +LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsUnsized { Qux { x: &Foo, y: Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumAllFieldsUnsized { Qux { x: Box, y: Foo } } + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:298:52 + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: &[u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } } + | ++++ + + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:305:50 + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: &Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Box } } + | ++++ + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/impls.rs:160: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:13: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:166:19 + | +LL | needs_sized::<[u8]>(); + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/impls.rs:172:19 + | +LL | needs_sized::(); + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:181:19 + | +LL | needs_sized::(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:183:23 + | +LL | needs_metasized::(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `main::Foo` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:198:19 + | +LL | needs_sized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:200:23 + | +LL | needs_metasized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:202:26 + | +LL | needs_pointeesized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:206:19 + | +LL | needs_sized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:208:23 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:208:23 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = note: required because it appears within the type `(main::Foo, main::Foo)` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:211:26 + | +LL | needs_pointeesized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:215:19 + | +LL | needs_sized::<(u32, [u8])>(); + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(u32, [u8])`, the trait `Sized` is not implemented for `[u8]` + = note: required because it appears within the type `(u32, [u8])` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:221:19 + | +LL | needs_sized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(u32, main::Foo)`, the trait `Sized` is not implemented for `main::Foo` + = note: required because it appears within the type `(u32, main::Foo)` +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:223:23 + | +LL | needs_metasized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = note: required because it appears within the type `(u32, main::Foo)` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:242:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `StructAllFieldsMetaSized` + --> $DIR/impls.rs:240:12 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:250:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo` +note: required because it appears within the type `StructAllFieldsUnsized` + --> $DIR/impls.rs:248:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:252:23 + | +LL | needs_metasized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo` +note: required because it appears within the type `StructAllFieldsUnsized` + --> $DIR/impls.rs:248:12 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:258:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `StructLastFieldMetaSized` + --> $DIR/impls.rs:257:12 + | +LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time + --> $DIR/impls.rs:265:19 + | +LL | needs_sized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo` +note: required because it appears within the type `StructLastFieldUnsized` + --> $DIR/impls.rs:264:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:13:19 + | +LL | fn needs_sized() { } + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/impls.rs:267:23 + | +LL | needs_metasized::(); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo` +note: required because it appears within the type `StructLastFieldUnsized` + --> $DIR/impls.rs:264:12 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:16:23 + | +LL | fn needs_metasized() { } + | ^^^^^^^^^ 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/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs new file mode 100644 index 000000000000..4bf486890bf2 --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs @@ -0,0 +1,28 @@ +//@ check-pass +#![feature(sized_hierarchy)] + +// This is a reduction of some code in `library/core/src/cmp.rs` that would ICE if a default +// `Pointee` bound is added - motivating the current status quo of `PointeeSized` being syntactic +// sugar for an absense of any bounds whatsoever. + +use std::marker::PhantomData; + +pub trait Bar<'a> { + type Foo; +} + +pub struct Foo<'a, T: Bar<'a>> { + phantom: PhantomData<&'a T>, +} + +impl<'a, 'b, T> PartialEq> 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/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 000000000000..0412ff651cee --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -0,0 +1,26 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, NegSizedTr, MetaSizedTr, PointeeSizedTr}; + +// Test that printing the sizedness trait bounds in the conflicting impl error without enabling +// `sized_hierarchy` will continue to print `?Sized`, even if the dependency is compiled with +// `sized_hierarchy`. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +struct X(T); + +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 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-dep-has-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr new file mode 100644 index 000000000000..cb9bfd178f88 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr @@ -0,0 +1,42 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:16:1 + | +LL | impl 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:19: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 `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22: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:25: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 4 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat.rs new file mode 100644 index 000000000000..d5800be58280 --- /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 000000000000..1d50f0145fe9 --- /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 000000000000..955108a20744 --- /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 000000000000..bbe19870937e --- /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 000000000000..2aceee23a017 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -0,0 +1,45 @@ +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait Tr: PointeeSized {} +impl Tr for u32 {} + +pub fn sized() -> Box { + if true { + let x = 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 + 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 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 000000000000..ecf4d912be8f --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -0,0 +1,59 @@ +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:35:26 + | +LL | pub fn pointeesized() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:20:30 + | +LL | let y: Box = 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 + 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 + 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:38:17 + | +LL | let x = pointeesized(); + | ^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:40:30 + | +LL | let y: Box = 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:40: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 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs new file mode 100644 index 000000000000..0908e76490ce --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -0,0 +1,28 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +// Test that printing the sizedness trait bounds in the conflicting impl error with +// `sized_hierarchy` enabled prints all of the appropriate bounds. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +use std::marker::{MetaSized, PointeeSized}; + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, MetaSizedTr, PointeeSizedTr}; + +struct X(T); + +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 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.stderr b/tests/ui/sized-hierarchy/pretty-print.stderr new file mode 100644 index 000000000000..3602c804945b --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.stderr @@ -0,0 +1,43 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:18:1 + | +LL | impl SizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl SizedTr for T + where T: Sized; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:21:1 + | +LL | impl pretty_print_dep::NegSizedTr for X {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl NegSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:24: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:27: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 4 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/trait-aliases.rs b/tests/ui/sized-hierarchy/trait-aliases.rs new file mode 100644 index 000000000000..5f77aafea457 --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-aliases.rs @@ -0,0 +1,9 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(trait_alias)] + +// Tests that `?Sized` is migrated to `MetaSized` in trait aliases. + +use std::ops::{Index, IndexMut}; + +pub trait SlicePrereq = ?Sized + IndexMut>::Output>; diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index dc61e35a089a..a635976c8427 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -11,8 +11,15 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} diff --git a/tests/ui/symbol-names/foreign-types.rs b/tests/ui/symbol-names/foreign-types.rs index 2a9aadfcb83b..b863e8c17594 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 630449914852..4640ceae8116 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-cpu/explicit-target-cpu.rs b/tests/ui/target-cpu/explicit-target-cpu.rs index cd4c2384bc1d..e4ae73b513b4 100644 --- a/tests/ui/target-cpu/explicit-target-cpu.rs +++ b/tests/ui/target-cpu/explicit-target-cpu.rs @@ -29,6 +29,12 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang="sized"] trait Sized {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr index 49c5479275f3..1b9b8e0a789c 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/abi-incompatible-target-feature-attribute.rs:15:90 + --> $DIR/abi-incompatible-target-feature-attribute.rs:21:90 | LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs index a87334407592..c07b6c448e94 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs @@ -9,6 +9,12 @@ #![feature(no_core, lang_items, riscv_target_feature, x87_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr index 81471fd7e303..e14094972328 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr @@ -1,5 +1,5 @@ error: target feature `soft-float` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/abi-incompatible-target-feature-attribute.rs:15:32 + --> $DIR/abi-incompatible-target-feature-attribute.rs:21:32 | LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index 68e1d3b9ddc6..302cceccf693 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -11,6 +11,12 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} #[lang = "freeze"] diff --git a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs index 0013d033b9c5..876134002ed1 100644 --- a/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN unstable feature specified for `-Ctarget-feature`: `x87` diff --git a/tests/ui/target-feature/abi-required-target-feature-attribute.rs b/tests/ui/target-feature/abi-required-target-feature-attribute.rs index 95723c57f94d..5eb9e85f85f6 100644 --- a/tests/ui/target-feature/abi-required-target-feature-attribute.rs +++ b/tests/ui/target-feature/abi-required-target-feature-attribute.rs @@ -6,8 +6,14 @@ #![feature(no_core, lang_items, x87_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "x87")] pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs index c3ce05baa64b..00b594bdce38 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs @@ -20,6 +20,12 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 315ec983a19a..ccf32a35f72e 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -12,10 +12,18 @@ // Tests vetting "feature hierarchies" in the cases where we impose them. // Supporting minimal rust core code +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} + impl Copy for bool {} #[stable(feature = "test", since = "1.0.0")] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs index 215e64979f73..e96e17a42121 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "d")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr index 84d27463b38c..9406c3bbfdcb 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-e-d.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute-e-d.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute-e-d.rs:16:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs index d74f4a1d4b17..70075b1bb78f 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs @@ -4,6 +4,12 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] pub trait Sized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr index af0e53f34f23..8c98d847e17f 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute-f-zfinx.stderr @@ -1,5 +1,5 @@ error: target feature `zfinx` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute-f-zfinx.rs:16:18 | LL | #[target_feature(enable = "zdinx")] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs new file mode 100644 index 000000000000..2692cf802f2d --- /dev/null +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs @@ -0,0 +1,20 @@ +//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib +//@ needs-llvm-components: x86 +//@ check-pass +#![feature(no_core, lang_items)] +#![no_core] +#![allow(unexpected_cfgs)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this +// complains about the missing macro rather than showing the error... but that's good enough. +#[cfg(not(target_feature = "x87"))] +compile_error!("the x87 feature *should* be exposed in `cfg`"); diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index 6bb6f8aaffb6..a59747ec80ff 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "forced-atomics")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr index f8ea0c0e793f..65814e8edcf6 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `forced-atomics` cannot be enabled with `#[target_feature]`: unsound because it changes the ABI of atomic operations - --> $DIR/forbidden-target-feature-attribute.rs:10:18 + --> $DIR/forbidden-target-feature-attribute.rs:16:18 | LL | #[target_feature(enable = "forced-atomics")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs index e848ffde018e..c21eb63257a0 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -6,8 +6,14 @@ #![no_core] #![allow(unexpected_cfgs)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} // The compile_error macro does not exist, so if the `cfg` evaluates to `true` this // complains about the missing macro rather than showing the error... but that's good enough. diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs index d394dbe7b15d..4d4d833caab2 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `forced-atomics` cannot be disabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index a04d7e347530..6e3e60e0409c 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -8,7 +8,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `forced-atomics` cannot be enabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs index be6cd2b6faf8..fcb8c3827411 100644 --- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs +++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs @@ -7,7 +7,13 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} //~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index ce1dc3224a19..e9de4561ced3 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -14,8 +14,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} fn main() {} diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 63a1d77dae9f..6c6e9e06b6ec 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -6,8 +6,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // In this test, demonstrate that +paca and +pacg both result in the tied feature error if there // isn't something causing an error. diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr index 4ff42d31e946..8b034c098d06 100644 --- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr +++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `foo` is defined multiple times - --> $DIR/tied-features-no-implication.rs:27:1 + --> $DIR/tied-features-no-implication.rs:33:1 | LL | fn foo() {} | -------- previous definition of the value `foo` here diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 1625f71431a6..5e38d5329f31 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -7,8 +7,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // Can't use `compile_error!` here without `core`/`std` but requiring these makes this test only // work if you have libcore built in the sysroot for `aarch64-unknown-linux-gnu`. Can't run this diff --git a/tests/ui/traits/cache-reached-depth-ice.rs b/tests/ui/traits/cache-reached-depth-ice.rs index 8c2391113d71..bc62adf4842d 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 e84ebc91ae16..fd76dc92dfbd 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 08d7817548d7..073337b2ac6d 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -12,20 +12,27 @@ fundamental, marker_trait_attr, const_trait_impl, - const_destruct + const_destruct, )] #![allow(internal_features, incomplete_features)] #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} + #[lang = "copy"] pub trait Copy {} impl Copy for bool {} impl Copy for u8 {} -impl Copy for &T {} +impl Copy for &T {} #[lang = "add"] #[const_trait] @@ -106,17 +113,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 +169,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 +206,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 +230,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 +314,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 +364,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 +379,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 +425,7 @@ impl Clone for RefCell { } } -struct RefCell { +struct RefCell { borrow: UnsafeCell<()>, value: UnsafeCell, } @@ -427,7 +434,7 @@ impl RefCell { loop {} } } -impl RefCell { +impl RefCell { fn borrow(&self) -> Ref<'_, T> { loop {} } @@ -435,16 +442,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/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs index 3818456d3a67..745b6ee9bc5c 100644 --- a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs +++ b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs @@ -5,8 +5,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "default_trait1"] auto trait DefaultTrait1 {} diff --git a/tests/ui/traits/default_auto_traits/default-bounds.rs b/tests/ui/traits/default_auto_traits/default-bounds.rs index 64733a400340..8535f82fc012 100644 --- a/tests/ui/traits/default_auto_traits/default-bounds.rs +++ b/tests/ui/traits/default_auto_traits/default-bounds.rs @@ -11,8 +11,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/ui/traits/default_auto_traits/default-bounds.stderr b/tests/ui/traits/default_auto_traits/default-bounds.stderr index 10fdcc43417d..318fc57fc9c2 100644 --- a/tests/ui/traits/default_auto_traits/default-bounds.stderr +++ b/tests/ui/traits/default_auto_traits/default-bounds.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Forbidden: SyncDrop` is not satisfied - --> $DIR/default-bounds.rs:37:9 + --> $DIR/default-bounds.rs:43:9 | LL | bar(Forbidden); | --- ^^^^^^^^^ the trait `SyncDrop` is not implemented for `Forbidden` @@ -7,13 +7,13 @@ LL | bar(Forbidden); | required by a bound introduced by this call | note: required by a bound in `bar` - --> $DIR/default-bounds.rs:33:8 + --> $DIR/default-bounds.rs:39:8 | LL | fn bar(_: T) {} | ^ required by this bound in `bar` error[E0277]: the trait bound `Forbidden: Leak` is not satisfied - --> $DIR/default-bounds.rs:37:9 + --> $DIR/default-bounds.rs:43:9 | LL | bar(Forbidden); | --- ^^^^^^^^^ the trait `Leak` is not implemented for `Forbidden` @@ -21,7 +21,7 @@ LL | bar(Forbidden); | required by a bound introduced by this call | note: required by a bound in `bar` - --> $DIR/default-bounds.rs:33:11 + --> $DIR/default-bounds.rs:39:11 | LL | fn bar(_: T) {} | ^^^^ required by this bound in `bar` diff --git a/tests/ui/traits/default_auto_traits/extern-types.current.stderr b/tests/ui/traits/default_auto_traits/extern-types.current.stderr index e1bd99b900f5..593204382e3a 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.current.stderr +++ b/tests/ui/traits/default_auto_traits/extern-types.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied - --> $DIR/extern-types.rs:44:13 + --> $DIR/extern-types.rs:50:13 | LL | foo(x); | --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque` @@ -7,9 +7,9 @@ LL | foo(x); | required by a bound introduced by this call | note: required by a bound in `foo` - --> $DIR/extern-types.rs:20:8 + --> $DIR/extern-types.rs:26:8 | -LL | fn foo(_: &T) {} +LL | fn foo(_: &T) {} | ^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/traits/default_auto_traits/extern-types.next.stderr b/tests/ui/traits/default_auto_traits/extern-types.next.stderr index e1bd99b900f5..593204382e3a 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.next.stderr +++ b/tests/ui/traits/default_auto_traits/extern-types.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied - --> $DIR/extern-types.rs:44:13 + --> $DIR/extern-types.rs:50:13 | LL | foo(x); | --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque` @@ -7,9 +7,9 @@ LL | foo(x); | required by a bound introduced by this call | note: required by a bound in `foo` - --> $DIR/extern-types.rs:20:8 + --> $DIR/extern-types.rs:26:8 | -LL | fn foo(_: &T) {} +LL | fn foo(_: &T) {} | ^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/traits/default_auto_traits/extern-types.rs b/tests/ui/traits/default_auto_traits/extern-types.rs index 822d4c0637f0..df106d83171c 100644 --- a/tests/ui/traits/default_auto_traits/extern-types.rs +++ b/tests/ui/traits/default_auto_traits/extern-types.rs @@ -7,8 +7,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} @@ -17,7 +23,7 @@ pub trait Copy {} auto trait Leak {} // implicit T: Leak here -fn foo(_: &T) {} +fn foo(_: &T) {} mod extern_leak { use crate::*; diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs index 49f2faba1468..5069cd256b27 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs @@ -12,8 +12,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr index b7ffb66e60bf..48745e40268d 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:53:25 + --> $DIR/maybe-bounds-in-dyn-traits.rs:59:25 | LL | let _: &dyn Trait = &NonLeakS; | ^^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` @@ -7,13 +7,13 @@ LL | let _: &dyn Trait = &NonLeakS; = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak` error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied - --> $DIR/maybe-bounds-in-dyn-traits.rs:58:7 + --> $DIR/maybe-bounds-in-dyn-traits.rs:64:7 | LL | x.leak_foo(); | ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait` | note: required by a bound in `Trait::leak_foo` - --> $DIR/maybe-bounds-in-dyn-traits.rs:45:5 + --> $DIR/maybe-bounds-in-dyn-traits.rs:51:5 | LL | fn leak_foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs index 4cb38bc8e795..b3801baaf704 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs @@ -14,8 +14,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "legacy_receiver"] trait LegacyReceiver {} diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr index 3dd8418b100f..bc797c9d9765 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:61:22 + --> $DIR/maybe-bounds-in-traits.rs:67:22 | LL | type Leak2 = NonLeakS; | ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` | note: required by a bound in `Test3::Leak2` - --> $DIR/maybe-bounds-in-traits.rs:61:9 + --> $DIR/maybe-bounds-in-traits.rs:67:9 | LL | type Leak2 = NonLeakS; | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2` error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:49:29 + --> $DIR/maybe-bounds-in-traits.rs:55:29 | LL | type MaybeLeakSelf: TestBase1 where Self: ?Leak; | ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self` | note: required by a bound in `TestBase1` - --> $DIR/maybe-bounds-in-traits.rs:45:21 + --> $DIR/maybe-bounds-in-traits.rs:51:21 | LL | trait TestBase1 {} | ^ required by this bound in `TestBase1` @@ -27,7 +27,7 @@ LL | trait Test1: Leak { | ++++++ error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/maybe-bounds-in-traits.rs:99:31 + --> $DIR/maybe-bounds-in-traits.rs:105:31 | LL | fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} | ^^^^^^^^^ @@ -38,13 +38,13 @@ LL | fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {} = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0277]: the trait bound `Self: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:86:43 + --> $DIR/maybe-bounds-in-traits.rs:92:43 | LL | const CNonLeak: usize = size_of::() where Self: ?Leak; | ^^^^ the trait `Leak` is not implemented for `Self` | note: required by a bound in `size_of` - --> $DIR/maybe-bounds-in-traits.rs:80:22 + --> $DIR/maybe-bounds-in-traits.rs:86:22 | LL | const fn size_of() -> usize { | ^ required by this bound in `size_of` @@ -54,13 +54,13 @@ LL | trait Trait: Leak { | ++++++ error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied - --> $DIR/maybe-bounds-in-traits.rs:109:18 + --> $DIR/maybe-bounds-in-traits.rs:115:18 | LL | NonLeakS.leak_foo(); | ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS` | note: required by a bound in `methods::Trait::leak_foo` - --> $DIR/maybe-bounds-in-traits.rs:95:9 + --> $DIR/maybe-bounds-in-traits.rs:101:9 | LL | fn leak_foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr index dd9393fae853..d99a4cbd3780 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr @@ -1,20 +1,5 @@ -error[E0308]: mismatched types - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 - | -LL | (MyType<'a, T>,): Sized, - | ^^^^^ lifetime mismatch - | - = note: expected trait ` as Sized>` - found trait ` as Sized>` -note: the lifetime `'a` as defined here... - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 - | -LL | fn foo<'a, T: ?Sized>() - | ^^ - = note: ...does not necessarily outlive the static lifetime - error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here @@ -22,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>() LL | is_sized::<(MyType<'a, T>,)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr index 05861877d413..d99a4cbd3780 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr @@ -1,18 +1,5 @@ -error[E0478]: lifetime bound not satisfied - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23 - | -LL | (MyType<'a, T>,): Sized, - | ^^^^^ - | -note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8 - | -LL | fn foo<'a, T: ?Sized>() - | ^^ - = note: but lifetime parameter must outlive the static lifetime - error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here @@ -20,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>() LL | is_sized::<(MyType<'a, T>,)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0478`. diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs index ae7a6c9bba33..6ddc0628dd19 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs @@ -11,8 +11,6 @@ fn is_sized() {} fn foo<'a, T: ?Sized>() where (MyType<'a, T>,): Sized, - //[current]~^ ERROR mismatched types - //[next]~^^ ERROR lifetime bound not satisfied MyType<'static, T>: Sized, { // Preferring the builtin `Sized` impl of tuples diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr index 8901805a20f5..1eb445f4848c 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -12,6 +12,13 @@ LL | impl Trait for T { | ----- ^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required by a bound in `Bound` + --> $DIR/normalizes-to-is-not-productive.rs:8:1 + | +LL | / trait Bound { +LL | | fn method(); +LL | | } + | |_^ required by this bound in `Bound` error[E0277]: the trait bound `Foo: Bound` is not satisfied --> $DIR/normalizes-to-is-not-productive.rs:47:19 diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index d179c8059623..8d8909625ffc 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -19,6 +19,23 @@ error[E0275]: overflow evaluating the requirement `<() as A>::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 { +LL | | type Assoc; +LL | | +LL | | fn f() +... | +LL | | } + | |_^ 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 +63,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 6 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index e91a48f62aec..2fd61a0b8e84 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,6 +4,20 @@ error[E0275]: overflow evaluating the requirement `::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 { +LL | | type Assoc; +LL | | } + | |_^ 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 +36,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 4 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 533891bf830d..09c0244ec954 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 0fd16c5d0ee0..9f2df2238d15 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.stderr +++ b/tests/ui/traits/non_lifetime_binders/basic.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:4:12 + --> $DIR/basic.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs index 74c23a59bee9..22044c2e6627 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs @@ -1,11 +1,14 @@ // Make sure not to construct predicates with escaping bound vars in `diagnostic_hir_wf_check`. // Regression test for . +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait A {} -impl A for () {} +use std::marker::PointeeSized; + +trait A {} +impl A for () {} trait B {} struct W(T); diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr index df99f4a67abb..8270fbeef0f6 100644 --- a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/diagnostic-hir-wf-check.rs:4:12 + --> $DIR/diagnostic-hir-wf-check.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,24 +8,24 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:12 + --> $DIR/diagnostic-hir-wf-check.rs:16:12 | LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:42 + --> $DIR/diagnostic-hir-wf-check.rs:16:42 | LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } | - ^^ the trait `B` is not implemented for `()` @@ -33,29 +33,29 @@ LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W(T); | ^ required by this bound in `W` error[E0277]: the trait bound `(): B` is not satisfied - --> $DIR/diagnostic-hir-wf-check.rs:13:40 + --> $DIR/diagnostic-hir-wf-check.rs:16:40 | LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } | ^^^^^ the trait `B` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/diagnostic-hir-wf-check.rs:10:1 + --> $DIR/diagnostic-hir-wf-check.rs:13:1 | LL | trait B {} | ^^^^^^^ note: required by a bound in `W` - --> $DIR/diagnostic-hir-wf-check.rs:11:13 + --> $DIR/diagnostic-hir-wf-check.rs:14:13 | LL | struct W(T); | ^ required by this bound in `W` diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 4d1cacb18908..1364f63a3733 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -1,11 +1,14 @@ //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait {} +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 34c56068c5cc..c8396c385484 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-rpit.rs:3:12 + --> $DIR/on-rpit.rs:4:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs index 28785ae3dea1..462724c73ee7 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs @@ -1,19 +1,22 @@ +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete +use std::marker::PointeeSized; + trait Foo: for 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 43b69d0b50e4..57f16b3dfd62 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-dyn-compatibility.rs:1:12 + --> $DIR/supertrait-dyn-compatibility.rs:2:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,14 +8,14 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:19:23 + --> $DIR/supertrait-dyn-compatibility.rs:22: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:7: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:22: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:7: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:25: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:7: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 3e5854ea1c85..6551253d2e9e 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr index 3e5854ea1c85..6551253d2e9e 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs index 2066887ea596..d900bd429e6e 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs @@ -3,19 +3,22 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Id { - type Output: ?Sized; +use std::marker::PointeeSized; + +trait Id: PointeeSized { + type Output: PointeeSized; } -impl 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 0224e5763e0b..fecdc860f8e7 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr index 0224e5763e0b..fecdc860f8e7 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs index 5334118e9ac7..04e34531f4d7 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs @@ -3,15 +3,18 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -pub trait Foo { - 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/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs index eadee6b711e5..b4e8e3a8aada 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.rs +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs @@ -1,12 +1,15 @@ +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Other {} +use std::marker::PointeeSized; -impl Other for U {} +trait Other: PointeeSized {} + +impl Other for U {} #[rustfmt::skip] -fn foo() +fn foo() where for T: Other {} diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr index ecc97e283bee..b997e7379e25 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/universe-error1.rs:1:12 + --> $DIR/universe-error1.rs:2:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,15 +8,15 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `T: Other<_>` is not satisfied - --> $DIR/universe-error1.rs:14:11 + --> $DIR/universe-error1.rs:17:11 | LL | foo::<_>(); | ^ the trait `Other<_>` is not implemented for `T` | note: required by a bound in `foo` - --> $DIR/universe-error1.rs:11:15 + --> $DIR/universe-error1.rs:14:15 | -LL | fn foo() +LL | fn foo() | --- required by a bound in this function LL | where LL | for T: Other {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 87f9c241e402..50d1a8745513 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -15,6 +15,7 @@ use foo::*; fn test() -> impl Sized { <() as Callable>::call() +//~^ ERROR: type annotations needed } fn main() {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e8e569ba625e..e5e989038a1f 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -1,9 +1,16 @@ +error[E0282]: type annotations needed + --> $DIR/resolve-impl-before-constrain-check.rs:17:6 + | +LL | <() as Callable>::call() + | ^^ cannot infer type for type parameter `V` + error[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 | LL | impl Callable for () { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2bb389c6ec16..f83069c88880 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -4,6 +4,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl Every for Thing { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/unconstrained-projection-normalization-2.rs:19:11 + | +LL | fn foo(_: ::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/unconstrained-projection-normalization-2.rs:19:11 + | +LL | fn foo(_: ::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for associated type `::Assoc` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.rs b/tests/ui/traits/unconstrained-projection-normalization-2.rs index 6b584c436c60..a2401ea461e0 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.rs +++ b/tests/ui/traits/unconstrained-projection-normalization-2.rs @@ -17,5 +17,7 @@ impl Every for Thing { } fn foo(_: ::Assoc) {} +//[next]~^ ERROR: type annotations needed +//[next]~| ERROR: type annotations needed fn main() {} diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index 991f0e8ba666..d9929065c5dc 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -4,6 +4,22 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl Every for Thing { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0283]: type annotations needed: cannot satisfy `::Assoc: Sync` + --> $DIR/unconstrained-projection-normalization.rs:18:11 + | +LL | static I: ::Assoc = 3; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: cannot satisfy `::Assoc: Sync` + = note: shared static variables must have a type that implements `Sync` + +error[E0282]: type annotations needed + --> $DIR/unconstrained-projection-normalization.rs:18:37 + | +LL | static I: ::Assoc = 3; + | ^ cannot infer type + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282, E0283. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/unconstrained-projection-normalization.rs b/tests/ui/traits/unconstrained-projection-normalization.rs index fa4ab7fec4c2..331d8af3a50b 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.rs +++ b/tests/ui/traits/unconstrained-projection-normalization.rs @@ -16,5 +16,7 @@ impl Every for Thing { } static I: ::Assoc = 3; +//[next]~^ ERROR: type annotations needed +//[next]~| ERROR: type annotations needed fn main() {}