#[derive(ShrAssign)]
{
// Attributes available to this derive:
#[shr_assign]
}
mul_assign only.Expand description
§What #[derive(MulAssign)] generates
NOTE:
DivAssign,RemAssign,ShrAssignandShlAssignderives are fully equivalent to theMulAssignderive described below.
Deriving MulAssign is very similar to deriving Mul. The difference is that it
mutates the existing instance instead of creating a new one.
§Scalar implementation
§Structs
Deriving MulAssign for a struct with multiple fields multiplies its fields with
anything multiplicable, mutating them in-place.
#[derive(MulAssign)]
struct MyInts(i32, i32);
#[derive(MulAssign)]
struct Point2D {
x: i32,
y: i32,
}This generates code equivalent to:
impl<Rhs: Copy> MulAssign<Rhs> for MyInts
where
i32: MulAssign<Rhs>
{
fn mul_assign(&mut self, rhs: Rhs) {
match self {
Self(self_0, self_1) => {
MulAssign::mul_assign(self_0, rhs);
MulAssign::mul_assign(self_1, rhs);
}
}
}
}
impl<Rhs: Copy> MulAssign<Rhs> for Point2D
where
i32: MulAssign<Rhs>
{
fn mul_assign(&mut self, rhs: Rhs) {
match self {
Self { x: self_0, y: self_1 } => {
MulAssign::mul_assign(self_0, rhs);
MulAssign::mul_assign(self_1, rhs);
},
}
}
}Note, that Copyis not required for Rhs when the struct has only a single field.
§Ignoring
Sometimes a struct needs to hold a field (most commonly PhantomData) that doesn’t
participate in a scalar MulAssign implementation. Such field could be ignored using
the #[mul_assign(skip)] attribute.
#[derive(MulAssign)]
struct TupleWithZst<T>(i32, #[mul_assign(skip)] PhantomData<T>);
#[derive(MulAssign)]
struct StructWithZst<T> {
x: i32,
#[mul_assign(skip)] // or #[mul_assign(ignore)]
_marker: PhantomData<T>,
}§Enums
Deriving scalar MulAssign implementation for enums is not (yet) supported (in the same manner as deriving Mul).
Although it shouldn’t be impossible no effort has been put into this yet.
§Structural implementation
Specifying the #[mul_assign(forward)] attribute generates a structural MulAssign
implementation with the same semantics as AddAssign: MulAssigning the respective
fields, mutating them in-place.
§Structs
#[derive(MulAssign)]
#[mul_assign(forward)]
struct MyInts(i32, i32);
#[derive(MulAssign)]
#[mul_assign(forward)]
struct Point2D {
x: i32,
y: i32,
}This generates code equivalent to:
impl MulAssign for MyInts {
fn mul_assign(&mut self, rhs: Self) {
match (self, rhs) {
(Self(self_0, self_1), Self(rhs_0, rhs_1)) => {
MulAssign::mul_assign(self_0, rhs_0);
MulAssign::mul_assign(self_1, rhs_1);
}
}
}
}
impl MulAssign for Point2D {
fn mul_assign(&mut self, rhs: Self) {
match (self, rhs) {
(Self { x: self_0, y: self_1 }, Self { x: rhs_0, y: rhs_1 }) => {
MulAssign::mul_assign(self_0, rhs_0);
MulAssign::mul_assign(self_1, rhs_1);
}
}
}
}The behaviour is similar with more or less fields.
§Ignoring
Sometimes a struct needs to hold a field (most commonly PhantomData) that doesn’t
participate in a structural MulAssign implementation. Such field could be ignored using
the #[mul_assign(skip)] attribute.
#[derive(MulAssign)]
#[mul_assign(forward)]
struct TupleWithZst<T>(i32, #[mul_assign(skip)] PhantomData<T>);
#[derive(MulAssign)]
#[mul_assign(forward)]
struct StructWithZst<T> {
x: i32,
#[mul_assign(skip)] // or #[mul_assign(ignore)]
_marker: PhantomData<T>,
}§Enums
Deriving AddAssign structurally is not (yet) supported for enums.
This is mostly due to the fact that it is not trivial convert the Mul
derivation code, because that returns a Result<EnumType> instead of an EnumType.
Handling the case where it errors would be hard and maybe impossible.