diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-07 11:41:37 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-07 11:41:37 +0800 |
commit | f1d8a4382fc5d40f7fd53391cd9879566392f984 (patch) | |
tree | e36f91d2fc6338bddd32334914c651a28b1954b2 /src | |
parent | 370708b535397882356541378f201cf505b78ac0 (diff) | |
download | mrust-f1d8a4382fc5d40f7fd53391cd9879566392f984.tar.gz |
HIR Typecheck - Coerce returned values
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 9ce5d00e..6a05ff52 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -1621,13 +1621,20 @@ namespace { public ::HIR::ExprVisitorDef { TypecheckContext& context; + ::HIR::ExprNodeP *m_node_ptr_ptr; public: ExprVisitor_Run(TypecheckContext& context): - context(context) + context(context), + m_node_ptr_ptr(nullptr) { } // TODO: Add a new method called for all ExprNodeP, which will save the pointer someho + void visit_node_ptr(::std::unique_ptr< ::HIR::ExprNode>& node_ptr) { + m_node_ptr_ptr = &node_ptr; + ::HIR::ExprVisitorDef::visit_node_ptr(node_ptr); + m_node_ptr_ptr = nullptr; + } // - Block: Ignore all return values except the last one (which is yeilded) void visit(::HIR::ExprNode_Block& node) override @@ -1904,7 +1911,11 @@ namespace { } } - void visit_call(const Span& sp, ::HIR::Path& path, bool is_method, ::std::vector< ::HIR::ExprNodeP>& args, ::HIR::TypeRef& res_type, ::std::vector< ::HIR::TypeRef>& arg_types) + void visit_call(const Span& sp, + ::HIR::Path& path, bool is_method, + ::std::vector< ::HIR::ExprNodeP>& args, ::HIR::TypeRef& res_type, ::HIR::ExprNodeP& this_node_ptr, + ::std::vector< ::HIR::TypeRef>& arg_types + ) { TRACE_FUNCTION_F("path = " << path); unsigned int arg_ofs = (is_method ? 1 : 0); @@ -2000,15 +2011,18 @@ namespace { } DEBUG("RV " << arg_types.back()); - this->context.apply_equality(sp, res_type, arg_types.back()); + this->context.apply_equality(sp, res_type, arg_types.back(), &this_node_ptr); } // - Call Path: Locate path and build return void visit(::HIR::ExprNode_CallPath& node) override { + auto& node_ptr = *m_node_ptr_ptr; TRACE_FUNCTION_F("CallPath " << node.m_path); + assert(node_ptr.get() == &node); // - Pass m_arg_types as a cache to avoid constant lookups - visit_call(node.span(), node.m_path, false, node.m_args, node.m_res_type, node.m_arg_types); + visit_call(node.span(), node.m_path, false, node.m_args, node.m_res_type, node_ptr, node.m_arg_types); + ::HIR::ExprVisitorDef::visit(node); } // - Call Value: If type is known, locate impl of Fn/FnMut/FnOnce @@ -2019,6 +2033,8 @@ namespace { // - Call Method: Locate method on type void visit(::HIR::ExprNode_CallMethod& node) override { + auto& node_ptr = *m_node_ptr_ptr; + ::HIR::ExprVisitorDef::visit(node); if( node.m_method_path.m_data.is_Generic() && node.m_method_path.m_data.as_Generic().m_path.m_components.size() == 0 ) { @@ -2054,8 +2070,9 @@ namespace { } } + assert(node_ptr.get() == &node); // - Pass m_arg_types as a cache to avoid constant lookups - visit_call(node.span(), node.m_method_path, true, node.m_args, node.m_res_type, node.m_arg_types); + visit_call(node.span(), node.m_method_path, true, node.m_args, node.m_res_type, node_ptr, node.m_arg_types); } // - Field: Locate field on type void visit(::HIR::ExprNode_Field& node) override @@ -2179,22 +2196,20 @@ void Typecheck_Code(TypecheckContext context, const ::HIR::TypeRef& result_type, { TRACE_FUNCTION; - // TODO: Perform type propagation "outward" from the root + auto root_ptr = expr.into_unique(); //context.apply_equality(expr->span(), result_type, expr->m_res_type); // 1. Enumerate inferrence variables and assign indexes to them { ExprVisitor_Enum visitor { context, result_type }; - expr->visit( visitor ); + visitor.visit_node_ptr(root_ptr); } // - Apply equality between the node result and the expected type DEBUG("- Apply RV"); { // Convert ExprPtr into unique_ptr for the execution of this function - auto root_ptr = expr.into_unique(); context.apply_equality(root_ptr->span(), result_type, root_ptr->m_res_type, &root_ptr); - expr = ::HIR::ExprPtr( mv$(root_ptr) ); } context.dump(); @@ -2202,12 +2217,12 @@ void Typecheck_Code(TypecheckContext context, const ::HIR::TypeRef& result_type, { ExprVisitor_Run visitor { context }; do { - expr->visit( visitor ); + visitor.visit_node_ptr(root_ptr); } while( context.take_changed() ); } // 3. Check that there's no unresolved types left - // TODO: Check for completed type resolution + expr = ::HIR::ExprPtr( mv$(root_ptr) ); context.dump(); { ExprVisitor_Apply visitor { context }; |