diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-01-20 16:20:09 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-01-20 16:20:09 +0800 |
commit | e329b15c2ef08d40535860b5b5779d2ce9b7e881 (patch) | |
tree | ad6bfdf360b5d63e25f766371dc7e874fd1837a7 /src | |
parent | 878c7bc03640ded25dd6e704aa443845cfd6d144 (diff) | |
download | mrust-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.cpp | 25 |
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 { |