diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-10 15:49:20 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-10 15:49:20 +0800 |
commit | 9744f22c07c28d1577de9ee7034e337c1cfc46de (patch) | |
tree | 31718bf84fb46ee2398b9493872089171ce02d74 /src | |
parent | 8f3fa5853e80590f666e4852f4f373c7b7826d3b (diff) | |
download | mrust-9744f22c07c28d1577de9ee7034e337c1cfc46de.tar.gz |
HIR - Add EnumValue variant to Pattern
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/pattern.cpp | 12 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 5 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 3 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 72 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 29 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 6 |
8 files changed, 132 insertions, 3 deletions
diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp index 8a95fa53..386d1699 100644 --- a/src/hir/pattern.cpp +++ b/src/hir/pattern.cpp @@ -76,6 +76,9 @@ namespace HIR { os << e.start << " ... " << e.end; ), + (EnumValue, + os << e.path; + ), (EnumTuple, os << e.path; os << "("; @@ -84,7 +87,7 @@ namespace HIR { os << ")"; ), (EnumTupleWildcard, - os << e.path; + os << e.path << "(..)"; ), (EnumStruct, os << e.path; @@ -204,14 +207,17 @@ namespace { })); ), + (EnumValue, + return Pattern(m_binding, Data::make_EnumValue({ e.path.clone(), e.binding_ptr, e.binding_idx })); + ), (EnumTuple, return Pattern(m_binding, Data::make_EnumTupleWildcard({ - e.path.clone() + e.path.clone(), e.binding_ptr, e.binding_idx })); ), (EnumTupleWildcard, return Pattern(m_binding, Data::make_EnumTupleWildcard({ - e.path.clone() + e.path.clone(), e.binding_ptr, e.binding_idx })); ), (EnumStruct, diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index 72cb061d..b02721b2 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -79,6 +79,11 @@ struct Pattern // Refutable (Value, struct { Value val; } ), (Range, struct { Value start; Value end; } ), + (EnumValue, struct { + GenericPath path; + const Enum* binding_ptr; + unsigned binding_idx; + } ), (EnumTuple, struct { GenericPath path; const Enum* binding_ptr; diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index cb942123..9767996e 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -351,6 +351,9 @@ void ::HIR::Visitor::visit_pattern(::HIR::Pattern& pat) this->visit_pattern_val(e.start); this->visit_pattern_val(e.end); ), + (EnumValue, + this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE); + ), (EnumTupleWildcard, this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE); ), diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index bb2273aa..a78d0d5a 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -141,6 +141,78 @@ namespace { TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (e), ( ), + (Value, + TU_IFLET( ::HIR::Pattern::Value, e.val, Named, ve, + TU_IFLET( ::HIR::Path::Data, ve.m_data, Generic, pe, + const ::HIR::Enum* enm = nullptr; + const ::HIR::Module* mod = &m_crate.m_root_module; + const auto& path = pe.m_path; + for(unsigned int i = 0; i < path.m_components.size() - 1; i ++ ) + { + const auto& pc = path.m_components[i]; + auto it = mod->m_mod_items.find( pc ); + if( it == mod->m_mod_items.end() ) { + BUG(sp, "Couldn't find component " << i << " of " << path); + } + + if( i == path.m_components.size() - 2 ) { + // Here it's allowed to be either a module, or an enum. + TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2, + mod = &e2; + ) + else TU_IFLET( ::HIR::TypeItem, it->second->ent, Enum, e2, + enm = &e2; + ) + else { + BUG(sp, "Node " << i << " of path " << ve << " wasn't a module or enum"); + } + } + else { + TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2, + mod = &e2; + ) + else { + BUG(sp, "Node " << i << " of path " << ve << " wasn't a module"); + } + } + } + const auto& pc = path.m_components.back(); + if( enm ) { + // Enum variant + auto it = ::std::find_if( enm->m_variants.begin(), enm->m_variants.end(), [&](const auto&v){ return v.first == pc; }); + if( it == enm->m_variants.end() ) { + BUG(sp, "'" << pc << "' isn't a variant in path " << path); + } + unsigned int index = it - enm->m_variants.begin(); + auto path = mv$(pe); + fix_type_params(sp, enm->m_params, path.m_params); + //::std::cout << "HHHH: path=" << path << ::std::endl; + pat.m_data = ::HIR::Pattern::Data::make_EnumValue({ + mv$(path), + enm, + index + }); + } + else { + auto it = mod->m_value_items.find( pc ); + if( it == mod->m_value_items.end() ) { + BUG(sp, "Couldn't find final component of " << path); + } + // Unit-like struct match or a constant + // TODO: Store binding + TU_MATCH_DEF( ::HIR::ValueItem, (it->second->ent), (e2), + ( + ), + (StructConstant, + ) + ) + } + ) + else { + // UFCS/Opaque, leave for now. + } + ) + ), (StructTuple, const auto& str = get_struct_ptr(sp, m_crate, e.path); TU_IFLET(::HIR::Struct::Data, str.m_data, Tuple, _, diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 8df61ccc..288ea035 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -668,6 +668,8 @@ namespace { add_closure_def_from_pattern(sp, field_pat.second); } ), + (EnumValue, + ), (EnumTuple, for(const auto& field : e.sub_patterns) { add_closure_def_from_pattern(sp, field); diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp index 05faf069..61e0ac68 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -289,6 +289,10 @@ void typeck::TypecheckContext::add_binding(const Span& sp, ::HIR::Pattern& pat, ) ) ), + (EnumValue, + this->add_ivars_params( e.path.m_params ); + TODO(sp, "EnumValue"); + ), (EnumTuple, this->add_ivars_params( e.path.m_params ); if( type.m_data.is_Infer() ) { @@ -540,6 +544,8 @@ void typeck::TypecheckContext::apply_pattern(const ::HIR::Pattern& pat, ::HIR::T ) ) ), + (EnumValue, + ), (EnumTuple, if( ty.m_data.is_Infer() ) { TODO(sp, "EnumTuple - infer"); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index dbc948b5..4e704f5f 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2696,6 +2696,35 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type ) ) ), + (EnumValue, + this->add_ivars_params( e.path.m_params ); + if( type.m_data.is_Infer() ) { + auto path = e.path.clone(); + path.m_path.m_components.pop_back(); + //::std::cout << "HHHH ExprCS: path=" << path << ", pat=" << pat << ::std::endl; + + this->equate_types( sp, type, ::HIR::TypeRef::new_path(mv$(path), ::HIR::TypeRef::TypePathBinding(e.binding_ptr)) ); + } + const auto& ty = this->get_type(type); + const auto& type = ty; + + assert(e.binding_ptr); + const auto& enm = *e.binding_ptr; + const auto& var = enm.m_variants[e.binding_idx].second; + assert(var.is_Value() || var.is_Unit()); + + TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), + ( + ERROR(sp, E0000, "Type mismatch in enum pattern - " << type << " is not " << e.path); + ), + (Infer, throw ""; ), + (Path, + if( ! te.binding.is_Enum() || te.binding.as_Enum() != &enm ) { + ERROR(sp, E0000, "Type mismatch in enum pattern - " << type << " is not " << e.path); + } + ) + ) + ), (EnumTupleWildcard, this->add_ivars_params( e.path.m_params ); if( type.m_data.is_Infer() ) { diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 91a02c0c..e392815e 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -34,6 +34,7 @@ #define _DISP12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) _DISP4(n, a1,a2,a3,a4) _DISP4(n, b1,b2,b3,b4) _DISP4(n, c1,c2,c3,c4) #define _DISP13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP4(n, b1,b2,b3,b4) _DISP4(n, c1,c2,c3,c4) #define _DISP14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP4(n, c1,c2,c3,c4) +#define _DISP15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5) #define _DISPO0(n) #define _DISPO1(n, _1) n(_1) @@ -50,6 +51,7 @@ #define _DISPO12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) _DISPO4(n, a1,a2,a3,a4) _DISPO4(n, b1,b2,b3,b4) _DISPO4(n, c1,c2,c3,c4) #define _DISPO13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO4(n, b1,b2,b3,b4) _DISPO4(n, c1,c2,c3,c4) #define _DISPO14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO4(n, c1,c2,c3,c4) +#define _DISPO15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5) #define TU_DISPA(n, a) n a #define TU_DISPA1(n, a, _1) TU_DISPA(n, (TU_EXP a, TU_EXP _1)) @@ -70,6 +72,8 @@ #define TU_DISPA12(n, a, a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3) TU_DISPA3(n,a, a1,a2,a3) TU_DISPA3(n,a, b1,b2,b3) TU_DISPA3(n,a, c1,c2,c3) TU_DISPA3(n,a, d1,d2,d3) #define TU_DISPA13(n, a, a1,a2,a3,a4, b1,b2,b3, c1,c2,c3, d1,d2,d3) TU_DISPA4(n,a, a1,a2,a3,a4) TU_DISPA3(n,a, b1,b2,b3) TU_DISPA3(n,a, c1,c2,c3) TU_DISPA3(n,a, d1,d2,d3) #define TU_DISPA14(n, a, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3, d1,d2,d3) TU_DISPA4(n,a, a1,a2,a3,a4) TU_DISPA4(n,a, b1,b2,b3,b4) TU_DISPA3(n,a, c1,c2,c3) TU_DISPA3(n,a, d1,d2,d3) +#define TU_DISPA15(n, a, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4, d1,d2,d3) TU_DISPA4(n,a, a1,a2,a3,a4) TU_DISPA4(n,a, b1,b2,b3,b4) TU_DISPA4(n,a, c1,c2,c3,c4) TU_DISPA3(n,a, d1,d2,d3) +#define TU_DISPA16(n, a, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4, d1,d2,d3,d4) TU_DISPA4(n,a, a1,a2,a3,a4) TU_DISPA4(n,a, b1,b2,b3,b4) TU_DISPA4(n,a, c1,c2,c3,c4) TU_DISPA4(n,a, d1,d2,d3,d4) // Macro to obtain a numbered macro for argument counts // - Raw variant @@ -95,6 +99,8 @@ #define MAXS12(a, b, c, d, e, f, g, h, i, j, k, l) MAX2(MAXS6(a, b, c, d, e, f), MAXS6(g, h, i, j, k, l)) #define MAXS13(a1,a2,a3,a4,a5,a6,a7, b1,b2,b3,b4,b5,b6) MAX2(MAXS7(a1,a2,a3,a4,a5,a6,a7), MAXS6(b1,b2,b3,b4,b5,b6)) #define MAXS14(a1,a2,a3,a4,a5,a6,a7, b1,b2,b3,b4,b5,b6,b7) MAX2(MAXS7(a1,a2,a3,a4,a5,a6,a7), MAXS7(b1,b2,b3,b4,b5,b6,b7)) +#define MAXS15(a1,a2,a3,a4,a5,a6,a7,a8, b1,b2,b3,b4,b5,b6,b7) MAX2(MAXS8(a1,a2,a3,a4,a5,a6,a7,a8), MAXS7(b1,b2,b3,b4,b5,b6,b7)) +#define MAXS16(a1,a2,a3,a4,a5,a6,a7,a8, b1,b2,b3,b4,b5,b6,b7,b8) MAX2(MAXS8(a1,a2,a3,a4,a5,a6,a7,a8), MAXS8(b1,b2,b3,b4,b5,b6,b7,b8)) // TODO: use `decltype` in place of the `class` argument to TU_MATCH/TU_IFLET // "match"-like statement |