summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-27 07:58:30 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-27 07:58:30 +0800
commit6dd68cfffb31aa464742e666d6b936182dea9d4f (patch)
tree8c3a49d6638f3e8058e983045d8d4b06bfc87c29 /src
parentcfb898ae8505c05e59a0a21295b31ae64f94b0be (diff)
downloadmrust-6dd68cfffb31aa464742e666d6b936182dea9d4f.tar.gz
HIR - Support type aliases in struct patterns
Diffstat (limited to 'src')
-rw-r--r--src/hir/from_ast.cpp11
-rw-r--r--src/hir_conv/bind.cpp3
-rw-r--r--src/hir_conv/expand_type.cpp143
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 )