diff options
author | John Hodge <tpg@mutabah.net> | 2016-10-30 10:01:54 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-10-30 10:01:54 +0800 |
commit | 94504cac4d8900cd5c15e236f7f59ade89479bf4 (patch) | |
tree | 79629802c0d602b861d083a5109cb63939bb6c95 | |
parent | 38dbb9be89c0ee0acff26bf80c677691bdcadaf8 (diff) | |
download | mrust-94504cac4d8900cd5c15e236f7f59ade89479bf4.tar.gz |
HIR Const Eval - Field accesses in constants (requires type info)
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index b3e1cc9d..df9a66db 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -67,6 +67,7 @@ namespace { TAGGED_UNION(EntPtr, NotFound, (NotFound, struct{}), (Function, const ::HIR::Function*), + (Static, const ::HIR::Static*), (Constant, const ::HIR::Constant*), (Struct, const ::HIR::Struct*) ); @@ -124,6 +125,7 @@ namespace { return EntPtr { &e }; ), (Static, + return EntPtr { &e }; ) ) BUG(sp, "Path " << path << " pointed to a invalid item - " << it->second->ent.tag_str()); @@ -254,7 +256,7 @@ namespace { ::std::vector< ::HIR::Literal> m_values; - ::HIR::TypeRef m_exp_type; + ::HIR::TypeRef m_rv_type; ::HIR::Literal m_rv; Visitor(const ::HIR::Crate& crate, NewvalState newval_state): @@ -307,6 +309,7 @@ namespace { ERROR(node.span(), E0000, "ExprNode_BinOp - Types mismatched - " << left.tag_str() << " != " << right.tag_str()); } + // Keep m_rv_type switch(node.m_op) { case ::HIR::ExprNode_BinOp::Op::CmpEqu: @@ -399,6 +402,7 @@ namespace { node.m_value->visit(*this); auto val = mv$(m_rv); + // Keep m_rv_type switch(node.m_op) { case ::HIR::ExprNode_UniOp::Op::Invert: @@ -418,8 +422,6 @@ namespace { } } void visit(::HIR::ExprNode_Borrow& node) override { - //auto ty = m_exp_type; - node.m_value->visit(*this); auto val = mv$(m_rv); @@ -427,6 +429,7 @@ namespace { ERROR(node.span(), E0000, "Only shared borrows are allowed in constants"); } + m_rv_type = ::HIR::TypeRef::new_borrow( node.m_type, mv$(m_rv_type) ); // Create new static containing borrowed data auto name = FMT(m_newval_state.name_prefix << &node); m_newval_state.newval_output.push_back(::std::make_pair( name, ::HIR::Static { @@ -442,12 +445,14 @@ namespace { node.m_value->visit(*this); //auto val = mv$(m_rv); //DEBUG("ExprNode_Cast - val = " << val << " as " << node.m_type); + m_rv_type = node.m_res_type.clone(); } void visit(::HIR::ExprNode_Unsize& node) override { TRACE_FUNCTION_F("_Unsize"); node.m_value->visit(*this); //auto val = mv$(m_rv); //DEBUG("ExprNode_Unsize - val = " << val << " as " << node.m_type); + m_rv_type = node.m_res_type.clone(); } void visit(::HIR::ExprNode_Index& node) override { // Index @@ -466,6 +471,16 @@ namespace { if( idx >= v.size() ) ERROR(node.span(), E0000, "Constant array index " << idx << " out of range " << v.size()); m_rv = mv$(v[idx]); + + TU_MATCH_DEF( ::HIR::TypeRef::Data, (m_rv_type.m_data), (e), + ( + ERROR(node.span(), E0000, "Indexing non-array - " << m_rv_type); + ), + (Array, + auto tmp = mv$(e.inner); + m_rv_type = mv$(*tmp); + ) + ) } void visit(::HIR::ExprNode_Deref& node) override { badnode(node); @@ -487,9 +502,10 @@ namespace { { const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path); ASSERT_BUG(node.span(), ent.is_Struct(), "_TupleVariant with m_is_struct set pointing to " << ent.tag_str()); - //const auto& str = ent.as_Struct(); + const auto& str = ent.as_Struct(); m_rv = ::HIR::Literal::make_List(mv$(vals)); + m_rv_type = ::HIR::TypeRef::new_path( node.m_path.clone(), ::HIR::TypeRef::TypePathBinding(&str) ); } else { @@ -505,6 +521,7 @@ namespace { unsigned int var_idx = it - enm.m_variants.begin(); m_rv = ::HIR::Literal::make_Variant({var_idx, mv$(vals)}); + m_rv_type = ::HIR::TypeRef::new_path( mv$(tmp_path), ::HIR::TypeRef::TypePathBinding(&enm) ); } } void visit(::HIR::ExprNode_CallPath& node) override { @@ -546,7 +563,29 @@ namespace { badnode(node); } void visit(::HIR::ExprNode_Field& node) override { - badnode(node); + const auto& sp = node.span(); + TRACE_FUNCTION_FR("_Field", m_rv); + + node.m_value->visit(*this); + auto val = mv$( m_rv ); + + if( !val.is_List() ) + ERROR(sp, E0000, "Field access on invalid literal type - " << val.tag_str()); + auto& vals = val.as_List(); + + TU_MATCH_DEF( ::HIR::TypeRef::Data, (m_rv_type.m_data), (e), + ( + ERROR(sp, E0000, "Field access on invalid type - " << m_rv_type); + ), + (Tuple, + unsigned int idx = ::std::atoi( node.m_field.c_str() ); + ASSERT_BUG(sp, idx < e.size(), "Index out of range in tuple"); + ASSERT_BUG(sp, idx < vals.size(), "Index out of range in literal"); + + m_rv = mv$( vals[idx] ); + m_rv_type = mv$( e[idx] ); + ) + ) } void visit(::HIR::ExprNode_Literal& node) override { @@ -568,15 +607,17 @@ namespace { m_rv = ::HIR::Literal::make_String({e.begin(), e.end()}); ) ) + m_rv_type = node.m_res_type.clone(); } void visit(::HIR::ExprNode_UnitVariant& node) override { if( node.m_is_struct ) { const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path); ASSERT_BUG(node.span(), ent.is_Struct(), "_UnitVariant with m_is_struct set pointing to " << ent.tag_str()); - //const auto& str = ent.as_Struct(); + const auto& str = ent.as_Struct(); m_rv = ::HIR::Literal::make_List({}); + m_rv_type = ::HIR::TypeRef::new_path( node.m_path.clone(), ::HIR::TypeRef::TypePathBinding(&str) ); } else { @@ -592,6 +633,7 @@ namespace { unsigned int var_idx = it - enm.m_variants.begin(); m_rv = ::HIR::Literal::make_Variant({var_idx, {}}); + m_rv_type = ::HIR::TypeRef::new_path( mv$(tmp_path), ::HIR::TypeRef::TypePathBinding(&enm) ); } } void visit(::HIR::ExprNode_PathValue& node) override { @@ -601,10 +643,17 @@ namespace { ( BUG(node.span(), "Path value with unsupported value type - " << ep.tag_str()); ), + (Static, + // TODO: Should be a more complex path to support associated paths + ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "Static path not Path::Generic - " << node.m_path); + m_rv = ::HIR::Literal(node.m_path.m_data.as_Generic().m_path); + m_rv_type = e->m_type.clone(); + ), (Function, // TODO: Should be a more complex path to support associated paths ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "Function path not Path::Generic - " << node.m_path); m_rv = ::HIR::Literal(node.m_path.m_data.as_Generic().m_path); + m_rv_type = ::HIR::TypeRef(); // TODO: Better type ), (Constant, // TODO: Associated constants @@ -615,6 +664,7 @@ namespace { else { m_rv = clone_literal(c.m_value_res); } + m_rv_type = e->m_type.clone(); ) ) } @@ -636,15 +686,17 @@ namespace { m_rv = ::HIR::Literal(e); ) ) + m_rv_type = ::HIR::TypeRef(); // TODO: } void visit(::HIR::ExprNode_StructLiteral& node) override { TRACE_FUNCTION_FR("_StructLiteral - " << node.m_path, m_rv); - // TODO: Fix for enums - see _UnitVariant and _TupleVariant - const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path); - TU_IFLET( ::HIR::TypeItem, ent, Struct, str, - ASSERT_BUG(node.span(), node.m_is_struct, "_StructLiteral with m_is_struct clear pointing to a struct"); + if( node.m_is_struct ) + { + const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path); + ASSERT_BUG(node.span(), ent.is_Struct(), "_StructLiteral with m_is_struct set pointing to a " << ent.tag_str()); + const auto& str = ent.as_Struct(); const auto& fields = str.m_data.as_Named(); ::std::vector< ::HIR::Literal> vals; @@ -675,23 +727,27 @@ namespace { } m_rv = ::HIR::Literal::make_List(mv$(vals)); - ) - else TU_IFLET( ::HIR::TypeItem, ent, Enum, enm, - ASSERT_BUG(node.span(), !node.m_is_struct, "_StructLiteral with m_is_struct set pointing to an enum"); + m_rv_type = ::HIR::TypeRef::new_path( node.m_path.clone(), ::HIR::TypeRef::TypePathBinding(&str) ); + } + else + { + const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path); + ASSERT_BUG(node.span(), ent.is_Enum(), "_StructLiteral with m_is_struct clear pointing to a " << ent.tag_str()); + TODO(node.span(), "Handle Enum _UnitVariant - " << node.m_path); - ) - else { - BUG(node.span(), "Could not find struct/enum for " << node.m_path << " - " << ent.tag_str()); } } void visit(::HIR::ExprNode_Tuple& node) override { ::std::vector< ::HIR::Literal> vals; + ::std::vector< ::HIR::TypeRef> tys; for(const auto& vn : node.m_vals ) { vn->visit(*this); assert( !m_rv.is_Invalid() ); vals.push_back( mv$(m_rv) ); + tys.push_back( mv$(m_rv_type) ); } m_rv = ::HIR::Literal::make_List(mv$(vals)); + m_rv_type = ::HIR::TypeRef( mv$(tys) ); } void visit(::HIR::ExprNode_ArrayList& node) override { ::std::vector< ::HIR::Literal> vals; @@ -701,6 +757,7 @@ namespace { vals.push_back( mv$(m_rv) ); } m_rv = ::HIR::Literal::make_List(mv$(vals)); + m_rv_type = ::HIR::TypeRef::new_array( mv$(m_rv_type), vals.size() ); } void visit(::HIR::ExprNode_ArraySized& node) override { node.m_size->visit(*this); @@ -720,6 +777,7 @@ namespace { vals.push_back( mv$(m_rv) ); } m_rv = ::HIR::Literal::make_List(mv$(vals)); + m_rv_type = ::HIR::TypeRef::new_array( mv$(m_rv_type), count ); } void visit(::HIR::ExprNode_Closure& node) override { |