summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-05-07 15:55:51 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-05-07 15:55:51 +0800
commit592c816af31a534dde7274d2bd38661585a71ac7 (patch)
tree7eb175fb179d65ea7f413a87c871a81f3e8b6b72 /src/hir_typeck
parentec1dc3542bd5122db57f4459f63a6040f5e3ab20 (diff)
downloadmrust-592c816af31a534dde7274d2bd38661585a71ac7.tar.gz
HIR - Replace m_yeilds_final_value with a node
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/expr_check.cpp5
-rw-r--r--src/hir_typeck/expr_cs.cpp110
2 files changed, 56 insertions, 59 deletions
diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp
index 4f7bb5f4..614d52f4 100644
--- a/src/hir_typeck/expr_check.cpp
+++ b/src/hir_typeck/expr_check.cpp
@@ -59,9 +59,10 @@ namespace {
{
n->visit(*this);
}
- if( node.m_nodes.size() > 0 && node.m_yields_final )
+ if( node.m_value_node )
{
- check_types_equal(node.span(), node.m_res_type, node.m_nodes.back()->m_res_type);
+ node.m_value_node->visit(*this);
+ check_types_equal(node.span(), node.m_res_type, node.m_value_node->m_res_type);
}
}
void visit(::HIR::ExprNode_Asm& node) override
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index acf991dd..12819251 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -543,13 +543,12 @@ namespace {
return ty.m_data.is_Diverge();// || (ty.m_data.is_Infer() && ty.m_data.as_Infer().ty_class == ::HIR::InferClass::Diverge);
};
+ bool diverges = false;
+ this->push_traits( node.m_traits );
if( node.m_nodes.size() > 0 )
{
- bool diverges = false;
- this->push_traits( node.m_traits );
-
this->push_inner_coerce(false);
- for( unsigned int i = 0; i < node.m_nodes.size()-1; i ++ )
+ for( unsigned int i = 0; i < node.m_nodes.size(); i ++ )
{
auto& snp = node.m_nodes[i];
this->context.add_ivars( snp->m_res_type );
@@ -561,62 +560,56 @@ namespace {
}
}
this->pop_inner_coerce();
+ }
- if( node.m_yields_final )
- {
- auto& snp = node.m_nodes.back();
- DEBUG("Block yields final value");
- this->context.add_ivars( snp->m_res_type );
- this->context.equate_types(snp->span(), node.m_res_type, snp->m_res_type);
- snp->visit(*this);
- }
- else
+ if( node.m_value_node )
+ {
+ auto& snp = node.m_value_node;
+ DEBUG("Block yields final value");
+ this->context.add_ivars( snp->m_res_type );
+ this->context.equate_types(snp->span(), node.m_res_type, snp->m_res_type);
+ snp->visit(*this);
+ }
+ else if( node.m_nodes.size() > 0 )
+ {
+ // NOTE: If the final statement in the block diverges, mark this as diverging
+ const auto& snp = node.m_nodes.back();
+ bool defer = false;
+ if( !diverges )
{
- auto& snp = node.m_nodes.back();
- this->context.add_ivars( snp->m_res_type );
- // - Not yielded - so don't equate the return
- snp->visit(*this);
-
- // NOTE: If the final statement in the block diverges, mark this as diverging
- bool defer = false;
- if( !diverges )
- {
- TU_IFLET(::HIR::TypeRef::Data, this->context.get_type(snp->m_res_type).m_data, Infer, e,
- switch(e.ty_class)
- {
- case ::HIR::InferClass::Integer:
- case ::HIR::InferClass::Float:
- diverges = false;
- break;
- default:
- defer = true;
- break;
- }
- )
- else if( is_diverge(snp->m_res_type) ) {
- diverges = true;
- }
- else {
+ TU_IFLET(::HIR::TypeRef::Data, this->context.get_type(snp->m_res_type).m_data, Infer, e,
+ switch(e.ty_class)
+ {
+ case ::HIR::InferClass::Integer:
+ case ::HIR::InferClass::Float:
diverges = false;
+ break;
+ default:
+ defer = true;
+ break;
}
- }
-
- // If a statement in this block diverges
- if( defer ) {
- DEBUG("Block final node returns _, derfer diverge check");
- this->context.add_revisit(node);
- }
- else if( diverges ) {
- DEBUG("Block diverges, yield !");
- this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_diverge());
+ )
+ else if( is_diverge(snp->m_res_type) ) {
+ diverges = true;
}
else {
- DEBUG("Block doesn't diverge but doesn't yield a value, yield ()");
- this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
+ diverges = false;
}
}
- this->pop_traits( node.m_traits );
+ // If a statement in this block diverges
+ if( defer ) {
+ DEBUG("Block final node returns _, derfer diverge check");
+ this->context.add_revisit(node);
+ }
+ else if( diverges ) {
+ DEBUG("Block diverges, yield !");
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_diverge());
+ }
+ else {
+ DEBUG("Block doesn't diverge but doesn't yield a value, yield ()");
+ this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
+ }
}
else
{
@@ -624,6 +617,7 @@ namespace {
DEBUG("Block is empty, yield ()");
this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
}
+ this->pop_traits( node.m_traits );
}
void visit(::HIR::ExprNode_Asm& node) override
{
@@ -1953,6 +1947,7 @@ namespace {
return ty.m_data.is_Diverge();// || (ty.m_data.is_Infer() && ty.m_data.as_Infer().ty_class == ::HIR::InferClass::Diverge);
};
+ assert( !node.m_nodes.empty() );
const auto& last_ty = this->context.get_type( node.m_nodes.back()->m_res_type );
DEBUG("_Block: last_ty = " << last_ty);
@@ -4133,11 +4128,12 @@ namespace {
while( auto* p = dynamic_cast< ::HIR::ExprNode_Block*>(&**node_ptr_ptr) )
{
DEBUG("- Moving into block");
- ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, p->m_nodes.back()->m_res_type),
- "Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(p->m_nodes.back()->m_res_type));
+ assert( p->m_value_node );
+ ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, p->m_value_node->m_res_type),
+ "Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(p->m_value_node->m_res_type));
// - Override the the result type to the desired result
p->m_res_type = ::HIR::TypeRef::new_borrow(borrow_type, des_borrow_inner.clone());
- node_ptr_ptr = &p->m_nodes.back();
+ node_ptr_ptr = &p->m_value_node;
}
#endif
auto& node_ptr = *node_ptr_ptr;
@@ -4721,13 +4717,13 @@ namespace {
while( auto* p = dynamic_cast< ::HIR::ExprNode_Block*>(&**npp) )
{
DEBUG("- Propagate to the last node of a _Block");
- ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, p->m_nodes.back()->m_res_type),
- "Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(p->m_nodes.back()->m_res_type));
+ ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, p->m_value_node->m_res_type),
+ "Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(p->m_value_node->m_res_type));
ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, ty_src),
"Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(ty_src)
);
p->m_res_type = new_type.clone();
- npp = &p->m_nodes.back();
+ npp = &p->m_value_node;
}
::HIR::ExprNodeP& node_ptr = *npp;
#endif