From 6ec0d6dd7734b82d30122663a1ead436d09c9dfd Mon Sep 17 00:00:00 2001 From: Emilio Cobos Álvarez Date: Sat, 2 Apr 2016 02:59:00 +0200 Subject: Don't generate derive(Clone), make a manual impl instead using copy This is in order to bypass rustc's limits with large arrays. Still can't work with templates (cc @nox). --- src/gen.rs | 35 ++++++++++++++++++++++++++++++++--- tests/headers/class.hpp | 8 ++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/gen.rs b/src/gen.rs index 4bba708c..16bc3f26 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -1173,7 +1173,14 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec let mut attrs = mk_doc_attr(ctx, &ci.comment); attrs.push(mk_repr_attr(ctx, layout)); if !has_destructor { - attrs.push(mk_deriving_copy_attr(ctx)); + if template_args.is_empty() { + extra.push(mk_clone_impl(ctx, name)); + attrs.push(mk_deriving_copy_attr(ctx)); + } else { + // TODO: make mk_clone_impl work for template arguments, + // meanwhile just fallback to deriving. + attrs.push(mk_deriving_attr(ctx, &["Copy", "Clone"])) + } } let struct_def = ast::Item { ident: ctx.ext_cx.ident_of(&id), @@ -1307,6 +1314,8 @@ fn cunion_to_rs(ctx: &mut GenCtx, name: &str, layout: Layout, members: Vec f.ty.can_derive_debug(), _ => true }); + + extra.push(mk_clone_impl(ctx, name)); union_attrs.push(if can_derive_debug { mk_deriving_copy_and_maybe_debug_attr(ctx) } else { @@ -1495,6 +1504,8 @@ fn cenum_to_rs(ctx: &mut GenCtx, span: ctx.span, })); + items.push(mk_clone_impl(ctx, &name)); + items } @@ -1749,12 +1760,30 @@ fn mk_repr_attr(ctx: &mut GenCtx, layout: Layout) -> ast::Attribute { } fn mk_deriving_copy_attr(ctx: &mut GenCtx) -> ast::Attribute { - mk_deriving_attr(ctx, &["Copy", "Clone"]) + mk_deriving_attr(ctx, &["Copy"]) +} + +// NB: This requires that the type you implement it for also +// implements Copy. +// +// Implements std::clone::Clone using dereferencing. +// +// This is to bypass big arrays not implementing clone, +// but implementing copy due to hacks inside rustc's internals. +fn mk_clone_impl(ctx: &GenCtx, ty_name: &str) -> P { + let impl_str = format!(r" + impl ::std::clone::Clone for {} {{ + fn clone(&self) -> Self {{ *self }} + }} + ", ty_name); + + parse::new_parser_from_source_str(ctx.ext_cx.parse_sess(), + ctx.ext_cx.cfg(), "".to_owned(), impl_str).parse_item().unwrap().unwrap() } fn mk_deriving_copy_and_maybe_debug_attr(ctx: &mut GenCtx) -> ast::Attribute { if ctx.options.derive_debug { - mk_deriving_attr(ctx, &["Copy", "Clone", "Debug"]) + mk_deriving_attr(ctx, &["Copy", "Debug"]) } else { mk_deriving_copy_attr(ctx) } diff --git a/tests/headers/class.hpp b/tests/headers/class.hpp index 53894ab3..4d795363 100644 --- a/tests/headers/class.hpp +++ b/tests/headers/class.hpp @@ -1,3 +1,11 @@ class C { int a; + // More than rust limits (32) + char big_array[33]; +}; + +class WithDtor { + int b; + + ~WithDtor() {} }; -- cgit v1.2.3