diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/expr.cpp | 33 | ||||
-rw-r--r-- | src/hir/hir.cpp | 3 | ||||
-rw-r--r-- | src/hir/type.cpp | 11 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 52 | ||||
-rw-r--r-- | src/hir_expand/ufcs_everything.cpp | 8 | ||||
-rw-r--r-- | src/hir_typeck/expr_check.cpp | 13 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 31 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 33 |
8 files changed, 147 insertions, 37 deletions
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index fdeff6b5..4fb79470 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -23,6 +23,7 @@ DEF_VISIT(ExprNode_Return, node, visit_node_ptr(node.m_value); ) DEF_VISIT(ExprNode_Let, node, + visit_type(node.m_type); if( node.m_value ) { visit_node_ptr(node.m_value); } @@ -76,19 +77,39 @@ DEF_VISIT(ExprNode_Deref, node, ) DEF_VISIT(ExprNode_TupleVariant, node, + visit_generic_path(::HIR::Visitor::PathContext::VALUE, node.m_path); + + for(auto& ty : node.m_arg_types) + visit_type(ty); + for(auto& arg : node.m_args) visit_node_ptr(arg); ) DEF_VISIT(ExprNode_CallPath, node, + for(auto& ty : node.m_cache.m_arg_types) + visit_type(ty); + visit_path_params(node.m_cache.m_ty_impl_params); + + DEBUG("DEF _CallPath: " << node.m_path); + visit_path(::HIR::Visitor::PathContext::VALUE, node.m_path); for(auto& arg : node.m_args) visit_node_ptr(arg); ) DEF_VISIT(ExprNode_CallValue, node, + for(auto& ty : node.m_arg_types) + visit_type(ty); + visit_node_ptr(node.m_value); for(auto& arg : node.m_args) visit_node_ptr(arg); ) DEF_VISIT(ExprNode_CallMethod, node, + for(auto& ty : node.m_cache.m_arg_types) + visit_type(ty); + visit_path_params(node.m_cache.m_ty_impl_params); + + visit_path(::HIR::Visitor::PathContext::VALUE, node.m_method_path); + visit_node_ptr(node.m_value); for(auto& arg : node.m_args) visit_node_ptr(arg); @@ -98,10 +119,15 @@ DEF_VISIT(ExprNode_Field, node, ) DEF_VISIT(ExprNode_Literal, , ) -DEF_VISIT(ExprNode_UnitVariant, , ) -DEF_VISIT(ExprNode_PathValue, , ) +DEF_VISIT(ExprNode_UnitVariant, node, + visit_generic_path(::HIR::Visitor::PathContext::VALUE, node.m_path); +) +DEF_VISIT(ExprNode_PathValue, node, + visit_path(::HIR::Visitor::PathContext::VALUE, node.m_path); +) DEF_VISIT(ExprNode_Variable, , ) DEF_VISIT(ExprNode_StructLiteral, node, + visit_generic_path(::HIR::Visitor::PathContext::VALUE, node.m_path); if( node.m_base_value ) visit_node_ptr(node.m_base_value); for(auto& val : node.m_values) @@ -121,6 +147,9 @@ DEF_VISIT(ExprNode_ArraySized, node, ) DEF_VISIT(ExprNode_Closure, node, + for(auto& arg : node.m_args) + visit_type(arg.second); + visit_type(node.m_return); if(node.m_code) { visit_node_ptr(node.m_code); diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index e090b795..4ff909aa 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -148,8 +148,7 @@ namespace { return false; ), (Closure, - DEBUG("TODO: Compare " << left << " and " << right); - return false; + return le.node == re.node; ) ) return false; diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 45b47519..c4dfb9c3 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -140,10 +140,13 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const os << ") -> " << *e.m_rettype; ), (Closure, - os << "closure["<<e.node<<"]("; + os << "closure["<<e.node<<"]"; + #if 0 + os << "("; for(const auto& t : e.m_arg_types) os << t << ", "; os << ") -> " << *e.m_rettype; + #endif ) ) } @@ -217,7 +220,7 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const if( xe.size_val != te.size_val ) return false; if( te.size_val == ~0u ) - assert(!"TOD: Compre array types with non-resolved sizes"); + assert(!"TODO: Compre array types with non-resolved sizes"); return true; ), (Slice, @@ -586,7 +589,9 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x TODO(sp, "Function"); ), (Closure, - TODO(sp, "Closure"); + if( te.node != xe.node ) + return Compare::Unequal; + return Compare::Equal; ) ) throw ""; diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 8fe46f0c..892b6bad 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -52,14 +52,29 @@ namespace { const ::std::vector<unsigned int>& m_local_vars; const ::std::vector<unsigned int>& m_captures; + typedef ::std::function< const ::HIR::TypeRef&(const ::HIR::TypeRef&)> t_monomorph_cb; + t_monomorph_cb m_monomorph_cb; + ::HIR::ExprNodeP m_replacement; public: - ExprVisitor_Mutate(const ::HIR::TypeRef& closure_type, const ::std::vector<unsigned int>& local_vars, const ::std::vector<unsigned int>& captures): + ExprVisitor_Mutate(const ::HIR::TypeRef& closure_type, const ::std::vector<unsigned int>& local_vars, const ::std::vector<unsigned int>& captures, t_monomorph_cb mcb): m_closure_type(closure_type), m_local_vars(local_vars), - m_captures(captures) + m_captures(captures), + m_monomorph_cb(mcb) { } + + void visit_type(::HIR::TypeRef& ty) override { + TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Generic, e, + auto n = m_monomorph_cb(ty).clone(); + ty = mv$(n); + ) + else { + ::HIR::ExprVisitorDef::visit_type(ty); + } + } + void visit_node_ptr(::HIR::ExprNodeP& node_ptr) override { assert( node_ptr ); auto& node = *node_ptr; @@ -70,6 +85,8 @@ namespace { if( m_replacement ) { node_ptr = mv$(m_replacement); } + + visit_type( node_ptr->m_res_type ); } void visit(::HIR::ExprNode_Closure& node) override { @@ -262,6 +279,8 @@ namespace { { const auto& sp = node.span(); + TRACE_FUNCTION_F("Extract closure - " << node.m_res_type); + // --- Determine borrow set --- m_closure_stack.push_back( ClosureScope(node) ); @@ -279,6 +298,7 @@ namespace { // 1. Construct closure type (saving path/index in the node) ::HIR::GenericParams params; ::HIR::PathParams constructor_path_params; + ::HIR::PathParams impl_path_params; // - 0xFFFF "Self" -> 0 "Super" constructor_path_params.m_types.push_back( ::HIR::TypeRef("Self", 0xFFFF) ); params.m_types.push_back( ::HIR::TypeParamDef { "Super", {}, false } ); // TODO: Maybe Self is sized? @@ -298,6 +318,7 @@ namespace { ::std::vector<::HIR::TypeRef> params_placeholders; for(unsigned int i = 0; i < params.m_types.size(); i ++) { params_placeholders.push_back( ::HIR::TypeRef(params.m_types[i].m_name, i) ); + impl_path_params.m_types.push_back( ::HIR::TypeRef(params.m_types[i].m_name, i) ); } auto monomorph_cb = [&](const auto& ty)->const auto& { @@ -342,13 +363,15 @@ namespace { params.m_bounds.push_back( monomorph_bound(bound) ); } - + + DEBUG("--- Mutate inner code"); // 2. Iterate over the nodes and rewrite variable accesses to either renumbered locals, or field accesses // - TODO: Monomorphise all referenced types within this. - ExprVisitor_Mutate ev { node.m_res_type, ent.local_vars, ent.node.m_var_captures }; + ExprVisitor_Mutate ev { node.m_res_type, ent.local_vars, ent.node.m_var_captures, monomorph_cb }; ev.visit_node_ptr( node.m_code ); // - Types of local variables + DEBUG("--- Build locals and captures"); ::std::vector< ::HIR::TypeRef> local_types; local_types.push_back( ::HIR::TypeRef() ); // self - filled by make_fn* local_types.push_back( ::HIR::TypeRef() ); // args - filled by make_fn* @@ -371,7 +394,10 @@ namespace { } )); + // Mark the object pathname in the closure. node.m_obj_path = ::HIR::GenericPath( m_module_path + m_out_types.back().first, mv$(constructor_path_params) ); + //node.m_res_type = ::HIR::TypeRef( node.m_obj_path.clone() ); + DEBUG("-- Object name: " << node.m_obj_path); // - Args ::std::vector< ::HIR::Pattern> args_pat_inner; @@ -382,13 +408,17 @@ namespace { } ::HIR::TypeRef args_ty { mv$(args_ty_inner) }; ::HIR::Pattern args_pat { {}, ::HIR::Pattern::Data::make_Tuple({ mv$(args_pat_inner) }) }; - + ::HIR::TypeRef ret_type = monomorphise_type_with(sp, node.m_return, monomorph_cb); + + DEBUG("args_ty = " << args_ty << ", ret_type = " << ret_type); + ::HIR::ExprPtr body_code { mv$(node.m_code) }; body_code.m_bindings = mv$(local_types); // 3. Create trait impls - ::HIR::TypeRef closure_type = node.m_res_type.clone(); - const ::HIR::TypeRef& ret_type = node.m_return; + //::HIR::TypeRef closure_type = node.m_res_type.clone(); + ::HIR::TypeRef closure_type = ::HIR::TypeRef( ::HIR::GenericPath(node.m_obj_path.m_path.clone(), mv$(impl_path_params)) ); + ::HIR::PathParams trait_params; trait_params.m_types.push_back( args_ty.clone() ); switch(node.m_class) @@ -443,7 +473,7 @@ namespace { // - Fn m_out_impls.push_back(::std::make_pair( ::HIR::ExprNode_Closure::Class::Shared, - H::make_fn( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), node.m_return.clone(), mv$(body_code) ) + H::make_fn( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), mv$(ret_type), mv$(body_code) ) )); } break; case ::HIR::ExprNode_Closure::Class::Mut: { @@ -466,21 +496,21 @@ namespace { ); m_out_impls.push_back(::std::make_pair( ::HIR::ExprNode_Closure::Class::Once, - H::make_fnonce( params.clone(), trait_params.clone(), closure_type.clone(), mv$(args_arg), node.m_return.clone(), mv$(dispatch_node) ) + H::make_fnonce( params.clone(), trait_params.clone(), closure_type.clone(), mv$(args_arg), ret_type.clone(), mv$(dispatch_node) ) )); } // - FnMut (code) m_out_impls.push_back(::std::make_pair( ::HIR::ExprNode_Closure::Class::Mut, - H::make_fnmut( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), node.m_return.clone(), mv$(body_code) ) + H::make_fnmut( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), mv$(ret_type), mv$(body_code) ) )); } break; case ::HIR::ExprNode_Closure::Class::Once: // - FnOnce (code) m_out_impls.push_back(::std::make_pair( ::HIR::ExprNode_Closure::Class::Once, - H::make_fnonce( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), node.m_return.clone(), mv$(body_code) ) + H::make_fnonce( mv$(params), mv$(trait_params), mv$(closure_type), ::std::make_pair(mv$(args_pat), mv$(args_ty)), mv$(ret_type), mv$(body_code) ) )); break; } diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp index 6e7b42e5..91b6aaa3 100644 --- a/src/hir_expand/ufcs_everything.cpp +++ b/src/hir_expand/ufcs_everything.cpp @@ -36,6 +36,8 @@ namespace { root->visit(*this); if( m_replacement ) { auto usage = root->m_usage; + const auto* ptr = m_replacement.get(); + DEBUG("=> REPLACE " << ptr << " " << typeid(*ptr).name()); root.reset( m_replacement.release() ); root->m_usage = usage; } @@ -49,6 +51,8 @@ namespace { node->visit(*this); if( m_replacement ) { auto usage = node->m_usage; + const auto* ptr = m_replacement.get(); + DEBUG("=> REPLACE " << ptr << " " << typeid(*ptr).name()); node = mv$(m_replacement); node->m_usage = usage; } @@ -74,8 +78,8 @@ namespace { ::HIR::TypeRef arg_tup_type; { ::std::vector< ::HIR::TypeRef> arg_types; - for(unsigned int i = 0; i < node.m_arg_types.size() - 1; i ++) - arg_types.push_back( node.m_arg_types[i].clone() ); + for(unsigned int i = 0; i < node.m_args.size(); i ++) + arg_types.push_back( node.m_args[i]->m_res_type.clone() ); arg_tup_type = ::HIR::TypeRef( mv$(arg_types) ); } // - Make the trait arguments. diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index bbe028d0..83051653 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -341,6 +341,7 @@ namespace { ASSERT_BUG(sp, fields.size() == node.m_args.size(), ""); // Bind fields with type params (coercable) + // TODO: Remove use of m_arg_types (maybe assert that cache is correct?) for( unsigned int i = 0; i < node.m_args.size(); i ++ ) { const auto& des_ty_r = fields[i].ent; @@ -440,6 +441,10 @@ namespace { const auto& sp = node.span(); TRACE_FUNCTION_F(&node << " " << node.m_path << "(..., )"); + for( auto& val : node.m_args ) { + val->visit( *this ); + } + // Do function resolution again, this time with concrete types. const auto& path = node.m_path; /*const*/ auto& cache = node.m_cache; @@ -600,8 +605,10 @@ namespace { // Check types for(unsigned int i = 0; i < node.m_args.size(); i ++) { + DEBUG("CHECK ARG " << i << " " << node.m_cache.m_arg_types[i] << " == " << node.m_args[i]->m_res_type); check_types_equal(node.span(), node.m_cache.m_arg_types[i], node.m_args[i]->m_res_type); } + DEBUG("CHECK RV " << node.m_res_type << " == " << node.m_cache.m_arg_types.back()); check_types_equal(node.span(), node.m_res_type, node.m_cache.m_arg_types.back()); cache.m_monomorph_cb = mv$(monomorph_cb); @@ -643,14 +650,11 @@ namespace { ) ) } - - for( auto& val : node.m_args ) { - val->visit( *this ); - } } void visit(::HIR::ExprNode_CallValue& node) override { TRACE_FUNCTION_F(&node << " (...)(..., )"); + // TODO: Don't use m_arg_types (do full resolution again) ASSERT_BUG(node.span(), node.m_arg_types.size() > 0, "CallValue cache not populated"); for(unsigned int i = 0; i < node.m_args.size(); i ++) { @@ -668,6 +672,7 @@ namespace { void visit(::HIR::ExprNode_CallMethod& node) override { TRACE_FUNCTION_F(&node << " (...)." << node.m_method << "(...,) - " << node.m_method_path); + // TODO: Don't use m_cache ASSERT_BUG(node.span(), node.m_cache.m_arg_types.size() > 0, "CallMethod cache not populated"); ASSERT_BUG(node.span(), node.m_cache.m_arg_types.size() == 1 + node.m_args.size() + 1, "CallMethod cache mis-sized"); check_types_equal(node.m_cache.m_arg_types[0], node.m_value); diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 9f56527e..8abb7174 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -397,21 +397,28 @@ void StaticTraitResolve::expand_associated_types(const Span& sp, ::HIR::TypeRef& // - If it's a closure, then the only trait impls are those generated by typeck TU_IFLET(::HIR::TypeRef::Data, e2.type->m_data, Closure, te, - const auto trait_fn = this->m_crate.get_lang_item_path(sp, "fn"); - const auto trait_fn_mut = this->m_crate.get_lang_item_path(sp, "fn_mut"); - const auto trait_fn_once = this->m_crate.get_lang_item_path(sp, "fn_once"); - if( e2.trait.m_path == trait_fn || e2.trait.m_path == trait_fn_mut || e2.trait.m_path == trait_fn_once ) { - if( e2.item == "Output" ) { - input = te.m_rettype->clone(); - return ; + //if( te.node->m_obj_path == ::HIR::GenericPath() ) + //{ + const auto trait_fn = this->m_crate.get_lang_item_path(sp, "fn"); + const auto trait_fn_mut = this->m_crate.get_lang_item_path(sp, "fn_mut"); + const auto trait_fn_once = this->m_crate.get_lang_item_path(sp, "fn_once"); + if( e2.trait.m_path == trait_fn || e2.trait.m_path == trait_fn_mut || e2.trait.m_path == trait_fn_once ) { + if( e2.item == "Output" ) { + input = te.m_rettype->clone(); + return ; + } + else { + ERROR(sp, E0000, "No associated type " << e2.item << " for trait " << e2.trait); + } } else { - ERROR(sp, E0000, "No associated type " << e2.item << " for trait " << e2.trait); + ERROR(sp, E0000, "No implementation of " << e2.trait << " for " << *e2.type); } - } - else { - ERROR(sp, E0000, "No implementation of " << e2.trait << " for " << *e2.type); - } + //} + //else + //{ + // // TODO: Locate impl _without_ binding params too hard? + //} ) // 1. Bounds diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index ef0cf3a6..4c9d1aaf 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -845,10 +845,41 @@ namespace { void visit(::HIR::ExprNode_CallValue& node) override { - BUG(node.span(), "Leftover _CallValue"); + TRACE_FUNCTION_F("_CallValue " << node.m_value->m_res_type); + + // _CallValue is ONLY valid on function pointers (all others must be desugared) + ASSERT_BUG(node.span(), node.m_value->m_res_type.m_data.is_Function(), "Leftover _CallValue on a non-fn()"); + this->visit_node_ptr(node.m_value); + auto fcn_val = m_builder.lvalue_or_temp( node.m_value->m_res_type, m_builder.get_result(node.m_value->span()) ); + + ::std::vector< ::MIR::LValue> values; + values.reserve( node.m_args.size() ); + for(auto& arg : node.m_args) + { + this->visit_node_ptr(arg); + values.push_back( m_builder.lvalue_or_temp( arg->m_res_type, m_builder.get_result(arg->span()) ) ); + } + + + auto panic_block = m_builder.new_bb_unlinked(); + auto next_block = m_builder.new_bb_unlinked(); + auto res = m_builder.new_temporary( node.m_res_type ); + m_builder.end_block(::MIR::Terminator::make_Call({ + next_block, panic_block, + res.clone(), mv$(fcn_val), + mv$(values) + })); + + m_builder.set_cur_block(panic_block); + // TODO: Proper panic handling + m_builder.end_block( ::MIR::Terminator::make_Diverge({}) ); + + m_builder.set_cur_block( next_block ); + m_builder.set_result( node.span(), mv$(res) ); } void visit(::HIR::ExprNode_CallMethod& node) override { + // TODO: Allow use on trait objects. BUG(node.span(), "Leftover _CallMethod"); } void visit(::HIR::ExprNode_Field& node) override |