Question about Display impl

Why does T have to be unsized?

impl<T> Display for &T
where
    T: Display + ?Sized,

T doesn't have to be unsized but does not have to be sized.

From the docs of the Sized trait:

All type parameters have an implicit bound of Sized. The special syntax ?Sized can be used to remove this bound if it’s not appropriate.

1 Like

Ahhh. So I am missunderstanding this negative trait bound. It's only meant to "delete" the implicit Sized an doesn't mean unsized?

Yes, it just removes the implicit Sized marker

So would the negative_impls feature change this behaviour?

The tracking issue for this feature is #68318.


With the feature gate negative_impls, you can write negative impls as well as positive ones:

#![feature(negative_impls)]
trait DerefMut { }
impl<T: ?Sized> !DerefMut for &T { }

Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.

EDIT:
Sorry, I just saw the the negative impl uses a ! not a ?.

No. This is not an impl, this is a bound. The absence of a bound doesn't mean that the bounded type must not implement the trait. It means that it doesn't have to implement it. Also, it is a requirement on the part of the user, not a statement/specification/assertion by the implementor.

A negative trait impl on the other hand means that the type explicitly does not implement the given trait. This is a statement on the type, by the implementor. It does not describe a requirement by any users of the type.

1 Like

Regarding the original question, see also my comment here on impl<T: ?Sized>.

When I write fn consume<T>(t: T) , that is actually shorthand for saying “any type T that is Sized ”.
If you don’t want this default Sized bound, you write T: ?Sized . The leading ? means “maybe Sized” — i.e., now T can any type, whether it be sized (e.g., u32 ) or unsized (e.g., [u32] ).

This is important: a where-clause like T: Foo narrows the set of types that T can be, since now it must be a type that implements Foo . The “maybe” where-clause T: ?Sized (we don’t accept other traits here) broadens the set of types that T can be, by removing default bounds.
src: Must move types · baby steps

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.