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)"), |