summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-08-11 12:11:43 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-08-11 12:11:43 +0800
commit1b572c8a6c62459fc99a2b1df067cb8f77971ea9 (patch)
tree5c8e86eba98237e49411bea2c12858be5221b0e6 /src
parentfdc99699ea2ba7d27270b89619695c389dd6b2b1 (diff)
downloadmrust-1b572c8a6c62459fc99a2b1df067cb8f77971ea9.tar.gz
MIR Optimise - Fix mis-optimisation in splitting tuples
Diffstat (limited to 'src')
-rw-r--r--src/mir/optimise.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index 54c2d22a..2d4dbc68 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -3422,7 +3422,10 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
// --------------------------------------------------------------------
// Split `var = Tuple(...,)` into `varN = ...` if the tuple isn't used by
-// value.
+// value (nor borrowed).
+//
+// NOTE: The "nor borrowed" rule is needed to avoid issues when the first element of a tuple
+// is used as a proxy for the entire tuple.
// --------------------------------------------------------------------
bool MIR_Optimise_SplitAggregates(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
@@ -3476,6 +3479,18 @@ bool MIR_Optimise_SplitAggregates(::MIR::TypeResolve& state, ::MIR::Function& fc
auto it = potentials.find(lv.as_Local());
if( it != potentials.end() )
{
+ DEBUG(lv << " invalidated due to root usage");
+ potentials.erase(it);
+ }
+ }
+ // If the variable is borrowed (even via wrappers)
+ // TODO: Restrict this to when the borrow is just via field accesses
+ if( lv.m_root.is_Local() && vu == ValUsage::Borrow )
+ {
+ auto it = potentials.find(lv.m_root.as_Local());
+ if( it != potentials.end() )
+ {
+ DEBUG(lv << " invalidate due to any borrow");
potentials.erase(it);
}
}