summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp4
-rw-r--r--src/hir/hir.cpp6
-rw-r--r--src/hir/hir.hpp6
-rw-r--r--src/hir/serialise.cpp4
-rw-r--r--src/hir_conv/constant_evaluation.cpp154
-rw-r--r--src/hir_typeck/expr_cs.cpp24
6 files changed, 150 insertions, 48 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index 4161cd09..fcfaeda1 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -910,6 +910,10 @@ namespace {
{
#define _(x, ...) case ::HIR::Literal::TAG_##x: return ::HIR::Literal::make_##x(__VA_ARGS__);
_(List, deserialise_vec< ::HIR::Literal>() )
+ _(Variant, {
+ static_cast<unsigned int>(read_count()),
+ deserialise_vec< ::HIR::Literal>()
+ })
_(Integer, read_u64() )
_(Float, read_double() )
_(BorrowOf, deserialise_path() )
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index c2ad4d00..aa3344eb 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -15,6 +15,12 @@ namespace HIR {
os << " " << val << ",";
os << " ]";
),
+ (Variant,
+ os << "#" << e.idx << ":[";
+ for(const auto& val : e.vals)
+ os << " " << val << ",";
+ os << " ]";
+ ),
(Integer,
os << e;
),
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index b1f18fcf..5c7f5a30 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -49,6 +49,12 @@ TAGGED_UNION(Literal, Invalid,
(Invalid, struct {}),
// List = Array, Tuple, struct literal
(List, ::std::vector<Literal>), // TODO: Have a variant for repetition lists
+ // Variant = Enum variant
+ (Variant, struct {
+ unsigned int idx;
+ ::std::vector<Literal> vals;
+ }),
+ // Literal values
(Integer, uint64_t),
(Float, double),
(BorrowOf, ::HIR::Path),
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 6a74d348..0b581a27 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -466,6 +466,10 @@ namespace {
(List,
serialise_vec(e);
),
+ (Variant,
+ write_count(e.idx);
+ serialise_vec(e.vals);
+ ),
(Integer,
write_u64(e);
),
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 909c70da..47a0db6d 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -41,6 +41,13 @@ namespace {
}
return ::HIR::Literal( mv$(vals) );
),
+ (Variant,
+ ::std::vector< ::HIR::Literal> vals;
+ for(const auto& val : e.vals) {
+ vals.push_back( clone_literal(val) );
+ }
+ return ::HIR::Literal::make_Variant({ e.idx, mv$(vals) });
+ ),
(Integer,
return ::HIR::Literal(e);
),
@@ -194,16 +201,6 @@ namespace {
TODO(sp, "Could not find function for " << path << " - " << rv.tag_str());
}
}
- const ::HIR::Struct& get_struct(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path)
- {
- auto rv = get_ent_fullpath(sp, crate, path, EntNS::Type);
- TU_IFLET( EntPtr, rv, Struct, e,
- return *e;
- )
- else {
- TODO(sp, "Could not find struct for " << path << " - " << rv.tag_str());
- }
- }
::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, ::std::vector< ::HIR::Literal> args)
{
@@ -421,16 +418,37 @@ namespace {
}
void visit(::HIR::ExprNode_TupleVariant& node) override {
- 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));
+
+ 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(), "_TupleVariant with m_is_struct set pointing to " << ent.tag_str());
+ //const auto& str = ent.as_Struct();
+
+ m_rv = ::HIR::Literal::make_List(mv$(vals));
+ }
+ else
+ {
+ const auto& varname = node.m_path.m_path.m_components.back();
+ auto tmp_path = node.m_path.m_path;
+ tmp_path.m_components.pop_back();
+ const auto& ent = m_crate.get_typeitem_by_path(node.span(), tmp_path);
+ ASSERT_BUG(node.span(), ent.is_Enum(), "_TupleVariant with m_is_struct clear pointing to " << ent.tag_str());
+ const auto& enm = ent.as_Enum();
+
+ auto it = ::std::find_if( enm.m_variants.begin(), enm.m_variants.end(), [&](const auto&x){ return x.first == varname; } );
+ ASSERT_BUG(node.span(), it != enm.m_variants.end(), "_TupleVariant points to unknown variant - " << node.m_path);
+ unsigned int var_idx = it - enm.m_variants.begin();
+
+ m_rv = ::HIR::Literal::make_Variant({var_idx, mv$(vals)});
+ }
}
void visit(::HIR::ExprNode_CallPath& node) override {
TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv);
@@ -495,7 +513,29 @@ namespace {
)
}
void visit(::HIR::ExprNode_UnitVariant& node) override {
- TODO(node.span(), "Unit varant/struct constructors in constant context");
+ 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();
+
+ m_rv = ::HIR::Literal::make_List({});
+ }
+ else
+ {
+ const auto& varname = node.m_path.m_path.m_components.back();
+ auto tmp_path = node.m_path.m_path;
+ tmp_path.m_components.pop_back();
+ const auto& ent = m_crate.get_typeitem_by_path(node.span(), tmp_path);
+ ASSERT_BUG(node.span(), ent.is_Enum(), "_UnitVariant with m_is_struct clear pointing to " << ent.tag_str());
+ const auto& enm = ent.as_Enum();
+
+ auto it = ::std::find_if( enm.m_variants.begin(), enm.m_variants.end(), [&](const auto&x){ return x.first == varname; } );
+ ASSERT_BUG(node.span(), it != enm.m_variants.end(), "_UnitVariant points to unknown variant - " << node.m_path);
+ unsigned int var_idx = it - enm.m_variants.begin();
+
+ m_rv = ::HIR::Literal::make_Variant({var_idx, {}});
+ }
}
void visit(::HIR::ExprNode_PathValue& node) override {
TRACE_FUNCTION_FR("_PathValue - " << node.m_path, m_rv);
@@ -541,37 +581,49 @@ namespace {
void visit(::HIR::ExprNode_StructLiteral& node) override {
TRACE_FUNCTION_FR("_StructLiteral - " << node.m_path, m_rv);
- const auto& str = get_struct(node.span(), m_crate, node.m_path.m_path);
- const auto& fields = str.m_data.as_Named();
- ::std::vector< ::HIR::Literal> vals;
- if( node.m_base_value ) {
- node.m_base_value->visit(*this);
- auto base_val = mv$(m_rv);
- if( !base_val.is_List() || base_val.as_List().size() != fields.size() ) {
- BUG(node.span(), "Struct literal base value had an incorrect field count");
+ // 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");
+ const auto& fields = str.m_data.as_Named();
+
+ ::std::vector< ::HIR::Literal> vals;
+ if( node.m_base_value ) {
+ node.m_base_value->visit(*this);
+ auto base_val = mv$(m_rv);
+ if( !base_val.is_List() || base_val.as_List().size() != fields.size() ) {
+ BUG(node.span(), "Struct literal base value had an incorrect field count");
+ }
+ vals = mv$(base_val.as_List());
}
- vals = mv$(base_val.as_List());
- }
- else {
- vals.resize( fields.size() );
- }
- for( const auto& val_set : node.m_values ) {
- unsigned int idx = ::std::find_if( fields.begin(), fields.end(), [&](const auto& v) { return v.first == val_set.first; } ) - fields.begin();
- if( idx == fields.size() ) {
- ERROR(node.span(), E0000, "Field name " << val_set.first << " isn't a member of " << node.m_path);
+ else {
+ vals.resize( fields.size() );
}
- val_set.second->visit(*this);
- vals[idx] = mv$(m_rv);
- }
- for( unsigned int i = 0; i < vals.size(); i ++ ) {
- const auto& val = vals[i];
- if( val.is_Invalid() ) {
- ERROR(node.span(), E0000, "Field " << fields[i].first << " wasn't set");
+ for( const auto& val_set : node.m_values ) {
+ unsigned int idx = ::std::find_if( fields.begin(), fields.end(), [&](const auto& v) { return v.first == val_set.first; } ) - fields.begin();
+ if( idx == fields.size() ) {
+ ERROR(node.span(), E0000, "Field name " << val_set.first << " isn't a member of " << node.m_path);
+ }
+ val_set.second->visit(*this);
+ vals[idx] = mv$(m_rv);
+ }
+ for( unsigned int i = 0; i < vals.size(); i ++ ) {
+ const auto& val = vals[i];
+ if( val.is_Invalid() ) {
+ ERROR(node.span(), E0000, "Field " << fields[i].first << " wasn't set");
+ }
}
- }
- m_rv = ::HIR::Literal::make_List(mv$(vals));
+ 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");
+ 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;
@@ -762,6 +814,7 @@ namespace {
uint64_t mask;
switch(te)
{
+ // Integers mask down
case ::HIR::CoreType::I8:
case ::HIR::CoreType::U8:
mask = 0xFF;
@@ -791,6 +844,15 @@ namespace {
default:
TODO(sp, "RValue::Cast to " << e.type << ", val = " << inval);
}
+ ),
+ // Allow casting any integer value to a pointer (TODO: Ensure that the pointer is sized?)
+ (Pointer,
+ TU_IFLET( ::HIR::Literal, inval, Integer, i,
+ val = ::HIR::Literal(i);
+ )
+ else {
+ BUG(sp, "Invalid cast of " << inval.tag_str() << " to " << e.type);
+ }
)
)
),
@@ -932,6 +994,7 @@ namespace {
void visit_constant(::HIR::ItemPath p, ::HIR::Constant& item) override
{
visit_type(item.m_type);
+ assert(item.m_value);
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);
@@ -939,9 +1002,12 @@ namespace {
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);
+ if( item.m_value )
+ {
+ 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)
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 6af70d30..8b4cc3a1 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1999,8 +1999,17 @@ namespace {
}
void visit(::HIR::ExprNode_CallValue& node) override {
const auto& sp = node.span();
- const auto& ty = this->context.get_type(node.m_value->m_res_type);
- TRACE_FUNCTION_F("CallValue: ty=" << ty);
+ const auto& ty_o = this->context.get_type(node.m_value->m_res_type);
+ TRACE_FUNCTION_F("CallValue: ty=" << ty_o);
+
+ unsigned int deref_count = 0;
+ const auto* ty_p = &ty_o;
+ while(ty_p->m_data.is_Borrow())
+ {
+ deref_count ++;
+ ty_p = &this->context.get_type(*ty_p->m_data.as_Borrow().inner);
+ }
+ const auto& ty = *ty_p;
TU_MATCH_DEF(decltype(ty.m_data), (ty.m_data), (e),
(
@@ -2099,8 +2108,9 @@ namespace {
node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Fn;
),
(Borrow,
- // TODO: Locate trait impl via borrow
- TODO(sp, "CallValue on an &-ptr");
+ // - Check inner (recursively)
+ // > use upper
+ TODO(sp, "CallValue on an &-ptr - " << ty);
return ;
),
(Infer,
@@ -2108,6 +2118,12 @@ namespace {
return ;
)
)
+
+ if( deref_count > 0 )
+ {
+ TODO(sp, "Insert autoderef for CallValue (" << deref_count << " needed) - " << ty << " and " << ty_o);
+ }
+
assert( node.m_arg_types.size() == node.m_args.size() + 1 );
for(unsigned int i = 0; i < node.m_args.size(); i ++)
{