summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-08 14:31:06 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-08 14:31:06 +0800
commit6a6fed23f8293712a0e504de07d39c8baf6150a0 (patch)
tree6ffa897116d51e0461a101ac80d73b6903c56298
parent564bdfbb3ecb99ccf1dc25fdd7c11fdab6ddc6a8 (diff)
downloadmrust-6a6fed23f8293712a0e504de07d39c8baf6150a0.tar.gz
HIR Typecheck+Expand - Type annotations to allow generated closure code to pass
-rw-r--r--src/hir_expand/closures.cpp353
-rw-r--r--src/hir_typeck/expr_check.cpp26
-rw-r--r--src/hir_typeck/helpers.hpp9
-rw-r--r--src/hir_typeck/static.hpp9
4 files changed, 273 insertions, 124 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index e5374327..1030c5a3 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -12,9 +12,9 @@
#include "main_bindings.hpp"
namespace {
- inline HIR::ExprNodeP mk_exprnodep(HIR::ExprNode* en){ return HIR::ExprNodeP(en); }
+ inline HIR::ExprNodeP mk_exprnodep(HIR::ExprNode* en, ::HIR::TypeRef ty){ en->m_res_type = mv$(ty); return HIR::ExprNodeP(en); }
}
-#define NEWNODE(type, ...) mk_exprnodep(new HIR::ExprNode_##type(__VA_ARGS__))
+#define NEWNODE(TY, CLASS, ...) mk_exprnodep(new HIR::ExprNode_##CLASS(__VA_ARGS__), TY)
namespace {
@@ -35,16 +35,27 @@ namespace {
rv.push_back( mv$(v2) );
return rv;
}
+ template<typename T>
+ ::std::vector<T> make_vec3(T v1, T v2, T v3) {
+ ::std::vector<T> rv;
+ rv.reserve(3);
+ rv.push_back( mv$(v1) );
+ rv.push_back( mv$(v2) );
+ rv.push_back( mv$(v3) );
+ return rv;
+ }
class ExprVisitor_Mutate:
public ::HIR::ExprVisitorDef
{
+ const ::HIR::TypeRef& m_closure_type;
const ::std::vector<unsigned int>& m_local_vars;
const ::std::vector<unsigned int>& m_captures;
::HIR::ExprNodeP m_replacement;
public:
- ExprVisitor_Mutate(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):
+ m_closure_type(closure_type),
m_local_vars(local_vars),
m_captures(captures)
{
@@ -75,8 +86,8 @@ namespace {
// 2. Is it a capture?
binding_it = ::std::find(m_captures.begin(), m_captures.end(), node.m_slot);
if( binding_it != m_captures.end() ) {
- m_replacement = NEWNODE(Field, node.span(),
- NEWNODE(Variable, node.span(), "self", 0),
+ m_replacement = NEWNODE(node.m_res_type.clone(), Field, node.span(),
+ NEWNODE(m_closure_type.clone(), Variable, node.span(), "self", 0),
FMT(binding_it - m_captures.begin())
);
return ;
@@ -86,6 +97,101 @@ namespace {
}
};
+ struct H {
+ static ::HIR::TraitImpl make_fnonce(
+ ::HIR::GenericParams params,
+ ::HIR::PathParams trait_params,
+ ::HIR::TypeRef closure_type,
+ ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
+ ::HIR::TypeRef ret_ty,
+ ::HIR::ExprNodeP code
+ )
+ {
+ return ::HIR::TraitImpl {
+ mv$(params), mv$(trait_params), mv$(closure_type),
+ make_map1(
+ ::std::string("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
+ "rust", false, false,
+ {},
+ make_vec2(
+ ::std::make_pair(::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} }, ::HIR::TypeRef("Self", 0xFFFF)),
+ mv$( args_argent )
+ ),
+ ret_ty.clone(),
+ mv$(code)
+ } }
+ ),
+ {},
+ make_map1(
+ ::std::string("Output"), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { false, mv$(ret_ty) }
+ ),
+ ::HIR::SimplePath()
+ };
+ }
+ static ::HIR::TraitImpl make_fnmut(
+ ::HIR::GenericParams params,
+ ::HIR::PathParams trait_params,
+ ::HIR::TypeRef closure_type,
+ ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
+ ::HIR::TypeRef ret_ty,
+ ::HIR::ExprNodeP code
+ )
+ {
+ return ::HIR::TraitImpl {
+ mv$(params), mv$(trait_params), mv$(closure_type),
+ make_map1(
+ ::std::string("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
+ "rust", false, false,
+ {},
+ make_vec2(
+ ::std::make_pair(
+ ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} },
+ ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Unique, ::HIR::TypeRef("Self", 0xFFFF) )
+ ),
+ mv$( args_argent )
+ ),
+ ret_ty.clone(),
+ mv$(code)
+ } }
+ ),
+ {},
+ {},
+ ::HIR::SimplePath()
+ };
+ }
+ static ::HIR::TraitImpl make_fn(
+ ::HIR::GenericParams params,
+ ::HIR::PathParams trait_params,
+ ::HIR::TypeRef closure_type,
+ ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
+ ::HIR::TypeRef ret_ty,
+ ::HIR::ExprNodeP code
+ )
+ {
+ return ::HIR::TraitImpl {
+ mv$(params), mv$(trait_params), mv$(closure_type),
+ make_map1(
+ ::std::string("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
+ "rust", false, false,
+ {},
+ make_vec2(
+ ::std::make_pair(
+ ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} },
+ ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ::HIR::TypeRef("Self", 0xFFFF) )
+ ),
+ mv$(args_argent)
+ ),
+ ret_ty.clone(),
+ mv$(code)
+ } }
+ ),
+ {},
+ {},
+ ::HIR::SimplePath()
+ };
+ }
+ };
+
class ExprVisitor_Extract:
public ::HIR::ExprVisitorDef
{
@@ -135,36 +241,66 @@ namespace {
{
const auto& sp = node.span();
+ // --- Determine borrow set ---
m_closure_stack.push_back( ClosureScope(node) );
- ::std::vector< ::HIR::Pattern> args_pat_inner;
- ::std::vector< ::HIR::TypeRef> args_ty_inner;
for(const auto& arg : node.m_args) {
- args_pat_inner.push_back( arg.first.clone() );
- args_ty_inner.push_back( arg.second.clone() );
add_closure_def_from_pattern(node.span(), arg.first);
}
- ::HIR::TypeRef args_ty { mv$(args_ty_inner) };
- ::HIR::Pattern args_pat { {}, ::HIR::Pattern::Data::make_Tuple({ mv$(args_pat_inner) }) };
::HIR::ExprVisitorDef::visit(node);
auto ent = mv$( m_closure_stack.back() );
m_closure_stack.pop_back();
- // Extract and mutate code into a trait impl on the closure type
+ // --- Extract and mutate code into a trait impl on the closure type ---
// 1. Iterate over the nodes and rewrite variable accesses to either renumbered locals, or field accesses
- ExprVisitor_Mutate ev { ent.local_vars, ent.node.m_var_captures };
+ ExprVisitor_Mutate ev { node.m_res_type, ent.local_vars, ent.node.m_var_captures };
ev.visit_node_ptr( node.m_code );
// 2. Construct closure type (saving path/index in the node)
// Includes:
// - Generics based on the current scope (compacted)
::HIR::GenericParams params;
- // - Types of captured variables
+ 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) {
+ 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) {
+ params.m_types.push_back( ::HIR::TypeParamDef { ty_def.m_name, {}, ty_def.m_is_sized } );
+ }
+
+ ::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) );
+ }
+
+ // - Types of captured variables (to be monomorphised)
+ auto monomorph_cb = [&](const auto& ty)->const auto& {
+ const auto& ge = ty.m_data.as_Generic();
+ if( ge.binding == 0xFFFF ) {
+ return params_placeholders.at(0);
+ }
+ else if( ge.binding < 256 ) {
+ auto idx = ge.binding;
+ ASSERT_BUG(sp, ofs_impl + idx < params_placeholders.size(), "Impl generic binding OOR - " << ty << " (" << ofs_impl + idx << " !< " << params_placeholders.size() << ")");
+ return params_placeholders.at(ofs_impl + idx);
+ }
+ else if( ge.binding < 2*256 ) {
+ auto idx = ge.binding - 256;
+ ASSERT_BUG(sp, ofs_item + idx < params_placeholders.size(), "Item generic binding OOR - " << ty << " (" << ofs_item + idx << " !< " << params_placeholders.size() << ")");
+ return params_placeholders.at(ofs_item + idx);
+ }
+ else {
+ BUG(sp, "Generic type " << ty << " unknown");
+ }
+ };
::std::vector< ::HIR::VisEnt< ::HIR::TypeRef> > capture_types;
for(const auto binding_idx : node.m_var_captures) {
- capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { false, m_variable_types.at(binding_idx).clone() } );
+ auto ty_mono = monomorphise_type_with(sp, m_variable_types.at(binding_idx).clone(), monomorph_cb);
+ capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { false, mv$(ty_mono) } );
}
m_out_types.push_back( ::std::make_pair(
FMT("closure_" << &node),
@@ -175,104 +311,21 @@ namespace {
}
));
- struct H {
- static ::HIR::TraitImpl make_fnonce(
- ::HIR::GenericParams params,
- ::HIR::PathParams trait_params,
- ::HIR::TypeRef closure_type,
- ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
- ::HIR::TypeRef ret_ty,
- ::HIR::ExprNodeP code
- )
- {
- return ::HIR::TraitImpl {
- mv$(params), mv$(trait_params), mv$(closure_type),
- make_map1(
- ::std::string("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
- "rust", false, false,
- {},
- make_vec2(
- ::std::make_pair(::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} }, ::HIR::TypeRef("Self", 0xFFFF)),
- mv$( args_argent )
- ),
- ret_ty.clone(),
- mv$(code)
- } }
- ),
- {},
- make_map1(
- ::std::string("Output"), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { false, mv$(ret_ty) }
- ),
- ::HIR::SimplePath()
- };
- }
- static ::HIR::TraitImpl make_fnmut(
- ::HIR::GenericParams params,
- ::HIR::PathParams trait_params,
- ::HIR::TypeRef closure_type,
- ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
- ::HIR::TypeRef ret_ty,
- ::HIR::ExprNodeP code
- )
- {
- return ::HIR::TraitImpl {
- mv$(params), mv$(trait_params), mv$(closure_type),
- make_map1(
- ::std::string("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
- "rust", false, false,
- {},
- make_vec2(
- ::std::make_pair(
- ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} },
- ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Unique, ::HIR::TypeRef("Self", 0xFFFF) )
- ),
- mv$( args_argent )
- ),
- ret_ty.clone(),
- mv$(code)
- } }
- ),
- {},
- {},
- ::HIR::SimplePath()
- };
- }
- static ::HIR::TraitImpl make_fn(
- ::HIR::GenericParams params,
- ::HIR::PathParams trait_params,
- ::HIR::TypeRef closure_type,
- ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> args_argent,
- ::HIR::TypeRef ret_ty,
- ::HIR::ExprNodeP code
- )
- {
- return ::HIR::TraitImpl {
- mv$(params), mv$(trait_params), mv$(closure_type),
- make_map1(
- ::std::string("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function {
- "rust", false, false,
- {},
- make_vec2(
- ::std::make_pair(
- ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "self", 0}, {} },
- ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ::HIR::TypeRef("Self", 0xFFFF) )
- ),
- mv$(args_argent)
- ),
- ret_ty.clone(),
- mv$(code)
- } }
- ),
- {},
- {},
- ::HIR::SimplePath()
- };
- }
- };
+ // - Args
+ ::std::vector< ::HIR::Pattern> args_pat_inner;
+ ::std::vector< ::HIR::TypeRef> args_ty_inner;
+ for(const auto& arg : node.m_args) {
+ args_pat_inner.push_back( arg.first.clone() );
+ args_ty_inner.push_back( monomorphise_type_with(sp, arg.second, monomorph_cb) );
+ }
+ ::HIR::TypeRef args_ty { mv$(args_ty_inner) };
+ ::HIR::Pattern args_pat { {}, ::HIR::Pattern::Data::make_Tuple({ mv$(args_pat_inner) }) };
// 3. Create trait impls
::HIR::TypeRef closure_type = node.m_res_type.clone();
+ const ::HIR::TypeRef& ret_type = node.m_return;
::HIR::PathParams trait_params;
+ trait_params.m_types.push_back( args_ty.clone() );
switch(node.m_class)
{
case ::HIR::ExprNode_Closure::Class::Unknown:
@@ -280,41 +333,44 @@ namespace {
case ::HIR::ExprNode_Closure::Class::NoCapture:
case ::HIR::ExprNode_Closure::Class::Shared: {
const auto& lang_Fn = m_resolve.m_crate.get_lang_item_path(node.span(), "fn");
+ const auto method_self_ty = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, closure_type.clone() );
// - FnOnce
{
- auto dispatch_node = NEWNODE(CallPath, sp,
- ::HIR::Path(closure_type.clone(), lang_Fn, "call"),
+ auto dispatch_node = NEWNODE(ret_type.clone(), CallPath, sp,
+ ::HIR::Path(closure_type.clone(), ::HIR::GenericPath(lang_Fn, trait_params.clone()), "call"),
make_vec2(
- NEWNODE(UniOp, sp, ::HIR::ExprNode_UniOp::Op::Ref, NEWNODE(Variable, sp, "self", 0)),
- NEWNODE(Variable, sp, "arg", 1)
+ NEWNODE(method_self_ty.clone(), UniOp, sp, ::HIR::ExprNode_UniOp::Op::Ref, NEWNODE(closure_type.clone(), Variable, sp, "self", 0)),
+ NEWNODE(args_ty.clone(), Variable, sp, "arg", 1)
)
);
+ dynamic_cast<::HIR::ExprNode_CallPath&>(*dispatch_node).m_cache.m_arg_types = make_vec3( method_self_ty.clone(), args_ty.clone(), ret_type.clone() );
auto args_arg = ::std::make_pair(
::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "args", 1}, {} },
args_ty.clone()
);
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
{
- auto dispatch_node = NEWNODE(CallPath, sp,
- ::HIR::Path(closure_type.clone(), lang_Fn, "call"),
+ auto dispatch_node = NEWNODE(ret_type.clone(), CallPath, sp,
+ ::HIR::Path(closure_type.clone(), ::HIR::GenericPath(lang_Fn, trait_params.clone()), "call"),
make_vec2(
- NEWNODE(UniOp, sp, ::HIR::ExprNode_UniOp::Op::Ref, NEWNODE(Deref, sp, NEWNODE(Variable, sp, "self", 0))),
- NEWNODE(Variable, sp, "arg", 1)
+ NEWNODE(method_self_ty.clone(), UniOp, sp, ::HIR::ExprNode_UniOp::Op::Ref, NEWNODE(closure_type.clone(), Deref, sp, NEWNODE(::HIR::TypeRef(), Variable, sp, "self", 0))),
+ NEWNODE(args_ty.clone(), Variable, sp, "arg", 1)
)
);
+ dynamic_cast<::HIR::ExprNode_CallPath&>(*dispatch_node).m_cache.m_arg_types = make_vec3( method_self_ty.clone(), args_ty.clone(), ret_type.clone() );
auto args_arg = ::std::make_pair(
::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "args", 1}, {} },
args_ty.clone()
);
m_out_impls.push_back(::std::make_pair(
::HIR::ExprNode_Closure::Class::Mut,
- H::make_fnmut( params.clone(), trait_params.clone(), closure_type.clone(), mv$(args_arg), node.m_return.clone(), mv$(dispatch_node) )
+ H::make_fnmut( params.clone(), trait_params.clone(), closure_type.clone(), mv$(args_arg), ret_type.clone(), mv$(dispatch_node) )
));
}
@@ -326,16 +382,18 @@ namespace {
} break;
case ::HIR::ExprNode_Closure::Class::Mut: {
const auto& lang_FnMut = m_resolve.m_crate.get_lang_item_path(node.span(), "fn_mut");
+ const auto method_self_ty = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Unique, closure_type.clone() );
// - FnOnce
{
- auto dispatch_node = NEWNODE(CallPath, sp,
- ::HIR::Path(closure_type.clone(), lang_FnMut, "call"),
+ auto dispatch_node = NEWNODE(ret_type.clone(), CallPath, sp,
+ ::HIR::Path(closure_type.clone(), ::HIR::GenericPath(lang_FnMut, trait_params.clone()), "call"),
make_vec2(
- NEWNODE(UniOp, sp, ::HIR::ExprNode_UniOp::Op::RefMut, NEWNODE(Variable, sp, "self", 0)),
- NEWNODE(Variable, sp, "arg", 1)
+ NEWNODE(method_self_ty.clone(), UniOp, sp, ::HIR::ExprNode_UniOp::Op::RefMut, NEWNODE(closure_type.clone(), Variable, sp, "self", 0)),
+ NEWNODE(args_ty.clone(), Variable, sp, "arg", 1)
)
);
+ dynamic_cast<::HIR::ExprNode_CallPath&>(*dispatch_node).m_cache.m_arg_types = make_vec3( method_self_ty.clone(), args_ty.clone(), ret_type.clone() );
auto args_arg = ::std::make_pair(
::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "args", 1}, {} },
args_ty.clone()
@@ -678,9 +736,36 @@ namespace {
m_resolve(crate)
{}
+ void visit_crate(::HIR::Crate& crate) override
+ {
+ Span sp;
+ ::HIR::Visitor::visit_crate(crate);
+
+ for(auto& impl : m_new_trait_impls)
+ {
+ const auto& trait =
+ impl.first == ::HIR::ExprNode_Closure::Class::Once ? crate.get_lang_item_path(sp, "fn_once")
+ : impl.first == ::HIR::ExprNode_Closure::Class::Mut ? crate.get_lang_item_path(sp, "fn_mut")
+ : /*impl.first == ::HIR::ExprNode_Closure::Class::Shared ?*/ crate.get_lang_item_path(sp, "fn")
+ ;
+ crate.m_trait_impls.insert( ::std::make_pair(trait.clone(), mv$(impl.second)) );
+ }
+ m_new_trait_impls.resize(0);
+ }
+
void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override
{
::HIR::Visitor::visit_module(p, mod);
+
+ // - Insert newly created closure types
+ auto new_types = mv$(m_new_types);
+ for(auto& ty_def : new_types)
+ {
+ mod.m_mod_items.insert( ::std::make_pair(
+ mv$(ty_def.first),
+ box$(( ::HIR::VisEnt< ::HIR::TypeItem> { false, ::HIR::TypeItem(mv$(ty_def.second)) } ))
+ ));
+ }
}
// NOTE: This is left here to ensure that any expressions that aren't handled by higher code cause a failure
@@ -708,7 +793,7 @@ namespace {
// Code-containing items
// ------
void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override {
- //auto _ = this->m_ms.set_item_generics(item.m_params);
+ auto _ = this->m_resolve.set_item_generics(item.m_params);
if( item.m_code )
{
DEBUG("Function code " << p);
@@ -753,6 +838,26 @@ namespace {
)
}
}
+
+ void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override
+ {
+ 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);
+
+ ::HIR::Visitor::visit_type_impl(impl);
+ }
+ void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
+ {
+ TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
+ auto _ = this->m_resolve.set_impl_generics(impl.m_params);
+
+ ::HIR::Visitor::visit_trait_impl(trait_path, impl);
+ }
};
}
diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp
index 838c653c..89bde549 100644
--- a/src/hir_typeck/expr_check.cpp
+++ b/src/hir_typeck/expr_check.cpp
@@ -439,6 +439,8 @@ namespace {
{
TRACE_FUNCTION_F(&node << " " << node.m_path << "(..., )");
// Link arguments
+ // - NOTE: The last entry in m_arg_types is the return type
+ ASSERT_BUG(node.span(), node.m_cache.m_arg_types.size() == node.m_args.size() + 1, "Cache and aruments disagree - " << node.m_cache.m_arg_types << " vs " << node.m_args.size());
for(unsigned int i = 0; i < node.m_args.size(); i ++)
{
check_types_equal(node.span(), node.m_cache.m_arg_types[i], node.m_args[i]->m_res_type);
@@ -495,6 +497,10 @@ namespace {
{
ASSERT_BUG(sp, is_index, "Non-index _Field on tuple");
}
+ else if( str_ty.m_data.is_Closure() )
+ {
+ ASSERT_BUG(sp, is_index, "Non-index _Field on closure");
+ }
else
{
ASSERT_BUG(sp, str_ty.m_data.is_Path(), "Value type of _Field isn't Path - " << str_ty);
@@ -735,6 +741,26 @@ namespace {
)
}
}
+
+ void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override
+ {
+ 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);
+
+ ::HIR::Visitor::visit_type_impl(impl);
+ }
+ void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
+ {
+ TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
+ auto _ = this->m_resolve.set_impl_generics(impl.m_params);
+
+ ::HIR::Visitor::visit_trait_impl(trait_path, impl);
+ }
};
}
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index d2fccfde..34ea4185 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -160,6 +160,15 @@ public:
prep_indexes();
}
+ const ::HIR::GenericParams& impl_params() const {
+ static ::HIR::GenericParams empty;
+ return m_impl_params ? *m_impl_params : empty;
+ }
+ const ::HIR::GenericParams& item_params() const {
+ static ::HIR::GenericParams empty;
+ return m_item_params ? *m_item_params : empty;
+ }
+
void prep_indexes();
::HIR::Compare compare_pp(const Span& sp, const ::HIR::PathParams& left, const ::HIR::PathParams& right) const;
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index bb39e164..f2ca411d 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -25,6 +25,15 @@ public:
m_item_generics(nullptr)
{}
+ const ::HIR::GenericParams& impl_generics() const {
+ static ::HIR::GenericParams empty;
+ return m_impl_generics ? *m_impl_generics : empty;
+ }
+ const ::HIR::GenericParams& item_generics() const {
+ static ::HIR::GenericParams empty;
+ return m_item_generics ? *m_item_generics : empty;
+ }
+
/// \brief State manipulation
/// \{
template<typename T>