expand_deriving_clone
tweaks.
Improve a comment, and panic on an impossible code path.
This commit is contained in:
parent
623ebbe42a
commit
78ec19ffe6
1 changed files with 22 additions and 28 deletions
|
@ -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),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue