Skip to content

Commit 861872e

Browse files
Seems to work
1 parent c5266e4 commit 861872e

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

compiler/rustc_builtin_macros/src/deriving/clone.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub fn expand_deriving_clone(
116116
ret_ty: nil_ty(),
117117
attributes: attrs.to_vec(),
118118
is_unsafe: false,
119-
unify_fieldless_variants: false,
119+
unify_fieldless_variants: true,
120120
combine_substructure: substructure_clone_from,
121121
})
122122
}
@@ -267,19 +267,18 @@ fn cs_clone_from(
267267
let all_fields = match *substr.fields {
268268
Struct(.., ref af) => af,
269269
EnumMatching(.., ref af) => af,
270-
EnumNonMatchingCollapsed(ref idents, ..) => {
270+
EnumNonMatchingCollapsed(..) => {
271271
// Cannot do something smart here.
272272
// so emit `*self = other.clone();`
273273

274-
let [self_, other] = idents[..] else{
274+
let [self_, other] = &substr.self_args[..] else{
275275
cx.span_bug(trait_span, &format!("not exactly 2 arguments in `clone_from` in `derive({})`", name))
276276
};
277-
let self_ = cx.expr_deref(trait_span, cx.expr_ident(trait_span, self_));
278-
let other = cx.expr_ident(trait_span, other);
277+
let self_ = self_.clone();
279278
let clone_call = cx.expr_call_global(
280279
trait_span,
281280
clone_fn_full_path(cx),
282-
vec![cx.expr_addr_of(trait_span, other)],
281+
vec![cx.expr_addr_of(trait_span, other.clone())],
283282
);
284283
return cx.expr(trait_span, ast::ExprKind::Assign(self_, clone_call, trait_span));
285284
}

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

+30-10
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ use rustc_ast::ptr::P;
185185
use rustc_ast::{self as ast, BinOpKind, EnumDef, Expr, Generics, PatKind};
186186
use rustc_ast::{GenericArg, GenericParamKind, VariantData};
187187
use rustc_attr as attr;
188-
use rustc_data_structures::map_in_place::MapInPlace;
189188
use rustc_expand::base::{Annotatable, ExtCtxt};
190189
use rustc_span::symbol::{kw, sym, Ident, Symbol};
191190
use rustc_span::Span;
@@ -1207,7 +1206,7 @@ impl<'a> MethodDef<'a> {
12071206
trait_: &TraitDef<'b>,
12081207
enum_def: &'b EnumDef,
12091208
type_ident: Ident,
1210-
mut self_args: Vec<P<Expr>>,
1209+
self_args: Vec<P<Expr>>,
12111210
nonself_args: &[P<Expr>],
12121211
) -> P<Expr> {
12131212
let span = trait_.span;
@@ -1247,6 +1246,13 @@ impl<'a> MethodDef<'a> {
12471246

12481247
let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty());
12491248

1249+
// Support mutability only for `&mut self` for now.
1250+
let self_mutbl = match &self.explicit_self {
1251+
Some(Some(PtrTy::Borrowed(_, mutbl))) => *mutbl,
1252+
Some(Some(PtrTy::Raw(mutbl))) => *mutbl,
1253+
_ => ast::Mutability::Not,
1254+
};
1255+
12501256
// These arms are of the form:
12511257
// (Variant1, Variant1, ...) => Body1
12521258
// (Variant2, Variant2, ...) => Body2
@@ -1257,12 +1263,6 @@ impl<'a> MethodDef<'a> {
12571263
.enumerate()
12581264
.filter(|&(_, v)| !(self.unify_fieldless_variants && v.data.fields().is_empty()))
12591265
.map(|(index, variant)| {
1260-
// Support mutability only for `&mut self` for now.
1261-
let self_mutbl = match &self.explicit_self {
1262-
Some(Some(PtrTy::Borrowed(_, mutbl))) => *mutbl,
1263-
Some(Some(PtrTy::Raw(mutbl))) => *mutbl,
1264-
_ => ast::Mutability::Not,
1265-
};
12661266
let mk_self_pat =
12671267
|cx: &mut ExtCtxt<'_>, self_arg_name: &str, mutbl: ast::Mutability| {
12681268
let (p, idents) = trait_.create_enum_variant_pattern(
@@ -1454,7 +1454,17 @@ impl<'a> MethodDef<'a> {
14541454
// them when they are fed as r-values into a tuple
14551455
// expression; here add a layer of borrowing, turning
14561456
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1457-
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
1457+
let self_args: Vec<_> = self_args
1458+
.into_iter()
1459+
.enumerate()
1460+
.map(|(i, self_arg)| {
1461+
if i == 0 && self_mutbl == ast::Mutability::Mut {
1462+
cx.expr_addr_of_mut(span, self_arg)
1463+
} else {
1464+
cx.expr_addr_of(span, self_arg)
1465+
}
1466+
})
1467+
.collect();
14581468
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
14591469

14601470
// Lastly we create an expression which branches on all discriminants being equal
@@ -1530,7 +1540,17 @@ impl<'a> MethodDef<'a> {
15301540
// them when they are fed as r-values into a tuple
15311541
// expression; here add a layer of borrowing, turning
15321542
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1533-
self_args.map_in_place(|self_arg| cx.expr_addr_of(span, self_arg));
1543+
let self_args: Vec<_> = self_args
1544+
.into_iter()
1545+
.enumerate()
1546+
.map(|(i, self_arg)| {
1547+
if i == 0 && self_mutbl == ast::Mutability::Mut {
1548+
cx.expr_addr_of_mut(span, self_arg)
1549+
} else {
1550+
cx.expr_addr_of(span, self_arg)
1551+
}
1552+
})
1553+
.collect();
15341554
let match_arg = cx.expr(span, ast::ExprKind::Tup(self_args));
15351555
cx.expr_match(span, match_arg, match_arms)
15361556
}

0 commit comments

Comments
 (0)