summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-01-20 16:20:09 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-01-20 16:20:09 +0800
commite329b15c2ef08d40535860b5b5779d2ce9b7e881 (patch)
treead6bfdf360b5d63e25f766371dc7e874fd1837a7 /src
parent878c7bc03640ded25dd6e704aa443845cfd6d144 (diff)
downloadmrust-e329b15c2ef08d40535860b5b5779d2ce9b7e881.tar.gz
Trans Enumerate - Ensure that clone impls called by auto clone impl are enumerated
Diffstat (limited to 'src')
-rw-r--r--src/trans/enumerate.cpp25
1 files changed, 23 insertions, 2 deletions
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
{