summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-08 14:31:34 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-08 14:31:34 +0800
commit9db1983ed557ccc99d33b07cc1be75ee3f5b303d (patch)
tree632d3436bad2299227cedac755208565a08b4367 /src
parent5961266133f5e0cbcd57403021086c788d732ec1 (diff)
downloadmrust-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.cpp4
-rw-r--r--src/hir/expr.hpp21
-rw-r--r--src/hir/from_ast_expr.cpp24
-rw-r--r--src/hir_conv/constant_evaluation.cpp3
-rw-r--r--src/hir_typeck/expr.cpp93
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 ++ )
{