Auto merge of #99046 - nnethercote:final-derive-output-improvements, … · rust-lang/rust@0fe5390 (original) (raw)

11 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -148,7 +148,7 @@ fn cs_clone_simple(
148 148 ),
149 149 }
150 150 }
151 -BlockOrExpr::new_mixed(stmts, cx.expr_deref(trait_span, cx.expr_self(trait_span)))
151 +BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span))))
152 152 }
153 153
154 154 fn cs_clone(
@@ -161,7 +161,7 @@ fn cs_clone(
161 161 let all_fields;
162 162 let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
163 163 let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo
164 -let args = vec![cx.expr_addr_of(field.span, field.self_expr.clone())];
164 +let args = vec![field.self_expr.clone()];
165 165 cx.expr_call_global(field.span, fn_path.clone(), args)
166 166 };
167 167
@@ -177,9 +177,7 @@ fn cs_clone(
177 177 all_fields = af;
178 178 vdata = &variant.data;
179 179 }
180 -EnumNonMatchingCollapsed(..) => {
181 - cx.span_bug(trait_span, &format!("non-matching enum variants in `derive({})`", name,))
182 -}
180 +EnumTag(..) => cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,)),
183 181 StaticEnum(..) | StaticStruct(..) => {
184 182 cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
185 183 }
Original file line number Diff line number Diff line change
@@ -63,10 +63,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
63 63 let [other_expr] = &field.other_selflike_exprs[..] else {
64 64 cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
65 65 };
66 -let args = vec![
67 - cx.expr_addr_of(field.span, field.self_expr.clone()),
68 - cx.expr_addr_of(field.span, other_expr.clone()),
69 -];
66 +let args = vec![field.self_expr.clone(), other_expr.clone()];
70 67 cx.expr_call_global(field.span, cmp_path.clone(), args)
71 68 }
72 69 CsFold::Combine(span, expr1, expr2) => {
@@ -76,16 +73,6 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
76 73 cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
77 74 }
78 75 CsFold::Fieldless => cx.expr_path(equal_path.clone()),
79 -CsFold::EnumNonMatching(span, tag_tuple) => {
80 -if tag_tuple.len() != 2 {
81 - cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
82 -} else {
83 -let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
84 -let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
85 -let fn_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
86 - cx.expr_call_global(span, fn_cmp_path, vec![lft, rgt])
87 -}
88 -}
89 76 },
90 77 );
91 78 BlockOrExpr::new_expr(expr)
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@ use crate::deriving::generic::ty::*;
2 2 use crate::deriving::generic::*;
3 3 use crate::deriving::{path_local, path_std};
4 4
5 -use rustc_ast::{BinOpKind, MetaItem};
5 +use rustc_ast::ptr::P;
6 +use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
6 7 use rustc_expand::base::{Annotatable, ExtCtxt};
7 8 use rustc_span::symbol::sym;
8 9 use rustc_span::Span;
@@ -32,11 +33,24 @@ pub fn expand_deriving_partial_eq(
32 33 let [other_expr] = &field.other_selflike_exprs[..] else {
33 34 cx.span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
34 35 };
35 - cx.expr_binary(field.span, op, field.self_expr.clone(), other_expr.clone())
36 +
37 +// We received `&T` arguments. Convert them to `T` by
38 +// stripping `&` or adding `*`. This isn't necessary for
39 +// type checking, but it results in much better error
40 +// messages if something goes wrong.
41 +let convert = |expr: &P<Expr>
42 +if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) =
43 +&expr.kind
44 +{
45 + inner.clone()
46 +} else {
47 + cx.expr_deref(field.span, expr.clone())
48 +}
49 +};
50 + cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
36 51 }
37 52 CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
38 53 CsFold::Fieldless => cx.expr_bool(span, base),
39 -CsFold::EnumNonMatching(span, _tag_tuple) => cx.expr_bool(span, !base),
40 54 },
41 55 );
42 56 BlockOrExpr::new_expr(expr)
Original file line number Diff line number Diff line change
@@ -71,10 +71,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
71 71 let [other_expr] = &field.other_selflike_exprs[..] else {
72 72 cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
73 73 };
74 -let args = vec![
75 - cx.expr_addr_of(field.span, field.self_expr.clone()),
76 - cx.expr_addr_of(field.span, other_expr.clone()),
77 -];
74 +let args = vec![field.self_expr.clone(), other_expr.clone()];
78 75 cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
79 76 }
80 77 CsFold::Combine(span, expr1, expr2) => {
@@ -85,17 +82,6 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
85 82 cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
86 83 }
87 84 CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),
88 -CsFold::EnumNonMatching(span, tag_tuple) => {
89 -if tag_tuple.len() != 2 {
90 - cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
91 -} else {
92 -let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
93 -let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
94 -let fn_partial_cmp_path =
95 - cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
96 - cx.expr_call_global(span, fn_partial_cmp_path, vec![lft, rgt])
97 -}
98 -}
99 85 },
100 86 );
101 87 BlockOrExpr::new_expr(expr)
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
45 45 let (ident, vdata, fields) = match substr.fields {
46 46 Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
47 47 EnumMatching(_, _, v, fields) => (v.ident, &v.data, fields),
48 -EnumNonMatchingCollapsed(..) | StaticStruct(..) StaticEnum(..) => {
48 +EnumTag(..) | StaticStruct(..) StaticEnum(..) => {
49 49 cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
50 50 }
51 51 };
@@ -95,9 +95,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
95 95 );
96 96 args.push(name);
97 97 }
98 -// Use double indirection to make sure this works for unsized types
98 +// Use an extra indirection to make sure this works for unsized types.
99 99 let field = cx.expr_addr_of(field.span, field.self_expr.clone());
100 -let field = cx.expr_addr_of(field.span, field);
101 100 args.push(field);
102 101 }
103 102 let expr = cx.expr_call_global(span, fn_path_debug, args);
@@ -115,9 +114,9 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
115 114 ));
116 115 }
117 116
118 -// Use double indirection to make sure this works for unsized types
119 -let value_ref = cx.expr_addr_of(field.span, field.self_expr.clone());
120 - value_exprs.push(cx.expr_addr_of(field.span, value_ref));
117 +// Use an extra indirection to make sure this works for unsized types.
118 +let field = cx.expr_addr_of(field.span, field.self_expr.clone());
119 + value_exprs.push(field);
121 120 }
122 121
123 122 // `let names: &'static _ = &["field1", "field2"];`
@@ -177,6 +176,6 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
177 176 stmts.push(names_let.unwrap());
178 177 }
179 178 stmts.push(values_let);
180 -BlockOrExpr::new_mixed(stmts, expr)
179 +BlockOrExpr::new_mixed(stmts, Some(expr))
181 180 }
182 181 }
Original file line number Diff line number Diff line change
@@ -287,7 +287,7 @@ fn encodable_substructure(
287 287 fn_emit_enum_path,
288 288 vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk],
289 289 );
290 -BlockOrExpr::new_mixed(vec![me], expr)
290 +BlockOrExpr::new_mixed(vec![me], Some(expr))
291 291 }
292 292
293 293 _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),