summaryrefslogtreecommitdiff
path: root/src/hir_conv/constant_evaluation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/hir_conv/constant_evaluation.cpp')
-rw-r--r--src/hir_conv/constant_evaluation.cpp76
1 files changed, 60 insertions, 16 deletions
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 5a41e954..a2847e04 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -48,7 +48,7 @@ namespace {
}
};
- ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={});
+ ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={});
::HIR::Literal clone_literal(const ::HIR::Literal& v)
{
@@ -245,7 +245,26 @@ namespace {
}
}
- ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args)
+ ::HIR::Literal evaluate_constant_intrinsic(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::std::string& name, const ::HIR::PathParams& params, ::std::vector< ::HIR::Literal> args)
+ {
+ TRACE_FUNCTION_F("\"" << name << "\"" << params << " " << args);
+ if( name == "size_of" ) {
+ ASSERT_BUG(sp, params.m_types.size() == 1, "size_of intrinsic takes one type param (consteval)");
+ const auto& ty = params.m_types[0];
+
+ size_t size;
+ if( !Target_GetSizeOf(sp, StaticTraitResolve { crate }, ty, size) )
+ {
+ TODO(sp, "Handle error from Target_GetSizeOf(" << ty << ") in evaluate_constant_intrinsic");
+ }
+ return ::HIR::Literal::make_Integer(size);
+ }
+ else {
+ TODO(sp, "name=" << name << params << " args=" << args);
+ }
+ }
+
+ ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args)
{
// TODO: Force this function/tree through the entire pipeline so we can MIR it?
// - Requires a HUGE change to the way the compiler operates.
@@ -260,6 +279,7 @@ namespace {
::HIR::TypeRef m_exp_type;
::HIR::TypeRef m_rv_type;
::HIR::Literal m_rv;
+ t_cb_generic m_monomorph_cb;
Visitor(const ::HIR::Crate& crate, NewvalState newval_state, ::HIR::TypeRef exp_ty):
m_crate(crate),
@@ -613,7 +633,7 @@ namespace {
}
void visit(::HIR::ExprNode_CallPath& node) override
{
-
+ const auto& sp = node.span();
TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv);
auto& fcn = get_function(node.span(), m_crate, node.m_path);
@@ -651,10 +671,27 @@ namespace {
exp_ret_type = fcn.m_return.clone();
- // Call by invoking evaluate_constant on the function
+ if( fcn.m_abi == "rust-intrinsic" )
+ {
+ auto pp = monomorphise_path_params_with(node.span(), node.m_path.m_data.as_Generic().m_params, m_monomorph_cb, true);
+ m_rv = evaluate_constant_intrinsic(node.span(), m_crate, m_newval_state, fcn.m_linkage.name, pp, mv$(args));
+ }
+ else
{
- TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " }");
- m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, mv$(exp_ret_type), mv$(args));
+ // Call by invoking evaluate_constant on the function
+ t_cb_generic cb;
+ ::HIR::PathParams pp;
+ if( const auto* g = node.m_path.m_data.opt_Generic() )
+ {
+ pp = monomorphise_path_params_with(node.span(), g->m_params, m_monomorph_cb, true);
+ cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pp);
+ }
+ else
+ {
+ cb = monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr);
+ }
+ TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " } - pp=" << pp);
+ m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, cb, mv$(exp_ret_type), mv$(args));
}
}
void visit(::HIR::ExprNode_CallValue& node) override {
@@ -1009,6 +1046,7 @@ namespace {
};
Visitor v { crate, newval_state, mv$(exp_type) };
+ v.m_monomorph_cb = monomorph_cb;
for(auto& arg : args)
v.m_values.push_back( mv$(arg) );
const_cast<::HIR::ExprNode&>(expr).visit(v);
@@ -1021,7 +1059,7 @@ namespace {
return mv$(v.m_rv);
}
- ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args)
+ ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args)
{
// TODO: Full-blown miri
TRACE_FUNCTION_F("exp=" << exp << ", args=" << args);
@@ -1452,7 +1490,8 @@ namespace {
// Call by invoking evaluate_constant on the function
{
TRACE_FUNCTION_F("Call const fn " << fcnp << " args={ " << call_args << " }");
- dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, fcn.m_return.clone(), mv$(call_args));
+ // TODO: Correct monomorph_cb
+ dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, monomorph_cb, fcn.m_return.clone(), mv$(call_args));
}
cur_block = e.ret_block;
@@ -1461,13 +1500,13 @@ namespace {
}
}
- ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args)
+ ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args)
{
if( expr.m_mir ) {
- return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, mv$(exp), mv$(args));
+ return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, monomorph_cb, mv$(exp), mv$(args));
}
else if( expr ) {
- return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, mv$(exp), mv$(args));
+ return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, monomorph_cb, mv$(exp), mv$(args));
}
else {
BUG(sp, "Attempting to evaluate constant expression with no associated code");
@@ -1585,13 +1624,14 @@ namespace {
::HIR::Visitor::visit_type(ty);
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,
+ TRACE_FUNCTION_FR(ty, ty);
if( e.size_val == ~0u )
{
assert(e.size);
assert(*e.size);
const auto& expr_ptr = *e.size;
auto nvs = NewvalState { m_new_values, *m_mod_path, FMT("ty_" << &ty << "$") };
- auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, ::HIR::CoreType::Usize);
+ auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, monomorphise_type_get_cb(expr_ptr->span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize);
if( !val.is_Integer() )
ERROR(expr_ptr->span(), E0000, "Array size isn't an integer");
e.size_val = static_cast<size_t>(val.as_Integer());
@@ -1615,14 +1655,16 @@ namespace {
// return ;
auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$") };
- item.m_value_res = evaluate_constant(item.m_value->span(), m_crate, nvs, item.m_value, item.m_type.clone(), {});
+ const auto& sp = item.m_value->span();
+ item.m_value_res = evaluate_constant(sp, m_crate, nvs, item.m_value, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), item.m_type.clone(), {});
- check_lit_type(item.m_value->span(), item.m_type, item.m_value_res);
+ check_lit_type(sp, item.m_type, item.m_value_res);
DEBUG("constant: " << item.m_type << " = " << item.m_value_res);
}
}
void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override {
+ static Span sp;
if( auto* e = item.m_data.opt_Value() )
{
uint64_t i = 0;
@@ -1630,7 +1672,9 @@ namespace {
{
if( var.expr )
{
- auto val = evaluate_constant(var.expr->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") }, var.expr, {});
+ auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") };
+ const auto& sp = var.expr->span();
+ auto val = evaluate_constant(sp, m_crate, nvs, var.expr, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), {}, {});
DEBUG("enum variant: " << p << "::" << var.name << " = " << val);
i = val.as_Integer();
}
@@ -1664,7 +1708,7 @@ namespace {
void visit(::HIR::ExprNode_ArraySized& node) override {
assert( node.m_size );
NewvalState nvs { m_exp.m_new_values, *m_exp.m_mod_path, FMT("array_" << &node << "$") };
- auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, ::HIR::CoreType::Usize, {});
+ auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, monomorphise_type_get_cb(node.span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize, {});
if( !val.is_Integer() )
ERROR(node.span(), E0000, "Array size isn't an integer");
node.m_size_val = static_cast<size_t>(val.as_Integer());