diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-20 09:26:13 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-20 09:26:13 +0800 |
commit | a6aae2e4413789e548a30fd9cb421cc2f6964b14 (patch) | |
tree | a6872cea76eaea7fe24e4c11ac5eb9b42482a3c4 /src | |
parent | ad7c16cd3664a79c09e00a76ae4e081aadd88493 (diff) | |
download | mrust-a6aae2e4413789e548a30fd9cb421cc2f6964b14.tar.gz |
MIR - Union support hacked up
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 19 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 5 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 3 | ||||
-rw-r--r-- | src/mir/check.cpp | 80 | ||||
-rw-r--r-- | src/mir/dump.cpp | 5 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 13 | ||||
-rw-r--r-- | src/mir/mir.cpp | 3 | ||||
-rw-r--r-- | src/mir/mir.hpp | 19 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 3 |
9 files changed, 114 insertions, 36 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 5eeffdb9..e1939d6d 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -368,6 +368,11 @@ namespace { _(Array, { deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); }) }) + _(Variant, { + deserialise_genericpath(), + static_cast<unsigned int>( m_in.read_count() ), + deserialise_mir_lvalue() + }) _(Struct, { deserialise_genericpath(), deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); }) @@ -419,6 +424,8 @@ namespace { return ::HIR::TypeItem( deserialise_struct() ); case 5: return ::HIR::TypeItem( deserialise_trait() ); + case 6: + return ::HIR::TypeItem( deserialise_union() ); default: throw ""; } @@ -506,6 +513,7 @@ namespace { ::HIR::Enum::Variant deserialise_enumvariant(); ::HIR::Struct deserialise_struct(); + ::HIR::Union deserialise_union(); ::HIR::Trait deserialise_trait(); ::HIR::TraitValueItem deserialise_traitvalueitem() @@ -765,6 +773,17 @@ namespace { throw ""; } } + ::HIR::Union HirDeserialiser::deserialise_union() + { + TRACE_FUNCTION; + auto params = deserialise_genericparams(); + auto repr = static_cast< ::HIR::Union::Repr>( m_in.read_tag() ); + + return ::HIR::Union { + mv$(params), repr, + deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() + }; + } ::HIR::Struct HirDeserialiser::deserialise_struct() { TRACE_FUNCTION; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 4cb2771a..ea4dfabf 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -572,6 +572,11 @@ namespace { (Array, serialise_vec(e.vals); ), + (Variant, + serialise_genericpath(e.path); + m_out.write_count(e.index); + serialise(e.val); + ), (Struct, serialise_genericpath(e.path); serialise_vec(e.vals); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 8d93ced1..bd1e740a 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -1136,6 +1136,9 @@ namespace { vals.push_back( read_lval(v) ); val = ::HIR::Literal::make_List( mv$(vals) ); ), + (Variant, + TODO(sp, "MIR _Variant"); + ), (Struct, ::std::vector< ::HIR::Literal> vals; vals.reserve( e.vals.size() ); 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 ) diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index fe1e16f1..967bc98d 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -376,6 +376,11 @@ namespace { } os << "]"; ), + (Variant, + os << e.path << " #" << e.index << " ("; + fmt_val(os, e.val); + os << ")"; + ), (Struct, os << e.path << " { "; for(const auto& v : e.vals) { diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 0dda293b..bccbdb13 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1721,12 +1721,21 @@ namespace { } void visit(::HIR::ExprNode_UnionLiteral& node) override { + TRACE_FUNCTION_F("_UnionLiteral " << node.m_path); this->visit_node_ptr(node.m_value); auto val = m_builder.get_result_in_lvalue(node.m_value->span(), node.m_value->m_res_type); - // TODO: Need a way of initialising just this "variant" - TODO(node.span(), "_UnionLiteral"); + const auto& unm = *node.m_res_type.m_data.as_Path().binding.as_Union(); + auto it = ::std::find_if(unm.m_variants.begin(), unm.m_variants.end(), [&](const auto&v)->auto{ return v.first == node.m_variant_name; }); + assert(it != unm.m_variants.end()); + unsigned int idx = it - unm.m_variants.begin(); + + m_builder.set_result( node.span(), ::MIR::RValue::make_Variant({ + node.m_path.clone(), + idx, + mv$(val) + }) ); } void visit(::HIR::ExprNode_Tuple& node) override diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index f65c7616..0517111a 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -114,6 +114,9 @@ namespace MIR { (Array, os << "Array(" << e.vals << ")"; ), + (Variant, + os << "Variant(" << e.path << " #" << e.index << ", " << e.val << ")"; + ), (Struct, os << "Struct(" << e.path << ", {" << e.vals << "})"; ) diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index c0c94807..c0ee0d21 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -109,22 +109,28 @@ TAGGED_UNION(RValue, Use, ::HIR::BorrowType type; LValue val; }), + // Cast on primitives (Cast, struct { LValue val; ::HIR::TypeRef type; }), + // Binary operation on primitives (BinOp, struct { LValue val_l; eBinOp op; LValue val_r; }), + // Unary operation on primitives (UniOp, struct { LValue val; eUniOp op; }), + // Extract the metadata from a DST pointer + // NOTE: If used on an array, this yields the array size (for generics) (DstMeta, struct { LValue val; }), + // Construct a DST pointer from a thin pointer and metadata (MakeDst, struct { LValue ptr_val; LValue meta_val; @@ -132,14 +138,17 @@ TAGGED_UNION(RValue, Use, (Tuple, struct { ::std::vector<LValue> vals; }), + // Array literal (Array, struct { ::std::vector<LValue> vals; }), - //(Variant, struct { - // ::HIR::GenericPath path; - // unsigned int index; - // LValue val; - // }), + // Create a new instance of a union (and eventually enum) + (Variant, struct { + ::HIR::GenericPath path; + unsigned int index; + LValue val; + }), + // Create a new instance of a struct (or enum) (Struct, struct { ::HIR::GenericPath path; ::std::vector<LValue> vals; diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index a64867b1..73867918 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -238,6 +238,9 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal for(const auto& val : e.vals) this->moved_lvalue(sp, val); ), + (Variant, + this->moved_lvalue(sp, e.val); + ), (Struct, for(const auto& val : e.vals) this->moved_lvalue(sp, val); |