diff options
author | John Hodge <tpg@mutabah.net> | 2016-10-27 07:58:30 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-10-27 07:58:30 +0800 |
commit | 6dd68cfffb31aa464742e666d6b936182dea9d4f (patch) | |
tree | 8c3a49d6638f3e8058e983045d8d4b06bfc87c29 /src | |
parent | cfb898ae8505c05e59a0a21295b31ae64f94b0be (diff) | |
download | mrust-6dd68cfffb31aa464742e666d6b936182dea9d4f.tar.gz |
HIR - Support type aliases in struct patterns
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/from_ast.cpp | 11 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 3 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 143 |
3 files changed, 126 insertions, 31 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 7a2417d8..7731f04c 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -321,6 +321,17 @@ }) }; ), + (TypeAlias, + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Struct({ + LowerHIR_GenericPath(pat.span(), e.path), + nullptr, + mv$(sub_patterns), + e.is_exhaustive + }) + }; + ), (Struct, return ::HIR::Pattern { mv$(binding), diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 93f63abd..b15b08e0 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -351,6 +351,9 @@ namespace { ( ERROR(sp, E0000, "Unexpected item type returned for " << pe.m_path << " - " << item.tag_str()); ), + (TypeAlias, + BUG(sp, "TypeAlias encountered after `Resolve Type Aliases` - " << ty); + ), (Struct, fix_param_count(sp, pe, e3.m_params, pe.m_params); e.binding = ::HIR::TypeRef::TypePathBinding::make_Struct(&e3); diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index ff00743d..c176aa71 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -7,42 +7,48 @@ #include <hir/visitor.hpp> #include <hir_typeck/common.hpp> // monomorphise_type_with +::HIR::TypeRef ConvertHIR_ExpandAliases_GetExpansion_GP(const Span& sp, const ::HIR::Crate& crate, const ::HIR::GenericPath& path) +{ + const auto& ti = crate.get_typeitem_by_path(sp, path.m_path); + TU_MATCH_DEF( ::HIR::TypeItem, (ti), (e2), + ( + // Anything else - leave it be + ), + (TypeAlias, + if( path.m_params.m_types.size() != e2.m_params.m_types.size() ) { + ERROR(sp, E0000, "Mismatched parameter count in " << path); + } + if( e2.m_params.m_types.size() > 0 ) { + // TODO: Better `monomorphise_type` + return monomorphise_type_with(sp, e2.m_type, [&](const auto& gt)->const auto& { + const auto& ge = gt.m_data.as_Generic(); + if( ge.binding == 0xFFFF ) { + BUG(sp, "Self encountered in expansion for " << path << " - " << e2.m_type); + } + else if( (ge.binding >> 8) == 0 ) { + auto idx = ge.binding & 0xFF; + ASSERT_BUG(sp, idx < path.m_params.m_types.size(), ""); + return path.m_params.m_types[idx]; + } + else { + BUG(sp, "Bad index " << ge.binding << " encountered in expansion for " << path << " - " << e2.m_type); + } + }); + } + else { + return e2.m_type.clone(); + } + ) + ) + return ::HIR::TypeRef(); +} + ::HIR::TypeRef ConvertHIR_ExpandAliases_GetExpansion(const ::HIR::Crate& crate, const ::HIR::Path& path) { static Span sp; TU_MATCH(::HIR::Path::Data, (path.m_data), (e), (Generic, - const auto& ti = crate.get_typeitem_by_path(sp, e.m_path); - TU_MATCH_DEF( ::HIR::TypeItem, (ti), (e2), - ( - // Anything else - leave it be - ), - (TypeAlias, - if( e.m_params.m_types.size() != e2.m_params.m_types.size() ) { - ERROR(sp, E0000, "Mismatched parameter count in " << path); - } - if( e2.m_params.m_types.size() > 0 ) { - // TODO: Better `monomorphise_type` - return monomorphise_type_with(sp, e2.m_type, [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - BUG(sp, "Self encountered in expansion for " << path << " - " << e2.m_type); - } - else if( (ge.binding >> 8) == 0 ) { - auto idx = ge.binding & 0xFF; - ASSERT_BUG(sp, idx < e.m_params.m_types.size(), ""); - return e.m_params.m_types[idx]; - } - else { - BUG(sp, "Bad index " << ge.binding << " encountered in expansion for " << path << " - " << e2.m_type); - } - }); - } - else { - return e2.m_type.clone(); - } - ) - ) + return ConvertHIR_ExpandAliases_GetExpansion_GP(sp, crate, e); ), (UfcsInherent, DEBUG("TODO: Locate impl blocks for types - path=" << path); @@ -79,6 +85,7 @@ public: while(num_exp < MAX_RECURSIVE_TYPE_EXPANSIONS) { TU_IFLET(::HIR::TypeRef::Data, (new_type.m_data), Path, (e), + ::HIR::Visitor::visit_type(new_type); auto nt = ConvertHIR_ExpandAliases_GetExpansion(m_crate, e.path); if( nt == ::HIR::TypeRef() ) break; @@ -97,6 +104,69 @@ public: ) } + + ::HIR::GenericPath expand_alias_pattern(const Span& sp, const ::HIR::GenericPath& path) + { + const unsigned int MAX_RECURSIVE_TYPE_EXPANSIONS = 100; + + ::HIR::GenericPath rv; + const auto* cur = &path; + + unsigned int num_exp = 0; + do { + auto ty = ConvertHIR_ExpandAliases_GetExpansion_GP(sp, m_crate, *cur); + if( ty == ::HIR::TypeRef() ) + break ; + if( !ty.m_data.is_Path() ) + ERROR(sp, E0000, "Type alias referenced in pattern doesn't point to a path"); + auto& ty_p = ty.m_data.as_Path().path; + if( !ty_p.m_data.is_Generic() ) + ERROR(sp, E0000, "Type alias referenced in pattern doesn't point to a generic path"); + rv = mv$( ty_p.m_data.as_Generic() ); + + this->visit_generic_path(rv, ::HIR::Visitor::PathContext::TYPE); + + cur = &rv; + } while( ++num_exp < MAX_RECURSIVE_TYPE_EXPANSIONS ); + ASSERT_BUG(sp, num_exp < MAX_RECURSIVE_TYPE_EXPANSIONS, "Recursion limit expanding " << path << " (currently on " << *cur << ")"); + return rv; + } + + void visit_pattern(::HIR::Pattern& pat) override + { + static Span sp; + ::HIR::Visitor::visit_pattern(pat); + + TU_MATCH_DEF( ::HIR::Pattern::Data, (pat.m_data), (e), + ( + ), + (StructValue, + auto new_path = expand_alias_pattern(sp, e.path); + if( new_path.m_path.m_components.size() != 0 ) + { + DEBUG("Replacing " << e.path << " with " << new_path); + e.path = mv$(new_path); + } + ), + (StructTuple, + auto new_path = expand_alias_pattern(sp, e.path); + if( new_path.m_path.m_components.size() != 0 ) + { + DEBUG("Replacing " << e.path << " with " << new_path); + e.path = mv$(new_path); + } + ), + (Struct, + auto new_path = expand_alias_pattern(sp, e.path); + if( new_path.m_path.m_components.size() != 0 ) + { + DEBUG("Replacing " << e.path << " with " << new_path); + e.path = mv$(new_path); + } + ) + ) + } + void visit_expr(::HIR::ExprPtr& expr) override { struct Visitor: @@ -111,6 +181,7 @@ public: void visit(::HIR::ExprNode_Let& node) override { upper_visitor.visit_type(node.m_type); + upper_visitor.visit_pattern(node.m_pattern); ::HIR::ExprVisitorDef::visit(node); } void visit(::HIR::ExprNode_Cast& node) override @@ -139,6 +210,16 @@ public: } ::HIR::ExprVisitorDef::visit(node); } + + void visit(::HIR::ExprNode_Match& node) override + { + for(auto& arm : node.m_arms) { + for(auto& pat : arm.m_patterns) { + upper_visitor.visit_pattern(pat); + } + } + ::HIR::ExprVisitorDef::visit(node); + } }; if( expr.get() != nullptr ) |