Deduce fields of a struct are Sized when Self is sized

I have encountered this problem when trying to implement a Wrapper type that forwards all method calls to its inner field:

#[derive(PartialEq,Eq,PartialOrd)]
struct Wrap<T:?Sized>(
   T
    );

impl<T:?Sized+Ord+Eq> Ord for Wrap<T> {
    fn cmp(&self, _:&Self) -> Ordering {
        unimplemented!()
    }
    fn max(self, o: Self) -> Self where Self:Sized {
         Self(self.0.max(o.0))  //Error T is not sized.
    }
}

This output error message: "the size for values of type T cannot be known at compile time". But within max, Self is sized so T is sized.

Thinking about it I suppose rust could, in theory, produce deduction rules in the form "Self:Sized <=> T1: Sized && T2:Sized ... " where the Ti covers some but not all of the generic type parameter of the struct denoted by Self (no generic parameters that only appear within field reference types, PhantomData, etc...)

1 Like

There is no max method for PartialOrd. You have to use Ord for that. I would guess this is just a bad error message for the fact that max doesn't exist.

https://doc.rust-lang.org/core/cmp/trait.Ord.html#method.max

The T: Sized requirement issues is not fixed by changing the bound from PartialOrd to Ord.

A perhaps relevant question is whether we want to make sure that changing

struct Wrap<T: ?Sized>(T);

into

struct Wrap<T: ?Sized>(Box<T>);

is always possible without this change being a breaking change.

If this is the case, reasoning that deduces T: Sized from Wrap<T>: Sized would have to be prohibited (at least outside of the crate defining Wrap; and technically also only if the fields of Wrap aren’t public, and if the crate wouldn’t opt out of such a possible future change using some to-be-specified syntax).

1 Like

No this is just a typo within the code, the error is the same with T:?Sized+Eq+Ord