summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2019-11-10 09:52:51 +0800
committerJohn Hodge <tpg@mutabah.net>2019-11-10 09:52:51 +0800
commit80fe05a7198104c840edea449a12f4b55dbd45c7 (patch)
treefc3239c6b5844b649b673bdfc654826fad217cfa
parent76e18750da25fd5617009e5864bdd4461fcbf982 (diff)
downloadmrust-80fe05a7198104c840edea449a12f4b55dbd45c7.tar.gz
HIR Typecheck - Remove pre-setting of node result type
-rw-r--r--src/hir/expr.hpp41
-rw-r--r--src/hir_typeck/expr_cs.cpp24
-rw-r--r--src/hir_typeck/helpers.cpp16
3 files changed, 43 insertions, 38 deletions
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index c87ae3a7..0eb64fce 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -56,10 +56,6 @@ public:
ExprNode(Span sp):
m_span( mv$(sp) )
{}
- ExprNode(Span sp, ::HIR::TypeRef ty):
- m_span( mv$(sp) ),
- m_res_type( mv$(ty) )
- {}
virtual ~ExprNode();
};
@@ -106,7 +102,7 @@ struct ExprNode_Asm:
::std::vector< ::std::string> m_flags;
ExprNode_Asm(Span sp, ::std::string tpl_str, ::std::vector<ValRef> outputs, ::std::vector<ValRef> inputs, ::std::vector< ::std::string> clobbers, ::std::vector< ::std::string> flags):
- ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
+ ExprNode(mv$(sp)),
m_template( mv$(tpl_str) ),
m_outputs( mv$(outputs) ),
m_inputs( mv$(inputs) ),
@@ -123,7 +119,7 @@ struct ExprNode_Return:
::HIR::ExprNodeP m_value;
ExprNode_Return(Span sp, ::HIR::ExprNodeP value):
- ExprNode(mv$(sp), ::HIR::TypeRef::new_diverge()),
+ ExprNode(mv$(sp)),
m_value( mv$(value) )
{
}
@@ -138,8 +134,7 @@ struct ExprNode_Loop:
bool m_diverges = false;
ExprNode_Loop(Span sp, RcString label, ::HIR::ExprNodeP code):
- //ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
- ExprNode(mv$(sp), ::HIR::TypeRef()),
+ ExprNode(mv$(sp)),
m_label( mv$(label) ),
m_code( mv$(code) )
{}
@@ -154,7 +149,7 @@ struct ExprNode_LoopControl:
::HIR::ExprNodeP m_value;
ExprNode_LoopControl(Span sp, RcString label, bool cont, ::HIR::ExprNodeP value={}):
- ExprNode(mv$(sp), ::HIR::TypeRef::new_diverge()),
+ ExprNode(mv$(sp)),
m_label( mv$(label) ),
m_continue( cont ),
m_value( mv$(value) )
@@ -170,7 +165,7 @@ struct ExprNode_Let:
::HIR::ExprNodeP m_value;
ExprNode_Let(Span sp, ::HIR::Pattern pat, ::HIR::TypeRef ty, ::HIR::ExprNodeP val):
- ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
+ ExprNode(mv$(sp)),
m_pattern( mv$(pat) ),
m_type( mv$(ty) ),
m_value( mv$(val) )
@@ -253,7 +248,7 @@ struct ExprNode_Assign:
ExprNodeP m_value;
ExprNode_Assign(Span sp, Op op, ::HIR::ExprNodeP slot, ::HIR::ExprNodeP value):
- ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
+ ExprNode(mv$(sp)),
m_op(op),
m_slot( mv$(slot) ),
m_value( mv$(value) )
@@ -378,12 +373,15 @@ struct ExprNode_Cast:
public ExprNode
{
::HIR::ExprNodeP m_value;
- // TODO: Re-instate the local type, to allow for coercions?
+ //::HIR::TypeRef m_dst_type;
ExprNode_Cast(Span sp, ::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
- ExprNode( mv$(sp), mv$(dst_type) ),
- m_value( mv$(value) )
- {}
+ ExprNode( mv$(sp) )
+ ,m_value( mv$(value) )
+ //,m_dst_type( mv$(dst_type) )
+ {
+ m_res_type = mv$(dst_type);
+ }
NODE_METHODS();
};
@@ -391,15 +389,20 @@ struct ExprNode_Cast:
// - `&[T; n] -> &[T]`
// - `&T -> &Trait`
// - `Box<T> -> Box<Trait>`
+// NOTE: Also used for type ascription
struct ExprNode_Unsize:
public ExprNode
{
::HIR::ExprNodeP m_value;
+ //::HIR::TypeRef m_dst_type;
ExprNode_Unsize(Span sp, ::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
- ExprNode( mv$(sp), mv$(dst_type) ),
- m_value( mv$(value) )
- {}
+ ExprNode( mv$(sp) )
+ ,m_value( mv$(value) )
+ //,m_dst_type( mv$(dst_type) )
+ {
+ m_res_type = mv$(dst_type);
+ }
NODE_METHODS();
};
@@ -756,7 +759,7 @@ struct ExprNode_ArrayList:
::std::vector< ::HIR::ExprNodeP> m_vals;
ExprNode_ArrayList(Span sp, ::std::vector< ::HIR::ExprNodeP> vals):
- ExprNode( mv$(sp), ::HIR::TypeRef::new_array( ::HIR::TypeRef(), vals.size() ) ),
+ ExprNode( mv$(sp) ),
m_vals( mv$(vals) )
{}
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 8a374946..8becc775 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -621,7 +621,7 @@ namespace {
void visit(::HIR::ExprNode_Block& node) override
{
- TRACE_FUNCTION_F(&node << " { ... }");
+ TRACE_FUNCTION_FR(&node << " { ... }", &node << " " << this->context.get_type(node.m_res_type));
const auto is_diverge = [&](const ::HIR::TypeRef& rty)->bool {
const auto& ty = this->context.get_type(rty);
@@ -724,6 +724,7 @@ namespace {
}
this->pop_inner_coerce();
// TODO: Revisit to check that the input are integers, and the outputs are integer lvalues
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
}
void visit(::HIR::ExprNode_Return& node) override
{
@@ -736,6 +737,7 @@ namespace {
this->push_inner_coerce( true );
node.m_value->visit( *this );
this->pop_inner_coerce();
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_diverge());
}
void visit(::HIR::ExprNode_Loop& node) override
@@ -797,6 +799,7 @@ namespace {
this->context.equate_types(node.span(), loop_node.m_res_type, ::HIR::TypeRef::new_unit());
}
}
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_diverge());
}
void visit(::HIR::ExprNode_Let& node) override
@@ -824,6 +827,7 @@ namespace {
this->context.require_sized(node.span(), node.m_value->m_res_type);
this->pop_inner_coerce();
}
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
}
void visit(::HIR::ExprNode_Match& node) override
{
@@ -942,6 +946,8 @@ namespace {
auto _2 = this->push_inner_coerce_scoped( node.m_op == ::HIR::ExprNode_Assign::Op::None );
node.m_value->visit( *this );
this->context.require_sized(node.span(), node.m_value->m_res_type);
+
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
}
void visit(::HIR::ExprNode_BinOp& node) override
{
@@ -1617,9 +1623,10 @@ namespace {
this->context.add_ivars( val->m_res_type );
}
+ auto array_ty = ::HIR::TypeRef::new_array( context.m_ivars.new_ivar_tr(), node.m_vals.size() );
+ this->context.equate_types(node.span(), node.m_res_type, array_ty);
// Cleanly equate into array (with coercions)
- // - Result type already set, just need to extract ivar
- const auto& inner_ty = *node.m_res_type.m_data.as_Array().inner;
+ const auto& inner_ty = *array_ty.m_data.as_Array().inner;
for( auto& val : node.m_vals ) {
this->equate_types_inner_coerce(node.span(), inner_ty, val);
}
@@ -1635,8 +1642,7 @@ namespace {
// Create result type (can't be known until after const expansion)
// - Should it be created in const expansion?
- auto ty = ::HIR::TypeRef::new_array( ::HIR::TypeRef(), node.m_size_val );
- this->context.add_ivars(ty);
+ auto ty = ::HIR::TypeRef::new_array( context.m_ivars.new_ivar_tr(), node.m_size_val );
this->context.equate_types(node.span(), node.m_res_type, ty);
// Equate with coercions
const auto& inner_ty = *ty.m_data.as_Array().inner;
@@ -8830,13 +8836,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
for(const auto& node : context.to_visit)
{
const auto& sp = node->span();
- if( const auto* np = dynamic_cast<::HIR::ExprNode_CallMethod*>(node) )
- {
- WARNING(sp, W0000, "Spare Rule - {" << context.m_ivars.fmt_type(np->m_value->m_res_type) << "}." << np->m_method << " -> " << context.m_ivars.fmt_type(np->m_res_type));
- }
- else
- {
- }
+ WARNING(sp, W0000, "Spare rule - " << FMT_CB(os, { ExprVisitor_Print ev(context, os); node->visit(ev); }) << " -> " << context.m_ivars.fmt_type(node->m_res_type));
}
for(const auto& adv : context.adv_revisits)
{
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 010df546..7f20ef28 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -652,8 +652,10 @@ void HMTypeInferrence::ivar_unify(unsigned int left_slot, unsigned int right_slo
// TODO: Assert that setting this won't cause a loop.
auto& root_ivar = this->get_pointed_ivar(right_slot);
- TU_IFLET(::HIR::TypeRef::Data, root_ivar.type->m_data, Infer, re,
- if( re.ty_class == ::HIR::InferClass::Diverge )
+ if( const auto* re = root_ivar.type->m_data.opt_Infer() )
+ {
+ DEBUG("Class unify " << *left_ivar.type << " <- " << *root_ivar.type);
+ if( re->ty_class == ::HIR::InferClass::Diverge )
{
TU_IFLET(::HIR::TypeRef::Data, left_ivar.type->m_data, Infer, le,
if( le.ty_class == ::HIR::InferClass::None ) {
@@ -661,7 +663,7 @@ void HMTypeInferrence::ivar_unify(unsigned int left_slot, unsigned int right_slo
}
)
}
- else if(re.ty_class != ::HIR::InferClass::None)
+ else if(re->ty_class != ::HIR::InferClass::None)
{
TU_MATCH_DEF(::HIR::TypeRef::Data, (left_ivar.type->m_data), (le),
(
@@ -671,24 +673,24 @@ void HMTypeInferrence::ivar_unify(unsigned int left_slot, unsigned int right_slo
if( le.ty_class == ::HIR::InferClass::Diverge )
{
}
- else if( le.ty_class != ::HIR::InferClass::None && le.ty_class != re.ty_class )
+ else if( le.ty_class != ::HIR::InferClass::None && le.ty_class != re->ty_class )
{
ERROR(sp, E0000, "Unifying types with mismatching literal classes - " << *left_ivar.type << " := " << *root_ivar.type);
}
else
{
}
- le.ty_class = re.ty_class;
+ le.ty_class = re->ty_class;
),
(Primitive,
- check_type_class_primitive(sp, *left_ivar.type, re.ty_class, le);
+ check_type_class_primitive(sp, *left_ivar.type, re->ty_class, le);
)
)
}
else
{
}
- )
+ }
else {
BUG(sp, "Unifying over a concrete type - " << *root_ivar.type);
}