diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-21 17:35:44 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-21 17:35:44 +0800 |
commit | d28ef52c6424d04662bf4070d263b2bd10e132a0 (patch) | |
tree | 3b8118e8a900736ddeed91874a31a930b2bb2d13 /src/mir/mir_builder.cpp | |
parent | 18be0631d249ed11a1ee433cfb39583dcc342687 (diff) | |
download | mrust-d28ef52c6424d04662bf4070d263b2bd10e132a0.tar.gz |
MIR Gen - Include Copy checking
Diffstat (limited to 'src/mir/mir_builder.cpp')
-rw-r--r-- | src/mir/mir_builder.cpp | 106 |
1 files changed, 101 insertions, 5 deletions
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index f3b9c263..893dcffa 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -11,7 +11,8 @@ // -------------------------------------------------------------------- // MirBuilder // -------------------------------------------------------------------- -MirBuilder::MirBuilder(::MIR::Function& output): +MirBuilder::MirBuilder(const StaticTraitResolve& resolve, ::MIR::Function& output): + m_resolve(resolve), m_output(output), m_block_active(false), m_result_valid(false), @@ -208,10 +209,10 @@ void MirBuilder::push_stmt_assign(::MIR::LValue dst, ::MIR::RValue val) break; case VarState::Moved: case VarState::MaybeMoved: - // ERROR? + // ERROR? Temporaries shouldn't be resassigned after becoming valid break; case VarState::Init: - // ERROR. + // ERROR. Temporaries are single-assignment break; } set_temp_state(e.idx, VarState::Init); @@ -227,11 +228,11 @@ void MirBuilder::push_stmt_assign(::MIR::LValue dst, ::MIR::RValue val) case VarState::Moved: break; case VarState::Dropped: - // TODO: Is this an error? + // TODO: Is this an error? The variable has descoped. break; case VarState::Init: // 1. Must be mut - // 2. Drop + // 2. Drop (if not Copy) push_stmt_drop( dst.clone() ); break; case VarState::MaybeMoved: @@ -247,6 +248,12 @@ void MirBuilder::push_stmt_drop(::MIR::LValue val) { ASSERT_BUG(Span(), m_block_active, "Pushing statement with no active block"); ASSERT_BUG(Span(), val.tag() != ::MIR::LValue::TAGDEAD, ""); + + if( lvalue_is_copy(val) ) { + // Don't emit a drop for Copy values + return ; + } + m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val) }) ); } @@ -448,6 +455,95 @@ void MirBuilder::complete_scope(ScopeDef& sd) ) } +void MirBuilder::with_val_type(const ::MIR::LValue& val, ::std::function<void(const ::HIR::TypeRef&)> cb) +{ + Span sp; + TU_MATCH(::MIR::LValue, (val), (e), + (Variable, + cb( m_output.named_variables.at(e) ); + ), + (Temporary, + cb( m_output.temporaries.at(e.idx) ); + ), + (Argument, + TODO(sp, "Argument"); + ), + (Static, + TODO(sp, "Static"); + ), + (Return, + TODO(sp, "Return"); + ), + (Field, + with_val_type(*e.val, [&](const auto& ty){ + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), + ( + BUG(sp, ""); + ), + (Path, + TODO(sp, "Field - Path"); + ), + (Tuple, + assert( e.field_index < te.size() ); + cb( te[e.field_index] ); + ) + ) + }); + ), + (Deref, + with_val_type(*e.val, [&](const auto& ty){ + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), + ( + BUG(sp, ""); + ), + (Pointer, + cb(*te.inner); + ), + (Borrow, + cb(*te.inner); + ) + ) + }); + ), + (Index, + with_val_type(*e.val, [&](const auto& ty){ + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), + ( + BUG(sp, ""); + ), + (Slice, + cb(*te.inner); + ), + (Array, + cb(*te.inner); + ) + ) + }); + ), + (Downcast, + with_val_type(*e.val, [&](const auto& ty){ + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), + ( + BUG(sp, ""); + ), + (Path, + TODO(sp, "Downcast - Path"); + ) + ) + }); + ) + ) +} + +bool MirBuilder::lvalue_is_copy(const ::MIR::LValue& val) +{ + int rv = 0; + with_val_type(val, [&](const auto& ty){ + rv = (m_resolve.type_is_copy(ty) ? 2 : 1); + }); + assert(rv != 0); + return rv == 2; +} VarState MirBuilder::get_variable_state(unsigned int idx) const { |