@@ -2007,10 +2007,14 @@ macro_rules! transmute {
2007
2007
// This branch, though never taken, ensures that the type of `e` is
2008
2008
// `AsBytes` and that the type of this macro invocation expression
2009
2009
// is `FromBytes`.
2010
- const fn transmute<T : $crate:: AsBytes , U : $crate:: FromBytes >( _t: T ) -> U {
2011
- loop { }
2012
- }
2013
- transmute( e)
2010
+
2011
+ struct AssertIsAsBytes <T : $crate:: AsBytes >( T ) ;
2012
+ let _ = AssertIsAsBytes ( e) ;
2013
+
2014
+ struct AssertIsFromBytes <U : $crate:: FromBytes >( U ) ;
2015
+ #[ allow( unused, unreachable_code) ]
2016
+ let u = AssertIsFromBytes ( loop { } ) ;
2017
+ u. 0
2014
2018
} else {
2015
2019
// SAFETY: `core::mem::transmute` ensures that the type of `e` and
2016
2020
// the type of this macro invocation expression have the same size.
@@ -2092,7 +2096,18 @@ macro_rules! transmute_ref {
2092
2096
// `&T` where `T: 't + Sized + AsBytes`, that the type of this macro
2093
2097
// expression is `&U` where `U: 'u + Sized + FromBytes`, and that
2094
2098
// `'t` outlives `'u`.
2095
- const fn transmute<' u, ' t: ' u, T : ' t + Sized + $crate:: AsBytes , U : ' u + Sized + $crate:: FromBytes >( _t: & ' t T ) -> & ' u U {
2099
+
2100
+ struct AssertIsAsBytes <' a, T : :: core:: marker:: Sized + $crate:: AsBytes >( & ' a T ) ;
2101
+ let _ = AssertIsAsBytes ( e) ;
2102
+
2103
+ struct AssertIsFromBytes <' a, U : :: core:: marker:: Sized + $crate:: FromBytes >( & ' a U ) ;
2104
+ #[ allow( unused, unreachable_code) ]
2105
+ let u = AssertIsFromBytes ( loop { } ) ;
2106
+ u. 0
2107
+ } else if false {
2108
+ // This branch, though never taken, ensures that the source lifetime
2109
+ // is not shorter than the destination lifetime.
2110
+ const fn transmute<' u, ' t: ' u, T : ' t, U : ' u>( t: & ' t T ) -> & ' u U {
2096
2111
loop { }
2097
2112
}
2098
2113
transmute( e)
@@ -2191,19 +2206,44 @@ macro_rules! transmute_mut {
2191
2206
// because there's no way, in a generic context, to enforce that two
2192
2207
// types have the same size or alignment.
2193
2208
2194
- let e = $e;
2209
+ // Ensure that the source type is a mutable reference.
2210
+ let e = & mut * $e;
2195
2211
2196
2212
#[ allow( unused, clippy:: diverging_sub_expression) ]
2197
2213
if false {
2198
2214
// This branch, though never taken, ensures that the type of `e` is
2199
- // `&mut T` where `T: 't + Sized + AsBytes + FromBytes `, that the
2215
+ // `&mut T` where `T: 't + Sized + FromBytes + AsBytes `, that the
2200
2216
// type of this macro expression is `&mut U` where `U: 'u + Sized +
2201
- // AsBytes + FromBytes`.
2202
- fn transmute<' t, T , U >( _t: & ' t mut T ) -> & ' t mut U
2203
- where
2204
- T : ' t + Sized + $crate:: AsBytes + $crate:: FromBytes ,
2205
- U : ' t + Sized + $crate:: AsBytes + $crate:: FromBytes ,
2206
- {
2217
+ // FromBytes + AsBytes`.
2218
+
2219
+ // We use immutable references here rather than mutable so that, if
2220
+ // this macro is used in a const context (in which, as of this
2221
+ // writing, mutable references are banned), the error message
2222
+ // appears to originate in the user's code rather than in the
2223
+ // internals of this macro.
2224
+ struct AssertIsFromBytes <' a, T : :: core:: marker:: Sized + $crate:: FromBytes >( & ' a T ) ;
2225
+ struct AssertIsAsBytes <' a, T : :: core:: marker:: Sized + $crate:: AsBytes >( & ' a T ) ;
2226
+
2227
+ if true {
2228
+ let _ = AssertIsFromBytes ( & * e) ;
2229
+ } else {
2230
+ let _ = AssertIsAsBytes ( & * e) ;
2231
+ }
2232
+
2233
+ if true {
2234
+ #[ allow( unused, unreachable_code) ]
2235
+ let u = AssertIsFromBytes ( loop { } ) ;
2236
+ & mut * u. 0
2237
+ } else {
2238
+ #[ allow( unused, unreachable_code) ]
2239
+ let u = AssertIsAsBytes ( loop { } ) ;
2240
+ & mut * u. 0
2241
+ }
2242
+ } else if false {
2243
+ // This branch, though never taken, ensures that the source lifetime
2244
+ // is not shorter than the destination lifetime, and that the source
2245
+ // type is a mutable (rather than immutable) reference.
2246
+ fn transmute<' u, ' t: ' u, T : ' t, U : ' u>( t: & ' t mut T ) -> & ' u mut U {
2207
2247
loop { }
2208
2248
}
2209
2249
transmute( e)
@@ -3654,7 +3694,7 @@ pub use alloc_support::*;
3654
3694
mod tests {
3655
3695
#![ allow( clippy:: unreadable_literal) ]
3656
3696
3657
- use core:: ops:: Deref ;
3697
+ use core:: { convert :: TryInto as _ , ops:: Deref } ;
3658
3698
3659
3699
use static_assertions:: assert_impl_all;
3660
3700
0 commit comments