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 } 190