summaryrefslogtreecommitdiff
path: root/src/hir/from_ast.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-18 21:40:06 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-18 21:40:06 +0800
commitc0d8141930e95f71a6d4fb84114fdc8a449527b7 (patch)
tree828892e2cbee599bc15227ba3270f6ddc82d2581 /src/hir/from_ast.cpp
parent65aba167033019994e35f43b819d8fbd3620e9ff (diff)
downloadmrust-c0d8141930e95f71a6d4fb84114fdc8a449527b7.tar.gz
All - Support tuple patterns with .. at the start/end - TODO: Support in the middle
Diffstat (limited to 'src/hir/from_ast.cpp')
-rw-r--r--src/hir/from_ast.cpp116
1 files changed, 83 insertions, 33 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 01917193..1bf63ac3 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -122,9 +122,30 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"});
case ::AST::PatternBinding::Type::REF: bt = ::HIR::PatternBinding::Type::Ref; break;
case ::AST::PatternBinding::Type::MUTREF: bt = ::HIR::PatternBinding::Type::MutRef; break;
}
- // TODO: Get bound slot
binding = ::HIR::PatternBinding(pat.binding().m_mutable, bt, pat.binding().m_name, pat.binding().m_slot);
}
+
+ struct H {
+ static ::std::vector< ::HIR::Pattern> lowerhir_patternvec(const ::std::vector< ::AST::Pattern>& sub_patterns) {
+ ::std::vector< ::HIR::Pattern> rv;
+ for(const auto& sp : sub_patterns)
+ rv.push_back( LowerHIR_Pattern(sp) );
+ return rv;
+ }
+ static ::HIR::Pattern::GlobPos lowerhir_globpos(::AST::Pattern::TupleGlob pos) {
+ switch(pos)
+ {
+ case ::AST::Pattern::TupleGlob::None:
+ return ::HIR::Pattern::GlobPos::None;
+ case ::AST::Pattern::TupleGlob::Start:
+ return ::HIR::Pattern::GlobPos::Start;
+ case ::AST::Pattern::TupleGlob::End:
+ return ::HIR::Pattern::GlobPos::End;
+ }
+ throw "";
+ }
+ };
+
TU_MATCH(::AST::Pattern::Data, (pat.data()), (e),
(MaybeBind,
BUG(pat.span(), "Encountered MaybeBind pattern");
@@ -156,53 +177,54 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"});
};
),
(Tuple,
- ::std::vector< ::HIR::Pattern> sub_patterns;
- for(const auto& sp : e.sub_patterns)
- sub_patterns.push_back( LowerHIR_Pattern(sp) );
+ auto glob_pos = H::lowerhir_globpos( e.glob_pos );
+ auto sub_patterns = H::lowerhir_patternvec( e.sub_patterns );
return ::HIR::Pattern {
mv$(binding),
::HIR::Pattern::Data::make_Tuple({
- mv$(sub_patterns)
+ glob_pos, mv$(sub_patterns)
})
};
),
- (WildcardStructTuple,
- TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb),
- (
- BUG(pat.span(), "Encountered StructTuple pattern not pointing to a enum variant or a struct - " << e.path);
- ),
- (EnumVar,
- return ::HIR::Pattern {
- mv$(binding),
- ::HIR::Pattern::Data::make_EnumTupleWildcard({
- LowerHIR_GenericPath(pat.span(), e.path),
- nullptr, 0
- })
- };
- ),
- (Struct,
- return ::HIR::Pattern {
- mv$(binding),
- ::HIR::Pattern::Data::make_StructTupleWildcard({
- LowerHIR_GenericPath(pat.span(), e.path),
- nullptr
- })
- };
- )
- )
- ),
(StructTuple,
- ::std::vector< ::HIR::Pattern> sub_patterns;
- for(const auto& sp : e.sub_patterns)
- sub_patterns.push_back( LowerHIR_Pattern(sp) );
+ auto sub_patterns = H::lowerhir_patternvec( e.tup_pat.sub_patterns );
TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb),
(
BUG(pat.span(), "Encountered StructTuple pattern not pointing to a enum variant or a struct - " << e.path);
),
(EnumVar,
+ const auto& var = pb.enum_->variants()[pb.idx].m_data;
+ const auto& var_tup_tys = var.as_Tuple().m_sub_types;
+ switch(e.tup_pat.glob_pos)
+ {
+ case ::AST::Pattern::TupleGlob::None:
+ // Check count
+ if( var_tup_tys.size() != sub_patterns.size() ) {
+ ERROR(pat.span(), E0000, "Enum variant pattern has a mismatched field count - " << var_tup_tys.size() << " exp, got " << sub_patterns.size());
+ }
+ break;
+ case ::AST::Pattern::TupleGlob::Start:
+ // NOTE == is allowed
+ if( var_tup_tys.size() < sub_patterns.size() ) {
+ ERROR(pat.span(), E0000, "Enum variant pattern has too many fields - " << var_tup_tys.size() << " max, got " << sub_patterns.size());
+ }
+ while( sub_patterns.size() < var_tup_tys.size() ) {
+ sub_patterns.insert( sub_patterns.begin(), ::HIR::Pattern() );
+ }
+ break;
+ case ::AST::Pattern::TupleGlob::End:
+ // NOTE == is allowed
+ if( var_tup_tys.size() < sub_patterns.size() ) {
+ ERROR(pat.span(), E0000, "Enum variant pattern has too many fields - " << var_tup_tys.size() << " max, got " << sub_patterns.size());
+ }
+ while( sub_patterns.size() < var_tup_tys.size() ) {
+ sub_patterns.insert( sub_patterns.end(), ::HIR::Pattern() );
+ }
+ break;
+ }
return ::HIR::Pattern {
mv$(binding),
::HIR::Pattern::Data::make_EnumTuple({
@@ -213,6 +235,34 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"});
};
),
(Struct,
+ const auto& tys = pb.struct_->m_data.as_Tuple().ents;
+ switch(e.tup_pat.glob_pos)
+ {
+ case ::AST::Pattern::TupleGlob::None:
+ // Check count
+ if( tys.size() != sub_patterns.size() ) {
+ ERROR(pat.span(), E0000, "Struct pattern has a mismatched field count - " << tys.size() << " exp, got " << sub_patterns.size());
+ }
+ break;
+ case ::AST::Pattern::TupleGlob::Start:
+ // NOTE == is allowed
+ if( sub_patterns.size() > tys.size() ) {
+ ERROR(pat.span(), E0000, "Struct pattern has too many fields - " << tys.size() << " max, got " << sub_patterns.size());
+ }
+ while( sub_patterns.size() < tys.size() ) {
+ sub_patterns.insert( sub_patterns.begin(), ::HIR::Pattern() );
+ }
+ break;
+ case ::AST::Pattern::TupleGlob::End:
+ // NOTE == is allowed
+ if( sub_patterns.size() > tys.size() ) {
+ ERROR(pat.span(), E0000, "Struct pattern has too many fields - " << tys.size() << " max, got " << sub_patterns.size());
+ }
+ while( sub_patterns.size() < tys.size() ) {
+ sub_patterns.insert( sub_patterns.end(), ::HIR::Pattern() );
+ }
+ break;
+ }
return ::HIR::Pattern {
mv$(binding),
::HIR::Pattern::Data::make_StructTuple({