diff options
-rw-r--r-- | src/hir/type.cpp | 14 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 44 |
2 files changed, 49 insertions, 9 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp index de60dcb1..8166118f 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -2,6 +2,7 @@ */ #include "type.hpp" #include <span.hpp> +#include "expr.hpp" namespace HIR { @@ -692,13 +693,22 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x return ::HIR::TypeRef( Data::make_TraitObject( mv$(rv) ) ); ), (Array, + unsigned int size_val = e.size_val; if( e.size_val == ~0u ) { - BUG(Span(), "Attempting to clone array with unknown size - " << *this); + // TODO: Need to invoke const eval here? Or support cloning expressions? Or run consteval earlier. + if( const auto* ptr = dynamic_cast<const ::HIR::ExprNode_Literal*>(&*e.size) ) + { + size_val = ptr->m_data.as_Integer().m_value; + } + else + { + BUG(Span(), "Attempting to clone array with unknown size - " << *this); + } } return ::HIR::TypeRef( Data::make_Array({ box$( e.inner->clone() ), ::HIR::ExprPtr(), - e.size_val + size_val }) ); ), (Slice, diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 1d1349f5..6ecbfbc7 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -421,7 +421,16 @@ namespace { } void visit(::HIR::ExprNode_TupleVariant& node) override { - TODO(node.span(), "ExprNode_TupleVariant"); + if( ! node.m_is_struct ) { + TODO(node.span(), "_TupleVariant - Enum"); + } + ::std::vector< ::HIR::Literal> vals; + for(const auto& vn : node.m_args ) { + vn->visit(*this); + assert( !m_rv.is_Invalid() ); + vals.push_back( mv$(m_rv) ); + } + m_rv = ::HIR::Literal::make_List(mv$(vals)); } void visit(::HIR::ExprNode_CallPath& node) override { TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv); @@ -583,7 +592,23 @@ namespace { m_rv = ::HIR::Literal::make_List(mv$(vals)); } void visit(::HIR::ExprNode_ArraySized& node) override { - TODO(node.span(), "ExprNode_ArraySized"); + node.m_size->visit(*this); + assert( m_rv.is_Integer() ); + unsigned int count = static_cast<unsigned int>(m_rv.as_Integer()); + + ::std::vector< ::HIR::Literal> vals; + vals.reserve( count ); + if( count > 0 ) + { + node.m_val->visit(*this); + assert( !m_rv.is_Invalid() ); + for(unsigned int i = 0; i < count-1; i ++) + { + vals.push_back( clone_literal(m_rv) ); + } + vals.push_back( mv$(m_rv) ); + } + m_rv = ::HIR::Literal::make_List(mv$(vals)); } void visit(::HIR::ExprNode_Closure& node) override { @@ -851,11 +876,14 @@ namespace { { TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e, ::HIR::Visitor::visit_type(*e.inner); - assert(e.size.get() != nullptr); - auto val = evaluate_constant(e.size->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT("ty_" << &ty << "$") }, e.size); - if( !val.is_Integer() ) - ERROR(e.size->span(), E0000, "Array size isn't an integer"); - e.size_val = val.as_Integer(); + if( e.size_val == ~0u ) + { + assert(e.size.get() != nullptr); + auto val = evaluate_constant(e.size->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT("ty_" << &ty << "$") }, e.size); + if( !val.is_Integer() ) + ERROR(e.size->span(), E0000, "Array size isn't an integer"); + e.size_val = val.as_Integer(); + } DEBUG("Array " << ty << " - size = " << e.size_val); ) else { @@ -867,12 +895,14 @@ namespace { visit_type(item.m_type); item.m_value_res = evaluate_constant(item.m_value->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$") }, item.m_value, {}); DEBUG("constant: " << item.m_type << " = " << item.m_value_res); + visit_expr(item.m_value); } void visit_static(::HIR::ItemPath p, ::HIR::Static& item) override { visit_type(item.m_type); item.m_value_res = evaluate_constant(item.m_value->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$") }, item.m_value, {}); DEBUG("static: " << item.m_type << " = " << item.m_value_res); + visit_expr(item.m_value); } void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override { for(auto& var : item.m_variants) |