summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp134
1 files changed, 107 insertions, 27 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 57bf90cd..01cefa0c 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -313,7 +313,7 @@ namespace {
void visit(::HIR::ExprNode_Block& node) override
{
- TRACE_FUNCTION_F("{ ... }");
+ TRACE_FUNCTION_F(&node << " { ... }");
this->push_traits( node.m_traits );
for( unsigned int i = 0; i < node.m_nodes.size(); i ++ )
@@ -335,7 +335,7 @@ namespace {
}
void visit(::HIR::ExprNode_Return& node) override
{
- TRACE_FUNCTION_F("return ...");
+ TRACE_FUNCTION_F(&node << " return ...");
this->context.add_ivars( node.m_value->m_res_type );
this->context.equate_types_coerce(node.span(), this->ret_type, node.m_value);
@@ -345,7 +345,7 @@ namespace {
void visit(::HIR::ExprNode_Loop& node) override
{
- TRACE_FUNCTION_F("loop { ... }");
+ TRACE_FUNCTION_F(&node << " loop { ... }");
this->context.equate_types(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
@@ -354,13 +354,13 @@ namespace {
}
void visit(::HIR::ExprNode_LoopControl& node) override
{
- TRACE_FUNCTION_F((node.m_continue ? "continue" : "break") << " '" << node.m_label);
+ TRACE_FUNCTION_F(&node << " " << (node.m_continue ? "continue" : "break") << " '" << node.m_label);
// Nothing
}
void visit(::HIR::ExprNode_Let& node) override
{
- TRACE_FUNCTION_F("let " << node.m_pattern << ": " << node.m_type);
+ TRACE_FUNCTION_F(&node << " let " << node.m_pattern << ": " << node.m_type);
this->context.add_ivars( node.m_type );
this->context.add_binding(node.span(), node.m_pattern, node.m_type);
@@ -372,7 +372,7 @@ namespace {
}
void visit(::HIR::ExprNode_Match& node) override
{
- TRACE_FUNCTION_F("match ...");
+ TRACE_FUNCTION_F(&node << " match ...");
this->context.add_ivars(node.m_value->m_res_type);
@@ -401,7 +401,7 @@ namespace {
void visit(::HIR::ExprNode_If& node) override
{
- TRACE_FUNCTION_F("if ...");
+ TRACE_FUNCTION_F(&node << " if ...");
this->context.add_ivars( node.m_cond->m_res_type );
this->context.equate_types_coerce(node.m_cond->span(), ::HIR::TypeRef(::HIR::CoreType::Bool), node.m_cond);
@@ -424,7 +424,7 @@ namespace {
void visit(::HIR::ExprNode_Assign& node) override
{
- TRACE_FUNCTION_F("... = ...");
+ TRACE_FUNCTION_F(&node << "... = ...");
this->context.add_ivars( node.m_slot ->m_res_type );
this->context.add_ivars( node.m_value->m_res_type );
@@ -461,7 +461,7 @@ namespace {
}
void visit(::HIR::ExprNode_BinOp& node) override
{
- TRACE_FUNCTION_F("... "<<::HIR::ExprNode_BinOp::opname(node.m_op)<<" ...");
+ TRACE_FUNCTION_F(&node << "... "<<::HIR::ExprNode_BinOp::opname(node.m_op)<<" ...");
this->context.add_ivars( node.m_left ->m_res_type );
this->context.add_ivars( node.m_right->m_res_type );
@@ -535,7 +535,7 @@ namespace {
}
void visit(::HIR::ExprNode_UniOp& node) override
{
- TRACE_FUNCTION_F(::HIR::ExprNode_UniOp::opname(node.m_op) << "...");
+ TRACE_FUNCTION_F(&node << " " << ::HIR::ExprNode_UniOp::opname(node.m_op) << "...");
this->context.add_ivars( node.m_value->m_res_type );
switch(node.m_op)
{
@@ -557,7 +557,7 @@ namespace {
}
void visit(::HIR::ExprNode_Cast& node) override
{
- TRACE_FUNCTION_F("... as " << node.m_res_type);
+ TRACE_FUNCTION_F(&node << " ... as " << node.m_res_type);
this->context.add_ivars( node.m_value->m_res_type );
this->context.add_revisit(node);
@@ -570,7 +570,7 @@ namespace {
}
void visit(::HIR::ExprNode_Index& node) override
{
- TRACE_FUNCTION_F("... [ ... ]");
+ TRACE_FUNCTION_F(&node << " ... [ ... ]");
this->context.add_ivars( node.m_value->m_res_type );
this->context.add_ivars( node.m_index->m_res_type );
@@ -582,7 +582,7 @@ namespace {
}
void visit(::HIR::ExprNode_Deref& node) override
{
- TRACE_FUNCTION_F("*...");
+ TRACE_FUNCTION_F(&node << " *...");
this->context.add_ivars( node.m_value->m_res_type );
const auto& op_trait = this->context.m_crate.get_lang_item_path(node.span(), "deref");
@@ -641,7 +641,7 @@ namespace {
void visit(::HIR::ExprNode_TupleVariant& node) override
{
const auto& sp = node.span();
- TRACE_FUNCTION_F(node.m_path << "(...) [" << (node.m_is_struct ? "struct" : "enum") << "]");
+ TRACE_FUNCTION_F(&node << " " << node.m_path << "(...) [" << (node.m_is_struct ? "struct" : "enum") << "]");
for( auto& val : node.m_args ) {
this->context.add_ivars( val->m_res_type );
}
@@ -708,7 +708,7 @@ namespace {
}
void visit(::HIR::ExprNode_StructLiteral& node) override
{
- TRACE_FUNCTION_F(node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]");
+ TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]");
for( auto& val : node.m_values ) {
this->context.add_ivars( val.second->m_res_type );
}
@@ -781,7 +781,7 @@ namespace {
}
void visit(::HIR::ExprNode_UnitVariant& node) override
{
- TRACE_FUNCTION_F(node.m_path << " [" << (node.m_is_struct ? "struct" : "enum") << "]");
+ TRACE_FUNCTION_F(&node << " " << node.m_path << " [" << (node.m_is_struct ? "struct" : "enum") << "]");
// - Create ivars in path, and set result type
const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, node.m_path);
@@ -791,7 +791,7 @@ namespace {
void visit(::HIR::ExprNode_CallPath& node) override
{
this->visit_path(node.span(), node.m_path);
- TRACE_FUNCTION_F(node.m_path << "(...)");
+ TRACE_FUNCTION_F(&node << " " << node.m_path << "(...)");
for( auto& val : node.m_args ) {
this->context.add_ivars( val->m_res_type );
}
@@ -819,7 +819,7 @@ namespace {
}
void visit(::HIR::ExprNode_CallValue& node) override
{
- TRACE_FUNCTION_F("...(...)");
+ TRACE_FUNCTION_F(&node << " ...(...)");
this->context.add_ivars( node.m_value->m_res_type );
for( auto& val : node.m_args ) {
this->context.add_ivars( val->m_res_type );
@@ -835,7 +835,7 @@ namespace {
}
void visit(::HIR::ExprNode_CallMethod& node) override
{
- TRACE_FUNCTION_F("(...)."<<node.m_method<<"(...)");
+ TRACE_FUNCTION_F(&node << " (...)."<<node.m_method<<"(...)");
this->context.add_ivars( node.m_value->m_res_type );
for( auto& val : node.m_args ) {
this->context.add_ivars( val->m_res_type );
@@ -871,7 +871,7 @@ namespace {
}
void visit(::HIR::ExprNode_Field& node) override
{
- TRACE_FUNCTION_F("(...)."<<node.m_field);
+ TRACE_FUNCTION_F(&node << " (...)."<<node.m_field);
this->context.add_ivars( node.m_value->m_res_type );
this->context.add_revisit( node );
@@ -881,7 +881,7 @@ namespace {
void visit(::HIR::ExprNode_Tuple& node) override
{
- TRACE_FUNCTION_F("(...,)");
+ TRACE_FUNCTION_F(&node << " (...,)");
for( auto& val : node.m_vals ) {
this->context.add_ivars( val->m_res_type );
}
@@ -899,7 +899,7 @@ namespace {
}
void visit(::HIR::ExprNode_ArrayList& node) override
{
- TRACE_FUNCTION_F("[...,]");
+ TRACE_FUNCTION_F(&node << " [...,]");
for( auto& val : node.m_vals ) {
this->context.add_ivars( val->m_res_type );
}
@@ -917,7 +917,7 @@ namespace {
}
void visit(::HIR::ExprNode_ArraySized& node) override
{
- TRACE_FUNCTION_F("[...; "<<node.m_size_val<<"]");
+ TRACE_FUNCTION_F(&node << " [...; "<<node.m_size_val<<"]");
this->context.add_ivars( node.m_val->m_res_type );
this->context.add_ivars( node.m_size->m_res_type );
@@ -957,7 +957,7 @@ namespace {
{
const auto& sp = node.span();
this->visit_path(sp, node.m_path);
- TRACE_FUNCTION_F(node.m_path);
+ TRACE_FUNCTION_F(&node << " " << node.m_path);
this->add_ivars_path(node.span(), node.m_path);
@@ -1085,14 +1085,14 @@ namespace {
}
void visit(::HIR::ExprNode_Variable& node) override
{
- TRACE_FUNCTION_F(node.m_name << "{" << node.m_slot << "}");
+ TRACE_FUNCTION_F(&node << " " << node.m_name << "{" << node.m_slot << "}");
this->context.equate_types(node.span(), node.m_res_type, this->context.get_var(node.span(), node.m_slot));
}
void visit(::HIR::ExprNode_Closure& node) override
{
- TRACE_FUNCTION_F("|...| ...");
+ TRACE_FUNCTION_F(&node << " |...| ...");
for(auto& arg : node.m_args) {
this->context.add_ivars( arg.second );
this->context.add_binding( node.span(), arg.first, arg.second );
@@ -1278,7 +1278,83 @@ namespace {
}
void visit(::HIR::ExprNode_CallValue& node) override {
// TODO:
- TODO(node.span(), "ExprNode_CallValue - revisit");
+ const auto& ty = this->context.get_type(node.m_value->m_res_type);
+ DEBUG("(CallValue) ty = " << ty);
+
+ TU_MATCH_DEF(decltype(ty.m_data), (ty.m_data), (e),
+ (
+ // Search for FnOnce impl
+ const auto& lang_FnOnce = this->context.m_crate.get_lang_item_path(node.span(), "fn_once");
+
+ ::HIR::TypeRef fcn_args_tup;
+ ::HIR::TypeRef fcn_ret;
+
+ // Create a param set with a single tuple (of all argument types)
+ ::HIR::PathParams trait_pp;
+ {
+ ::std::vector< ::HIR::TypeRef> arg_types;
+ for(const auto& arg : node.m_args) {
+ arg_types.push_back( this->context.get_type(arg->m_res_type).clone() );
+ }
+ trait_pp.m_types.push_back( ::HIR::TypeRef( mv$(arg_types) ) );
+ }
+ auto was_bounded = this->context.m_resolve.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](const auto& , const auto& args, const auto& assoc) {
+ const auto& tup = args.m_types[0];
+ if( !tup.m_data.is_Tuple() )
+ ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup);
+ fcn_args_tup = tup.clone();
+ return true;
+ });
+ if( was_bounded )
+ {
+ // RV must be in a bound
+ fcn_ret = ::HIR::TypeRef( ::HIR::Path(::HIR::Path::Data::make_UfcsKnown({
+ box$( ty.clone() ),
+ ::HIR::GenericPath(lang_FnOnce),
+ "Output",
+ {}
+ })) );
+ fcn_ret.m_data.as_Path().path.m_data.as_UfcsKnown().trait.m_params.m_types.push_back( fcn_args_tup.clone() );
+ }
+ else if( !ty.m_data.is_Generic() )
+ {
+ TODO(node.span(), "Search for other implementations of FnOnce for " << ty);
+ }
+ else
+ {
+ // Didn't find anything. Error?
+ ERROR(node.span(), E0000, "Unable to find an implementation of Fn* for " << ty);
+ }
+
+ node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() );
+ node.m_arg_types.push_back( mv$(fcn_ret) );
+ ),
+ (Closure,
+ for( const auto& arg : e.m_arg_types )
+ node.m_arg_types.push_back( arg.clone() );
+ node.m_arg_types.push_back( e.m_rettype->clone() );
+ ),
+ (Function,
+ for( const auto& arg : e.m_arg_types )
+ node.m_arg_types.push_back( arg.clone() );
+ node.m_arg_types.push_back( e.m_rettype->clone() );
+ ),
+ (Borrow,
+ // TODO: Autoderef?
+ return ;
+ ),
+ (Infer,
+ // No idea yet
+ return ;
+ )
+ )
+ assert( node.m_arg_types.size() == node.m_args.size() + 1 );
+ for(unsigned int i = 0; i < node.m_args.size(); i ++)
+ {
+ this->context.equate_types_coerce(node.span(), node.m_arg_types[i], node.m_args[i]);
+ }
+ this->context.equate_types(node.span(), node.m_res_type, node.m_arg_types.back());
+ this->m_completed = true;
}
void visit(::HIR::ExprNode_CallMethod& node) override {
const auto& ty = this->context.get_type(node.m_value->m_res_type);
@@ -1298,6 +1374,8 @@ namespace {
}
// Link arguments
+ // 1+ because it's a method call (#0 is Self)
+ DEBUG("node.m_cache.m_arg_types = " << node.m_cache.m_arg_types);
for(unsigned int i = 0; i < node.m_args.size(); i ++)
{
this->context.equate_types_coerce(node.span(), node.m_cache.m_arg_types[1+i], node.m_args[i]);
@@ -1991,6 +2069,7 @@ void Context::add_revisit(::HIR::ExprNode& node) {
}
void Context::possible_equate_type(unsigned int ivar_index, const ::HIR::TypeRef& t) {
+ DEBUG(ivar_index << " ?= " << t << " " << this->m_ivars.get_type(t));
{
::HIR::TypeRef ty_l;
ty_l.m_data.as_Infer().index = ivar_index;
@@ -2177,6 +2256,7 @@ namespace {
const auto& sp = node_ptr->span();
const auto& ty = context.m_ivars.get_type(v.left_ty);
const auto& ty_r = context.m_ivars.get_type(node_ptr->m_res_type);
+ TRACE_FUNCTION_F(v << " - " << ty << " := " << ty_r);
// TODO: CoerceUnsized trait