summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-08-24 22:50:49 +0800
committerJohn Hodge <tpg@mutabah.net>2015-08-24 22:50:49 +0800
commit7156d7d274184a085452a58ee3398d06024112b5 (patch)
tree874e8ca17500870c7aeb8e440e9d09d982284593 /src
parentedbd5db807dd66876ad25e0b67a37a567187f076 (diff)
downloadmrust-7156d7d274184a085452a58ee3398d06024112b5.tar.gz
BROKEN - Halfway through a rewrite of type handling
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp6
-rw-r--r--src/ast/ast.hpp6
-rw-r--r--src/ast/path.cpp11
-rw-r--r--src/ast/path.hpp2
-rw-r--r--src/common.hpp12
-rw-r--r--src/convert/ast_iterate.cpp5
-rw-r--r--src/include/serialise.hpp2
-rw-r--r--src/include/tagged_enum.hpp120
-rw-r--r--src/main.cpp14
-rw-r--r--src/types.cpp800
-rw-r--r--src/types.hpp241
11 files changed, 693 insertions, 526 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index d712edd3..f0d38199 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -916,10 +916,10 @@ bool TypeParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bool
if( bound.is_trait() && bound.test() == test )
{
const auto& trait = bound.bound();
- const auto& ty_traits = type.traits();
+ //const auto& ty_traits = type.traits();
- auto it = ::std::find(ty_traits.begin(), ty_traits.end(), trait);
- if( it == ty_traits.end() )
+ //auto it = ::std::find(ty_traits.begin(), ty_traits.end(), trait);
+ //if( it == ty_traits.end() )
{
throw ::std::runtime_error( FMT("No matching impl of "<<trait<<" for "<<type));
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index f1229fb2..2376b054 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -653,10 +653,10 @@ public:
m_submods.push_back( ::std::make_pair( move(mod), is_public ) );
}
void add_impl(Impl impl) {
- m_impls.push_back( ::std::move(impl) );
+ m_impls.emplace_back( ::std::move(impl) );
}
void add_neg_impl(ImplDef impl) {
- m_neg_impls.push_back( ::std::move(impl) );
+ m_neg_impls.emplace_back( ::std::move(impl) );
}
void add_macro(bool is_exported, ::std::string name, MacroRules macro) {
m_macros.push_back( Item<MacroRules>( move(name), move(macro), is_exported ) );
@@ -859,7 +859,7 @@ public:
m_params(params),
m_args(args)
{}
- TypeRef operator()(const char *argname) {
+ const TypeRef& operator()(const char *argname) {
for(unsigned int i = 0; i < m_params.ty_params().size(); i ++)
{
if( m_params.ty_params()[i].name() == argname ) {
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index df00f147..9757e576 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -568,6 +568,17 @@ void Path::match_args(const Path& other, ::std::function<void(const char*,const
}
}
+bool Path::is_concrete() const
+{
+ for(const auto& n : this->nodes())
+ {
+ for(const auto& p : n.args())
+ if( not p.is_concrete() )
+ return false;
+ }
+ return true;
+}
+
/// Compare if two paths refer to the same non-generic item
///
/// - This doesn't handle the (impossible?) case where a generic might
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index f53561fa..ff267c73 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -317,6 +317,8 @@ public:
bool is_absolute() const { return m_class == ABSOLUTE; }
bool is_relative() const { return m_class == RELATIVE; }
size_t size() const { return m_nodes.size(); }
+
+ bool is_concrete() const;
const PathBinding& binding() const { return m_binding; }
diff --git a/src/common.hpp b/src/common.hpp
index 457d58b0..8fef294a 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -8,15 +8,27 @@
#include <map>
#include <cassert>
#include <sstream>
+#include <memory>
#define FMT(ss) (dynamic_cast< ::std::stringstream&>(::std::stringstream() << ss).str())
// XXX: Evil hack - Define 'mv$' to be ::std::move
#define mv$(x) ::std::move(x)
+#define box$(x) ::make_unique_ptr(::std::move(x))
+#define rc_new$(x) ::make_shared_ptr(::std::move(x))
#include "include/debug.hpp"
#include "include/rustic.hpp" // slice and option
#include "include/compile_error.hpp"
+template<typename T>
+::std::unique_ptr<T> make_unique_ptr(T&& v) {
+ return ::std::unique_ptr<T>(new T(mv$(v)));
+}
+template<typename T>
+::std::shared_ptr<T> make_shared_ptr(T&& v) {
+ return ::std::shared_ptr<T>(new T(mv$(v)));
+}
+
enum Ordering
{
OrdLess,
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp
index 24dbf5f0..32125eaf 100644
--- a/src/convert/ast_iterate.cpp
+++ b/src/convert/ast_iterate.cpp
@@ -15,8 +15,9 @@ void CASTIterator::handle_type(TypeRef& type)
}
else
{
- for(auto& subtype : type.sub_types())
- handle_type(subtype);
+ throw ::std::runtime_error("TODO: handle_type");
+ //for(auto& subtype : type.sub_types())
+ // handle_type(subtype);
}
}
void CASTIterator::handle_expr(AST::ExprNode& node)
diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp
index 0840d54b..5556a510 100644
--- a/src/include/serialise.hpp
+++ b/src/include/serialise.hpp
@@ -59,6 +59,7 @@ public:
virtual Serialiser& operator<<(uint64_t val) = 0;
virtual Serialiser& operator<<(int64_t val) = 0;
virtual Serialiser& operator<<(double val) = 0;
+ Serialiser& operator<<(unsigned int val) { return *this << (uint64_t)val; };
virtual Serialiser& operator<<(const char* s) = 0;
Serialiser& operator<<(const ::std::string& s) {
return *this << s.c_str();
@@ -120,6 +121,7 @@ protected:
public:
virtual void item(bool& b) = 0;
virtual void item(uint64_t& v) = 0;
+ void item(unsigned int& v) { uint64_t v1; this->item(v1); v = v1; }
virtual void item(int64_t& val) = 0;
virtual void item(double& v) = 0;
virtual void item(::std::string& s) = 0;
diff --git a/src/include/tagged_enum.hpp b/src/include/tagged_enum.hpp
index e491e154..8f5b34e0 100644
--- a/src/include/tagged_enum.hpp
+++ b/src/include/tagged_enum.hpp
@@ -1,3 +1,8 @@
+/*
+ * The most evil CPP abuse I have ever written
+ */
+#ifndef INCLUDED_TAGGED_UNION_H_
+#define INCLUDED_TAGGED_UNION_H_
#define TE_DATANAME(name) Data_##name
#define ENUM_CONS(__tag, __type) \
@@ -14,16 +19,29 @@
__type& as_##__tag() { return reinterpret_cast<__type&>(m_data); } \
__type unwrap_##__tag() { return ::std::move(reinterpret_cast<__type&>(m_data)); } \
+// Argument iteration
+#define _DISP2(n, _1, _2) n _1 n _2
+#define _DISP3(n, v, v2, v3) n v n v2 n v3 // _DISP2(n, __VA_ARGS__)
+#define _DISP4(n, v, v2, v3, v4) n v n v2 n v3 n v4 // #define _DISP4(n, v, ...) n v _DISP3(n, __VA_ARGS__)
+#define _DISP5(n, v, ...) n v _DISP4(n, __VA_ARGS__)
+#define _DISP6(n, v, ...) n v _DISP5(n, __VA_ARGS__)
+#define _DISP7(n, v, ...) n v _DISP6(n, __VA_ARGS__)
+#define _DISP8(n, v, ...) n v _DISP7(n, __VA_ARGS__)
+#define _DISP9(n, v, ...) n v _DISP8(n, __VA_ARGS__)
+#define _DISP10(n, v, ...) n v _DISP9(n, __VA_ARGS__)
+#define _DISP11(n, v, ...) n v _DISP10(n, __VA_ARGS__)
+#define _DISP12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) _DISP4(n, a1,a2,a3,a4) _DISP4(n, b1,b2,b3,b4) _DISP4(n, c1,c2,c3,c4) //n v _DISP11(n, __VA_ARGS__)
+
+// Macro to obtain a numbered macro for argument counts
+// - Raw variant
+#define TE_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,COUNT,...) SUF##COUNT
+#define TE_GM(SUF,...) TE_GM_I(SUF,__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,x)
+// - _DISP based variant (for iteration)
+#define TE_GMX(...) TE_GM(_DISP,__VA_ARGS__)
+
+
+// "
#define TE_CONS(name, _) ENUM_CONS(name, TE_DATANAME(name))
-#define TE_CONS2(a, b) TE_CONS a TE_CONS b
-#define TE_CONS3(a, ...) TE_CONS a TE_CONS2(__VA_ARGS__)
-#define TE_CONS4(a, ...) TE_CONS a TE_CONS3(__VA_ARGS__)
-#define TE_CONS5(a, ...) TE_CONS a TE_CONS4(__VA_ARGS__)
-#define TE_CONS6(a, ...) TE_CONS a TE_CONS5(__VA_ARGS__)
-#define TE_CONS7(a, ...) TE_CONS a TE_CONS6(__VA_ARGS__)
-#define TE_CONS8(a, ...) TE_CONS a TE_CONS7(__VA_ARGS__)
-#define TE_CONS9(a, ...) TE_CONS a TE_CONS8(__VA_ARGS__)
-#define TE_CONS10(a, ...) TE_CONS a TE_CONS9(__VA_ARGS__)
// Sizes of structures
#define TE_SO(name, _) sizeof(TE_DATANAME(name))
@@ -37,94 +55,39 @@
#define MAXS8(a, b, c, d, e, f, g, h) MAX2(MAXS4(a, b, c, d), MAXS4(e, f, g, h))
#define MAXS9(a, b, c, d, e, f, g, h, i) MAX2(MAXS4(a, b, c, d), MAXS5(e, f, g, h, i))
#define MAXS10(a, b, c, d, e, f, g, h, i, j) MAX2(MAXS5(a, b, c, d, e), MAXS5(f, g, h, i, j))
+#define MAXS11(a, b, c, d, e, f, g, h, i, j, k) MAX2(MAXS6(a, b, c, d, e, f), MAXS5(g, h, i, j, k))
+#define MAXS12(a, b, c, d, e, f, g, h, i, j, k, l) MAX2(MAXS6(a, b, c, d, e, f), MAXS6(g, h, i, j, k, l))
// Type definitions
#define TE_EXP(...) __VA_ARGS__
-#define TE_TYPEDEF(name, content) struct TE_DATANAME(name) { TE_EXP content };/*
+#define TE_TYPEDEF(name, content) struct TE_DATANAME(name) { TE_EXP content; };/*
*/
-#define TE_TYPEDEF2(_1, _2) TE_TYPEDEF _1 TE_TYPEDEF _2
-#define TE_TYPEDEF3(v, ...) TE_TYPEDEF v TE_TYPEDEF2(__VA_ARGS__)
-#define TE_TYPEDEF4(v, ...) TE_TYPEDEF v TE_TYPEDEF3(__VA_ARGS__)
-#define TE_TYPEDEF5(v, ...) TE_TYPEDEF v TE_TYPEDEF4(__VA_ARGS__)
-#define TE_TYPEDEF6(v, ...) TE_TYPEDEF v TE_TYPEDEF5(__VA_ARGS__)
-#define TE_TYPEDEF7(v, ...) TE_TYPEDEF v TE_TYPEDEF6(__VA_ARGS__)
-#define TE_TYPEDEF8(v, ...) TE_TYPEDEF v TE_TYPEDEF7(__VA_ARGS__)
-#define TE_TYPEDEF9(v, ...) TE_TYPEDEF v TE_TYPEDEF8(__VA_ARGS__)
-#define TE_TYPEDEF10(v, ...) TE_TYPEDEF v TE_TYPEDEF9(__VA_ARGS__)
#define TE_TAG(name, _) name,
-#define TE_TAG2(_1,_2) TE_TAG _1 TE_TAG _2
-#define TE_TAG3(_1,...) TE_TAG _1 TE_TAG2(__VA_ARGS__)
-#define TE_TAG4(_1,...) TE_TAG _1 TE_TAG3(__VA_ARGS__)
-#define TE_TAG5(_1,...) TE_TAG _1 TE_TAG4(__VA_ARGS__)
-#define TE_TAG6(_1,...) TE_TAG _1 TE_TAG5(__VA_ARGS__)
-#define TE_TAG7(_1,...) TE_TAG _1 TE_TAG6(__VA_ARGS__)
-#define TE_TAG8(_1,...) TE_TAG _1 TE_TAG7(__VA_ARGS__)
-#define TE_TAG9(_1,...) TE_TAG _1 TE_TAG9(__VA_ARGS__)
-#define TE_TAG10(_1,...) TE_TAG _1 TE_TAG9(__VA_ARGS__)
+// Destructor internals
#define TE_DEST_CASE(tag, _) case tag: as_##tag().~TE_DATANAME(tag)(); break;/*
*/
-#define TE_DEST_CASE2(_1,_2) TE_DEST_CASE _1 TE_DEST_CASE _2
-#define TE_DEST_CASE3(v, ...) TE_DEST_CASE v TE_DEST_CASE2(__VA_ARGS__)
-#define TE_DEST_CASE4(v, ...) TE_DEST_CASE v TE_DEST_CASE3(__VA_ARGS__)
-#define TE_DEST_CASE5(v, ...) TE_DEST_CASE v TE_DEST_CASE4(__VA_ARGS__)
-#define TE_DEST_CASE6(v, ...) TE_DEST_CASE v TE_DEST_CASE5(__VA_ARGS__)
-#define TE_DEST_CASE7(v, ...) TE_DEST_CASE v TE_DEST_CASE6(__VA_ARGS__)
-#define TE_DEST_CASE8(v, ...) TE_DEST_CASE v TE_DEST_CASE7(__VA_ARGS__)
-#define TE_DEST_CASE9(v, ...) TE_DEST_CASE v TE_DEST_CASE8(__VA_ARGS__)
-#define TE_DEST_CASE10(v, ...) TE_DEST_CASE v TE_DEST_CASE9(__VA_ARGS__)
+// move constructor internals
#define TE_MOVE_CASE(tag, _) case tag: new(m_data) TE_DATANAME(tag)(x.unwrap_##tag()); break;/*
*/
-#define TE_MOVE_CASE2(_1,_2) TE_MOVE_CASE _1 TE_MOVE_CASE _2
-#define TE_MOVE_CASE3(v, ...) TE_MOVE_CASE v TE_MOVE_CASE2(__VA_ARGS__)
-#define TE_MOVE_CASE4(v, ...) TE_MOVE_CASE v TE_MOVE_CASE3(__VA_ARGS__)
-#define TE_MOVE_CASE5(v, ...) TE_MOVE_CASE v TE_MOVE_CASE4(__VA_ARGS__)
-#define TE_MOVE_CASE6(v, ...) TE_MOVE_CASE v TE_MOVE_CASE5(__VA_ARGS__)
-#define TE_MOVE_CASE7(v, ...) TE_MOVE_CASE v TE_MOVE_CASE6(__VA_ARGS__)
-#define TE_MOVE_CASE8(v, ...) TE_MOVE_CASE v TE_MOVE_CASE7(__VA_ARGS__)
-#define TE_MOVE_CASE9(v, ...) TE_MOVE_CASE v TE_MOVE_CASE8(__VA_ARGS__)
-#define TE_MOVE_CASE10(v, ...) TE_MOVE_CASE v TE_MOVE_CASE9(__VA_ARGS__)
// "tag_to_str" internals
#define TE_TOSTR_CASE(tag,_) case tag: return #tag;/*
*/
-#define TE_TOSTR_CASE2(a,b) TE_TOSTR_CASE a TE_TOSTR_CASE b
-#define TE_TOSTR_CASE3(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE2(__VA_ARGS__)
-#define TE_TOSTR_CASE4(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE3(__VA_ARGS__)
-#define TE_TOSTR_CASE5(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE4(__VA_ARGS__)
-#define TE_TOSTR_CASE6(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE5(__VA_ARGS__)
-#define TE_TOSTR_CASE7(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE6(__VA_ARGS__)
-#define TE_TOSTR_CASE8(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE7(__VA_ARGS__)
-#define TE_TOSTR_CASE9(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE8(__VA_ARGS__)
-#define TE_TOSTR_CASE10(a,...) TE_TOSTR_CASE a TE_TOSTR_CASE9(__VA_ARGS__)
// "tag_from_str" internals
#define TE_FROMSTR_CASE(tag,_) else if(str == #tag) return tag;/*
*/
-#define TE_FROMSTR_CASE2(a,b) TE_FROMSTR_CASE a TE_FROMSTR_CASE b
-#define TE_FROMSTR_CASE3(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE2(__VA_ARGS__)
-#define TE_FROMSTR_CASE4(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE3(__VA_ARGS__)
-#define TE_FROMSTR_CASE5(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE4(__VA_ARGS__)
-#define TE_FROMSTR_CASE6(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE5(__VA_ARGS__)
-#define TE_FROMSTR_CASE7(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE6(__VA_ARGS__)
-#define TE_FROMSTR_CASE8(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE7(__VA_ARGS__)
-#define TE_FROMSTR_CASE9(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE8(__VA_ARGS__)
-#define TE_FROMSTR_CASE10(a,...) TE_FROMSTR_CASE a TE_FROMSTR_CASE9(__VA_ARGS__)
-// Macro to obtain a numbered macro for argument counts
-#define TE_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,COUNT,...) SUF##COUNT
-#define TE_GM(SUF,...) TE_GM_I(SUF,__VA_ARGS__,10,9,8,7,6,5,4,3,2,x)
-//#define TE_GMx(SUF,...) TE_GM_I(SUF,__VA_ARGS__,x,x,x,x,x,x,2)
-
-#define MAXS(...) TE_GM(MAXS ,__VA_ARGS__)(__VA_ARGS__)
-#define TE_CONSS(...) TE_GM(TE_CONS ,__VA_ARGS__)(__VA_ARGS__)
-#define TE_TYPEDEFS(...) TE_GM(TE_TYPEDEF ,__VA_ARGS__)(__VA_ARGS__)
-#define TE_TAGS(...) TE_GM(TE_TAG ,__VA_ARGS__)(__VA_ARGS__)
-#define TE_DEST_CASES(...) TE_GM(TE_DEST_CASE,__VA_ARGS__)(__VA_ARGS__)
-#define TE_MOVE_CASES(...) TE_GM(TE_MOVE_CASE,__VA_ARGS__)(__VA_ARGS__)
-#define TE_TOSTR_CASES(...) TE_GM(TE_TOSTR_CASE ,__VA_ARGS__)(__VA_ARGS__)
-#define TE_FROMSTR_CASES(...) TE_GM(TE_FROMSTR_CASE,__VA_ARGS__)(__VA_ARGS__)
+#define MAXS(...) TE_GM(MAXS,__VA_ARGS__)(__VA_ARGS__)
+#define TE_CONSS(...) TE_GMX(__VA_ARGS__)(TE_CONS , __VA_ARGS__)
+#define TE_TYPEDEFS(...) TE_GMX(__VA_ARGS__)(TE_TYPEDEF ,__VA_ARGS__)
+#define TE_TAGS(...) TE_GMX(__VA_ARGS__)(TE_TAG ,__VA_ARGS__)
+#define TE_DEST_CASES(...) TE_GMX(__VA_ARGS__)(TE_DEST_CASE,__VA_ARGS__)
+#define TE_MOVE_CASES(...) TE_GMX(__VA_ARGS__)(TE_MOVE_CASE,__VA_ARGS__)
+#define TE_TOSTR_CASES(...) TE_GMX(__VA_ARGS__)(TE_TOSTR_CASE ,__VA_ARGS__)
+#define TE_FROMSTR_CASES(...) TE_GMX(__VA_ARGS__)(TE_FROMSTR_CASE,__VA_ARGS__)
#define TAGGED_ENUM(_name, _def, ...) \
class _name { \
@@ -175,3 +138,6 @@ class _name { \
Range, struct { ::std::unique_ptr<ExprNode> left; ::std::unique_ptr<ExprNode> right; }
) m_contents;
*/
+
+#endif
+
diff --git a/src/main.cpp b/src/main.cpp
index 710b7e89..6515685a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,12 +20,11 @@ int g_debug_indent_level = 0;
bool debug_enabled()
{
-
- return true;
+ return true;
}
::std::ostream& debug_output(int indent, const char* function)
{
- return ::std::cout << g_cur_phase << "- " << RepeatLitStr { " ", indent } << function << ": ";
+ return ::std::cout << g_cur_phase << "- " << RepeatLitStr { " ", indent } << function << ": ";
}
struct ProgramParams
@@ -84,17 +83,19 @@ int main(int argc, char *argv[])
// XXX: Dump crate before resolve
CompilePhaseV("Temp output - Parsed", [&]() {
- Dump_Rust( FMT(params.outfile << ".rs").c_str(), crate );
+ Dump_Rust( FMT(params.outfile << "_0_pp.rs").c_str(), crate );
});
// Resolve names to be absolute names (include references to the relevant struct/global/function)
+ // - This does name checking on types and free functions.
+ // - Resolves all identifiers/paths to references
CompilePhaseV("Resolve", [&]() {
ResolvePaths(crate);
});
// XXX: Dump crate before typecheck
CompilePhaseV("Temp output - Resolved", [&]() {
- Dump_Rust( FMT(params.outfile << ".rs").c_str(), crate );
+ Dump_Rust( FMT(params.outfile << "_1_res.rs").c_str(), crate );
});
// Replace type aliases (`type`) into the actual type
@@ -102,6 +103,9 @@ int main(int argc, char *argv[])
//
});
+ // Perform type checking on items
+
+ //
// Typecheck / type propagate module (type annotations of all values)
// - Check all generic conditions (ensure referenced trait is valid)
// > Also mark parameter with applicable traits
diff --git a/src/types.cpp b/src/types.cpp
index 25c2f159..9924ff0f 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -34,41 +34,59 @@ const char* coretype_name(const eCoreType ct ) {
return "NFI";
}
+Type_Function::Type_Function(const Type_Function& other):
+ is_unsafe(other.is_unsafe),
+ m_abi(other.m_abi),
+ m_rettype( box$( TypeRef(*other.m_rettype) ) ),
+ m_arg_types(other.m_arg_types)
+{
+}
+
+Ordering Type_Function::ord(const Type_Function& x) const
+{
+ Ordering rv;
+
+ rv = ::ord(m_abi, x.m_abi);
+ if(rv != OrdEqual) return rv;
+ rv = ::ord(m_arg_types, x.m_arg_types);
+ if(rv != OrdEqual) return rv;
+ return (*m_rettype).ord( *x.m_rettype );
+}
+
/// Replace this type reference with a dereferenced version
bool TypeRef::deref(bool is_implicit)
{
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
- throw ::std::runtime_error("Dereferencing ! - bugcheck");
- case TypeRef::ANY:
- // TODO: Check if the _ is bounded by Deref<Output=?>, if so use that
- throw ::std::runtime_error("Dereferencing _");
- break;
- case TypeRef::UNIT:
- throw ::std::runtime_error("Dereferencing ()");
- case TypeRef::PRIMITIVE:
- throw ::std::runtime_error("Dereferencing a primtive type");
- case TypeRef::GENERIC:
- throw ::std::runtime_error("Dereferencing a generic");
- case TypeRef::FUNCTION:
- throw ::std::runtime_error("Dereferencing a function");
- case TypeRef::REFERENCE:
- *this = m_inner_types[0];
+ case TypeData::None: throw ::std::runtime_error("Dereferencing ! - bugcheck");
+ case TypeData::Any: throw ::std::runtime_error("Dereferencing _");
+ case TypeData::Unit: throw ::std::runtime_error("Dereferencing ()");
+ case TypeData::Primitive: throw ::std::runtime_error("Dereferencing a primtive type");
+ case TypeData::Function: throw ::std::runtime_error("Dereferencing a function");
+
+ case TypeData::Generic:
+ // TODO: Check for Deref<Output=?> bound
+ throw ::std::runtime_error("TODO: Check for a Deref bound on generic");
+ _(Borrow,
+ *this = *ent.inner;
return true;
- case TypeRef::POINTER:
+ )
+ _(Pointer,
// raw pointers can't be implicitly dereferenced
if( is_implicit )
return false;
- *this = m_inner_types[0];
+ *this = *ent.inner;
return true;
- case TypeRef::TUPLE:
- case TypeRef::ARRAY:
- case TypeRef::PATH:
+ )
+ case TypeData::Tuple:
+ case TypeData::Array:
+ case TypeData::Path:
throw ::std::runtime_error("TODO: Search for an impl of Deref");
- case TypeRef::MULTIDST:
+ case TypeData::TraitObject:
throw ::std::runtime_error("TODO: TypeRef::deref on MULTIDST");
}
+ #undef _
throw ::std::runtime_error("BUGCHECK: Fell off end of TypeRef::deref");
}
@@ -84,15 +102,15 @@ void TypeRef::merge_with(const TypeRef& other)
//}
// If this is a wildcard, then replace with the other type
- if( m_class == TypeRef::ANY ) {
- if( m_inner_types.size() && m_inner_types.size() != other.m_inner_types.size() )
- throw ::std::runtime_error("TypeRef::merge_with - Handle bounded wildcards");
+ if( m_data.is_Any() ) {
+ //if( m_inner_types.size() && m_inner_types.size() != other.m_inner_types.size() )
+ // throw ::std::runtime_error("TypeRef::merge_with - Handle bounded wildcards");
*this = other;
return;
}
// If classes don't match, then merge is impossible
- if( m_class != other.m_class )
+ if( m_data.tag() != other.m_data.tag() )
throw ::std::runtime_error("TypeRef::merge_with - Types not compatible");
// If both types are concrete, then they must be the same
@@ -102,45 +120,66 @@ void TypeRef::merge_with(const TypeRef& other)
throw ::std::runtime_error("TypeRef::merge_with - Types not compatible");
return;
}
-
- switch(m_class)
+
+ #define _(VAR, ...) case TypeData::VAR: { auto &ent = m_data.as_##VAR(); (void)&ent; const auto &other_ent = other.m_data.as_##VAR(); (void)&other_ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
- case TypeRef::ANY:
- case TypeRef::UNIT:
- case TypeRef::PRIMITIVE:
+ _(None,
throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard");
- case TypeRef::FUNCTION:
- if( m_inner_types.size() != other.m_inner_types.size() )
+ )
+ _(Any,
+ throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard");
+ )
+ _(Unit,
+ throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard");
+ )
+ _(Primitive,
+ throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard");
+ )
+ _(Function,
+ ent.info.m_rettype->merge_with( *other_ent.info.m_rettype );
+
+ if( ent.info.m_arg_types.size() != other_ent.info.m_arg_types.size() )
throw ::std::runtime_error("TypeRef::merge_with - Types not compatible [function sz]");
- // - fall through to tuple code
- case TypeRef::TUPLE:
+ for(unsigned int i = 0; i < ent.info.m_arg_types.size(); i ++)
+ {
+ ent.info.m_arg_types[i].merge_with( other_ent.info.m_arg_types[i] );
+ }
+ )
+ _(Tuple,
// Other is known not to be wildcard, and is also a tuple, so it must be the same size
- if( m_inner_types.size() != other.m_inner_types.size() )
+ if( ent.inner_types.size() != other_ent.inner_types.size() )
throw ::std::runtime_error("TypeRef::merge_with - Types not compatible [tuple sz]");
- for(unsigned int i = 0; i < m_inner_types.size(); i ++)
+ for(unsigned int i = 0; i < ent.inner_types.size(); i ++)
{
- m_inner_types[i].merge_with( other.m_inner_types[i] );
+ ent.inner_types[i].merge_with( other_ent.inner_types[i] );
}
- break;
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- if( m_is_inner_mutable != other.m_is_inner_mutable )
+ )
+ _(Borrow,
+ if( ent.is_mut != other_ent.is_mut )
throw ::std::runtime_error("TypeRef::merge_with - Types not compatible [inner mut]");
- assert( m_inner_types.size() == 1 );
- assert( other.m_inner_types.size() == 1 );
- m_inner_types[0].merge_with( other.m_inner_types[0] );
- break;
- case TypeRef::ARRAY:
+ ent.inner->merge_with( *other_ent.inner );
+ )
+ _(Pointer,
+ if( ent.is_mut != other_ent.is_mut )
+ throw ::std::runtime_error("TypeRef::merge_with - Types not compatible [inner mut]");
+ ent.inner->merge_with( *other_ent.inner );
+ )
+ _(Array,
throw ::std::runtime_error("TODO: TypeRef::merge_with on ARRAY");
- case TypeRef::GENERIC:
+ )
+ _(Generic,
throw ::std::runtime_error("TODO: TypeRef::merge_with on GENERIC");
- case TypeRef::PATH:
+ )
+ _(Path,
throw ::std::runtime_error("TODO: TypeRef::merge_with on PATH");
- case TypeRef::MULTIDST:
+ )
+ _(TraitObject,
throw ::std::runtime_error("TODO: TypeRef::merge_with on MULTIDST");
+ )
}
+ #undef _
}
/// Resolve all Generic/Argument types to the value returned by the passed closure
@@ -150,35 +189,46 @@ void TypeRef::merge_with(const TypeRef& other)
void TypeRef::resolve_args(::std::function<TypeRef(const char*)> fcn)
{
DEBUG("" << *this);
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
+ _(None,
throw ::std::runtime_error("TypeRef::resolve_args on !");
- case TypeRef::ANY:
- // TODO: Is resolving args on an ANY an erorr?
- break;
- case TypeRef::UNIT:
- case TypeRef::PRIMITIVE:
- break;
- case TypeRef::FUNCTION:
- case TypeRef::TUPLE:
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- case TypeRef::ARRAY:
- for( auto& t : m_inner_types )
+ )
+ // TODO: Is resolving args on an ANY an erorr?
+ _(Any)
+ _(Unit)
+ _(Primitive)
+ _(Function,
+ ent.info.m_rettype->resolve_args(fcn);
+ for( auto& t : ent.info.m_arg_types )
t.resolve_args(fcn);
- break;
- case TypeRef::GENERIC:
- *this = fcn(m_path[0].name().c_str());
- break;
- case TypeRef::PATH:
- m_path.resolve_args(fcn);
- break;
- case TypeRef::MULTIDST:
- for(auto& t : m_inner_types )
+ )
+ _(Tuple,
+ for( auto& t : ent.inner_types )
t.resolve_args(fcn);
- break;
+ )
+ _(Borrow,
+ ent.inner->resolve_args(fcn);
+ )
+ _(Pointer,
+ ent.inner->resolve_args(fcn);
+ )
+ _(Array,
+ ent.inner->resolve_args(fcn);
+ )
+ _(Generic,
+ *this = fcn(ent.name.c_str());
+ )
+ _(Path,
+ ent.path.resolve_args(fcn);
+ )
+ _(TraitObject,
+ for( auto& p : ent.traits )
+ p.resolve_args(fcn);
+ )
}
+ #undef _
}
/// Match this type against another type, calling the provided function for all generics found in this
@@ -189,119 +239,135 @@ void TypeRef::resolve_args(::std::function<TypeRef(const char*)> fcn)
void TypeRef::match_args(const TypeRef& other, ::std::function<void(const char*,const TypeRef&)> fcn) const
{
// If this type is a generic, then call the closure with the other type
- if( m_class == TypeRef::GENERIC ) {
- fcn( m_path[0].name().c_str(), other );
+ if( m_data.tag() == TypeData::Generic ) {
+ fcn( m_data.as_Generic().name.c_str(), other );
return ;
}
// If the other type is a wildcard, early return
// - TODO - Might want to restrict the other type to be of the same form as this type
- if( other.m_class == TypeRef::ANY )
+ if( other.m_data.tag() == TypeData::Any )
return;
DEBUG("this = " << *this << ", other = " << other);
// Any other case, it's a "pattern" match
- if( m_class != other.m_class )
+ if( m_data.tag() != other.m_data.tag() )
throw ::std::runtime_error("Type mismatch (class)");
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = m_data.as_##VAR(); const auto &other_ent = other.m_data.as_##VAR(); (void)&ent; (void)&other_ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
+ _(None,
throw ::std::runtime_error("TypeRef::match_args on !");
- case TypeRef::ANY:
+ )
+ _(Any,
// Wait, isn't this an error?
throw ::std::runtime_error("Encountered '_' in match_args");
- case TypeRef::UNIT:
- break;
- case TypeRef::PRIMITIVE:
+ )
+ _(Unit)
+ _(Primitive,
// TODO: Should check if the type matches
- if( m_core_type != other.m_core_type )
+ if( ent.core_type != other_ent.core_type )
throw ::std::runtime_error("Type mismatch (core)");
- break;
- case TypeRef::FUNCTION:
- if( m_path[0].name() != other.m_path[0].name() )
- throw ::std::runtime_error("Type mismatch (function abo)");
- if( m_inner_types.size() != other.m_inner_types.size() )
+ )
+ _(Function,
+ if( ent.info.m_abi != other_ent.info.m_abi )
+ throw ::std::runtime_error("Type mismatch (function abi)");
+ ent.info.m_rettype->match_args( *other_ent.info.m_rettype, fcn );
+
+ if( ent.info.m_arg_types.size() != other_ent.info.m_arg_types.size() )
throw ::std::runtime_error("Type mismatch (function size)");
- case TypeRef::TUPLE:
- if( m_inner_types.size() != other.m_inner_types.size() )
+ for(unsigned int i = 0; i < ent.info.m_arg_types.size(); i ++ )
+ ent.info.m_arg_types[i].match_args( other_ent.info.m_arg_types[i], fcn );
+ )
+ _(Tuple,
+ if( ent.inner_types.size() != other_ent.inner_types.size() )
throw ::std::runtime_error("Type mismatch (tuple size)");
- for(unsigned int i = 0; i < m_inner_types.size(); i ++ )
- m_inner_types[i].match_args( other.m_inner_types[i], fcn );
- break;
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- if( m_is_inner_mutable != other.m_is_inner_mutable )
+ for(unsigned int i = 0; i < ent.inner_types.size(); i ++ )
+ ent.inner_types[i].match_args( other_ent.inner_types[i], fcn );
+ )
+ _(Borrow,
+ if( ent.is_mut != other_ent.is_mut )
throw ::std::runtime_error("Type mismatch (inner mutable)");
- m_inner_types[0].match_args( other.m_inner_types[0], fcn );
- break;
- case TypeRef::ARRAY:
- m_inner_types[0].match_args( other.m_inner_types[0], fcn );
- if(m_size_expr.get())
+ ent.inner->match_args( *other_ent.inner, fcn );
+ )
+ _(Pointer,
+ if( ent.is_mut != other_ent.is_mut )
+ throw ::std::runtime_error("Type mismatch (inner mutable)");
+ ent.inner->match_args( *other_ent.inner, fcn );
+ )
+ _(Array,
+ ent.inner->match_args( *other_ent.inner, fcn );
+ if(ent.size.get() || other_ent.size.get())
{
throw ::std::runtime_error("TODO: Sized array match_args");
}
- break;
- case TypeRef::GENERIC:
+ )
+ _(Generic,
throw ::std::runtime_error("Encountered GENERIC in match_args");
- case TypeRef::PATH:
- m_path.match_args(other.m_path, fcn);
- break;
- case TypeRef::MULTIDST:
+ )
+ _(Path,
+ ent.path.match_args(other_ent.path, fcn);
+ )
+ _(TraitObject,
throw ::std::runtime_error("TODO: TypeRef::match_args on MULTIDST");
+ )
}
+ #undef _
}
bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) const
{
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
+ _(None,
throw CompileError::BugCheck("TypeRef::impls_wildcard on !");
- case TypeRef::ANY:
+ )
+ _(Any,
throw CompileError::BugCheck("TypeRef::impls_wildcard on _");
+ )
// Generics are an error?
- case GENERIC:
+ _(Generic,
// TODO: Include an annotation to the TypeParams structure relevant to this type
// - Allows searching the params for the impl, without having to pass the params down
throw CompileError::Todo("TypeRef::impls_wildcard - param");
+ )
// Primitives always impl
- case UNIT:
- case PRIMITIVE:
- return true;
+ _(Unit, return true; )
+ _(Primitive, return true; )
// Functions are pointers (currently), so they implement the trait
- case FUNCTION:
- return true;
+ _(Function, return true; )
// Pointers/arrays inherit directly
- case REFERENCE:
- return crate.find_impl(trait, sub_types()[0], nullptr, nullptr);
- case POINTER:
- return crate.find_impl(trait, sub_types()[0], nullptr, nullptr);
- case ARRAY:
- return crate.find_impl(trait, sub_types()[0], nullptr, nullptr);
+ _(Borrow,
+ return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
+ )
+ _(Pointer,
+ return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
+ )
+ _(Array,
+ return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
+ )
// Tuples just destructure
- case TUPLE:
- for( const auto& fld : sub_types() )
+ _(Tuple,
+ for( const auto& fld : ent.inner_types )
{
if( !crate.find_impl(trait, fld, nullptr, nullptr) )
return false;
}
return true;
- // MultiDST is special - It only impls if this trait is in the list
- // (or if a listed trait requires/impls the trait)
- case MULTIDST:
- throw CompileError::Todo("TypeRef::impls_wildcard - MULTIDST");
+ )
// Path types destructure
- case PATH:
+ _(Path,
// - structs need all fields to impl this trait (cache result)
// - same for enums, tuples, arrays, pointers...
// - traits check the Self bounds
// CATCH: Need to handle recursion, keep a list of currently processing paths and assume true if found
- switch(m_path.binding().type())
+ switch(ent.path.binding().type())
{
case AST::PathBinding::STRUCT: {
- const auto &s = m_path.binding().bound_struct();
- GenericResolveClosure resolve_fn( s.params(), m_path.nodes().back().args() );
+ const auto &s = ent.path.binding().bound_struct();
+ GenericResolveClosure resolve_fn( s.params(), ent.path.nodes().back().args() );
for(const auto& fld : s.fields())
{
TypeRef fld_ty = fld.data;
@@ -313,8 +379,8 @@ bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) co
}
return true; }
case AST::PathBinding::ENUM: {
- const auto& i = m_path.binding().bound_enum();
- GenericResolveClosure resolve_fn( i.params(), m_path.nodes().back().args() );
+ const auto& i = ent.path.binding().bound_enum();
+ GenericResolveClosure resolve_fn( i.params(), ent.path.nodes().back().args() );
for( const auto& var : i.variants() )
{
for( const auto& ty : var.m_sub_types )
@@ -331,138 +397,172 @@ bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) co
default:
throw CompileError::Todo("wildcard impls - auto determine path");
}
+ )
+ // MultiDST is special - It only impls if this trait is in the list
+ // (or if a listed trait requires/impls the trait)
+ _(TraitObject,
+ throw CompileError::Todo("TypeRef::impls_wildcard - MULTIDST");
+ )
}
+ #undef _
throw CompileError::BugCheck("TypeRef::impls_wildcard - Fell off end");
}
/// Checks if the type is fully bounded
bool TypeRef::is_concrete() const
{
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
+ _(None,
throw ::std::runtime_error("TypeRef::is_concrete on !");
- case TypeRef::ANY:
- return false;
- case TypeRef::UNIT:
- case TypeRef::PRIMITIVE:
+ )
+ _(Any, return false;)
+ _(Unit, return true; )
+ _(Primitive, return true; )
+ _(Function,
+ if( not ent.info.m_rettype->is_concrete() )
+ return false;
+ for(const auto& t : ent.info.m_arg_types )
+ if( not t.is_concrete() )
+ return false;
return true;
- case TypeRef::FUNCTION:
- case TypeRef::TUPLE:
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- case TypeRef::ARRAY:
- for(const auto& t : m_inner_types )
+ )
+ _(Tuple,
+ for(const auto& t : ent.inner_types)
if( not t.is_concrete() )
return false;
return true;
- case TypeRef::GENERIC:
+ )
+ _(Borrow,
+ return ent.inner->is_concrete();
+ )
+ _(Pointer,
+ return ent.inner->is_concrete();
+ )
+ _(Array,
+ return ent.inner->is_concrete();
+ )
+ _(Generic,
// Well, I guess a generic param is "concrete"
return true;
- case TypeRef::PATH:
- for(const auto& n : m_path.nodes())
- {
- for(const auto& p : n.args())
- if( not p.is_concrete() )
- return false;
- }
- return true;
- case TypeRef::MULTIDST:
- for(const auto& t : m_inner_types )
- if( not t.is_concrete() )
+ )
+ _(Path,
+ return ent.path.is_concrete();
+ )
+ _(TraitObject,
+ for(const auto& p : ent.traits )
+ if( not p.is_concrete() )
return false;
return true;
+ )
}
+ #undef _
throw ::std::runtime_error( FMT("BUGCHECK - Invalid type class on " << *this) );
}
int TypeRef::equal_no_generic(const TypeRef& x) const
{
//DEBUG(*this << ", " << x);
- if( m_class == TypeRef::GENERIC ) //|| x.m_class == TypeRef::GENERIC )
+ if( m_data.tag() == TypeData::Generic ) //|| x.m_class == TypeRef::GENERIC )
return 1;
- if( m_class != x.m_class ) return -1;
- switch(m_class)
+ if( m_data.tag() != x.m_data.tag() ) return -1;
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = m_data.as_##VAR(); const auto& x_ent = x.m_data.as_##VAR(); (void)&ent; (void)&x_ent; __VA_ARGS__ } break;
+ switch(m_data.tag())
{
- case TypeRef::NONE:
- case TypeRef::UNIT:
+ _(None, return 0;)
+ _(Unit, return 0;)
+ _(Any, return 0;)
+ _(Primitive,
+ if( ent.core_type != x_ent.core_type ) return -1;
return 0;
- case TypeRef::ANY:
- return 0;
- case TypeRef::PRIMITIVE:
- if( m_core_type != x.m_core_type ) return -1;
- return 0;
- case TypeRef::FUNCTION:
- if( m_path[0].name() != x.m_path[0].name() ) return -1;
+ )
+ _(Function,
+ if( ent.info.m_abi != x_ent.info.m_abi ) return -1;
throw CompileError::Todo("TypeRef::equal_no_generic - FUNCTION");
- case TypeRef::PATH:
- return m_path.equal_no_generic( x.m_path );
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- if( m_is_inner_mutable != x.m_is_inner_mutable )
+ )
+ _(Generic,
+ throw CompileError::BugCheck("equal_no_generic - Generic should have been handled above");
+ )
+ _(Path,
+ return ent.path.equal_no_generic( x_ent.path );
+ )
+ _(Borrow,
+ if( ent.is_mut != x_ent.is_mut )
return -1;
- return m_inner_types[0].equal_no_generic( x.m_inner_types[0] );
- case TypeRef::ARRAY:
- if( m_size_expr.get() || x.m_size_expr.get() )
+ return ent.inner->equal_no_generic( *x_ent.inner );
+ )
+ _(Pointer,
+ if( ent.is_mut != x_ent.is_mut )
+ return -1;
+ return ent.inner->equal_no_generic( *x_ent.inner );
+ )
+ _(Array,
+ if( ent.size.get() || x_ent.size.get() )
throw CompileError::Todo("TypeRef::equal_no_generic - sized array");
- return m_inner_types[0].equal_no_generic( x.m_inner_types[0] );
- case TypeRef::TUPLE: {
+ return ent.inner->equal_no_generic( *x_ent.inner );
+ )
+ _(Tuple,
bool fuzzy = false;
- if( m_inner_types.size() != x.m_inner_types.size() )
+ if( ent.inner_types.size() != x_ent.inner_types.size() )
return -1;
- for( unsigned int i = 0; i < m_inner_types.size(); i ++ )
+ for( unsigned int i = 0; i < ent.inner_types.size(); i ++ )
{
- int rv = m_inner_types[i].equal_no_generic( x.m_inner_types[i] );
+ int rv = ent.inner_types[i].equal_no_generic( x_ent.inner_types[i] );
if(rv < 0) return -1;
if(rv > 0) fuzzy = true;
}
- return (fuzzy ? 1 : 0); }
- case TypeRef::MULTIDST:
+ return (fuzzy ? 1 : 0);
+ )
+ _(TraitObject,
throw CompileError::Todo("TypeRef::equal_no_generic - MULTIDST");
- case TypeRef::GENERIC:
- throw CompileError::BugCheck("equal_no_generic - Generic should have been handled above");
+ )
}
+ #undef _
throw CompileError::BugCheck("equal_no_generic - Ran off end");
}
Ordering TypeRef::ord(const TypeRef& x) const
{
Ordering rv;
- rv = ::ord( (unsigned)m_class, (unsigned)x.m_class );
+ rv = ::ord( (unsigned)m_data.tag(), (unsigned)x.m_data.tag() );
if(rv != OrdEqual) return rv;
- switch(m_class)
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = m_data.as_##VAR(); const auto& x_ent = x.m_data.as_##VAR(); (void)&ent; (void)&x_ent; __VA_ARGS__ } break;
+ switch(x.m_data.tag())
{
- case TypeRef::NONE:
- return OrdEqual;
- case TypeRef::ANY:
- case TypeRef::UNIT:
- return OrdEqual;
- case TypeRef::PRIMITIVE:
- rv = ::ord( (unsigned)m_core_type, (unsigned)x.m_core_type );
+ _(None, return OrdEqual;)
+ _(Any, return OrdEqual;)
+ _(Unit, return OrdEqual;)
+ _(Primitive,
+ return ::ord( (unsigned)ent.core_type, (unsigned)x_ent.core_type );
+ )
+ _(Function,
+ return ent.info.ord( x_ent.info );
+ )
+ _(Tuple,
+ return ::ord(ent.inner_types, x_ent.inner_types);
+ )
+ _(Borrow,
+ rv = ::ord(ent.is_mut, x_ent.is_mut);
if(rv != OrdEqual) return rv;
- return OrdEqual;
- case TypeRef::FUNCTION:
- rv = ::ord(m_path[0].name(),x.m_path[0].name());
- if(rv != OrdEqual) return rv;
- return ::ord(m_inner_types, x.m_inner_types);
- case TypeRef::TUPLE:
- return ::ord(m_inner_types, x.m_inner_types);
- //return m_inner_types == x.m_inner_types;
- case TypeRef::REFERENCE:
- case TypeRef::POINTER:
- rv = ::ord(m_is_inner_mutable, x.m_is_inner_mutable);
+ return (*ent.inner).ord(*x_ent.inner);
+ )
+ _(Pointer,
+ rv = ::ord(ent.is_mut, x_ent.is_mut);
if(rv != OrdEqual) return rv;
- return ::ord(m_inner_types, x.m_inner_types);
- case TypeRef::ARRAY:
- rv = m_inner_types[0].ord( x.m_inner_types[0] );
+ return (*ent.inner).ord(*x_ent.inner);
+ )
+ _(Array,
+ rv = (*ent.inner).ord( *x_ent.inner );
if(rv != OrdEqual) return rv;
- if(m_size_expr.get())
+ if(ent.size.get())
{
throw ::std::runtime_error("TODO: Sized array comparisons");
}
return OrdEqual;
- case TypeRef::GENERIC:
+ )
+ _(Generic,
if( m_tagged_ptr != x.m_tagged_ptr )
{
DEBUG(*this << " == " << x);
@@ -472,13 +572,17 @@ Ordering TypeRef::ord(const TypeRef& x) const
}
else {
}
- return m_path.ord( x.m_path );
- case TypeRef::PATH:
- return m_path.ord( x.m_path );
- case TypeRef::MULTIDST:
- return ::ord(m_inner_types, x.m_inner_types);
+ return ::ord(ent.name, x_ent.name);
+ )
+ _(Path,
+ return ent.path.ord( x_ent.path );
+ )
+ _(TraitObject,
+ return ::ord(ent.traits, x_ent.traits);
+ )
}
- throw ::std::runtime_error(FMT("BUGCHECK - Unhandled TypeRef class '" << m_class << "'"));
+ #undef _
+ throw ::std::runtime_error(FMT("BUGCHECK - Unhandled TypeRef class '" << m_data.tag() << "'"));
}
::std::ostream& operator<<(::std::ostream& os, const eCoreType ct) {
@@ -487,71 +591,67 @@ Ordering TypeRef::ord(const TypeRef& x) const
::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr) {
//os << "TypeRef(";
- switch(tr.m_class)
+ #define _(VAR, ...) case TypeData::VAR: { const auto &ent = tr.m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+ switch(tr.m_data.tag())
{
- case TypeRef::NONE:
+ _(None,
os << "!";
- break;
- case TypeRef::ANY:
- //os << "TagAny";
+ )
+ _(Any,
os << "_";
- if( tr.m_inner_types.size() ) {
- os << ": " << tr.m_inner_types << "";
- }
- break;
- case TypeRef::UNIT:
- //os << "TagUnit";
+ )
+ _(Unit,
os << "()";
- break;
- case TypeRef::PRIMITIVE:
- //os << "TagPrimitive, " << tr.m_core_type;
- os << tr.m_core_type;
- break;
- case TypeRef::FUNCTION:
- if( tr.m_path[0].name() != "" )
- os << "extern \"" << tr.m_path[0].name() << "\" ";
+ )
+ _(Primitive,
+ os << tr.m_data.as_Primitive().core_type;
+ )
+ _(Function,
+ if( ent.info.m_abi != "" )
+ os << "extern \"" << ent.info.m_abi << "\" ";
os << "fn (";
- for( unsigned int i = 0; i < tr.m_inner_types.size()-1; i ++ )
- os << tr.m_inner_types[i] << ", ";
- os << ") -> " << tr.m_inner_types.back();
- break;
- case TypeRef::TUPLE:
+ for( const auto& arg : ent.info.m_arg_types )
+ os << arg << ", ";
+ os << ") -> " << *ent.info.m_rettype;
+ )
+ _(Tuple,
//os << "TagTuple, {" << tr.m_inner_types << "}";
os << "( ";
- for( const auto& it : tr.m_inner_types )
+ for( const auto& it : ent.inner_types )
os << it << ", ";
os << ")";
- break;
- case TypeRef::REFERENCE:
+ )
+ _(Borrow,
//os << "TagReference, " << (tr.m_is_inner_mutable ? "mut" : "const") << ", " << tr.m_inner_types[0];
- os << "&" << (tr.m_is_inner_mutable ? "mut " : "") << tr.m_inner_types[0];
- break;
- case TypeRef::POINTER:
+ os << "&" << (ent.is_mut ? "mut " : "") << *ent.inner;
+ )
+ _(Pointer,
//os << "TagPointer, " << (tr.m_is_inner_mutable ? "mut" : "const") << ", " << tr.m_inner_types[0];
- os << "*" << (tr.m_is_inner_mutable ? "mut" : "const") << " " << tr.m_inner_types[0];
- break;
- case TypeRef::ARRAY:
- os << "[" << tr.m_inner_types[0];
- if( tr.m_size_expr.get() )
- os << "; " << *tr.m_size_expr;
+ os << "*" << (ent.is_mut ? "mut" : "const") << " " << *ent.inner;
+ )
+ _(Array,
+ os << "[" << *ent.inner;
+ if( ent.size.get() )
+ os << "; " << *ent.size;
os << "]";
- break;
- case TypeRef::GENERIC:
- os << "/* arg */ " << tr.m_path[0].name();
- break;
- case TypeRef::PATH:
- os << tr.m_path;
- break;
- case TypeRef::MULTIDST:
+ )
+ _(Generic,
+ os << "/* arg */ " << ent.name << "/*"<<ent.level<<"*/";
+ )
+ _(Path,
+ os << ent.path;
+ )
+ _(TraitObject,
os << "(";
- for( const auto& it : tr.m_inner_types ) {
- if( &it != &tr.m_inner_types.front() )
+ for( const auto& it : ent.traits ) {
+ if( &it != &ent.traits.front() )
os << "+";
os << it;
}
os << ")";
- break;
+ )
}
+ #undef _
//os << ")";
return os;
}
@@ -581,70 +681,114 @@ void operator% (::Deserialiser& d, eCoreType& ct) {
else
throw ::std::runtime_error("Deserialise failure - coretype " + n);
}
-const char* TypeRef::class_name(TypeRef::Class c) {
- switch(c)
- {
- #define _(x) case TypeRef::x: return #x;
- _(NONE)
- _(ANY)
- _(UNIT)
- _(PRIMITIVE)
- _(FUNCTION)
- _(TUPLE)
- _(REFERENCE)
- _(POINTER)
- _(ARRAY)
- _(GENERIC)
- _(PATH)
- _(MULTIDST)
- #undef _
- }
- return "NFI";
+void operator%(Serialiser& s, TypeData::Tag c) {
+ s << TypeData::tag_to_str(c);
}
-void operator>>(::Deserialiser& d, TypeRef::Class& c) {
- ::std::string n;
- d.item(n);
- #define _(x) if(n == #x) c = TypeRef::x;
- /**/ _(ANY)
- else _(NONE)
- else _(UNIT)
- else _(PRIMITIVE)
- else _(FUNCTION)
- else _(TUPLE)
- else _(REFERENCE)
- else _(POINTER)
- else _(ARRAY)
- else _(GENERIC)
- else _(PATH)
- else _(MULTIDST)
- else
- throw ::std::runtime_error("Deserialise failure - " + n);
- #undef _
+void operator%(::Deserialiser& s, TypeData::Tag& c) {
+ ::std::string n;
+ s.item(n);
+ c = TypeData::tag_from_str(n);
+}
+
+::std::unique_ptr<TypeRef> TypeRef::from_deserialiser(Deserialiser& s) {
+ TypeRef n;
+ n.deserialise(s);
+ return box$(n);
}
+
+#define _S(VAR, ...) case TypeData::VAR: { const auto& ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+#define _D(VAR, ...) case TypeData::VAR: { m_data = TypeData::make_null_##VAR(); auto& ent = m_data.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
SERIALISE_TYPE(TypeRef::, "TypeRef", {
- s << class_name(m_class);
- if(m_class == PRIMITIVE)
- s << coretype_name(m_core_type);
- s << m_inner_types;
- if(m_class == REFERENCE || m_class == POINTER)
- s << m_is_inner_mutable;
- s << m_size_expr;
- s << m_path;
+ s % m_data.tag();
+ switch(m_data.tag())
+ {
+ _S(None)
+ _S(Any)
+ _S(Unit)
+ _S(Primitive,
+ s << coretype_name(ent.core_type);
+ )
+ _S(Function,
+ s.item( ent.info );
+ )
+ _S(Tuple,
+ s.item( ent.inner_types );
+ )
+ _S(Borrow,
+ s.item( ent.is_mut );
+ s.item( ent.inner );
+ )
+ _S(Pointer,
+ s.item( ent.is_mut );
+ s.item( ent.inner );
+ )
+ _S(Generic,
+ s.item( ent.name );
+ s.item( ent.level );
+ )
+ _S(Array,
+ s.item( ent.inner );
+ bool size_present = (ent.size.get() != 0);
+ s.item( size_present );
+ if(ent.size.get()) {
+ s.item( ent.size );
+ }
+ )
+ _S(Path,
+ s.item( ent.path );
+ )
+ _S(TraitObject,
+ s.item( ent.traits );
+ )
+ }
},{
- s >> m_class;
- if(m_class == PRIMITIVE)
- s % m_core_type;
- s.item( m_inner_types );
- if(m_class == REFERENCE || m_class == POINTER)
- s.item( m_is_inner_mutable );
- bool size_expr_present;
- s.item(size_expr_present);
- if( size_expr_present )
- m_size_expr = AST::ExprNode::from_deserialiser(s);
- else
- m_size_expr.reset();
- s.item( m_path );
+ TypeData::Tag tag;
+ s % tag;
+ switch(tag)
+ {
+ _D(None)
+ _D(Any)
+ _D(Unit)
+ _D(Primitive,
+ s % ent.core_type;
+ )
+ _D(Function,
+ s.item( ent.info );
+ )
+ _D(Tuple,
+ s.item( ent.inner_types );
+ )
+ _D(Borrow,
+ s.item( ent.is_mut );
+ s.item( ent.inner );
+ )
+ _D(Pointer,
+ s.item( ent.is_mut );
+ s.item( ent.inner );
+ )
+ _D(Generic,
+ s.item( ent.name );
+ s.item( ent.level );
+ )
+ _D(Array,
+ s.item( ent.inner );
+ bool size_present;
+ s.item( size_present );
+ if( size_present )
+ ent.size = AST::ExprNode::from_deserialiser(s);
+ else
+ ent.size.reset();
+ )
+ _D(Path,
+ s.item( ent.path );
+ )
+ _D(TraitObject,
+ s.item( ent.traits );
+ )
+ }
})
+#undef _D
+#undef _S
void PrettyPrintType::print(::std::ostream& os) const
diff --git a/src/types.hpp b/src/types.hpp
index 997031de..8e869f19 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -13,17 +13,6 @@ class ExprNode;
class Expr;
}
-/// Representation of restrictions placed on a type before it is made concrete
-// Possible bounds:
-// - Known to be a tuple of various inner types
-// - Unknown struct / enum
-// - Impls a trait
-// - Unknown
-class TypeBounds
-{
-
-};
-
class PrettyPrintType
{
const TypeRef& m_type;
@@ -37,117 +26,168 @@ public:
friend ::std::ostream& operator<<(::std::ostream& os, const PrettyPrintType& v);
};
+struct TypeArgRef
+{
+ ::std::string name;
+ unsigned int level;
+ const AST::TypeParams* params;
+};
+
+struct Type_Function:
+ public Serialisable
+{
+ bool is_unsafe;
+ ::std::string m_abi;
+ ::std::unique_ptr<TypeRef> m_rettype;
+ ::std::vector<TypeRef> m_arg_types;
+
+ Type_Function() {}
+ Type_Function(bool is_unsafe, ::std::string abi, ::std::unique_ptr<TypeRef> ret, ::std::vector<TypeRef> args):
+ is_unsafe(is_unsafe),
+ m_abi(abi),
+ m_rettype(mv$(ret)),
+ m_arg_types(mv$(args))
+ {}
+ Type_Function(const Type_Function& other);
+
+ Ordering ord(const Type_Function& x) const;
+
+ SERIALISABLE_PROTOTYPES();
+};
+
+TAGGED_ENUM(TypeData, None,
+ (None, ()),
+ (Any, ()),
+ (Unit, ()),
+ (Primitive, (
+ enum eCoreType core_type;
+ )),
+ (Function, (
+ Type_Function info;
+ )),
+ (Tuple, (
+ ::std::vector<TypeRef> inner_types;
+ )),
+ (Borrow, (
+ bool is_mut;
+ ::std::unique_ptr<TypeRef> inner;
+ )),
+ (Pointer, (
+ bool is_mut;
+ ::std::unique_ptr<TypeRef> inner;
+ )),
+ (Array, (
+ ::std::unique_ptr<TypeRef> inner;
+ ::std::shared_ptr<AST::ExprNode> size;
+ )),
+ (Generic, (
+ ::std::string name;
+ unsigned int level;
+ const AST::TypeParams* params;
+ )),
+ (Path, (
+ AST::Path path;
+ )),
+ (TraitObject, (
+ ::std::vector<AST::Path> traits;
+ ))
+ );
+
/// A type
class TypeRef:
public Serialisable
{
- /// Class
- enum Class {
- NONE,
- ANY, //< '_' - Wildcard
- //BOUNDED, //< '_: Traits' - Bounded type (a resolved type parameter usually)
- UNIT, //< '()' - Unit / void
- PRIMITIVE, //< Any primitive (builtin type)
- FUNCTION,
- TUPLE,
- REFERENCE,
- POINTER,
- ARRAY,
- GENERIC,
- PATH,
- MULTIDST, // Multi-trait DST (e.g. Trait + Send + Sync)
- };
-
- Class m_class;
- enum eCoreType m_core_type;
- bool m_is_inner_mutable;
-
- AST::Path m_path; // local = argument
- ::std::vector<TypeRef> m_inner_types;
- ::std::shared_ptr<AST::ExprNode> m_size_expr; //< Can be null (unsized array)
+ TypeData m_data;
/// A generic pointer, used for tagging with extra information
/// e.g. The source TypeParams for GENERIC
const void* m_tagged_ptr;
public:
+ TypeRef(TypeRef&& other) noexcept:
+ m_data( mv$(other.m_data) )
+ {}
+
+ TypeRef(const TypeRef& other)
+ {
+ switch( other.m_data.tag() )
+ {
+ #define _COPY(VAR) case TypeData::VAR: m_data = TypeData::make_##VAR(other.m_data.as_##VAR()); break;
+ #define _CLONE(VAR, code...) case TypeData::VAR: { auto& old = other.m_data.as_##VAR(); m_data = TypeData::make_##VAR(code); } break;
+ _COPY(None)
+ _COPY(Any)
+ _COPY(Unit)
+ _COPY(Primitive)
+ _COPY(Function)
+ _COPY(Tuple)
+ _CLONE(Borrow, { old.is_mut, box$(TypeRef(*old.inner)) })
+ _CLONE(Pointer, { old.is_mut, box$(TypeRef(*old.inner)) })
+ _CLONE(Array, { box$(TypeRef(*old.inner)), old.size })
+ _COPY(Generic)
+ _COPY(Path)
+ _COPY(TraitObject)
+ #undef _COPY
+ #undef _CLONE
+ }
+ }
+ TypeRef& operator=(const TypeRef& other) {
+ *this = TypeRef(other);
+ return *this;
+ }
+
TypeRef():
- m_class(ANY)
+ m_data(TypeData::make_Any({}))
{}
struct TagInvalid {};
TypeRef(TagInvalid):
- m_class(NONE)
- {}
-
- struct TagBoundedAny {};
- TypeRef(TagBoundedAny, ::std::vector<TypeRef> traits):
- m_class(ANY),
- m_inner_types( ::std::move(traits) )
+ m_data(TypeData::make_None({}))
{}
struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
TypeRef(TagUnit):
- m_class(UNIT)
+ m_data(TypeData::make_Unit({}))
{}
struct TagPrimitive {};
TypeRef(TagPrimitive, enum eCoreType type):
- m_class(PRIMITIVE),
- m_core_type(type)
+ m_data(TypeData::make_Primitive({type}))
{}
TypeRef(enum eCoreType type):
- m_class(PRIMITIVE),
- m_core_type(type)
+ m_data(TypeData::make_Primitive({type}))
{}
struct TagTuple {};
TypeRef(TagTuple _, ::std::vector<TypeRef> inner_types):
- m_class(TUPLE),
- m_inner_types( ::std::move(inner_types) )
+ m_data(TypeData::make_Tuple({::std::move(inner_types)}))
{}
struct TagFunction {};
TypeRef(TagFunction, ::std::string abi, ::std::vector<TypeRef> args, TypeRef ret):
- m_class(FUNCTION),
- m_path( {AST::PathNode( ::std::move(abi), {})} ), // abuse path for string
- m_inner_types( ::std::move(args) )
- {
- m_inner_types.push_back( ::std::move(ret) );
- }
+ m_data(TypeData::make_Function({ Type_Function( false, abi, box$(ret), mv$(args) ) }))
+ {}
struct TagReference {};
TypeRef(TagReference _, bool is_mut, TypeRef inner_type):
- m_class(REFERENCE),
- m_is_inner_mutable(is_mut),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Borrow({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagPointer {};
TypeRef(TagPointer _, bool is_mut, TypeRef inner_type):
- m_class(POINTER),
- m_is_inner_mutable(is_mut),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Pointer({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagSizedArray {};
TypeRef(TagSizedArray _, TypeRef inner_type, ::std::shared_ptr<AST::ExprNode> size):
- m_class(ARRAY),
- m_inner_types({::std::move(inner_type)}),
- m_size_expr( ::std::move(size) )
+ m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), mv$(size) }))
{}
struct TagUnsizedArray {};
TypeRef(TagUnsizedArray _, TypeRef inner_type):
- m_class(ARRAY),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), ::std::shared_ptr<AST::ExprNode>() }))
{}
struct TagArg {};
TypeRef(TagArg, ::std::string name):
- m_class(GENERIC),
- m_path( ::std::move(name) ),
- m_tagged_ptr(nullptr)
+ m_data(TypeData::make_Generic({ name, 0, nullptr }))
{}
TypeRef(TagArg, ::std::string name, const AST::TypeParams& params):
- m_class(GENERIC),
- m_path( ::std::move(name) ),
- m_tagged_ptr(&params)
+ m_data(TypeData::make_Generic({ name, 0, &params }))
{}
TypeRef(::std::string name):
TypeRef(TagArg(), ::std::move(name))
@@ -155,19 +195,15 @@ public:
struct TagPath {};
TypeRef(TagPath, AST::Path path):
- m_class(PATH),
- m_path( ::std::move(path) )
+ m_data(TypeData::make_Path({ ::std::move(path) }))
{}
TypeRef(AST::Path path):
TypeRef(TagPath(), ::std::move(path))
{}
TypeRef( ::std::vector<AST::Path> traits ):
- m_class(MULTIDST)
- {
- for( auto& t : traits )
- m_inner_types.push_back( TypeRef(::std::move(t)) );
- }
+ m_data(TypeData::make_TraitObject({ ::std::move(traits) }))
+ {}
/// Dereference the type (return the result of *type_instance)
bool deref(bool is_implicit);
@@ -183,33 +219,33 @@ public:
/// Returns true if the type is fully known (all sub-types are not wildcards)
bool is_concrete() const;
- bool is_unbounded() const { return m_class == ANY && m_inner_types.size() == 0; }
- bool is_wildcard() const { return m_class == ANY; }
+ bool is_unbounded() const { return m_data.is_Any(); }
+ bool is_wildcard() const { return m_data.is_Any(); }
- bool is_unit() const { return m_class == UNIT; }
- bool is_primitive() const { return m_class == PRIMITIVE; }
+ bool is_unit() const { return m_data.is_Unit(); }
+ bool is_primitive() const { return m_data.is_Primitive(); }
- bool is_path() const { return m_class == PATH; }
- const AST::Path& path() const { assert(is_path()); return m_path; }
- AST::Path& path() { assert(is_path()); return m_path; }
+ bool is_path() const { return m_data.is_Path(); }
+ const AST::Path& path() const { return m_data.as_Path().path; }
+ AST::Path& path() { return m_data.as_Path().path; }
- bool is_type_param() const { return m_class == GENERIC; }
- const ::std::string& type_param() const { assert(is_type_param()); return m_path[0].name(); }
+ bool is_type_param() const { return m_data.is_Generic(); }
+ const ::std::string& type_param() const { return m_data.as_Generic().name; }
void set_type_params_ptr(const AST::TypeParams& p) { assert(is_type_param()); m_tagged_ptr = &p; };
const AST::TypeParams* type_params_ptr() const {
assert(is_type_param());
return reinterpret_cast<const AST::TypeParams*>(m_tagged_ptr);
}
- bool is_reference() const { return m_class == REFERENCE; }
- bool is_pointer() const { return m_class == POINTER; }
- bool is_tuple() const { return m_class == TUPLE; }
+ bool is_reference() const { return m_data.is_Borrow(); }
+ bool is_pointer() const { return m_data.is_Pointer(); }
+ bool is_tuple() const { return m_data.is_Tuple(); }
- ::std::vector<TypeRef>& sub_types() { return m_inner_types; }
- const ::std::vector<TypeRef>& sub_types() const { return m_inner_types; }
+ //::std::vector<TypeRef>& sub_types() { return m_inner_types; }
+ //const ::std::vector<TypeRef>& sub_types() const { return m_inner_types; }
- void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
- const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
+ //void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
+ //const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
/// Returns 0 if types are identical, 1 if TypeRef::TagArg is present in one, and -1 if form differs
int equal_no_generic(const TypeRef& x) const;
@@ -224,20 +260,9 @@ public:
friend class PrettyPrintType;
friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr);
-
- static const char* class_name(TypeRef::Class c);
- friend void operator>>(::Deserialiser& d, TypeRef::Class& c);
+ static ::std::unique_ptr<TypeRef> from_deserialiser(Deserialiser& s);
SERIALISABLE_PROTOTYPES();
};
-class Type_Function:
- public Serialisable
-{
- bool is_unsafe;
- ::std::string m_abi;
- TypeRef m_rettype;
- ::std::vector<TypeRef> m_arg_types;
-};
-
#endif // TYPES_HPP_INCLUDED