about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-11-19 17:04:24 +0200
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2017-11-26 16:12:43 +0200
commit617b413e18f8a6bbd24853f5bf84e8a4ac319ae1 (patch)
tree1acc1883e0cd5414436f18f7fe6b2b81f94d1a3d /src/libsyntax_ext
parentdee8a71cd5221536c319ca8c14108e93521092f5 (diff)
downloadrust-617b413e18f8a6bbd24853f5bf84e8a4ac319ae1.tar.gz
rust-617b413e18f8a6bbd24853f5bf84e8a4ac319ae1.zip
limit packed copy-out to non-generic Copy structs
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 5abf524313a..2b565ca51e9 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -413,7 +413,24 @@ impl<'a> TraitDef<'a> {
                     attr::find_repr_attrs(&cx.parse_sess.span_diagnostic, attr)
                         .contains(&attr::ReprPacked)
                 });
-                let use_temporaries = is_packed;
+                let has_no_type_params = match item.node {
+                    ast::ItemKind::Struct(_, ref generics) |
+                    ast::ItemKind::Enum(_, ref generics) |
+                    ast::ItemKind::Union(_, ref generics) => {
+                        generics.ty_params.is_empty()
+                    }
+                    _ => {
+                        // Non-ADT derive is an error, but it should have been
+                        // set earlier; see
+                        // libsyntax/ext/expand.rs:MacroExpander::expand()
+                        return;
+                    }
+                };
+                let is_always_copy =
+                    attr::contains_name(&item.attrs, "rustc_copy_clone_marker") &&
+                    has_no_type_params;
+                let use_temporaries = is_packed && is_always_copy;
+
                 let newitem = match item.node {
                     ast::ItemKind::Struct(ref struct_def, ref generics) => {
                         self.expand_struct_def(cx, &struct_def, item.ident, generics, from_scratch,
@@ -440,12 +457,7 @@ impl<'a> TraitDef<'a> {
                             return;
                         }
                     }
-                    _ => {
-                        // Non-ADT derive is an error, but it should have been
-                        // set earlier; see
-                        // libsyntax/ext/expand.rs:MacroExpander::expand()
-                        return;
-                    }
+                    _ => unreachable!(),
                 };
                 // Keep the lint attributes of the previous item to control how the
                 // generated implementations are linted