diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-08 14:31:34 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-08 14:31:34 +0800 |
commit | 9db1983ed557ccc99d33b07cc1be75ee3f5b303d (patch) | |
tree | 632d3436bad2299227cedac755208565a08b4367 /src | |
parent | 5961266133f5e0cbcd57403021086c788d732ec1 (diff) | |
download | mrust-9db1983ed557ccc99d33b07cc1be75ee3f5b303d.tar.gz |
HIR - Move tuple struct/enum construtors to their on HIR node
- This makes typeck of those invocations easier
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/expr.cpp | 4 | ||||
-rw-r--r-- | src/hir/expr.hpp | 21 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 24 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 93 |
5 files changed, 139 insertions, 6 deletions
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 457d903a..00953c5d 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -72,6 +72,10 @@ DEF_VISIT(ExprNode_Deref, node, visit_node_ptr(node.m_value); ) +DEF_VISIT(ExprNode_TupleVariant, node, + for(auto& arg : node.m_args) + visit_node_ptr(arg); +) DEF_VISIT(ExprNode_CallPath, node, for(auto& arg : node.m_args) visit_node_ptr(arg); diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index bd952348..88e34671 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -293,6 +293,25 @@ struct ExprNode_Deref: NODE_METHODS(); }; +struct ExprNode_TupleVariant: + public ExprNode +{ + // Path to variant/struct + ::HIR::GenericPath m_path; + bool m_is_struct; + ::std::vector<ExprNodeP> m_args; + + // - Cache for typeck + ::std::vector< ::HIR::TypeRef> m_arg_types; + + ExprNode_TupleVariant(Span sp, ::HIR::GenericPath path, bool is_struct, ::std::vector< ::HIR::ExprNodeP> args): + ExprNode(mv$(sp)), + m_path( mv$(path) ), + m_args( mv$(args) ) + {} + + NODE_METHODS(); +}; struct ExprNode_CallPath: public ExprNode { @@ -564,6 +583,7 @@ public: NV(ExprNode_Index) NV(ExprNode_Deref) + NV(ExprNode_TupleVariant); NV(ExprNode_CallPath); NV(ExprNode_CallValue); NV(ExprNode_CallMethod); @@ -604,6 +624,7 @@ public: NV(ExprNode_Index) NV(ExprNode_Deref) + NV(ExprNode_TupleVariant); NV(ExprNode_CallPath); NV(ExprNode_CallValue); NV(ExprNode_CallMethod); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 40f27d5a..742a4fed 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -224,10 +224,26 @@ struct LowerHIR_ExprNode_Visitor: ) else { - m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(), - LowerHIR_Path(Span(v.get_pos()), v.m_path), - mv$( args ) - ) ); + TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), + ( + m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(), + LowerHIR_Path(Span(v.get_pos()), v.m_path), + mv$( args ) + ) ); + ), + (EnumVar, + m_rv.reset( new ::HIR::ExprNode_TupleVariant( v.span(), + LowerHIR_GenericPath(v.span(), v.m_path), false, + mv$( args ) + ) ); + ), + (Struct, + m_rv.reset( new ::HIR::ExprNode_TupleVariant( v.span(), + LowerHIR_GenericPath(v.span(), v.m_path), true, + mv$( args ) + ) ); + ) + ) } } virtual void visit(::AST::ExprNode_CallMethod& v) override { diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 4c17f2b0..c9fcaf0a 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -354,6 +354,9 @@ namespace { badnode(node); } + void visit(::HIR::ExprNode_TupleVariant& node) override { + TODO(node.span(), "ExprNode_TupleVariant"); + } void visit(::HIR::ExprNode_CallPath& node) override { auto& fcn = get_function(node.span(), m_crate, node.m_path); // TODO: Set m_const during parse diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index e60c4350..5107ffdc 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -2199,6 +2199,97 @@ namespace { } } } + void visit(::HIR::ExprNode_TupleVariant& node) override { + const Span& sp = node.span(); + auto& arg_types = node.m_arg_types; + if( arg_types.size() == 0 ) + { + auto& path_params = node.m_path.m_params; + auto monomorph_cb = [&](const auto& gt)->const auto& { + const auto& e = gt.m_data.as_Generic(); + if( e.name == "Self" ) + TODO(sp, "Handle 'Self' when monomorphising type"); + if( e.binding < 256 ) { + auto idx = e.binding; + if( idx >= path_params.m_types.size() ) { + BUG(sp, "Generic param out of input range - " << idx << " '"<<e.name<<"' >= " << path_params.m_types.size()); + } + return path_params.m_types[idx]; + } + else if( e.binding < 512 ) { + BUG(sp, "Method-level parameter on struct/enum"); + } + else { + BUG(sp, "Generic bounding out of total range"); + } + }; + + if( node.m_is_struct ) + { + const auto& str = this->context.m_crate.get_struct_by_path(sp, node.m_path.m_path); + // TODO: Remove this clone + this->fix_param_count(sp, ::HIR::Path(node.m_path.clone()), str.m_params, path_params); + const auto& fields = str.m_data.as_Tuple(); + arg_types.reserve( fields.size() ); + for(const auto& fld : fields) + { + if( monomorphise_type_needed(fld.ent) ) { + arg_types.push_back( this->context.expand_associated_types(sp, monomorphise_type_with(sp, fld.ent, monomorph_cb)) ); + } + else { + arg_types.push_back( fld.ent.clone() ); + } + } + + arg_types.push_back( ::HIR::TypeRef(node.m_path.clone()) ); + } + else + { + const auto& variant_name = node.m_path.m_path.m_components.back(); + auto type_path = node.m_path.m_path; + type_path.m_components.pop_back(); + + const auto& enm = this->context.m_crate.get_enum_by_path(sp, type_path); + // TODO: Remove this clone + this->fix_param_count(sp, ::HIR::Path(node.m_path.clone()), enm.m_params, path_params); + + auto it = ::std::find_if( enm.m_variants.begin(), enm.m_variants.end(), [&](const auto& x){ return x.first == variant_name; }); + if( it == enm.m_variants.end() ) { + ERROR(sp, E0000, "Unable to find variant '" << variant_name << " of " << type_path); + } + const auto& fields = it->second.as_Tuple(); + arg_types.reserve( fields.size() ); + for(const auto& fld : fields) + { + if( monomorphise_type_needed(fld) ) { + arg_types.push_back( this->context.expand_associated_types(sp, monomorphise_type_with(sp, fld, monomorph_cb)) ); + } + else { + arg_types.push_back( fld.clone() ); + } + } + arg_types.push_back( ::HIR::TypeRef( ::HIR::GenericPath(type_path, path_params.clone()) ) ); + } + + if( node.m_args.size() != arg_types.size() - 1 ) { + ERROR(sp, E0000, "Incorrect number of arguments to " << node.m_path); + } + DEBUG("--- RESOLVED"); + } + + for( unsigned int i = 0; i < arg_types.size() - 1; i ++ ) + { + auto& arg_expr_ptr = node.m_args[i]; + const auto& arg_ty = arg_types[i]; + DEBUG("Arg " << i << ": " << arg_ty); + this->context.apply_equality(sp, arg_ty, arg_expr_ptr->m_res_type, &arg_expr_ptr); + } + + DEBUG("Rreturn: " << arg_types.back()); + this->context.apply_equality(sp, node.m_res_type, arg_types.back() /*, &this_node_ptr*/); + + ::HIR::ExprVisitorDef::visit(node); + } void visit_call(const Span& sp, ::HIR::Path& path, bool is_method, @@ -2349,8 +2440,6 @@ namespace { arg_types.push_back( fcn.m_return.clone() ); } } - // TODO: Save the arg_types vector - // - Prevents need to do lookups and monomorph on every cycle for( unsigned int i = arg_ofs; i < arg_types.size() - 1; i ++ ) { |