Merge pull request #20100 from ShoyuVanilla/ignore-sized-hierarchy
Some checks are pending
metrics / build_metrics (push) Waiting to run
metrics / other_metrics (diesel-1.4.8) (push) Blocked by required conditions
metrics / other_metrics (hyper-0.14.18) (push) Blocked by required conditions
metrics / other_metrics (ripgrep-13.0.0) (push) Blocked by required conditions
metrics / other_metrics (self) (push) Blocked by required conditions
metrics / other_metrics (webrender-2022) (push) Blocked by required conditions
metrics / generate_final_metrics (push) Blocked by required conditions
rustdoc / rustdoc (push) Waiting to run

Backport new sized-hierarchy trait bounds in old ways
This commit is contained in:
Chayim Refael Friedman 2025-06-26 20:37:18 +00:00 committed by GitHub
commit a6c1fa01d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 142 additions and 65 deletions

View file

@ -308,6 +308,8 @@ impl LangItem {
language_item_table! { language_item_table! {
// Variant name, Name, Getter method name, Target Generic requirements; // Variant name, Name, Getter method name, Target Generic requirements;
Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0); Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
MetaSized, sym::meta_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
PointeeSized, sym::pointee_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;

View file

@ -581,11 +581,28 @@ impl<'a> TyLoweringContext<'a> {
match bound { match bound {
&TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => { &TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
// FIXME Don't silently drop the hrtb lifetimes here // FIXME Don't silently drop the hrtb lifetimes here
if let Some((trait_ref, ctx)) = self.lower_trait_ref_from_path(path, self_ty) { if let Some((trait_ref, mut ctx)) =
if !ignore_bindings { self.lower_trait_ref_from_path(path, self_ty.clone())
assoc_bounds = ctx.assoc_type_bindings_from_type_bound(trait_ref.clone()); {
// FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
// sized-hierarchy correctly.
let meta_sized = LangItem::MetaSized
.resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
let pointee_sized = LangItem::PointeeSized
.resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
if meta_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
// Ignore this bound
} else if pointee_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
// Regard this as `?Sized` bound
ctx.ty_ctx().unsized_types.insert(self_ty);
} else {
if !ignore_bindings {
assoc_bounds =
ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
}
clause =
Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
} }
clause = Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
} }
} }
&TypeBound::Path(path, TraitBoundModifier::Maybe) => { &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
@ -945,8 +962,32 @@ pub(crate) fn generic_predicates_for_param_query(
| WherePredicate::TypeBound { target, bound, .. } => { | WherePredicate::TypeBound { target, bound, .. } => {
let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) }; let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
if invalid_target { if invalid_target {
// If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types` // FIXME(sized-hierarchy): Revisit and adjust this properly once we have implemented
if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound { // sized-hierarchy correctly.
// If this is filtered out without lowering, `?Sized` or `PointeeSized` is not gathered into
// `ctx.unsized_types`
let lower = || -> bool {
match bound {
TypeBound::Path(_, TraitBoundModifier::Maybe) => true,
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
return false;
};
let Some(pointee_sized) =
LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
else {
return false;
};
// Lower the path directly with `Resolver` instead of PathLoweringContext`
// to prevent diagnostics duplications.
ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path).is_some_and(
|it| matches!(it, TypeNs::TraitId(tr) if tr == pointee_sized),
)
}
_ => false,
}
}();
if lower {
ctx.lower_where_predicate(pred, true).for_each(drop); ctx.lower_where_predicate(pred, true).for_each(drop);
} }
return false; return false;

View file

@ -1,3 +1,5 @@
use std::slice;
use ide_db::assists::GroupLabel; use ide_db::assists::GroupLabel;
use stdx::to_lower_snake_case; use stdx::to_lower_snake_case;
use syntax::ast::HasVisibility; use syntax::ast::HasVisibility;
@ -52,7 +54,7 @@ pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext<'_>
let fn_name = format!("is_{}", &to_lower_snake_case(&variant_name.text())); let fn_name = format!("is_{}", &to_lower_snake_case(&variant_name.text()));
// Return early if we've found an existing new fn // Return early if we've found an existing new fn
let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?; let impl_def = find_struct_impl(ctx, &parent_enum, slice::from_ref(&fn_name))?;
let target = variant.syntax().text_range(); let target = variant.syntax().text_range();
acc.add_group( acc.add_group(

View file

@ -1,3 +1,5 @@
use std::slice;
use ide_db::assists::GroupLabel; use ide_db::assists::GroupLabel;
use itertools::Itertools; use itertools::Itertools;
use stdx::to_lower_snake_case; use stdx::to_lower_snake_case;
@ -148,7 +150,7 @@ fn generate_enum_projection_method(
let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text())); let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text()));
// Return early if we've found an existing new fn // Return early if we've found an existing new fn
let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?; let impl_def = find_struct_impl(ctx, &parent_enum, slice::from_ref(&fn_name))?;
let target = variant.syntax().text_range(); let target = variant.syntax().text_range();
acc.add_group( acc.add_group(

View file

@ -143,7 +143,7 @@ fn foo<T>() {}
file_id: FileId( file_id: FileId(
1, 1,
), ),
range: 135..140, range: 446..451,
}, },
), ),
), ),

View file

@ -438,6 +438,8 @@ define_symbols! {
shr, shr,
simd, simd,
sized, sized,
meta_sized,
pointee_sized,
skip, skip,
slice_len_fn, slice_len_fn,
Some, Some,

View file

@ -26,7 +26,7 @@
//! deref: sized //! deref: sized
//! derive: //! derive:
//! discriminant: //! discriminant:
//! drop: //! drop: sized
//! env: option //! env: option
//! eq: sized //! eq: sized
//! error: fmt //! error: fmt
@ -37,7 +37,7 @@
//! future: pin //! future: pin
//! coroutine: pin //! coroutine: pin
//! dispatch_from_dyn: unsize, pin //! dispatch_from_dyn: unsize, pin
//! hash: //! hash: sized
//! include: //! include:
//! index: sized //! index: sized
//! infallible: //! infallible:
@ -77,33 +77,46 @@
pub mod marker { pub mod marker {
// region:sized // region:sized
#[lang = "pointee_sized"]
#[fundamental]
#[rustc_specialization_trait]
#[rustc_coinductive]
pub trait PointeeSized {}
#[lang = "meta_sized"]
#[fundamental]
#[rustc_specialization_trait]
#[rustc_coinductive]
pub trait MetaSized: PointeeSized {}
#[lang = "sized"] #[lang = "sized"]
#[fundamental] #[fundamental]
#[rustc_specialization_trait] #[rustc_specialization_trait]
pub trait Sized {} #[rustc_coinductive]
pub trait Sized: MetaSized {}
// endregion:sized // endregion:sized
// region:send // region:send
pub unsafe auto trait Send {} pub unsafe auto trait Send {}
impl<T: ?Sized> !Send for *const T {} impl<T: PointeeSized> !Send for *const T {}
impl<T: ?Sized> !Send for *mut T {} impl<T: PointeeSized> !Send for *mut T {}
// region:sync // region:sync
unsafe impl<T: Sync + ?Sized> Send for &T {} unsafe impl<T: Sync + PointeeSized> Send for &T {}
unsafe impl<T: Send + ?Sized> Send for &mut T {} unsafe impl<T: Send + PointeeSized> Send for &mut T {}
// endregion:sync // endregion:sync
// endregion:send // endregion:send
// region:sync // region:sync
pub unsafe auto trait Sync {} pub unsafe auto trait Sync {}
impl<T: ?Sized> !Sync for *const T {} impl<T: PointeeSized> !Sync for *const T {}
impl<T: ?Sized> !Sync for *mut T {} impl<T: PointeeSized> !Sync for *mut T {}
// endregion:sync // endregion:sync
// region:unsize // region:unsize
#[lang = "unsize"] #[lang = "unsize"]
pub trait Unsize<T: ?Sized> {} pub trait Unsize<T: PointeeSized>: PointeeSized {}
// endregion:unsize // endregion:unsize
// region:unpin // region:unpin
@ -120,7 +133,7 @@ pub mod marker {
// endregion:derive // endregion:derive
mod copy_impls { mod copy_impls {
use super::Copy; use super::{Copy, PointeeSized};
macro_rules! impl_copy { macro_rules! impl_copy {
($($t:ty)*) => { ($($t:ty)*) => {
@ -137,9 +150,9 @@ pub mod marker {
bool char bool char
} }
impl<T: ?Sized> Copy for *const T {} impl<T: PointeeSized> Copy for *const T {}
impl<T: ?Sized> Copy for *mut T {} impl<T: PointeeSized> Copy for *mut T {}
impl<T: ?Sized> Copy for &T {} impl<T: PointeeSized> Copy for &T {}
impl Copy for ! {} impl Copy for ! {}
} }
// endregion:copy // endregion:copy
@ -151,7 +164,7 @@ pub mod marker {
// region:phantom_data // region:phantom_data
#[lang = "phantom_data"] #[lang = "phantom_data"]
pub struct PhantomData<T: ?Sized>; pub struct PhantomData<T: PointeeSized>;
// endregion:phantom_data // endregion:phantom_data
// region:discriminant // region:discriminant
@ -206,9 +219,11 @@ pub mod default {
// region:hash // region:hash
pub mod hash { pub mod hash {
use crate::marker::PointeeSized;
pub trait Hasher {} pub trait Hasher {}
pub trait Hash { pub trait Hash: PointeeSized {
fn hash<H: Hasher>(&self, state: &mut H); fn hash<H: Hasher>(&self, state: &mut H);
} }
@ -221,10 +236,11 @@ pub mod hash {
// region:cell // region:cell
pub mod cell { pub mod cell {
use crate::marker::PointeeSized;
use crate::mem; use crate::mem;
#[lang = "unsafe_cell"] #[lang = "unsafe_cell"]
pub struct UnsafeCell<T: ?Sized> { pub struct UnsafeCell<T: PointeeSized> {
value: T, value: T,
} }
@ -238,7 +254,7 @@ pub mod cell {
} }
} }
pub struct Cell<T: ?Sized> { pub struct Cell<T: PointeeSized> {
value: UnsafeCell<T>, value: UnsafeCell<T>,
} }
@ -357,7 +373,7 @@ pub mod convert {
// endregion:from // endregion:from
// region:as_ref // region:as_ref
pub trait AsRef<T: ?Sized> { pub trait AsRef<T: crate::marker::PointeeSized>: crate::marker::PointeeSized {
fn as_ref(&self) -> &T; fn as_ref(&self) -> &T;
} }
// endregion:as_ref // endregion:as_ref
@ -368,9 +384,11 @@ pub mod convert {
pub mod mem { pub mod mem {
// region:manually_drop // region:manually_drop
use crate::marker::PointeeSized;
#[lang = "manually_drop"] #[lang = "manually_drop"]
#[repr(transparent)] #[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> { pub struct ManuallyDrop<T: PointeeSized> {
value: T, value: T,
} }
@ -381,7 +399,7 @@ pub mod mem {
} }
// region:deref // region:deref
impl<T: ?Sized> crate::ops::Deref for ManuallyDrop<T> { impl<T: PointeeSized> crate::ops::Deref for ManuallyDrop<T> {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
&self.value &self.value
@ -428,7 +446,7 @@ pub mod mem {
pub mod ptr { pub mod ptr {
// region:drop // region:drop
#[lang = "drop_in_place"] #[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { pub unsafe fn drop_in_place<T: crate::marker::PointeeSized>(to_drop: *mut T) {
unsafe { drop_in_place(to_drop) } unsafe { drop_in_place(to_drop) }
} }
pub const unsafe fn read<T>(src: *const T) -> T { pub const unsafe fn read<T>(src: *const T) -> T {
@ -444,7 +462,7 @@ pub mod ptr {
// region:pointee // region:pointee
#[lang = "pointee_trait"] #[lang = "pointee_trait"]
#[rustc_deny_explicit_impl(implement_via_object = false)] #[rustc_deny_explicit_impl(implement_via_object = false)]
pub trait Pointee { pub trait Pointee: crate::marker::PointeeSized {
#[lang = "metadata_type"] #[lang = "metadata_type"]
type Metadata: Copy + Send + Sync + Ord + Hash + Unpin; type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
} }
@ -452,12 +470,14 @@ pub mod ptr {
// region:non_null // region:non_null
#[rustc_layout_scalar_valid_range_start(1)] #[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed] #[rustc_nonnull_optimization_guaranteed]
pub struct NonNull<T: ?Sized> { pub struct NonNull<T: crate::marker::PointeeSized> {
pointer: *const T, pointer: *const T,
} }
// region:coerce_unsized // region:coerce_unsized
impl<T: ?Sized, U: ?Sized> crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T> where impl<T: crate::marker::PointeeSized, U: crate::marker::PointeeSized>
T: crate::marker::Unsize<U> crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T>
where
T: crate::marker::Unsize<U>,
{ {
} }
// endregion:coerce_unsized // endregion:coerce_unsized
@ -478,42 +498,44 @@ pub mod ptr {
pub mod ops { pub mod ops {
// region:coerce_unsized // region:coerce_unsized
mod unsize { mod unsize {
use crate::marker::Unsize; use crate::marker::{PointeeSized, Unsize};
#[lang = "coerce_unsized"] #[lang = "coerce_unsized"]
pub trait CoerceUnsized<T: ?Sized> {} pub trait CoerceUnsized<T> {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {}
} }
pub use self::unsize::CoerceUnsized; pub use self::unsize::CoerceUnsized;
// endregion:coerce_unsized // endregion:coerce_unsized
// region:deref // region:deref
mod deref { mod deref {
use crate::marker::PointeeSized;
#[lang = "deref"] #[lang = "deref"]
pub trait Deref { pub trait Deref: PointeeSized {
#[lang = "deref_target"] #[lang = "deref_target"]
type Target: ?Sized; type Target: ?Sized;
fn deref(&self) -> &Self::Target; fn deref(&self) -> &Self::Target;
} }
impl<T: ?Sized> Deref for &T { impl<T: PointeeSized> Deref for &T {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
loop {} loop {}
} }
} }
impl<T: ?Sized> Deref for &mut T { impl<T: PointeeSized> Deref for &mut T {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
loop {} loop {}
@ -521,19 +543,19 @@ pub mod ops {
} }
// region:deref_mut // region:deref_mut
#[lang = "deref_mut"] #[lang = "deref_mut"]
pub trait DerefMut: Deref { pub trait DerefMut: Deref + PointeeSized {
fn deref_mut(&mut self) -> &mut Self::Target; fn deref_mut(&mut self) -> &mut Self::Target;
} }
// endregion:deref_mut // endregion:deref_mut
// region:receiver // region:receiver
#[lang = "receiver"] #[lang = "receiver"]
pub trait Receiver { pub trait Receiver: PointeeSized {
#[lang = "receiver_target"] #[lang = "receiver_target"]
type Target: ?Sized; type Target: ?Sized;
} }
impl<P: ?Sized, T: ?Sized> Receiver for P impl<P: PointeeSized, T: PointeeSized> Receiver for P
where where
P: Deref<Target = T>, P: Deref<Target = T>,
{ {
@ -1006,18 +1028,18 @@ pub mod ops {
// region:dispatch_from_dyn // region:dispatch_from_dyn
mod dispatch_from_dyn { mod dispatch_from_dyn {
use crate::marker::Unsize; use crate::marker::{PointeeSized, Unsize};
#[lang = "dispatch_from_dyn"] #[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {} pub trait DispatchFromDyn<T> {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {}
} }
pub use self::dispatch_from_dyn::DispatchFromDyn; pub use self::dispatch_from_dyn::DispatchFromDyn;
// endregion:dispatch_from_dyn // endregion:dispatch_from_dyn
@ -1025,15 +1047,17 @@ pub mod ops {
// region:eq // region:eq
pub mod cmp { pub mod cmp {
use crate::marker::PointeeSized;
#[lang = "eq"] #[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> { pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
fn eq(&self, other: &Rhs) -> bool; fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool { fn ne(&self, other: &Rhs) -> bool {
!self.eq(other) !self.eq(other)
} }
} }
pub trait Eq: PartialEq<Self> {} pub trait Eq: PartialEq<Self> + PointeeSized {}
// region:derive // region:derive
#[rustc_builtin_macro] #[rustc_builtin_macro]
@ -1044,11 +1068,11 @@ pub mod cmp {
// region:ord // region:ord
#[lang = "partial_ord"] #[lang = "partial_ord"]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>; fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
} }
pub trait Ord: Eq + PartialOrd<Self> { pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
fn cmp(&self, other: &Self) -> Ordering; fn cmp(&self, other: &Self) -> Ordering;
} }
@ -1071,6 +1095,8 @@ pub mod cmp {
// region:fmt // region:fmt
pub mod fmt { pub mod fmt {
use crate::marker::PointeeSized;
pub struct Error; pub struct Error;
pub type Result = crate::result::Result<(), Error>; pub type Result = crate::result::Result<(), Error>;
pub struct Formatter<'a>; pub struct Formatter<'a>;
@ -1106,10 +1132,10 @@ pub mod fmt {
} }
} }
pub trait Debug { pub trait Debug: PointeeSized {
fn fmt(&self, f: &mut Formatter<'_>) -> Result; fn fmt(&self, f: &mut Formatter<'_>) -> Result;
} }
pub trait Display { pub trait Display: PointeeSized {
fn fmt(&self, f: &mut Formatter<'_>) -> Result; fn fmt(&self, f: &mut Formatter<'_>) -> Result;
} }
@ -1268,7 +1294,7 @@ pub mod fmt {
} }
} }
impl<T: Debug + ?Sized> Debug for &T { impl<T: Debug + PointeeSized> Debug for &T {
fn fmt(&self, f: &mut Formatter<'_>) -> Result { fn fmt(&self, f: &mut Formatter<'_>) -> Result {
(&**self).fmt(f) (&**self).fmt(f)
} }
@ -1512,6 +1538,8 @@ pub mod iter {
mod traits { mod traits {
mod iterator { mod iterator {
use crate::marker::PointeeSized;
#[doc(notable_trait)] #[doc(notable_trait)]
#[lang = "iterator"] #[lang = "iterator"]
pub trait Iterator { pub trait Iterator {
@ -1543,7 +1571,7 @@ pub mod iter {
} }
// endregion:iterators // endregion:iterators
} }
impl<I: Iterator + ?Sized> Iterator for &mut I { impl<I: Iterator + PointeeSized> Iterator for &mut I {
type Item = I::Item; type Item = I::Item;
fn next(&mut self) -> Option<I::Item> { fn next(&mut self) -> Option<I::Item> {
(**self).next() (**self).next()