summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-25 23:09:17 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-25 23:09:17 +0800
commit6c16703e6a3be274c4fe183ffde10fd7a20f8236 (patch)
tree8a9b0ad911f73b9e2f6357fa6534e4583165dd40 /src
parent72e2a322f52edd7bf3f37ad840f2d48be4192d62 (diff)
downloadmrust-6c16703e6a3be274c4fe183ffde10fd7a20f8236.tar.gz
AST - Convert use statements to normal items
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp131
-rw-r--r--src/ast/ast.hpp73
-rw-r--r--src/dump_as_rust.cpp10
-rw-r--r--src/expand/mod.cpp21
-rw-r--r--src/hir/from_ast.cpp3
-rw-r--r--src/parse/root.cpp33
-rw-r--r--src/resolve/absolute.cpp4
-rw-r--r--src/resolve/index.cpp71
-rw-r--r--src/resolve/use.cpp70
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),