Skip to content

Commit 277bc96

Browse files
committed
Remove unnecessary sigils and refs in derived code.
E.g. improving code like this: ``` match &*self { &Enum1::Single { x: ref __self_0 } => { ::core::hash::Hash::hash(&*__self_0, state) } } ``` to this: ``` match self { Enum1::Single { x: __self_0 } => { ::core::hash::Hash::hash(&*__self_0, state) } } ``` by removing the `&*`, the `&`, and the `ref`. I suspect the current generated code predates deref-coercion. The commit also gets rid of `use_temporaries`, instead passing around `always_copy`, which makes things a little clearer. And it fixes up some comments.
1 parent f314ece commit 277bc96

File tree

3 files changed

+160
-196
lines changed

3 files changed

+160
-196
lines changed

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

Lines changed: 53 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ use rustc_ast::ptr::P;
183183
use rustc_ast::{self as ast, BinOpKind, EnumDef, Expr, Generics, PatKind};
184184
use rustc_ast::{GenericArg, GenericParamKind, VariantData};
185185
use rustc_attr as attr;
186-
use rustc_data_structures::map_in_place::MapInPlace;
187186
use rustc_expand::base::{Annotatable, ExtCtxt};
188187
use rustc_span::symbol::{kw, sym, Ident, Symbol};
189188
use 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

compiler/rustc_builtin_macros/src/deriving/generic/ty.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,8 @@ impl Bounds {
196196
}
197197

198198
pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
199-
// this constructs a fresh `self` path
199+
// This constructs a fresh `self` path.
200200
let self_path = cx.expr_self(span);
201201
let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
202-
let self_expr = cx.expr_deref(span, self_path);
203-
(self_expr, self_ty)
202+
(self_path, self_ty)
204203
}

0 commit comments

Comments
 (0)