diff options
Diffstat (limited to 'src')
57 files changed, 612 insertions, 664 deletions
diff --git a/src/ast/generics.hpp b/src/ast/generics.hpp index 2de5aeaa..bc14202e 100644 --- a/src/ast/generics.hpp +++ b/src/ast/generics.hpp @@ -1,3 +1,10 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * ast/generics.hpp + * - AST Generics (type parameters, bounds, ...) + */ #pragma once #include <string> @@ -5,11 +12,10 @@ namespace AST { - class TypeParam { ::std::string m_name; - TypeRef m_default; + ::TypeRef m_default; public: TypeParam(TypeParam&& x) = default; TypeParam& operator=(TypeParam&& x) = default; diff --git a/src/ast/path.cpp b/src/ast/path.cpp index da86b066..ebec5d5a 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -190,18 +190,18 @@ void Path::bind_variable(unsigned int slot) } void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector<TypeRef>& /*args*/) { - unsigned int idx = 0; - for( idx = 0; idx < ent.variants().size(); idx ++ ) - { - if( ent.variants()[idx].m_name == name ) { - break; - } - } - if( idx == ent.variants().size() ) - throw ParseError::Generic("Enum variant not found"); + auto it = ::std::find_if(ent.variants().begin(), ent.variants().end(), [&](const auto& x) { return x.m_name == name; }); + if( it == ent.variants().end() ) + { + throw ParseError::Generic("Enum variant not found"); + } + unsigned int idx = it - ent.variants().begin(); DEBUG("Bound to enum variant '" << name << "' (#" << idx << ")"); - m_binding = PathBinding::make_EnumVar({ &ent, idx }); + ::AST::PathBinding::Data_EnumVar tmp; + tmp.enum_ = &ent; + tmp.idx = idx; + m_binding = PathBinding::make_EnumVar(tmp); } Path& Path::operator+=(const Path& other) diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 7a67b93e..f3a72133 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -48,27 +48,27 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( }), (Module, struct { const Module* module_; - const ::HIR::Module* hir = nullptr; + const ::HIR::Module* hir; }), (Struct, struct { const Struct* struct_; - const ::HIR::Struct* hir = nullptr; + const ::HIR::Struct* hir; }), (Enum, struct { const Enum* enum_; - const ::HIR::Enum* hir = nullptr; + const ::HIR::Enum* hir; }), (Union, struct { const Union* union_; - const ::HIR::Union* hir = nullptr; + const ::HIR::Union* hir; }), (Trait, struct { const Trait* trait_; - const ::HIR::Trait* hir = nullptr; + const ::HIR::Trait* hir; }), (Static, struct { const Static* static_; - const ::HIR::Static* hir = nullptr; // if nullptr and static_ == nullptr, points to a `const` + const ::HIR::Static* hir; // if nullptr and static_ == nullptr, points to a `const` }), (Function, struct { const Function* func_; @@ -76,7 +76,7 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( (EnumVar, struct { const Enum* enum_; unsigned int idx; - const ::HIR::Enum* hir = nullptr; + const ::HIR::Enum* hir; }), (TypeAlias, struct { const TypeAlias* alias_; diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index af6a5adf..583ce351 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -14,6 +14,7 @@ #include <string> #include <tagged_union.hpp> #include <ident.hpp> +#include "path.hpp" namespace AST { diff --git a/src/ast/types.cpp b/src/ast/types.cpp index ccd169d7..d49feccd 100644 --- a/src/ast/types.cpp +++ b/src/ast/types.cpp @@ -118,7 +118,7 @@ TypeRef TypeRef::clone() const { case TypeData::TAGDEAD: assert(!"Copying a destructed type"); #define _COPY(VAR) case TypeData::TAG_##VAR: return TypeRef(m_span, TypeData::make_##VAR(m_data.as_##VAR()) ); break; - #define _CLONE(VAR, code...) case TypeData::TAG_##VAR: { auto& old = m_data.as_##VAR(); return TypeRef(m_span, TypeData::make_##VAR(code) ); } break; + #define _CLONE(VAR, ...) case TypeData::TAG_##VAR: { auto& old = m_data.as_##VAR(); return TypeRef(m_span, TypeData::make_##VAR(__VA_ARGS__) ); } break; _COPY(None) _COPY(Any) _COPY(Bang) diff --git a/src/ast/types.hpp b/src/ast/types.hpp index e2114bae..314ab828 100644 --- a/src/ast/types.hpp +++ b/src/ast/types.hpp @@ -3,7 +3,7 @@ #include <memory> -#include "common.hpp" +#include "../common.hpp" #include "coretypes.hpp" #include "ast/path.hpp" #include "ast/macro.hpp" diff --git a/src/common.hpp b/src/common.hpp index 1971faa9..55e0f833 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -11,11 +11,15 @@ #include <sstream> #include <memory> +#ifdef _MSC_VER +#define __attribute__(x) +#endif + #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)) +#define box$(...) ::make_unique_ptr(::std::move(__VA_ARGS__)) +#define rc_new$(...) ::make_shared_ptr(::std::move(__VA_ARGS__)) #include "include/debug.hpp" #include "include/rustic.hpp" // slice and option diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index 89503e0c..92afcbb2 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -14,6 +14,7 @@ #include "../parse/interpolated_fragment.hpp" #include <ast/crate.hpp> // for m_load_std #include <ast/expr.hpp> // for ExprNode_* +#include <cctype> namespace { @@ -551,7 +552,7 @@ class CFormatArgsExpander: toks.push_back( Token(TOK_LIFETIME, "static") ); toks.push_back( Token(TOK_IDENT, "str") ); toks.push_back( Token(TOK_SEMICOLON) ); - toks.push_back( Token(fragments.size() + 1, CORETYPE_UINT) ); + toks.push_back( Token(static_cast<uint64_t>(fragments.size() + 1), CORETYPE_UINT) ); toks.push_back( TokenTree(TOK_SQUARE_CLOSE) ); toks.push_back( Token(TOK_EQUAL) ); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 1ee2e19e..01786284 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -15,6 +15,8 @@ #include <ast/expr.hpp> #include "cfg.hpp" +DecoratorDef* g_decorators_list = nullptr; +MacroDef* g_macros_list = nullptr; ::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> > g_decorators; ::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> > g_macros; @@ -24,10 +26,18 @@ void Expand_Expr(::AST::Crate& crate, LList<const AST::Module*> modstack, AST::E void Expand_Expr(::AST::Crate& crate, LList<const AST::Module*> modstack, ::std::shared_ptr<AST::ExprNode>& node); void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler) { - g_decorators[name] = mv$(handler); + g_decorators.insert(::std::make_pair( mv$(name), mv$(handler) )); } void Register_Synext_Macro(::std::string name, ::std::unique_ptr<ExpandProcMacro> handler) { - g_macros[name] = mv$(handler); + g_macros.insert(::std::make_pair( mv$(name), mv$(handler) )); +} +void Register_Synext_Decorator_Static(DecoratorDef* def) { + def->prev = g_decorators_list; + g_decorators_list = def; +} +void Register_Synext_Macro_Static(MacroDef* def) { + def->prev = g_macros_list; + g_macros_list = def; } @@ -1064,6 +1074,18 @@ void Expand_Mod_IndexAnon(::AST::Crate& crate, ::AST::Module& mod) } void Expand(::AST::Crate& crate) { + // Fill macro/decorator map from init list + while(g_decorators_list) + { + g_decorators.insert(::std::make_pair( mv$(g_decorators_list->name), mv$(g_decorators_list->def) )); + g_decorators_list = g_decorators_list->prev; + } + while (g_macros_list) + { + g_macros.insert(::std::make_pair(mv$(g_macros_list->name), mv$(g_macros_list->def))); + g_macros_list = g_macros_list->prev; + } + auto modstack = LList<const ::AST::Module*>(nullptr, &crate.m_root_module); // 1. Crate attributes diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index f4409310..0ff4d63b 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -505,10 +505,10 @@ namespace { ::HIR::Linkage deserialise_linkage() { - return ::HIR::Linkage { - ::HIR::Linkage::Type::Auto, - m_in.read_string(), - }; + ::HIR::Linkage l; + l.type = ::HIR::Linkage::Type::Auto; + l.name = m_in.read_string(); + return l; } // - Value items @@ -708,7 +708,7 @@ namespace { _(Array, { deserialise_ptr< ::HIR::TypeRef>(), nullptr, - m_in.read_u64c() + m_in.read_u64c() & SIZE_MAX }) _(Slice, { deserialise_ptr< ::HIR::TypeRef>() @@ -1003,12 +1003,13 @@ namespace { deserialise_vec< ::std::string>(), deserialise_vec< ::std::string>() }); - case 3: - return ::MIR::Statement::make_SetDropFlag({ - static_cast<unsigned int>(m_in.read_count()), - m_in.read_bool(), - static_cast<unsigned int>(m_in.read_count()) - }); + case 3: { + ::MIR::Statement::Data_SetDropFlag sdf; + sdf.idx = static_cast<unsigned int>(m_in.read_count()); + sdf.new_val = m_in.read_bool(); + sdf.other = static_cast<unsigned int>(m_in.read_count()); + return ::MIR::Statement::make_SetDropFlag(sdf); + } case 4: return ::MIR::Statement::make_ScopeEnd({ deserialise_vec<unsigned int>(), diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp index 8bcffa4e..649116e0 100644 --- a/src/hir/dump.cpp +++ b/src/hir/dump.cpp @@ -261,7 +261,14 @@ namespace { } void visit_constant(::HIR::ItemPath p, ::HIR::Constant& item) override { - m_os << indent() << "const " << p.get_name() << ": " << item.m_type << " = " << item.m_value_res << ";\n"; + m_os << indent() << "const " << p.get_name() << ": " << item.m_type << " = " << item.m_value_res; + if( item.m_value ) + { + m_os << " /*= "; + item.m_value->visit(*this); + m_os << "*/"; + } + m_os << ";\n"; } // - Misc @@ -523,6 +530,7 @@ namespace { m_os << ", "; } m_os << ")"; + m_os << "/* : " << node.m_res_type << " */"; } void visit(::HIR::ExprNode_CallValue& node) override { diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index be823c6b..c0a3151e 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -702,7 +702,8 @@ { if( ptr->m_datatype == CORETYPE_UINT || ptr->m_datatype == CORETYPE_ANY ) { - unsigned int size_val = ptr->m_value; + // TODO: Limit check. + auto size_val = static_cast<unsigned int>( ptr->m_value ); return ::HIR::TypeRef::new_array( mv$(inner), size_val ); } } diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index ea887e6e..66070dc7 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -879,8 +879,8 @@ const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path_opt(const char* name) const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path, bool ignore_crate_name, bool ignore_last_node) const { - ASSERT_BUG(sp, path.m_components.size() > 0, "get_typeitem_by_path received invalid path - " << path); - ASSERT_BUG(sp, path.m_components.size() > (ignore_last_node ? 1 : 0), "get_typeitem_by_path received invalid path - " << path); + ASSERT_BUG(sp, path.m_components.size() > 0u, "get_typeitem_by_path received invalid path - " << path); + ASSERT_BUG(sp, path.m_components.size() > (ignore_last_node ? 1u : 0u), "get_typeitem_by_path received invalid path - " << path); const ::HIR::Module* mod; if( !ignore_crate_name && path.m_crate_name != m_crate_name ) { diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 51235c7d..304bdd64 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -97,8 +97,9 @@ public: Literal m_value_res; }; -struct Constant +class Constant { +public: // NOTE: The generics can't influence the value of this `const` GenericParams m_params; @@ -275,8 +276,9 @@ TAGGED_UNION(TraitValueItem, Constant, (Static, Static), (Function, Function) ); -struct Trait +class Trait { +public: GenericParams m_params; ::std::string m_lifetime; ::std::vector< ::HIR::TraitPath > m_parent_traits; diff --git a/src/hir/path.hpp b/src/hir/path.hpp index eb9aca27..12e32dd1 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -16,7 +16,7 @@ namespace HIR { -struct Trait; +class Trait; enum Compare { Equal, diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index 51e20c5c..df14de79 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -52,11 +52,11 @@ struct Pattern { TAGGED_UNION(Value, String, (Integer, struct { - enum ::HIR::CoreType type; // Str == _ + ::HIR::CoreType type; // Str == _ uint64_t value; // Signed numbers are encoded as 2's complement }), (Float, struct { - enum ::HIR::CoreType type; // Str == _ + ::HIR::CoreType type; // Str == _ double value; }), (String, ::std::string), @@ -85,7 +85,7 @@ struct Pattern (SplitTuple, struct { ::std::vector<Pattern> leading; ::std::vector<Pattern> trailing; - unsigned int total_size = 0; + unsigned int total_size; }), (StructValue, struct { GenericPath path; diff --git a/src/hir/serialise_lowlevel.hpp b/src/hir/serialise_lowlevel.hpp index fb4504e7..de913432 100644 --- a/src/hir/serialise_lowlevel.hpp +++ b/src/hir/serialise_lowlevel.hpp @@ -52,7 +52,7 @@ public: // Variable-length encoded u64 (for array sizes) void write_u64c(uint64_t v) { if( v < (1<<7) ) { - write_u8(v); + write_u8(static_cast<uint8_t>(v)); } else if( v < (1<<(6+16)) ) { uint8_t buf[] = { @@ -62,7 +62,7 @@ public: }; this->write(buf, sizeof buf); } - else if( v < (1ul << (5 + 32)) ) { + else if( v < (1ull << (5 + 32)) ) { uint8_t buf[] = { static_cast<uint8_t>(0xC0 + (v >> 32)), // 0xC0 -- 0xDF static_cast<uint8_t>(v >> 24), diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 7168da53..7dd8dc80 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -173,12 +173,12 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const ), (Closure, os << "closure["<<e.node<<"]"; - #if 0 + /* os << "("; for(const auto& t : e.m_arg_types) os << t << ", "; os << ") -> " << *e.m_rettype; - #endif + */ ) ) } @@ -370,7 +370,7 @@ Ordering HIR::TypeRef::ord(const ::HIR::TypeRef& x) const return ::ord(*te.m_rettype, *xe.m_rettype); ), (Closure, - ORD( (::std::uintptr_t)te.node, xe.node); + ORD( reinterpret_cast<::std::uintptr_t>(te.node), reinterpret_cast<::std::uintptr_t>(xe.node) ); //assert( te.m_rettype == xe.m_rettype ); return OrdEqual; ) @@ -781,6 +781,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x (Enum , return ::HIR::TypeRef::TypePathBinding(e); ) ) assert(!"Fell off end of clone_binding"); + throw ""; } @@ -832,7 +833,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x // TODO: Need to invoke const eval here? Or support cloning expressions? Or run consteval earlier. if( const auto* ptr = dynamic_cast<const ::HIR::ExprNode_Literal*>(&**e.size) ) { - size_val = ptr->m_data.as_Integer().m_value; + size_val = static_cast<unsigned int>( ptr->m_data.as_Integer().m_value ); } else { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 3bf384a6..a832e8e9 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -123,10 +123,10 @@ public: ) ); - TAGGED_UNION(Data, Infer, + TAGGED_UNION(Data, Diverge, (Infer, struct { - unsigned int index = ~0u; - InferClass ty_class = InferClass::None; + unsigned int index; + InferClass ty_class; }), (Diverge, struct {}), (Primitive, ::HIR::CoreType), @@ -177,7 +177,9 @@ public: Data m_data; - TypeRef() {} + TypeRef(): + m_data(Data::make_Infer({ ~0u, InferClass::None })) + {} TypeRef(TypeRef&& ) = default; TypeRef(const TypeRef& ) = delete; TypeRef& operator=(TypeRef&& ) = default; @@ -210,6 +212,9 @@ public: static TypeRef new_diverge() { return TypeRef(Data::make_Diverge({})); } + static TypeRef new_infer(unsigned int idx = ~0u, InferClass ty_class = InferClass::None) { + return TypeRef(Data::make_Infer({idx, ty_class})); + } static TypeRef new_borrow(BorrowType bt, TypeRef inner) { return TypeRef(Data::make_Borrow({bt, box$(mv$(inner))})); } diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 6949e2d6..a950a3dd 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -431,7 +431,7 @@ namespace { case ::HIR::ExprNode_UniOp::Op::Negate: TU_MATCH_DEF(::HIR::Literal, (val), (e), ( throw ""; ), - (Integer, m_rv = ::HIR::Literal(-e); ), + (Integer, m_rv = ::HIR::Literal(static_cast<uint64_t>(-static_cast<int64_t>(e))); ), (Float, m_rv = ::HIR::Literal(-e); ) ) break; @@ -542,7 +542,7 @@ namespace { node.m_index->visit(*this); if( !m_rv.is_Integer() ) ERROR(node.span(), E0000, "Array index isn't an integer - got " << m_rv.tag_str()); - auto idx = m_rv.as_Integer(); + auto idx = static_cast<size_t>( m_rv.as_Integer() ); // Value m_exp_type = ::HIR::TypeRef::new_slice( mv$(exp_ty) ); @@ -1023,7 +1023,7 @@ namespace { TRACE_FUNCTION_F("exp=" << exp << ", args=" << args); StaticTraitResolve resolve { crate }; - ::MIR::TypeResolve state { sp, resolve, FMT_CB(), exp, {}, fcn }; + ::MIR::TypeResolve state { sp, resolve, FMT_CB(,), exp, {}, fcn }; ::HIR::Literal retval; ::std::vector< ::HIR::Literal> locals; @@ -1596,7 +1596,7 @@ namespace { auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, ::HIR::CoreType::Usize); if( !val.is_Integer() ) ERROR(expr_ptr->span(), E0000, "Array size isn't an integer"); - e.size_val = val.as_Integer(); + e.size_val = static_cast<size_t>(val.as_Integer()); } DEBUG("Array " << ty << " - size = " << e.size_val); ) @@ -1670,7 +1670,7 @@ namespace { auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, ::HIR::CoreType::Usize, {}); if( !val.is_Integer() ) ERROR(node.span(), E0000, "Array size isn't an integer"); - node.m_size_val = val.as_Integer(); + node.m_size_val = static_cast<size_t>(val.as_Integer()); DEBUG("Array literal [?; " << node.m_size_val << "]"); } diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index 303eae90..511a35b0 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -26,7 +26,7 @@ } if( e2.m_params.m_types.size() > 0 ) { // TODO: Better `monomorphise_type` - return monomorphise_type_with(sp, e2.m_type, [&](const auto& gt)->const auto& { + return monomorphise_type_with(sp, e2.m_type, [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == GENERIC_Self ) { BUG(sp, "Self encountered in expansion for " << path << " - " << e2.m_type); diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp index 8f4947c5..d397d78c 100644 --- a/src/hir_conv/resolve_ufcs.cpp +++ b/src/hir_conv/resolve_ufcs.cpp @@ -253,7 +253,7 @@ namespace { return true; } - auto monomorph_cb = [&](const auto& ty)->const auto& { + auto monomorph_cb = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { // TODO: This has to be the _exact_ same type, including future ivars. @@ -282,7 +282,7 @@ namespace { } }; ::HIR::GenericPath par_trait_path_tmp; - auto monomorph_gp_if_needed = [&](const auto& tpl)->const auto& { + auto monomorph_gp_if_needed = [&](const ::HIR::GenericPath& tpl)->const ::HIR::GenericPath& { // NOTE: This doesn't monomorph if the parameter set is the same if( monomorphise_genericpath_needed(tpl) && tpl.m_params != trait_path.m_params ) { DEBUG("- Monomorph " << tpl); @@ -321,10 +321,10 @@ namespace { const auto& type = *e.type; // TODO: This is VERY arbitary and possibly nowhere near what rustc does. - this->m_resolve.find_impl(sp, trait_path.m_path, nullptr, type, [&](const auto& impl, bool fuzzy){ + this->m_resolve.find_impl(sp, trait_path.m_path, nullptr, type, [&](const auto& impl, bool fuzzy)->bool{ auto pp = impl.get_trait_params(); // Replace all placeholder parameters (group 2) with ivars (empty types) - pp = monomorphise_path_params_with(sp, pp, [&](const auto& gt)->const auto& { + pp = monomorphise_path_params_with(sp, pp, [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( (ge.binding >> 8) == 2 ) { static ::HIR::TypeRef empty_type; diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 5b4fd722..b58f2398 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -508,7 +508,7 @@ namespace { impl_path_params.m_types.push_back( ::HIR::TypeRef(params.m_types[i].m_name, i) ); } - auto monomorph_cb = [&](const auto& ty)->const auto& { + auto monomorph_cb = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return params_placeholders.at(0); @@ -528,7 +528,7 @@ namespace { } }; auto monomorph = [&](const auto& ty){ return monomorphise_type_with(sp, ty, monomorph_cb); }; - auto cb_replace = [&](const auto& tpl, auto& rv) { + auto cb_replace = [&](const auto& tpl, auto& rv)->bool { if( tpl.m_data.is_Infer() ) { BUG(sp, ""); } @@ -552,7 +552,7 @@ namespace { }; // - Clone the bounds (from both levels) - auto monomorph_bound = [&](const ::HIR::GenericBound& b)->auto { + auto monomorph_bound = [&](const ::HIR::GenericBound& b)->::HIR::GenericBound { TU_MATCHA( (b), (e), (Lifetime, return ::HIR::GenericBound(e); ), diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp index 3bdec96f..538693f4 100644 --- a/src/hir_expand/const_eval_full.cpp +++ b/src/hir_expand/const_eval_full.cpp @@ -351,7 +351,7 @@ namespace { auto& idx = get_lval(*e.idx); MIR_ASSERT(state, idx.is_Integer(), "LValue::Index with non-integer index literal - " << idx.tag_str() << " - " << lv); auto& vals = val.as_List(); - auto idx_v = idx.as_Integer(); + auto idx_v = static_cast<size_t>( idx.as_Integer() ); MIR_ASSERT(state, idx_v < vals.size(), "LValue::Index index out of range"); return vals[ idx_v ]; ), diff --git a/src/hir_expand/erased_types.cpp b/src/hir_expand/erased_types.cpp index e4075e92..aca58207 100644 --- a/src/hir_expand/erased_types.cpp +++ b/src/hir_expand/erased_types.cpp @@ -14,19 +14,21 @@ const ::HIR::Function& HIR_Expand_ErasedType_GetFunction(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::Path& origin_path, t_cb_generic& monomorph_cb, ::HIR::PathParams& impl_params) { const ::HIR::Function* fcn_ptr = nullptr; - TU_MATCHA( (origin_path.m_data), (pe), - (UfcsUnknown, - BUG(Span(), "UfcsUnknown in ErasedType - " << origin_path); - ), - (Generic, - monomorph_cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pe.m_params); - fcn_ptr = &resolve.m_crate.get_function_by_path(sp, pe.m_path); - ), - (UfcsKnown, - // NOTE: This isn't possible yet (will it be? or will it expand to an associated type?) - TODO(sp, "Replace ErasedType - " << origin_path << " with source (UfcsKnown)"); - ), - (UfcsInherent, + switch(origin_path.m_data.tag()) + { + case ::HIR::Path::Data::TAG_UfcsUnknown: + BUG(Span(), "UfcsUnknown in ErasedType - " << origin_path); + case ::HIR::Path::Data::TAG_Generic: { + const auto& pe = origin_path.m_data.as_Generic(); + monomorph_cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pe.m_params); + fcn_ptr = &resolve.m_crate.get_function_by_path(sp, pe.m_path); + } break; + case ::HIR::Path::Data::TAG_UfcsKnown: + // NOTE: This isn't possible yet (will it be? or will it expand to an associated type?) + TODO(sp, "Replace ErasedType - " << origin_path << " with source (UfcsKnown)"); + break; + case ::HIR::Path::Data::TAG_UfcsInherent: { + const auto& pe = origin_path.m_data.as_UfcsInherent(); // 1. Find correct impl block for the path const ::HIR::TypeImpl* impl_ptr = nullptr; resolve.m_crate.find_type_impls(*pe.type, [&](const auto& ty)->const auto& { return ty; }, @@ -50,12 +52,16 @@ const ::HIR::Function& HIR_Expand_ErasedType_GetFunction(const Span& sp, const S return ::HIR::Compare::Equal; }); for(const auto& t : impl_params.m_types) + { if( t == ::HIR::TypeRef() ) + { TODO(sp, "Handle ErasedType where an impl parameter comes from a bound - " << origin_path); + } + } monomorph_cb = monomorphise_type_get_cb(sp, &*pe.type, &impl_params, &pe.params); - ) - ) + } break; + } assert(fcn_ptr); return *fcn_ptr; } diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp index 925543eb..44921105 100644 --- a/src/hir_expand/ufcs_everything.cpp +++ b/src/hir_expand/ufcs_everything.cpp @@ -289,8 +289,7 @@ namespace { ASSERT_BUG(sp, ty_slot == ty_val, "Types must equal for non-operator assignment, " << ty_slot << " != " << ty_val); return ; _(Shr): {langitem = "shr_assign"; opname = "shr_assign"; } if(0) - _(Shl): {langitem = "shl_assign"; opname = "shl_assign"; } if(0) - ; + _(Shl): {langitem = "shl_assign"; opname = "shl_assign"; } if( is_op_valid_shift(ty_slot, ty_val) ) { return ; } @@ -298,8 +297,7 @@ namespace { _(And): {langitem = "bitand_assign"; opname = "bitand_assign"; } if(0) _(Or ): {langitem = "bitor_assign" ; opname = "bitor_assign" ; } if(0) - _(Xor): {langitem = "bitxor_assign"; opname = "bitxor_assign"; } if(0) - ; + _(Xor): {langitem = "bitxor_assign"; opname = "bitxor_assign"; } if( is_op_valid_bitmask(ty_slot, ty_val) ) { return ; } @@ -309,8 +307,7 @@ namespace { _(Sub): {langitem = "sub_assign"; opname = "sub_assign"; } if(0) _(Mul): {langitem = "mul_assign"; opname = "mul_assign"; } if(0) _(Div): {langitem = "div_assign"; opname = "div_assign"; } if(0) - _(Mod): {langitem = "rem_assign"; opname = "rem_assign"; } if(0) - ; + _(Mod): {langitem = "rem_assign"; opname = "rem_assign"; } if( is_op_valid_arith(ty_slot, ty_val) ) { return ; } @@ -359,8 +356,8 @@ namespace { case ::HIR::ExprNode_BinOp::Op::CmpLt: { langitem = "ord"; method = "lt"; } if(0) case ::HIR::ExprNode_BinOp::Op::CmpLtE: { langitem = "ord"; method = "le"; } if(0) case ::HIR::ExprNode_BinOp::Op::CmpGt: { langitem = "ord"; method = "gt"; } if(0) - case ::HIR::ExprNode_BinOp::Op::CmpGtE: { langitem = "ord"; method = "ge"; } if(0) - ; { + case ::HIR::ExprNode_BinOp::Op::CmpGtE: { langitem = "ord"; method = "ge"; } + { // 1. Check if the types are valid for primitive comparison if( ty_l == ty_r ) { TU_MATCH_DEF(::HIR::TypeRef::Data, (ty_l.m_data), (e), @@ -388,8 +385,10 @@ namespace { auto ty_r_ref = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ty_r.clone() ); ::std::vector< ::HIR::ExprNodeP> args; - args.push_back(NEWNODE(ty_l_ref.clone(), Borrow, node.m_left ->span(), ::HIR::BorrowType::Shared, mv$(node.m_left ) )); - args.push_back(NEWNODE(ty_r_ref.clone(), Borrow, node.m_right->span(), ::HIR::BorrowType::Shared, mv$(node.m_right) )); + auto sp_left = node.m_left ->span(); + auto sp_right = node.m_right->span(); + args.push_back(NEWNODE(ty_l_ref.clone(), Borrow, sp_left , ::HIR::BorrowType::Shared, mv$(node.m_left ) )); + args.push_back(NEWNODE(ty_r_ref.clone(), Borrow, sp_right, ::HIR::BorrowType::Shared, mv$(node.m_right) )); m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp, ::HIR::Path(ty_l.clone(), mv$(trait), method), @@ -406,8 +405,7 @@ namespace { case ::HIR::ExprNode_BinOp::Op::Xor: langitem = method = "bitxor"; if(0) case ::HIR::ExprNode_BinOp::Op::Or : langitem = method = "bitor" ; if(0) - case ::HIR::ExprNode_BinOp::Op::And: langitem = method = "bitand"; if(0) - ; + case ::HIR::ExprNode_BinOp::Op::And: langitem = method = "bitand"; if( is_op_valid_bitmask(ty_l, ty_r) ) { return ; } diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp index 54d9b038..09a5d9b2 100644 --- a/src/hir_typeck/common.hpp +++ b/src/hir_typeck/common.hpp @@ -88,7 +88,7 @@ extern ::std::ostream& operator<<(::std::ostream& os, const MonomorphState& ms); static inline t_cb_generic monomorphise_type_get_cb(const Span& sp, const ::HIR::TypeRef* self_ty, const ::HIR::PathParams* params_i, const ::HIR::PathParams* params_m, const ::HIR::PathParams* params_p=nullptr) { - return [=](const auto& gt)->const auto& { + return [=](const ::HIR::TypeRef& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { ASSERT_BUG(sp, self_ty, "Self wasn't expected here"); diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index 66fdcb14..fe67865f 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -39,7 +39,7 @@ namespace { node_ptr->visit(*this); // Monomorphise erased type - ::HIR::TypeRef new_ret_type = clone_ty_with(sp, ret_type, [&](const auto& tpl, auto& rv) { + ::HIR::TypeRef new_ret_type = clone_ty_with(sp, ret_type, [&](const auto& tpl, auto& rv)->bool { if( tpl.m_data.is_ErasedType() ) { const auto& e = tpl.m_data.as_ErasedType(); @@ -504,7 +504,7 @@ namespace { #if 1 const auto& ty_params = node.m_path.m_params.m_types; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return ty; @@ -603,7 +603,7 @@ namespace { fcn_ptr = &fcn; cache.m_fcn_params = &fcn.m_params; - monomorph_cb = [&](const auto& gt)->const auto& { + monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& e = gt.m_data.as_Generic(); if( e.name == "Self" || e.binding == 0xFFFF ) TODO(sp, "Handle 'Self' when monomorphising"); @@ -640,29 +640,7 @@ namespace { fcn_ptr = &fcn; - monomorph_cb = [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return *e.type; - } - else if( ge.binding < 256 ) { - auto idx = ge.binding; - if( idx >= trait_params.m_types.size() ) { - BUG(sp, "Generic param (impl) out of input range - " << idx << " '"<<ge.name<<"' >= " << trait_params.m_types.size()); - } - return trait_params.m_types[idx]; - } - else if( ge.binding < 512 ) { - auto idx = ge.binding - 256; - if( idx >= path_params.m_types.size() ) { - BUG(sp, "Generic param out of input range - " << idx << " '"<<ge.name<<"' >= " << path_params.m_types.size()); - } - return path_params.m_types[idx]; - } - else { - BUG(sp, "Generic bounding out of total range"); - } - }; + monomorph_cb = monomorphise_type_get_cb(sp, &*e.type, &trait_params, &path_params); ), (UfcsUnknown, TODO(sp, "Hit a UfcsUnknown (" << path << ") - Is this an error?"); @@ -670,7 +648,7 @@ namespace { (UfcsInherent, // - Locate function (and impl block) const ::HIR::TypeImpl* impl_ptr = nullptr; - m_resolve.m_crate.find_type_impls(*e.type, [&](const auto& ty)->const auto& { return ty; }, + m_resolve.m_crate.find_type_impls(*e.type, [&](const auto& ty)->const ::HIR::TypeRef& { return ty; }, [&](const auto& impl) { DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type); auto it = impl.m_methods.find(e.item); @@ -694,29 +672,7 @@ namespace { // Create monomorphise callback const auto& fcn_params = e.params; - monomorph_cb = [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return *e.type; - } - else if( ge.binding < 256 ) { - auto idx = ge.binding; - if( idx >= impl_params.m_types.size() ) { - BUG(sp, "Generic param out of input range (impl) - " << idx << " '" << ge.name << "' >= " << impl_params.m_types.size()); - } - return impl_params.m_types[idx]; - } - else if( ge.binding < 512 ) { - auto idx = ge.binding - 256; - if( idx >= fcn_params.m_types.size() ) { - BUG(sp, "Generic param out of input range (item) - " << idx << " '" << ge.name << "' >= " << fcn_params.m_types.size()); - } - return fcn_params.m_types[idx]; - } - else { - BUG(sp, "Generic bounding out of total range"); - } - }; + monomorph_cb = monomorphise_type_get_cb(sp, &*e.type, &impl_params, &fcn_params); ) ) @@ -733,7 +689,7 @@ namespace { } DEBUG("Ret " << fcn.m_return); // Replace ErasedType and monomorphise - cache.m_arg_types.push_back( clone_ty_with(sp, fcn.m_return, [&](const auto& tpl, auto& rv) { + cache.m_arg_types.push_back( clone_ty_with(sp, fcn.m_return, [&](const auto& tpl, auto& rv)->bool { if( tpl.m_data.is_Infer() ) { BUG(sp, ""); } @@ -850,7 +806,7 @@ namespace { ::HIR::PathParams params; params.m_types.push_back( ::HIR::TypeRef( mv$(tup_ents) ) ); - bool found = m_resolve.find_impl(node.span(), trait, ¶ms, val_ty, [&](auto , bool fuzzy){ + bool found = m_resolve.find_impl(node.span(), trait, ¶ms, val_ty, [&](auto , bool fuzzy)->bool{ ASSERT_BUG(node.span(), !fuzzy, "Fuzzy match in check pass"); return true; }); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index fb56abc4..eb922414 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -283,7 +283,7 @@ namespace { //const auto& params_def = fcn.m_params; const auto& path_params = e.m_params; - cache.m_monomorph_cb = [&](const auto& gt)->const auto& { + cache.m_monomorph_cb = [&](const ::HIR::TypeRef& gt)->const ::HIR::TypeRef& { const auto& e = gt.m_data.as_Generic(); if( e.name == "Self" || e.binding == 0xFFFF ) TODO(sp, "Handle 'Self' when monomorphising"); @@ -320,7 +320,7 @@ namespace { const auto& trait_params = e.trait.m_params; const auto& path_params = e.params; - cache.m_monomorph_cb = [&](const auto& gt)->const auto& { + cache.m_monomorph_cb = [&](const ::HIR::TypeRef& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return *e.type; @@ -431,7 +431,7 @@ namespace { // Monomorphise the impl type with the new ivars, and equate to *e.type - auto impl_monomorph_cb = [&](const auto& gt)->const auto& { + auto impl_monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return context.get_type(*e.type); @@ -464,7 +464,7 @@ namespace { // Create monomorphise callback const auto& fcn_params = e.params; - cache.m_monomorph_cb = [&](const auto& gt)->const auto& { + cache.m_monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return context.get_type(*e.type); @@ -1094,7 +1094,7 @@ namespace { } const auto& ty_params = node.m_path.m_params.m_types; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return ty; @@ -1190,7 +1190,7 @@ namespace { const ::HIR::t_struct_fields& fields = *fields_ptr; const auto& ty_params = node.m_path.m_params.m_types; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return ty; @@ -1255,22 +1255,7 @@ namespace { this->context.equate_types(node.span(), node.m_res_type, ty); - const auto& ty_params = node.m_path.m_params.m_types; - auto monomorph_cb = [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return ty; - } - else if( ge.binding < 256 ) { - if( ge.binding >= ty_params.size() ) { - BUG(node.span(), "Type parameter index out of range (#" << ge.binding << " " << ge.name << ")"); - } - return ty_params[ge.binding]; - } - else { - BUG(node.span(), "Method-level parameter on struct (#" << ge.binding << " " << ge.name << ")"); - } - }; + auto monomorph_cb = monomorphise_type_get_cb(node.span(), &ty, &node.m_path.m_params, nullptr); // Convert bounds on the type into rules apply_bounds_as_rules(context, node.span(), unm.m_params, monomorph_cb); @@ -1556,26 +1541,7 @@ namespace { const auto& f = this->context.m_crate.get_function_by_path(sp, e.m_path); fix_param_count(sp, this->context, ::HIR::TypeRef(), false, e, f.m_params, e.m_params); - const auto& params = e.m_params; - auto monomorph_cb = [&](const auto& gt)->const auto& { - const auto& e = gt.m_data.as_Generic(); - if( e.binding == 0xFFFF ) { - BUG(sp, "Reference to Self in free function - " << gt); - } - else if( (e.binding >> 8) == 0 ) { - BUG(sp, "Reference to impl-level param in free function - " << gt); - } - else if( (e.binding >> 8) == 1 ) { - auto idx = e.binding & 0xFF; - if( idx >= params.m_types.size() ) { - BUG(sp, "Generic param out of input range - " << gt << " >= " << params.m_types.size()); - } - return params.m_types[idx]; - } - else { - BUG(sp, "Unknown param in free function - " << gt); - } - }; + auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &e.m_params); ::HIR::FunctionType ft { f.m_unsafe, @@ -1679,27 +1645,7 @@ namespace { const auto& fcn_params = e.params; const auto& trait_params = e.trait.m_params; - auto monomorph_cb = [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return this->context.get_type(*e.type); - } - else if( (ge.binding >> 8) == 0 ) { - auto idx = ge.binding; - ASSERT_BUG(sp, idx < trait_params.m_types.size(), "Generic param out of input range - " << gt << " >= " << trait_params.m_types.size()); - return this->context.get_type(trait_params.m_types[idx]); - } - else if( (ge.binding >> 8) == 1 ) { - auto idx = ge.binding & 0xFF; - if( idx >= fcn_params.m_types.size() ) { - BUG(sp, "Generic param out of input range - " << gt << " >= " << fcn_params.m_types.size()); - } - return this->context.get_type(fcn_params.m_types[idx]); - } - else { - BUG(sp, "Generic bounding out of total range - " << gt); - } - }; + auto monomorph_cb = monomorphise_type_get_cb(sp, &*e.type, &e.trait.m_params, &e.params); ::HIR::FunctionType ft { ie.m_unsafe, ie.m_abi, box$( monomorphise_type_with(sp, ie.m_return, monomorph_cb) ), @@ -1782,7 +1728,7 @@ namespace { { // Create monomorphise callback const auto& fcn_params = e.params; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return this->context.get_type(*e.type); @@ -2061,29 +2007,6 @@ namespace { this->m_completed = true; ), (Path, - #if 0 - TU_MATCHA( (e.binding), (be), - (Unbound, - BUG(sp, "Encountered unbound type in _Cast Path - " << tgt_ty); - ), - (Opaque, - // TODO: Bounds search - TODO(sp, "Cast Path::Opaque with CoerceUnsized - " << tgt_ty); - ), - (Struct, - if( !be->m_markings.can_coerce ) - ERROR(sp, E0000, "Non-scalar cast to " << this->context.m_ivars.fmt_type(tgt_ty)); - ), - (Union, - if( !be->m_markings.can_coerce ) - ERROR(sp, E0000, "Non-scalar cast to " << this->context.m_ivars.fmt_type(tgt_ty)); - ), - (Enum, - if( !be->m_markings.can_coerce ) - ERROR(sp, E0000, "Non-scalar cast to " << this->context.m_ivars.fmt_type(tgt_ty)); - ) - ) - #endif this->context.equate_types_coerce(sp, tgt_ty, node.m_value); this->m_completed = true; return ; @@ -2445,147 +2368,148 @@ namespace { const auto& ty = *ty_p; DEBUG("- ty = " << ty); - TU_MATCH_DEF(decltype(ty.m_data), (ty.m_data), (e), - ( - ::HIR::TypeRef fcn_args_tup; - ::HIR::TypeRef fcn_ret; - - // TODO: Use `find_trait_impls` instead of two different calls - // - This will get the TraitObject impl search too - - // Locate an impl of FnOnce (exists for all other Fn* traits) - unsigned int count = 0; - this->context.m_resolve.find_trait_impls(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) { - count ++; - - auto tup = impl.get_trait_ty_param(0); - if( !tup.m_data.is_Tuple() ) - ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup); - fcn_args_tup = mv$(tup); - - fcn_ret = impl.get_type("Output"); - DEBUG("[visit:_CallValue] fcn_args_tup=" << fcn_args_tup << ", fcn_ret=" << fcn_ret); - return cmp == ::HIR::Compare::Equal; - }); - DEBUG("Found " << count << " impls of FnOnce"); - if( count > 1 ) { - return ; - } - if( count == 1 ) - { - - // 3. Locate the most permissive implemented Fn* trait (Fn first, then FnMut, then assume just FnOnce) - // NOTE: Borrowing is added by the expansion to CallPath - if( this->context.m_resolve.find_trait_impls(node.span(), lang_Fn, trait_pp, ty, [&](auto impl, auto cmp) { - // TODO: Take the value of `cmp` into account - fcn_ret = impl.get_type("Output"); - return true; - //return cmp == ::HIR::Compare::Equal; - }) - ) - { - DEBUG("-- Using Fn"); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Fn; - - this->context.equate_types_assoc(node.span(), node.m_res_type, lang_Fn, ::make_vec1( fcn_args_tup.clone() ), ty, "Output"); - } - else if( this->context.m_resolve.find_trait_impls(node.span(), lang_FnMut, trait_pp, ty, [&](auto impl, auto cmp) { - // TODO: Take the value of `cmp` into account - fcn_ret = impl.get_type("Output"); - return true; - //return cmp == ::HIR::Compare::Equal; - }) - ) - { - DEBUG("-- Using FnMut"); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::FnMut; - - this->context.equate_types_assoc(node.span(), node.m_res_type, lang_FnMut, ::make_vec1( fcn_args_tup.clone() ), ty, "Output"); - } - else - { - DEBUG("-- Using FnOnce (default)"); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::FnOnce; - - this->context.equate_types_assoc(node.span(), node.m_res_type, lang_FnOnce, ::make_vec1( fcn_args_tup.clone() ), ty, "Output"); - } - - // If the return type wasn't found in the impls, emit it as a UFCS - if( fcn_ret == ::HIR::TypeRef() ) - { - fcn_ret = ::HIR::TypeRef( ::HIR::Path(::HIR::Path::Data::make_UfcsKnown({ - box$( ty.clone() ), - // - Clone argument tuple, as it's stolen into cache below - ::HIR::GenericPath(lang_FnOnce, ::HIR::PathParams( fcn_args_tup.clone() )), - "Output", - {} - })) ); - } - } - else TU_IFLET( ::HIR::TypeRef::Data, ty.m_data, Borrow, e, - deref_count ++; - ty_p = &this->context.get_type(*e.inner); - DEBUG("Deref " << ty << " -> " << *ty_p); - keep_looping = true; - continue ; - ) - else - { - if( !ty.m_data.is_Generic() ) - { - bool found = this->context.m_resolve.find_trait_impls_crate(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) { - if( cmp == ::HIR::Compare::Fuzzy ) - TODO(node.span(), "Handle fuzzy match - " << impl); - - auto tup = impl.get_trait_ty_param(0); - if( !tup.m_data.is_Tuple() ) - ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup); - fcn_args_tup = mv$(tup); - fcn_ret = impl.get_type("Output"); - ASSERT_BUG(node.span(), fcn_ret != ::HIR::TypeRef(), "Impl didn't have a type for Output - " << impl); - return true; - }); - if( found ) { - // Fill cache and leave the TU_MATCH - node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() ); - node.m_arg_types.push_back( mv$(fcn_ret) ); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Unknown; - break ; // leaves TU_MATCH - } - } - if( const auto* next_ty_p = this->context.m_resolve.autoderef(node.span(), ty, tmp_type) ) - { - DEBUG("Deref (autoderef) " << ty << " -> " << *next_ty_p); - deref_count ++; - ty_p = next_ty_p; - keep_looping = true; - continue ; - } - - // Didn't find anything. Error? - ERROR(node.span(), E0000, "Unable to find an implementation of Fn*"<<trait_pp<<" for " << this->context.m_ivars.fmt_type(ty)); - } - - node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() ); - node.m_arg_types.push_back( mv$(fcn_ret) ); - ), - (Closure, - for( const auto& arg : e.m_arg_types ) - node.m_arg_types.push_back( arg.clone() ); - node.m_arg_types.push_back( e.m_rettype->clone() ); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Unknown; - ), - (Function, - for( const auto& arg : e.m_arg_types ) - node.m_arg_types.push_back( arg.clone() ); - node.m_arg_types.push_back( e.m_rettype->clone() ); - node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Fn; - ), - (Infer, - // No idea yet - return ; - ) - ) + if( const auto* e = ty.m_data.opt_Closure() ) + { + for( const auto& arg : e->m_arg_types ) + node.m_arg_types.push_back(arg.clone()); + node.m_arg_types.push_back(e->m_rettype->clone()); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Unknown; + } + else if( const auto* e = ty.m_data.opt_Function() ) + { + for( const auto& arg : e->m_arg_types ) + node.m_arg_types.push_back(arg.clone()); + node.m_arg_types.push_back(e->m_rettype->clone()); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Fn; + } + else if( ty.m_data.is_Infer() ) + { + // No idea yet + return ; + } + else + { + ::HIR::TypeRef fcn_args_tup; + ::HIR::TypeRef fcn_ret; + + // TODO: Use `find_trait_impls` instead of two different calls + // - This will get the TraitObject impl search too + + // Locate an impl of FnOnce (exists for all other Fn* traits) + unsigned int count = 0; + this->context.m_resolve.find_trait_impls(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp)->bool { + count++; + + auto tup = impl.get_trait_ty_param(0); + if (!tup.m_data.is_Tuple()) + ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup); + fcn_args_tup = mv$(tup); + + fcn_ret = impl.get_type("Output"); + DEBUG("[visit:_CallValue] fcn_args_tup=" << fcn_args_tup << ", fcn_ret=" << fcn_ret); + return cmp == ::HIR::Compare::Equal; + }); + DEBUG("Found " << count << " impls of FnOnce"); + if(count > 1) { + return; + } + if(count == 1) + { + + // 3. Locate the most permissive implemented Fn* trait (Fn first, then FnMut, then assume just FnOnce) + // NOTE: Borrowing is added by the expansion to CallPath + if( this->context.m_resolve.find_trait_impls(node.span(), lang_Fn, trait_pp, ty, [&](auto impl, auto cmp) { + // TODO: Take the value of `cmp` into account + fcn_ret = impl.get_type("Output"); + return true; + //return cmp == ::HIR::Compare::Equal; + }) ) + { + DEBUG("-- Using Fn"); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Fn; + + this->context.equate_types_assoc(node.span(), node.m_res_type, lang_Fn, ::make_vec1(fcn_args_tup.clone()), ty, "Output"); + } + else if( this->context.m_resolve.find_trait_impls(node.span(), lang_FnMut, trait_pp, ty, [&](auto impl, auto cmp) { + // TODO: Take the value of `cmp` into account + fcn_ret = impl.get_type("Output"); + return true; + //return cmp == ::HIR::Compare::Equal; + }) ) + { + DEBUG("-- Using FnMut"); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::FnMut; + + this->context.equate_types_assoc(node.span(), node.m_res_type, lang_FnMut, ::make_vec1(fcn_args_tup.clone()), ty, "Output"); + } + else + { + DEBUG("-- Using FnOnce (default)"); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::FnOnce; + + this->context.equate_types_assoc(node.span(), node.m_res_type, lang_FnOnce, ::make_vec1(fcn_args_tup.clone()), ty, "Output"); + } + + // If the return type wasn't found in the impls, emit it as a UFCS + if(fcn_ret == ::HIR::TypeRef()) + { + fcn_ret = ::HIR::TypeRef(::HIR::Path(::HIR::Path::Data::make_UfcsKnown({ + box$(ty.clone()), + // - Clone argument tuple, as it's stolen into cache below + ::HIR::GenericPath(lang_FnOnce, ::HIR::PathParams(fcn_args_tup.clone())), + "Output", + {} + }))); + } + } + else if( const auto* e = ty.m_data.opt_Borrow() ) + { + deref_count++; + ty_p = &this->context.get_type(*e->inner); + DEBUG("Deref " << ty << " -> " << *ty_p); + keep_looping = true; + continue; + } + else + { + if( !ty.m_data.is_Generic() ) + { + bool found = this->context.m_resolve.find_trait_impls_crate(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp)->bool { + if (cmp == ::HIR::Compare::Fuzzy) + TODO(node.span(), "Handle fuzzy match - " << impl); + + auto tup = impl.get_trait_ty_param(0); + if (!tup.m_data.is_Tuple()) + ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup); + fcn_args_tup = mv$(tup); + fcn_ret = impl.get_type("Output"); + ASSERT_BUG(node.span(), fcn_ret != ::HIR::TypeRef(), "Impl didn't have a type for Output - " << impl); + return true; + }); + if (found) { + // Fill cache and leave the TU_MATCH + node.m_arg_types = mv$(fcn_args_tup.m_data.as_Tuple()); + node.m_arg_types.push_back(mv$(fcn_ret)); + node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Unknown; + break; // leaves TU_MATCH + } + } + if( const auto* next_ty_p = this->context.m_resolve.autoderef(node.span(), ty, tmp_type) ) + { + DEBUG("Deref (autoderef) " << ty << " -> " << *next_ty_p); + deref_count++; + ty_p = next_ty_p; + keep_looping = true; + continue; + } + + // Didn't find anything. Error? + ERROR(node.span(), E0000, "Unable to find an implementation of Fn*" << trait_pp << " for " << this->context.m_ivars.fmt_type(ty)); + } + + node.m_arg_types = mv$(fcn_args_tup.m_data.as_Tuple()); + node.m_arg_types.push_back(mv$(fcn_ret)); + } } while( keep_looping ); if( deref_count > 0 ) @@ -3183,13 +3107,13 @@ void Context::equate_types(const Span& sp, const ::HIR::TypeRef& li, const ::HIR // Instantly apply equality TRACE_FUNCTION_F(li << " == " << ri); - visit_ty_with(ri, [&](const auto& ty) { + visit_ty_with(ri, [&](const auto& ty)->bool { if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) { BUG(sp, "Type contained an impl placeholder parameter - " << ri); } return false; }); - visit_ty_with(li, [&](const auto& ty) { + visit_ty_with(li, [&](const auto& ty)->bool { if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) { BUG(sp, "Type contained an impl placeholder parameter - " << li); } @@ -4110,7 +4034,7 @@ void fix_param_count_(const Span& sp, Context& context, const ::HIR::TypeRef& se ERROR(sp, E0000, "Omitted type parameter with no default in " << path); } else if( monomorphise_type_needed(typ.m_default) ) { - auto cb = [&](const auto& ty)->const auto& { + auto cb = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { ASSERT_BUG(sp, self_ty != ::HIR::TypeRef(), "Self not allowed in this context"); @@ -4351,7 +4275,7 @@ namespace { } } - add_coerce_borrow(context, node_ptr, types.back(), [&](auto& node_ptr) { + add_coerce_borrow(context, node_ptr, types.back(), [&](auto& node_ptr)->void { // node_ptr = node that yeilds ty_src assert( count == types.size() ); for(unsigned int i = 0; i < types.size(); i ++ ) @@ -4556,7 +4480,7 @@ namespace { bool fuzzy_match = false; ImplRef best_impl; - bool found = context.m_resolve.find_trait_impls(sp, lang_CoerceUnsized, pp, ty_src, [&](auto impl, auto cmp) { + bool found = context.m_resolve.find_trait_impls(sp, lang_CoerceUnsized, pp, ty_src, [&](auto impl, auto cmp)->bool { DEBUG("[check_coerce] cmp=" << cmp << ", impl=" << impl); // TODO: Allow fuzzy match if it's the only matching possibility? // - Recorded for now to know if there could be a matching impl later @@ -4761,7 +4685,6 @@ namespace { // If the coercion is of a block, do the reborrow on the last node of the block // - Cleans up the dumped MIR and prevents needing a reborrow elsewhere. - #if 1 ::HIR::ExprNodeP* npp = &node_ptr; while( auto* p = dynamic_cast< ::HIR::ExprNode_Block*>(&**npp) ) { @@ -4775,7 +4698,6 @@ namespace { npp = &p->m_value_node; } ::HIR::ExprNodeP& node_ptr = *npp; - #endif // Add cast down auto span = node_ptr->span(); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index b60b03c8..a3fe9b1c 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -436,6 +436,7 @@ void HMTypeInferrence::add_ivars(::HIR::TypeRef& type) e.index = this->new_ivar(); this->get_type(type).m_data.as_Infer().ty_class = e.ty_class; this->mark_change(); + DEBUG("New ivar " << type); } ), (Diverge, @@ -932,7 +933,7 @@ void TraitResolution::prep_indexes() this->m_type_equalities.insert(::std::make_pair( mv$(long_ty), mv$(short_ty) )); }; - this->iterate_bounds([&](const auto& b) { + this->iterate_bounds([&](const auto& b)->bool { TU_MATCH_DEF(::HIR::GenericBound, (b), (be), ( ), @@ -947,7 +948,7 @@ void TraitResolution::prep_indexes() } const auto& trait_params = be.trait.m_path.m_params; - auto cb_mono = [&](const auto& ty)->const auto& { + auto cb_mono = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return be.type; @@ -1835,7 +1836,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, // 1. Bounds bool rv; bool assume_opaque = true; - rv = this->iterate_bounds([&](const auto& b) { + rv = this->iterate_bounds([&](const auto& b)->bool { TU_MATCH_DEF(::HIR::GenericBound, (b), (be), ( ), @@ -1935,7 +1936,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, DEBUG("TODO: Search bounds on associated type - " << assoc_ty.m_trait_bounds); // Resolve where Self=pe_inner.type (i.e. for the trait this inner UFCS is on) - auto cb_placeholders_trait = [&](const auto& ty)->const auto&{ + auto cb_placeholders_trait = [&](const auto& ty)->const ::HIR::TypeRef&{ TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Generic, e, if( e.binding == 0xFFFF ) return *pe_inner.type; @@ -1984,7 +1985,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, unsigned int count = 0; bool is_specialisable = false; ImplRef best_impl; - rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *pe.type, [&](auto impl, auto qual) { + rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *pe.type, [&](auto impl, auto qual)->bool { DEBUG("[expand_associated_types__UfcsKnown] Found " << impl << " qual=" << qual); // If it's a fuzzy match, keep going (but count if a concrete hasn't been found) if( qual == ::HIR::Compare::Fuzzy ) { @@ -2018,8 +2019,8 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, if( ty == ::HIR::TypeRef() ) ERROR(sp, E0000, "Couldn't find assocated type " << pe.item << " in " << pe.trait); - if( impl.has_magic_params() ) - ; + if( impl.has_magic_params() ) { + } // TODO: What if there's multiple impls? DEBUG("Converted UfcsKnown - " << e.path << " = " << ty); @@ -2087,7 +2088,7 @@ bool TraitResolution::find_named_trait_in_trait(const Span& sp, BUG(sp, "Incorrect number of parameters for trait"); } - const auto monomorph_cb = [&](const auto& gt)->const auto& { + const auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return target_type; @@ -2132,7 +2133,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple // TODO: A bound can imply something via its associated types. How deep can this go? // E.g. `T: IntoIterator<Item=&u8>` implies `<T as IntoIterator>::IntoIter : Iterator<Item=&u8>` - return this->iterate_bounds([&](const auto& b) { + return this->iterate_bounds([&](const auto& b)->bool { if( b.is_TraitBound() ) { const auto& e = b.as_TraitBound(); @@ -2207,7 +2208,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple for(const auto& bound : at.m_trait_bounds) { if( bound.m_path.m_path == trait ) { - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return *assoc_info->type; @@ -2335,7 +2336,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, DEBUG("- Search positive impls"); bool positive_found = false; this->m_crate.find_auto_trait_impls(trait, type, this->m_ivars.callback_resolve_infer(), - [&](const auto& impl) { + [&](const auto& impl)->bool { // Skip any negative impls on this pass if( impl.is_positive != true ) return false; @@ -2351,7 +2352,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, return false; } - auto monomorph = [&](const auto& gt)->const auto& { + auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); assert( ge.binding < impl_params.size() ); @@ -2454,7 +2455,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, TU_MATCH( ::HIR::Path::Data, (e.path.m_data), (pe), (Generic, ::HIR::TypeRef tmp; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { BUG(sp, "Self type in struct/enum generics"); @@ -2469,7 +2470,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, } }; // HELPER: Get a possibily monomorphised version of the input type (stored in `tmp` if needed) - auto monomorph_get = [&](const auto& ty)->const auto& { + auto monomorph_get = [&](const auto& ty)->const ::HIR::TypeRef& { if( monomorphise_type_needed(ty) ) { return (tmp = monomorphise_type_with(sp, ty, monomorph_cb)); } @@ -2595,7 +2596,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ) const { impl_params.resize( impl_params_def.m_types.size() ); - auto cb = [&](auto idx, const auto& ty) { + auto cb = [&](auto idx, const auto& ty)->::HIR::Compare{ DEBUG("[ftic_check_params] Param " << idx << " = " << ty); assert( idx < impl_params.size() ); if( ! impl_params[idx] ) { @@ -2608,7 +2609,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, } }; - //auto cb_res = [&](const auto& ty)->const auto& { + //auto cb_res = [&](const auto& ty)->const ::HIR::TypeRef& { // if( ty.m_data.is_Infer() ) { // return this->m_ivars.get_type(ty); // } @@ -2652,7 +2653,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i); } } - auto cb_infer = [&](const auto& ty)->const auto& { + auto cb_infer = [&](const auto& ty)->const ::HIR::TypeRef& { if( ty.m_data.is_Infer() ) return this->m_ivars.get_type(ty); #if 0 @@ -2677,7 +2678,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, else return ty; }; - auto cb_match = [&](unsigned int idx, const auto& ty) { + auto cb_match = [&](unsigned int idx, const auto& ty)->::HIR::Compare { if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding == idx ) return ::HIR::Compare::Equal; if( idx >> 8 == 2 ) { @@ -2697,7 +2698,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, return ::HIR::Compare::Unequal; } }; - auto monomorph = [&](const auto& gt)->const auto& { + auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); assert( ge.binding < impl_params.size() ); @@ -2862,20 +2863,7 @@ bool TraitResolution::trait_contains_method(const Span& sp, const ::HIR::Generic return true; } - auto monomorph_cb = [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return self; - } - else if( (ge.binding >> 8) == 0 ) { - auto idx = ge.binding & 0xFF; - assert(idx < trait_path.m_params.m_types.size()); - return trait_path.m_params.m_types[ge.binding]; - } - else { - BUG(sp, "Unexpected type parameter " << gt); - } - }; + auto monomorph_cb = monomorphise_type_get_cb(sp, &self, &trait_path.m_params, nullptr); for(const auto& st : trait_ptr.m_all_parent_traits) { if( trait_contains_method_(*st.m_trait_ptr, name, ar) ) @@ -2898,7 +2886,7 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa return true; } - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); assert(ge.binding < 256); assert(ge.binding < trait_path.m_params.m_types.size()); @@ -2985,7 +2973,7 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa const auto& lang_Copy = this->m_crate.get_lang_item_path(sp, "copy"); // NOTE: Don't use find_trait_impls, because that calls this bool is_fuzzy = false; - bool has_eq = find_trait_impls_crate(sp, lang_Copy, ::HIR::PathParams{}, ty, [&](auto , auto c){ + bool has_eq = find_trait_impls_crate(sp, lang_Copy, ::HIR::PathParams{}, ty, [&](auto , auto c)->bool{ switch(c) { case ::HIR::Compare::Equal: return true; @@ -3021,7 +3009,7 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa (Generic, // TODO: Store this result - or even pre-calculate it. const auto& lang_Copy = this->m_crate.get_lang_item_path(sp, "copy"); - return this->iterate_bounds([&](const auto& b) { + return this->iterate_bounds([&](const auto& b)->bool { TU_IFLET(::HIR::GenericBound, b, TraitBound, be, if(be.type == ty) { @@ -3030,7 +3018,7 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa ::HIR::PathParams pp; bool rv = this->find_named_trait_in_trait(sp, lang_Copy,pp, *be.trait.m_trait_ptr, be.trait.m_path.m_path, be.trait.m_path.m_params, type, - [&](const auto& , const auto&, const auto&) { return true; } + [&](const auto& , const auto&, const auto&)->bool { return true; } ); if(rv) return true; @@ -3637,7 +3625,7 @@ bool TraitResolution::find_method( // `Self` = `*e.type` // `/*I:#*/` := `e.trait.m_params` - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return *e.type; @@ -3800,7 +3788,7 @@ bool TraitResolution::find_method( ::HIR::PathParams trait_params; trait_params.m_types.reserve( n_params ); for(unsigned int i = 0; i < n_params; i++) { - trait_params.m_types.push_back( ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Infer({ ivars[i], ::HIR::InferClass::None }) ) ); + trait_params.m_types.push_back( ::HIR::TypeRef::new_infer(ivars[i], ::HIR::InferClass::None) ); ASSERT_BUG(sp, m_ivars.get_type( trait_params.m_types.back() ).m_data.as_Infer().index == ivars[i], "A method selection ivar was bound"); } @@ -3877,7 +3865,7 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const // Has fields! const auto& str = *be; const auto& params = e.path.m_data.as_Generic().m_params; - auto monomorph = [&](const auto& gt)->const auto& { + auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) TODO(sp, "Monomorphise struct field types (Self) - " << gt); @@ -3922,7 +3910,7 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const (Union, const auto& unm = *be; const auto& params = e.path.m_data.as_Generic().m_params; - auto monomorph = [&](const auto& gt)->const auto& { + auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) TODO(sp, "Monomorphise union field types (Self) - " << gt); diff --git a/src/hir_typeck/impl_ref.cpp b/src/hir_typeck/impl_ref.cpp index 81f018b4..d3cfd215 100644 --- a/src/hir_typeck/impl_ref.cpp +++ b/src/hir_typeck/impl_ref.cpp @@ -86,7 +86,7 @@ bool ImplRef::type_is_specialisable(const char* name) const ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> ImplRef::get_cb_monomorph_traitimpl(const Span& sp) const { const auto& e = this->m_data.as_TraitImpl(); - return [this,&e,&sp](const auto& gt)->const auto& { + return [this,&e,&sp](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { // Store (or cache) a monomorphisation of Self, and error if this recurses diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index ad0fc46b..d8b692c9 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -23,7 +23,7 @@ void StaticTraitResolve::prep_indexes() this->m_type_equalities.insert(::std::make_pair( mv$(long_ty), mv$(short_ty) )); }; - this->iterate_bounds([&](const auto& b) { + this->iterate_bounds([&](const auto& b)->bool { TU_MATCH_DEF(::HIR::GenericBound, (b), (be), ( ), @@ -38,7 +38,7 @@ void StaticTraitResolve::prep_indexes() } const auto& trait_params = be.trait.m_path.m_params; - auto cb_mono = [&](const auto& ty)->const auto& { + auto cb_mono = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return be.type; @@ -93,7 +93,7 @@ bool StaticTraitResolve::find_impl( ) const { TRACE_FUNCTION_F(trait_path << FMT_CB(os, if(trait_params) { os << *trait_params; } else { os << "<?>"; }) << " for " << type); - auto cb_ident = [](const auto&ty)->const auto&{return ty;}; + auto cb_ident = [](const ::HIR::TypeRef&ty)->const ::HIR::TypeRef& { return ty; }; static ::HIR::PathParams null_params; static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; @@ -331,23 +331,39 @@ bool StaticTraitResolve::find_impl( if( m_crate.get_trait_by_path(sp, trait_path).m_is_marker ) { + struct H { + static bool find_impl__auto_trait_check(const StaticTraitResolve& self, + const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, const ::HIR::TypeRef& type, + t_cb_find_impl found_cb, + const ::HIR::MarkerImpl& impl, bool& out_rv + ) + { + DEBUG("- Auto " << (impl.is_positive ? "Pos" : "Neg") + << " impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << " " << impl.m_params.fmt_bounds()); + if (impl.is_positive) + { + return self.find_impl__check_crate_raw(sp, trait_path, trait_params, type, impl.m_params, impl.m_trait_args, impl.m_type, + [&](auto impl_params, auto placeholders, auto cmp)->bool { + //rv = found_cb( ImplRef(impl_params, trait_path, impl, mv$(placeholders)), (cmp == ::HIR::Compare::Fuzzy) ); + out_rv = found_cb(ImplRef(&type, trait_params, &null_assoc), cmp == ::HIR::Compare::Fuzzy); + return out_rv; + }); + } + else + { + return self.find_impl__check_crate_raw(sp, trait_path, trait_params, type, impl.m_params, impl.m_trait_args, impl.m_type, + [&](auto impl_params, auto placeholders, auto cmp)->bool { + out_rv = false; + return true; + }); + } + } + }; + // Positive/negative impls bool rv = false; - ret = this->m_crate.find_auto_trait_impls(trait_path, type, cb_ident, [&](const auto& impl) { - DEBUG("[find_impls] - Auto " << (impl.is_positive?"Pos":"Neg") - << " impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << " " << impl.m_params.fmt_bounds()); - return this->find_impl__check_crate_raw(sp, trait_path, trait_params, type, impl.m_params, impl.m_trait_args, impl.m_type, - [&](auto impl_params, auto placeholders, auto cmp) { - if( impl.is_positive ) { - //rv = found_cb( ImplRef(impl_params, trait_path, impl, mv$(placeholders)), (match == ::HIR::Compare::Fuzzy) ); - rv = found_cb( ImplRef(&type, trait_params, &null_assoc), cmp == ::HIR::Compare::Fuzzy ); - return rv; - } - else { - rv = false; - return true; - } - }); + ret = this->m_crate.find_auto_trait_impls(trait_path, type, cb_ident, [&](const auto& impl)->bool { + return H::find_impl__auto_trait_check(*this, sp, trait_path, trait_params, type, found_cb, impl, rv); }); if(ret) return rv; @@ -468,7 +484,7 @@ bool StaticTraitResolve::find_impl__check_bound( if( bound.m_path.m_path == trait_path && (!trait_params || H::compare_pp(sp, bound.m_path.m_params, *trait_params)) ) { DEBUG("- Found an associated type impl"); - auto tp_mono = monomorphise_traitpath_with(sp, bound, [&assoc_info,&sp](const auto& gt)->const auto& { + auto tp_mono = monomorphise_traitpath_with(sp, bound, [&assoc_info,&sp](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return *assoc_info->type; @@ -502,7 +518,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( ::std::function<bool(::std::vector<const ::HIR::TypeRef*>, ::std::vector<::HIR::TypeRef>, ::HIR::Compare)> found_cb ) const { - auto cb_ident = [](const auto&ty)->const auto&{return ty;}; + auto cb_ident = [](const auto&ty)->const ::HIR::TypeRef&{return ty;}; TRACE_FUNCTION_F("impl" << impl_params_def.fmt_args() << " " << des_trait_path << impl_trait_params << " for " << impl_type << impl_params_def.fmt_bounds()); ::std::vector< const ::HIR::TypeRef*> impl_params; @@ -543,7 +559,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( } } // Callback that matches placeholders to concrete types - auto cb_match = [&](unsigned int idx, const auto& ty) { + auto cb_match = [&](unsigned int idx, const auto& ty)->::HIR::Compare { if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding == idx ) return ::HIR::Compare::Equal; if( idx >> 8 == 2 ) { @@ -564,7 +580,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( } }; // Callback that returns monomorpisation results - auto cb_monomorph = [&](const auto& gt)->const auto& { + auto cb_monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); assert( ge.binding < impl_params.size() ); @@ -576,10 +592,10 @@ bool StaticTraitResolve::find_impl__check_crate_raw( // Bounds for(const auto& bound : impl_params_def.m_bounds) { - TU_MATCH_DEF(::HIR::GenericBound, (bound), (e), - ( - ), - (TraitBound, + if( const auto* ep = bound.opt_TraitBound() ) + { + const auto& e = *ep; + DEBUG("Trait bound " << e.type << " : " << e.trait); auto b_ty_mono = monomorphise_type_with(sp, e.type, cb_monomorph); this->expand_associated_types(sp, b_ty_mono); @@ -614,7 +630,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( rv = true; } else { - rv = this->find_impl(sp, aty_src_trait.m_path, aty_src_trait.m_params, b_ty_mono, [&](const auto& impl, bool) { + rv = this->find_impl(sp, aty_src_trait.m_path, aty_src_trait.m_params, b_ty_mono, [&](const auto& impl, bool)->bool { ::HIR::TypeRef have = impl.get_type(aty_name.c_str()); this->expand_associated_types(sp, have); @@ -649,8 +665,11 @@ bool StaticTraitResolve::find_impl__check_crate_raw( return false; } } - ) - ) + } + else // bound.opt_TraitBound() + { + // Ignore + } } return found_cb( mv$(impl_params), mv$(placeholders), match ); @@ -686,12 +705,14 @@ bool StaticTraitResolve::find_impl__check_crate( }; // - If the type is a path (struct/enum/...), search for impls for all contained types. - TU_IFLET( ::HIR::TypeRef::Data, type.m_data, Path, e, + if( const auto* ep = type.m_data.opt_Path() ) + { + const auto& e = *ep; ::HIR::Compare res = ::HIR::Compare::Equal; TU_MATCH( ::HIR::Path::Data, (e.path.m_data), (pe), (Generic, ::HIR::TypeRef tmp; - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { BUG(sp, "Self type in struct/enum generics"); @@ -706,7 +727,7 @@ bool StaticTraitResolve::find_impl__check_crate( } }; // HELPER: Get a possibily monomorphised version of the input type (stored in `tmp` if needed) - auto monomorph_get = [&](const auto& ty)->const auto& { + auto monomorph_get = [&](const auto& ty)->const ::HIR::TypeRef& { if( monomorphise_type_needed(ty) ) { tmp = monomorphise_type_with(sp, ty, monomorph_cb); this->expand_associated_types(sp, tmp); @@ -807,20 +828,22 @@ bool StaticTraitResolve::find_impl__check_crate( ) ) return res; - ) - else TU_IFLET( ::HIR::TypeRef::Data, type.m_data, Tuple, e, + } + else if( const auto* ep = type.m_data.opt_Tuple() ) + { ::HIR::Compare res = ::HIR::Compare::Equal; - for(const auto& sty : e) + for(const auto& sty : *ep) { res &= type_impls_trait(sty); if( res == ::HIR::Compare::Unequal ) return ::HIR::Compare::Unequal; } return res; - ) - else TU_IFLET( ::HIR::TypeRef::Data, type.m_data, Array, e, - return type_impls_trait(*e.inner); - ) + } + else if( const auto* e = type.m_data.opt_Array() ) + { + return type_impls_trait(*e->inner); + } // Otherwise, there's no negative so it must be positive else { return ::HIR::Compare::Equal; @@ -962,11 +985,10 @@ void StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI // 1. Bounds bool rv; bool assume_opaque = true; - rv = this->iterate_bounds([&](const auto& b) { - TU_MATCH_DEF(::HIR::GenericBound, (b), (be), - ( - ), - (TraitBound, + rv = this->iterate_bounds([&](const auto& b)->bool { + if( const auto* bep = b.opt_TraitBound() ) + { + const auto& be = *bep; DEBUG("Trait bound - " << be.type << " : " << be.trait); // 1. Check if the type matches // - TODO: This should be a fuzzier match? @@ -1018,15 +1040,20 @@ void StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI } // - Didn't match - ), - (TypeEquality, + } + else if( const auto* bep = b.opt_TypeEquality() ) + { + const auto& be = *bep; DEBUG("Equality - " << be.type << " = " << be.other_type); if( input == be.type ) { input = be.other_type.clone(); return true; } - ) - ) + } + else + { + // Nothing. + } return false; }); if( rv ) { @@ -1050,7 +1077,7 @@ void StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI const auto& assoc_ty = trait_ptr.m_types.at(pe_inner.item); // Resolve where Self=pe_inner.type (i.e. for the trait this inner UFCS is on) - auto cb_placeholders_trait = [&](const auto& ty)->const auto&{ + auto cb_placeholders_trait = [&](const auto& ty)->const ::HIR::TypeRef&{ TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Generic, e, if( e.binding == 0xFFFF ) return *pe_inner.type; @@ -1231,7 +1258,7 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp, BUG(sp, "Incorrect number of parameters for trait - " << trait_path << pp); } - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { return target_type; @@ -1266,7 +1293,7 @@ bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::Generi return true; } - auto monomorph = [&](const auto& gt)->const auto& { + auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); assert(ge.binding < 256); assert(ge.binding < trait_path.m_params.m_types.size()); @@ -1295,7 +1322,7 @@ bool StaticTraitResolve::type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) return it->second; } } - bool rv = this->iterate_bounds([&](const auto& b) { + bool rv = this->iterate_bounds([&](const auto& b)->bool { auto pp = ::HIR::PathParams(); return this->find_impl__check_bound(sp, m_lang_Copy, &pp, ty, [&](auto , bool ){ return true; }, b); }); @@ -1907,7 +1934,7 @@ StaticTraitResolve::ValuePtr StaticTraitResolve::get_value(const Span& sp, const out_params.pp_impl = &out_params.pp_impl_data; out_params.pp_method = &pe.params; ValuePtr rv; - m_crate.find_type_impls(*pe.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) { + m_crate.find_type_impls(*pe.type, [](const auto&x)->const ::HIR::TypeRef& { return x; }, [&](const auto& impl) { DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type); // TODO: Populate pp_impl // TODO: Specialisation diff --git a/src/include/cpp_unpack.h b/src/include/cpp_unpack.h index d5087668..69417589 100644 --- a/src/include/cpp_unpack.h +++ b/src/include/cpp_unpack.h @@ -25,7 +25,7 @@ // Macro to obtain a numbered macro for argument counts // - Raw variant #define CC_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,COUNT,...) SUF##COUNT -#define CC_GM(SUF,...) CC_GM_I(SUF,__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) +#define CC_GM(SUF,...) CC_EXP( CC_GM_I(SUF,__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) ) #define CC_ITERATE(fcn, args, ...) CC_EXP( CC_GM(CC_CALL_A, __VA_ARGS__)(fcn, args, __VA_ARGS__) ) diff --git a/src/include/debug.hpp b/src/include/debug.hpp index ce2f89da..2bbecb39 100644 --- a/src/include/debug.hpp +++ b/src/include/debug.hpp @@ -38,11 +38,14 @@ struct RepeatLitStr } }; -class NullSink: - public ::std::ostream +class NullSink { public: - NullSink() {} + NullSink() + {} + + template<typename T> + const NullSink& operator<<(const T&) const { return *this; } }; class TraceLog @@ -59,11 +62,15 @@ public: struct FmtLambda { ::std::function<void(::std::ostream&)> m_cb; + FmtLambda(::std::function<void(::std::ostream&)> cb): + m_cb(cb) + { } friend ::std::ostream& operator<<(::std::ostream& os, const FmtLambda& x) { x.m_cb(os); return os; } }; -#define FMT_CB(os, ...) ::FmtLambda { [&](auto& os) { __VA_ARGS__ } } +#define FMT_CB(os, ...) ::FmtLambda( [&](auto& os) { __VA_ARGS__; } ) +#define FMT_CB_S(...) ::FmtLambda( [&](auto& _os) { _os << __VA_ARGS__; } ) diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp index 6a9abf95..0d6d781a 100644 --- a/src/include/serialise.hpp +++ b/src/include/serialise.hpp @@ -25,7 +25,7 @@ class Deserialiser; #define SERIALISE_TU(class_, tag_str, val_name, ...) SERIALISE_TYPE(class_::, tag_str,\ {\ s << class_::tag_to_str(this->tag());\ - TU_MATCH(class_, (*this), (val_name), __VA_ARGS__);\ + TU_MATCH(class_, (*this), (val_name), __VA_ARGS__)\ },/* */ {\ ::std::string STU_tag_str;\ @@ -41,7 +41,7 @@ class Deserialiser; */ auto& VAL_NAME = this->as_##TAG(); /* */ __VA_ARGS__/* */} break; -#define SERIALISE_TU_MATCH_ARMS(CLASS, NAME, ...) TU_GMA(__VA_ARGS__)(SERIALISE_TU_MATCH_ARM, (CLASS, NAME), __VA_ARGS__) +#define SERIALISE_TU_MATCH_ARMS(CLASS, NAME, ...) TU_EXP1( TU_GMA(__VA_ARGS__)(SERIALISE_TU_MATCH_ARM, (CLASS, NAME), __VA_ARGS__) ) class DeserialiseFailure: public ::std::runtime_error @@ -141,7 +141,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; } + void item(unsigned int& v) { uint64_t v1; this->item(v1); v = static_cast<unsigned int>(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/synext_decorator.hpp b/src/include/synext_decorator.hpp index c3985855..4988c624 100644 --- a/src/include/synext_decorator.hpp +++ b/src/include/synext_decorator.hpp @@ -57,14 +57,25 @@ public: virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate, ::AST::ExprNode_Match_Arm& expr) const { unexpected(sp, mi, "match arm"); } }; -#define STATIC_DECORATOR(ident, _handler_class) \ - struct register_##_handler_class##_c {\ - register_##_handler_class##_c() {\ - Register_Synext_Decorator( ident, ::std::unique_ptr<ExpandDecorator>(new _handler_class()) ); \ - } \ - } s_register_##_handler_class; - +struct DecoratorDef; extern void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler); +extern void Register_Synext_Decorator_Static(DecoratorDef* def); + +struct DecoratorDef +{ + DecoratorDef* prev; + ::std::string name; + ::std::unique_ptr<ExpandDecorator> def; + DecoratorDef(::std::string name, ::std::unique_ptr<ExpandDecorator> def): + name(::std::move(name)), + def(::std::move(def)), + prev(nullptr) + { + Register_Synext_Decorator_Static(this); + } +}; + +#define STATIC_DECORATOR(ident, _handler_class) static DecoratorDef s_register_##_handler_class ( ident, ::std::unique_ptr<ExpandDecorator>(new _handler_class()) ); #endif diff --git a/src/include/synext_macro.hpp b/src/include/synext_macro.hpp index 400016d9..c109b56e 100644 --- a/src/include/synext_macro.hpp +++ b/src/include/synext_macro.hpp @@ -25,14 +25,25 @@ public: virtual ::std::unique_ptr<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; }; -#define STATIC_MACRO(ident, _handler_class) \ - struct register_##_handler_class##_c {\ - register_##_handler_class##_c() {\ - Register_Synext_Macro( ident, ::std::unique_ptr<ExpandProcMacro>(new _handler_class()) ); \ - } \ - } s_register_##_handler_class; - +struct MacroDef; extern void Register_Synext_Macro(::std::string name, ::std::unique_ptr<ExpandProcMacro> handler); +extern void Register_Synext_Macro_Static(MacroDef* def); + +struct MacroDef +{ + MacroDef* prev; + ::std::string name; + ::std::unique_ptr<ExpandProcMacro> def; + MacroDef(::std::string name, ::std::unique_ptr<ExpandProcMacro> def) : + name(::std::move(name)), + def(::std::move(def)), + prev(nullptr) + { + Register_Synext_Macro_Static(this); + } +}; + +#define STATIC_MACRO(ident, _handler_class) static MacroDef s_register_##_handler_class(ident, ::std::unique_ptr<ExpandProcMacro>(new _handler_class())); #endif diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 9bd060d6..fbd42a77 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -10,59 +10,59 @@ //#include "cpp_unpack.h" #include <cassert> +#include <string> + +#define TU_FIRST(a, ...) a +#define TU_EXP1(x) x +#define TU_EXP(...) __VA_ARGS__ #define TU_CASE_ITEM(src, mod, var, name) mod auto& name = src.as_##var(); (void)&name; #define TU_CASE_BODY(class,var, ...) case class::var: { __VA_ARGS__ } break; #define TU_CASE(mod, class, var, name,src, ...) TU_CASE_BODY(mod,class,var, TU_CASE_ITEM(src,mod,var,name) __VA_ARGS__) #define TU_CASE2(mod, class, var, n1,s1, n2,s2, ...) TU_CASE_BODY(mod,class,var, TU_CASE_ITEM(s1,mod,var,n1) TU_CASE_ITEM(s2,mod,var,n2) __VA_ARGS__) -#define TU_FIRST(a, ...) a // Argument iteration -#define _DISP0(n) -#define _DISP1(n, _1) n _1 -#define _DISP2(n, _1, _2) n _1 n _2 -#define _DISP3(n, v, v2, v3) n v n v2 n v3 -#define _DISP4(n, v, v2, v3, v4) n v n v2 n v3 n v4 -#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, a1,a2,a3,a4, b1,b2,b3,b4, c1) _DISP4(n, a1,a2,a3,a4) _DISP3(n, b1,b2,b3) _DISP2(n, b4,c1) -#define _DISP10(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2) _DISP4(n, a1,a2,a3,a4) _DISP4(n, b1,b2,b3,b4) _DISP2(n, c1,c2) -#define _DISP11(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3) _DISP4(n, a1,a2,a3,a4) _DISP4(n, b1,b2,b3,b4) _DISP3(n, c1,c2,c3) -#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) -#define _DISP13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP4(n, b1,b2,b3,b4) _DISP4(n, c1,c2,c3,c4) -#define _DISP14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP4(n, c1,c2,c3,c4) -#define _DISP15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5) -#define _DISP16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5) _DISP1(n, d1) - -#define _DISPO0(n) -#define _DISPO1(n, _1) n(_1) -#define _DISPO2(n, _1, _2) n(_1) n(_2) -#define _DISPO3(n, v, v2, v3) n(v) n(v2) n(v3) -#define _DISPO4(n, v, v2, v3, v4) n(v) n(v2) n(v3) n(v4) -#define _DISPO5(n, v, ...) n v _DISPO4(n, __VA_ARGS__) -#define _DISPO6(n, v, ...) n v _DISPO5(n, __VA_ARGS__) -#define _DISPO7(n, v, ...) n v _DISPO6(n, __VA_ARGS__) -#define _DISPO8(n, v, ...) n v _DISPO7(n, __VA_ARGS__) -#define _DISPO9(n, a1,a2,a3,a4, b1,b2,b3,b4, c1) _DISPO4(n, a1,a2,a3,a4) _DISPO3(n, b1,b2,b3) _DISPO2(n, b4,c1) -#define _DISPO10(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2) _DISPO4(n, a1,a2,a3,a4) _DISPO4(n, b1,b2,b3,b4) _DISPO2(n, c1,c2) -#define _DISPO11(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3) _DISPO4(n, a1,a2,a3,a4) _DISPO4(n, b1,b2,b3,b4) _DISPO3(n, c1,c2,c3) -#define _DISPO12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) _DISPO4(n, a1,a2,a3,a4) _DISPO4(n, b1,b2,b3,b4) _DISPO4(n, c1,c2,c3,c4) -#define _DISPO13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO4(n, b1,b2,b3,b4) _DISPO4(n, c1,c2,c3,c4) -#define _DISPO14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO4(n, c1,c2,c3,c4) -#define _DISPO15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5) -#define _DISPO16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5) _DISPO1(n, d1) +#define TU_DISP0(n) +#define TU_DISP1(n, _1) n _1 +#define TU_DISP2(n, _1, _2) n _1 n _2 +#define TU_DISP3(n, v, v2, v3) n v n v2 n v3 +#define TU_DISP4(n, v, v2, v3, v4) n v n v2 n v3 n v4 +#define TU_DISP5(n, a1,a2,a3, b1,b2 ) TU_DISP3(n, a1,a2,a3) TU_DISP2(n, b1,b2) +#define TU_DISP6(n, a1,a2,a3, b1,b2,b3) TU_DISP3(n, a1,a2,a3) TU_DISP3(n, b1,b2,b3) +#define TU_DISP7(n, a1,a2,a3,a4, b1,b2,b3 ) TU_DISP4(n, a1,a2,a3,a4) TU_DISP3(n, b1,b2,b3) +#define TU_DISP8(n, a1,a2,a3,a4, b1,b2,b3,b4) TU_DISP4(n, a1,a2,a3,a4) TU_DISP4(n, b1,b2,b3,b4) +#define TU_DISP9(n, a1,a2,a3,a4, b1,b2,b3,b4, c1 ) TU_DISP4(n, a1,a2,a3,a4) TU_DISP3(n, b1,b2,b3 ) TU_DISP2(n, b4,c1) +#define TU_DISP10(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2 ) TU_DISP4(n, a1,a2,a3,a4) TU_DISP4(n, b1,b2,b3,b4) TU_DISP2(n, c1,c2) +#define TU_DISP11(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3 ) TU_DISP4(n, a1,a2,a3,a4) TU_DISP4(n, b1,b2,b3,b4) TU_DISP3(n, c1,c2,c3) +#define TU_DISP12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) TU_DISP4(n, a1,a2,a3,a4) TU_DISP4(n, b1,b2,b3,b4) TU_DISP4(n, c1,c2,c3,c4) +#define TU_DISP13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) TU_DISP5(n, a1,a2,a3,a4,a5) TU_DISP4(n, b1,b2,b3,b4) TU_DISP4(n, c1,c2,c3,c4) +#define TU_DISP14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4 ) TU_DISP5(n, a1,a2,a3,a4,a5) TU_DISP5(n, b1,b2,b3,b4,b5) TU_DISP4(n, c1,c2,c3,c4) +#define TU_DISP15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5 ) TU_DISP5(n, a1,a2,a3,a4,a5) TU_DISP5(n, b1,b2,b3,b4,b5) TU_DISP5(n, c1,c2,c3,c4,c5) +#define TU_DISP16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) TU_DISP5(n, a1,a2,a3,a4,a5) TU_DISP5(n, b1,b2,b3,b4,b5) TU_DISP5(n, c1,c2,c3,c4,c5) TU_DISP1(n, d1) + +#define TU_DISPO0(n) +#define TU_DISPO1(n, _1) n(_1) +#define TU_DISPO2(n, _1, _2) n(_1) n(_2) +#define TU_DISPO3(n, v, v2, v3) n(v) n(v2) n(v3) +#define TU_DISPO4(n, v, v2, v3, v4) n(v) n(v2) n(v3) n(v4) +#define TU_DISPO5(n, a1,a2,a3, b1,b2 ) TU_DISPO3(n, a1,a2,a3) TU_DISPO2(n, b1,b2) +#define TU_DISPO6(n, a1,a2,a3, b1,b2,b3) TU_DISPO3(n, a1,a2,a3) TU_DISPO3(n, b1,b2,b3) +#define TU_DISPO7(n, a1,a2,a3,a4, b1,b2,b3 ) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO3(n, b1,b2,b3) +#define TU_DISPO8(n, a1,a2,a3,a4, b1,b2,b3,b4) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO4(n, b1,b2,b3,b4) +#define TU_DISPO9(n, a1,a2,a3,a4, b1,b2,b3,b4, c1) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO3(n, b1,b2,b3) TU_DISPO2(n, b4,c1) +#define TU_DISPO10(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO4(n, b1,b2,b3,b4) TU_DISPO2(n, c1,c2) +#define TU_DISPO11(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO4(n, b1,b2,b3,b4) TU_DISPO3(n, c1,c2,c3) +#define TU_DISPO12(n, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4) TU_DISPO4(n, a1,a2,a3,a4) TU_DISPO4(n, b1,b2,b3,b4) TU_DISPO4(n, c1,c2,c3,c4) +#define TU_DISPO13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) TU_DISPO5(n, a1,a2,a3,a4,a5) TU_DISPO4(n, b1,b2,b3,b4) TU_DISPO4(n, c1,c2,c3,c4) +#define TU_DISPO14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) TU_DISPO5(n, a1,a2,a3,a4,a5) TU_DISPO5(n, b1,b2,b3,b4,b5) TU_DISPO4(n, c1,c2,c3,c4) +#define TU_DISPO15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) TU_DISPO5(n, a1,a2,a3,a4,a5) TU_DISPO5(n, b1,b2,b3,b4,b5) TU_DISPO5(n, c1,c2,c3,c4,c5) +#define TU_DISPO16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) TU_DISPO5(n, a1,a2,a3,a4,a5) TU_DISPO5(n, b1,b2,b3,b4,b5) TU_DISPO5(n, c1,c2,c3,c4,c5) TU_DISPO1(n, d1) #define TU_DISPA(n, a) n a #define TU_DISPA1(n, a, _1) TU_DISPA(n, (TU_EXP a, TU_EXP _1)) -#define TU_DISPA2(n, a, _1, _2) TU_DISPA(n, (TU_EXP a, TU_EXP _1))/* -*/ TU_DISPA(n, (TU_EXP a, TU_EXP _2)) -#define TU_DISPA3(n, a, _1, _2, _3) \ - TU_DISPA(n, (TU_EXP a, TU_EXP _1))/* -*/ TU_DISPA(n, (TU_EXP a, TU_EXP _2))/* -*/ TU_DISPA(n, (TU_EXP a, TU_EXP _3)) +#define TU_DISPA2(n, a, _1, _2) TU_DISPA(n, (TU_EXP a, TU_EXP _1)) TU_DISPA(n, (TU_EXP a, TU_EXP _2)) +#define TU_DISPA3(n, a, _1, _2, _3) TU_DISPA(n, (TU_EXP a, TU_EXP _1)) TU_DISPA(n, (TU_EXP a, TU_EXP _2)) TU_DISPA(n, (TU_EXP a, TU_EXP _3)) #define TU_DISPA4(n, a, a1,a2, b1,b2) TU_DISPA2(n,a, a1,a2) TU_DISPA2(n,a, b1,b2) #define TU_DISPA5(n, a, a1,a2,a3, b1,b2) TU_DISPA3(n,a, a1,a2,a3) TU_DISPA2(n,a, b1,b2) #define TU_DISPA6(n, a, a1,a2,a3, b1,b2,b3) TU_DISPA3(n,a, a1,a2,a3) TU_DISPA3(n,a, b1,b2,b3) @@ -80,29 +80,10 @@ // Macro to obtain a numbered macro for argument counts // - Raw variant #define TU_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,COUNT,...) SUF##COUNT -#define TU_GM(SUF,...) TU_GM_I(SUF, __VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define TU_GM(SUF,...) TU_EXP1( TU_GM_I(SUF, __VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) ) // - _DISP based variant (for iteration) -#define TU_GMX(...) TU_GM(_DISP, __VA_ARGS__) -#define TU_GMA(...) TU_GM(TU_DISPA, __VA_ARGS__) - -// Sizes of structures -#define TU_SO(name, ...) sizeof(TU_DATANAME(name)) -#define MAX2(a, b) (a < b ? b : a) -#define MAXS2(a, b) (TU_SO a < TU_SO b ? TU_SO b : TU_SO a) -#define MAXS3(a, b, c) MAX2(MAXS2(a, b), TU_SO c) -#define MAXS4(a, b, c, d) MAX2(MAXS2(a, b), MAXS2(c, d)) -#define MAXS5(a, b, c, d, e) MAX2(MAXS3(a, b, c), MAXS2(d, e)) -#define MAXS6(a, b, c, d, e, f) MAX2(MAXS3(a, b, c), MAXS3(d, e, f)) -#define MAXS7(a, b, c, d, e, f, g) MAX2(MAXS3(a, b, c), MAXS4(d, e, f, g)) -#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)) -#define MAXS13(a1,a2,a3,a4,a5,a6,a7, b1,b2,b3,b4,b5,b6) MAX2(MAXS7(a1,a2,a3,a4,a5,a6,a7), MAXS6(b1,b2,b3,b4,b5,b6)) -#define MAXS14(a1,a2,a3,a4,a5,a6,a7, b1,b2,b3,b4,b5,b6,b7) MAX2(MAXS7(a1,a2,a3,a4,a5,a6,a7), MAXS7(b1,b2,b3,b4,b5,b6,b7)) -#define MAXS15(a1,a2,a3,a4,a5,a6,a7,a8, b1,b2,b3,b4,b5,b6,b7) MAX2(MAXS8(a1,a2,a3,a4,a5,a6,a7,a8), MAXS7(b1,b2,b3,b4,b5,b6,b7)) -#define MAXS16(a1,a2,a3,a4,a5,a6,a7,a8, b1,b2,b3,b4,b5,b6,b7,b8) MAX2(MAXS8(a1,a2,a3,a4,a5,a6,a7,a8), MAXS8(b1,b2,b3,b4,b5,b6,b7,b8)) +#define TU_GMX(...) TU_EXP1( TU_GM(TU_DISP, __VA_ARGS__) ) +#define TU_GMA(...) TU_EXP1( TU_GM(TU_DISPA, __VA_ARGS__) ) // TODO: use `decltype` in place of the `class` argument to TU_MATCH/TU_IFLET // "match"-like statement @@ -119,12 +100,12 @@ */} #define TU_MATCH_BIND1(TAG, VAR, NAME) /*MATCH_BIND*/ auto& NAME = (VAR).as_##TAG(); (void)&NAME; #define TU_MATCH_BIND2_(TAG, v1,v2, n1,n2) TU_MATCH_BIND1(TAG, v1, n1) TU_MATCH_BIND1(TAG, v2, n2) -#define TU_MATCH_BIND2(...) TU_MATCH_BIND2_(__VA_ARGS__) // << Exists to cause expansion of the vars +#define TU_MATCH_BIND2(...) TU_EXP1( TU_MATCH_BIND2_(__VA_ARGS__) ) // << Exists to cause expansion of the vars #define TU_MATCH_ARM(CLASS, VAR, NAME, TAG, ...) case CLASS::TAG_##TAG: {/* */ TU_GM(TU_MATCH_BIND, TU_EXP VAR)(TAG, TU_EXP VAR , TU_EXP NAME)/* */ __VA_ARGS__/* */} break; -#define TU_MATCH_ARMS(CLASS, VAR, NAME, ...) TU_GMA(__VA_ARGS__)(TU_MATCH_ARM, (CLASS, VAR, NAME), __VA_ARGS__) +#define TU_MATCH_ARMS(CLASS, VAR, NAME, ...) TU_EXP1( TU_GMA(__VA_ARGS__)(TU_MATCH_ARM, (CLASS, VAR, NAME), __VA_ARGS__) ) #define TU_IFLET(CLASS, VAR, TAG, NAME, ...) if(VAR.tag() == CLASS::TAG_##TAG) { auto& NAME = VAR.as_##TAG(); (void)&NAME; __VA_ARGS__ } @@ -143,8 +124,7 @@ // Define a tagged union constructor #define TU_CONS(__name, name, ...) TU_CONS_I(__name, name, TU_DATANAME(name)) -// Type definitions -#define TU_EXP(...) __VA_ARGS__ +// Type definitions_ #define TU_TYPEDEF(name, ...) typedef __VA_ARGS__ TU_DATANAME(name);/* */ @@ -164,19 +144,18 @@ // "tag_from_str" internals #define TU_FROMSTR_CASE(tag,...) else if(str == #tag) return TAG_##tag;/* */ -#define TU_FROMSTR_CASES(...) TU_GMX(__VA_ARGS__)(TU_FROMSTR_CASE,__VA_ARGS__) +#define TU_FROMSTR_CASES(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_FROMSTR_CASE,__VA_ARGS__) ) #define TU_UNION_FIELD(tag, ...) TU_DATANAME(tag) tag;/* */ -#define TU_UNION_FIELDS(...) TU_GMX(__VA_ARGS__)(TU_UNION_FIELD,__VA_ARGS__) +#define TU_UNION_FIELDS(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_UNION_FIELD,__VA_ARGS__) ) -#define MAXS(...) TU_GM(MAXS,__VA_ARGS__)(__VA_ARGS__) -#define TU_CONSS(_name, ...) TU_GMA(__VA_ARGS__)(TU_CONS, (_name), __VA_ARGS__) -#define TU_TYPEDEFS(...) TU_GMX(__VA_ARGS__)(TU_TYPEDEF ,__VA_ARGS__) -#define TU_TAGS(...) TU_GMX(__VA_ARGS__)(TU_TAG ,__VA_ARGS__) -#define TU_DEST_CASES(...) TU_GMX(__VA_ARGS__)(TU_DEST_CASE,__VA_ARGS__) -#define TU_MOVE_CASES(...) TU_GMX(__VA_ARGS__)(TU_MOVE_CASE,__VA_ARGS__) -#define TU_TOSTR_CASES(...) TU_GMX(__VA_ARGS__)(TU_TOSTR_CASE ,__VA_ARGS__) +#define TU_CONSS(_name, ...) TU_EXP1( TU_GMA(__VA_ARGS__)(TU_CONS, (_name), __VA_ARGS__) ) +#define TU_TYPEDEFS(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_TYPEDEF ,__VA_ARGS__) ) +#define TU_TAGS(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_TAG ,__VA_ARGS__) ) +#define TU_DEST_CASES(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_DEST_CASE ,__VA_ARGS__) ) +#define TU_MOVE_CASES(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_MOVE_CASE ,__VA_ARGS__) ) +#define TU_TOSTR_CASES(...) TU_EXP1( TU_GMX(__VA_ARGS__)(TU_TOSTR_CASE,__VA_ARGS__) ) /** * Define a new tagged union @@ -191,7 +170,7 @@ * ); * ``` */ -#define TAGGED_UNION(_name, _def, ...) TAGGED_UNION_EX(_name, (), _def, (__VA_ARGS__), (), (), ()) +#define TAGGED_UNION(_name, _def, ...) TU_EXP1( TAGGED_UNION_EX(_name, (), _def, (TU_EXP(__VA_ARGS__)), (), (), ()) ) #define TAGGED_UNION_EX(_name, _inherit, _def, _variants, _extra_move, _extra_assign, _extra) \ class _name TU_EXP _inherit { \ typedef _name self_t;/* diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 11ec74f2..18ef563e 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -564,7 +564,7 @@ public: const MacroExpansionEnt* next_ent(); const ::std::vector<unsigned int> iterations() const { return m_iterations; } - unsigned int top_pos() const { return m_offsets[0].read_pos; } + unsigned int top_pos() const { if(m_offsets.empty()) return 0; return m_offsets[0].read_pos; } private: const MacroExpansionEnt& getCurLayerEnt() const; diff --git a/src/main.cpp b/src/main.cpp index 1c52de8c..ec4e9f38 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -258,19 +258,18 @@ int main(int argc, char *argv[]) crate_name = ::std::string(params.infile.begin() + s, params.infile.begin() + e); for(auto& b : crate_name) { - switch(b) - { - case '0' ... '9': - case 'A' ... 'Z': - case 'a' ... 'z': - case '_': - break; - case '-': - b = '_'; - break; - default: - break; - } + if ('0' <= b && b <= '9') { + } + else if ('A' <= b && b <= 'Z') { + } + else if (b == '_') { + } + else if (b == '-') { + b = '_'; + } + else { + // TODO: Error? + } } } crate.m_crate_name = crate_name; @@ -572,12 +571,14 @@ ProgramParams::ProgramParams(int argc, char *argv[]) if( arg[0] != '-' ) { - if( this->infile != "" ) - ; - this->infile = arg; - - if( this->infile == "" ) - ; + if (this->infile == "") + { + this->infile = arg; + } + else + { + // TODO: Error + } } else if( arg[1] != '-' ) { @@ -646,14 +647,15 @@ ProgramParams::ProgramParams(int argc, char *argv[]) } this->crate_path = argv[++i]; } - else if( strcmp(arg, "--out-dir") == 0 ) { - if( i == argc - 1 ) { - ::std::cerr << "Flag " << arg << " requires an argument" << ::std::endl; - exit(1); - } - this->output_dir = argv[++i]; - if( this->output_dir == "" ) - ; + else if (strcmp(arg, "--out-dir") == 0) { + if (i == argc - 1) { + ::std::cerr << "Flag " << arg << " requires an argument" << ::std::endl; + exit(1); + } + this->output_dir = argv[++i]; + if (this->output_dir == "") { + // TODO: Error? + } if( this->output_dir.back() != '/' ) this->output_dir += '/'; } diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 54b831df..4b9dfd8b 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -689,7 +689,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path // TODO: Check suitability of source type (COMPLEX) ), (BinOp, - #if 0 + /* ::HIR::TypeRef tmp_l, tmp_r; const auto& ty_l = state.get_lvalue_type(tmp_l, e.val_l); const auto& ty_r = state.get_lvalue_type(tmp_r, e.val_r); @@ -704,7 +704,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path if( ty_l != ty_r ) MIR_BUG(state, "Type mismatch in binop, " << ty_l << " != " << ty_r); } - #endif + */ // TODO: Check return type ), (UniOp, @@ -721,8 +721,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ity_p = &*ty.m_data.as_Borrow().inner; else if( ty.m_data.is_Pointer() ) ity_p = &*ty.m_data.as_Pointer().inner; - else + else { MIR_BUG(state, "DstMeta requires a &-ptr as input, got " << ty); + } const auto& ity = *ity_p; if( ity.m_data.is_Generic() ) ; @@ -754,8 +755,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ity_p = &*ty.m_data.as_Borrow().inner; else if( ty.m_data.is_Pointer() ) ity_p = &*ty.m_data.as_Pointer().inner; - else + else { MIR_BUG(state, "DstPtr requires a &-ptr as input, got " << ty); + } const auto& ity = *ity_p; if( ity.m_data.is_Slice() ) ; @@ -781,8 +783,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ity_p = &*te->inner; else if( const auto* te = ty.m_data.opt_Pointer() ) ity_p = &*te->inner; - else + else { MIR_BUG(state, "DstMeta requires a pointer as output, got " << ty); + } assert(ity_p); auto meta = get_metadata_type(state, *ity_p); if( meta == ::HIR::TypeRef() ) diff --git a/src/mir/check_full.cpp b/src/mir/check_full.cpp index 52c0aaf5..cacd9bef 100644 --- a/src/mir/check_full.cpp +++ b/src/mir/check_full.cpp @@ -754,9 +754,10 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio TU_MATCHA( (blk.statements[i]), (se), (Assign, - #if ENABLE_LEAK_DETECTOR - // TODO: Check if the target isn't valid. Allow if either invaid, or too complex to know. - #endif + if( ENABLE_LEAK_DETECTOR ) + { + // TODO: Check if the target isn't valid. Allow if either invaid, or too complex to know. + } TU_MATCHA( (se.src), (ve), (Use, state.move_lvalue(mir_res, ve); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 6b756952..d9796aed 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -961,19 +961,16 @@ namespace { case _(Sub): op = ::MIR::eBinOp::SUB; if(0) case _(Mul): op = ::MIR::eBinOp::MUL; if(0) case _(Div): op = ::MIR::eBinOp::DIV; if(0) - case _(Mod): op = ::MIR::eBinOp::MOD; if(0) - ; + case _(Mod): op = ::MIR::eBinOp::MOD; this->generate_checked_binop(sp, mv$(dst), op, mv$(dst_clone), ty_slot, mv$(val_p), ty_val); break; case _(Xor): op = ::MIR::eBinOp::BIT_XOR; if(0) case _(Or ): op = ::MIR::eBinOp::BIT_OR ; if(0) - case _(And): op = ::MIR::eBinOp::BIT_AND; if(0) - ; + case _(And): op = ::MIR::eBinOp::BIT_AND; this->generate_checked_binop(sp, mv$(dst), op, mv$(dst_clone), ty_slot, mv$(val_p), ty_val); break; case _(Shl): op = ::MIR::eBinOp::BIT_SHL; if(0) - case _(Shr): op = ::MIR::eBinOp::BIT_SHR; if(0) - ; + case _(Shr): op = ::MIR::eBinOp::BIT_SHR; this->generate_checked_binop(sp, mv$(dst), op, mv$(dst_clone), ty_slot, mv$(val_p), ty_val); break; } @@ -1963,7 +1960,7 @@ namespace { (Function, // TODO: Why not use the result type? //auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pe.m_params); - auto monomorph_cb = [&](const auto& gt)->const auto& { + auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& e = gt.m_data.as_Generic(); if( e.binding == 0xFFFF ) { BUG(sp, "Reference to Self in free function - " << gt); @@ -2029,7 +2026,7 @@ namespace { ), (UfcsInherent, // 1. Find item in an impl block - auto rv = m_builder.crate().find_type_impls(*pe.type, [&](const auto& ty)->const auto& { return ty; }, + auto rv = m_builder.crate().find_type_impls(*pe.type, [&](const auto& ty)->const ::HIR::TypeRef& { return ty; }, [&](const auto& impl) { DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type); // Associated functions diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index 291fbe7f..6b10d5bd 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -56,6 +56,7 @@ TAGGED_UNION_EX(VarState, (), Invalid, ( // Partially valid (Map of field states) (Partial, struct { ::std::vector<VarState> inner_states; + unsigned int outer_flag; // If ~0u there's no condition on the outer }), (MovedOut, struct { ::std::unique_ptr<VarState> inner_state; diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 46331ca6..a68fd1bf 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -2240,22 +2240,6 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& ), (Array, TODO(sp, "Match directly on array?"); - #if 0 - unsigned int total = 0; - for( unsigned int i = 0; i < te.size_val; i ++ ) { - unsigned int cnt = MIR_LowerHIR_Match_Simple__GeneratePattern( - builder, sp, - rules, num_rules, *te.inner, - ::MIR::LValue::make_Field({ box$(match_val.clone()), i }), - fail_bb - ); - total += cnt; - rules += cnt; - num_rules -= cnt; - if( num_rules == 0 ) - return total; - } - #endif ), (Slice, ASSERT_BUG(sp, rule.is_Slice() || rule.is_SplitSlice() || (rule.is_Value() && rule.as_Value().is_Bytes()), "Can only match slice with Bytes or Slice rules - " << rule); diff --git a/src/mir/helpers.hpp b/src/mir/helpers.hpp index d7aefe25..802ce88f 100644 --- a/src/mir/helpers.hpp +++ b/src/mir/helpers.hpp @@ -13,8 +13,8 @@ namespace HIR { class Crate; class TypeRef; -class Pattern; -class SimplePath; +struct Pattern; +struct SimplePath; } namespace MIR { @@ -22,7 +22,7 @@ namespace MIR { class Function; class LValue; class Constant; -class BasicBlock; +struct BasicBlock; class Terminator; class Statement; class RValue; diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index dc33d673..c22f8d5d 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -265,7 +265,7 @@ TAGGED_UNION(Statement, Assign, (SetDropFlag, struct { unsigned int idx; bool new_val; // If `other` is populated, this indicates that the other value should be negated - unsigned int other = ~0u; + unsigned int other; }), // Drop a value (Drop, struct { diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index 69f787c0..478146e8 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -212,7 +212,7 @@ void MirBuilder::define_variable(unsigned int idx) { auto temp = new_temporary(ty); push_stmt_assign( sp, ::MIR::LValue(temp.clone()), mv$(rv) ); - return temp; + return ::MIR::Param( mv$(temp) ); } } void MirBuilder::set_result(const Span& sp, ::MIR::RValue val) diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index ab863600..28729b93 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -965,7 +965,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) ::std::map<unsigned int, ExprNodeP> nodes; while( GET_TOK(tok, lex) == TOK_INTEGER ) { - unsigned int ofs = tok.intval(); + unsigned int ofs = static_cast<unsigned int>(tok.intval()); GET_CHECK_TOK(tok, lex, TOK_COLON); ExprNodeP val = Parse_Stmt(lex); if( ! nodes.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { diff --git a/src/parse/interpolated_fragment.hpp b/src/parse/interpolated_fragment.hpp index a3e72816..1b18845a 100644 --- a/src/parse/interpolated_fragment.hpp +++ b/src/parse/interpolated_fragment.hpp @@ -11,7 +11,7 @@ namespace AST { class Path; class ExprNode; class MetaItem; - template<typename T> class Named; + template<typename T> struct Named; class Item; }; diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 71ccbfb2..0587e443 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -14,6 +14,7 @@ #include <cstdlib> // strtol #include <typeinfo> #include <algorithm> // std::count +#include <cctype> Lexer::Lexer(const ::std::string& filename): m_path(filename.c_str()), @@ -222,7 +223,9 @@ signed int Lexer::getSymbol() bool issym(Codepoint ch) { - if( ::std::isalnum(ch.v) ) + if('0' <= ch.v && ch.v <= '9') + return true; + if( ::std::isalpha(ch.v) ) return true; if( ch == '_' ) return true; @@ -661,11 +664,11 @@ Token Lexer::getTokenInt() } } } - catch(const Lexer::EndOfFile& e) + catch(const Lexer::EndOfFile& /*e*/) { return Token(TOK_EOF); } - //assert(!"bugcheck"); + throw "Fell off the end of getTokenInt"; } Token Lexer::getTokenInt_RawString(bool is_byte) @@ -695,7 +698,7 @@ Token Lexer::getTokenInt_RawString(bool is_byte) try { ch = this->getc(); } - catch( Lexer::EndOfFile e ) { + catch( const Lexer::EndOfFile& /*e*/ ) { throw ParseError::Generic(*this, "EOF reached in raw string"); } @@ -980,7 +983,7 @@ bool Codepoint::isspace() const { case ' ': case 0xC: // ^L case 0x85: - case 0x200E ... 0x200F: // LTR / RTL markers + case 0x200E: case 0x200F: // LTR / RTL markers case 0x2028: // Line Separator case 0x2029: // Paragrah Separator return true; diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index aed2c91d..e9d086f9 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -410,7 +410,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut ::std::map<unsigned int, AST::Pattern> pats; while( GET_TOK(tok, lex) == TOK_INTEGER ) { - unsigned int ofs = tok.intval(); + unsigned int ofs = static_cast<unsigned int>(tok.intval()); GET_CHECK_TOK(tok, lex, TOK_COLON); auto val = Parse_Pattern(lex, is_refutable); if( ! pats.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { diff --git a/src/parse/token.cpp b/src/parse/token.cpp index cf0038bd..ffa566f4 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -244,11 +244,10 @@ enum eTokenType Token::typefromstr(const ::std::string& s) { if(s == "") return TOK_NULL; - #define _(t) else if( s == #t ) return t; + #define _(t) if( s == #t ) return t; #include "eTokenType.enum.h" #undef _ - else - return TOK_NULL; + return TOK_NULL; } struct EscapedString { diff --git a/src/parse/token.hpp b/src/parse/token.hpp index 0fcf0ed7..0ef8f009 100644 --- a/src/parse/token.hpp +++ b/src/parse/token.hpp @@ -49,8 +49,9 @@ namespace AST { class ExprNode; class MetaItem; class Item; + template<typename T> - class Named; + struct Named; }; class InterpolatedFragment; @@ -107,7 +108,7 @@ public: enum eTokenType type() const { return m_type; } ::std::string& str() { return m_data.as_String(); } const ::std::string& str() const { return m_data.as_String(); } - enum eCoreType datatype() const { TU_MATCH_DEF(Data, (m_data), (e), (assert(!"Getting datatype of invalid token type");), (Integer, return e.m_datatype;), (Float, return e.m_datatype;)) } + enum eCoreType datatype() const { TU_MATCH_DEF(Data, (m_data), (e), (assert(!"Getting datatype of invalid token type");), (Integer, return e.m_datatype;), (Float, return e.m_datatype;)) throw ""; } uint64_t intval() const { return m_data.as_Integer().m_intval; } double floatval() const { return m_data.as_Float().m_floatval; } diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp index 5322822f..8cb9a910 100644 --- a/src/parse/tokenstream.cpp +++ b/src/parse/tokenstream.cpp @@ -24,7 +24,7 @@ TokenStream::~TokenStream() Token TokenStream::innerGetToken() { Token ret = this->realGetToken(); - if( ret.get_pos().filename == "" ) + if( ret != TOK_EOF && ret.get_pos().filename == "" ) ret.set_pos( this->getPosition() ); //DEBUG("ret.get_pos() = " << ret.get_pos()); return ret; @@ -109,9 +109,8 @@ ProtoSpan TokenStream::start_span() const { auto p = this->getPosition(); return ProtoSpan { - .filename = p.filename, - .start_line = p.line, - .start_ofs = p.ofs, + p.filename, + p.line, p.ofs }; } Span TokenStream::end_span(ProtoSpan ps) const diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 55c949b8..4e2874f0 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -262,7 +262,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path BUG(span, "Invalid anon path segment '" << des_item_name << "'"); } assert( mod.anon_mods()[idx] ); - return ::AST::PathBinding::make_Module({&*mod.anon_mods()[idx]}); + return ::AST::PathBinding::make_Module({&*mod.anon_mods()[idx], nullptr}); } // Seach for the name defined in the module. diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 21555101..a85ab12a 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -6,6 +6,7 @@ * - Target-specific information */ #include "target.hpp" +#include <algorithm> // TODO: Replace with target selection #define POINTER_SIZE_BYTES 8 |