summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-16 18:36:22 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-16 18:36:22 +0800
commita3d37e1f829fc974238815a9d9d468c9087048b4 (patch)
treeacf322854baa582943e4886a2648a61f9f74f34b
parent967a2fd0b278c3e8f19bf8fd189304cb36000acf (diff)
downloadmrust-a3d37e1f829fc974238815a9d9d468c9087048b4.tar.gz
AST - Rework struct/enum fields
-rw-r--r--src/ast/ast.cpp32
-rw-r--r--src/ast/ast.hpp121
-rw-r--r--src/ast/provided_module.cpp7
-rw-r--r--src/convert/ast_iterate.cpp26
-rw-r--r--src/convert/typecheck_expr.cpp12
-rw-r--r--src/dump_as_rust.cpp72
-rw-r--r--src/expand/derive.cpp45
-rw-r--r--src/expand/mod.cpp63
-rw-r--r--src/include/synext.hpp3
-rw-r--r--src/parse/root.cpp10
-rw-r--r--src/types.cpp68
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;
)