summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/expr.hpp4
-rw-r--r--src/hir/from_ast.cpp63
-rw-r--r--src/hir/from_ast.hpp1
-rw-r--r--src/hir/from_ast_expr.cpp1
-rw-r--r--src/hir/hir.cpp10
-rw-r--r--src/hir/hir.hpp7
-rw-r--r--src/hir/visitor.hpp3
-rw-r--r--src/hir_conv/resolve_ufcs.cpp10
-rw-r--r--src/hir_typeck/expr.cpp37
-rw-r--r--src/hir_typeck/expr.hpp3
-rw-r--r--src/hir_typeck/expr_context.cpp17
11 files changed, 117 insertions, 39 deletions
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 761c0ce4..7e43e206 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -42,7 +42,9 @@ struct ExprNode_Block:
{
bool m_is_unsafe;
::std::vector< ExprNodeP > m_nodes;
- ::std::vector< ::HIR::SimplePath> m_traits;
+
+ ::HIR::SimplePath m_local_mod;
+ ::std::vector< ::std::pair<const ::HIR::SimplePath*,const ::HIR::Trait*> > m_traits;
ExprNode_Block(Span sp):
ExprNode(mv$(sp)),
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 8a975c25..4ea9ea8a 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -7,9 +7,8 @@
#include "from_ast.hpp"
#include "visitor.hpp"
-::HIR::Module LowerHIR_Module(const ::AST::Module& module, ::HIR::SimplePath path);
+::HIR::Module LowerHIR_Module(const ::AST::Module& module, ::HIR::SimplePath path, ::std::vector< ::HIR::SimplePath> traits = {});
::HIR::Function LowerHIR_Function(const ::AST::Function& f);
-::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Path& path, bool allow_final_generic = false);
::HIR::PathParams LowerHIR_PathParams(const Span& sp, const ::AST::PathParams& src_params, bool allow_assoc);
::HIR::TraitPath LowerHIR_TraitPath(const Span& sp, const ::AST::Path& path);
@@ -814,12 +813,32 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H
mod.m_value_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::ValueItem> { is_pub, mv$(ti) }) ) );
}
-::HIR::Module LowerHIR_Module(const ::AST::Module& module, ::HIR::SimplePath path)
+::HIR::Module LowerHIR_Module(const ::AST::Module& ast_mod, ::HIR::SimplePath path, ::std::vector< ::HIR::SimplePath> traits)
{
TRACE_FUNCTION_F("path = " << path);
::HIR::Module mod { };
+
+ mod.m_traits = mv$(traits);
+
+ // Populate trait list
+ for(const auto& item : ast_mod.m_type_items)
+ {
+ if( item.second.path.binding().is_Trait() ) {
+ auto sp = LowerHIR_SimplePath(Span(), item.second.path);
+ if( ::std::find(mod.m_traits.begin(), mod.m_traits.end(), sp) == mod.m_traits.end() )
+ mod.m_traits.push_back( mv$(sp) );
+ }
+ }
+
+ for( unsigned int i = 0; i < ast_mod.anon_mods().size(); i ++ )
+ {
+ auto& submod = *ast_mod.anon_mods()[i];
+ ::std::string name = FMT("#" << i);
+ auto item_path = path + name;
+ _add_mod_ns_item( mod, mv$(name), false, ::HIR::TypeItem::make_Module( LowerHIR_Module(submod, mv$(item_path), mod.m_traits) ) );
+ }
- for( const auto& item : module.items() )
+ for( const auto& item : ast_mod.items() )
{
auto item_path = path + item.name;
TU_MATCH(::AST::Item, (item.data), (e),
@@ -872,24 +891,6 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H
)
}
- for( unsigned int i = 0; i < module.anon_mods().size(); i ++ )
- {
- auto& submod = *module.anon_mods()[i];
- ::std::string name = FMT("#" << i);
- auto item_path = path + name;
- _add_mod_ns_item( mod, mv$(name), false, ::HIR::TypeItem::make_Module( LowerHIR_Module(submod, mv$(item_path)) ) );
- }
-
- // TODO: Impl blocks
-
- // TODO: Populate trait list
- for(const auto& item : module.m_type_items)
- {
- if( item.second.path.binding().is_Trait() ) {
- mod.m_traits.push_back( LowerHIR_SimplePath(Span(), item.second.path) );
- }
- }
-
return mod;
}
@@ -921,15 +922,15 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
auto trait_name = mv$(trait_path.m_path);
auto trait_args = mv$(trait_path.m_params);
- // TODO: Determine if a trait is a marker (i.e. is a OIBIT)
-
if( is_marker )
{
hir_crate.m_marker_impls.insert( ::std::make_pair( mv$(trait_name), ::HIR::MarkerImpl {
mv$(params),
mv$(trait_args),
true,
- mv$(type)
+ mv$(type),
+
+ LowerHIR_SimplePath(Span(), ast_mod.path())
} ) );
}
else
@@ -961,7 +962,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
mv$(methods),
mv$(constants),
- mv$(types)
+ mv$(types),
+
+ LowerHIR_SimplePath(Span(), ast_mod.path())
}) );
}
}
@@ -985,7 +988,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
hir_crate.m_type_impls.push_back( ::HIR::TypeImpl {
mv$(params),
mv$(type),
- mv$( methods )
+ mv$(methods),
+
+ LowerHIR_SimplePath(Span(), ast_mod.path())
} );
}
}
@@ -1001,7 +1006,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
mv$(params),
mv$(trait_args),
false,
- mv$(type)
+ mv$(type),
+
+ LowerHIR_SimplePath(Span(), ast_mod.path())
} ) );
}
}
diff --git a/src/hir/from_ast.hpp b/src/hir/from_ast.hpp
index f0795fcf..231f1286 100644
--- a/src/hir/from_ast.hpp
+++ b/src/hir/from_ast.hpp
@@ -5,6 +5,7 @@
extern ::HIR::ExprPtr LowerHIR_ExprNode(const ::AST::ExprNode& e);
extern ::HIR::Path LowerHIR_Path(const Span& sp, const ::AST::Path& path);
extern ::HIR::GenericPath LowerHIR_GenericPath(const Span& sp, const ::AST::Path& path, bool allow_assoc=false);
+extern ::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Path& path, bool allow_final_generic = false);
extern ::HIR::TypeRef LowerHIR_Type(const ::TypeRef& ty);
extern ::HIR::Pattern LowerHIR_Pattern(const ::AST::Pattern& pat);
diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp
index ea46c4c3..13b0f47c 100644
--- a/src/hir/from_ast_expr.cpp
+++ b/src/hir/from_ast_expr.cpp
@@ -37,6 +37,7 @@ struct LowerHIR_ExprNode_Visitor:
if( v.m_local_mod )
{
// TODO: Populate m_traits from the local module's import list
+ rv->m_local_mod = LowerHIR_SimplePath(v.span(), v.m_local_mod->path());
}
m_rv.reset( static_cast< ::HIR::ExprNode*>(rv) );
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 1eb4609a..ee1d76a5 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -199,6 +199,16 @@ const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const
return it->second->ent;
}
+const ::HIR::Module& ::HIR::Crate::get_mod_by_path(const Span& sp, const ::HIR::SimplePath& path) const
+{
+ const auto& ti = this->get_typeitem_by_path(sp, path);
+ TU_IFLET(::HIR::TypeItem, ti, Module, e,
+ return e;
+ )
+ else {
+ BUG(sp, "Module path " << path << " didn't point to a module");
+ }
+}
const ::HIR::Trait& ::HIR::Crate::get_trait_by_path(const Span& sp, const ::HIR::SimplePath& path) const
{
const auto& ti = this->get_typeitem_by_path(sp, path);
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index fb27c44d..e1163b49 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -211,6 +211,8 @@ public:
::HIR::TypeRef m_type;
::std::map< ::std::string, ::HIR::Function> m_methods;
+
+ ::HIR::SimplePath m_src_module;
bool matches_type(const ::HIR::TypeRef& tr, t_cb_resolve_type ty_res) const;
bool matches_type(const ::HIR::TypeRef& tr) const {
@@ -229,6 +231,8 @@ public:
::std::map< ::std::string, ::HIR::ExprPtr> m_constants;
::std::map< ::std::string, ::HIR::TypeRef> m_types;
+ ::HIR::SimplePath m_src_module;
+
bool matches_type(const ::HIR::TypeRef& tr, t_cb_resolve_type ty_res) const;
bool matches_type(const ::HIR::TypeRef& tr) const {
return matches_type(tr, [](const auto& x)->const auto&{ return x; });
@@ -243,6 +247,8 @@ public:
bool is_positive;
::HIR::TypeRef m_type;
+ ::HIR::SimplePath m_src_module;
+
bool matches_type(const ::HIR::TypeRef& tr, t_cb_resolve_type ty_res) const;
bool matches_type(const ::HIR::TypeRef& tr) const {
return matches_type(tr, [](const auto& x)->const auto&{ return x; });
@@ -272,6 +278,7 @@ public:
const ::HIR::Trait& get_trait_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
const ::HIR::Struct& get_struct_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
const ::HIR::Enum& get_enum_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
+ const ::HIR::Module& get_mod_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
const ::HIR::ValueItem& get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
const ::HIR::Function& get_function_by_path(const Span& sp, const ::HIR::SimplePath& path) const;
diff --git a/src/hir/visitor.hpp b/src/hir/visitor.hpp
index 8e0d6d39..844603df 100644
--- a/src/hir/visitor.hpp
+++ b/src/hir/visitor.hpp
@@ -9,8 +9,9 @@ namespace HIR {
class PathChain
{
const PathChain* prev;
- const ::std::string& name;
public:
+ const ::std::string& name;
+
PathChain(const PathChain& prev, const ::std::string& name):
prev(&prev),
name(name)
diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp
index daa075ba..509faddf 100644
--- a/src/hir_conv/resolve_ufcs.cpp
+++ b/src/hir_conv/resolve_ufcs.cpp
@@ -117,8 +117,14 @@ namespace {
void visit(::HIR::ExprNode_Block& node) override
{
- for( const auto& trait_path : node.m_traits )
- upper_visitor.m_traits.push_back( ::std::make_pair( &trait_path, &upper_visitor.find_trait(trait_path) ) );
+ if( node.m_traits.size() == 0 && node.m_local_mod.m_components.size() > 0 ) {
+ const auto& mod = upper_visitor.m_crate.get_mod_by_path(node.span(), node.m_local_mod);
+ for( const auto& trait_path : mod.m_traits ) {
+ node.m_traits.push_back( ::std::make_pair( &trait_path, &upper_visitor.m_crate.get_trait_by_path(node.span(), trait_path) ) );
+ }
+ }
+ for( const auto& trait_ref : node.m_traits )
+ upper_visitor.m_traits.push_back( trait_ref );
::HIR::ExprVisitorDef::visit(node);
for(unsigned int i = 0; i < node.m_traits.size(); i ++ )
upper_visitor.m_traits.pop_back();
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index b621b92f..90ac7917 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -339,6 +339,7 @@ namespace typeck {
}
void visit(::HIR::ExprNode_Block& node) override
{
+ this->context.push_traits( node.m_traits );
::HIR::ExprVisitorDef::visit(node);
if( node.m_nodes.size() > 0 ) {
auto& ln = *node.m_nodes.back();
@@ -347,6 +348,7 @@ namespace typeck {
else {
node.m_res_type = ::HIR::TypeRef::new_unit();
}
+ this->context.pop_traits( node.m_traits );
}
void visit(::HIR::ExprNode_Return& node) override
{
@@ -558,6 +560,7 @@ namespace typeck {
void visit(::HIR::ExprNode_Block& node) override
{
TRACE_FUNCTION_F("{ }");
+ this->context.push_traits( node.m_traits );
if( node.m_nodes.size() ) {
auto& lastnode = node.m_nodes.back();
this->context.apply_equality(node.span(), node.m_res_type, lastnode->m_res_type, &lastnode);
@@ -566,6 +569,7 @@ namespace typeck {
this->context.apply_equality(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
}
::HIR::ExprVisitorDef::visit(node);
+ this->context.pop_traits( node.m_traits );
}
// - Let: Equates inner to outer
void visit(::HIR::ExprNode_Let& node) override
@@ -2066,18 +2070,30 @@ namespace {
m_item_generics = &gps;
return NullOnDrop< ::HIR::GenericParams>(m_item_generics);
}
-
- public:
- void visit_module(::HIR::PathChain p, ::HIR::Module& mod) override
- {
+
+ void push_traits(const ::HIR::Module& mod) {
+ auto sp = Span();
DEBUG("Module has " << mod.m_traits.size() << " in-scope traits");
+ // - Push a NULL entry to prevent parent module import lists being searched
+ m_traits.push_back( ::std::make_pair(nullptr, nullptr) );
for( const auto& trait_path : mod.m_traits ) {
DEBUG("Push " << trait_path);
- m_traits.push_back( ::std::make_pair( &trait_path, &this->m_crate.get_trait_by_path(Span(), trait_path) ) );
+ m_traits.push_back( ::std::make_pair( &trait_path, &this->m_crate.get_trait_by_path(sp, trait_path) ) );
}
- ::HIR::Visitor::visit_module(p, mod);
+ }
+ void pop_traits(const ::HIR::Module& mod) {
+ DEBUG("Module has " << mod.m_traits.size() << " in-scope traits");
for(unsigned int i = 0; i < mod.m_traits.size(); i ++ )
m_traits.pop_back();
+ m_traits.pop_back();
+ }
+
+ public:
+ void visit_module(::HIR::PathChain p, ::HIR::Module& mod) override
+ {
+ push_traits(mod);
+ ::HIR::Visitor::visit_module(p, mod);
+ pop_traits(mod);
}
// NOTE: This is left here to ensure that any expressions that aren't handled by higher code cause a failure
@@ -2096,21 +2112,30 @@ namespace {
TRACE_FUNCTION_F("impl " << impl.m_type);
auto _ = this->set_impl_generics(impl.m_params);
+ const auto& mod = this->m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ push_traits(mod);
::HIR::Visitor::visit_type_impl(impl);
+ pop_traits(mod);
}
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->set_impl_generics(impl.m_params);
+ const auto& mod = this->m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ push_traits(mod);
::HIR::Visitor::visit_trait_impl(trait_path, impl);
+ pop_traits(mod);
}
void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override
{
TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type << " { }");
auto _ = this->set_impl_generics(impl.m_params);
+ const auto& mod = this->m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ push_traits(mod);
::HIR::Visitor::visit_marker_impl(trait_path, impl);
+ pop_traits(mod);
}
void visit_type(::HIR::TypeRef& ty) override
diff --git a/src/hir_typeck/expr.hpp b/src/hir_typeck/expr.hpp
index 0eb3b1d4..9972e8e4 100644
--- a/src/hir_typeck/expr.hpp
+++ b/src/hir_typeck/expr.hpp
@@ -83,6 +83,9 @@ public:
m_has_changed = true;
}
+ void push_traits(const ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > >& list);
+ void pop_traits(const ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > >& list);
+
void compact_ivars();
/// Apply defaults (i32 or f64), returns true if a default was applied
bool apply_defaults();
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 14eb869c..a425aa56 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -4,6 +4,15 @@
#include <hir/hir.hpp>
#include <algorithm> // std::find_if
+void typeck::TypecheckContext::push_traits(const ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > >& list)
+{
+ this->m_traits.insert( this->m_traits.end(), list.begin(), list.end() );
+}
+void typeck::TypecheckContext::pop_traits(const ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > >& list)
+{
+ this->m_traits.erase( this->m_traits.end() - list.size(), this->m_traits.end() );
+}
+
void typeck::TypecheckContext::dump() const
{
DEBUG("TypecheckContext - " << m_ivars.size() << " ivars, " << m_locals.size() << " locals");
@@ -1694,12 +1703,14 @@ bool typeck::TypecheckContext::find_trait_impls_crate(const Span& sp,
if( ty2 == assoc_bound.second ) {
return true;
}
+ this->dump();
TODO(sp, "Check type bound (fuzz) " << ty2 << " = " << assoc_bound.second);
}
else {
- if( it->second == assoc_bound.second ) {
+ if( this->get_type(it->second) == assoc_bound.second ) {
return true;
}
+ this->dump();
TODO(sp, "Check type bound (fuzz) " << it->second << " = " << assoc_bound.second);
}
}
@@ -1955,6 +1966,10 @@ bool typeck::TypecheckContext::find_method(const Span& sp, const ::HIR::TypeRef&
// 3. Search for trait methods (using currently in-scope traits)
for(const auto& trait_ref : ::reverse(m_traits))
{
+ if( trait_ref.first == nullptr )
+ break;
+ DEBUG("Search for impl of ?" << *trait_ref.first);
+
// TODO: Search supertraits too
auto it = trait_ref.second->m_values.find(method_name);
if( it == trait_ref.second->m_values.end() )