summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-06-02 12:12:59 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-06-02 12:12:59 +0800
commit6f45483d70b7da92adec01ab67f5c7450c421801 (patch)
tree9ec323205f437f35d7453e6444c46f4782ba75ad
parent6747de8643ffd4a0a1705ac4c00c8cfb9a957154 (diff)
downloadmrust-6f45483d70b7da92adec01ab67f5c7450c421801.tar.gz
Tweaks to handling of struct patterns
-rw-r--r--src/hir_conv/bind.cpp30
-rw-r--r--src/hir_typeck/expr_cs.cpp23
-rw-r--r--src/parse/root.cpp4
3 files changed, 41 insertions, 16 deletions
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index c7a0829a..cf443eb6 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -248,37 +248,41 @@ namespace {
(Struct,
const auto& str = get_struct_ptr(sp, m_crate, e.path);
if(str.m_data.is_Named() ) {
- e.binding = &str;
}
else if( str.m_data.is_Unit() && e.sub_patterns.size() == 0 ) {
- e.binding = &str;
+ }
+ else if( str.m_data.is_Tuple() && str.m_data.as_Tuple().empty() && e.sub_patterns.size() == 0 ) {
}
else {
- ERROR(sp, E0000, "Struct pattern on field-less struct " << e.path);
+ ERROR(sp, E0000, "Struct pattern `" << pat << "` on field-less struct " << e.path);
}
+ e.binding = &str;
),
(EnumTuple,
auto p = get_enum_ptr(sp, m_crate, e.path);
const auto& var = p.first->m_variants[p.second].second;
- TU_IFLET(::HIR::Enum::Variant, var, Tuple, _,
- e.binding_ptr = p.first;
- e.binding_idx = p.second;
- )
+ if( var.is_Tuple() ) {
+ }
else {
ERROR(sp, E0000, "Enum tuple pattern on non-tuple variant " << e.path);
}
+ e.binding_ptr = p.first;
+ e.binding_idx = p.second;
),
(EnumStruct,
auto p = get_enum_ptr(sp, m_crate, e.path);
const auto& var = p.first->m_variants[p.second].second;
- TU_IFLET(::HIR::Enum::Variant, var, Struct, _,
- // All good
- e.binding_ptr = p.first;
- e.binding_idx = p.second;
- )
+ if( var.is_Struct() ) {
+ }
+ else if( var.is_Unit() && e.sub_patterns.empty() ) {
+ }
+ else if( var.is_Tuple() && var.as_Tuple().empty() && e.sub_patterns.empty() ) {
+ }
else {
- ERROR(sp, E0000, "Enum tuple pattern on non-tuple variant " << e.path);
+ ERROR(sp, E0000, "Enum struct pattern `" << pat << "` on non-struct variant " << e.path);
}
+ e.binding_ptr = p.first;
+ e.binding_idx = p.second;
)
)
}
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 5597b022..fb56abc4 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1157,6 +1157,12 @@ namespace {
const auto& enm = *e;
auto it = ::std::find_if(enm.m_variants.begin(), enm.m_variants.end(), [&](const auto&v)->auto{ return v.first == var_name; });
assert(it != enm.m_variants.end());
+ if( it->second.is_Unit() || it->second.is_Value() || it->second.is_Tuple() ) {
+ ASSERT_BUG(node.span(), node.m_values.size() == 0, "Values provided for unit-like variant");
+ ASSERT_BUG(node.span(), ! node.m_base_value, "Values provided for unit-like variant");
+ return ;
+ }
+ ASSERT_BUG(node.span(), it->second.is_Struct(), "_StructLiteral for non-struct variant - " << node.m_path);
fields_ptr = &it->second.as_Struct();
generics = &enm.m_params;
),
@@ -1164,10 +1170,14 @@ namespace {
TODO(node.span(), "StructLiteral of a union - " << ty);
),
(Struct,
- if( e->m_data.is_Unit() )
+ if( e->m_data.is_Unit() || e->m_data.is_Tuple() )
{
ASSERT_BUG(node.span(), node.m_values.size() == 0, "Values provided for unit-like struct");
- ASSERT_BUG(node.span(), ! node.m_base_value, "Values provided for unit-like struct");
+
+ if( node.m_base_value ) {
+ auto _ = this->push_inner_coerce_scoped(false);
+ node.m_base_value->visit( *this );
+ }
return ;
}
@@ -3817,10 +3827,14 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type
this->add_ivars_params( e.path.m_params );
this->equate_types( sp, type, ::HIR::TypeRef::new_path(e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)) );
+ if( e.sub_patterns.empty() )
+ return ;
+
assert(e.binding);
const auto& str = *e.binding;
+
// - assert check from earlier pass
- assert( str.m_data.is_Named() );
+ ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-Named struct");
const auto& sd = str.m_data.as_Named();
const auto& params = e.path.m_params;
@@ -3893,6 +3907,9 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type
this->equate_types( sp, type, ::HIR::TypeRef::new_path(mv$(path), ::HIR::TypeRef::TypePathBinding(e.binding_ptr)) );
}
+ if( e.sub_patterns.empty() )
+ return ;
+
assert(e.binding_ptr);
const auto& enm = *e.binding_ptr;
const auto& var = enm.m_variants[e.binding_idx].second;
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 2dc2ffc4..5f8ed0a3 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -824,6 +824,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
CHECK_TOK(tok, TOK_IDENT);
::std::string name = mv$(tok.str());
+ // Tuple-like variants
if( GET_TOK(tok, lex) == TOK_PAREN_OPEN )
{
::std::vector<TypeRef> types;
@@ -850,6 +851,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
GET_TOK(tok, lex);
variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), mv$(types)) );
}
+ // Struct-like variants
else if( tok.type() == TOK_BRACE_OPEN )
{
::std::vector<::AST::StructItem> fields;
@@ -880,12 +882,14 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), mv$(fields)) );
}
+ // Value variants
else if( tok.type() == TOK_EQUAL )
{
auto node = Parse_Expr(lex);
variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), mv$(node)) );
GET_TOK(tok, lex);
}
+ // Unit variants
else
{
variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), ::AST::Expr()) );