简体   繁体   中英

Why does a trait requiring AddAssign as a supertrait also require it to be Sized?

I have a trait, and to implement that trait, I would like to require the implementor to implement AddAssign ; however, doing that results in my trait seemingly needing to require Sized :

trait Foo: ::std::ops::AddAssign {}

trait Bar: Iterator {}

(playground)

Bar compiles fine; Foo , however:

error[E0277]: the trait bound `Self: std::marker::Sized` is not satisfied
 --> src/main.rs:1:1
  |
1 | trait Foo: ::std::ops::AddAssign {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Self` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `Self`
  = help: consider adding a `where Self: std::marker::Sized` bound
  = note: required by `std::ops::AddAssign`

If I add + Sized to the trait bounds, all is fine, but… why do I need to do this? Why doesn't AddAssign need this?

Let's look at the definition of the trait:

pub trait AddAssign<Rhs = Self> {
    fn add_assign(&mut self, rhs: Rhs);
}

That is, trait Foo: ::std::ops::AddAssign is equivalent to trait Foo: ::std::ops::AddAssign<Foo> and add_assign takes a Rhs as its second parameter, hence Rhs needs to be sized.

Note that trait Foo: ::std::ops::AddAssign<u32> does not require Foo to be sized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM