summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp11
-rw-r--r--src/ast/ast.hpp17
-rw-r--r--src/ast/path.cpp14
-rw-r--r--src/ast/path.hpp12
-rw-r--r--src/expand/mod.cpp13
-rw-r--r--src/hir/from_ast.cpp7
-rw-r--r--src/hir/hir.hpp16
-rw-r--r--src/hir/serialise.cpp12
-rw-r--r--src/hir/visitor.cpp10
-rw-r--r--src/hir/visitor.hpp1
-rw-r--r--src/hir_conv/constant_evaluation.cpp2
-rw-r--r--src/hir_typeck/outer.cpp3
-rw-r--r--src/parse/root.cpp67
-rw-r--r--src/resolve/absolute.cpp18
-rw-r--r--src/resolve/index.cpp8
-rw-r--r--src/resolve/use.cpp7
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});
)