diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-01-05 21:29:24 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-01-05 21:29:24 +0800 |
commit | 20ae8946a614f93cd8b1d1f9315a4478de2c867f (patch) | |
tree | 9a0f4f88408e770b8aeb2d43a89eda033b1ed61a /src | |
parent | fa3bf839ff871f862697ee1d992f0e6175c2a25b (diff) | |
download | mrust-20ae8946a614f93cd8b1d1f9315a4478de2c867f.tar.gz |
Resolve Use - Handle external enums
Diffstat (limited to 'src')
-rw-r--r-- | src/resolve/use.cpp | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 5fe7ee5c..52a4ebb6 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -217,6 +217,9 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path (None, // Deleted, ignore ), + (MacroInv, + // TODO: Should this already be deleted? + ), (Type, ), (Function, @@ -764,33 +767,57 @@ namespace { return Resolve_Use_GetBinding__ext(span, crate, path, *e.crate_, i+1); } TU_ARMA(Enum, e) { - const auto& enum_ = *e.enum_; + ASSERT_BUG(span, e.enum_ || e.hir, "nullptr enum pointer in node " << i << " of " << path); + ASSERT_BUG(span, e.enum_ == nullptr || e.hir == nullptr, "both AST and HIR pointers set in node " << i << " of " << path); i += 1; if( i != nodes.size() - 1 ) { ERROR(span, E0000, "Encountered enum at unexpected location in import"); } + ASSERT_BUG(span, i < nodes.size(), "Enum import position error, " << i << " >= " << nodes.size() << " - " << path); const auto& node2 = nodes[i]; - int variant_index = -1; + + unsigned variant_index = 0; bool is_value; - for( unsigned int j = 0; j < enum_.variants().size(); j ++ ) + if(e.hir) { - if( enum_.variants()[j].m_name == node2.name() ) { - variant_index = j; - is_value = !enum_.variants()[j].m_data.is_Struct(); - break ; + const auto& enum_ = *e.hir; + size_t idx = enum_.find_variant(node2.name()); + if( idx == ~0u ) { + ERROR(span, E0000, "Unknown enum variant " << path); } + TU_MATCH_HDRA( (enum_.m_data), {) + TU_ARMA(Value, ve) { + is_value = true; + } + TU_ARMA(Data, ve) { + is_value = !ve[idx].is_struct; + } + } + DEBUG("AST Enum variant - " << variant_index << ", is_value=" << is_value); } - if( variant_index < 0 ) { - ERROR(span, E0000, "Unknown enum variant '" << node2.name() << "'"); - } + else + { + const auto& enum_ = *e.enum_; + for( const auto& var : enum_.variants() ) + { + if( var.m_name == node2.name() ) { + is_value = !var.m_data.is_Struct(); + break ; + } + variant_index ++; + } + if( variant_index == enum_.variants().size() ) { + ERROR(span, E0000, "Unknown enum variant '" << node2.name() << "'"); + } - DEBUG("AST Enum variant - " << variant_index << ", is_value=" << is_value << " " << enum_.variants()[variant_index].m_data.tag_str()); + DEBUG("AST Enum variant - " << variant_index << ", is_value=" << is_value << " " << enum_.variants()[variant_index].m_data.tag_str()); + } if( is_value ) { - rv.value = ::AST::PathBinding_Value::make_EnumVar({&enum_, static_cast<unsigned int>(variant_index)}); + rv.value = ::AST::PathBinding_Value::make_EnumVar({e.enum_, variant_index, e.hir}); } else { - rv.type = ::AST::PathBinding_Type::make_EnumVar({&enum_, static_cast<unsigned int>(variant_index)}); + rv.type = ::AST::PathBinding_Type::make_EnumVar({e.enum_, variant_index, e.hir}); } return rv; } |