diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 11 | ||||
-rw-r--r-- | src/ast/ast.hpp | 17 | ||||
-rw-r--r-- | src/ast/path.cpp | 14 | ||||
-rw-r--r-- | src/ast/path.hpp | 12 | ||||
-rw-r--r-- | src/expand/mod.cpp | 13 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 7 | ||||
-rw-r--r-- | src/hir/hir.hpp | 16 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 12 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 10 | ||||
-rw-r--r-- | src/hir/visitor.hpp | 1 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/outer.cpp | 3 | ||||
-rw-r--r-- | src/parse/root.cpp | 67 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 18 | ||||
-rw-r--r-- | src/resolve/index.cpp | 8 | ||||
-rw-r--r-- | src/resolve/use.cpp | 7 |
16 files changed, 207 insertions, 11 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 420ac250..6e93a0d9 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -191,6 +191,14 @@ Struct Struct::clone() const throw "";
}
+Union Union::clone() const
+{
+ decltype(m_variants) new_vars;
+ for(const auto& f : m_variants)
+ new_vars.push_back( f.clone() );
+ return Union(m_params.clone(), mv$(new_vars));
+}
+
::std::ostream& operator<<(::std::ostream& os, const ImplDef& impl)
{
return os << "impl<" << impl.m_params << "> " << impl.m_trait.ent << " for " << impl.m_type << "";
@@ -343,6 +351,9 @@ Item Item::clone() const (Enum,
return AST::Item(e.clone());
),
+ (Union,
+ return AST::Item(e.clone());
+ ),
(Trait,
return AST::Item(e.clone());
),
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 63a8b751..597d9bdc 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -351,11 +351,23 @@ public: const GenericParams& params() const { return m_params; }
GenericParams& params() { return m_params; }
- TypeRef get_field_type(const char *name, const ::std::vector<TypeRef>& args);
-
Struct clone() const;
};
+class Union
+{
+public:
+ GenericParams m_params;
+ ::std::vector<StructItem> m_variants;
+
+ Union( GenericParams params, ::std::vector<StructItem> fields ):
+ m_params( move(params) ),
+ m_variants( mv$(fields) )
+ {}
+
+ Union clone() const;
+};
+
class ImplDef
{
Span m_span;
@@ -572,6 +584,7 @@ TAGGED_UNION_EX(Item, (), None, (Type, TypeAlias),
(Struct, Struct),
(Enum, Enum),
+ (Union, Union),
(Trait, Trait),
(Function, Function),
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 7574f707..583c3396 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -20,6 +20,7 @@ namespace AST { (Trait, os << "Trait"; ), (Struct, os << "Struct"; ), (Enum, os << "Enum"; ), + (Union, os << "Union"; ), (Static, os << "Static"; ), (Function, os << "Function";), (EnumVar, os << "EnumVar(" << i.idx << ")"; ), @@ -37,12 +38,13 @@ PathBinding PathBinding::clone() const TU_MATCH(::AST::PathBinding, (*this), (e), (Unbound , return PathBinding::make_Unbound({}); ), (Module , return PathBinding::make_Module(e); ), - (Crate , return PathBinding(e); ), - (Trait , return PathBinding::make_Trait(e); ), - (Struct , return PathBinding::make_Struct(e); ), - (Enum , return PathBinding::make_Enum(e); ), - (Static , return PathBinding::make_Static(e); ), - (Function, return PathBinding::make_Function(e); ), + (Crate , return PathBinding(e); ), + (Trait , return PathBinding(e); ), + (Struct , return PathBinding(e); ), + (Enum , return PathBinding(e); ), + (Union , return PathBinding(e); ), + (Static , return PathBinding(e); ), + (Function, return PathBinding(e); ), (TypeAlias, return PathBinding::make_TypeAlias(e); ), (EnumVar , return PathBinding::make_EnumVar(e); ), (StructMethod, return PathBinding::make_StructMethod(e); ), diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 3a00cdfd..479b26b8 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -21,6 +21,7 @@ class Module; class Trait; class Enum; class Struct; +class Union; class Static; } // namespace HIR @@ -32,6 +33,7 @@ class Module; class TypeAlias; class Enum; class Struct; +class Union; class Trait; class Static; class Function; @@ -47,13 +49,17 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( const Module* module_; const ::HIR::Module* hir = nullptr; }), + (Struct, struct { + const Struct* struct_; + const ::HIR::Struct* hir = nullptr; + }), (Enum, struct { const Enum* enum_; const ::HIR::Enum* hir = nullptr; }), - (Struct, struct { - const Struct* struct_; - const ::HIR::Struct* hir = nullptr; + (Union, struct { + const Union* union_; + const ::HIR::Union* hir = nullptr; }), (Trait, struct { const Trait* trait_; diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index b752c51b..5542b333 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -848,6 +848,19 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: Expand_Attrs(var.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, var); }); } ), + (Union, + for(auto it = e.m_variants.begin(); it != e.m_variants.end(); ) { + auto& si = *it; + Expand_Attrs(si.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); + Expand_Type(crate, modstack, mod, si.m_type); + Expand_Attrs(si.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); + + if( si.m_name == "" ) + it = e.m_variants.erase(it); + else + ++it; + } + ), (Trait, for(auto& ti : e.items()) { diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index a3957d2b..ebca4418 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -868,6 +868,10 @@ namespace { mv$(variants) }; } +::HIR::Union LowerHIR_Union(::HIR::ItemPath path, const ::AST::Union& f) +{ + TODO(Span(), "LowerHIR_Union"); +} ::HIR::Trait LowerHIR_Trait(::HIR::SimplePath trait_path, const ::AST::Trait& f) { TRACE_FUNCTION_F(trait_path); @@ -1114,6 +1118,9 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H (Enum, _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Enum(item_path, e) ); ), + (Union, + _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Union(item_path, e) ); + ), (Trait, _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Trait(item_path.get_simple_path(), e) ); ), diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index fed2e577..be043e22 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -204,6 +204,21 @@ public: TraitMarkings m_markings; }; +class Union +{ +public: + enum class Repr + { + Rust, + C, + }; + + GenericParams m_params; + Repr m_repr; + t_struct_fields m_variants; + + TraitMarkings m_markings; +}; struct AssociatedType { @@ -262,6 +277,7 @@ TAGGED_UNION(TypeItem, Import, (TypeAlias, TypeAlias), // NOTE: These don't introduce new values (Enum, Enum), (Struct, Struct), + (Union, Union), (Trait, Trait) ); TAGGED_UNION(ValueItem, Import, diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index cb928832..36395105 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -633,6 +633,10 @@ namespace { (Trait, m_out.write_tag(5); serialise(e); + ), + (Union, + m_out.write_tag(6); + serialise(e); ) ) } @@ -756,6 +760,14 @@ namespace { ) ) } + void serialise(const ::HIR::Union& item) + { + TRACE_FUNCTION; + + serialise_generics(item.m_params); + m_out.write_tag( static_cast<int>(item.m_repr) ); + serialise_vec(item.m_variants); + } void serialise(const ::HIR::Trait& item) { TRACE_FUNCTION_F("_trait:"); diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 64458901..c489e053 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -55,6 +55,10 @@ void ::HIR::Visitor::visit_module(::HIR::ItemPath p, ::HIR::Module& mod) DEBUG("struct " << name); this->visit_struct(p + name, e); ), + (Union, + DEBUG("union " << name); + this->visit_union(p + name, e); + ), (Trait, DEBUG("trait " << name); this->visit_trait(p + name, e); @@ -223,6 +227,12 @@ void ::HIR::Visitor::visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) ) } } +void ::HIR::Visitor::visit_union(::HIR::ItemPath p, ::HIR::Union& item) +{ + this->visit_params(item.m_params); + for(auto& var : item.m_variants) + this->visit_type(var.second.ent); +} void ::HIR::Visitor::visit_function(::HIR::ItemPath p, ::HIR::Function& item) { this->visit_params(item.m_params); diff --git a/src/hir/visitor.hpp b/src/hir/visitor.hpp index b101cbe4..dfae710d 100644 --- a/src/hir/visitor.hpp +++ b/src/hir/visitor.hpp @@ -33,6 +33,7 @@ public: virtual void visit_type_alias(ItemPath p, ::HIR::TypeAlias& item); virtual void visit_trait(ItemPath p, ::HIR::Trait& item); virtual void visit_struct(ItemPath p, ::HIR::Struct& item); + virtual void visit_union(ItemPath p, ::HIR::Union& item); virtual void visit_enum(ItemPath p, ::HIR::Enum& item); // - Value Items virtual void visit_function(ItemPath p, ::HIR::Function& item); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index df9a66db..463b39ce 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -146,6 +146,8 @@ namespace { (Struct, return &e; ), + (Union, + ), (Enum, ), (TypeAlias, diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index ff536709..5e436fa9 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -88,6 +88,9 @@ namespace { (Enum, return e.m_params; ), + (Union, + return e.m_params; + ), (Trait, return e.m_params; ) diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 1ea9ea93..5954c76d 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -843,6 +843,62 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items) return AST::Enum( mv$(params), mv$(variants) );
}
+::AST::Union Parse_Union(TokenStream& lex, AST::MetaItems& meta_items)
+{
+ Token tok;
+
+ TRACE_FUNCTION;
+
+ AST::GenericParams params;
+ if( GET_TOK(tok, lex) == TOK_LT )
+ {
+ params = Parse_GenericParams(lex);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ if(GET_TOK(tok, lex) == TOK_RWORD_WHERE)
+ {
+ Parse_WhereClause(lex, params);
+ tok = lex.getToken();
+ }
+ }
+
+ ::std::vector< ::AST::StructItem> variants;
+
+ CHECK_TOK(tok, TOK_BRACE_OPEN);
+ do {
+ if( LOOK_AHEAD(lex) == TOK_BRACE_CLOSE ) {
+ GET_TOK(tok, lex);
+ break ;
+ }
+
+ AST::MetaItems item_attrs;
+ while( tok.type() == TOK_ATTR_OPEN )
+ {
+ item_attrs.push_back( Parse_MetaItem(lex) );
+ GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
+ GET_TOK(tok, lex);
+ }
+ SET_ATTRS(lex, item_attrs);
+
+ bool is_pub = false;
+ if( LOOK_AHEAD(lex) == TOK_RWORD_PUB ) {
+ is_pub = true;
+ GET_TOK(tok, lex);
+ }
+
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto name = mv$(tok.str());
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+
+ auto ty = Parse_Type(lex);
+
+ variants.push_back( ::AST::StructItem( mv$(item_attrs), is_pub, mv$(name), mv$(ty) ) );
+
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_BRACE_CLOSE);
+
+ return ::AST::Union( mv$(params), mv$(variants) );
+}
+
/// Parse a meta-item declaration (either #![ or #[)
AST::MetaItem Parse_MetaItem(TokenStream& lex)
{
@@ -1572,6 +1628,17 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin item_name = mv$(tok.str());
item_data = ::AST::Item( Parse_EnumDef(lex, meta_items) );
break;
+ // Contextual keywords
+ case TOK_IDENT:
+ if( tok.str() == "union" ) {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ item_name = mv$(tok.str());
+ item_data = ::AST::Item( Parse_Union(lex, meta_items) );
+ }
+ else {
+ throw ParseError::Unexpected(lex, tok);
+ }
+ break;
// `impl`
case TOK_RWORD_IMPL:
return ::AST::Named< ::AST::Item> { "", Parse_Impl(lex, mv$(meta_items)), false };
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 34f217a8..76da7ed1 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -766,6 +766,9 @@ namespace { (Struct, pb = ::AST::PathBinding::make_Struct({nullptr, &e}); ), + (Union, + pb = ::AST::PathBinding::make_Union({nullptr, &e}); + ), (Enum, pb = ::AST::PathBinding::make_Enum({nullptr, &e}); ) @@ -868,6 +871,12 @@ namespace { path = split_into_ufcs_ty(sp, mv$(path), i-start); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); ), + (Union, + // TODO: set binding + path = split_into_crate(sp, mv$(path), start, crate.m_name); + path = split_into_ufcs_ty(sp, mv$(path), i-start); + return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); + ), (Enum, const auto& last_node = path_abs.nodes.back(); // If this refers to an enum variant, return the full path @@ -924,6 +933,9 @@ namespace { ), (Struct, path.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); + ), + (Union, + path.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); ) ) // Update path (trim down to `start` and set crate name) @@ -1800,6 +1812,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: (Enum , BUG(i.data.span, "Resolve_Absolute_ImplItems - Enum");), (Trait , BUG(i.data.span, "Resolve_Absolute_ImplItems - Trait");), (Struct, BUG(i.data.span, "Resolve_Absolute_ImplItems - Struct");), + (Union , BUG(i.data.span, "Resolve_Absolute_ImplItems - Union");), (Type, DEBUG("Type - " << i.name); assert( e.params().ty_params().size() == 0 ); @@ -1862,6 +1875,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Im (Enum , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Trait , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Struct, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Union , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Type, DEBUG("Type - " << i.name); assert( e.params().ty_params().size() == 0 ); @@ -2098,6 +2112,10 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) DEBUG("Struct - " << i.name); Resolve_Absolute_Struct(item_context, e); ), + (Union, + DEBUG("Union - " << i.name); + TODO(i.data.span, "Union"); + ), (Function, DEBUG("Function - " << i.name); Resolve_Absolute_Function(item_context, e); diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 09d3909b..c65327b0 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -130,6 +130,10 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) p.bind( ::AST::PathBinding::make_Enum({&e}) ); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), + (Union, + p.bind( ::AST::PathBinding::make_Union({&e}) ); + _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + ), (Trait, p.bind( ::AST::PathBinding::make_Trait({&e}) ); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); @@ -194,6 +198,7 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) (Crate , _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), (Module, _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), (Enum, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), + (Union, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), (Trait, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), (TypeAlias,_add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), @@ -286,6 +291,9 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C (Struct, p.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); ), + (Union, + p.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); + ), (Enum, p.bind( ::AST::PathBinding::make_Enum({nullptr}) ); ), diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 9c5bf090..89957696 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -324,6 +324,10 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( allow != Lookup::Value ) return ::AST::PathBinding::make_Enum({&e}); ), + (Union, + if( allow != Lookup::Value ) + return ::AST::PathBinding::make_Union({&e}); + ), (Module, if( allow != Lookup::Value ) return ::AST::PathBinding::make_Module({&e}); @@ -591,6 +595,9 @@ namespace { (Struct, return ::AST::PathBinding::make_Struct({nullptr, &e}); ), + (Union, + return ::AST::PathBinding::make_Union({nullptr, &e}); + ), (Trait, return ::AST::PathBinding::make_Trait({nullptr, &e}); ) |