diff options
-rw-r--r-- | src/ast/ast.cpp | 131 | ||||
-rw-r--r-- | src/ast/ast.hpp | 73 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 10 | ||||
-rw-r--r-- | src/expand/mod.cpp | 21 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 3 | ||||
-rw-r--r-- | src/parse/root.cpp | 33 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 4 | ||||
-rw-r--r-- | src/resolve/index.cpp | 71 | ||||
-rw-r--r-- | src/resolve/use.cpp | 70 |
9 files changed, 126 insertions, 290 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 60c813d4..885ea677 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -243,6 +243,11 @@ MacroInvocation MacroInvocation::clone() const }
+UseStmt UseStmt::clone() const
+{
+ return UseStmt(sp, path);
+}
+
::std::unique_ptr<AST::Module> Module::add_anon() {
auto rv = box$( Module(m_my_path + FMT("#" << m_anon_modules.size())) );
@@ -264,8 +269,7 @@ void Module::add_ext_crate(bool is_public, ::std::string ext_name, ::std::string this->add_item( is_public, imp_name, Item::make_Crate({mv$(ext_name)}), mv$(attrs) );
}
void Module::add_alias(bool is_public, UseStmt us, ::std::string name, MetaItems attrs) {
- us.attrs = mv$(attrs);
- m_imports.push_back( Named<UseStmt>( mv$(name), mv$(us), is_public) );
+ this->add_item( is_public, mv$(name), Item(mv$(us)), mv$(attrs) );
}
void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) {
m_macros.push_back( Named<MacroRulesPtr>( mv$(name), mv$(macro), is_exported ) );
@@ -282,126 +286,6 @@ void Module::prescan() //}
}
-template<typename T>
-typename ::std::vector<Named<T> >::const_iterator find_named(const ::std::vector<Named<T> >& vec, const ::std::string& name)
-{
- return ::std::find_if(vec.begin(), vec.end(), [&name](const Named<T>& x) {
- //DEBUG("find_named - x.name = " << x.name);
- return x.name == name && !x.data.is_None();
- });
-}
-
-Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves, bool ignore_private_wildcard) const
-{
- TRACE_FUNCTION_F("path = " << m_my_path << ", needle = " << needle);
-
- {
- auto it = find_named(this->items(), needle);
- if( it != this->items().end() ) {
- TU_MATCH(::AST::Item, (it->data), (e),
- (None,
- throw ::std::runtime_error("BUG: Hit a None item");
- ),
- (MacroInv,
- throw ::std::runtime_error("BUG: Hit a macro invocation");
- ),
- (Module, return ItemRef(e); ),
- (Crate, return ItemRef(e.name); ),
- (Type, return ItemRef(e); ),
- (Struct, return ItemRef(e); ),
- (Enum, return ItemRef(e); ),
- (Trait, return ItemRef(e); ),
- (Function,
- if( allow_leaves )
- return ItemRef(e);
- else
- DEBUG("Skipping function, leaves not allowed");
- ),
- (Static,
- if( allow_leaves )
- return ItemRef(e);
- else
- DEBUG("Skipping function, leaves not allowed");
- )
- )
- DEBUG("Item not checked at this level, try re-export list");
- }
- }
-
- // - Re-exports
- // > Comes last, as it's a potentially expensive operation
- {
- for( const auto& imp : this->imports() )
- {
- //DEBUG("imp: '" << imp.name << "' = " << imp.data);
- if( !imp.is_pub && ignore_private_wildcard )
- {
- // not public, ignore
- //DEBUG("Private import, '" << imp.name << "' = " << imp.data);
- }
- else if( imp.name == needle )
- {
- DEBUG("Match " << needle << " = " << imp.data);
- return ItemRef(imp);
- }
- else if( imp.name == "" )
- {
- // Loop avoidance, don't check this
- //if( &imp.data == this )
- // continue ;
- //
- const auto& binding = imp.data.path.binding();
- if( binding.is_Unbound() )
- {
- // not yet bound, so run resolution (recursion)
- DEBUG("Recursively resolving pub wildcard use " << imp.data);
- //imp.data.resolve(root_crate);
- throw ParseError::Todo("AST::Module::find_item() - Wildcard `use` not bound, call resolve here?");
- }
-
- TU_MATCH_DEF(AST::PathBinding, (binding), (info),
- // - any other type - error
- (
- DEBUG("ERROR: Import of invalid class : " << imp.data.path);
- throw ParseError::Generic("Wildcard import of non-module/enum");
- ),
- (Unbound,
- throw ParseError::BugCheck("Wildcard import path not bound");
- ),
- // - If it's a module, recurse
- (Module,
- auto rv = info.module_->find_item(needle);
- if( !rv.is_None() ) {
- // Don't return RV, return the import (so caller can rewrite path if need be)
- return ItemRef(imp);
- //return rv;
- }
- ),
- // - If it's an enum, search for this name and then pass to resolve
- (Enum,
- auto& vars = info.enum_->variants();
- // Damnit C++ "let it = vars.find(|a| a.name == needle);"
- auto it = ::std::find_if(vars.begin(), vars.end(),
- [&needle](const EnumVariant& ev) { return ev.m_name == needle; });
- if( it != vars.end() ) {
- DEBUG("Found enum variant " << it->m_name);
- return ItemRef(imp);
- //throw ParseError::Todo("Handle lookup_path_in_module for wildcard imports - enum");
- }
- )
- )
- }
- else
- {
- // Can't match, ignore
- }
- }
-
- }
-
- return Module::ItemRef();
-}
-
Item Item::clone() const
{
TU_MATCHA( (*this), (e),
@@ -411,6 +295,9 @@ Item Item::clone() const (MacroInv,
TODO(Span(), "Clone on Item::MacroInv");
),
+ (Use,
+ return AST::Item(e.clone());
+ ),
(Module,
TODO(Span(), "Clone on Item::Module");
),
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 2042563e..1b923ef3 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -436,7 +436,6 @@ private: struct UseStmt
{
Span sp;
- ::AST::MetaItems attrs;
::AST::Path path;
::AST::PathBinding alt_binding;
@@ -448,82 +447,19 @@ struct UseStmt {
}
+ UseStmt clone() const;
+
friend ::std::ostream& operator<<(::std::ostream& os, const UseStmt& x);
};
/// Representation of a parsed (and being converted) function
class Module
{
-public:
- class ItemRef
- {
- public:
- enum Type
- {
- TAG_None,
- TAG_Module,
- TAG_Crate,
- TAG_TypeAlias,
- TAG_Function,
- TAG_Trait,
- TAG_Struct,
- TAG_Enum,
- TAG_Static,
- TAG_Use,
- };
- private:
- Type m_type;
- const void* m_ref;
- public:
- ItemRef(): m_type(TAG_None) {}
-
- Type tag() const { return m_type; }
- bool is_None() const { return m_type == TAG_None; }
- const Type& as_None() const { return m_type; } // HACK: Returns &Type in place of &void
- #define _(ty,ident) \
- ItemRef(const ty& ref): m_type(TAG_##ident), m_ref(&ref) {} \
- bool is_##ident() const { return m_type == TAG_##ident; } \
- const ty& as_##ident() const { assert(m_type == TAG_##ident); return *(const ty*)m_ref; }
- _(AST::Module, Module)
- _(::std::string, Crate)
- _(AST::TypeAlias, TypeAlias)
- _(AST::Function, Function)
- _(AST::Trait, Trait)
- _(AST::Struct, Struct)
- _(AST::Enum, Enum)
- _(AST::Static, Static)
- _(AST::Named<UseStmt>, Use)
- #undef _
- friend ::std::ostream& operator<<(::std::ostream& os, const ItemRef& x) {
- switch(x.m_type)
- {
- #define _(ident) case TAG_##ident: return os << "ItemRef(" #ident ")";
- _(None)
- _(Module)
- _(Crate)
- _(TypeAlias)
- _(Function)
- _(Trait)
- _(Struct)
- _(Enum)
- _(Static)
- _(Use)
- #undef _
- }
- throw "";
- }
- };
-
-private:
- typedef ::std::vector< Named<UseStmt> > itemlist_use_t;
-
::AST::Path m_my_path;
// Module-level items
/// General items
::std::vector<Named<Item>> m_items;
- /// `use` imports (public and private)
- itemlist_use_t m_imports;
/// Macro invocations
::std::vector<MacroInvocation> m_macro_invocations;
@@ -607,14 +543,10 @@ public: }
const ::AST::Path& path() const { return m_my_path; }
- ItemRef find_item(const ::std::string& needle, bool allow_leaves = true, bool ignore_private_wildcard = true) const;
::std::vector<Named<Item>>& items() { return m_items; }
const ::std::vector<Named<Item>>& items() const { return m_items; }
- itemlist_use_t& imports() { return m_imports; }
- const itemlist_use_t& imports() const { return m_imports; }
-
::std::vector<Impl>& impls() { return m_impls; }
const ::std::vector<Impl>& impls() const { return m_impls; }
@@ -639,6 +571,7 @@ TAGGED_UNION_EX(Item, (), None, (
(None, struct {} ),
(MacroInv, MacroInvocation),
+ (Use, UseStmt),
(Module, Module),
(Crate, struct {
::std::string name;
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 0a322ee5..8909e2e4 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -558,21 +558,23 @@ void RustPrinter::handle_module(const AST::Module& mod) { bool need_nl = true; - for( const auto& i : mod.imports() ) + for( const auto& i : mod.items() ) { + if( !i.data.is_Use() ) continue ; + const auto& i_data = i.data.as_Use(); //if(need_nl) { // m_os << "\n"; // need_nl = false; //} - if( i.data.path == AST::Path() ) { + if( i_data.path == AST::Path() ) { continue ; } - m_os << indent() << (i.is_pub ? "pub " : "") << "use " << i.data; + m_os << indent() << (i.is_pub ? "pub " : "") << "use " << i_data; if( i.name == "" ) { m_os << "::*"; } - else if( i.data.path.nodes().back().name() != i.name ) + else if( i_data.path.nodes().back().name() != i.name ) { m_os << " as " << i.name; } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index d45b6ae3..1ca7f3eb 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -680,24 +680,6 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo } } - // 2. Use statements - for( auto it = mod.imports().begin(); it != mod.imports().end(); ) - { - auto& i = *it; - auto attrs = mv$(i.data.attrs); - Expand_Attrs(attrs, stage_pre (is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, i.data); }); - Expand_Attrs(attrs, stage_post(is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, i.data); }); - if( i.data.attrs.m_items.size() == 0 ) - i.data.attrs = mv$(attrs); - - if( i.data.path == AST::Path() ) { - it = mod.imports().erase(it); - } - else { - ++ it; - } - } - // 3. General items DEBUG("Items"); for( auto& i : mod.items() ) @@ -715,6 +697,9 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo (MacroInv, TODO(Span(), "Macro invocation in item list"); ), + (Use, + // No inner expand. + ), (Module, LList<const AST::Module*> sub_modstack(&modstack, &e); Expand_Mod(is_early, crate, sub_modstack, path, e); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index e723d26b..46e9afa1 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1036,6 +1036,9 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H (MacroInv, BUG(Span(), "Stray macro invocation in " << path); ), + (Use, + // Ignore - The index is used to add `Import`s + ), (Module, _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Module(e, mv$(item_path)) ); ), diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 1b6bf15a..3a942b6c 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -1300,7 +1300,22 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_USE:
+ #if 0
TODO(lex.getPosition(), "Encode a single use statement as a single Item");
+ #else
+ // NOTE: The only problem here is with things like `use foo::{a, b, c}` - all others are a single statement.
+ // - These are caught by the condition in the closure
+ Parse_Use(lex, [&](AST::UseStmt p, std::string s) {
+ DEBUG(mod_path << " - use " << p << " as '" << s << "'");
+ if( !item_data.is_None() )
+ TODO(lex.getPosition(), "Encode multi-item use statements as a single Item");
+ item_data = ::AST::Item(mv$(p));
+ item_name = mv$(s);
+ });
+ assert( !item_data.is_None() );
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ break;
+ #endif
case TOK_RWORD_EXTERN:
switch( GET_TOK(tok, lex) )
@@ -1639,6 +1654,7 @@ void Parse_Mod_Item(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_item });
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
}
+ //else if( LOOKAHEAD2(lex, TOK_RWORD_EXTERN, TOK_BRACE_OPEN) || LOOKAHEAD3(lex, TOK_RWORD_EXTERN, TOK_STRING, TOK_BRACE_OPEN) )
else if( lex.lookahead(0) == TOK_RWORD_EXTERN && ( (lex.lookahead(1) == TOK_STRING && lex.lookahead(2) == TOK_BRACE_OPEN) || lex.lookahead(1) == TOK_BRACE_OPEN ) )
{
// `extern "<ABI>" { ...`
@@ -1652,17 +1668,18 @@ void Parse_Mod_Item(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_item Parse_ExternBlock(lex, mod, mv$(abi), mv$(meta_items));
}
+ // `unsafe impl`
// TODO: Move these two into Parse_Mod_Item_S
- else if( lex.lookahead(0) == TOK_RWORD_UNSAFE && lex.lookahead(1) == TOK_RWORD_IMPL )
- {
- GET_CHECK_TOK(tok, lex, TOK_RWORD_UNSAFE);
- GET_CHECK_TOK(tok, lex, TOK_RWORD_IMPL);
- Parse_Impl(lex, mod, mv$(meta_items), true);
- }
- else if( lex.lookahead(0) == TOK_RWORD_IMPL )
+ //else if( LOOKAHEAD1(lex, TOK_RWORD_IMPL) || LOOKAHEAD2(lex, TOK_RWORD_UNSAFE, TOK_RWORD_IMPL) )
+ else if( lex.lookahead(0) == TOK_RWORD_IMPL || (lex.lookahead(0) == TOK_RWORD_UNSAFE && lex.lookahead(1) == TOK_RWORD_IMPL) )
{
+ bool is_unsafe = false;
+ if( lex.lookahead(0) == TOK_RWORD_UNSAFE ) {
+ GET_CHECK_TOK(tok, lex, TOK_RWORD_UNSAFE);
+ is_unsafe = true;
+ }
GET_CHECK_TOK(tok, lex, TOK_RWORD_IMPL);
- Parse_Impl(lex, mod, mv$(meta_items), true);
+ Parse_Impl(lex, mod, mv$(meta_items), is_unsafe);
}
else
{
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 5666cdd7..8bb712dc 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1674,6 +1674,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: TU_MATCH(AST::Item, (i.data), (e), (None, ), (MacroInv, BUG(i.data.span, "Resolve_Absolute_ImplItems - MacroInv");), + (Use, BUG(i.data.span, "Resolve_Absolute_ImplItems - Use");), (Module, BUG(i.data.span, "Resolve_Absolute_ImplItems - Module");), (Crate , BUG(i.data.span, "Resolve_Absolute_ImplItems - Crate");), (Enum , BUG(i.data.span, "Resolve_Absolute_ImplItems - Enum");), @@ -1754,6 +1755,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Im TU_MATCH(AST::Item, (*i.data), (e), (None, ), (MacroInv, BUG(i.data->span, "Resolve_Absolute_ImplItems - MacroInv");), + (Use , BUG(i.data->span, "Resolve_Absolute_ImplItems - Use");), (Module, BUG(i.data->span, "Resolve_Absolute_ImplItems - Module");), (Crate , BUG(i.data->span, "Resolve_Absolute_ImplItems - Crate");), (Enum , BUG(i.data->span, "Resolve_Absolute_ImplItems - Enum");), @@ -1796,6 +1798,8 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) ), (MacroInv, ), + (Use, + ), (Module, DEBUG("Module - " << i.name); Resolve_Absolute_Mod(item_context.m_crate, e); diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 0ff94db4..b5706f10 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -96,6 +96,9 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) ), (MacroInv, ), + (Use, + // Skip for now + ), // - Types/modules only (Module, p.bind( ::AST::PathBinding::make_Module({&e}) ); @@ -140,16 +143,20 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) bool has_pub_wildcard = false; // Named imports - for( const auto& i : mod.imports() ) + for( const auto& i : mod.items() ) { + if( ! i.data.is_Use() ) + continue ; + const auto& i_data = i.data.as_Use(); if( i.name != "" ) { // TODO: Ensure that the path is canonical? - const auto& sp = i.data.sp; + const auto& sp = i_data.sp; struct H { - static void handle_pb(const Span& sp, AST::Module& mod, const AST::Named<AST::UseStmt>& i, const AST::PathBinding& pb, bool allow_collide) + static void handle_pb(const Span& sp, AST::Module& mod, const AST::Named<AST::Item>& i, const AST::PathBinding& pb, bool allow_collide) { + const auto& i_data = i.data.as_Use(); TU_MATCH(::AST::PathBinding, (pb), (e), (Unbound, ), @@ -166,44 +173,44 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) BUG(sp, "Import was bound to struct method"); ), - (Crate , _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i.data.path, !allow_collide); ), - (Module, _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i.data.path, !allow_collide); ), - (Enum, _add_item_type(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ), - (Trait, _add_item_type(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ), - (TypeAlias,_add_item_type(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ), + (Crate , _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), + (Module, _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), + (Enum, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), + (Trait, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), + (TypeAlias,_add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), (Struct, - _add_item_type(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); // - If the struct is a tuple-like struct, it presents in the value namespace assert(e.struct_ || e.hir); if( e.struct_ ) { if( e.struct_->m_data.is_Tuple() ) { - _add_item_value(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); } } else { if( ! e.hir->m_data.is_Named() ) { - _add_item_value(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); } } ), - (Static , _add_item_value(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ), - (Function, _add_item_value(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ), - (EnumVar , _add_item_value(sp, mod, i.name, i.is_pub, i.data.path, !allow_collide); ) + (Static , _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), + (Function, _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), + (EnumVar , _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ) ) } }; - if( i.data.path.binding().is_Unbound() ) { - BUG(sp, "Import left unbound ("<<i.data.path<<")"); + if( i_data.path.binding().is_Unbound() ) { + BUG(sp, "Import left unbound ("<<i_data.path<<")"); } else { - H::handle_pb(sp, mod, i, i.data.path.binding(), false); + H::handle_pb(sp, mod, i, i_data.path.binding(), false); } - if( i.data.alt_binding.is_Unbound() ) { + if( i_data.alt_binding.is_Unbound() ) { // Doesn't matter } else { - H::handle_pb(sp, mod, i, i.data.alt_binding, true); + H::handle_pb(sp, mod, i, i_data.alt_binding, true); } } else @@ -238,18 +245,22 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han { TRACE_FUNCTION_F("mod = " << mod.path()); // Glob/wildcard imports - for( const auto& i : mod.imports() ) + for( const auto& i : mod.items() ) { + if( ! i.data.is_Use() ) + continue ; + const auto& i_data = i.data.as_Use(); + if( i.name == "" && i.is_pub == handle_pub ) { - const auto& sp = i.data.sp; - const auto& b = i.data.path.binding(); + const auto& sp = i_data.sp; + const auto& b = i_data.path.binding(); TU_MATCH_DEF(::AST::PathBinding, (b), (e), ( BUG(sp, "Glob import of invalid type encountered"); ), (Unbound, - BUG(sp, "Import left unbound ("<<i.data.path<<")"); + BUG(sp, "Import left unbound ("<<i_data.path<<")"); ), (Variable, BUG(sp, "Import was bound to variable"); @@ -268,10 +279,10 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han TODO(sp, "Glob import of crate"); ), (Module, - DEBUG("Glob mod " << i.data.path); + DEBUG("Glob mod " << i_data.path); if( !e.module_ ) { - ASSERT_BUG(sp, e.hir, "Glob import where HIR module pointer not set - " << i.data.path); + ASSERT_BUG(sp, e.hir, "Glob import where HIR module pointer not set - " << i_data.path); const auto& hmod = *e.hir; for(const auto& it : hmod.m_mod_items) { const auto& ve = *it.second; @@ -281,7 +292,7 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han p = hir_to_ast( ve.ent.as_Import() ); } else { - p = i.data.path + it.first; + p = i_data.path + it.first; } TU_MATCHA( (ve.ent), (e), (Import, @@ -332,7 +343,7 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han vep = &hmod->m_value_items.at( spath.m_components.back() )->ent; } else { - p = i.data.path + it.first; + p = i_data.path + it.first; } if( vep ) { @@ -387,11 +398,11 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han } ), (Enum, - ASSERT_BUG(sp, e.enum_, "Glob import but enum pointer not set - " << i.data.path); - DEBUG("Glob enum " << i.data.path); + ASSERT_BUG(sp, e.enum_, "Glob import but enum pointer not set - " << i_data.path); + DEBUG("Glob enum " << i_data.path); unsigned int idx = 0; for( const auto& ev : e.enum_->variants() ) { - ::AST::Path p = i.data.path + ev.m_name; + ::AST::Path p = i_data.path + ev.m_name; p.bind( ::AST::PathBinding::make_EnumVar({e.enum_, idx}) ); if( ev.m_data.is_Struct() ) { _add_item_type ( sp, mod, ev.m_name, i.is_pub, mv$(p), false ); diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 09c1cee9..3377d2aa 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -83,20 +83,24 @@ void Resolve_Use(::AST::Crate& crate) void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path, slice< const ::AST::Module* > parent_modules) { TRACE_FUNCTION_F("path = " << path << ", mod.path() = " << mod.path()); - for(auto& use_stmt : mod.imports()) + for(auto& use_stmt : mod.items()) { - const Span& span = use_stmt.data.sp; - use_stmt.data.path = Resolve_Use_AbsolutisePath(span, path, mv$(use_stmt.data.path)); - if( !use_stmt.data.path.m_class.is_Absolute() ) + if( ! use_stmt.data.is_Use() ) + continue ; + auto& use_stmt_data = use_stmt.data.as_Use(); + + const Span& span = use_stmt_data.sp; + use_stmt_data.path = Resolve_Use_AbsolutisePath(span, path, mv$(use_stmt_data.path)); + if( !use_stmt_data.path.m_class.is_Absolute() ) BUG(span, "Use path is not absolute after absolutisation"); // TODO: Have Resolve_Use_GetBinding return the actual path - use_stmt.data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt.data.path, parent_modules) ); + use_stmt_data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules) ); // - If doing a glob, ensure the item type is valid if( use_stmt.name == "" ) { - TU_MATCH_DEF(::AST::PathBinding, (use_stmt.data.path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding, (use_stmt_data.path.binding()), (e), ( ERROR(span, E0000, "Wildcard import of invalid item type"); ), @@ -111,7 +115,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path // TODO: Handle case where a use can resolve to two different items (one value, one type/namespace) // - Easiest way is with an extra binding slot Lookup allow = Lookup::Any; - switch( use_stmt.data.path.binding().tag() ) + switch( use_stmt_data.path.binding().tag() ) { case ::AST::PathBinding::TAG_Crate: case ::AST::PathBinding::TAG_Module: @@ -134,7 +138,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path break; } ASSERT_BUG(span, allow != Lookup::Any, ""); - use_stmt.data.alt_binding = Resolve_Use_GetBinding(span, crate, use_stmt.data.path, parent_modules, allow); + use_stmt_data.alt_binding = Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules, allow); } } @@ -243,22 +247,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path Lookup allow ) { - // HACK - Catch the possibiliy of a name clash (not sure if this is really an error) - { - bool found = false; - for( const auto& item : mod.items() ) - { - if( item.data.is_None() ) - continue ; - if( item.name == des_item_name ) { - if( found ) { - TODO(span, "Duplicate name found resolving use statement searching in module " << mod.path()); - } - found = true; - } - } - } - // If the desired item is an anon module (starts with #) then parse and index if( des_item_name.size() > 0 && des_item_name[0] == '#' ) { unsigned int idx = 0; @@ -285,6 +273,9 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path (MacroInv, BUG(span, "Hit MacroInv in use resolution"); ), + (Use, + continue; // Skip for now + ), (Crate, if( allow != Lookup::Value ) return ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) }); @@ -326,21 +317,24 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } // Imports - for( const auto& imp : mod.imports() ) + for( const auto& imp : mod.items() ) { - const Span& sp2 = imp.data.sp; + if( ! imp.data.is_Use() ) + continue ; + const auto& imp_data = imp.data.as_Use(); + const Span& sp2 = imp_data.sp; if( imp.name == des_item_name ) { - DEBUG("- Named import " << imp.name << " = " << imp.data); - if( imp.data.path.binding().is_Unbound() ) { + DEBUG("- Named import " << imp.name << " = " << imp_data); + if( imp_data.path.binding().is_Unbound() ) { DEBUG(" > Needs resolve"); // TODO: Handle possibility of recursion - //out_path = imp.data.path; - return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path), parent_modules, allow); + //out_path = imp_data.path; + return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules, allow); } else { if( allow != Lookup::Any && allow != Lookup::AnyOpt ) { - switch( imp.data.path.binding().tag() ) + switch( imp_data.path.binding().tag() ) { case ::AST::PathBinding::TAG_Crate: case ::AST::PathBinding::TAG_Module: @@ -363,23 +357,23 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path break; } } - //out_path = imp.data.path; - return imp.data.path.binding().clone(); + //out_path = imp_data.path; + return imp_data.path.binding().clone(); } } if( imp.is_pub && imp.name == "" ) { - DEBUG("- Search glob of " << imp.data.path); + DEBUG("- Search glob of " << imp_data.path); // INEFFICIENT! Resolves and throws away the result (because we can't/shouldn't mutate here) ::AST::PathBinding binding_; - const auto* binding = &imp.data.path.binding(); + const auto* binding = &imp_data.path.binding(); if( binding->is_Unbound() ) { - DEBUG("Temp resolving wildcard " << imp.data); + DEBUG("Temp resolving wildcard " << imp_data); // TODO: Handle possibility of recursion - binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path), parent_modules); + binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules); binding = &binding_; } else { - //out_path = imp.data.path; + //out_path = imp_data.path; } TU_MATCH_DEF(::AST::PathBinding, (*binding), (e), |