Skip to content

Commit

Permalink
Auto merge of #99046 - nnethercote:final-derive-output-improvements, …
Browse files Browse the repository at this point in the history
…r=Mark-Simulacrum

Final derive output improvements

With all these changes, the derive output in `deriving-all-codegen.stdout` is pretty close to optimal, i.e. very similar to what you'd write by hand.

r? `@ghost`
  • Loading branch information
bors committed Jul 15, 2022
2 parents 116819f + 1cb1d63 commit 0fe5390
Show file tree
Hide file tree
Showing 11 changed files with 717 additions and 575 deletions.
8 changes: 3 additions & 5 deletions compiler/rustc_builtin_macros/src/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn cs_clone_simple(
),
}
}
BlockOrExpr::new_mixed(stmts, cx.expr_deref(trait_span, cx.expr_self(trait_span)))
BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span))))
}

fn cs_clone(
Expand All @@ -161,7 +161,7 @@ fn cs_clone(
let all_fields;
let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo| {
let args = vec![cx.expr_addr_of(field.span, field.self_expr.clone())];
let args = vec![field.self_expr.clone()];
cx.expr_call_global(field.span, fn_path.clone(), args)
};

Expand All @@ -177,9 +177,7 @@ fn cs_clone(
all_fields = af;
vdata = &variant.data;
}
EnumNonMatchingCollapsed(..) => {
cx.span_bug(trait_span, &format!("non-matching enum variants in `derive({})`", name,))
}
EnumTag(..) => cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,)),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
}
Expand Down
15 changes: 1 addition & 14 deletions compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = vec![
cx.expr_addr_of(field.span, field.self_expr.clone()),
cx.expr_addr_of(field.span, other_expr.clone()),
];
let args = vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, cmp_path.clone(), args)
}
CsFold::Combine(span, expr1, expr2) => {
Expand All @@ -76,16 +73,6 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
}
CsFold::Fieldless => cx.expr_path(equal_path.clone()),
CsFold::EnumNonMatching(span, tag_tuple) => {
if tag_tuple.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
} else {
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
let fn_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
cx.expr_call_global(span, fn_cmp_path, vec![lft, rgt])
}
}
},
);
BlockOrExpr::new_expr(expr)
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};

use rustc_ast::{BinOpKind, MetaItem};
use rustc_ast::ptr::P;
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
Expand Down Expand Up @@ -32,11 +33,24 @@ pub fn expand_deriving_partial_eq(
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
};
cx.expr_binary(field.span, op, field.self_expr.clone(), other_expr.clone())

// We received `&T` arguments. Convert them to `T` by
// stripping `&` or adding `*`. This isn't necessary for
// type checking, but it results in much better error
// messages if something goes wrong.
let convert = |expr: &P<Expr>| {
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) =
&expr.kind
{
inner.clone()
} else {
cx.expr_deref(field.span, expr.clone())
}
};
cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
}
CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
CsFold::Fieldless => cx.expr_bool(span, base),
CsFold::EnumNonMatching(span, _tag_tuple) => cx.expr_bool(span, !base),
},
);
BlockOrExpr::new_expr(expr)
Expand Down
16 changes: 1 addition & 15 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = vec![
cx.expr_addr_of(field.span, field.self_expr.clone()),
cx.expr_addr_of(field.span, other_expr.clone()),
];
let args = vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
}
CsFold::Combine(span, expr1, expr2) => {
Expand All @@ -85,17 +82,6 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
}
CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),
CsFold::EnumNonMatching(span, tag_tuple) => {
if tag_tuple.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
let fn_partial_cmp_path =
cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
cx.expr_call_global(span, fn_partial_cmp_path, vec![lft, rgt])
}
}
},
);
BlockOrExpr::new_expr(expr)
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, _, v, fields) => (v.ident, &v.data, fields),
EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
EnumTag(..) | StaticStruct(..) | StaticEnum(..) => {
cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
}
};
Expand Down Expand Up @@ -95,9 +95,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
);
args.push(name);
}
// Use double indirection to make sure this works for unsized types
// Use an extra indirection to make sure this works for unsized types.
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
let field = cx.expr_addr_of(field.span, field);
args.push(field);
}
let expr = cx.expr_call_global(span, fn_path_debug, args);
Expand All @@ -115,9 +114,9 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
));
}

// Use double indirection to make sure this works for unsized types
let value_ref = cx.expr_addr_of(field.span, field.self_expr.clone());
value_exprs.push(cx.expr_addr_of(field.span, value_ref));
// Use an extra indirection to make sure this works for unsized types.
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
value_exprs.push(field);
}

// `let names: &'static _ = &["field1", "field2"];`
Expand Down Expand Up @@ -177,6 +176,6 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
stmts.push(names_let.unwrap());
}
stmts.push(values_let);
BlockOrExpr::new_mixed(stmts, expr)
BlockOrExpr::new_mixed(stmts, Some(expr))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/encodable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ fn encodable_substructure(
fn_emit_enum_path,
vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk],
);
BlockOrExpr::new_mixed(vec![me], expr)
BlockOrExpr::new_mixed(vec![me], Some(expr))
}

_ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
Expand Down
Loading

0 comments on commit 0fe5390

Please sign in to comment.