From 6b459cee4eec7f75388901e80af71993eb3a90b3 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 14 May 2017 23:32:12 +0800 Subject: Lex - Handle i128/u128 literals --- src/parse/lex.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/parse') diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 4cd9954f..71ccbfb2 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -463,11 +463,13 @@ Token Lexer::getTokenInt() else if(suffix == "i16") num_type = CORETYPE_I16; else if(suffix == "i32") num_type = CORETYPE_I32; else if(suffix == "i64") num_type = CORETYPE_I64; + else if(suffix == "i128") num_type = CORETYPE_I128; else if(suffix == "isize") num_type = CORETYPE_INT; else if(suffix == "u8") num_type = CORETYPE_U8; else if(suffix == "u16") num_type = CORETYPE_U16; else if(suffix == "u32") num_type = CORETYPE_U32; else if(suffix == "u64") num_type = CORETYPE_U64; + else if(suffix == "u128") num_type = CORETYPE_U128; else if(suffix == "usize") num_type = CORETYPE_UINT; else if(suffix == "f32") num_type = CORETYPE_F32; else if(suffix == "f64") num_type = CORETYPE_F64; -- cgit v1.2.3 From 9e2a6a73c9cb629e1143691885e48eb9b0fb2119 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 15 May 2017 12:14:05 +0800 Subject: Parse - Handle `Struct { var }` initialisation --- src/parse/expr.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/parse') diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 27d122ce..ab863600 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -999,9 +999,18 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) while( GET_TOK(tok, lex) == TOK_IDENT ) { auto name = mv$(tok.str()); - GET_CHECK_TOK(tok, lex, TOK_COLON); - ExprNodeP val = Parse_Stmt(lex); - items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) ); + + if( lex.lookahead(0) != TOK_COLON ) + { + ExprNodeP val = NEWNODE( AST::ExprNode_NamedValue, ::AST::Path(name) ); + items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) ); + } + else + { + GET_CHECK_TOK(tok, lex, TOK_COLON); + ExprNodeP val = Parse_Stmt(lex); + items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) ); + } if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE ) break; -- cgit v1.2.3 From 6747de8643ffd4a0a1705ac4c00c8cfb9a957154 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 28 May 2017 13:45:16 +0800 Subject: AST - Refactor to make unit-like structs their own variant --- Makefile | 2 +- src/ast/ast.cpp | 3 +++ src/ast/ast.hpp | 6 +++++ src/ast/dump.cpp | 26 ++++++++----------- src/expand/derive.cpp | 65 +++++++++++++++++++++++++++++++---------------- src/expand/mod.cpp | 2 ++ src/hir/from_ast.cpp | 30 +++++++++++----------- src/hir/from_ast_expr.cpp | 2 +- src/hir_conv/bind.cpp | 7 +++-- src/parse/root.cpp | 4 +-- src/resolve/absolute.cpp | 4 ++- src/resolve/index.cpp | 14 +++------- 12 files changed, 96 insertions(+), 69 deletions(-) (limited to 'src/parse') diff --git a/Makefile b/Makefile index 3c164dcb..2aac73d1 100644 --- a/Makefile +++ b/Makefile @@ -375,7 +375,7 @@ DISABLED_TESTS += run-pass/allocator-override # - Lazy. DISABLED_TESTS += run-pass/associated-types-projection-in-where-clause # Not normalizing bounds DISABLED_TESTS += run-pass/cast # Disallows cast from char to i32 -DISABLED_TESTS += run-pass/empty-struct-braces # Empty struct support +DISABLED_TESTS += run-pass/empty-struct-braces # HIR Gen - Empty struct support DISABLED_TESTS += run-pass/explicit-self-generic # Method Selection: Picks ExactSizeIterator::len instead of Self::len DISABLED_TESTS += run-pass/extern-compare-with-return-type # TODO Specialisation with function pointers DISABLED_TESTS += run-pass/issue-14399 # Inferrence ran though a coercion point. diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 39250a41..df5f4d5a 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -175,6 +175,9 @@ Enum Enum::clone() const Struct Struct::clone() const { TU_MATCHA( (m_data), (e), + (Unit, + return Struct(m_params.clone()); + ), (Tuple, decltype(e.ents) new_fields; for(const auto& f : e.ents) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index b63cb2e6..c067001a 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -319,6 +319,7 @@ public: TAGGED_UNION_EX(StructData, (), Struct, ( + (Unit, struct {}), (Tuple, struct { ::std::vector ents; }), @@ -339,6 +340,11 @@ public: StructData m_data; Struct() {} + Struct(GenericParams params): + m_params( mv$(params) ), + m_data( StructData::make_Unit({}) ) + { + } Struct( GenericParams params, ::std::vector fields ): m_params( move(params) ), m_data( StructData::make_Struct({mv$(fields)}) ) diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp index a6c298b0..0d77054c 100644 --- a/src/ast/dump.cpp +++ b/src/ast/dump.cpp @@ -991,22 +991,18 @@ void RustPrinter::handle_struct(const AST::Struct& s) print_params(s.params()); TU_MATCH(AST::StructData, (s.m_data), (e), + (Unit, + m_os << " /* unit-like */\n"; + print_bounds(s.params()); + m_os << indent() << ";\n"; + ), (Tuple, - if( e.ents.size() == 0 ) - { - m_os << " /* unit-like */\n"; - print_bounds(s.params()); - m_os << indent() << ";\n"; - } - else - { - m_os << "("; - for( const auto& i : e.ents ) - m_os << i.m_type << ", "; - m_os << ")\n"; - print_bounds(s.params()); - m_os << indent() << ";\n"; - } + m_os << "("; + for( const auto& i : e.ents ) + m_os << i.m_type << ", "; + m_os << ")\n"; + print_bounds(s.params()); + m_os << indent() << ";\n"; ), (Struct, m_os << "\n"; diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index c363b689..f09e9298 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -102,6 +102,8 @@ struct Deriver { ::std::vector ret; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -299,6 +301,13 @@ public: // Generate code for Debug AST::ExprNodeP node; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + node = NEWNODE(NamedValue, AST::Path("f")); + node = NEWNODE(CallMethod, + mv$(node), AST::PathNode("write_str",{}), + vec$( NEWNODE(String, name) ) + ); + ), (Struct, node = NEWNODE(NamedValue, AST::Path("f")); node = NEWNODE(CallMethod, @@ -480,6 +489,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -685,6 +696,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -896,6 +909,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -1049,6 +1064,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -1265,6 +1282,9 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + nodes.push_back( NEWNODE(NamedValue, AST::Path(ty_path)) ); + ), (Struct, ::std::vector< ::std::pair< ::std::string, AST::ExprNodeP> > vals; for( const auto& fld : e.ents ) @@ -1274,19 +1294,12 @@ public: nodes.push_back( NEWNODE(StructLiteral, ty_path, nullptr, mv$(vals)) ); ), (Tuple, - if( e.ents.size() == 0 ) - { - nodes.push_back( NEWNODE(NamedValue, AST::Path(ty_path)) ); - } - else + ::std::vector vals; + for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) { - ::std::vector vals; - for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) - { - vals.push_back( this->clone_val_ref(core_name, this->field(FMT(idx))) ); - } - nodes.push_back( NEWNODE(CallPath, AST::Path(ty_path), mv$(vals)) ); + vals.push_back( this->clone_val_ref(core_name, this->field(FMT(idx))) ); } + nodes.push_back( NEWNODE(CallPath, AST::Path(ty_path), mv$(vals)) ); ) ) @@ -1428,6 +1441,9 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + nodes.push_back( NEWNODE(NamedValue, AST::Path(ty_path)) ); + ), (Struct, ::std::vector< ::std::pair< ::std::string, AST::ExprNodeP> > vals; for( const auto& fld : e.ents ) @@ -1437,19 +1453,12 @@ public: nodes.push_back( NEWNODE(StructLiteral, ty_path, nullptr, mv$(vals)) ); ), (Tuple, - if( e.ents.size() == 0 ) - { - nodes.push_back( NEWNODE(NamedValue, AST::Path(ty_path)) ); - } - else + ::std::vector vals; + for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) { - ::std::vector vals; - for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) - { - vals.push_back( this->default_call(core_name) ); - } - nodes.push_back( NEWNODE(CallPath, AST::Path(ty_path), mv$(vals)) ); + vals.push_back( this->default_call(core_name) ); } + nodes.push_back( NEWNODE(CallPath, AST::Path(ty_path), mv$(vals)) ); ) ) @@ -1522,6 +1531,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, for( const auto& fld : e.ents ) { @@ -1680,6 +1691,8 @@ public: ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, unsigned int idx = 0; for( const auto& fld : e.ents ) @@ -1707,6 +1720,9 @@ public: ::AST::ExprNodeP node; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + node = get_val_ok(core_name); + ), (Struct, node = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_struct", @@ -1917,6 +1933,8 @@ public: AST::ExprNodeP node_v; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + ), (Struct, ::std::vector< ::std::pair< ::std::string, AST::ExprNodeP > > vals; unsigned int idx = 0; @@ -1949,6 +1967,9 @@ public: ::AST::ExprNodeP node; TU_MATCH(AST::StructData, (str.m_data), (e), + (Unit, + node = NEWNODE(NamedValue, mv$(base_path)); + ), (Struct, assert( !args[2] ); args[2] = NEWNODE(Integer, e.ents.size(), CORETYPE_UINT); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 788b2109..1ee2e19e 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -896,6 +896,8 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: (Struct, TU_MATCH(AST::StructData, (e.m_data), (sd), + (Unit, + ), (Struct, for(auto it = sd.ents.begin(); it != sd.ents.end(); ) { auto& si = *it; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 1f1bc4e3..be823c6b 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -818,18 +818,16 @@ namespace { ::HIR::Struct::Data data; TU_MATCH(::AST::StructData, (ent.m_data), (e), + (Unit, + data = ::HIR::Struct::Data::make_Unit({}); + ), (Tuple, - if( e.ents.size() == 0 ) { - data = ::HIR::Struct::Data::make_Unit({}); - } - else { - ::HIR::Struct::Data::Data_Tuple fields; + ::HIR::Struct::Data::Data_Tuple fields; - for(const auto& field : e.ents) - fields.push_back( { field.m_is_public, LowerHIR_Type(field.m_type) } ); + for(const auto& field : e.ents) + fields.push_back( { field.m_is_public, LowerHIR_Type(field.m_type) } ); - data = ::HIR::Struct::Data::make_Tuple( mv$(fields) ); - } + data = ::HIR::Struct::Data::make_Tuple( mv$(fields) ); ), (Struct, ::HIR::Struct::Data::Data_Named fields; @@ -1217,12 +1215,14 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H ), (Struct, /// Add value reference - TU_IFLET( ::AST::StructData, e.m_data, Tuple, e2, - if( e2.ents.size() == 0 ) - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstant({item_path.get_simple_path()}) ); - else - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstructor({item_path.get_simple_path()}) ); - ) + if( e.m_data.is_Unit() ) { + _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstant({item_path.get_simple_path()}) ); + } + else if( e.m_data.is_Tuple() ) { + _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstructor({item_path.get_simple_path()}) ); + } + else { + } _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Struct(item_path, e) ); ), (Enum, diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index cd2b27fa..9085bd3b 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -627,7 +627,7 @@ struct LowerHIR_ExprNode_Visitor: if( e.struct_->m_data.is_Struct() ) { ERROR(v.span(), E0000, "Named value referring to a struct that isn't tuple-like or unit-like - " << v.m_path); } - is_tuple_constructor = e.struct_->m_data.as_Tuple().ents.size() > 0; + is_tuple_constructor = e.struct_->m_data.is_Tuple(); } else { diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 20e8f7ca..c7a0829a 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -247,9 +247,12 @@ namespace { ), (Struct, const auto& str = get_struct_ptr(sp, m_crate, e.path); - TU_IFLET(::HIR::Struct::Data, str.m_data, Named, _, + 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 { ERROR(sp, E0000, "Struct pattern on field-less struct " << e.path); } diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 3bdd34b1..2dc2ffc4 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -563,7 +563,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) else if(tok.type() == TOK_SEMICOLON) { // Unit-like struct - return AST::Struct(mv$(params), ::std::vector()); + return AST::Struct(mv$(params)); } else if(tok.type() == TOK_BRACE_OPEN) { @@ -594,7 +594,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) } //if( items.size() == 0 ) // WARNING( , W000, "Use 'struct Name;' instead of 'struct Nam { };' ... ning-nong"); - return AST::Struct(::std::move(params), ::std::move(items)); + return AST::Struct(mv$(params), mv$(items)); } else { diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index db85ed3f..26a45a1e 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1020,7 +1020,7 @@ namespace { } break; } - ERROR(sp, E0000, "Couldn't find path component '" << path_abs.nodes.back().name() << "' of " << path); + ERROR(sp, E0000, "Couldn't find " << Context::lookup_mode_msg(mode) << " '" << path_abs.nodes.back().name() << "' of " << path); } } @@ -1946,6 +1946,8 @@ void Resolve_Absolute_Struct(Context& item_context, ::AST::Struct& e) Resolve_Absolute_Generic(item_context, e.params()); TU_MATCH(::AST::StructData, (e.m_data), (s), + (Unit, + ), (Tuple, for(auto& field : s.ents) { Resolve_Absolute_Type(item_context, field.m_type); diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 7b988bc0..f57fc3e6 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -149,7 +149,7 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) (Struct, p.bind( ::AST::PathBinding::make_Struct({&e}) ); // - If the struct is a tuple-like struct (or unit-like), it presents in the value namespace - if( e.m_data.is_Tuple() ) { + if( ! e.m_data.is_Struct() ) { _add_item_value(i.data.span, mod, i.name, i.is_pub, p); } _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); @@ -209,15 +209,9 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); // - If the struct is a tuple-like struct, it presents in the value namespace assert(e.struct_ || e.hir); - if( e.struct_ ) { - if( e.struct_->m_data.is_Tuple() ) { - _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - } - } - else { - if( ! e.hir->m_data.is_Named() ) { - _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - } + if( !(e.struct_ ? e.struct_->m_data.is_Struct() : e.hir->m_data.is_Named()) ) + { + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); } ), (Static , _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), -- cgit v1.2.3 From 6f45483d70b7da92adec01ab67f5c7450c421801 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 2 Jun 2017 12:12:59 +0800 Subject: Tweaks to handling of struct patterns --- src/hir_conv/bind.cpp | 30 +++++++++++++++++------------- src/hir_typeck/expr_cs.cpp | 23 ++++++++++++++++++++--- src/parse/root.cpp | 4 ++++ 3 files changed, 41 insertions(+), 16 deletions(-) (limited to 'src/parse') 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 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()) ); -- cgit v1.2.3