summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Notes/Quirks.md5
-rw-r--r--src/hir_expand/annotate_value_usage.cpp10
2 files changed, 12 insertions, 3 deletions
diff --git a/Notes/Quirks.md b/Notes/Quirks.md
index b312dfec..998c5d25 100644
--- a/Notes/Quirks.md
+++ b/Notes/Quirks.md
@@ -44,3 +44,8 @@ Blocks that don't yield a value can mark as diverged if ?any statement diverges
=============
- This includes any function call (or method call)
- TODO: Is this just the last statement? or all statements
+
+The "base" value of a struct literal isn't always moved
+======================================================
+- Only the values used are moved, which can lead to the source not being moved (if all used values are Copy)
+
diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp
index 0650e52c..04be9644 100644
--- a/src/hir_expand/annotate_value_usage.cpp
+++ b/src/hir_expand/annotate_value_usage.cpp
@@ -254,8 +254,10 @@ namespace {
void visit(::HIR::ExprNode_Field& node) override
{
+ bool is_copy = m_resolve.type_is_copy(node.span(), node.m_res_type);
+ DEBUG("ty = " << node.m_res_type << ", is_copy=" << is_copy);
// If taking this field by value, but the type is Copy - pretend it's a borrow.
- if( this->get_usage() == ::HIR::ValueUsage::Move && m_resolve.type_is_copy(node.span(), node.m_res_type) ) {
+ if( this->get_usage() == ::HIR::ValueUsage::Move && is_copy ) {
auto _ = push_usage( ::HIR::ValueUsage::Borrow );
this->visit_node_ptr(node.m_value);
}
@@ -310,11 +312,13 @@ namespace {
void visit(::HIR::ExprNode_StructLiteral& node) override
{
- auto _ = push_usage( ::HIR::ValueUsage::Move );
-
if( node.m_base_value ) {
+ // TODO: If only Copy fields will be used, set usage to Borrow
+ auto _ = push_usage( ::HIR::ValueUsage::Move );
this->visit_node_ptr(node.m_base_value);
}
+
+ auto _ = push_usage( ::HIR::ValueUsage::Move );
for( auto& fld_val : node.m_values ) {
this->visit_node_ptr(fld_val.second);
}