From e329b15c2ef08d40535860b5b5779d2ce9b7e881 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Jan 2019 16:20:09 +0800 Subject: Trans Enumerate - Ensure that clone impls called by auto clone impl are enumerated --- src/trans/enumerate.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/trans/enumerate.cpp') diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index bb6d6e6f..6aeb3485 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -1393,9 +1393,30 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co { const auto& pe = path_mono.m_data.as_UfcsKnown(); ASSERT_BUG(sp, pe.item == "clone", ""); - // TODO: If this is !Copy, then we need to ensure that the inner type's clone impls are also available + const auto& inner_ty = *pe.type; + // If this is !Copy, then we need to ensure that the inner type's clone impls are also available + ::StaticTraitResolve resolve { state.crate }; + if( !resolve.type_is_copy(sp, inner_ty) ) + { + auto enum_impl = [&](const ::HIR::TypeRef& ity) { + if( !resolve.type_is_copy(sp, ity) ) + { + auto p = ::HIR::Path(ity.clone(), pe.trait.clone(), "clone"); + Trans_Enumerate_FillFrom_Path(state, p, {}); + } + }; + if( const auto* te = inner_ty.m_data.opt_Tuple() ) { + for(const auto& ity : *te) + { + enum_impl(ity); + } + } + else { + BUG(sp, "Unhandled magic clone in enumerate - " << inner_ty); + } + } // Add this type to a list of types that will have the impl auto-generated - state.rv.auto_clone_impls.insert( pe.type->clone() ); + state.rv.auto_clone_impls.insert( inner_ty.clone() ); } else { -- cgit v1.2.3