@@ -183,7 +183,6 @@ use rustc_ast::ptr::P;
183183use rustc_ast:: { self as ast, BinOpKind , EnumDef , Expr , Generics , PatKind } ;
184184use rustc_ast:: { GenericArg , GenericParamKind , VariantData } ;
185185use rustc_attr as attr;
186- use rustc_data_structures:: map_in_place:: MapInPlace ;
187186use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
188187use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
189188use rustc_span:: Span ;
@@ -455,7 +454,6 @@ impl<'a> TraitDef<'a> {
455454 } ;
456455 let container_id = cx. current_expansion . id . expn_data ( ) . parent . expect_local ( ) ;
457456 let always_copy = has_no_type_params && cx. resolver . has_derive_copy ( container_id) ;
458- let use_temporaries = is_packed && always_copy;
459457
460458 let newitem = match item. kind {
461459 ast:: ItemKind :: Struct ( ref struct_def, ref generics) => self . expand_struct_def (
@@ -464,11 +462,11 @@ impl<'a> TraitDef<'a> {
464462 item. ident ,
465463 generics,
466464 from_scratch,
467- use_temporaries,
468465 is_packed,
466+ always_copy,
469467 ) ,
470468 ast:: ItemKind :: Enum ( ref enum_def, ref generics) => {
471- // We ignore `use_temporaries ` here, because
469+ // We ignore `is_packed`/`always_copy ` here, because
472470 // `repr(packed)` enums cause an error later on.
473471 //
474472 // This can only cause further compilation errors
@@ -484,8 +482,8 @@ impl<'a> TraitDef<'a> {
484482 item. ident ,
485483 generics,
486484 from_scratch,
487- use_temporaries,
488485 is_packed,
486+ always_copy,
489487 )
490488 } else {
491489 cx. span_err ( mitem. span , "this trait cannot be derived for unions" ) ;
@@ -766,8 +764,8 @@ impl<'a> TraitDef<'a> {
766764 type_ident : Ident ,
767765 generics : & Generics ,
768766 from_scratch : bool ,
769- use_temporaries : bool ,
770767 is_packed : bool ,
768+ always_copy : bool ,
771769 ) -> P < ast:: Item > {
772770 let field_tys: Vec < P < ast:: Ty > > =
773771 struct_def. fields ( ) . iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
@@ -795,8 +793,8 @@ impl<'a> TraitDef<'a> {
795793 type_ident,
796794 & selflike_args,
797795 & nonselflike_args,
798- use_temporaries,
799796 is_packed,
797+ always_copy,
800798 )
801799 } ;
802800
@@ -937,9 +935,7 @@ impl<'a> MethodDef<'a> {
937935
938936 match ty {
939937 // Selflike (`&Self`) arguments only occur in non-static methods.
940- Ref ( box Self_ , _) if !self . is_static ( ) => {
941- selflike_args. push ( cx. expr_deref ( span, arg_expr) )
942- }
938+ Ref ( box Self_ , _) if !self . is_static ( ) => selflike_args. push ( arg_expr) ,
943939 Self_ => cx. span_bug ( span, "`Self` in non-return position" ) ,
944940 _ => nonselflike_args. push ( arg_expr) ,
945941 }
@@ -1025,9 +1021,9 @@ impl<'a> MethodDef<'a> {
10251021 /// # struct A { x: i32, y: i32 }
10261022 /// impl PartialEq for A {
10271023 /// fn eq(&self, other: &A) -> bool {
1028- /// let Self { x: ref __self_0_0, y: ref __self_0_1 } = *self;
1029- /// let Self { x: ref __self_1_0, y: ref __self_1_1 } = *other;
1030- /// * __self_0_0 == * __self_1_0 && * __self_0_1 == * __self_1_1
1024+ /// let Self { x: __self_0_0, y: __self_0_1 } = *self;
1025+ /// let Self { x: __self_1_0, y: __self_1_1 } = *other;
1026+ /// __self_0_0 == __self_1_0 && __self_0_1 == __self_1_1
10311027 /// }
10321028 /// }
10331029 /// ```
@@ -1039,8 +1035,8 @@ impl<'a> MethodDef<'a> {
10391035 type_ident : Ident ,
10401036 selflike_args : & [ P < Expr > ] ,
10411037 nonselflike_args : & [ P < Expr > ] ,
1042- use_temporaries : bool ,
10431038 is_packed : bool ,
1039+ always_copy : bool ,
10441040 ) -> BlockOrExpr {
10451041 let span = trait_. span ;
10461042 assert ! ( selflike_args. len( ) == 1 || selflike_args. len( ) == 2 ) ;
@@ -1062,23 +1058,21 @@ impl<'a> MethodDef<'a> {
10621058 } else {
10631059 let prefixes: Vec < _ > =
10641060 ( 0 ..selflike_args. len ( ) ) . map ( |i| format ! ( "__self_{}" , i) ) . collect ( ) ;
1061+ let no_deref = always_copy;
10651062 let selflike_fields =
1066- trait_. create_struct_pattern_fields ( cx, struct_def, & prefixes, use_temporaries ) ;
1063+ trait_. create_struct_pattern_fields ( cx, struct_def, & prefixes, no_deref ) ;
10671064 let mut body = mk_body ( cx, selflike_fields) ;
10681065
10691066 let struct_path = cx. path ( span, vec ! [ Ident :: new( kw:: SelfUpper , type_ident. span) ] ) ;
1070- let patterns = trait_. create_struct_patterns (
1071- cx,
1072- struct_path,
1073- struct_def,
1074- & prefixes,
1075- use_temporaries,
1076- ) ;
1067+ let use_ref_pat = is_packed && !always_copy;
1068+ let patterns =
1069+ trait_. create_struct_patterns ( cx, struct_path, struct_def, & prefixes, use_ref_pat) ;
10771070
10781071 // Do the let-destructuring.
10791072 let mut stmts: Vec < _ > = iter:: zip ( selflike_args, patterns)
10801073 . map ( |( selflike_arg_expr, pat) | {
1081- cx. stmt_let_pat ( span, pat, selflike_arg_expr. clone ( ) )
1074+ let selflike_arg_expr = cx. expr_deref ( span, selflike_arg_expr. clone ( ) ) ;
1075+ cx. stmt_let_pat ( span, pat, selflike_arg_expr)
10821076 } )
10831077 . collect ( ) ;
10841078 stmts. extend ( std:: mem:: take ( & mut body. 0 ) ) ;
@@ -1118,18 +1112,16 @@ impl<'a> MethodDef<'a> {
11181112 /// impl ::core::cmp::PartialEq for A {
11191113 /// #[inline]
11201114 /// fn eq(&self, other: &A) -> bool {
1121- /// {
1122- /// let __self_vi = ::core::intrinsics::discriminant_value(&*self);
1123- /// let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
1124- /// if true && __self_vi == __arg_1_vi {
1125- /// match (&*self, &*other) {
1126- /// (&A::A2(ref __self_0), &A::A2(ref __arg_1_0)) =>
1127- /// (*__self_0) == (*__arg_1_0),
1128- /// _ => true,
1129- /// }
1130- /// } else {
1131- /// false // catch-all handler
1115+ /// let __self_vi = ::core::intrinsics::discriminant_value(self);
1116+ /// let __arg_1_vi = ::core::intrinsics::discriminant_value(other);
1117+ /// if __self_vi == __arg_1_vi {
1118+ /// match (self, other) {
1119+ /// (A::A2(__self_0), A::A2(__arg_1_0)) =>
1120+ /// *__self_0 == *__arg_1_0,
1121+ /// _ => true,
11321122 /// }
1123+ /// } else {
1124+ /// false // catch-all handler
11331125 /// }
11341126 /// }
11351127 /// }
@@ -1202,28 +1194,21 @@ impl<'a> MethodDef<'a> {
12021194 // A single arm has form (&VariantK, &VariantK, ...) => BodyK
12031195 // (see "Final wrinkle" note below for why.)
12041196
1205- let use_temporaries = false ; // enums can't be repr(packed)
1206- let fields = trait_. create_struct_pattern_fields (
1197+ let no_deref = false ; // because enums can't be repr(packed)
1198+ let fields =
1199+ trait_. create_struct_pattern_fields ( cx, & variant. data , & prefixes, no_deref) ;
1200+
1201+ let sp = variant. span . with_ctxt ( trait_. span . ctxt ( ) ) ;
1202+ let variant_path = cx. path ( sp, vec ! [ type_ident, variant. ident] ) ;
1203+ let use_ref_pat = false ; // because enums can't be repr(packed)
1204+ let mut subpats: Vec < _ > = trait_. create_struct_patterns (
12071205 cx,
1206+ variant_path,
12081207 & variant. data ,
12091208 & prefixes,
1210- use_temporaries ,
1209+ use_ref_pat ,
12111210 ) ;
12121211
1213- let sp = variant. span . with_ctxt ( trait_. span . ctxt ( ) ) ;
1214- let variant_path = cx. path ( sp, vec ! [ type_ident, variant. ident] ) ;
1215- let mut subpats: Vec < _ > = trait_
1216- . create_struct_patterns (
1217- cx,
1218- variant_path,
1219- & variant. data ,
1220- & prefixes,
1221- use_temporaries,
1222- )
1223- . into_iter ( )
1224- . map ( |p| cx. pat ( span, PatKind :: Ref ( p, ast:: Mutability :: Not ) ) )
1225- . collect ( ) ;
1226-
12271212 // Here is the pat = `(&VariantK, &VariantK, ...)`
12281213 let single_pat = if subpats. len ( ) == 1 {
12291214 subpats. pop ( ) . unwrap ( )
@@ -1302,25 +1287,23 @@ impl<'a> MethodDef<'a> {
13021287 // Build a series of let statements mapping each selflike_arg
13031288 // to its discriminant value.
13041289 //
1305- // i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
1306- // with three Self args, builds three statements:
1290+ // i.e., for `enum E<T> { A, B(1), C(T, T) }` for `PartialEq::eq`,
1291+ // builds two statements:
13071292 // ```
1308- // let __self_vi = std::intrinsics::discriminant_value(&self);
1309- // let __arg_1_vi = std::intrinsics::discriminant_value(&arg1);
1310- // let __arg_2_vi = std::intrinsics::discriminant_value(&arg2);
1293+ // let __self_vi = ::core::intrinsics::discriminant_value(self);
1294+ // let __arg_1_vi = ::core::intrinsics::discriminant_value(other);
13111295 // ```
13121296 let mut index_let_stmts: Vec < ast:: Stmt > = Vec :: with_capacity ( vi_idents. len ( ) + 1 ) ;
13131297
1314- // We also build an expression which checks whether all discriminants are equal:
1315- // `__self_vi == __arg_1_vi && __self_vi == __arg_2_vi && ...`
1298+ // We also build an expression which checks whether all discriminants are equal, e.g.
1299+ // `__self_vi == __arg_1_vi`.
13161300 let mut discriminant_test = cx. expr_bool ( span, true ) ;
13171301 for ( i, ( & ident, selflike_arg) ) in iter:: zip ( & vi_idents, & selflike_args) . enumerate ( ) {
1318- let selflike_addr = cx. expr_addr_of ( span, selflike_arg. clone ( ) ) ;
13191302 let variant_value = deriving:: call_intrinsic (
13201303 cx,
13211304 span,
13221305 sym:: discriminant_value,
1323- vec ! [ selflike_addr ] ,
1306+ vec ! [ selflike_arg . clone ( ) ] ,
13241307 ) ;
13251308 let let_stmt = cx. stmt_let ( span, false , ident, variant_value) ;
13261309 index_let_stmts. push ( let_stmt) ;
@@ -1347,17 +1330,11 @@ impl<'a> MethodDef<'a> {
13471330 )
13481331 . into_expr ( cx, span) ;
13491332
1350- // Final wrinkle: the selflike_args are expressions that deref
1351- // down to desired places, but we cannot actually deref
1352- // them when they are fed as r-values into a tuple
1353- // expression; here add a layer of borrowing, turning
1354- // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1355- selflike_args. map_in_place ( |selflike_arg| cx. expr_addr_of ( span, selflike_arg) ) ;
13561333 let match_arg = cx. expr ( span, ast:: ExprKind :: Tup ( selflike_args) ) ;
13571334
1358- // Lastly we create an expression which branches on all discriminants being equal
1359- // if discriminant_test {
1360- // match (... ) {
1335+ // Lastly we create an expression which branches on all discriminants being equal, e.g.
1336+ // if __self_vi == _arg_1_vi {
1337+ // match (self, other ) {
13611338 // (Variant1, Variant1, ...) => Body1
13621339 // (Variant2, Variant2, ...) => Body2,
13631340 // ...
@@ -1376,12 +1353,6 @@ impl<'a> MethodDef<'a> {
13761353 // for the zero variant case.
13771354 BlockOrExpr ( vec ! [ ] , Some ( deriving:: call_unreachable ( cx, span) ) )
13781355 } else {
1379- // Final wrinkle: the selflike_args are expressions that deref
1380- // down to desired places, but we cannot actually deref
1381- // them when they are fed as r-values into a tuple
1382- // expression; here add a layer of borrowing, turning
1383- // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1384- selflike_args. map_in_place ( |selflike_arg| cx. expr_addr_of ( span, selflike_arg) ) ;
13851356 let match_arg = if selflike_args. len ( ) == 1 {
13861357 selflike_args. pop ( ) . unwrap ( )
13871358 } else {
@@ -1451,18 +1422,18 @@ impl<'a> TraitDef<'a> {
14511422 struct_path : ast:: Path ,
14521423 struct_def : & ' a VariantData ,
14531424 prefixes : & [ String ] ,
1454- use_temporaries : bool ,
1425+ use_ref_pat : bool ,
14551426 ) -> Vec < P < ast:: Pat > > {
14561427 prefixes
14571428 . iter ( )
14581429 . map ( |prefix| {
14591430 let pieces_iter =
14601431 struct_def. fields ( ) . iter ( ) . enumerate ( ) . map ( |( i, struct_field) | {
14611432 let sp = struct_field. span . with_ctxt ( self . span . ctxt ( ) ) ;
1462- let binding_mode = if use_temporaries {
1463- ast:: BindingMode :: ByValue ( ast:: Mutability :: Not )
1464- } else {
1433+ let binding_mode = if use_ref_pat {
14651434 ast:: BindingMode :: ByRef ( ast:: Mutability :: Not )
1435+ } else {
1436+ ast:: BindingMode :: ByValue ( ast:: Mutability :: Not )
14661437 } ;
14671438 let ident = self . mk_pattern_ident ( prefix, i) ;
14681439 let path = ident. with_span_pos ( sp) ;
@@ -1541,15 +1512,15 @@ impl<'a> TraitDef<'a> {
15411512 cx : & mut ExtCtxt < ' _ > ,
15421513 struct_def : & ' a VariantData ,
15431514 prefixes : & [ String ] ,
1544- use_temporaries : bool ,
1515+ no_deref : bool ,
15451516 ) -> Vec < FieldInfo > {
15461517 self . create_fields ( struct_def, |i, _struct_field, sp| {
15471518 prefixes
15481519 . iter ( )
15491520 . map ( |prefix| {
15501521 let ident = self . mk_pattern_ident ( prefix, i) ;
15511522 let expr = cx. expr_path ( cx. path_ident ( sp, ident) ) ;
1552- if use_temporaries { expr } else { cx. expr_deref ( sp, expr) }
1523+ if no_deref { expr } else { cx. expr_deref ( sp, expr) }
15531524 } )
15541525 . collect ( )
15551526 } )
@@ -1564,11 +1535,7 @@ impl<'a> TraitDef<'a> {
15641535 self . create_fields ( struct_def, |i, struct_field, sp| {
15651536 selflike_args
15661537 . iter ( )
1567- . map ( |mut selflike_arg| {
1568- // We don't the need the deref, if there is one.
1569- if let ast:: ExprKind :: Unary ( ast:: UnOp :: Deref , inner) = & selflike_arg. kind {
1570- selflike_arg = inner;
1571- }
1538+ . map ( |selflike_arg| {
15721539 // Note: we must use `struct_field.span` rather than `span` in the
15731540 // `unwrap_or_else` case otherwise the hygiene is wrong and we get
15741541 // "field `0` of struct `Point` is private" errors on tuple
0 commit comments