summaryrefslogtreecommitdiff
path: root/src/mir/check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir/check.cpp')
-rw-r--r--src/mir/check.cpp80
1 files changed, 51 insertions, 29 deletions
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index 8833df09..80909902 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -208,36 +208,55 @@ namespace {
MIR_BUG(*this, "Downcast on unexpected type - " << ty);
),
(Path,
- MIR_ASSERT(*this, te.binding.is_Enum(), "Downcast on non-Enum");
- const auto& enm = *te.binding.as_Enum();
- const auto& variants = enm.m_variants;
- MIR_ASSERT(*this, e.variant_index < variants.size(), "Variant index out of range");
- const auto& variant = variants[e.variant_index];
- // TODO: Make data variants refer to associated types (unify enum and struct handling)
- TU_MATCHA( (variant.second), (ve),
- (Value,
- ),
- (Unit,
- ),
- (Tuple,
- // HACK! Create tuple.
- ::std::vector< ::HIR::TypeRef> tys;
- for(const auto& fld : ve)
- tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.ent) );
- tmp = ::HIR::TypeRef( mv$(tys) );
- this->resolve.expand_associated_types(sp, tmp);
- return tmp;
- ),
- (Struct,
- // HACK! Create tuple.
- ::std::vector< ::HIR::TypeRef> tys;
- for(const auto& fld : ve)
- tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.second.ent) );
- tmp = ::HIR::TypeRef( mv$(tys) );
- this->resolve.expand_associated_types(sp, tmp);
- return tmp;
+ MIR_ASSERT(*this, te.binding.is_Enum() || te.binding.is_Union(), "Downcast on non-Enum");
+ if( te.binding.is_Enum() )
+ {
+ const auto& enm = *te.binding.as_Enum();
+ const auto& variants = enm.m_variants;
+ MIR_ASSERT(*this, e.variant_index < variants.size(), "Variant index out of range");
+ const auto& variant = variants[e.variant_index];
+ // TODO: Make data variants refer to associated types (unify enum and struct handling)
+ TU_MATCHA( (variant.second), (ve),
+ (Value,
+ ),
+ (Unit,
+ ),
+ (Tuple,
+ // HACK! Create tuple.
+ ::std::vector< ::HIR::TypeRef> tys;
+ for(const auto& fld : ve)
+ tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.ent) );
+ tmp = ::HIR::TypeRef( mv$(tys) );
+ this->resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ ),
+ (Struct,
+ // HACK! Create tuple.
+ ::std::vector< ::HIR::TypeRef> tys;
+ for(const auto& fld : ve)
+ tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.second.ent) );
+ tmp = ::HIR::TypeRef( mv$(tys) );
+ this->resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ )
)
- )
+ }
+ else
+ {
+ const auto& unm = *te.binding.as_Union();
+ MIR_ASSERT(*this, e.variant_index < unm.m_variants.size(), "Variant index out of range");
+ const auto& variant = unm.m_variants[e.variant_index];
+ const auto& var_ty = variant.second.ent;
+
+ if( monomorphise_type_needed(var_ty) ) {
+ tmp = monomorphise_type(sp, unm.m_params, te.path.m_data.as_Generic().m_params, variant.second.ent);
+ this->resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ }
+ else {
+ return var_ty;
+ }
+ }
)
)
)
@@ -505,6 +524,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
(Array,
// TODO: Check return type
),
+ (Variant,
+ // TODO: Check return type
+ ),
(Struct,
// TODO: Check return type
)