1
Fork 0

expand_deriving_clone tweaks.

Improve a comment, and panic on an impossible code path.
This commit is contained in:
Nicholas Nethercote 2022-06-28 15:23:16 +10:00
parent 623ebbe42a
commit 78ec19ffe6

View file

@ -15,23 +15,22 @@ pub fn expand_deriving_clone(
item: &Annotatable, item: &Annotatable,
push: &mut dyn FnMut(Annotatable), push: &mut dyn FnMut(Annotatable),
) { ) {
// check if we can use a short form // The simple form is `fn clone(&self) -> Self { *self }`, possibly with
// some additional `AssertParamIsClone` assertions.
// //
// the short form is `fn clone(&self) -> Self { *self }` // We can use the simple form if either of the following are true.
// // - The type derives Copy and there are no generic parameters. (If we
// we can use the short form if: // used the simple form with generics, we'd have to bound the generics
// - the item is Copy (unfortunately, all we can check is whether it's also deriving Copy) // with Clone + Copy, and then there'd be no Clone impl at all if the
// - there are no generic parameters (after specialization this limitation can be removed) // user fills in something that is Clone but not Copy. After
// if we used the short form with generics, we'd have to bound the generics with // specialization we can remove this no-generics limitation.)
// Clone + Copy, and then there'd be no Clone impl at all if the user fills in something // - The item is a union. (Unions with generic parameters still can derive
// that is Clone but not Copy. and until specialization we can't write both impls. // Clone because they require Copy for deriving, Clone alone is not
// - the item is a union with Copy fields // enough. Whether Clone is implemented for fields is irrelevant so we
// Unions with generic parameters still can derive Clone because they require Copy // don't assert it.)
// for deriving, Clone alone is not enough.
// Wherever Clone is implemented for fields is irrelevant so we don't assert it.
let bounds; let bounds;
let substructure; let substructure;
let is_shallow; let is_simple;
match *item { match *item {
Annotatable::Item(ref annitem) => match annitem.kind { Annotatable::Item(ref annitem) => match annitem.kind {
ItemKind::Struct(_, Generics { ref params, .. }) ItemKind::Struct(_, Generics { ref params, .. })
@ -44,30 +43,25 @@ pub fn expand_deriving_clone(
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. }))
{ {
bounds = vec![]; bounds = vec![];
is_shallow = true; is_simple = true;
substructure = combine_substructure(Box::new(|c, s, sub| { substructure = combine_substructure(Box::new(|c, s, sub| {
cs_clone_shallow("Clone", c, s, sub, false) cs_clone_simple("Clone", c, s, sub, false)
})); }));
} else { } else {
bounds = vec![]; bounds = vec![];
is_shallow = false; is_simple = false;
substructure = substructure =
combine_substructure(Box::new(|c, s, sub| cs_clone("Clone", c, s, sub))); combine_substructure(Box::new(|c, s, sub| cs_clone("Clone", c, s, sub)));
} }
} }
ItemKind::Union(..) => { ItemKind::Union(..) => {
bounds = vec![Literal(path_std!(marker::Copy))]; bounds = vec![Literal(path_std!(marker::Copy))];
is_shallow = true; is_simple = true;
substructure = combine_substructure(Box::new(|c, s, sub| { substructure = combine_substructure(Box::new(|c, s, sub| {
cs_clone_shallow("Clone", c, s, sub, true) cs_clone_simple("Clone", c, s, sub, true)
})); }));
} }
_ => { _ => cx.span_bug(span, "`#[derive(Clone)]` on wrong item kind"),
bounds = vec![];
is_shallow = false;
substructure =
combine_substructure(Box::new(|c, s, sub| cs_clone("Clone", c, s, sub)));
}
}, },
_ => cx.span_bug(span, "`#[derive(Clone)]` on trait item or impl item"), _ => cx.span_bug(span, "`#[derive(Clone)]` on trait item or impl item"),
@ -95,10 +89,10 @@ pub fn expand_deriving_clone(
associated_types: Vec::new(), associated_types: Vec::new(),
}; };
trait_def.expand_ext(cx, mitem, item, push, is_shallow) trait_def.expand_ext(cx, mitem, item, push, is_simple)
} }
fn cs_clone_shallow( fn cs_clone_simple(
name: &str, name: &str,
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
trait_span: Span, trait_span: Span,
@ -141,7 +135,7 @@ fn cs_clone_shallow(
} }
_ => cx.span_bug( _ => cx.span_bug(
trait_span, trait_span,
&format!("unexpected substructure in shallow `derive({})`", name), &format!("unexpected substructure in simple `derive({})`", name),
), ),
} }
} }