diff options
-rw-r--r-- | src/hir/from_ast.cpp | 2 | ||||
-rw-r--r-- | src/hir/pattern.cpp | 14 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 10 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 5 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 161 | ||||
-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 | 6 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 2 |
10 files changed, 134 insertions, 76 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index ebf2e2a6..3f492633 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -301,7 +301,7 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"}); return ::HIR::Pattern::Value::make_String(e); ), (Named, - return ::HIR::Pattern::Value::make_Named( LowerHIR_Path(sp, e) ); + return ::HIR::Pattern::Value::make_Named( {LowerHIR_Path(sp, e), nullptr} ); ) ) throw "BUGCHECK: Reached end of LowerHIR_Pattern::H::lowerhir_pattern_value"; diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp index 386d1699..f3ad277e 100644 --- a/src/hir/pattern.cpp +++ b/src/hir/pattern.cpp @@ -12,7 +12,7 @@ namespace HIR { os << "\"" << e << "\""; ), (Named, - os << e; + os << e.path; ) ) return os; @@ -51,6 +51,9 @@ namespace HIR { os << s << ", "; os << ")"; ), + (StructValue, + os << e.path; + ), (StructTuple, os << e.path; os << "("; @@ -59,7 +62,7 @@ namespace HIR { os << ")"; ), (StructTupleWildcard, - os << e.path; + os << e.path << "(..)"; ), (Struct, os << e.path; @@ -145,7 +148,7 @@ namespace { return ::HIR::Pattern::Value::make_String(e); ), (Named, - return ::HIR::Pattern::Value::make_Named(e.clone()); + return ::HIR::Pattern::Value::make_Named({ e.path.clone(), e.binding }); ) ) throw ""; @@ -173,6 +176,11 @@ namespace { clone_pat_vec(e.sub_patterns) })); ), + (StructValue, + return Pattern(m_binding, Data::make_StructValue({ + e.path.clone(), e.binding + })); + ), (StructTuple, return Pattern(m_binding, Data::make_StructTuple({ e.path.clone(), diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index b02721b2..2a5ebb2a 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -12,6 +12,7 @@ namespace HIR { class Struct; class Enum; +class Constant; struct PatternBinding { @@ -50,7 +51,10 @@ struct Pattern uint64_t value; // Signed numbers are encoded as 2's complement }), (String, ::std::string), - (Named, Path) + (Named, struct { + Path path; + const ::HIR::Constant* binding; + }) ); friend ::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& x); @@ -60,6 +64,10 @@ struct Pattern (Box, struct { ::std::unique_ptr<Pattern> sub; }), (Ref, struct { ::HIR::BorrowType type; ::std::unique_ptr<Pattern> sub; } ), (Tuple, struct { ::std::vector<Pattern> sub_patterns; } ), + (StructValue, struct { + GenericPath path; + const Struct* binding; + }), (StructTuple, struct { // NOTE: Type paths in patterns _can_ have parameters GenericPath path; diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 9767996e..daef834d 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -330,6 +330,9 @@ void ::HIR::Visitor::visit_pattern(::HIR::Pattern& pat) for(auto& sp : e.sub_patterns) this->visit_pattern(sp); ), + (StructValue, + this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE); + ), (StructTupleWildcard, this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE); ), @@ -387,7 +390,7 @@ void ::HIR::Visitor::visit_pattern_val(::HIR::Pattern::Value& val) (String, ), (Named, - this->visit_path(e, ::HIR::Visitor::PathContext::VALUE); + this->visit_path(e.path, ::HIR::Visitor::PathContext::VALUE); ) ) } diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 9457585c..8447daee 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -131,87 +131,108 @@ namespace { ::HIR::Visitor::visit_trait_path(p); } - void visit_pattern(::HIR::Pattern& pat) override + + void visit_pattern_Value(const Span& sp, ::HIR::Pattern& pat, ::HIR::Pattern::Value& val) { - static Span _sp = Span(); - const Span& sp = _sp; - - ::HIR::Visitor::visit_pattern(pat); + bool allow_enum = pat.m_data.is_Value(); - 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"); - } - } + TU_IFLET( ::HIR::Pattern::Value, val, Named, ve, + TU_IFLET( ::HIR::Path::Data, ve.path.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); } - 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); + + 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.path << " wasn't a module or enum"); } - 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, - ) + TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2, + mod = &e2; ) + else { + BUG(sp, "Node " << i << " of path " << ve.path << " wasn't a module"); + } } - ) + } + const auto& pc = path.m_components.back(); + if( enm ) { + if( !allow_enum ) { + ERROR(sp, E0000, "Enum variant in range pattern - " << pat); + } + + // 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 { - // UFCS/Opaque, leave for now. + 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 + TU_MATCH_DEF( ::HIR::ValueItem, (it->second->ent), (e2), + ( + ERROR(sp, E0000, "Value pattern pointing to unexpected type") + ), + (Constant, + // TODO: Store reference to this item for later use + ), + (StructConstant, + // TODO: Convert into a dedicated pattern type + ) + ) } ) + else { + // UFCS/Opaque, leave for now. + } + ) + } + + + void visit_pattern(::HIR::Pattern& pat) override + { + static Span _sp = Span(); + const Span& sp = _sp; + + ::HIR::Visitor::visit_pattern(pat); + + TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (e), + ( + ), + (Value, + this->visit_pattern_Value(sp, pat, e.val); + ), + (Range, + this->visit_pattern_Value(sp, pat, e.start); + this->visit_pattern_Value(sp, pat, e.end); ), (StructTuple, const auto& str = get_struct_ptr(sp, m_crate, e.path); diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index b76a61ca..3d207f5d 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -666,6 +666,8 @@ namespace { ), // - Enums/Structs + (StructValue, + ), (StructTuple, 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 61e0ac68..e1cb6c1f 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -182,6 +182,9 @@ void typeck::TypecheckContext::add_binding(const Span& sp, ::HIR::Pattern& pat, ), // - Enums/Structs + (StructValue, + throw "TODO"; + ), (StructTuple, this->add_ivars_params( e.path.m_params ); if( type.m_data.is_Infer() ) { @@ -509,6 +512,9 @@ void typeck::TypecheckContext::apply_pattern(const ::HIR::Pattern& pat, ::HIR::T ), // - Enums/Structs + (StructValue, + throw "TODO"; + ), (StructTuple, if( ty.m_data.is_Infer() ) { ty.m_data = ::HIR::TypeRef::Data::make_Path( {e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)} ); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index f43a2ecd..32af3ff3 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2548,6 +2548,12 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type ), // - Enums/Structs + (StructValue, + this->add_ivars_params( e.path.m_params ); + const auto& str = *e.binding; + assert( str.m_data.is_Unit() ); + this->equate_types( sp, type, ::HIR::TypeRef::new_path(e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)) ); + ), (StructTuple, this->add_ivars_params( e.path.m_params ); const auto& str = *e.binding; diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 1e319b08..0627b525 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -35,6 +35,7 @@ #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 _DISP16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5) _DISP1(n, d1) #define _DISPO0(n) #define _DISPO1(n, _1) n(_1) @@ -52,6 +53,7 @@ #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 _DISPO16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5) _DISPO1(n, d1) #define TU_DISPA(n, a) n a #define TU_DISPA1(n, a, _1) TU_DISPA(n, (TU_EXP a, TU_EXP _1)) diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 02baf445..6f166f65 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -86,6 +86,8 @@ namespace { destructure_from_ex(sp, e.sub_patterns[i], ::MIR::LValue::make_Field({ box$( lval.clone() ), i}), allow_refutable); } ), + (StructValue, + ), (StructTuple, for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) { |