diff options
author | John Hodge <tpg@mutabah.net> | 2018-12-28 16:58:52 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-12-28 16:58:52 +0800 |
commit | e16796df604ba1017a19917ea94840ee8c4b0336 (patch) | |
tree | 5989361e02b98f036612c064229a77d040424942 /src | |
parent | 83f59c8887adcaa3486cb64c5a78a4660223e234 (diff) | |
download | mrust-e16796df604ba1017a19917ea94840ee8c4b0336.tar.gz |
Resolve - Clean up AST path bindings, one binding per namespace
- This is prep work for supporting `use` of macros
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 2 | ||||
-rw-r--r-- | src/ast/ast.hpp | 1 | ||||
-rw-r--r-- | src/ast/path.cpp | 140 | ||||
-rw-r--r-- | src/ast/path.hpp | 122 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 71 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 54 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 6 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 110 | ||||
-rw-r--r-- | src/resolve/index.cpp | 197 | ||||
-rw-r--r-- | src/resolve/use.cpp | 412 |
10 files changed, 600 insertions, 515 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index e4fe49da..b439553a 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -257,7 +257,7 @@ MacroInvocation MacroInvocation::clone() const UseStmt UseStmt::clone() const { - return UseStmt(sp, path); + return UseStmt(sp, AST::Path(path)); } void ExternBlock::add_item(Named<Item> named_item) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 49e2bdc6..2d802f53 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -466,7 +466,6 @@ struct UseStmt { Span sp; ::AST::Path path; - ::AST::PathBinding alt_binding; UseStmt(Span sp, Path p): sp(sp), diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 6fdf1e40..0c8c4c69 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -17,8 +17,8 @@ namespace AST { // --- AST::PathBinding -::std::ostream& operator<<(::std::ostream& os, const PathBinding& x) { - TU_MATCH(PathBinding, (x), (i), +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Type& x) { + TU_MATCHA( (x), (i), (Unbound, os << "_"; ), (Crate , os << "Crate"; ), (Module, os << "Module"; ), @@ -26,39 +26,80 @@ namespace AST { (Struct, os << "Struct"; ), (Enum, os << "Enum"; ), (Union, os << "Union"; ), + (EnumVar, os << "EnumVar(" << i.idx << ")"; ), + (TypeAlias, os << "TypeAlias";), + (TypeParameter, os << "TyParam(" << i.level << " # " << i.idx << ")"; ) + ) + return os; +} +PathBinding_Type PathBinding_Type::clone() const +{ + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Type::make_Unbound({}); ), + (Module , return PathBinding_Type::make_Module(e); ), + (Crate , return PathBinding_Type(e); ), + (Trait , return PathBinding_Type(e); ), + (Struct , return PathBinding_Type(e); ), + (Enum , return PathBinding_Type(e); ), + (Union , return PathBinding_Type(e); ), + (TypeAlias, return PathBinding_Type::make_TypeAlias(e); ), + (EnumVar , return PathBinding_Type::make_EnumVar(e); ), + + (TypeParameter, return PathBinding_Type::make_TypeParameter(e); ) + ) + throw "BUG: Fell off the end of PathBinding_Type::clone"; +} +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Value& x) { + TU_MATCHA( (x), (i), + (Unbound, os << "_"; ), + (Struct, os << "Struct"; ), (Static, os << "Static"; ), (Function, os << "Function";), (EnumVar, os << "EnumVar(" << i.idx << ")"; ), - (TypeAlias, os << "TypeAlias";), - (StructMethod, os << "StructMethod"; ), - (TraitMethod, os << "TraitMethod"; ), - - (TypeParameter, os << "TyParam(" << i.level << " # " << i.idx << ")"; ), (Variable, os << "Var(" << i.slot << ")"; ) ) return os; } -PathBinding PathBinding::clone() const +PathBinding_Value PathBinding_Value::clone() const { - TU_MATCH(::AST::PathBinding, (*this), (e), - (Unbound , return PathBinding::make_Unbound({}); ), - (Module , return PathBinding::make_Module(e); ), - (Crate , return PathBinding(e); ), - (Trait , return PathBinding(e); ), - (Struct , return PathBinding(e); ), - (Enum , return PathBinding(e); ), - (Union , return PathBinding(e); ), - (Static , return PathBinding(e); ), - (Function, return PathBinding(e); ), - (TypeAlias, return PathBinding::make_TypeAlias(e); ), - (EnumVar , return PathBinding::make_EnumVar(e); ), - (StructMethod, return PathBinding::make_StructMethod(e); ), - (TraitMethod, return PathBinding::make_TraitMethod(e); ), - - (TypeParameter, return PathBinding::make_TypeParameter(e); ), - (Variable, return PathBinding::make_Variable(e); ) + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Value::make_Unbound({}); ), + (Struct , return PathBinding_Value(e); ), + (Static , return PathBinding_Value(e); ), + (Function, return PathBinding_Value(e); ), + (EnumVar , return PathBinding_Value::make_EnumVar(e); ), + (Variable, return PathBinding_Value::make_Variable(e); ) ) - throw "BUG: Fell off the end of PathBinding::clone"; + throw "BUG: Fell off the end of PathBinding_Value::clone"; +} +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Macro& x) { + TU_MATCHA( (x), (i), + (Unbound, os << "_"; ), + (ProcMacroDerive, + os << "ProcMacroDerive(? " << i.mac_name << ")"; + ), + (ProcMacroAttribute, + os << "ProcMacroAttribute(? " << i.mac_name << ")"; + ), + (ProcMacro, + os << "ProcMacro(? " << i.mac_name << ")"; + ), + (MacroRules, + os << "MacroRules(? ?)"; + ) + ) + return os; +} +PathBinding_Macro PathBinding_Macro::clone() const +{ + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Macro::make_Unbound({}); ), + (ProcMacroDerive, return PathBinding_Macro(e); ), + (ProcMacroAttribute, return PathBinding_Macro(e); ), + (ProcMacro, return PathBinding_Macro(e); ), + (MacroRules, return PathBinding_Macro(e); ) + ) + throw "BUG: Fell off the end of PathBinding_Macro::clone"; } ::std::ostream& operator<<(::std::ostream& os, const PathParams& x) @@ -159,8 +200,10 @@ AST::Path::Path(TagUfcs, TypeRef type, Path trait, ::std::vector<AST::PathNode> } AST::Path::Path(const Path& x): m_class() - //m_binding(x.m_binding) + //,m_bindings(x.m_bindings) { + memcpy(&m_bindings, &x.m_bindings, sizeof(Bindings)); + TU_MATCH(Class, (x.m_class), (ent), (Invalid, m_class = Class::make_Invalid({});), (Local, @@ -185,15 +228,13 @@ AST::Path::Path(const Path& x): m_class = Class::make_UFCS({ box$(ent.type->clone()), nullptr, ent.nodes }); ) ) - - memcpy(&m_binding, &x.m_binding, sizeof(PathBinding)); } void Path::bind_variable(unsigned int slot) { - m_binding = PathBinding::make_Variable({slot}); + m_bindings.value = PathBinding_Value::make_Variable({slot}); } -void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector<TypeRef>& /*args*/) +void Path::bind_enum_var(const Enum& ent, const ::std::string& name) { auto it = ::std::find_if(ent.variants().begin(), ent.variants().end(), [&](const auto& x) { return x.m_name == name; }); if( it == ent.variants().end() ) @@ -203,10 +244,8 @@ void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std unsigned int idx = it - ent.variants().begin(); DEBUG("Bound to enum variant '" << name << "' (#" << idx << ")"); - ::AST::PathBinding::Data_EnumVar tmp = {}; - tmp.enum_ = &ent; - tmp.idx = idx; - m_binding = PathBinding::make_EnumVar( mv$(tmp) ); + m_bindings.type = PathBinding_Type::make_EnumVar({ &ent, idx }); + m_bindings.value = PathBinding_Value::make_EnumVar({ &ent, idx }); } Path& Path::operator+=(const Path& other) @@ -214,7 +253,7 @@ Path& Path::operator+=(const Path& other) for(auto& node : other.nodes()) append(node); // If the path is modified, clear the binding - m_binding = PathBinding(); + m_bindings = Bindings(); return *this; } @@ -268,13 +307,13 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context, bool is_debug) ), (Local, // Only print comment if there's no binding - if( m_binding.is_Unbound() ) + if( m_bindings.value.is_Unbound() ) { if( is_debug ) os << "/*var*/"; } else - assert( m_binding.is_Variable() ); + assert( m_bindings.value.is_Variable() ); os << ent.name; ), (Relative, @@ -334,8 +373,29 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context, bool is_debug) } ) ) - if( is_debug ) - os << "/*" << m_binding << "*/"; + if( is_debug ) { + os << "/*"; + bool printed = false; + if( !m_bindings.value.is_Unbound() ) { + if(printed) os << ","; + os << "v:" << m_bindings.value; + printed = true; + } + if( !m_bindings.type.is_Unbound() ) { + if(printed) os << ","; + os << "t:" << m_bindings.type; + printed = true; + } + if( !m_bindings.macro.is_Unbound() ) { + if(printed) os << ","; + os << "m:" << m_bindings.macro; + printed = true; + } + if( !printed ) { + os << "?"; + } + os << "*/"; + } } ::std::ostream& operator<<(::std::ostream& os, const Path& path) diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 2693a070..b1453f04 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -45,7 +45,36 @@ class Static; class Function; class ExternCrate; -TAGGED_UNION_EX(PathBinding, (), Unbound, ( +TAGGED_UNION_EX(PathBinding_Value, (), Unbound, ( + (Unbound, struct { + }), + (Struct, struct { + const Struct* struct_; + const ::HIR::Struct* hir; + }), + (Static, struct { + const Static* static_; + const ::HIR::Static* hir; // if nullptr and static_ == nullptr, points to a `const` + }), + (Function, struct { + const Function* func_; + }), + (EnumVar, struct { + const Enum* enum_; + unsigned int idx; + const ::HIR::Enum* hir; + }), + (Variable, struct { + unsigned int slot; + }) + ), + (), (), + ( + public: + PathBinding_Value clone() const; + ) + ); +TAGGED_UNION_EX(PathBinding_Type, (), Unbound, ( (Unbound, struct { }), (Crate, struct { @@ -71,13 +100,7 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( const Trait* trait_; const ::HIR::Trait* hir; }), - (Static, struct { - const Static* static_; - const ::HIR::Static* hir; // if nullptr and static_ == nullptr, points to a `const` - }), - (Function, struct { - const Function* func_; - }), + (EnumVar, struct { const Enum* enum_; unsigned int idx; @@ -86,31 +109,48 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( (TypeAlias, struct { const TypeAlias* alias_; }), - (StructMethod, struct { - const Struct* struct_; - ::std::string name; - }), - (TraitMethod, struct { - const Trait* trait_; - ::std::string name; - }), (TypeParameter, struct { unsigned int level; unsigned int idx; + }) + ), + (), (), + ( + public: + PathBinding_Type clone() const; + ) + ); +TAGGED_UNION_EX(PathBinding_Macro, (), Unbound, ( + (Unbound, struct { }), - (Variable, struct { - unsigned int slot; + (ProcMacroDerive, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (ProcMacroAttribute, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (ProcMacro, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (MacroRules, struct { + const ExternCrate* crate_; // Can be NULL + //const MacroRules* mac; }) ), (), (), ( public: - PathBinding clone() const; + PathBinding_Macro clone() const; ) ); -extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Value& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Type& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Macro& x); struct PathParams { @@ -191,23 +231,30 @@ public: public: Class m_class; -private: - PathBinding m_binding; -public: + struct Bindings { + PathBinding_Value value; + PathBinding_Type type; + PathBinding_Macro macro; + + Bindings clone() const { + return Bindings { + value.clone(), type.clone(), macro.clone() + }; + } + bool has_binding() const { + return !value.is_Unbound() || !type.is_Unbound() || !macro.is_Unbound(); + } + } m_bindings; + virtual ~Path(); // INVALID Path(): m_class() {} Path(Path&&) = default; - Path& operator=(AST::Path&& x) { - m_class = mv$(x.m_class); - m_binding = mv$(x.m_binding); - //DEBUG("Path, " << x); - return *this; - } + Path& operator=(AST::Path&& x) = default; - Path(const Path& x); + /*explicit*/ Path(const Path& x); Path& operator=(const AST::Path&) = delete; // ABSOLUTE @@ -281,7 +328,7 @@ public: //if( m_class.is_Invalid() ) // m_class = Class::make_Relative({}); nodes().push_back( mv$(node) ); - m_binding = PathBinding(); + m_bindings = Bindings(); } bool is_trivial() const { @@ -318,8 +365,6 @@ public: bool is_concrete() const; - bool is_bound() const { return !m_binding.is_Unbound(); } - const PathBinding& binding() const { return m_binding; } void bind_variable(unsigned int slot); ::std::vector<PathNode>& nodes() { @@ -353,14 +398,9 @@ private: void check_param_counts(const GenericParams& params, bool expect_params, PathNode& node); public: - void bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector<TypeRef>& args={}); - void bind_function(const Function& ent, const ::std::vector<TypeRef>& args={}) { - (void)args; - m_binding = PathBinding::make_Function({&ent}); - } - - void bind(::AST::PathBinding pb) { - m_binding = mv$(pb); + void bind_enum_var(const Enum& ent, const ::std::string& name); + void bind_function(const Function& ent) { + m_bindings.value = PathBinding_Value::make_Function({&ent}); } }; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 1079e981..f62d097a 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -214,11 +214,10 @@ const ::AST::Crate* g_ast_crate_ptr; (StructTuple, unsigned int leading_count = e.tup_pat.start.size(); unsigned int trailing_count = e.tup_pat.end .size(); - TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), - ( + TU_MATCH_HDRA( (e.path.m_bindings.value), {) + default: BUG(pat.span(), "Encountered StructTuple pattern not pointing to a enum variant or a struct - " << e.path); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { assert( pb.enum_ || pb.hir ); unsigned int field_count; if( pb.enum_ ) { @@ -268,8 +267,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(sub_patterns) }) }; - ), - (Struct, + } + TU_ARMA(Struct, pb) { assert( pb.struct_ || pb.hir ); unsigned int field_count; if( pb.struct_ ) { @@ -317,8 +316,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(sub_patterns) }) }; - ) - ) + } + } ), (Struct, ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > sub_patterns; @@ -326,11 +325,10 @@ const ::AST::Crate* g_ast_crate_ptr; sub_patterns.push_back( ::std::make_pair(sp.first, LowerHIR_Pattern(sp.second)) ); - TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), - ( + TU_MATCH_HDRA( (e.path.m_bindings.type), {) + default: BUG(pat.span(), "Encountered Struct pattern not pointing to a enum variant or a struct - " << e.path); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_EnumStruct({ @@ -340,8 +338,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ), - (TypeAlias, + } + TU_ARMA(TypeAlias, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Struct({ @@ -351,8 +349,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ), - (Struct, + } + TU_ARMA(Struct, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Struct({ @@ -362,8 +360,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ) - ) + } + } ), (Value, @@ -750,9 +748,9 @@ const ::AST::Crate* g_ast_crate_ptr; TU_IFLET(::AST::Path::Class, e.path.m_class, Local, l, unsigned int slot; // NOTE: TypeParameter is unused - TU_IFLET(::AST::PathBinding, e.path.binding(), Variable, p, - slot = p.slot; - ) + if( const auto* p = e.path.m_bindings.value.opt_Variable() ) { + slot = p->slot; + } else { BUG(ty.span(), "Unbound local encountered in " << e.path); } @@ -768,7 +766,7 @@ const ::AST::Crate* g_ast_crate_ptr; for(const auto& t : e.traits) { DEBUG("t = " << t.path); - const auto& tb = t.path.binding().as_Trait(); + const auto& tb = t.path.m_bindings.type.as_Trait(); assert( tb.trait_ || tb.hir ); if( (tb.trait_ ? tb.trait_->is_marker() : tb.hir->m_is_marker) ) { @@ -1361,7 +1359,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H // Populate trait list for(const auto& item : ast_mod.m_type_items) { - if( item.second.path.binding().is_Trait() ) { + if( item.second.path.m_bindings.type.is_Trait() ) { auto sp = LowerHIR_SimplePath(Span(), item.second.path); if( ::std::find(mod.m_traits.begin(), mod.m_traits.end(), sp) == mod.m_traits.end() ) mod.m_traits.push_back( mv$(sp) ); @@ -1500,16 +1498,14 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H if( ie.second.is_import ) { auto hir_path = LowerHIR_SimplePath( sp, ie.second.path ); ::HIR::TypeItem ti; - TU_MATCH_DEF( ::AST::PathBinding, (ie.second.path.binding()), (pb), - ( + if( const auto* pb = ie.second.path.m_bindings.type.opt_EnumVar() ) { + DEBUG("Import NS " << ie.first << " = " << hir_path << " (Enum Variant)"); + ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), true, pb->idx }); + } + else { DEBUG("Import NS " << ie.first << " = " << hir_path); ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), false, 0 }); - ), - (EnumVar, - DEBUG("Import NS " << ie.first << " = " << hir_path << " (Enum Variant)"); - ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), true, pb.idx }); - ) - ) + } _add_mod_ns_item(mod, ie.first, ie.second.is_pub, mv$(ti)); } } @@ -1520,16 +1516,15 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H auto hir_path = LowerHIR_SimplePath( sp, ie.second.path ); ::HIR::ValueItem vi; - TU_MATCH_DEF( ::AST::PathBinding, (ie.second.path.binding()), (pb), - ( + TU_MATCH_HDRA( (ie.second.path.m_bindings.value), {) + default: DEBUG("Import VAL " << ie.first << " = " << hir_path); vi = ::HIR::ValueItem::make_Import({ mv$(hir_path), false, 0 }); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { DEBUG("Import VAL " << ie.first << " = " << hir_path << " (Enum Variant)"); vi = ::HIR::ValueItem::make_Import({ mv$(hir_path), true, pb.idx }); - ) - ) + } + } _add_mod_val_item(mod, ie.first, ie.second.is_pub, mv$(vi)); } } @@ -1566,7 +1561,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat if( impl.def().trait().ent.is_valid() ) { - const auto& pb = impl.def().trait().ent.binding(); + const auto& pb = impl.def().trait().ent.m_bindings.type; ASSERT_BUG(Span(), pb.is_Trait(), "Binding for trait path in impl isn't a Trait - " << impl.def().trait().ent); ASSERT_BUG(Span(), pb.as_Trait().trait_ || pb.as_Trait().hir, "Trait pointer for trait path in impl isn't set"); bool is_marker = (pb.as_Trait().trait_ ? pb.as_Trait().trait_->is_marker() : pb.as_Trait().hir->m_is_marker); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 6daf49c3..cc642482 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -211,22 +211,22 @@ struct LowerHIR_ExprNode_Visitor: TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, m_rv.reset( new ::HIR::ExprNode_CallValue( v.span(), - ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( v.span(), e.name, v.m_path.binding().as_Variable().slot )), + ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( v.span(), e.name, v.m_path.m_bindings.value.as_Variable().slot )), mv$(args) ) ); ) else { - TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding_Value, (v.m_path.m_bindings.value), (e), ( m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(), LowerHIR_Path(v.span(), v.m_path), mv$( args ) ) ); ), - (TypeAlias, - TODO(v.span(), "CallPath -> TupleVariant TypeAlias"); - ), + //(TypeAlias, + // TODO(v.span(), "CallPath -> TupleVariant TypeAlias"); + // ), (EnumVar, m_rv.reset( new ::HIR::ExprNode_TupleVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), false, @@ -508,7 +508,7 @@ struct LowerHIR_ExprNode_Visitor: ) ); } virtual void visit(::AST::ExprNode_StructLiteral& v) override { - if( v.m_path.binding().is_Union() ) + if( v.m_path.m_bindings.type.is_Union() ) { if( v.m_values.size() != 1 ) ERROR(v.span(), E0000, "Union constructors can only specify a single field"); @@ -528,7 +528,7 @@ struct LowerHIR_ExprNode_Visitor: values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), - ! v.m_path.binding().is_EnumVar(), + ! v.m_path.m_bindings.type.is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) ) ); @@ -559,22 +559,14 @@ struct LowerHIR_ExprNode_Visitor: } virtual void visit(::AST::ExprNode_NamedValue& v) override { TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, - if( !v.m_path.binding().is_Variable() ) { - BUG(v.span(), "Named value was a local, but wasn't bound - " << v.m_path); - } - auto slot = v.m_path.binding().as_Variable().slot; + ASSERT_BUG(v.span(), v.m_path.m_bindings.value.is_Variable(), "Named value was a local, but wasn't bound - " << v.m_path); + auto slot = v.m_path.m_bindings.value.as_Variable().slot; m_rv.reset( new ::HIR::ExprNode_Variable( v.span(), e.name, slot ) ); ) - else { - TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), - ( - auto p = LowerHIR_Path(v.span(), v.m_path); - if( p.m_data.is_Generic() ) { - BUG(v.span(), "Unknown binding for PathValue but path is generic - " << v.m_path); - } - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), mv$(p), ::HIR::ExprNode_PathValue::UNKNOWN ) ); - ), - (Struct, + else + { + TU_MATCH_HDRA( (v.m_path.m_bindings.value), {) + TU_ARMA(Struct, e) { ASSERT_BUG(v.span(), e.struct_ || e.hir, "PathValue bound to a struct but pointer not set - " << v.m_path); // Check the form and emit a PathValue if not a unit bool is_tuple_constructor = false; @@ -604,8 +596,8 @@ struct LowerHIR_ExprNode_Visitor: else { m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), true ) ); } - ), - (EnumVar, + } + TU_ARMA(EnumVar, e) { ASSERT_BUG(v.span(), e.enum_ || e.hir, "PathValue bound to an enum but pointer not set - " << v.m_path); const auto& var_name = v.m_path.nodes().back().name(); bool is_tuple_constructor = false; @@ -646,11 +638,11 @@ struct LowerHIR_ExprNode_Visitor: else { m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), false ) ); } - ), - (Function, + } + TU_ARMA(Function, e) { m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::FUNCTION ) ); - ), - (Static, + } + TU_ARMA(Static, e) { if( e.static_ ) { if( e.static_->s_class() != ::AST::Static::CONST ) { @@ -669,8 +661,12 @@ struct LowerHIR_ExprNode_Visitor: { m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); } - ) - ) + } + break; default: + auto p = LowerHIR_Path(v.span(), v.m_path); + ASSERT_BUG(v.span(), !p.m_data.is_Generic(), "Unknown binding for PathValue but path is generic - " << v.m_path); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), mv$(p), ::HIR::ExprNode_PathValue::UNKNOWN ) ); + } } } diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 12e39fc8..d249de13 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -118,10 +118,14 @@ #define TU_MATCH_HDR(VARS, brace) TU_MATCH_HDR_(::std::remove_reference<decltype(TU_FIRST VARS)>::type, VARS, brace) #define TU_MATCH_HDR_(CLASS, VARS, brace) switch( (TU_FIRST VARS).tag() ) brace case CLASS::TAGDEAD: assert(!"ERROR: destructed tagged union used"); - // Evil hack: two for loops, the inner stops the outer after it's done. #define TU_ARM(VAR, TAG, NAME) break; case ::std::remove_reference<decltype(VAR)>::type::TAG_##TAG: for(bool tu_lc = true; tu_lc; tu_lc=false) for(auto& NAME = (VAR).as_##TAG(); (void)NAME, tu_lc; tu_lc=false) +#define TU_MATCH_HDRA(VARS, brace) TU_MATCH_HDRA_(::std::remove_reference<decltype(TU_FIRST VARS)>::type, VARS, brace) +#define TU_MATCH_HDRA_(CLASS, VARS, brace) const auto& tu_match_hdr2_v = (TU_FIRST VARS); switch( tu_match_hdr2_v.tag() ) brace case CLASS::TAGDEAD: assert(!"ERROR: destructed tagged union used"); +// Evil hack: two for loops, the inner stops the outer after it's done. +#define TU_ARMA(TAG, NAME) break; case ::std::remove_reference<decltype(tu_match_hdr2_v)>::type::TAG_##TAG: for(bool tu_lc = true; tu_lc; tu_lc=false) for(auto& NAME = tu_match_hdr2_v.as_##TAG(); (void)NAME, tu_lc; tu_lc=false) + //#define TU_TEST(VAL, ...) (VAL.is_##TAG() && VAL.as_##TAG() TEST) #define TU_TEST1(VAL, TAG1, TEST) (VAL.is_##TAG1() && VAL.as_##TAG1() TEST) #define TU_TEST2(VAL, TAG1, FLD1,TAG2, TEST) (VAL.is_##TAG1() && VAL.as_##TAG1() FLD1.is_##TAG2() && VAL.as_##TAG1() FLD1.as_##TAG2() TEST) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 19da5820..d0db3c13 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -313,6 +313,7 @@ namespace { auto v = mod.m_namespace_items.find(name); if( v != mod.m_namespace_items.end() ) { + DEBUG("- NS: Namespace " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -320,6 +321,7 @@ namespace { auto v = mod.m_type_items.find(name); if( v != mod.m_type_items.end() ) { + DEBUG("- NS: Type " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -327,15 +329,10 @@ namespace break; case LookupMode::Type: - //if( name == "IntoIterator" ) { - // DEBUG("lookup_in_mod(mod="<<mod.path()<<")"); - // for(const auto& v : mod.m_type_items) { - // DEBUG("- " << v.first << " = " << (v.second.is_pub ? "pub " : "") << v.second.path); - // } - //} { auto v = mod.m_type_items.find(name); if( v != mod.m_type_items.end() ) { + DEBUG("- TY: Type " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -345,14 +342,15 @@ namespace { auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { - const auto& b = v->second.path.binding(); + const auto& b = v->second.path.m_bindings.value; switch( b.tag() ) { - case ::AST::PathBinding::TAG_EnumVar: - case ::AST::PathBinding::TAG_Static: + case ::AST::PathBinding_Value::TAG_EnumVar: + case ::AST::PathBinding_Value::TAG_Static: + DEBUG("- PV: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; - case ::AST::PathBinding::TAG_Struct: + case ::AST::PathBinding_Value::TAG_Struct: // TODO: Restrict this to unit-like structs if( b.as_Struct().struct_ && !b.as_Struct().struct_->m_data.is_Unit() ) ; @@ -360,6 +358,7 @@ namespace ; else { + DEBUG("- PV: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -375,6 +374,7 @@ namespace { auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { + DEBUG("- C/V: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -592,7 +592,7 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L { // Trait is specified, definitely a trait item // - Must resolve here - const auto& pb = ufcs.trait->binding(); + const auto& pb = ufcs.trait->m_bindings.type; if( ! pb.is_Trait() ) { ERROR(sp, E0000, "UFCS trait was not a trait - " << *ufcs.trait); } @@ -662,7 +662,7 @@ namespace { { np.nodes().push_back( mv$(nodes[i]) ); } - np.bind( path.binding().clone() ); + np.m_bindings = path.m_bindings.clone(); return np; } AST::Path split_into_ufcs_ty(const Span& sp, AST::Path path, unsigned int i /*item_name_idx*/) @@ -716,7 +716,6 @@ namespace { const auto& varname = p.m_components.back(); auto var_idx = e.find_variant(varname); ASSERT_BUG(sp, var_idx != SIZE_MAX, "Extern crate import path points to non-present variant - " << p); - auto pb = ::AST::PathBinding::make_EnumVar({nullptr, static_cast<unsigned>(var_idx), &e}); // Construct output path (with same set of parameters) AST::Path rv( p.m_crate_name, {} ); @@ -724,7 +723,12 @@ namespace { for(const auto& c : p.m_components) rv.nodes().push_back( AST::PathNode(c) ); rv.nodes().back().args() = mv$( path.nodes().back().args() ); - rv.bind( mv$(pb) ); + if( e.m_data.is_Data() && e.m_data.as_Data()[var_idx].is_struct ) { + rv.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, static_cast<unsigned>(var_idx), &e}); + } + else { + rv.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, static_cast<unsigned>(var_idx), &e}); + } path = mv$(rv); return ; @@ -735,7 +739,7 @@ namespace { ) } - ::AST::PathBinding pb; + ::AST::Path::Bindings pb; const auto& name = p.m_components.back(); if( is_value ) @@ -749,19 +753,19 @@ namespace { BUG(sp, "HIR Import item pointed to an import"); ), (Constant, - pb = ::AST::PathBinding::make_Static({nullptr, nullptr}); + pb.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); ), (Static, - pb = ::AST::PathBinding::make_Static({nullptr, &e}); + pb.value = ::AST::PathBinding_Value::make_Static({nullptr, &e}); ), (StructConstant, - pb = ::AST::PathBinding::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); + pb.value = ::AST::PathBinding_Value::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); ), (Function, - pb = ::AST::PathBinding::make_Function({nullptr/*, &e*/}); + pb.value = ::AST::PathBinding_Value::make_Function({nullptr/*, &e*/}); ), (StructConstructor, - pb = ::AST::PathBinding::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); + pb.value = ::AST::PathBinding_Value::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); ) ) } @@ -776,22 +780,22 @@ namespace { BUG(sp, "HIR Import item pointed to an import"); ), (Module, - pb = ::AST::PathBinding::make_Module({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (Trait, - pb = ::AST::PathBinding::make_Trait({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (TypeAlias, - pb = ::AST::PathBinding::make_TypeAlias({nullptr/*, &e*/}); + pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), (Struct, - pb = ::AST::PathBinding::make_Struct({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - pb = ::AST::PathBinding::make_Union({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ), (Enum, - pb = ::AST::PathBinding::make_Enum({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ) ) } @@ -802,7 +806,7 @@ namespace { for(const auto& c : p.m_components) rv.nodes().push_back( AST::PathNode(c) ); rv.nodes().back().args() = mv$( path.nodes().back().args() ); - rv.bind( mv$(pb) ); + rv.m_bindings = mv$(pb); path = mv$(rv); } @@ -816,7 +820,7 @@ namespace { switch(mode) { case Context::LookupMode::Namespace: - path.bind( ::AST::PathBinding::make_Module({nullptr, &crate.m_hir->m_root_module}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &crate.m_hir->m_root_module}); return ; default: TODO(sp, "Looking up a non-namespace, but pointed to crate root"); @@ -862,7 +866,7 @@ namespace { trait_path.nodes().back().args().m_types.push_back( ::TypeRef(sp) ); } } - trait_path.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + trait_path.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ::AST::Path new_path; const auto& next_node = path_abs.nodes[i+1]; @@ -922,7 +926,12 @@ namespace { ERROR(sp, E0000, "Type parameters were not expected here (enum params go on the variant)"); } - path.bind( ::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 ) { + path.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, static_cast<unsigned int>(idx), &e}); + } + else { + path.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, static_cast<unsigned int>(idx), &e}); + } path = split_into_crate(sp, mv$(path), start, crate.m_name); return; } @@ -949,22 +958,22 @@ namespace { return ; ), (Trait, - path.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (Module, - path.bind( ::AST::PathBinding::make_Module({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (TypeAlias, - path.bind( ::AST::PathBinding::make_TypeAlias({nullptr/*, &e*/}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), (Enum, - path.bind( ::AST::PathBinding::make_Enum({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ), (Struct, - path.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - path.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ) ) // Update path (trim down to `start` and set crate name) @@ -984,7 +993,7 @@ namespace { ), (StructConstant, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); path = split_into_crate(sp, mv$(path), start, crate.m_name); return ; ), @@ -994,7 +1003,7 @@ namespace { ), (Constant, // Bind and update path - path.bind( ::AST::PathBinding::make_Static({nullptr, nullptr}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); path = split_into_crate(sp, mv$(path), start, crate.m_name); return ; ) @@ -1016,22 +1025,22 @@ namespace { return ; ), (Function, - path.bind( ::AST::PathBinding::make_Function({nullptr/*, &e*/}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Function({nullptr/*, &e*/}); ), (StructConstructor, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); ), (StructConstant, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); ), (Static, - path.bind( ::AST::PathBinding::make_Static({nullptr, &e}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, &e}); ), (Constant, // Bind - path.bind( ::AST::PathBinding::make_Static({nullptr, nullptr}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); ) ) path = split_into_crate(sp, mv$(path), start, crate.m_name); @@ -1088,7 +1097,7 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex const auto& name_ref = it->second; DEBUG("#" << i << " \"" << n.name() << "\" = " << name_ref.path << (name_ref.is_import ? " (import)" : "") ); - TU_MATCH_DEF(::AST::PathBinding, (name_ref.path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding_Type, (name_ref.path.m_bindings.type), (e), ( ERROR(sp, E0000, "Encountered non-namespace item '" << n.name() << "' ("<<name_ref.path<<") in path " << path); ), @@ -1235,7 +1244,7 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex if( ! Context::lookup_in_mod(*mod, path_abs.nodes.back().name(), mode, tmp) ) { ERROR(sp, E0000, "Couldn't find " << Context::lookup_mode_msg(mode) << " '" << path_abs.nodes.back().name() << "' of " << path); } - assert( ! tmp.binding().is_Unbound() ); + ASSERT_BUG(sp, tmp.m_bindings.has_binding(), "Lookup for " << path << " succeeded, but had no binding"); // Replaces the path with the one returned by `lookup_in_mod`, ensuring that `use` aliases are eliminated DEBUG("Replace " << path << " with " << tmp); @@ -1283,7 +1292,8 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: // - If the next component isn't found in the located module // > Instead use the type name. if( ! p.m_class.is_Local() && coretype_fromstring(e.nodes[0].name()) != CORETYPE_INVAL ) { - TU_IFLET( ::AST::PathBinding, p.binding(), Module, pe, + if( const auto* pep = p.m_bindings.type.opt_Module() ) { + const auto& pe = *pep; bool found = false; const auto& name = e.nodes[1].name(); if( !pe.module_ ) { @@ -1340,7 +1350,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: } DEBUG("Primitive module hack yeilded " << p); - ) + } } if( e.nodes.size() > 1 ) @@ -1447,7 +1457,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: BUG(sp, "Path wasn't absolutised correctly"); ), (Local, - if( path.binding().is_Unbound() ) + if( !path.m_bindings.has_binding() ) { TODO(sp, "Bind unbound local path - " << path); } @@ -1565,7 +1575,7 @@ void Resolve_Absolute_Type(Context& context, TypeRef& type) assert( ufcs.nodes.size() == 1); ) - TU_IFLET(::AST::PathBinding, e.path.binding(), Trait, be, + TU_IFLET(::AST::PathBinding_Type, e.path.m_bindings.type, Trait, be, auto ty = ::TypeRef( type.span(), ::make_vec1(Type_TraitPath { {}, mv$(e.path)}), {} ); type = mv$(ty); return ; @@ -2157,7 +2167,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) item_context.pop(def.params()); - const_cast< ::AST::Trait*>(def.trait().ent.binding().as_Trait().trait_)->set_is_marker(); + const_cast< ::AST::Trait*>(def.trait().ent.m_bindings.type.as_Trait().trait_)->set_is_marker(); } else { diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 659bded4..148bf069 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -125,46 +125,47 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) ), // - Types/modules only (Module, - p.bind( ::AST::PathBinding::make_Module({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Module({&e}); _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Crate, ASSERT_BUG(i.data.span, crate.m_extern_crates.count(e.name) > 0, "Referenced crate '" << e.name << "' isn't loaded for `extern crate`"); - p.bind( ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) }) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Crate({ &crate.m_extern_crates.at(e.name) }); _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Enum, - p.bind( ::AST::PathBinding::make_Enum({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Union, - p.bind( ::AST::PathBinding::make_Union({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Union({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Trait, - p.bind( ::AST::PathBinding::make_Trait({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Trait({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Type, - p.bind( ::AST::PathBinding::make_TypeAlias({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), // - Mixed (Struct, - p.bind( ::AST::PathBinding::make_Struct({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Struct({&e}); // - If the struct is a tuple-like struct (or unit-like), it presents in the value namespace if( ! e.m_data.is_Struct() ) { + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, p); } _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), // - Values only (Function, - p.bind( ::AST::PathBinding::make_Function({&e}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Function({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Static, - p.bind( ::AST::PathBinding::make_Static({&e}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); ) ) @@ -182,73 +183,48 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) // TODO: Ensure that the path is canonical? const auto& sp = i_data.sp; - struct H { - 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, - ), - (Variable, - BUG(sp, "Import was bound to variable"); - ), - (TypeParameter, - BUG(sp, "Import was bound to type parameter"); - ), - (TraitMethod, - BUG(sp, "Import was bound to trait method"); - ), - (StructMethod, - 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); ), - (Union, _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); - // - If the struct is a tuple-like struct, it presents in the value namespace - assert(e.struct_ || e.hir); - if( !(e.struct_ ? e.struct_->m_data.is_Struct() : e.hir->m_data.is_Named()) ) - { - _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 , - bool is_struct = false; - if( e.enum_ ) { - ASSERT_BUG(sp, e.idx < e.enum_->variants().size(), "Variant out of range for " << i_data.path); - is_struct = e.enum_->variants().at(e.idx).m_data.is_Struct(); - } - else { - //ASSERT_BUG(sp, e.idx < e.hir->m_variants.size(), "Variant out of range for " << i_data.path); - is_struct = TU_TEST1(e.hir->m_data, Data, .at(e.idx).is_struct); - } - if( is_struct ) - _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - else - _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - ) - ) + ASSERT_BUG(sp, i_data.path.m_bindings.has_binding(), "`use " << i_data.path << "` left unbound in module " << mod.path()); + + bool allow_collide = false; + // - Types + {TU_MATCH_HDRA( (i_data.path.m_bindings.type), {) + TU_ARMA(Unbound, _e) { + DEBUG(i.name << " - Not a type/module"); } - }; - if( i_data.path.binding().is_Unbound() ) { - BUG(sp, "`use " << i_data.path << "` left unbound in module " << mod.path()); - } - else { - H::handle_pb(sp, mod, i, i_data.path.binding(), false); - } - if( i_data.alt_binding.is_Unbound() ) { - // Doesn't matter - } - else { - H::handle_pb(sp, mod, i, i_data.alt_binding, true); + TU_ARMA(TypeParameter, e) + BUG(sp, "Import was bound to type parameter"); + TU_ARMA(Crate , e) + _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Module, e) + _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Enum, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Union, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Trait, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(TypeAlias, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Struct, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(EnumVar, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + }} + // - Values + TU_MATCH_HDRA( (i_data.path.m_bindings.value), {) + TU_ARMA(Unbound, _e) { + DEBUG(i.name << " - Not a value"); + } + TU_ARMA(Variable, e) + BUG(sp, "Import was bound to a variable"); + TU_ARMA(Struct, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(EnumVar, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Static , e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Function, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); } } else @@ -298,22 +274,22 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C //throw ""; ), (Module, - p.bind( ::AST::PathBinding::make_Module({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (Trait, - p.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (Struct, - p.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - p.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ), (Enum, - p.bind( ::AST::PathBinding::make_Enum({nullptr}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr}); ), (TypeAlias, - p.bind( ::AST::PathBinding::make_TypeAlias({nullptr}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ) ) _add_item_type( sp, dst_mod, it.first, is_pub, mv$(p), false ); @@ -333,8 +309,8 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C for(unsigned int i = 0; i < spath.m_components.size()-1; i ++) { const auto& it = hmod->m_mod_items.at( spath.m_components[i] ); if(it->ent.is_Enum()) { - ASSERT_BUG(sp, i + 1 == spath.m_components.size() - 1, ""); - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, 0}) ); + ASSERT_BUG(sp, i + 1 == spath.m_components.size() - 1, "Found enum not at penultimate component of HIR import path"); + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, 0}); // TODO: What's the index? vep = nullptr; hmod = nullptr; break ; @@ -355,20 +331,20 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C throw ""; ), (Constant, - p.bind( ::AST::PathBinding::make_Static({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr}); ), (Static, - p.bind( ::AST::PathBinding::make_Static({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr}); ), // TODO: What if these refer to an enum variant? (StructConstant, - p.bind( ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }); ), (StructConstructor, - p.bind( ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }); ), (Function, - p.bind( ::AST::PathBinding::make_Function({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Function({nullptr}); ) ) } @@ -418,14 +394,14 @@ void Resolve_Index_Module_Wildcard__submod(AST::Crate& crate, AST::Module& dst_m void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst_mod, const AST::UseStmt& i_data, bool is_pub) { const auto& sp = i_data.sp; - const auto& b = i_data.path.binding(); + const auto& b = i_data.path.m_bindings.type; - TU_IFLET(::AST::PathBinding, b, Crate, e, + TU_IFLET(::AST::PathBinding_Type, b, Crate, e, DEBUG("Glob crate " << i_data.path); const auto& hmod = e.crate_->m_hir->m_root_module; Resolve_Index_Module_Wildcard__glob_in_hir_mod(sp, crate, dst_mod, hmod, i_data.path, is_pub); ) - else TU_IFLET(::AST::PathBinding, b, Module, e, + else TU_IFLET(::AST::PathBinding_Type, b, Module, e, DEBUG("Glob mod " << i_data.path); if( !e.module_ ) { @@ -438,7 +414,7 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst Resolve_Index_Module_Wildcard__submod(crate, dst_mod, *e.module_, is_pub); } ) - else TU_IFLET(::AST::PathBinding, b, Enum, e, + else TU_IFLET(::AST::PathBinding_Type, b, Enum, e, ASSERT_BUG(sp, e.enum_ || e.hir, "Glob import but enum pointer not set - " << i_data.path); if( e.enum_ ) { @@ -446,11 +422,12 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst unsigned int idx = 0; for( const auto& ev : e.enum_->variants() ) { ::AST::Path p = i_data.path + ev.m_name; - p.bind( ::AST::PathBinding::make_EnumVar({e.enum_, idx}) ); if( ev.m_data.is_Struct() ) { + p.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({e.enum_, idx}); _add_item_type ( sp, dst_mod, ev.m_name, is_pub, mv$(p), false ); } else { + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({e.enum_, idx}); _add_item_value( sp, dst_mod, ev.m_name, is_pub, mv$(p), false ); } @@ -467,7 +444,7 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst for(const auto& ev : de->variants) { ::AST::Path p = i_data.path + ev.name; - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, idx, e.hir}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, idx, e.hir}); _add_item_value( sp, dst_mod, ev.name, is_pub, mv$(p), false ); @@ -480,12 +457,13 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst for(const auto& ev : *de) { ::AST::Path p = i_data.path + ev.name; - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, idx, e.hir}) ); if( ev.is_struct ) { + p.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, idx, e.hir}); _add_item_type ( sp, dst_mod, ev.name, is_pub, mv$(p), false ); } else { + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, idx, e.hir}); _add_item_value( sp, dst_mod, ev.name, is_pub, mv$(p), false ); } @@ -598,9 +576,9 @@ void Resolve_Index_Module_Normalise_Path_ext(const ::AST::Crate& crate, const Sp { TU_IFLET( ::HIR::TypeItem, it_m->second->ent, Import, e, // Replace the path with this path (maintaining binding) - auto binding = path.binding().clone(); + auto bindings = path.m_bindings.clone(); path = hir_to_ast(e.path); - path.bind( mv$(binding) ); + path.m_bindings = mv$(bindings); ) return ; } @@ -611,9 +589,9 @@ void Resolve_Index_Module_Normalise_Path_ext(const ::AST::Crate& crate, const Sp { TU_IFLET( ::HIR::ValueItem, it_v->second->ent, Import, e, // Replace the path with this path (maintaining binding) - auto binding = path.binding().clone(); + auto bindings = path.m_bindings.clone(); path = hir_to_ast(e.path); - path.bind( mv$(binding) ); + path.m_bindings = mv$(bindings); ) return ; } @@ -648,27 +626,26 @@ bool Resolve_Index_Module_Normalise_Path(const ::AST::Crate& crate, const Span& auto new_path = ie.path; for(unsigned int j = i+1; j < info.nodes.size(); j ++) new_path.nodes().push_back( mv$(info.nodes[j]) ); - new_path.bind( path.binding().clone() ); + new_path.m_bindings = path.m_bindings.clone(); path = mv$(new_path); return Resolve_Index_Module_Normalise_Path(crate, sp, path, loc); } else { - TU_MATCH_DEF(::AST::PathBinding, (ie.path.binding()), (e), - ( + TU_MATCH_HDR( (ie.path.m_bindings.type), {) + default: BUG(sp, "Path " << path << " pointed to non-module " << ie.path); - ), - (Module, + TU_ARM( ie.path.m_bindings.type, Module, e) { mod = e.module_; - ), - (Crate, + } + TU_ARM( ie.path.m_bindings.type, Crate, e) { Resolve_Index_Module_Normalise_Path_ext(crate, sp, path, loc, *e.crate_, i+1); return false; - ), - (Enum, + } + TU_ARM( ie.path.m_bindings.type, Enum, e) { // NOTE: Just assuming that if an Enum is hit, it's sane return false; - ) - ) + } + } } } 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 ""; +//} |