summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-05-05 21:58:06 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-05-05 21:58:06 +0800
commit92afcb37de80802d91164d9f1cd307c6964d1811 (patch)
tree85b7cfbea66deaab8819cc3733514fde7447bdde /src
parent203862df03f8ee9f49ab704063bd28523f13ba2d (diff)
downloadmrust-92afcb37de80802d91164d9f1cd307c6964d1811.tar.gz
HIR Expand Closures - Run on constants
Diffstat (limited to 'src')
-rw-r--r--src/hir/from_ast_expr.cpp6
-rw-r--r--src/hir_expand/closures.cpp71
2 files changed, 75 insertions, 2 deletions
diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp
index 7d676bf8..fdb2b867 100644
--- a/src/hir/from_ast_expr.cpp
+++ b/src/hir/from_ast_expr.cpp
@@ -227,6 +227,12 @@ struct LowerHIR_ExprNode_Visitor:
mv$( args )
) );
),
+ (Static,
+ m_rv.reset( new ::HIR::ExprNode_CallValue( v.span(),
+ ::HIR::ExprNodeP(new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::STATIC )),
+ mv$(args)
+ ) );
+ ),
//(TypeAlias,
// TODO(v.span(), "CallPath -> TupleVariant TypeAlias");
// ),
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index d7d476e5..ace154ff 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -9,6 +9,7 @@
#include <hir/expr.hpp>
#include <hir_typeck/static.hpp>
#include <algorithm>
+#include <hir/expr_state.hpp>
#include "main_bindings.hpp"
namespace {
@@ -1357,9 +1358,75 @@ namespace {
};
}
-void HIR_Expand_Closures_Expr(const ::HIR::Crate& crate, ::HIR::ExprPtr& exp)
+void HIR_Expand_Closures_Expr(const ::HIR::Crate& crate_ro, ::HIR::ExprPtr& exp)
{
- // TODO:
+ Span sp;
+ auto& crate = const_cast<::HIR::Crate&>(crate_ro);
+ TRACE_FUNCTION;
+
+ StaticTraitResolve resolve { crate };
+ assert(exp);
+ if(exp.m_state->m_impl_generics) resolve.set_impl_generics(*exp.m_state->m_impl_generics);
+ if(exp.m_state->m_item_generics) resolve.set_item_generics(*exp.m_state->m_item_generics);
+
+ const ::HIR::TypeRef* self_type = nullptr; // TODO: Need to be able to get this?
+
+ static int closure_count = 0;
+ out_impls_t new_trait_impls;
+ new_type_cb_t new_type_cb = [&](auto s)->::HIR::SimplePath {
+ auto name = FMT("closure#C_" << closure_count);
+ closure_count += 1;
+ auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { ::HIR::Publicity::new_none(), ::HIR::TypeItem( mv$(s) ) } ));
+ crate.m_root_module.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) );
+ return ::HIR::SimplePath(crate.m_crate_name, {}) + name;
+ };
+
+ {
+ ExprVisitor_Extract ev(resolve, self_type, exp.m_bindings, new_trait_impls, new_type_cb);
+ ev.visit_root( *exp );
+ }
+
+ {
+ ExprVisitor_Fixup fixup(crate, nullptr, [](const auto& x)->const auto&{ return x; });
+ fixup.visit_root( exp );
+ }
+
+ for(auto& impl : new_trait_impls)
+ {
+ for( auto& m : impl.second.m_methods )
+ {
+ m.second.data.m_code.m_state = ::HIR::ExprStatePtr(*exp.m_state);
+ m.second.data.m_code.m_state->stage = ::HIR::ExprState::Stage::Typecheck;
+ }
+ impl.second.m_src_module = exp.m_state->m_mod_path;
+ switch(impl.first)
+ {
+ case ::HIR::ExprNode_Closure::Class::Once:
+ crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_once"), mv$(impl.second)) );
+ break;
+ case ::HIR::ExprNode_Closure::Class::Mut:
+ crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_mut" ), mv$(impl.second)) );
+ break;
+ case ::HIR::ExprNode_Closure::Class::Shared:
+ crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn" ), mv$(impl.second)) );
+ break;
+ case ::HIR::ExprNode_Closure::Class::NoCapture:
+ assert(impl.second.m_methods.size() == 1);
+ assert(impl.second.m_types.empty());
+ assert(impl.second.m_constants.empty());
+ crate.m_type_impls.push_back( ::HIR::TypeImpl {
+ mv$(impl.second.m_params),
+ mv$(impl.second.m_type),
+ make_map1(impl.second.m_methods.begin()->first, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { ::HIR::Publicity::new_global(), false, mv$(impl.second.m_methods.begin()->second.data) }),
+ {},
+ mv$(impl.second.m_src_module)
+ } );
+ break;
+ case ::HIR::ExprNode_Closure::Class::Unknown:
+ BUG(Span(), "Encountered Unkown closure type in new impls");
+ break;
+ }
+ }
}
void HIR_Expand_Closures(::HIR::Crate& crate)