@@ -1004,7 +1004,7 @@ impl<'a> MethodDef<'a> {
1004
1004
/// ```
1005
1005
/// #[derive(PartialEq)]
1006
1006
/// # struct Dummy;
1007
- /// struct A { x: i32 , y: i32 }
1007
+ /// struct A { x: u8 , y: u8 }
1008
1008
///
1009
1009
/// // equivalent to:
1010
1010
/// impl PartialEq for A {
@@ -1016,9 +1016,9 @@ impl<'a> MethodDef<'a> {
1016
1016
/// But if the struct is `repr(packed)`, we can't use something like
1017
1017
/// `&self.x` on a packed type (as required for e.g. `Debug` and `Hash`)
1018
1018
/// because that might cause an unaligned ref. So we use let-destructuring
1019
- /// instead.
1019
+ /// instead. If the struct impls `Copy`:
1020
1020
/// ```
1021
- /// # struct A { x: i32 , y: i32 }
1021
+ /// # struct A { x: u8 , y: u8 }
1022
1022
/// impl PartialEq for A {
1023
1023
/// fn eq(&self, other: &A) -> bool {
1024
1024
/// let Self { x: __self_0_0, y: __self_0_1 } = *self;
@@ -1027,6 +1027,19 @@ impl<'a> MethodDef<'a> {
1027
1027
/// }
1028
1028
/// }
1029
1029
/// ```
1030
+ /// If it doesn't impl `Copy`:
1031
+ /// ```
1032
+ /// # struct A { x: u8, y: u8 }
1033
+ /// impl PartialEq for A {
1034
+ /// fn eq(&self, other: &A) -> bool {
1035
+ /// let Self { x: ref __self_0_0, y: ref __self_0_1 } = *self;
1036
+ /// let Self { x: ref __self_1_0, y: ref __self_1_1 } = *other;
1037
+ /// *__self_0_0 == *__self_1_0 && *__self_0_1 == *__self_1_1
1038
+ /// }
1039
+ /// }
1040
+ /// ```
1041
+ /// This latter case only works if the fields match the alignment required
1042
+ /// by the `packed(N)` attribute.
1030
1043
fn expand_struct_method_body < ' b > (
1031
1044
& self ,
1032
1045
cx : & mut ExtCtxt < ' _ > ,
@@ -1058,9 +1071,9 @@ impl<'a> MethodDef<'a> {
1058
1071
} else {
1059
1072
let prefixes: Vec < _ > =
1060
1073
( 0 ..selflike_args. len ( ) ) . map ( |i| format ! ( "__self_{}" , i) ) . collect ( ) ;
1061
- let no_deref = always_copy;
1074
+ let addr_of = always_copy;
1062
1075
let selflike_fields =
1063
- trait_. create_struct_pattern_fields ( cx, struct_def, & prefixes, no_deref ) ;
1076
+ trait_. create_struct_pattern_fields ( cx, struct_def, & prefixes, addr_of ) ;
1064
1077
let mut body = mk_body ( cx, selflike_fields) ;
1065
1078
1066
1079
let struct_path = cx. path ( span, vec ! [ Ident :: new( kw:: SelfUpper , type_ident. span) ] ) ;
@@ -1194,9 +1207,9 @@ impl<'a> MethodDef<'a> {
1194
1207
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
1195
1208
// (see "Final wrinkle" note below for why.)
1196
1209
1197
- let no_deref = false ; // because enums can't be repr(packed)
1210
+ let addr_of = false ; // because enums can't be repr(packed)
1198
1211
let fields =
1199
- trait_. create_struct_pattern_fields ( cx, & variant. data , & prefixes, no_deref ) ;
1212
+ trait_. create_struct_pattern_fields ( cx, & variant. data , & prefixes, addr_of ) ;
1200
1213
1201
1214
let sp = variant. span . with_ctxt ( trait_. span . ctxt ( ) ) ;
1202
1215
let variant_path = cx. path ( sp, vec ! [ type_ident, variant. ident] ) ;
@@ -1512,15 +1525,15 @@ impl<'a> TraitDef<'a> {
1512
1525
cx : & mut ExtCtxt < ' _ > ,
1513
1526
struct_def : & ' a VariantData ,
1514
1527
prefixes : & [ String ] ,
1515
- no_deref : bool ,
1528
+ addr_of : bool ,
1516
1529
) -> Vec < FieldInfo > {
1517
1530
self . create_fields ( struct_def, |i, _struct_field, sp| {
1518
1531
prefixes
1519
1532
. iter ( )
1520
1533
. map ( |prefix| {
1521
1534
let ident = self . mk_pattern_ident ( prefix, i) ;
1522
1535
let expr = cx. expr_path ( cx. path_ident ( sp, ident) ) ;
1523
- if no_deref { expr } else { cx . expr_deref ( sp , expr) }
1536
+ if addr_of { cx . expr_addr_of ( sp , expr) } else { expr }
1524
1537
} )
1525
1538
. collect ( )
1526
1539
} )
@@ -1536,17 +1549,20 @@ impl<'a> TraitDef<'a> {
1536
1549
selflike_args
1537
1550
. iter ( )
1538
1551
. map ( |selflike_arg| {
1539
- // Note: we must use `struct_field.span` rather than `span ` in the
1552
+ // Note: we must use `struct_field.span` rather than `sp ` in the
1540
1553
// `unwrap_or_else` case otherwise the hygiene is wrong and we get
1541
1554
// "field `0` of struct `Point` is private" errors on tuple
1542
1555
// structs.
1543
- cx. expr (
1556
+ cx. expr_addr_of (
1544
1557
sp,
1545
- ast:: ExprKind :: Field (
1546
- selflike_arg. clone ( ) ,
1547
- struct_field. ident . unwrap_or_else ( || {
1548
- Ident :: from_str_and_span ( & i. to_string ( ) , struct_field. span )
1549
- } ) ,
1558
+ cx. expr (
1559
+ sp,
1560
+ ast:: ExprKind :: Field (
1561
+ selflike_arg. clone ( ) ,
1562
+ struct_field. ident . unwrap_or_else ( || {
1563
+ Ident :: from_str_and_span ( & i. to_string ( ) , struct_field. span )
1564
+ } ) ,
1565
+ ) ,
1550
1566
) ,
1551
1567
)
1552
1568
} )
0 commit comments