summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-04 11:43:45 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-04 11:43:45 +0800
commitf9e94f5e907af0ce205a6b04deb5b0d35a4e1bc4 (patch)
tree55562cd226fa90c5c9ac24efa7eb4e4d74cf719f
parent6fad166a1c3b18bda2c9c6c981d72628cd256a00 (diff)
downloadmrust-f9e94f5e907af0ce205a6b04deb5b0d35a4e1bc4.tar.gz
HIR Typeck - Coming along, close to needing coercions
-rw-r--r--Makefile2
-rw-r--r--src/hir/expr.hpp49
-rw-r--r--src/hir/from_ast.cpp4
-rw-r--r--src/hir/from_ast_expr.cpp57
-rw-r--r--src/hir/pattern.cpp118
-rw-r--r--src/hir/pattern.hpp3
-rw-r--r--src/hir/type.cpp9
-rw-r--r--src/hir/type.hpp4
-rw-r--r--src/hir/visitor.cpp11
-rw-r--r--src/hir_typeck/expr.cpp52
10 files changed, 290 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 9a8ae478..015b20ee 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ OBJ += resolve/use.o resolve/index.o resolve/absolute.o
OBJ += hir/from_ast.o hir/from_ast_expr.o
OBJ += hir/hir.o
OBJ += hir/crate_ptr.o hir/type_ptr.o hir/expr_ptr.o
-OBJ += hir/type.o hir/path.o hir/expr.o
+OBJ += hir/type.o hir/path.o hir/expr.o hir/pattern.o
OBJ += hir/visitor.o
OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o hir_conv/resolve_ufcs.o hir_conv/bind.o
OBJ += hir_typeck/outer.o hir_typeck/expr.o
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 1f36158c..5343228e 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -55,7 +55,7 @@ struct ExprNode_Return:
::HIR::ExprNodeP m_value;
ExprNode_Return(::HIR::ExprNodeP value):
- ExprNode(::HIR::TypeRef({})),
+ ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
m_value( mv$(value) )
{
}
@@ -69,7 +69,7 @@ struct ExprNode_Loop:
::HIR::ExprNodeP m_code;
ExprNode_Loop(::std::string label, ::HIR::ExprNodeP code):
- ExprNode(::HIR::TypeRef({})),
+ ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
m_label( mv$(label) ),
m_code( mv$(code) )
{}
@@ -84,7 +84,7 @@ struct ExprNode_LoopControl:
//::HIR::ExprNodeP m_value;
ExprNode_LoopControl(::std::string label, bool cont):
- ExprNode(::HIR::TypeRef({})),
+ ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
m_label( mv$(label) ),
m_continue( cont )
{}
@@ -99,7 +99,7 @@ struct ExprNode_Let:
::HIR::ExprNodeP m_value;
ExprNode_Let(::HIR::Pattern pat, ::HIR::TypeRef ty, ::HIR::ExprNodeP val):
- ExprNode(::HIR::TypeRef({})),
+ ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
m_pattern( mv$(pat) ),
m_type( mv$(ty) ),
m_value( mv$(val) )
@@ -161,7 +161,7 @@ struct ExprNode_Assign:
ExprNodeP m_value;
ExprNode_Assign(Op op, ::HIR::ExprNodeP slot, ::HIR::ExprNodeP value):
- ExprNode(::HIR::TypeRef({})),
+ ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
m_op(op),
m_slot( mv$(slot) ),
m_value( mv$(value) )
@@ -340,7 +340,39 @@ struct ExprNode_Literal:
ExprNode_Literal(Data data):
m_data( mv$(data) )
- {}
+ {
+ TU_MATCH(Data, (m_data), (e),
+ (Integer,
+ if( e.m_type != ::HIR::CoreType::Str ) {
+ m_res_type = ::HIR::TypeRef::Data::make_Primitive(e.m_type);
+ }
+ ),
+ (Float,
+ if( e.m_type != ::HIR::CoreType::Str ) {
+ m_res_type = ::HIR::TypeRef::Data::make_Primitive(e.m_type);
+ }
+ ),
+ (Boolean,
+ m_res_type = ::HIR::TypeRef::Data::make_Primitive( ::HIR::CoreType::Bool );
+ ),
+ (String,
+ m_res_type = ::HIR::TypeRef::Data::make_Borrow({
+ ::HIR::BorrowType::Shared,
+ box$( ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Primitive(::HIR::CoreType::Str) ) )
+ });
+ ),
+ (ByteString,
+ m_res_type = ::HIR::TypeRef::Data::make_Borrow({
+ ::HIR::BorrowType::Shared,
+ box$( ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Array({
+ box$( ::HIR::TypeRef(::HIR::TypeRef::Data::make_Primitive(::HIR::CoreType::U8)) ),
+ ::HIR::ExprPtr(),
+ e.size()
+ }) ) )
+ });
+ )
+ )
+ }
NODE_METHODS();
};
@@ -403,6 +435,11 @@ struct ExprNode_ArrayList:
::std::vector< ::HIR::ExprNodeP> m_vals;
ExprNode_ArrayList(::std::vector< ::HIR::ExprNodeP> vals):
+ ExprNode( ::HIR::TypeRef::Data::make_Array({
+ box$( ::HIR::TypeRef() ),
+ ::HIR::ExprPtr(),
+ vals.size()
+ }) ),
m_vals( mv$(vals) )
{}
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 8681a078..626b3348 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -478,8 +478,8 @@
switch(e.core_type)
{
case CORETYPE_BOOL: return ::HIR::TypeRef( ::HIR::CoreType::Bool );
- case CORETYPE_CHAR: return ::HIR::TypeRef( ::HIR::CoreType::Str );
- case CORETYPE_STR : return ::HIR::TypeRef( ::HIR::CoreType::Char );
+ case CORETYPE_CHAR: return ::HIR::TypeRef( ::HIR::CoreType::Char );
+ case CORETYPE_STR : return ::HIR::TypeRef( ::HIR::CoreType::Str );
case CORETYPE_F32: return ::HIR::TypeRef( ::HIR::CoreType::F32 );
case CORETYPE_F64: return ::HIR::TypeRef( ::HIR::CoreType::F64 );
diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp
index f5e9b31a..b26b7874 100644
--- a/src/hir/from_ast_expr.cpp
+++ b/src/hir/from_ast_expr.cpp
@@ -265,6 +265,7 @@ struct LowerHIR_ExprNode_Visitor:
v.m_label,
LowerHIR_ExprNode_Inner(*v.m_code)
) );
+ assert( m_rv->m_res_type.m_data.is_Tuple() );
break;
case ::AST::ExprNode_Loop::WHILE: {
::std::vector< ::HIR::ExprNodeP> code;
@@ -280,6 +281,7 @@ struct LowerHIR_ExprNode_Visitor:
v.m_label,
::HIR::ExprNodeP(new ::HIR::ExprNode_Block(false, mv$(code)))
) );
+ assert( m_rv->m_res_type.m_data.is_Tuple() );
break; }
case ::AST::ExprNode_Loop::WHILELET: {
::std::vector< ::HIR::ExprNode_Match::Arm> arms;
@@ -304,12 +306,67 @@ struct LowerHIR_ExprNode_Visitor:
mv$(arms)
))
) );
+ assert( m_rv->m_res_type.m_data.is_Tuple() );
break; }
case ::AST::ExprNode_Loop::FOR:
// NOTE: This should already be desugared (as a pass before resolve)
BUG(v.get_pos(), "Encountered still-sugared for loop");
break;
}
+
+ // TODO: Iterate the constructed loop and determine if there are any `break` statements pointing to it
+ {
+ struct LoopVisitor:
+ public ::HIR::ExprVisitorDef
+ {
+ const ::std::string& top_label;
+ bool top_is_broken;
+ ::std::vector< const ::std::string*> name_stack;
+
+ LoopVisitor(const ::std::string& top_label):
+ top_label(top_label),
+ top_is_broken(false),
+ name_stack()
+ {}
+
+ void visit(::HIR::ExprNode_Loop& node) override {
+ if( node.m_label != "" ) {
+ this->name_stack.push_back( &node.m_label );
+ }
+ ::HIR::ExprVisitorDef::visit(node);
+ if( node.m_label != "" ) {
+ this->name_stack.pop_back( );
+ }
+ }
+ void visit(::HIR::ExprNode_LoopControl& node) override {
+ ::HIR::ExprVisitorDef::visit(node);
+
+ if( node.m_continue ) {
+ }
+ else {
+ for( auto it = this->name_stack.rbegin(); it != this->name_stack.rend(); ++ it )
+ {
+ if( node.m_label == **it )
+ return ;
+ }
+ if( node.m_label == this->top_label ) {
+ this->top_is_broken = true;
+ }
+ else {
+ // break is for a higher loop
+ }
+ }
+ }
+ };
+
+ auto& loop_node = dynamic_cast< ::HIR::ExprNode_Loop&>(*m_rv);;
+ LoopVisitor lv { loop_node.m_label };
+ loop_node.m_code->visit(lv);
+ if( ! lv.top_is_broken ) {
+ // If the loop never hit a 'break', the loop yields ! not ()
+ loop_node.m_res_type.m_data = ::HIR::TypeRef::Data::make_Diverge({});
+ }
+ }
}
virtual void visit(::AST::ExprNode_Match& v) override {
::std::vector< ::HIR::ExprNode_Match::Arm> arms;
diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp
new file mode 100644
index 00000000..64b132a3
--- /dev/null
+++ b/src/hir/pattern.cpp
@@ -0,0 +1,118 @@
+
+#include "pattern.hpp"
+
+namespace HIR {
+ ::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& x) {
+ TU_MATCH(Pattern::Value, (x), (e),
+ (Integer,
+ // TODO: Print with type
+ os << e.value;
+ ),
+ (String,
+ os << "\"" << e << "\"";
+ ),
+ (Named,
+ os << e;
+ )
+ )
+ return os;
+ }
+ ::std::ostream& operator<<(::std::ostream& os, const Pattern& x) {
+ if( x.m_binding.is_valid() ) {
+ if( x.m_binding.m_mutable )
+ os << "mut ";
+ switch(x.m_binding.m_type)
+ {
+ case PatternBinding::Type::Move: break;
+ case PatternBinding::Type::Ref: os << "ref "; break;
+ case PatternBinding::Type::MutRef: os << "ref mut "; break;
+ }
+ os << x.m_binding.m_name << " @ ";
+ }
+ TU_MATCH(Pattern::Data, (x.m_data), (e),
+ (Any,
+ os << "_";
+ ),
+ (Box,
+ os << "box " << *e.sub;
+ ),
+ (Ref,
+ switch(e.type)
+ {
+ case BorrowType::Shared: os << "&"; break;
+ case BorrowType::Unique: os << "&mut "; break;
+ case BorrowType::Owned: os << "&move "; break;
+ }
+ os << *e.sub;
+ ),
+ (Tuple,
+ os << "(";
+ for(const auto& s : e.sub_patterns)
+ os << s << ", ";
+ os << ")";
+ ),
+ (StructTuple,
+ os << e.path;
+ os << "(";
+ for(const auto& s : e.sub_patterns)
+ os << s << ", ";
+ os << ")";
+ ),
+ (StructTupleWildcard,
+ os << e.path;
+ ),
+ (Struct,
+ os << e.path;
+ os << "{ ";
+ for(const auto& ns : e.sub_patterns)
+ os << ns.first << ": " << ns.second << ", ";
+ os << "}";
+ ),
+
+ (Value,
+ os << e.val;
+ ),
+ (Range,
+ os << e.start << " ... " << e.end;
+ ),
+
+ (EnumTuple,
+ os << e.path;
+ os << "(";
+ for(const auto& s : e.sub_patterns)
+ os << s << ", ";
+ os << ")";
+ ),
+ (EnumTupleWildcard,
+ os << e.path;
+ ),
+ (EnumStruct,
+ os << e.path;
+ os << "{ ";
+ for(const auto& ns : e.sub_patterns)
+ os << ns.first << ": " << ns.second << ", ";
+ os << "}";
+ ),
+ (Slice,
+ os << "[";
+ for(const auto& s : e.sub_patterns)
+ os << s << ", ";
+ os << "]";
+ ),
+ (SplitSlice,
+ os << "[";
+ for(const auto& s : e.leading)
+ os << s << ", ";
+ if( e.extra_bind.is_valid() ) {
+ os << e.extra_bind.m_name << " @ ";
+ }
+ os << ".. ";
+ for(const auto& s : e.trailing)
+ os << s << ", ";
+ os << "]";
+ )
+ )
+ return os;
+ }
+}
+
diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp
index c7b0fe7d..4eefa181 100644
--- a/src/hir/pattern.hpp
+++ b/src/hir/pattern.hpp
@@ -52,6 +52,7 @@ struct Pattern
(String, ::std::string),
(Named, Path)
);
+ friend ::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& x);
TAGGED_UNION(Data, Any,
// Irrefutable / destructuring
@@ -108,6 +109,8 @@ struct Pattern
PatternBinding m_binding;
Data m_data;
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const Pattern& x);
};
}
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 5ee00cfd..17da7c4c 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -64,7 +64,12 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const
os << ")";
),
(Array,
- os << "[" << *e.inner << "; " << "/*sz*/" << "]";
+ os << "[" << *e.inner << "; ";
+ if( e.size_val != ~0u )
+ os << e.size_val;
+ else
+ os << "/*sz*/";
+ os << "]";
),
(Slice,
os << "[" << *e.inner << "]";
@@ -124,7 +129,7 @@ namespace {
{
TU_MATCH(::HIR::TypeRef::Data, (m_data), (e),
(Infer,
- return ::HIR::TypeRef( Data::make_Infer({}) );
+ return ::HIR::TypeRef( Data::make_Infer(e) );
),
(Diverge,
return ::HIR::TypeRef( Data::make_Diverge({}) );
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index 8db8d406..9fe13872 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -114,6 +114,10 @@ struct TypeRef
TypeRef& operator=(TypeRef&& ) = default;
TypeRef& operator=(const TypeRef&) = delete;
+ struct TagUnit {};
+ TypeRef(TagUnit ):
+ m_data( Data::make_Tuple({}) )
+ {}
TypeRef(::std::vector< ::HIR::TypeRef> sts):
m_data( Data::make_Tuple(mv$(sts)) )
{}
diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp
index 23acf4e4..d2ee9f74 100644
--- a/src/hir/visitor.cpp
+++ b/src/hir/visitor.cpp
@@ -88,26 +88,32 @@ void ::HIR::Visitor::visit_module(::HIR::Module& mod)
void ::HIR::Visitor::visit_type_impl(::HIR::TypeImpl& impl)
{
+ TRACE_FUNCTION_F("impl.m_type=" << impl.m_type);
this->visit_params(impl.m_params);
this->visit_type(impl.m_type);
for(auto& method : impl.m_methods) {
+ DEBUG("method " << method.first);
this->visit_function(method.second);
}
}
void ::HIR::Visitor::visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl)
{
+ TRACE_FUNCTION_F("trait_path=" << trait_path);
this->visit_params(impl.m_params);
this->visit_path_params(impl.m_trait_args);
this->visit_type(impl.m_type);
for(auto& ent : impl.m_methods) {
+ DEBUG("method " << ent.first);
this->visit_function(ent.second);
}
for(auto& ent : impl.m_constants) {
+ DEBUG("const " << ent.first);
this->visit_expr(ent.second);
}
for(auto& ent : impl.m_types) {
+ DEBUG("type " << ent.first);
this->visit_type(ent.second);
}
}
@@ -125,11 +131,13 @@ void ::HIR::Visitor::visit_type_alias(::HIR::TypeAlias& item)
}
void ::HIR::Visitor::visit_trait(::HIR::Trait& item)
{
+ TRACE_FUNCTION;
this->visit_params(item.m_params);
for(auto& par : item.m_parent_traits) {
this->visit_generic_path(par, ::HIR::Visitor::PathContext::TYPE);
}
for(auto& i : item.m_types) {
+ DEBUG("type " << i.first);
this->visit_params(i.second.m_params);
this->visit_type(i.second.m_default);
}
@@ -137,12 +145,15 @@ void ::HIR::Visitor::visit_trait(::HIR::Trait& item)
TU_MATCH(::HIR::TraitValueItem, (i.second), (e),
(None, ),
(Constant,
+ DEBUG("constant " << i.first);
this->visit_constant(e);
),
(Static,
+ DEBUG("static " << i.first);
this->visit_static(e);
),
(Function,
+ DEBUG("method " << i.first);
this->visit_function(e);
)
)
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 2a00406d..cd1ceccb 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -738,11 +738,12 @@ namespace {
// Adds a rule that two types must be equal
void apply_equality(const Span& sp, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right)
{
- assert( !left.m_data.is_Infer() || left.m_data.as_Infer().index != ~0u );
+ TRACE_FUNCTION_F(left << ", " << right);
+ assert( ! left.m_data.is_Infer() || left.m_data.as_Infer().index != ~0u );
assert( !right.m_data.is_Infer() || right.m_data.as_Infer().index != ~0u );
- DEBUG("apply_equality(" << left << ", " << right << ")");
const auto& l_t = this->get_type(left);
const auto& r_t = this->get_type(right);
+ DEBUG("- l_t = " << l_t << ", r_t = " << r_t);
TU_IFLET(::HIR::TypeRef::Data, r_t.m_data, Infer, r_e,
TU_IFLET(::HIR::TypeRef::Data, l_t.m_data, Infer, l_e,
// Both are infer, unify the two
@@ -769,6 +770,7 @@ namespace {
)
else {
root_ivar.type = box$( left.clone() );
+ DEBUG("Set IVar " << r_e.index << " = " << *root_ivar.type);
}
}
)
@@ -793,7 +795,11 @@ namespace {
)
else {
// Neither are infer - both should be of the same form
- // TODO: What if one of these is `!`?
+ // - If either side is `!`, return early (diverging type, matches anything)
+ if( l_t.m_data.is_Diverge() || r_t.m_data.is_Diverge() ) {
+ return ;
+ }
+ // - If tags don't match, error
if( l_t.m_data.tag() != r_t.m_data.tag() ) {
// Type error
this->dump();
@@ -829,10 +835,20 @@ namespace {
TODO(sp, "Recurse in apply_equality Slice - " << l_t << " and " << r_t);
),
(Tuple,
- TODO(sp, "Recurse in apply_equality Tuple - " << l_t << " and " << r_t);
+ if( l_e.size() != r_e.size() ) {
+ ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - Tuples are of different length");
+ }
+ for(unsigned int i = 0; i < l_e.size(); i ++)
+ {
+ this->apply_equality(sp, l_e[i], r_e[i]);
+ }
),
(Borrow,
- TODO(sp, "Recurse in apply_equality Borrow - " << l_t << " and " << r_t);
+ if( l_e.type != r_e.type ) {
+ // TODO: This could be allowed (using coercions)
+ ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - Borrow classes differ");
+ }
+ this->apply_equality(sp, *l_e.inner, *r_e.inner);
),
(Pointer,
TODO(sp, "Recurse in apply_equality Pointer - " << l_t << " and " << r_t);
@@ -906,28 +922,41 @@ namespace {
void visit_node(::HIR::ExprNode& node) override {
this->context.add_ivars(node.m_res_type);
+ DEBUG(typeid(node).name() << " : " << node.m_res_type);
}
void visit(::HIR::ExprNode_Block& node) override
{
::HIR::ExprVisitorDef::visit(node);
- assert( node.m_nodes.size() > 0 );
- this->context.apply_equality(node.span(), node.m_res_type, node.m_nodes.back()->m_res_type);
+ TRACE_FUNCTION_F("{ }");
+
+ if( node.m_nodes.size() ) {
+ this->context.apply_equality(node.span(), node.m_res_type, node.m_nodes.back()->m_res_type);
+ }
+ else {
+ this->context.apply_equality(node.span(), node.m_res_type, ::HIR::TypeRef( ::HIR::TypeRef::TagUnit() ));
+ }
}
void visit(::HIR::ExprNode_Let& node) override
{
::HIR::ExprVisitorDef::visit(node);
+ TRACE_FUNCTION_F("let " << node.m_pattern << ": " << node.m_type);
this->context.add_ivars(node.m_type);
this->context.add_binding(node.m_pattern, node.m_type);
+ if( node.m_value ) {
+ this->context.apply_equality(node.span(), node.m_type, node.m_value->m_res_type);
+ }
}
void visit(::HIR::ExprNode_Match& node) override
{
::HIR::ExprVisitorDef::visit(node);
+ TRACE_FUNCTION_F("match ...");
for(auto& arm : node.m_arms)
{
+ DEBUG("ARM " << arm.m_patterns);
for(auto& pat : arm.m_patterns)
{
this->context.add_binding(pat, node.m_value->m_res_type);
@@ -939,6 +968,7 @@ namespace {
void visit(::HIR::ExprNode_If& node) override
{
::HIR::ExprVisitorDef::visit(node);
+ TRACE_FUNCTION_F("if ...");
this->context.apply_equality(node.span(), node.m_res_type, node.m_true->m_res_type);
if( node.m_false ) {
this->context.apply_equality(node.span(), node.m_res_type, node.m_false->m_res_type);
@@ -979,7 +1009,9 @@ void Typecheck_Code(TypecheckContext context, const ::HIR::TypeRef& result_type,
ExprVisitor_Enum visitor { context };
root_node.visit( visitor );
}
- context.apply_equality(root_node.span(), root_node.m_res_type, result_type);
+ DEBUG("- Apply RV");
+ context.apply_equality(root_node.span(), result_type, root_node.m_res_type);
+ context.dump();
// 2. Iterate through nodes applying rules until nothing changes
{
ExprVisitor_Run visitor { context };
@@ -1106,6 +1138,7 @@ namespace {
for( auto& arg : item.m_args ) {
typeck_context.add_binding( arg.first, arg.second );
}
+ DEBUG("Function code");
Typecheck_Code( mv$(typeck_context), item.m_return, *item.m_code );
}
}
@@ -1114,6 +1147,7 @@ namespace {
if( &*item.m_value )
{
TypecheckContext typeck_context { };
+ DEBUG("Static value");
Typecheck_Code( mv$(typeck_context), item.m_type, *item.m_value );
}
}
@@ -1122,6 +1156,7 @@ namespace {
if( &*item.m_value )
{
TypecheckContext typeck_context { };
+ DEBUG("Const value");
Typecheck_Code( mv$(typeck_context), item.m_type, *item.m_value );
}
}
@@ -1136,6 +1171,7 @@ namespace {
{
TU_IFLET(::HIR::Enum::Variant, var.second, Value, e,
TypecheckContext typeck_context { };
+ DEBUG("Enum value");
Typecheck_Code( mv$(typeck_context), enum_type, *e );
)
}