summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more-impl/doc/mul.md
blob: a1068bef0de4d79f48b4f1e29c17bc21a44ed63d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# What `#[derive(Mul)]` generates

Deriving `Mul` is quite different from deriving `Add`. It is not used to
multiply two structs together. Instead it will normally multiply a struct, which
can have multiple fields, with a single primitive type (e.g. a `u64`). A new
struct is then created with all the fields from the previous struct multiplied
by this other value.

A simple way of explaining the reasoning behind this difference between `Add`
and `Mul` deriving, is looking at arithmetic on meters.
One meter can be added to one meter, to get two meters. Also, one meter times
two would be two meters, but one meter times one meter would be one square meter.
As this second case clearly requires more knowledge about the meaning of the
type in question deriving for this is not implemented.

NOTE: In case you don't want this behaviour you can add `#[mul(forward)]` in
addition to `#[derive(Mul)]`. This will instead generate a `Mul` implementation
with the same semantics as `Add`.




## Tuple structs

When deriving for a tuple struct with a single field (i.e. a newtype) like this:

```rust
# use derive_more::Mul;
#
#[derive(Mul)]
struct MyInt(i32);
```

Code like this will be generated:

```rust
# struct MyInt(i32);
impl<__RhsT> ::core::ops::Mul<__RhsT> for MyInt
    where i32: ::core::ops::Mul<__RhsT, Output = i32>
{
    type Output = MyInt;
    fn mul(self, rhs: __RhsT) -> MyInt {
        MyInt(self.0.mul(rhs))
    }
}
```

The behaviour is slightly different for multiple fields, since the right hand
side of the multiplication now needs the `Copy` trait.
For instance when deriving for a tuple struct with two fields like this:

```rust
# use derive_more::Mul;
#
#[derive(Mul)]
struct MyInts(i32, i32);
```

Code like this will be generated:

```rust
# struct MyInts(i32, i32);
impl<__RhsT: ::core::marker::Copy> ::core::ops::Mul<__RhsT> for MyInts
    where i32: ::core::ops::Mul<__RhsT, Output = i32>
{
    type Output = MyInts;
    fn mul(self, rhs: __RhsT) -> MyInts {
        MyInts(self.0.mul(rhs), self.1.mul(rhs))
    }
}
```

The behaviour is similar with more or less fields.




## Regular structs

When deriving `Mul` for a regular struct with a single field like this:

```rust
# use derive_more::Mul;
#
#[derive(Mul)]
struct Point1D {
    x: i32,
}
```

Code like this will be generated:

```rust
# struct Point1D {
#     x: i32,
# }
impl<__RhsT> ::core::ops::Mul<__RhsT> for Point1D
    where i32: ::core::ops::Mul<__RhsT, Output = i32>
{
    type Output = Point1D;
    fn mul(self, rhs: __RhsT) -> Point1D {
        Point1D { x: self.x.mul(rhs) }
    }
}
```

The behaviour is again slightly different when deriving for a struct with multiple
fields, because it still needs the `Copy` as well.
For instance when deriving for a tuple struct with two fields like this:

```rust
# use derive_more::Mul;
#
#[derive(Mul)]
struct Point2D {
    x: i32,
    y: i32,
}
```

Code like this will be generated:

```rust
# struct Point2D {
#     x: i32,
#     y: i32,
# }
impl<__RhsT: ::core::marker::Copy> ::core::ops::Mul<__RhsT> for Point2D
    where i32: ::core::ops::Mul<__RhsT, Output = i32>
{
    type Output = Point2D;
    fn mul(self, rhs: __RhsT) -> Point2D {
        Point2D {
            x: self.x.mul(rhs),
            y: self.y.mul(rhs),
        }
    }
}
```




## Enums

Deriving `Mul` for enums is not (yet) supported, except when you use
`#[mul(forward)]`.
Although it shouldn't be impossible no effort has been put into this yet.