]> git.lizzy.rs Git - rust.git/blob - library/core/src/internal_macros.rs
9c6acfb1e8c94f823ef1cb864dc62541074f9da1
[rust.git] / library / core / src / internal_macros.rs
1 // implements the unary operator "op &T"
2 // based on "op T" where T is expected to be `Copy`able
3 macro_rules! forward_ref_unop {
4     (impl $imp:ident, $method:ident for $t:ty) => {
5         forward_ref_unop!(impl $imp, $method for $t,
6                 #[stable(feature = "rust1", since = "1.0.0")]);
7     };
8     (impl const $imp:ident, $method:ident for $t:ty) => {
9         forward_ref_unop!(impl const $imp, $method for $t,
10                 #[stable(feature = "rust1", since = "1.0.0")]);
11     };
12     // Equivalent to the non-const version, with the addition of `rustc_const_unstable`
13     (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
14         #[$attr]
15         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
16         impl const $imp for &$t {
17             type Output = <$t as $imp>::Output;
18
19             #[inline]
20             fn $method(self) -> <$t as $imp>::Output {
21                 $imp::$method(*self)
22             }
23         }
24     };
25     (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
26         #[$attr]
27         impl $imp for &$t {
28             type Output = <$t as $imp>::Output;
29
30             #[inline]
31             fn $method(self) -> <$t as $imp>::Output {
32                 $imp::$method(*self)
33             }
34         }
35     }
36 }
37
38 // implements binary operators "&T op U", "T op &U", "&T op &U"
39 // based on "T op U" where T and U are expected to be `Copy`able
40 macro_rules! forward_ref_binop {
41     (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
42         forward_ref_binop!(impl $imp, $method for $t, $u,
43                 #[stable(feature = "rust1", since = "1.0.0")]);
44     };
45     (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => {
46         forward_ref_binop!(impl const $imp, $method for $t, $u,
47                 #[stable(feature = "rust1", since = "1.0.0")]);
48     };
49     // Equivalent to the non-const version, with the addition of `rustc_const_unstable`
50     (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
51         #[$attr]
52         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
53         impl<'a> const $imp<$u> for &'a $t {
54             type Output = <$t as $imp<$u>>::Output;
55
56             #[inline]
57             fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
58                 $imp::$method(*self, other)
59             }
60         }
61
62         #[$attr]
63         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
64         impl const $imp<&$u> for $t {
65             type Output = <$t as $imp<$u>>::Output;
66
67             #[inline]
68             fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
69                 $imp::$method(self, *other)
70             }
71         }
72
73         #[$attr]
74         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
75         impl const $imp<&$u> for &$t {
76             type Output = <$t as $imp<$u>>::Output;
77
78             #[inline]
79             fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
80                 $imp::$method(*self, *other)
81             }
82         }
83     };
84     (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
85         #[$attr]
86         impl<'a> $imp<$u> for &'a $t {
87             type Output = <$t as $imp<$u>>::Output;
88
89             #[inline]
90             fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
91                 $imp::$method(*self, other)
92             }
93         }
94
95         #[$attr]
96         impl $imp<&$u> for $t {
97             type Output = <$t as $imp<$u>>::Output;
98
99             #[inline]
100             fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
101                 $imp::$method(self, *other)
102             }
103         }
104
105         #[$attr]
106         impl $imp<&$u> for &$t {
107             type Output = <$t as $imp<$u>>::Output;
108
109             #[inline]
110             fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
111                 $imp::$method(*self, *other)
112             }
113         }
114     }
115 }
116
117 // implements "T op= &U", based on "T op= U"
118 // where U is expected to be `Copy`able
119 macro_rules! forward_ref_op_assign {
120     (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
121         forward_ref_op_assign!(impl $imp, $method for $t, $u,
122                 #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
123     };
124     (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => {
125         forward_ref_op_assign!(impl const $imp, $method for $t, $u,
126                 #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
127     };
128     // Equivalent to the non-const version, with the addition of `rustc_const_unstable`
129     (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
130         #[$attr]
131         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
132         impl const $imp<&$u> for $t {
133             #[inline]
134             fn $method(&mut self, other: &$u) {
135                 $imp::$method(self, *other);
136             }
137         }
138     };
139     (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
140         #[$attr]
141         impl $imp<&$u> for $t {
142             #[inline]
143             fn $method(&mut self, other: &$u) {
144                 $imp::$method(self, *other);
145             }
146         }
147     }
148 }
149
150 /// Create a zero-size type similar to a closure type, but named.
151 macro_rules! impl_fn_for_zst {
152     ($(
153         $( #[$attr: meta] )*
154         struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
155             |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
156             $body: block;
157     )+) => {
158         $(
159             $( #[$attr] )*
160             struct $Name;
161
162             impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
163                 #[inline]
164                 extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
165                     $body
166                 }
167             }
168
169             impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
170                 #[inline]
171                 extern "rust-call" fn call_mut(
172                     &mut self,
173                     ($( $arg, )*): ($( $ArgTy, )*)
174                 ) -> $ReturnTy {
175                     Fn::call(&*self, ($( $arg, )*))
176                 }
177             }
178
179             impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
180                 type Output = $ReturnTy;
181
182                 #[inline]
183                 extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
184                     Fn::call(&self, ($( $arg, )*))
185                 }
186             }
187         )+
188     }
189 }