summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_typeck/expr_cs.cpp42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 739d0f8b..99de3912 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -3917,7 +3917,24 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T
TU_ARM(pattern.m_data, StructTuple, e) {
context.add_ivars_params( e.path.m_params );
context.equate_types( sp, ty, ::HIR::TypeRef::new_path(e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)) );
- TODO(sp, "Match ergonomics - tuple struct pattern");
+
+ assert(e.binding);
+ const auto& str = *e.binding;
+
+ // - assert check from earlier pass
+ ASSERT_BUG(sp, str.m_data.is_Tuple(), "Struct-tuple pattern on non-Tuple struct");
+ const auto& sd = str.m_data.as_Tuple();
+ const auto& params = e.path.m_params;
+
+ rv = true;
+ for( unsigned int i = 0; i < e.sub_patterns.size(); i ++ )
+ {
+ /*const*/ auto& sub_pat = e.sub_patterns[i];
+ const auto& field_type = sd[i].ent;
+ ::HIR::TypeRef tmp;
+ const auto& var_ty = (monomorphise_type_needed(field_type) ? (tmp = monomorphise_type(sp, str.m_params, params, field_type)) : field_type);
+ rv &= this->revisit_inner(context, sub_pat, var_ty, binding_mode);
+ }
}
TU_ARM(pattern.m_data, Struct, e) {
context.add_ivars_params( e.path.m_params );
@@ -3982,7 +3999,28 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T
context.add_ivars_params( e.path.m_params );
context.equate_types( sp, ty, ::HIR::TypeRef::new_path(get_parent_path(e.path), ::HIR::TypeRef::TypePathBinding(e.binding_ptr)) );
assert(e.binding_ptr);
- TODO(sp, "Match ergonomics - enum struct pattern");
+
+ const auto& enm = *e.binding_ptr;
+ const auto& str = *enm.m_data.as_Data()[e.binding_idx].type.m_data.as_Path().binding.as_Struct();
+ const auto& tup_var = str.m_data.as_Named();
+ const auto& params = e.path.m_params;
+
+ rv = true; // &= below ensures that all must be complete to return complete
+ for( auto& field_pat : e.sub_patterns )
+ {
+ unsigned int f_idx = ::std::find_if( tup_var.begin(), tup_var.end(), [&](const auto& x){ return x.first == field_pat.first; } ) - tup_var.begin();
+ if( f_idx == tup_var.size() ) {
+ ERROR(sp, E0000, "Enum variant " << e.path << " doesn't have a field " << field_pat.first);
+ }
+ const ::HIR::TypeRef& field_type = tup_var[f_idx].second.ent;
+ if( monomorphise_type_needed(field_type) ) {
+ auto field_type_mono = monomorphise_type(sp, enm.m_params, params, field_type);
+ rv &= this->revisit_inner(context, field_pat.second, field_type_mono, binding_mode);
+ }
+ else {
+ rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode);
+ }
+ }
}
}
return rv;