Unfamiliar generics syntax

Im trying to go over some code in a project I started a year ago in rust (which I am still learning). I came across this code and can not figure out what this function is passing.

fn randomize_point<R: Rng + ?Sized>(rng: &mut R, p: &mut Point) {

Specifically the <R: Rng + ?Sized> what is going on with the ?Sized and the plus? This is Generic syntax I am unfamiliar with.

X: A + B means that X must implement both A and B.

Sized is a marker trait that is automatically implemented for all types that have a size that's known at compile time. For example, i32 is statically known to be 4 bytes, so it is Sized, but the size of [T] or dyn Foo cannot be known until runtime, so they are not Sized.

Interestingly, all generic parameters have an implicit bound on Sized - if you write R: Rng, it's the same as if you'd written R: Rng + Sized.

This is because, most of the time, it's what you want - without a Sized bound, you can't pass a generic parameter by value (as that wouldn't work for unsized types, which can only be stored in a variable/parameter behind some kind of indirection, like a reference or a Box). In order to save you from having to type + Sized everywhere, Rust just does it for you behind the scenes.

But what if you want R to allow unsized types too? That's totally valid in your case, as R is only accessed via a reference.

That's what the ? syntax is for - ?Sized removes this implicit bound, allowing you to accept sized and unsized types.

9 Likes