summaryrefslogtreecommitdiff
path: root/src/resolve/use.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve/use.cpp')
-rw-r--r--src/resolve/use.cpp412
1 files changed, 208 insertions, 204 deletions
diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp
index db942641..a0d1aa53 100644
--- a/src/resolve/use.cpp
+++ b/src/resolve/use.cpp
@@ -22,8 +22,8 @@ enum class Lookup
::AST::Path Resolve_Use_AbsolutisePath(const ::AST::Path& base_path, ::AST::Path path);
void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path, ::std::span< const ::AST::Module* > parent_modules={});
-::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules, Lookup allow=Lookup::Any);
-::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start, Lookup allow);
+::AST::Path::Bindings Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules);
+::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start);
void Resolve_Use(::AST::Crate& crate)
@@ -117,14 +117,22 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
if( !use_stmt_data.path.m_class.is_Absolute() )
BUG(span, "Use path is not absolute after absolutisation");
+ // NOTE: Use statements can refer to _three_ different items
+ // - types/modules ("type namespace")
+ // - values ("value namespace")
+ // - macros ("macro namespace")
// 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.m_bindings = Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules);
+ if( !use_stmt_data.path.m_bindings.has_binding() )
+ {
+ ERROR(span, E0000, "Unable to resolve `use` target " << use_stmt_data.path);
+ }
DEBUG("'" << use_stmt.name << "' = " << use_stmt_data.path);
// - 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_Type, (use_stmt_data.path.m_bindings.type), (e),
(
ERROR(span, E0000, "Wildcard import of invalid item type - " << use_stmt_data.path);
),
@@ -138,35 +146,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
}
else
{
- // 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() )
- {
- case ::AST::PathBinding::TAG_Crate:
- case ::AST::PathBinding::TAG_Module:
- case ::AST::PathBinding::TAG_Trait:
- case ::AST::PathBinding::TAG_TypeAlias:
- case ::AST::PathBinding::TAG_Enum:
- allow = Lookup::Value;
- break;
- case ::AST::PathBinding::TAG_Struct:
- case ::AST::PathBinding::TAG_Union:
- allow = Lookup::Value;
- break;
- case ::AST::PathBinding::TAG_EnumVar:
- allow = Lookup::Value;
- break;
- case ::AST::PathBinding::TAG_Static:
- case ::AST::PathBinding::TAG_Function:
- allow = Lookup::Type;
- break;
- // DEAD, Unbound, ...
- default: break;
- }
- ASSERT_BUG(span, allow != Lookup::Any, "Invalid path binding type in use statement - " << use_stmt_data.path);
- use_stmt_data.alt_binding = Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules, allow);
- DEBUG("- Alt Binding: " << use_stmt_data.alt_binding);
}
}
@@ -264,25 +243,24 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
}
}
-::AST::PathBinding Resolve_Use_GetBinding_Mod(
+::AST::Path::Bindings Resolve_Use_GetBinding_Mod(
const Span& span,
const ::AST::Crate& crate, const ::AST::Module& mod,
const ::std::string& des_item_name,
- ::std::span< const ::AST::Module* > parent_modules,
- Lookup allow
+ ::std::span< const ::AST::Module* > parent_modules
)
{
+ ::AST::Path::Bindings rv;
// 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;
if( ::std::sscanf(des_item_name.c_str(), "#%u", &idx) != 1 ) {
BUG(span, "Invalid anon path segment '" << des_item_name << "'");
}
- if( idx >= mod.anon_mods().size() ) {
- BUG(span, "Invalid anon path segment '" << des_item_name << "'");
- }
+ ASSERT_BUG(span, idx < mod.anon_mods().size(), "Invalid anon path segment '" << des_item_name << "'");
assert( mod.anon_mods()[idx] );
- return ::AST::PathBinding::make_Module({&*mod.anon_mods()[idx], nullptr});
+ rv.type = ::AST::PathBinding_Type::make_Module({&*mod.anon_mods()[idx], nullptr});
+ return rv;
}
// Seach for the name defined in the module.
@@ -292,8 +270,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
continue ;
if( item.name == des_item_name ) {
- //if( allow != Lookup::Any )
- // DEBUG(mod.path() << " " << des_item_name << " " << item.data.tag_str());
TU_MATCH(::AST::Item, (item.data), (e),
(None,
// IMPOSSIBLE - Handled above
@@ -314,46 +290,38 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
BUG(span, "Hit Extern in use resolution");
),
(Crate,
- if( allow != Lookup::Value )
- ASSERT_BUG(span, crate.m_extern_crates.count(e.name), "Crate '" << e.name << "' not loaded");
- return ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) });
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.name), "Crate '" << e.name << "' not loaded");
+ rv.type = ::AST::PathBinding_Type::make_Crate({ &crate.m_extern_crates.at(e.name) });
),
(Type,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_TypeAlias({&e});
+ rv.type = ::AST::PathBinding_Type::make_TypeAlias({&e});
),
(Trait,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_Trait({&e});
+ rv.type = ::AST::PathBinding_Type::make_Trait({&e});
),
(Function,
- if( allow != Lookup::Type )
- return ::AST::PathBinding::make_Function({&e});
+ rv.value = ::AST::PathBinding_Value::make_Function({&e});
),
(Static,
- if( allow != Lookup::Type )
- return ::AST::PathBinding::make_Static({&e});
+ rv.value = ::AST::PathBinding_Value::make_Static({&e});
),
(Struct,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_Struct({&e});
- if( e.m_data.is_Tuple() && allow != Lookup::Type )
- return ::AST::PathBinding::make_Struct({&e});
+ if( !e.m_data.is_Struct() )
+ rv.value = ::AST::PathBinding_Value::make_Struct({&e});
+ rv.type = ::AST::PathBinding_Type::make_Struct({&e});
),
(Enum,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_Enum({&e});
+ rv.type = ::AST::PathBinding_Type::make_Enum({&e});
),
(Union,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_Union({&e});
+ rv.type = ::AST::PathBinding_Type::make_Union({&e});
),
(Module,
- if( allow != Lookup::Value )
- return ::AST::PathBinding::make_Module({&e});
+ rv.type = ::AST::PathBinding_Type::make_Module({&e});
)
)
+ return rv;
}
}
@@ -366,58 +334,33 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
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() ) {
+ if( !imp_data.path.m_bindings.has_binding() ) {
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);
+ return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules);
}
else {
- if( allow != Lookup::Any && allow != Lookup::AnyOpt )
- {
- switch( imp_data.path.binding().tag() )
- {
- case ::AST::PathBinding::TAG_Crate:
- case ::AST::PathBinding::TAG_Module:
- case ::AST::PathBinding::TAG_Trait:
- case ::AST::PathBinding::TAG_TypeAlias:
- case ::AST::PathBinding::TAG_Enum:
- if( allow != Lookup::Type )
- continue;
- break;
- case ::AST::PathBinding::TAG_Struct:
- break;
- case ::AST::PathBinding::TAG_EnumVar:
- break;
- case ::AST::PathBinding::TAG_Static:
- case ::AST::PathBinding::TAG_Function:
- if( allow != Lookup::Value )
- continue;
- break;
- default:
- break;
- }
- }
//out_path = imp_data.path;
- return imp_data.path.binding().clone();
+ return imp_data.path.m_bindings.clone();
}
}
if( imp.is_pub && imp.name == "" ) {
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();
- if( binding->is_Unbound() ) {
+ ::AST::Path::Bindings bindings_;
+ const auto* bindings = &imp_data.path.m_bindings;
+ if( bindings->type.is_Unbound() ) {
DEBUG("Temp resolving wildcard " << imp_data);
// Handle possibility of recursion
static ::std::vector<const ::AST::UseStmt*> resolve_stack_ptrs;
if( ::std::find(resolve_stack_ptrs.begin(), resolve_stack_ptrs.end(), &imp_data) == resolve_stack_ptrs.end() )
{
resolve_stack_ptrs.push_back( &imp_data );
- binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules);
+ bindings_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules);
// *waves hand* I'm not evil.
- const_cast< ::AST::PathBinding&>( imp_data.path.binding() ) = binding_.clone();
- binding = &binding_;
+ const_cast< ::AST::Path::Bindings&>( imp_data.path.m_bindings ) = bindings_.clone();
+ bindings = &bindings_;
resolve_stack_ptrs.pop_back();
}
else {
@@ -428,28 +371,27 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
//out_path = imp_data.path;
}
- TU_MATCH_HDR( (*binding), {)
- TU_ARM(*binding, Crate, e) {
+ TU_MATCH_HDRA( (bindings->type), {)
+ TU_ARMA(Crate, e) {
assert(e.crate_);
const ::HIR::Module& hmod = e.crate_->m_hir->m_root_module;
- auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0, allow);
- if( ! rv.is_Unbound() ) {
+ auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0);
+ if( rv.has_binding() ) {
return mv$(rv);
}
}
- TU_ARM(*binding, Module, e) {
- auto allow_inner = (allow == Lookup::Any ? Lookup::AnyOpt : allow);
+ TU_ARMA(Module, e) {
if( 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() ) {
+ auto rv = Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {});
+ if( rv.has_binding() ) {
return mv$(rv);
}
}
else if( e.hir ) {
const ::HIR::Module& hmod = *e.hir;
- auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0, allow);
- if( ! rv.is_Unbound() ) {
+ auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0);
+ if( rv.has_binding() ) {
return mv$(rv);
}
}
@@ -457,7 +399,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
BUG(span, "NULL module for binding on glob of " << imp_data.path);
}
}
- TU_ARM(*binding, Enum, e) {
+ TU_ARMA(Enum, e) {
assert(e.enum_ || e.hir);
if( e.enum_ ) {
const auto& enm = *e.enum_;
@@ -465,7 +407,12 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
for(const auto& var : enm.variants())
{
if( var.m_name == des_item_name ) {
- return ::AST::PathBinding::make_EnumVar({ &enm, i });
+ ::AST::Path::Bindings rv;
+ if( var.m_data.is_Struct() )
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({ &enm, i });
+ else
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({ &enm, i });
+ return rv;
}
i ++;
}
@@ -475,12 +422,19 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
auto idx = enm.find_variant(des_item_name);
if( idx != SIZE_MAX )
{
- return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast<unsigned>(idx), &enm });
+ ::AST::Path::Bindings rv;
+ if( enm.m_data.is_Data() && enm.m_data.as_Data()[idx].is_struct ) {
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast<unsigned>(idx), &enm });
+ }
+ else {
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast<unsigned>(idx), &enm });
+ }
+ return rv;
}
}
} break;
default:
- BUG(sp2, "Wildcard import expanded to an invalid item class - " << binding->tag_str());
+ BUG(sp2, "Wildcard import expanded to an invalid item class - " << bindings->type.tag_str());
break;
}
}
@@ -488,13 +442,12 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
if( mod.path().nodes().size() > 0 && mod.path().nodes().back().name()[0] == '#' ) {
assert( parent_modules.size() > 0 );
- return Resolve_Use_GetBinding_Mod(span, crate, *parent_modules.back(), des_item_name, parent_modules.subspan(0, parent_modules.size()-1), allow);
+ return Resolve_Use_GetBinding_Mod(span, crate, *parent_modules.back(), des_item_name, parent_modules.subspan(0, parent_modules.size()-1));
}
else {
- if( allow == Lookup::Any )
- ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path());
- else
- return ::AST::PathBinding::make_Unbound({});
+ //if( allow == Lookup::Any )
+ // ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path());
+ return ::AST::Path::Bindings();
}
}
@@ -543,8 +496,9 @@ namespace {
}
}
-::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start, Lookup allow)
+::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start)
{
+ ::AST::Path::Bindings rv;
TRACE_FUNCTION_F(path);
const auto& nodes = path.nodes();
const ::HIR::Module* hmod = &hmodr;
@@ -577,7 +531,13 @@ namespace {
if( idx == SIZE_MAX ) {
ERROR(span, E0000, "Unable to find variant " << path);
}
- return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &enm });
+ if( enm.m_data.is_Data() && enm.m_data.as_Data()[idx].is_struct ) {
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &enm });
+ }
+ else {
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &enm });
+ }
+ return rv;
}
else {
hmod = reinterpret_cast<const ::HIR::Module*>(ptr);
@@ -597,16 +557,23 @@ namespace {
if(idx == SIZE_MAX) {
ERROR(span, E0000, "Unable to find variant " << path);
}
- return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &e });
+ if( e.m_data.is_Data() && e.m_data.as_Data()[idx].is_struct ) {
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &e });
+ }
+ else {
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast<unsigned int>(idx), &e });
+ }
+ return rv;
)
)
}
- if( allow != Lookup::Value )
+ // - namespace/type items
{
auto it = hmod->m_mod_items.find(nodes.back().name());
- if( it != hmod->m_mod_items.end() ) {
+ if( it != hmod->m_mod_items.end() )
+ {
const auto* item_ptr = &it->second->ent;
- DEBUG("E : " << nodes.back().name() << " = " << item_ptr->tag_str());
+ DEBUG("E : Mod " << nodes.back().name() << " = " << item_ptr->tag_str());
if( item_ptr->is_Import() ) {
const auto& e = item_ptr->as_Import();
const auto& ec = crate.m_extern_crates.at( e.path.m_crate_name );
@@ -616,94 +583,117 @@ namespace {
p.m_components.pop_back();
const auto& enm = ec.m_hir->get_typeitem_by_path(span, p, true).as_Enum();
assert(e.idx < enm.num_variants());
- return ::AST::PathBinding::make_EnumVar({ nullptr, e.idx, &enm });
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, e.idx, &enm });
+ }
+ else if( e.path.m_components.empty() )
+ {
+ rv.type = ::AST::PathBinding_Type::make_Module({nullptr, &ec.m_hir->m_root_module});
+ }
+ else
+ {
+ item_ptr = &ec.m_hir->get_typeitem_by_path(span, e.path, true); // ignore_crate_name=true
}
- if( e.path.m_components.empty() )
- return ::AST::PathBinding::make_Module({nullptr, &ec.m_hir->m_root_module});
- item_ptr = &ec.m_hir->get_typeitem_by_path(span, e.path, true); // ignore_crate_name=true
}
- TU_MATCHA( (*item_ptr), (e),
- (Import,
- BUG(span, "Recursive import in " << path << " - " << it->second->ent.as_Import().path << " -> " << e.path);
- ),
- (Module,
- return ::AST::PathBinding::make_Module({nullptr, &e});
- ),
- (TypeAlias,
- return ::AST::PathBinding::make_TypeAlias({nullptr});
- ),
- (Enum,
- return ::AST::PathBinding::make_Enum({nullptr, &e});
- ),
- (Struct,
- return ::AST::PathBinding::make_Struct({nullptr, &e});
- ),
- (Union,
- return ::AST::PathBinding::make_Union({nullptr, &e});
- ),
- (Trait,
- return ::AST::PathBinding::make_Trait({nullptr, &e});
+ if( rv.type.is_Unbound() )
+ {
+ TU_MATCHA( (*item_ptr), (e),
+ (Import,
+ BUG(span, "Recursive import in " << path << " - " << it->second->ent.as_Import().path << " -> " << e.path);
+ ),
+ (Module,
+ rv.type = ::AST::PathBinding_Type::make_Module({nullptr, &e});
+ ),
+ (TypeAlias,
+ rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr});
+ ),
+ (Enum,
+ rv.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e});
+ ),
+ (Struct,
+ rv.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e});
+ ),
+ (Union,
+ rv.type = ::AST::PathBinding_Type::make_Union({nullptr, &e});
+ ),
+ (Trait,
+ rv.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e});
+ )
)
- )
+ }
+ }
+ else
+ {
+ DEBUG("Types = " << FMT_CB(ss, for(const auto& e : hmod->m_mod_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; }));
}
- DEBUG("Types = " << FMT_CB(ss, for(const auto& e : hmod->m_mod_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; }));
}
- if( allow != Lookup::Type )
+ // - Values
{
auto it2 = hmod->m_value_items.find(nodes.back().name());
if( it2 != hmod->m_value_items.end() ) {
const auto* item_ptr = &it2->second->ent;
- DEBUG("E : " << nodes.back().name() << " = " << item_ptr->tag_str());
+ DEBUG("E : Value " << nodes.back().name() << " = " << item_ptr->tag_str());
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.path.m_crate_name );
- if( e.is_variant ) {
+ if( e.is_variant )
+ {
auto p = e.path;
p.m_components.pop_back();
const auto& enm = ec.m_hir->get_typeitem_by_path(span, p, true).as_Enum();
assert(e.idx < enm.num_variants());
- return ::AST::PathBinding::make_EnumVar({ nullptr, e.idx, &enm });
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, e.idx, &enm });
+ }
+ else
+ {
+ item_ptr = &ec.m_hir->get_valitem_by_path(span, e.path, true); // ignore_crate_name=true
}
- item_ptr = &ec.m_hir->get_valitem_by_path(span, e.path, true); // ignore_crate_name=true
}
- TU_MATCHA( (*item_ptr), (e),
- (Import,
- BUG(span, "Recursive import in " << path << " - " << it2->second->ent.as_Import().path << " -> " << e.path);
- ),
- (Constant,
- return ::AST::PathBinding::make_Static({ nullptr });
- ),
- (Static,
- return ::AST::PathBinding::make_Static({ nullptr });
- ),
- // TODO: What happens if these two refer to an enum constructor?
- (StructConstant,
- ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
- return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
- ),
- (StructConstructor,
- ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
- return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
- ),
- (Function,
- return ::AST::PathBinding::make_Function({ nullptr });
+ if( rv.value.is_Unbound() )
+ {
+ TU_MATCHA( (*item_ptr), (e),
+ (Import,
+ BUG(span, "Recursive import in " << path << " - " << it2->second->ent.as_Import().path << " -> " << e.path);
+ ),
+ (Constant,
+ rv.value = ::AST::PathBinding_Value::make_Static({ nullptr });
+ ),
+ (Static,
+ rv.value = ::AST::PathBinding_Value::make_Static({ nullptr });
+ ),
+ // TODO: What happens if these two refer to an enum constructor?
+ (StructConstant,
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
+ rv.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
+ ),
+ (StructConstructor,
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
+ rv.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
+ ),
+ (Function,
+ rv.value = ::AST::PathBinding_Value::make_Function({ nullptr });
+ )
)
- )
+ }
+ }
+ else
+ {
+ DEBUG("Values = " << FMT_CB(ss, for(const auto& e : hmod->m_value_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; }));
}
-
- DEBUG("Values = " << FMT_CB(ss, for(const auto& e : hmod->m_value_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; }));
}
- DEBUG("E : None");
- return ::AST::PathBinding::make_Unbound({});
+ if( rv.type.is_Unbound() && rv.value.is_Unbound() )
+ {
+ DEBUG("E : None");
+ }
+ return rv;
}
-::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const AST::ExternCrate& ec, unsigned int start, Lookup allow)
+::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const AST::ExternCrate& ec, unsigned int start)
{
- return Resolve_Use_GetBinding__ext(span, crate, path, ec.m_hir->m_root_module, start, allow);
+ return Resolve_Use_GetBinding__ext(span, crate, path, ec.m_hir->m_root_module, start);
}
-::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules, Lookup allow)
+::AST::Path::Bindings Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules)
{
TRACE_FUNCTION_F(path);
//::AST::Path rv;
@@ -713,14 +703,17 @@ namespace {
const auto& path_abs = path.m_class.as_Absolute();
ASSERT_BUG(span, crate.m_extern_crates.count(path_abs.crate), "Crate '" << path_abs.crate << "' not loaded");
- return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0, allow);
+ return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0);
}
+ ::AST::Path::Bindings rv;
+
const AST::Module* mod = &crate.m_root_module;
const auto& nodes = path.nodes();
if( nodes.size() == 0 ) {
// An import of the root.
- return ::AST::PathBinding::make_Module({ mod, nullptr });
+ rv.type = ::AST::PathBinding_Type::make_Module({ mod, nullptr });
+ return rv;
}
for( unsigned int i = 0; i < nodes.size()-1; i ++ )
{
@@ -729,19 +722,18 @@ namespace {
//rv = Resolve_Use_CanoniseAndBind_Mod(span, crate, *mod, mv$(rv), nodes[i].name(), parent_modules, Lookup::Type);
//const auto& b = rv.binding();
assert(mod);
- auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.at(i).name(), parent_modules, Lookup::Type);
- TU_MATCH_DEF(::AST::PathBinding, (b), (e),
- (
- ERROR(span, E0000, "Unexpected item type " << b.tag_str() << " in import of " << path);
- ),
- (Unbound,
- ERROR(span, E0000, "Cannot find component " << i << " of " << path);
- ),
- (Crate,
+ auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.at(i).name(), parent_modules);
+ TU_MATCH_HDRA( (b.type), {)
+ default:
+ ERROR(span, E0000, "Unexpected item type " << b.type.tag_str() << " in import of " << path);
+ TU_ARMA(Unbound, e) {
+ ERROR(span, E0000, "Cannot find component " << i << " of " << path << " (" << b.type << ")");
+ }
+ TU_ARMA(Crate, e) {
// TODO: Mangle the original path (or return a new path somehow)
- return Resolve_Use_GetBinding__ext(span, crate, path, *e.crate_, i+1, allow);
- ),
- (Enum,
+ return Resolve_Use_GetBinding__ext(span, crate, path, *e.crate_, i+1);
+ }
+ TU_ARMA(Enum, e) {
const auto& enum_ = *e.enum_;
i += 1;
if( i != nodes.size() - 1 ) {
@@ -750,10 +742,12 @@ namespace {
const auto& node2 = nodes[i];
int variant_index = -1;
+ bool is_value;
for( unsigned int j = 0; j < enum_.variants().size(); j ++ )
{
if( enum_.variants()[j].m_name == node2.name() ) {
variant_index = j;
+ is_value = !enum_.variants()[i].m_data.is_Struct();
break ;
}
}
@@ -761,22 +755,32 @@ namespace {
ERROR(span, E0000, "Unknown enum variant '" << node2.name() << "'");
}
- return ::AST::PathBinding::make_EnumVar({&enum_, static_cast<unsigned int>(variant_index)});
- ),
- (Module,
+ if( is_value ) {
+ rv.value = ::AST::PathBinding_Value::make_EnumVar({&enum_, static_cast<unsigned int>(variant_index)});
+ }
+ else {
+ rv.type = ::AST::PathBinding_Type::make_EnumVar({&enum_, static_cast<unsigned int>(variant_index)});
+ }
+ return rv;
+ }
+ TU_ARMA(Module, e) {
ASSERT_BUG(span, e.module_ || e.hir, "nullptr module pointer in node " << i << " of " << path);
if( !e.module_ )
{
assert(e.hir);
// TODO: Mangle the original path (or return a new path somehow)
- return Resolve_Use_GetBinding__ext(span, crate, path, *e.hir, i+1, allow);
+ return Resolve_Use_GetBinding__ext(span, crate, path, *e.hir, i+1);
}
mod = e.module_;
- )
- )
+ }
+ }
}
assert(mod);
- return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name(), parent_modules, allow);
+ return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name(), parent_modules);
}
+//::AST::PathBinding_Macro Resolve_Use_GetBinding_Macro(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules)
+//{
+// throw "";
+//}