summaryrefslogtreecommitdiff
path: root/src/mir/mir_builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir/mir_builder.cpp')
-rw-r--r--src/mir/mir_builder.cpp92
1 files changed, 60 insertions, 32 deletions
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 8cb8c088..478146e8 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -814,6 +814,7 @@ void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cl
drop_scope_values(scope_def);
// Emit ScopeEnd for all controlled values
+ #if 0
::MIR::Statement::Data_ScopeEnd se;
if(const auto* e = scope_def.data.opt_Variables() ) {
se.vars = e->vars;
@@ -827,6 +828,7 @@ void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cl
if( !se.vars.empty() || !se.tmps.empty() ) {
this->push_stmt(sp, ::MIR::Statement( mv$(se) ));
}
+ #endif
}
// 3. Pop scope (last because `drop_scope_values` uses the stack)
@@ -1638,39 +1640,59 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::
cb( *te.inner );
),
(Path,
- ASSERT_BUG(sp, te.binding.is_Struct(), "Field on non-Struct - " << ty);
- const auto& str = *te.binding.as_Struct();
- TU_MATCHA( (str.m_data), (se),
- (Unit,
- BUG(sp, "Field on unit-like struct - " << ty);
- ),
- (Tuple,
- ASSERT_BUG(sp, e.field_index < se.size(),
- "Field index out of range in tuple-struct " << ty << " - " << e.field_index << " > " << se.size());
- const auto& fld = se[e.field_index];
- if( monomorphise_type_needed(fld.ent) ) {
- auto sty = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, fld.ent);
- m_resolve.expand_associated_types(sp, sty);
- cb(sty);
- }
- else {
- cb(fld.ent);
- }
- ),
- (Named,
- ASSERT_BUG(sp, e.field_index < se.size(),
- "Field index out of range in struct " << ty << " - " << e.field_index << " > " << se.size());
- const auto& fld = se[e.field_index].second;
- if( monomorphise_type_needed(fld.ent) ) {
- auto sty = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, fld.ent);
- m_resolve.expand_associated_types(sp, sty);
- cb(sty);
- }
- else {
- cb(fld.ent);
- }
+ ::HIR::TypeRef tmp;
+ if( const auto* tep = te.binding.opt_Struct() )
+ {
+ const auto& str = **tep;
+ auto maybe_monomorph = [&](const ::HIR::TypeRef& t)->const ::HIR::TypeRef& {
+ if( monomorphise_type_needed(t) ) {
+ tmp = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, t);
+ m_resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ }
+ else {
+ return t;
+ }
+ };
+ TU_MATCHA( (str.m_data), (se),
+ (Unit,
+ BUG(sp, "Field on unit-like struct - " << ty);
+ ),
+ (Tuple,
+ ASSERT_BUG(sp, e.field_index < se.size(),
+ "Field index out of range in tuple-struct " << ty << " - " << e.field_index << " > " << se.size());
+ const auto& fld = se[e.field_index];
+ cb( maybe_monomorph(fld.ent) );
+ ),
+ (Named,
+ ASSERT_BUG(sp, e.field_index < se.size(),
+ "Field index out of range in struct " << ty << " - " << e.field_index << " > " << se.size());
+ const auto& fld = se[e.field_index].second;
+ cb( maybe_monomorph(fld.ent) );
+ )
)
- )
+ }
+ else if( const auto* tep = te.binding.opt_Union() )
+ {
+ BUG(sp, "Field access on a union isn't valid, use Downcast instead - " << ty);
+ const auto& unm = **tep;
+ auto maybe_monomorph = [&](const ::HIR::TypeRef& t)->const ::HIR::TypeRef& {
+ if( monomorphise_type_needed(t) ) {
+ tmp = monomorphise_type(sp, unm.m_params, te.path.m_data.as_Generic().m_params, t);
+ m_resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ }
+ else {
+ return t;
+ }
+ };
+ ASSERT_BUG(sp, e.field_index < unm.m_variants.size(), "Field index out of range for union");
+ cb( maybe_monomorph(unm.m_variants.at(e.field_index).second.ent) );
+ }
+ else
+ {
+ BUG(sp, "Field acess on unexpected type - " << ty);
+ }
),
(Tuple,
ASSERT_BUG(sp, e.field_index < te.size(), "Field index out of range in tuple " << e.field_index << " >= " << te.size());
@@ -2196,8 +2218,10 @@ void MirBuilder::drop_value_from_state(const Span& sp, const VarState& vs, ::MIR
),
(Partial,
bool is_enum = false;
+ bool is_union = false;
with_val_type(sp, lv, [&](const auto& ty){
is_enum = ty.m_data.is_Path() && ty.m_data.as_Path().binding.is_Enum();
+ is_union = ty.m_data.is_Path() && ty.m_data.as_Path().binding.is_Union();
});
if(is_enum)
{
@@ -2207,6 +2231,10 @@ void MirBuilder::drop_value_from_state(const Span& sp, const VarState& vs, ::MIR
// drop_value_from_state(sp, vse.inner_states[i], ::MIR::LValue::make_Downcast({ box$(lv.clone()), static_cast<unsigned int>(i) }));
//}
}
+ else if( is_union )
+ {
+ // NOTE: Unions don't drop inner items.
+ }
else
{
for(size_t i = 0; i < vse.inner_states.size(); i ++)