diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-11 16:14:16 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-11 16:14:16 +0800 |
commit | 09b562021cd873625fd25b98b508e853ba47d879 (patch) | |
tree | 5f8c666a076afaa4e1d8dae3c93bdfc5b2aba483 | |
parent | c06a0d7011130ffd63f81c604107db4e82323a5c (diff) | |
download | mrust-09b562021cd873625fd25b98b508e853ba47d879.tar.gz |
Resolve/Use - HIR imports and searching wildcard imports
-rw-r--r-- | src/hir/hir.cpp | 8 | ||||
-rw-r--r-- | src/hir/hir.hpp | 4 | ||||
-rw-r--r-- | src/resolve/use.cpp | 32 |
3 files changed, 29 insertions, 15 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 65a87d7a..636ff7a0 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -373,12 +373,12 @@ const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path(const Span& sp, const return it->second; } -const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const +const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name) const { ASSERT_BUG(sp, path.m_components.size() > 0, "get_typeitem_by_path received invalid path - " << path); const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( !ignore_crate_name && path.m_crate_name != "" ) { ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); mod = &m_ext_crates.at(path.m_crate_name)->m_root_module; } @@ -448,13 +448,13 @@ const ::HIR::Enum& ::HIR::Crate::get_enum_by_path(const Span& sp, const ::HIR::S } } -const ::HIR::ValueItem& ::HIR::Crate::get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const +const ::HIR::ValueItem& ::HIR::Crate::get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name) const { if( path.m_components.size() == 0) { BUG(sp, "get_valitem_by_path received invalid path"); } const ::HIR::Module* mod; - if( path.m_crate_name != "" ) { + if( !ignore_crate_name && path.m_crate_name != "" ) { ASSERT_BUG(sp, m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded"); mod = &m_ext_crates.at(path.m_crate_name)->m_root_module; } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index e18f6631..b1f18fcf 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -326,13 +326,13 @@ public: const ::HIR::SimplePath& get_lang_item_path(const Span& sp, const char* name) const; - const ::HIR::TypeItem& get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const; + const ::HIR::TypeItem& get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name=false) const; 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::ValueItem& get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name=false) const; const ::HIR::Function& get_function_by_path(const Span& sp, const ::HIR::SimplePath& path) const; const ::HIR::Static& get_static_by_path(const Span& sp, const ::HIR::SimplePath& path) const { const auto& ti = this->get_valitem_by_path(sp, path); diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 709c488a..18a8fb94 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -9,9 +9,10 @@ enum class Lookup { - Any, - Type, - Value, + Any, // Allow binding to anything + AnyOpt, // Allow binding to anything, but don't error on failure + Type, // Allow only type bindings + Value, // Allow only value bindings }; ::AST::Path Resolve_Use_AbsolutisePath(const ::AST::Path& base_path, ::AST::Path path); @@ -230,7 +231,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } } - if( des_item_name[0] == '#' ) { + if( des_item_name.size() > 0 && des_item_name[0] == '#' ) { unsigned int idx = 0; if( ::std::sscanf(des_item_name.c_str(), "#%u", &idx) != 1 ) { BUG(span, "Invalid anon path segment '" << des_item_name << "'"); @@ -345,12 +346,18 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path binding = &binding_; } - TU_MATCH_DEF(::AST::PathBinding, ((*binding)), (e), + TU_MATCH_DEF(::AST::PathBinding, (*binding), (e), ( BUG(sp2, "Wildcard import expanded to an invalid item class"); ), (Module, - TODO(span, "Look up wildcard in module"); + auto allow_inner = (allow == Lookup::Any ? Lookup::AnyOpt : allow); + assert(e.module_); + // TODO: Prevent infinite recursion + auto rv = Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {}, allow_inner); + if( ! rv.is_Unbound() ) { + return mv$(rv); + } ), (Enum, TODO(span, "Look up wildcard in enum"); @@ -408,9 +415,16 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path { auto it = hmod->m_mod_items.find(nodes.back().name()); if( it != hmod->m_mod_items.end() ) { - TU_MATCHA( (it->second->ent), (e), + const auto* item_ptr = &it->second->ent; + if( item_ptr->is_Import() ) { + const auto& e = item_ptr->as_Import(); + // This doesn't need to recurse - it can just do a single layer (as no Import should refer to another) + const auto& ec = crate.m_extern_crates.at( e.m_crate_name ); + item_ptr = &ec.m_hir->get_typeitem_by_path(span, e, true); // ignore_crate_name=true + } + TU_MATCHA( (*item_ptr), (e), (Import, - TODO(span, "Recurse to get binding for an import"); + BUG(span, "Recursive import in " << path << " - " << it->second->ent.as_Import() << " -> " << e); ), (Module, return ::AST::PathBinding::make_Module({nullptr, &e}); @@ -436,7 +450,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( it2 != hmod->m_value_items.end() ) { TU_MATCHA( (it2->second->ent), (e), (Import, - TODO(span, "Recurse to get binding for an import"); + TODO(span, "Recurse to get binding for an import - " << path << " = " << e); ), (Constant, return ::AST::PathBinding::make_Static({ nullptr }); |