diff options
author | John Hodge <tpg@mutabah.net> | 2016-03-16 18:36:22 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-03-16 18:36:22 +0800 |
commit | a3d37e1f829fc974238815a9d9d468c9087048b4 (patch) | |
tree | acf322854baa582943e4886a2648a61f9f74f34b | |
parent | 967a2fd0b278c3e8f19bf8fd189304cb36000acf (diff) | |
download | mrust-a3d37e1f829fc974238815a9d9d468c9087048b4.tar.gz |
AST - Rework struct/enum fields
-rw-r--r-- | src/ast/ast.cpp | 32 | ||||
-rw-r--r-- | src/ast/ast.hpp | 121 | ||||
-rw-r--r-- | src/ast/provided_module.cpp | 7 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 26 | ||||
-rw-r--r-- | src/convert/typecheck_expr.cpp | 12 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 72 | ||||
-rw-r--r-- | src/expand/derive.cpp | 45 | ||||
-rw-r--r-- | src/expand/mod.cpp | 63 | ||||
-rw-r--r-- | src/include/synext.hpp | 3 | ||||
-rw-r--r-- | src/parse/root.cpp | 10 | ||||
-rw-r--r-- | src/types.cpp | 68 |
11 files changed, 342 insertions, 117 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index a8a8c342..0739fde2 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -497,9 +497,13 @@ SERIALISE_TYPE(Trait::, "AST_Trait", { })
SERIALISE_TYPE_A(EnumVariant::, "AST_EnumVariant", {
+ s.item(m_attrs);
s.item(m_name);
- s.item(m_sub_types);
- s.item(m_value);
+ s.item(m_data);
+})
+SERIALISE_TYPE(EnumVariantData::, "AST_EnumVariantData", {
+ // TODO: Serialise AST::EnumVariantData
+},{
})
SERIALISE_TYPE(Enum::, "AST_Enum", {
@@ -517,20 +521,20 @@ TypeRef Struct::get_field_type(const char *name, const ::std::vector<TypeRef>& a throw ::std::runtime_error("Incorrect parameter count for struct");
}
// TODO: Should the bounds be checked here? Or is the count sufficient?
- for(const auto& f : m_fields)
+ for(const auto& f : m_data.as_Struct().ents)
{
- if( f.name == name )
+ if( f.m_name == name )
{
// Found it!
if( args.size() )
{
- TypeRef res = f.data;
+ TypeRef res = f.m_type;
res.resolve_args( GenericResolveClosure(m_params, args) );
return res;
}
else
{
- return f.data;
+ return f.m_type;
}
}
}
@@ -540,10 +544,22 @@ TypeRef Struct::get_field_type(const char *name, const ::std::vector<TypeRef>& a SERIALISE_TYPE(Struct::, "AST_Struct", {
s << m_params;
- s << m_fields;
+ s << m_data;
},{
s.item(m_params);
- s.item(m_fields);
+ s.item(m_data);
+})
+SERIALISE_TYPE(StructData::, "AST_StructData", {
+ // TODO: AST::StructData serialise
+},{
+})
+SERIALISE_TYPE(StructItem::, "AST_StructItem", {
+ // TODO: AST::StructItem serialise
+},{
+})
+SERIALISE_TYPE(TupleItem::, "AST_TupleItem", {
+ // TODO: AST::TupleItem serialise
+},{
})
::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp)
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index c05e7aa4..d79adf8d 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -43,7 +43,57 @@ enum eItemType ITEM_FN,
};
-typedef Named<TypeRef> StructItem;
+struct StructItem:
+ public Serialisable
+{
+ ::AST::MetaItems m_attrs;
+ bool m_is_public;
+ ::std::string m_name;
+ TypeRef m_type;
+
+ StructItem()
+ {
+ }
+
+ StructItem(::AST::MetaItems attrs, bool is_pub, ::std::string name, TypeRef ty):
+ m_attrs( mv$(attrs) ),
+ m_is_public(is_pub),
+ m_name( mv$(name) ),
+ m_type( mv$(ty) )
+ {
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const StructItem& x) {
+ return os << (x.m_is_public ? "pub " : "") << x.m_name << ": " << x.m_type;
+ }
+
+ SERIALISABLE_PROTOTYPES();
+};
+
+struct TupleItem:
+ public Serialisable
+{
+ ::AST::MetaItems m_attrs;
+ bool m_is_public;
+ TypeRef m_type;
+
+ TupleItem()
+ {
+ }
+
+ TupleItem(::AST::MetaItems attrs, bool is_pub, TypeRef ty):
+ m_attrs( mv$(attrs) ),
+ m_is_public(is_pub),
+ m_type( mv$(ty) )
+ {
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const TupleItem& x) {
+ return os << (x.m_is_public ? "pub " : "") << x.m_type;
+ }
+
+ SERIALISABLE_PROTOTYPES();
+};
class Crate;
@@ -198,14 +248,31 @@ public: SERIALISABLE_PROTOTYPES();
};
+TAGGED_UNION_EX(EnumVariantData, (: public Serialisable), Value,
+ (
+ (Value, (
+ ::AST::Expr m_value;
+ )),
+ (Tuple, (
+ ::std::vector<TypeRef> m_sub_types;
+ )),
+ (Struct, (
+ ::std::vector<StructItem> m_fields;
+ ))
+ ),
+ (), (),
+ (
+ public:
+ SERIALISABLE_PROTOTYPES();
+ )
+ );
+
struct EnumVariant:
public Serialisable
{
MetaItems m_attrs;
::std::string m_name;
- ::std::vector<TypeRef> m_sub_types;
- ::std::vector<StructItem> m_fields;
- AST::Expr m_value;
+ EnumVariantData m_data;
EnumVariant()
{
@@ -214,26 +281,39 @@ struct EnumVariant: EnumVariant(MetaItems attrs, ::std::string name, Expr&& value):
m_attrs( mv$(attrs) ),
m_name( mv$(name) ),
- m_value( mv$(value) )
+ m_data( EnumVariantData::make_Value({mv$(value)}) )
{
}
EnumVariant(MetaItems attrs, ::std::string name, ::std::vector<TypeRef> sub_types):
m_attrs( mv$(attrs) ),
m_name( ::std::move(name) ),
- m_sub_types( ::std::move(sub_types) )
+ m_data( EnumVariantData::make_Tuple( {mv$(sub_types)} ) )
{
}
EnumVariant(MetaItems attrs, ::std::string name, ::std::vector<StructItem> fields):
m_attrs( mv$(attrs) ),
m_name( ::std::move(name) ),
- m_fields( ::std::move(fields) )
+ m_data( EnumVariantData::make_Struct( {mv$(fields)} ) )
{
}
- friend ::std::ostream& operator<<(::std::ostream& os, const EnumVariant& x) {
- return os << "EnumVariant(" << x.m_name << "(" << x.m_sub_types << ") = " << x.m_value << ")";
+ friend ::std::ostream& operator<<(::std::ostream& os, const EnumVariant& x)
+ {
+ os << "EnumVariant(" << x.m_name;
+ TU_MATCH(EnumVariantData, (x.m_data), (e),
+ (Value,
+ os << " = " << e.m_value;
+ ),
+ (Tuple,
+ os << "(" << e.m_sub_types << ")";
+ ),
+ (Struct,
+ os << " { " << e.m_fields << " }";
+ )
+ )
+ return os << ")";
}
SERIALISABLE_PROTOTYPES();
@@ -260,23 +340,38 @@ public: SERIALISABLE_PROTOTYPES();
};
+TAGGED_UNION_EX(StructData, (: public Serialisable), Struct,
+ (
+ (Tuple, (
+ ::std::vector<TupleItem> ents;
+ )),
+ (Struct, (
+ ::std::vector<StructItem> ents;
+ ))
+ ),
+ (),(),
+ (
+ public:
+ SERIALISABLE_PROTOTYPES();
+ )
+ );
+
class Struct:
public Serialisable
{
GenericParams m_params;
- ::std::vector<StructItem> m_fields;
public:
+ StructData m_data;
+
Struct() {}
Struct( GenericParams params, ::std::vector<StructItem> fields ):
m_params( move(params) ),
- m_fields( move(fields) )
+ m_data( StructData::make_Struct({mv$(fields)}) )
{}
const GenericParams& params() const { return m_params; }
- const ::std::vector<StructItem>& fields() const { return m_fields; }
GenericParams& params() { return m_params; }
- ::std::vector<StructItem>& fields() { return m_fields; }
TypeRef get_field_type(const char *name, const ::std::vector<TypeRef>& args);
diff --git a/src/ast/provided_module.cpp b/src/ast/provided_module.cpp index 13b3b910..99c86d3c 100644 --- a/src/ast/provided_module.cpp +++ b/src/ast/provided_module.cpp @@ -11,10 +11,9 @@ AST::Path g_sized_marker_path; void AST_InitProvidedModule() { // "struct str([u8])" - g_compiler_module.add_struct(true, "str", - AST::Struct( AST::GenericParams(), ::std::vector<AST::StructItem> { - AST::StructItem("", TypeRef(TypeRef::TagUnsizedArray(), Span(), TypeRef(Span(), CORETYPE_U8)), false), - }), AST::MetaItems()); + ::std::vector<AST::StructItem> fields; + fields.push_back( AST::StructItem(AST::MetaItems(), false, "", TypeRef(TypeRef::TagUnsizedArray(), Span(), TypeRef(Span(), CORETYPE_U8))) ); + g_compiler_module.add_struct(true, "str", AST::Struct(AST::GenericParams(), mv$(fields)), AST::MetaItems()); // TODO: Defer this until AFTER AST_InitProvidedModule_Impls(); diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 2a910692..5f309361 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -463,8 +463,16 @@ void CASTIterator::handle_struct(AST::Path path, AST::Struct& str) { start_scope(); handle_params( str.params() ); - for( auto& f : str.fields() ) - handle_type( f.data ); + TU_MATCH(AST::StructData, (str.m_data), (e), + (Tuple, + for( auto& f : e.ents ) + handle_type( f.m_type ); + ), + (Struct, + for( auto& f : e.ents ) + handle_type( f.m_type ); + ) + ) end_scope(); } void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) @@ -473,8 +481,18 @@ void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) handle_params( enm.params() ); for( auto& f : enm.variants() ) { - for( auto& t : f.m_sub_types ) - handle_type(t); + TU_MATCH(AST::EnumVariantData, (f.m_data), (e), + (Value, + ), + (Tuple, + for( auto& t : e.m_sub_types ) + handle_type(t); + ), + (Struct, + for( auto& t : e.m_fields ) + handle_type(t.m_type); + ) + ) } end_scope(); } diff --git a/src/convert/typecheck_expr.cpp b/src/convert/typecheck_expr.cpp index 314102ef..a91e2207 100644 --- a/src/convert/typecheck_expr.cpp +++ b/src/convert/typecheck_expr.cpp @@ -135,6 +135,7 @@ void CTypeChecker::handle_pattern_enum( ::std::vector<AST::Pattern>& sub_patterns ) { + #if 0 check_enum_variant(pat_args, hint_args, enum_params, var); // Ensure that sub_patterns is the same length as the variant @@ -153,6 +154,9 @@ void CTypeChecker::handle_pattern_enum( }); handle_pattern(sub_patterns[i], var_types[i]); } + #else + throw ::std::runtime_error("TODO: CTypeChecker::handle_pattern_enum "); + #endif } TypeRef& CTypeChecker::get_local_var(const char* name) @@ -240,6 +244,7 @@ void CTypeChecker::iterate_traits(::std::function<bool(const TypeRef& trait)> fc void CTypeChecker::check_enum_variant(::std::vector<TypeRef>& path_args, const ::std::vector<TypeRef>& argtypes, const AST::GenericParams& params, const AST::EnumVariant& var) { + #if 0 // We know the enum, but it might have type params, need to handle that case // TODO: Check for more parameters than required if( params.ty_params().size() > 0 ) @@ -274,6 +279,9 @@ void CTypeChecker::check_enum_variant(::std::vector<TypeRef>& path_args, const : } DEBUG("new path_args = [" << path_args << "]"); } + #else + throw ::std::runtime_error("TODO: CTypeChecker::check_enum_variant"); + #endif } /// Named value - leaf @@ -296,8 +304,8 @@ void CTC_NodeVisitor::visit(AST::ExprNode_NamedValue& node) auto idx = info.idx; // Enum variant: // - Check that this variant takes no arguments - if( enm.variants()[idx].m_sub_types.size() > 0 ) - throw ::std::runtime_error( FMT("Used a non-unit variant as a raw value - " << enm.variants()[idx].m_sub_types)); + if( ! enm.variants()[idx].m_data.is_Value() ) + throw ::std::runtime_error( "Used a non-unit variant as a raw value" ); // - Set output type to the enum (wildcard params, not default) AST::Path tp = p; tp.nodes().pop_back(); diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 1fd5494d..be8dbb64 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -858,33 +858,38 @@ void RustPrinter::handle_struct(const AST::Struct& s) { print_params(s.params()); - if( s.fields().size() == 0 ) - { - m_os << " /* unit-like */\n"; - print_bounds(s.params()); - m_os << indent() << ";\n"; - } - else if( s.fields().size() == 1 && s.fields()[0].name == "" ) - { - const auto& tuple = s.fields()[0].data; - m_os << "(" << tuple.print_pretty() <<")\n"; - print_bounds(s.params()); - m_os << indent() << ";\n"; - } - else - { + TU_MATCH(AST::StructData, (s.m_data), (e), + (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"; + } + ), + (Struct, m_os << "\n"; print_bounds(s.params()); m_os << indent() << "{\n"; inc_indent(); - for( const auto& i : s.fields() ) + for( const auto& i : e.ents ) { - m_os << indent() << (i.is_pub ? "pub " : "") << i.name << ": " << i.data.print_pretty() << "\n"; + m_os << indent() << (i.m_is_public ? "pub " : "") << i.m_name << ": " << i.m_type.print_pretty() << "\n"; } dec_indent(); m_os << indent() << "}\n"; - } + ) + ) m_os << "\n"; } @@ -900,18 +905,27 @@ void RustPrinter::handle_enum(const AST::Enum& s) for( const auto& i : s.variants() ) { m_os << indent() << "/*"<<idx<<"*/" << i.m_name; - if( i.m_sub_types.size() ) - { - for( const auto& t : i.m_sub_types ) + TU_MATCH(AST::EnumVariantData, (i.m_data), (e), + (Value, + m_os << " = " << e.m_value; + ), + (Tuple, + m_os << "("; + for( const auto& t : e.m_sub_types ) m_os << t.print_pretty() << ", "; - } - else if(i.m_value.is_valid()) - { - m_os << " = " << i.m_value; - } - else - { - } + m_os << ")"; + ), + (Struct, + m_os << "{\n"; + inc_indent(); + for( const auto& i : e.m_fields ) + { + m_os << indent() << i.m_name << ": " << i.m_type.print_pretty() << "\n"; + } + dec_indent(); + m_os << indent() << "}"; + ) + ) m_os << ",\n"; idx ++; } diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 028a8d9b..0096f809 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -58,27 +58,34 @@ public: // Generate code for Debug AST::ExprNodeP node; - node = NEWNODE(AST::ExprNode_NamedValue, AST::Path("f")); - node = NEWNODE(AST::ExprNode_CallMethod, - mv$(node), AST::PathNode("debug_struct",{}), - vec$( NEWNODE(AST::ExprNode_String, name) ) - ); - for( const auto& fld : str.fields() ) - { + TU_MATCH(AST::StructData, (str.m_data), (e), + (Struct, + node = NEWNODE(AST::ExprNode_NamedValue, AST::Path("f")); node = NEWNODE(AST::ExprNode_CallMethod, - mv$(node), AST::PathNode("field",{}), - vec$( - NEWNODE(AST::ExprNode_String, fld.name), - NEWNODE(AST::ExprNode_UniOp, AST::ExprNode_UniOp::REF, - NEWNODE(AST::ExprNode_Field, - NEWNODE(AST::ExprNode_NamedValue, AST::Path("self")), - fld.name - ) - ) - ) + mv$(node), AST::PathNode("debug_struct",{}), + vec$( NEWNODE(AST::ExprNode_String, name) ) ); - } - node = NEWNODE(AST::ExprNode_CallMethod, mv$(node), AST::PathNode("finish",{}), {}); + for( const auto& fld : e.ents ) + { + node = NEWNODE(AST::ExprNode_CallMethod, + mv$(node), AST::PathNode("field",{}), + vec$( + NEWNODE(AST::ExprNode_String, fld.m_name), + NEWNODE(AST::ExprNode_UniOp, AST::ExprNode_UniOp::REF, + NEWNODE(AST::ExprNode_Field, + NEWNODE(AST::ExprNode_NamedValue, AST::Path("self")), + fld.m_name + ) + ) + ) + ); + } + node = NEWNODE(AST::ExprNode_CallMethod, mv$(node), AST::PathNode("finish",{}), {}); + ), + (Tuple, + assert(!"TODO: derive() debug on tuple struct"); + ) + ) DEBUG("node = " << *node); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index e367f8ce..d7a142e9 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -483,22 +483,61 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo ), (Struct, - for(auto& fld : e.e.fields()) { - // TODO: Attributes on struct items - Expand_Type(is_early, crate, modstack, mod, fld.data); - } + TU_MATCH(AST::StructData, (e.e.m_data), (sd), + (Struct, + for(auto it = sd.ents.begin(); it != sd.ents.end(); ) { + auto& si = *it; + Expand_Attrs(si.m_attrs, stage_pre (is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + Expand_Type(is_early, crate, modstack, mod, si.m_type); + Expand_Attrs(si.m_attrs, stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + + if( si.m_name == "" ) + it = sd.ents.erase(it); + else + ++it; + } + ), + (Tuple, + for(auto it = sd.ents.begin(); it != sd.ents.end(); ) { + auto& si = *it; + //Expand_Attrs(si.m_attrs, stage_pre (is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + Expand_Type(is_early, crate, modstack, mod, si.m_type); + //Expand_Attrs(si.m_attrs, stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + + if( ! si.m_type.is_valid() ) + it = sd.ents.erase(it); + else + ++it; + } + ) + ) ), (Enum, for(auto& var : e.e.variants()) { Expand_Attrs(var.m_attrs, stage_pre (is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, var); }); - for(auto& ty : var.m_sub_types) { - Expand_Type(is_early, crate, modstack, mod, ty); - } - for(auto& si : var.m_fields) { - // TODO: Attributes on struct items - Expand_Type(is_early, crate, modstack, mod, si.data); - } - Expand_Expr(is_early, crate, modstack, var.m_value); + TU_MATCH(::AST::EnumVariantData, (var.m_data), (e), + (Value, + Expand_Expr(is_early, crate, modstack, e.m_value); + ), + (Tuple, + for(auto& ty : e.m_sub_types) { + Expand_Type(is_early, crate, modstack, mod, ty); + } + ), + (Struct, + for(auto it = e.m_fields.begin(); it != e.m_fields.end(); ) { + auto& si = *it; + Expand_Attrs(si.m_attrs, stage_pre (is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + Expand_Type(is_early, crate, modstack, mod, si.m_type); + Expand_Attrs(si.m_attrs, stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, si); }); + + if( si.m_name == "" ) + it = e.m_fields.erase(it); + else + ++it; + } + ) + ) Expand_Attrs(var.m_attrs, stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, crate, var); }); } ), diff --git a/src/include/synext.hpp b/src/include/synext.hpp index f33b7059..c1c7659d 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -13,8 +13,7 @@ namespace AST { class MetaItem; class Path; -// class StructItem; - typedef Named<::TypeRef> StructItem; + class StructItem; class EnumVariant; class Module; diff --git a/src/parse/root.cpp b/src/parse/root.cpp index b15f64ff..8f1a041d 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -441,6 +441,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) if(tok.type() == TOK_PAREN_OPEN)
{
// Tuple structs
+ // TODO: Using `StructItem` here isn't the best option. Should have another type
::std::vector<AST::StructItem> refs;
while(GET_TOK(tok, lex) != TOK_PAREN_CLOSE)
{
@@ -459,8 +460,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) else
lex.putback(tok);
- // TODO: Save item_attrs
- refs.push_back( AST::StructItem( "", Parse_Type(lex), is_pub ) );
+ refs.push_back( AST::StructItem( mv$(item_attrs), is_pub, "", Parse_Type(lex) ) );
if( GET_TOK(tok, lex) != TOK_COMMA )
break;
}
@@ -471,7 +471,6 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) GET_TOK(tok, lex);
Parse_WhereClause(lex, params);
}
- // TODO: Where block
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
//if( refs.size() == 0 )
// WARNING( , W000, "Use 'struct Name;' instead of 'struct Name();' ... ning-nong");
@@ -507,8 +506,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
- // TODO: Save item_attrs
- items.push_back( AST::StructItem( ::std::move(name), ::std::move(type), is_pub ) );
+ items.push_back( AST::StructItem( mv$(item_attrs), is_pub, mv$(name), mv$(type) ) );
if(GET_TOK(tok, lex) == TOK_BRACE_CLOSE)
break;
CHECK_TOK(tok, TOK_COMMA);
@@ -771,7 +769,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, AST::Module& mod, const AST::MetaItems GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
// TODO: Field attributes
- fields.push_back( ::AST::StructItem(mv$(name), mv$(ty), true) );
+ fields.push_back( ::AST::StructItem(mv$(field_attrs), true, mv$(name), mv$(ty)) );
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_BRACE_CLOSE);
GET_TOK(tok, lex);
diff --git a/src/types.cpp b/src/types.cpp index d8e655e6..e5dee127 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -441,15 +441,30 @@ bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) co (Struct, const auto &s = *info.struct_; GenericResolveClosure resolve_fn( s.params(), ent.path.nodes().back().args() ); - for(const auto& fld : s.fields()) - { - TypeRef fld_ty = fld.data; - fld_ty.resolve_args( resolve_fn ); - DEBUG("- Fld '" << fld.name << "' := " << fld.data << " => " << fld_ty); - // TODO: Defer failure until after all fields are processed - if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) ) - return false; - } + TU_MATCH(::AST::StructData, (s.m_data), (e), + (Struct, + for(const auto& fld : e.ents) + { + auto fld_ty = fld.m_type; + fld_ty.resolve_args( resolve_fn ); + DEBUG("- Fld '" << fld.m_name << "' := " << fld.m_type << " => " << fld_ty); + // TODO: Defer failure until after all fields are processed + if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) ) + return false; + } + ), + (Tuple, + for(const auto& fld : e.ents) + { + auto fld_ty = fld.m_type; + fld_ty.resolve_args( resolve_fn ); + DEBUG("- Fld ? := " << fld.m_type << " => " << fld_ty); + // TODO: Defer failure until after all fields are processed + if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) ) + return false; + } + ) + ) return true; ), (Enum, @@ -457,15 +472,32 @@ bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) co GenericResolveClosure resolve_fn( i.params(), ent.path.nodes().back().args() ); for( const auto& var : i.variants() ) { - for( const auto& ty : var.m_sub_types ) - { - TypeRef real_ty = ty; - real_ty.resolve_args( resolve_fn ); - DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty); - // TODO: Defer failure until after all fields are processed - if( !crate.find_impl(trait, real_ty, nullptr, nullptr) ) - return false; - } + TU_MATCH(AST::EnumVariantData, (var.m_data), (e), + (Value, + ), + (Tuple, + for( const auto& ty : e.m_sub_types ) + { + TypeRef real_ty = ty; + real_ty.resolve_args( resolve_fn ); + DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty); + // TODO: Defer failure until after all fields are processed + if( !crate.find_impl(trait, real_ty, nullptr, nullptr) ) + return false; + } + ), + (Struct, + for( const auto& fld : e.m_fields ) + { + auto fld_ty = fld.m_type; + fld_ty.resolve_args( resolve_fn ); + DEBUG("- Fld '" << fld.m_name << "' := " << fld.m_type << " => " << fld_ty); + // TODO: Defer failure until after all fields are processed + if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) ) + return false; + } + ) + ) } return true; ) |