summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/expr.hpp2
-rw-r--r--src/hir_expand/closures.cpp28
-rw-r--r--src/mir/from_hir.cpp33
3 files changed, 53 insertions, 10 deletions
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 4e75e321..203f878e 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -675,6 +675,8 @@ struct ExprNode_Closure:
// - Lists captured variables to be stored in autogenerated struct
::std::vector<unsigned int> m_var_captures;
+ // - Path to the generated closure type
+ ::HIR::GenericPath m_obj_path;
ExprNode_Closure(Span sp, args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code):
ExprNode(mv$(sp)),
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index f1a922ed..b76a61ca 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -215,6 +215,7 @@ namespace {
};
const StaticTraitResolve& m_resolve;
+ const ::HIR::SimplePath& m_module_path;
::std::vector< ::HIR::TypeRef>& m_variable_types;
// Outputs
@@ -226,8 +227,9 @@ namespace {
/// Stack of active closures
::std::vector<ClosureScope> m_closure_stack;
public:
- ExprVisitor_Extract(const StaticTraitResolve& resolve, ::std::vector< ::HIR::TypeRef>& var_types, out_impls_t& out_impls, out_types_t& out_types):
+ ExprVisitor_Extract(const StaticTraitResolve& resolve, const ::HIR::SimplePath& mod_path, ::std::vector< ::HIR::TypeRef>& var_types, out_impls_t& out_impls, out_types_t& out_types):
m_resolve(resolve),
+ m_module_path(mod_path),
m_variable_types(var_types),
m_out_impls( out_impls ),
m_out_types( out_types )
@@ -264,13 +266,17 @@ namespace {
// Includes:
// - Generics based on the current scope (compacted)
::HIR::GenericParams params;
+ ::HIR::PathParams constructor_path_params;
+ 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?
unsigned ofs_impl = params.m_types.size();
for(const auto& ty_def : m_resolve.impl_generics().m_types) {
+ constructor_path_params.m_types.push_back( ::HIR::TypeRef( ty_def.m_name, 0*256 + params.m_types.size() - ofs_impl ) );
params.m_types.push_back( ::HIR::TypeParamDef { ty_def.m_name, {}, ty_def.m_is_sized } );
}
unsigned ofs_item = params.m_types.size();
for(const auto& ty_def : m_resolve.item_generics().m_types) {
+ constructor_path_params.m_types.push_back( ::HIR::TypeRef( ty_def.m_name, 1*256 + params.m_types.size() - ofs_item ) );
params.m_types.push_back( ::HIR::TypeParamDef { ty_def.m_name, {}, ty_def.m_is_sized } );
}
@@ -313,6 +319,8 @@ namespace {
}
));
+ node.m_obj_path = ::HIR::GenericPath( m_module_path + m_out_types.back().first, mv$(constructor_path_params) );
+
// - Args
::std::vector< ::HIR::Pattern> args_pat_inner;
::std::vector< ::HIR::TypeRef> args_ty_inner;
@@ -735,9 +743,11 @@ namespace {
StaticTraitResolve m_resolve;
out_impls_t m_new_trait_impls;
out_types_t m_new_types;
+ const ::HIR::SimplePath* m_cur_mod_path;
public:
OuterVisitor(const ::HIR::Crate& crate):
- m_resolve(crate)
+ m_resolve(crate),
+ m_cur_mod_path( nullptr )
{}
void visit_crate(::HIR::Crate& crate) override
@@ -759,7 +769,11 @@ namespace {
void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override
{
+ auto saved = m_cur_mod_path;
+ auto path = p.get_simple_path();
+ m_cur_mod_path = &path;
::HIR::Visitor::visit_module(p, mod);
+ m_cur_mod_path = saved;
// - Insert newly created closure types
auto new_types = mv$(m_new_types);
@@ -800,9 +814,9 @@ namespace {
auto _ = this->m_resolve.set_item_generics(item.m_params);
if( item.m_code )
{
+ assert( m_cur_mod_path );
DEBUG("Function code " << p);
- //ExprVisitor_Extract ev(item.m_code.binding_types);
- ExprVisitor_Extract ev(m_resolve, item.m_code.m_bindings, m_new_trait_impls, m_new_types);
+ ExprVisitor_Extract ev(m_resolve, *m_cur_mod_path, item.m_code.m_bindings, m_new_trait_impls, m_new_types);
ev.visit_root( *item.m_code );
}
else
@@ -814,7 +828,7 @@ namespace {
if( item.m_value )
{
//::std::vector< ::HIR::TypeRef> tmp;
- //ExprVisitor_Extract ev(m_resolve, tmp, m_new_trait_impls);
+ //ExprVisitor_Extract ev(m_resolve, *m_cur_mod_path, tmp, m_new_trait_impls);
//ev.visit_root(*item.m_value);
}
}
@@ -846,10 +860,13 @@ namespace {
auto _ = this->m_resolve.set_impl_generics(item.m_params);
::HIR::Visitor::visit_trait(p, item);
}
+
+
void visit_type_impl(::HIR::TypeImpl& impl) override
{
TRACE_FUNCTION_F("impl " << impl.m_type);
auto _ = this->m_resolve.set_impl_generics(impl.m_params);
+ m_cur_mod_path = &impl.m_src_module;
::HIR::Visitor::visit_type_impl(impl);
}
@@ -857,6 +874,7 @@ namespace {
{
TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
auto _ = this->m_resolve.set_impl_generics(impl.m_params);
+ m_cur_mod_path = &impl.m_src_module;
::HIR::Visitor::visit_trait_impl(trait_path, impl);
}
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 6420619e..6123c834 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -437,6 +437,7 @@ namespace {
public ::HIR::ExprVisitor
{
MirBuilder m_builder;
+ const ::std::vector< ::HIR::TypeRef>& m_variable_types;
struct LoopDesc {
::std::string label;
@@ -450,8 +451,9 @@ namespace {
::std::vector<BlockDesc> m_block_stack;
public:
- ExprVisitor_Conv(::MIR::Function& output):
- m_builder(output)
+ ExprVisitor_Conv(::MIR::Function& output, const ::std::vector< ::HIR::TypeRef>& var_types):
+ m_builder(output),
+ m_variable_types(var_types)
{
}
@@ -1666,8 +1668,29 @@ namespace {
void visit(::HIR::ExprNode_Closure& node) override
{
- TRACE_FUNCTION_F("_Closure");
- TODO(node.span(), "_Closure");
+ TRACE_FUNCTION_F("_Closure - " << node.m_obj_path);
+
+ // Emit construction of the closure.
+ ::std::vector< ::MIR::LValue> vals;
+ for( const auto cap_idx : node.m_var_captures )
+ {
+ if( node.m_is_move ) {
+ vals.push_back( ::MIR::LValue::make_Variable(cap_idx) );
+ }
+ else {
+ auto borrow_ty = ::HIR::BorrowType::Shared;
+ auto lval = m_builder.lvalue_or_temp(
+ ::HIR::TypeRef::new_borrow(borrow_ty, m_variable_types.at(cap_idx).clone()),
+ ::MIR::RValue::make_Borrow({ 0, borrow_ty, ::MIR::LValue::make_Variable(cap_idx) })
+ );
+ vals.push_back( mv$(lval) );
+ }
+ }
+
+ m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({
+ node.m_obj_path.clone(),
+ mv$(vals)
+ }) );
}
};
}
@@ -1677,7 +1700,7 @@ namespace {
{
::MIR::Function fcn;
- ExprVisitor_Conv ev { fcn };
+ ExprVisitor_Conv ev { fcn, ptr.m_bindings };
// 1. Apply destructuring to arguments
unsigned int i = 0;