diff options
-rw-r--r-- | src/hir/expr.hpp | 4 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 63 | ||||
-rw-r--r-- | src/hir/from_ast.hpp | 1 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 1 | ||||
-rw-r--r-- | src/hir/hir.cpp | 10 | ||||
-rw-r--r-- | src/hir/hir.hpp | 7 | ||||
-rw-r--r-- | src/hir/visitor.hpp | 3 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 10 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 37 | ||||
-rw-r--r-- | src/hir_typeck/expr.hpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 17 |
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() ) |