summaryrefslogtreecommitdiff
path: root/src/mir/helpers.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-05-15 13:24:33 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-05-15 13:24:33 +0800
commit5fe20088ff99be255116407a3abefd0357a62902 (patch)
treef27fb8c8f4b58be4ea44f5000ae122860206420a /src/mir/helpers.cpp
parent9e2a6a73c9cb629e1143691885e48eb9b0fb2119 (diff)
downloadmrust-5fe20088ff99be255116407a3abefd0357a62902.tar.gz
MIR - Handle Union field access
Diffstat (limited to 'src/mir/helpers.cpp')
-rw-r--r--src/mir/helpers.cpp70
1 files changed, 46 insertions, 24 deletions
diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp
index 9242ccb7..c38e73e9 100644
--- a/src/mir/helpers.cpp
+++ b/src/mir/helpers.cpp
@@ -106,31 +106,53 @@ const ::HIR::TypeRef& ::MIR::TypeResolve::get_lvalue_type(::HIR::TypeRef& tmp, c
return te[e.field_index];
),
(Path,
- MIR_ASSERT(*this, te.binding.is_Struct(), "Field on non-Struct - " << ty);
- const auto& str = *te.binding.as_Struct();
- auto monomorph = [&](const auto& ty)->const auto& {
- if( monomorphise_type_needed(ty) ) {
- tmp = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, ty);
- m_resolve.expand_associated_types(sp, tmp);
- return tmp;
- }
- else {
- return ty;
- }
- };
- TU_MATCHA( (str.m_data), (se),
- (Unit,
- MIR_BUG(*this, "Field on unit-like struct - " << ty);
- ),
- (Tuple,
- MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in tuple-struct " << te.path);
- return monomorph(se[e.field_index].ent);
- ),
- (Named,
- MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in struct " << te.path);
- return monomorph(se[e.field_index].second.ent);
+ if( const auto* tep = te.binding.opt_Struct() )
+ {
+ const auto& str = **tep;
+ auto monomorph = [&](const auto& ty)->const auto& {
+ if( monomorphise_type_needed(ty) ) {
+ tmp = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, ty);
+ m_resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ }
+ else {
+ return ty;
+ }
+ };
+ TU_MATCHA( (str.m_data), (se),
+ (Unit,
+ MIR_BUG(*this, "Field on unit-like struct - " << ty);
+ ),
+ (Tuple,
+ MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in tuple-struct " << te.path);
+ return monomorph(se[e.field_index].ent);
+ ),
+ (Named,
+ MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in struct " << te.path);
+ return monomorph(se[e.field_index].second.ent);
+ )
)
- )
+ }
+ else if( const auto* tep = te.binding.opt_Union() )
+ {
+ 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;
+ }
+ };
+ MIR_ASSERT(*this, e.field_index < unm.m_variants.size(), "Field index out of range for union");
+ return maybe_monomorph(unm.m_variants.at(e.field_index).second.ent);
+ }
+ else
+ {
+ MIR_BUG(*this, "Field access on invalid type - " << ty);
+ }
)
)
),