diff options
Diffstat (limited to 'src/resolve/use.cpp')
-rw-r--r-- | src/resolve/use.cpp | 412 |
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 ""; +//} |