Can ?Sized bound represent all type in rust?

i see many ?Size in std lib, i know that this bound mean "may or not know size in compiler". any type either knows the size or not, is there any other situation? i have try struct , bool, i32, and even, all work fine.

In Rust, traits are not types, and since Sized is a trait, ?Sized is not a type. Instead, what you are looking at whenever you see ?Sized is known as a bound.

If you want a type that represents all types, that's the Any type.

fn generic<T: ?Sized>(t: &T) {
    
}

struct A {}

enum E {
    X
}

fn main() {
    let a = A{};
    generic(&a);

    let b  = true;
    generic(&b);    

    let n: i32  = 1;
    generic(&n); 

    let m = E::X;
    generic(&m);

    let static_ref: &'static mut usize = Box::leak(Box::new(1));
    generic(static_ref);

    let p = vec![1,2,3].as_ptr();
    generic(&p);
}

just want to know witch type can't be received by generic?, i want to know the range of ?Size.

Sized is a trait that is automatically implemented by the compiler, so it covers pretty much every type except DSTs (Dynamically-sized types, also known as unsized). When you put the question mark as a prefix for the trait bound, it means that T may or may not implement Sized.

DSTs require some type of indirection, and in your case you are using a shared reference to T (&T).

So, for all terms and purposes, your generic function virtually accepts any type that can be coerced to a shared reference.

?Sized means "the size is known at runtime". I think at the moment this includes all existing types in Rust, yes.

It may change in the future. For example, there could be types which don't know the precise size even at runtime. I think extern type is such a construct, but it's currently unstable. It is used to represent entirely opaque types, generally coming from code written in other languages, e.g. C++. However, I don't think you would lose any actual generality from such types, since they should be handled via pointers anyway, and not directly by value.

There could also be types which know their size (at runtime or compile time), but don't have compile-time information on their alignment. The ?Sized bound on its own would not be sufficient to handle ?Aligned types. I think there is an unstable feature for that, but it's far off from stabilization.

I don't know any other possibilities which are developed enough to be at least an unstable compiler feature.

3 Likes

cool, help much ,thanks

Some clarifications on this thread:

  • ?Sized is not a trait. Sized is a trait. Sized means the size is known at compile time.
  • Introducing a generic <T> generally also introduces an implied T: Sized bound. T: ?Sized removes the implied bound.
  • Thus removing the bound means the size may or may not be known at compile time. ?Sized does not mean known at runtime.
    • DynSized is a proposal to mean known at runtime
    • MetaSized is a proposal to mean known at runtime
    • Neither have been accepted
  • Any doesn't represent all types; it's only implemented for types that meet a 'static bound
    • Sized or not (but only Sized types coerce to dyn Any)

Unless/until

  • Rust gets more implied-everywhere bounds and another ?Trait to disable them (unlikely)
  • ?Sized becomes more special and does more than remove the Sized bound
  • Sized becomes more special by being an auto-trait with a supertrait like DynSized or MetaSized
  • Some new proposal related to these lines

T: ?Sized covers all types.

5 Likes

Introducing a generic `<T>` generally also introduces an implied `T: Sized` bound. `T: ?Sized` removes the implied bound. this really help me, i dont know this before.

1 Like

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.