From c971a6fa8375598ecf9c99ee6b086e8cf957f568 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 29 Jul 2018 12:47:44 +0100 Subject: All - Initial work on supporting 1.29 as a target version --- src/hir/from_ast.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 7f25a42b..5dbf9c03 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -901,6 +901,9 @@ namespace { else if( repr_str == "simd" ) { is_simd = true; } + else if( repr_str == "transparent" ) { + // TODO: Mark so the C backend knows that it's supposed to be transparent + } else { TODO(a.span(), "Handle struct repr '" << repr_str << "'"); } @@ -1247,7 +1250,8 @@ namespace { else TU_IFLET(::HIR::TypeRef::Data, arg_self_ty.m_data, Path, e, // Box - Compare with `owned_box` lang item TU_IFLET(::HIR::Path::Data, e.path.m_data, Generic, pe, - if( pe.m_path == g_crate_ptr->get_lang_item_path(sp, "owned_box") ) + auto p = g_crate_ptr->get_lang_item_path_opt("owned_box"); + if( pe.m_path == p ) { if( pe.m_params.m_types.size() == 1 && pe.m_params.m_types[0] == self_type ) { -- cgit v1.2.3 From a88d64cbbaeaeb2725259f318f7758ae7a7a91b0 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 1 Aug 2018 18:21:01 +0800 Subject: HIR - Conversion and typecheck fixes for 1.29 --- src/ast/ast.hpp | 3 +- src/hir/dump.cpp | 33 ++++++++++++++++ src/hir/from_ast.cpp | 15 +++++++ src/hir/hir.hpp | 2 + src/hir/visitor.cpp | 11 ++++-- src/hir/visitor.hpp | 3 +- src/hir_conv/constant_evaluation.cpp | 76 ++++++++++++++++++++++++++++-------- src/hir_typeck/expr_cs.cpp | 8 ++-- src/hir_typeck/helpers.cpp | 20 +++++++++- src/hir_typeck/outer.cpp | 35 +++++++++++++---- src/hir_typeck/static.cpp | 14 +++++++ src/include/target_version.hpp | 11 ++++++ 12 files changed, 196 insertions(+), 35 deletions(-) create mode 100644 src/include/target_version.hpp (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 19f0c66b..f78d559f 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -8,8 +8,7 @@ #ifndef AST_HPP_INCLUDED #define AST_HPP_INCLUDED -#define TARGETVER_1_19 true -#define TARGETVER_1_29 true +#include #include #include diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp index 874a80a7..e607925e 100644 --- a/src/hir/dump.cpp +++ b/src/hir/dump.cpp @@ -89,13 +89,46 @@ namespace { void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override { m_os << indent() << "trait " << p.get_name() << item.m_params.fmt_args() << "\n"; + if( ! item.m_parent_traits.empty() ) + { + m_os << indent() << " " << ": "; + bool is_first = true; + for(auto& bound : item.m_parent_traits) + { + if( !is_first ) + m_os << indent() << " " << "+ "; + m_os << bound << "\n"; + is_first = false; + } + } if( ! item.m_params.m_bounds.empty() ) { m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; } m_os << indent() << "{\n"; inc_indent(); + + for(auto& i : item.m_types) + { + m_os << indent() << "type " << i.first; + if( ! i.second.m_trait_bounds.empty() ) + { + m_os << ": "; + bool is_first = true; + for(auto& bound : i.second.m_trait_bounds) + { + if( !is_first ) + m_os << " + "; + m_os << bound; + is_first = false; + } + } + //this->visit_type(i.second.m_default); + m_os << ";\n"; + } + ::HIR::Visitor::visit_trait(p, item); + dec_indent(); m_os << indent() << "}\n"; } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 5dbf9c03..9c8f34f6 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1258,6 +1258,21 @@ namespace { receiver = ::HIR::Function::Receiver::Box; } } + // TODO: for other types, support arbitary structs/paths. + // - The path must include Self as a (the only?) type param. + if( receiver == ::HIR::Function::Receiver::Free ) + { + if( pe.m_params.m_types.size() == 0 ) { + ERROR(sp, E0000, "Unsupported receiver type - " << arg_self_ty); + } + if( pe.m_params.m_types.size() != 1 ) { + TODO(sp, "Receiver types with more than one param - " << arg_self_ty); + } + if( pe.m_params.m_types[0] != self_type ) { + ERROR(sp, E0000, "Unsupported receiver type - " << arg_self_ty); + } + receiver = ::HIR::Function::Receiver::Custom; + } ) ) else { diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 20b9ad58..daa27d10 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -8,6 +8,7 @@ * Contains the expanded and desugared AST */ #pragma once +#include #include #include @@ -122,6 +123,7 @@ public: //PointerMut, //PointerConst, Box, + Custom, }; typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > args_t; diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 2e03990a..87b790ae 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -168,10 +168,9 @@ void ::HIR::Visitor::visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) this->visit_trait_path(par); } for(auto& i : item.m_types) { + auto item_path = ::HIR::ItemPath(trait_ip, i.first.c_str()); DEBUG("type " << i.first); - for(auto& bound : i.second.m_trait_bounds) - this->visit_trait_path(bound); - this->visit_type(i.second.m_default); + this->visit_associatedtype(item_path, i.second); } for(auto& i : item.m_values) { auto item_path = ::HIR::ItemPath(trait_ip, i.first.c_str()); @@ -234,6 +233,12 @@ void ::HIR::Visitor::visit_union(::HIR::ItemPath p, ::HIR::Union& item) for(auto& var : item.m_variants) this->visit_type(var.second.ent); } +void ::HIR::Visitor::visit_associatedtype(ItemPath p, ::HIR::AssociatedType& item) +{ + for(auto& bound : item.m_trait_bounds) + this->visit_trait_path(bound); + this->visit_type(item.m_default); +} void ::HIR::Visitor::visit_function(::HIR::ItemPath p, ::HIR::Function& item) { this->visit_params(item.m_params); diff --git a/src/hir/visitor.hpp b/src/hir/visitor.hpp index dbf759a4..d432b29d 100644 --- a/src/hir/visitor.hpp +++ b/src/hir/visitor.hpp @@ -33,8 +33,9 @@ public: virtual void visit_type_alias(ItemPath p, ::HIR::TypeAlias& item); virtual void visit_trait(ItemPath p, ::HIR::Trait& item); virtual void visit_struct(ItemPath p, ::HIR::Struct& item); - virtual void visit_union(ItemPath p, ::HIR::Union& item); virtual void visit_enum(ItemPath p, ::HIR::Enum& item); + virtual void visit_union(ItemPath p, ::HIR::Union& item); + virtual void visit_associatedtype(ItemPath p, ::HIR::AssociatedType& item); // - Value Items virtual void visit_function(ItemPath p, ::HIR::Function& item); virtual void visit_static(ItemPath p, ::HIR::Static& item); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 5a41e954..a2847e04 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -48,7 +48,7 @@ namespace { } }; - ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={}); + ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={}); ::HIR::Literal clone_literal(const ::HIR::Literal& v) { @@ -245,7 +245,26 @@ namespace { } } - ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant_intrinsic(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::std::string& name, const ::HIR::PathParams& params, ::std::vector< ::HIR::Literal> args) + { + TRACE_FUNCTION_F("\"" << name << "\"" << params << " " << args); + if( name == "size_of" ) { + ASSERT_BUG(sp, params.m_types.size() == 1, "size_of intrinsic takes one type param (consteval)"); + const auto& ty = params.m_types[0]; + + size_t size; + if( !Target_GetSizeOf(sp, StaticTraitResolve { crate }, ty, size) ) + { + TODO(sp, "Handle error from Target_GetSizeOf(" << ty << ") in evaluate_constant_intrinsic"); + } + return ::HIR::Literal::make_Integer(size); + } + else { + TODO(sp, "name=" << name << params << " args=" << args); + } + } + + ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args) { // TODO: Force this function/tree through the entire pipeline so we can MIR it? // - Requires a HUGE change to the way the compiler operates. @@ -260,6 +279,7 @@ namespace { ::HIR::TypeRef m_exp_type; ::HIR::TypeRef m_rv_type; ::HIR::Literal m_rv; + t_cb_generic m_monomorph_cb; Visitor(const ::HIR::Crate& crate, NewvalState newval_state, ::HIR::TypeRef exp_ty): m_crate(crate), @@ -613,7 +633,7 @@ namespace { } void visit(::HIR::ExprNode_CallPath& node) override { - + const auto& sp = node.span(); TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv); auto& fcn = get_function(node.span(), m_crate, node.m_path); @@ -651,10 +671,27 @@ namespace { exp_ret_type = fcn.m_return.clone(); - // Call by invoking evaluate_constant on the function + if( fcn.m_abi == "rust-intrinsic" ) + { + auto pp = monomorphise_path_params_with(node.span(), node.m_path.m_data.as_Generic().m_params, m_monomorph_cb, true); + m_rv = evaluate_constant_intrinsic(node.span(), m_crate, m_newval_state, fcn.m_linkage.name, pp, mv$(args)); + } + else { - TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " }"); - m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, mv$(exp_ret_type), mv$(args)); + // Call by invoking evaluate_constant on the function + t_cb_generic cb; + ::HIR::PathParams pp; + if( const auto* g = node.m_path.m_data.opt_Generic() ) + { + pp = monomorphise_path_params_with(node.span(), g->m_params, m_monomorph_cb, true); + cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pp); + } + else + { + cb = monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr); + } + TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " } - pp=" << pp); + m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, cb, mv$(exp_ret_type), mv$(args)); } } void visit(::HIR::ExprNode_CallValue& node) override { @@ -1009,6 +1046,7 @@ namespace { }; Visitor v { crate, newval_state, mv$(exp_type) }; + v.m_monomorph_cb = monomorph_cb; for(auto& arg : args) v.m_values.push_back( mv$(arg) ); const_cast<::HIR::ExprNode&>(expr).visit(v); @@ -1021,7 +1059,7 @@ namespace { return mv$(v.m_rv); } - ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) { // TODO: Full-blown miri TRACE_FUNCTION_F("exp=" << exp << ", args=" << args); @@ -1452,7 +1490,8 @@ namespace { // Call by invoking evaluate_constant on the function { TRACE_FUNCTION_F("Call const fn " << fcnp << " args={ " << call_args << " }"); - dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, fcn.m_return.clone(), mv$(call_args)); + // TODO: Correct monomorph_cb + dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, monomorph_cb, fcn.m_return.clone(), mv$(call_args)); } cur_block = e.ret_block; @@ -1461,13 +1500,13 @@ namespace { } } - ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) { if( expr.m_mir ) { - return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, mv$(exp), mv$(args)); + return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, monomorph_cb, mv$(exp), mv$(args)); } else if( expr ) { - return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, mv$(exp), mv$(args)); + return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, monomorph_cb, mv$(exp), mv$(args)); } else { BUG(sp, "Attempting to evaluate constant expression with no associated code"); @@ -1585,13 +1624,14 @@ namespace { ::HIR::Visitor::visit_type(ty); TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e, + TRACE_FUNCTION_FR(ty, ty); if( e.size_val == ~0u ) { assert(e.size); assert(*e.size); const auto& expr_ptr = *e.size; auto nvs = NewvalState { m_new_values, *m_mod_path, FMT("ty_" << &ty << "$") }; - auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, ::HIR::CoreType::Usize); + auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, monomorphise_type_get_cb(expr_ptr->span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize); if( !val.is_Integer() ) ERROR(expr_ptr->span(), E0000, "Array size isn't an integer"); e.size_val = static_cast(val.as_Integer()); @@ -1615,14 +1655,16 @@ namespace { // return ; auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$") }; - item.m_value_res = evaluate_constant(item.m_value->span(), m_crate, nvs, item.m_value, item.m_type.clone(), {}); + const auto& sp = item.m_value->span(); + item.m_value_res = evaluate_constant(sp, m_crate, nvs, item.m_value, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), item.m_type.clone(), {}); - check_lit_type(item.m_value->span(), item.m_type, item.m_value_res); + check_lit_type(sp, item.m_type, item.m_value_res); DEBUG("constant: " << item.m_type << " = " << item.m_value_res); } } void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override { + static Span sp; if( auto* e = item.m_data.opt_Value() ) { uint64_t i = 0; @@ -1630,7 +1672,9 @@ namespace { { if( var.expr ) { - auto val = evaluate_constant(var.expr->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") }, var.expr, {}); + auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") }; + const auto& sp = var.expr->span(); + auto val = evaluate_constant(sp, m_crate, nvs, var.expr, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), {}, {}); DEBUG("enum variant: " << p << "::" << var.name << " = " << val); i = val.as_Integer(); } @@ -1664,7 +1708,7 @@ namespace { void visit(::HIR::ExprNode_ArraySized& node) override { assert( node.m_size ); NewvalState nvs { m_exp.m_new_values, *m_exp.m_mod_path, FMT("array_" << &node << "$") }; - auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, ::HIR::CoreType::Usize, {}); + auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, monomorphise_type_get_cb(node.span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize, {}); if( !val.is_Integer() ) ERROR(node.span(), E0000, "Array size isn't an integer"); node.m_size_val = static_cast(val.as_Integer()); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 4f698c15..07f86d44 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -890,10 +890,10 @@ namespace { { case ::HIR::ExprNode_BinOp::Op::CmpEqu: item_name = "eq"; break; case ::HIR::ExprNode_BinOp::Op::CmpNEqu: item_name = "eq"; break; - case ::HIR::ExprNode_BinOp::Op::CmpLt: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpLtE: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpGt: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpGtE: item_name = "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpLt: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpLtE: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpGt: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpGtE: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; default: break; } assert(item_name); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 22291123..8f1f0685 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1050,8 +1050,10 @@ bool TraitResolution::iterate_bounds( ::std::function cb) const { ::HIR::GenericPath trait_path; + DEBUG("Checking ATY bounds on " << pe.trait << " :: " << pe.item); if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item, trait_path) ) BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait); + DEBUG("trait_path=" << trait_path); const auto& trait_ref = m_crate.get_trait_by_path(sp, trait_path.m_path); const auto& aty_def = trait_ref.m_types.find(pe.item)->second; @@ -1361,12 +1363,19 @@ bool TraitResolution::find_trait_impls(const Span& sp, ASSERT_BUG(sp, e.path.m_data.is_UfcsKnown(), "Opaque bound type wasn't UfcsKnown - " << type); const auto& pe = e.path.m_data.as_UfcsKnown(); + // TODO: Should Self here be `type` or `*pe.type` + // - Depends... if implicit it should be `type` (as it relates to the associated type), but if explicit it's referring to the trait auto monomorph_cb = monomorphise_type_get_cb(sp, &*pe.type, &pe.trait.m_params, nullptr, nullptr); auto rv = this->iterate_aty_bounds(sp, pe, [&](const auto& bound) { + DEBUG("Bound on ATY: " << bound); const auto& b_params = bound.m_path.m_params; ::HIR::PathParams params_mono_o; const auto& b_params_mono = (monomorphise_pathparams_needed(b_params) ? params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false) : b_params); + // TODO: Monormophise and EAT associated types + ::std::map< ::std::string, ::HIR::TypeRef> b_atys; + for(const auto& aty : bound.m_type_bounds) + b_atys.insert(::std::make_pair( aty.first, monomorphise_type_with(sp, aty.second, monomorph_cb) )); if( bound.m_path.m_path == trait ) { @@ -1375,13 +1384,15 @@ bool TraitResolution::find_trait_impls(const Span& sp, { if( &b_params_mono == ¶ms_mono_o ) { - if( callback( ImplRef(type.clone(), mv$(params_mono_o), {}), cmp ) ) + // TODO: assoc bounds + if( callback( ImplRef(type.clone(), mv$(params_mono_o), mv$(b_atys)), cmp ) ) return true; params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false); } else { - if( callback( ImplRef(&type, &bound.m_path.m_params, &null_assoc), cmp ) ) + //if( callback( ImplRef(&type, &bound.m_path.m_params, &null_assoc), cmp ) ) + if( callback( ImplRef(&type, &bound.m_path.m_params, &b_atys), cmp ) ) return true; } } @@ -2219,12 +2230,14 @@ 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` implies `::IntoIter : Iterator` return this->iterate_bounds([&](const auto& b)->bool { + DEBUG(b); if( b.is_TraitBound() ) { const auto& e = b.as_TraitBound(); const auto& b_params = e.trait.m_path.m_params; auto cmp = e.type .compare_with_placeholders(sp, type, m_ivars.callback_resolve_infer()); + DEBUG("cmp = " << cmp); if( cmp == ::HIR::Compare::Unequal ) return false; @@ -3643,6 +3656,9 @@ const ::HIR::TypeRef* TraitResolution::check_method_receiver(const Span& sp, ::H return &this->m_ivars.get_type(*ty.m_data.as_Borrow().inner); } break; + case ::HIR::Function::Receiver::Custom: + // TODO: Handle custom-receiver functions + return nullptr; case ::HIR::Function::Receiver::Box: if(const auto* ity = this->type_is_owned_box(sp, ty)) { diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index dddb7731..b38511d1 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -201,13 +201,16 @@ namespace { { while( param_vals.m_types.size() < param_def.m_types.size() ) { unsigned int i = param_vals.m_types.size(); - if( param_def.m_types[i].m_default.m_data.is_Infer() ) { + const auto& ty_def = param_def.m_types[i]; + if( ty_def.m_default.m_data.is_Infer() ) { ERROR(sp, E0000, "Unspecified parameter with no default"); } // Replace and expand - param_vals.m_types.push_back( param_def.m_types[i].m_default.clone() ); + param_vals.m_types.push_back( ty_def.m_default.clone() ); auto& ty = param_vals.m_types.back(); + // TODO: Monomorphise? + // Replace `Self` here with the real Self update_self_type(sp, ty); } @@ -220,7 +223,7 @@ namespace { if( param_vals.m_types[i] == ::HIR::TypeRef() ) { //if( param_def.m_types[i].m_default == ::HIR::TypeRef() ) // ERROR(sp, E0000, "Unspecified parameter with no default"); - // TODO: Monomorph? + // TODO: Monomorphise? param_vals.m_types[i] = param_def.m_types[i].m_default.clone(); update_self_type(sp, param_vals.m_types[i]); } @@ -429,6 +432,16 @@ namespace { } return trait_path_g; } + ::HIR::GenericPath get_current_trait_gp() const + { + assert(m_current_trait_path); + assert(m_current_trait); + auto trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); + for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { + trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); + } + return trait_path; + } void visit_path_UfcsUnknown(const Span& sp, ::HIR::Path& p, ::HIR::Visitor::PathContext pc) { TRACE_FUNCTION_FR("UfcsUnknown - p=" << p, p); @@ -449,10 +462,7 @@ namespace { // If processing a trait, and the type is 'Self', search for the type/method on the trait // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues? if( te.name == "Self" && m_current_trait ) { - auto trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); - for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { - trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); - } + auto trait_path = this->get_current_trait_gp(); if( this->locate_in_trait_and_set(sp, pc, trait_path, *m_current_trait, p.m_data) ) { // Success! return ; @@ -616,6 +626,17 @@ namespace { auto _ = m_resolve.set_item_generics(item.m_params); ::HIR::Visitor::visit_enum(p, item); } + void visit_associatedtype(::HIR::ItemPath p, ::HIR::AssociatedType& item) + { + // Push `Self = ::Type` for processing defaults in the bounds. + auto path_aty = ::HIR::Path( ::HIR::TypeRef("Self", 0xFFFF), this->get_current_trait_gp(), p.get_name() ); + auto ty_aty = ::HIR::TypeRef::new_path( mv$(path_aty), ::HIR::TypeRef::TypePathBinding::make_Opaque({}) ); + m_self_types.push_back(&ty_aty); + + ::HIR::Visitor::visit_associatedtype(p, item); + + m_self_types.pop_back(); + } void visit_type_impl(::HIR::TypeImpl& impl) override { diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 8000f5af..cfa94dbb 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -118,6 +118,16 @@ bool StaticTraitResolve::find_impl( } } + if(const auto* e = type.m_data.opt_Generic() ) + { + if( (e->binding >> 8) == 2 ) + { + // TODO: If the type is a magic placeholder, assume it impls the specified trait. + // TODO: Restructure so this knows that the placehlder impls the impl-provided bounds. + return found_cb( ImplRef(&type, trait_params, &null_assoc), false ); + } + } + // --- MAGIC IMPLS --- // TODO: There should be quite a few more here, but laziness TU_IFLET(::HIR::TypeRef::Data, type.m_data, Function, e, @@ -556,6 +566,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( if( placeholders.size() == 0 ) placeholders.resize(impl_params.size()); placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i); + DEBUG("Placeholder " << placeholders[i] << " for " << impl_params_def.m_types[i].m_name); } } // Callback that matches placeholders to concrete types @@ -571,6 +582,9 @@ bool StaticTraitResolve::find_impl__check_crate_raw( ph = ty.clone(); return ::HIR::Compare::Equal; } + else if( ph == ty ) { + return ::HIR::Compare::Equal; + } else { TODO(sp, "[find_impl__check_crate_raw:cb_match] Compare placeholder " << i << " " << ph << " == " << ty); } diff --git a/src/include/target_version.hpp b/src/include/target_version.hpp new file mode 100644 index 00000000..dddf69e4 --- /dev/null +++ b/src/include/target_version.hpp @@ -0,0 +1,11 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * include/target_version.hpp + * - mrustc target lanuage version definitions + */ +#pragma once + +#define TARGETVER_1_19 true +#define TARGETVER_1_29 true -- cgit v1.2.3 From e842fbbc375907b13b69d0f53de6dc3149804c13 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 22 Dec 2018 21:07:47 +0800 Subject: Lang items for 1.29 (allocator traits removed, need to do magic) --- src/expand/lang_item.cpp | 5 ++++- src/hir/from_ast.cpp | 39 +++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp index f59d81c3..55bde52f 100644 --- a/src/expand/lang_item.cpp +++ b/src/expand/lang_item.cpp @@ -215,7 +215,10 @@ public: // collections else if( name == "str" ) {} else if( name == "slice" ) {} - else if( TARGETVER_1_29 && name == "slice_u8" ) {} + else if( TARGETVER_1_29 && name == "slice_u8" ) {} // libcore now, `impl [u8]` + else if( TARGETVER_1_29 && name == "slice_alloc" ) {} // liballoc's impls on [T] + else if( TARGETVER_1_29 && name == "slice_u8_alloc" ) {} // liballoc's impls on [u8] + else if( TARGETVER_1_29 && name == "str_alloc" ) {} // liballoc's impls on str // std - interestingly else if( name == "f32" ) {} else if( name == "f64" ) {} diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 40c872fa..1079e981 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1932,25 +1932,28 @@ public: } }; // Check for existing defintions of lang items before adding magic ones - if( rv.m_lang_items.count("boxed_trait") == 0 ) + if( TARGETVER_1_19 ) { - rv.m_lang_items.insert(::std::make_pair( ::std::string("boxed_trait"), H::resolve_path(rv, false, {"ops", "Boxed"}) )); - } - if( rv.m_lang_items.count("placer_trait") == 0 ) - { - rv.m_lang_items.insert(::std::make_pair( ::std::string("placer_trait"), H::resolve_path(rv, false, {"ops", "Placer"}) )); - } - if( rv.m_lang_items.count("place_trait") == 0 ) - { - rv.m_lang_items.insert(::std::make_pair( ::std::string("place_trait"), H::resolve_path(rv, false, {"ops", "Place"}) )); - } - if( rv.m_lang_items.count("box_place_trait") == 0 ) - { - rv.m_lang_items.insert(::std::make_pair( ::std::string("box_place_trait"), H::resolve_path(rv, false, {"ops", "BoxPlace"}) )); - } - if( rv.m_lang_items.count("in_place_trait") == 0 ) - { - rv.m_lang_items.insert(::std::make_pair( ::std::string("in_place_trait"), H::resolve_path(rv, false, {"ops", "InPlace"}) )); + if( rv.m_lang_items.count("boxed_trait") == 0 ) + { + rv.m_lang_items.insert(::std::make_pair( ::std::string("boxed_trait"), H::resolve_path(rv, false, {"ops", "Boxed"}) )); + } + if( rv.m_lang_items.count("placer_trait") == 0 ) + { + rv.m_lang_items.insert(::std::make_pair( ::std::string("placer_trait"), H::resolve_path(rv, false, {"ops", "Placer"}) )); + } + if( rv.m_lang_items.count("place_trait") == 0 ) + { + rv.m_lang_items.insert(::std::make_pair( ::std::string("place_trait"), H::resolve_path(rv, false, {"ops", "Place"}) )); + } + if( rv.m_lang_items.count("box_place_trait") == 0 ) + { + rv.m_lang_items.insert(::std::make_pair( ::std::string("box_place_trait"), H::resolve_path(rv, false, {"ops", "BoxPlace"}) )); + } + if( rv.m_lang_items.count("in_place_trait") == 0 ) + { + rv.m_lang_items.insert(::std::make_pair( ::std::string("in_place_trait"), H::resolve_path(rv, false, {"ops", "InPlace"}) )); + } } } -- cgit v1.2.3 From e16796df604ba1017a19917ea94840ee8c4b0336 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Dec 2018 16:58:52 +0800 Subject: Resolve - Clean up AST path bindings, one binding per namespace - This is prep work for supporting `use` of macros --- src/ast/ast.cpp | 2 +- src/ast/ast.hpp | 1 - src/ast/path.cpp | 140 ++++++++++----- src/ast/path.hpp | 122 ++++++++----- src/hir/from_ast.cpp | 71 ++++---- src/hir/from_ast_expr.cpp | 54 +++--- src/include/tagged_union.hpp | 6 +- src/resolve/absolute.cpp | 110 ++++++------ src/resolve/index.cpp | 197 +++++++++------------ src/resolve/use.cpp | 412 ++++++++++++++++++++++--------------------- 10 files changed, 600 insertions(+), 515 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index e4fe49da..b439553a 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -257,7 +257,7 @@ MacroInvocation MacroInvocation::clone() const UseStmt UseStmt::clone() const { - return UseStmt(sp, path); + return UseStmt(sp, AST::Path(path)); } void ExternBlock::add_item(Named named_item) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 49e2bdc6..2d802f53 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -466,7 +466,6 @@ struct UseStmt { Span sp; ::AST::Path path; - ::AST::PathBinding alt_binding; UseStmt(Span sp, Path p): sp(sp), diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 6fdf1e40..0c8c4c69 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -17,8 +17,8 @@ namespace AST { // --- AST::PathBinding -::std::ostream& operator<<(::std::ostream& os, const PathBinding& x) { - TU_MATCH(PathBinding, (x), (i), +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Type& x) { + TU_MATCHA( (x), (i), (Unbound, os << "_"; ), (Crate , os << "Crate"; ), (Module, os << "Module"; ), @@ -26,39 +26,80 @@ namespace AST { (Struct, os << "Struct"; ), (Enum, os << "Enum"; ), (Union, os << "Union"; ), + (EnumVar, os << "EnumVar(" << i.idx << ")"; ), + (TypeAlias, os << "TypeAlias";), + (TypeParameter, os << "TyParam(" << i.level << " # " << i.idx << ")"; ) + ) + return os; +} +PathBinding_Type PathBinding_Type::clone() const +{ + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Type::make_Unbound({}); ), + (Module , return PathBinding_Type::make_Module(e); ), + (Crate , return PathBinding_Type(e); ), + (Trait , return PathBinding_Type(e); ), + (Struct , return PathBinding_Type(e); ), + (Enum , return PathBinding_Type(e); ), + (Union , return PathBinding_Type(e); ), + (TypeAlias, return PathBinding_Type::make_TypeAlias(e); ), + (EnumVar , return PathBinding_Type::make_EnumVar(e); ), + + (TypeParameter, return PathBinding_Type::make_TypeParameter(e); ) + ) + throw "BUG: Fell off the end of PathBinding_Type::clone"; +} +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Value& x) { + TU_MATCHA( (x), (i), + (Unbound, os << "_"; ), + (Struct, os << "Struct"; ), (Static, os << "Static"; ), (Function, os << "Function";), (EnumVar, os << "EnumVar(" << i.idx << ")"; ), - (TypeAlias, os << "TypeAlias";), - (StructMethod, os << "StructMethod"; ), - (TraitMethod, os << "TraitMethod"; ), - - (TypeParameter, os << "TyParam(" << i.level << " # " << i.idx << ")"; ), (Variable, os << "Var(" << i.slot << ")"; ) ) return os; } -PathBinding PathBinding::clone() const +PathBinding_Value PathBinding_Value::clone() const { - TU_MATCH(::AST::PathBinding, (*this), (e), - (Unbound , return PathBinding::make_Unbound({}); ), - (Module , return PathBinding::make_Module(e); ), - (Crate , return PathBinding(e); ), - (Trait , return PathBinding(e); ), - (Struct , return PathBinding(e); ), - (Enum , return PathBinding(e); ), - (Union , return PathBinding(e); ), - (Static , return PathBinding(e); ), - (Function, return PathBinding(e); ), - (TypeAlias, return PathBinding::make_TypeAlias(e); ), - (EnumVar , return PathBinding::make_EnumVar(e); ), - (StructMethod, return PathBinding::make_StructMethod(e); ), - (TraitMethod, return PathBinding::make_TraitMethod(e); ), - - (TypeParameter, return PathBinding::make_TypeParameter(e); ), - (Variable, return PathBinding::make_Variable(e); ) + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Value::make_Unbound({}); ), + (Struct , return PathBinding_Value(e); ), + (Static , return PathBinding_Value(e); ), + (Function, return PathBinding_Value(e); ), + (EnumVar , return PathBinding_Value::make_EnumVar(e); ), + (Variable, return PathBinding_Value::make_Variable(e); ) ) - throw "BUG: Fell off the end of PathBinding::clone"; + throw "BUG: Fell off the end of PathBinding_Value::clone"; +} +::std::ostream& operator<<(::std::ostream& os, const PathBinding_Macro& x) { + TU_MATCHA( (x), (i), + (Unbound, os << "_"; ), + (ProcMacroDerive, + os << "ProcMacroDerive(? " << i.mac_name << ")"; + ), + (ProcMacroAttribute, + os << "ProcMacroAttribute(? " << i.mac_name << ")"; + ), + (ProcMacro, + os << "ProcMacro(? " << i.mac_name << ")"; + ), + (MacroRules, + os << "MacroRules(? ?)"; + ) + ) + return os; +} +PathBinding_Macro PathBinding_Macro::clone() const +{ + TU_MATCHA( (*this), (e), + (Unbound , return PathBinding_Macro::make_Unbound({}); ), + (ProcMacroDerive, return PathBinding_Macro(e); ), + (ProcMacroAttribute, return PathBinding_Macro(e); ), + (ProcMacro, return PathBinding_Macro(e); ), + (MacroRules, return PathBinding_Macro(e); ) + ) + throw "BUG: Fell off the end of PathBinding_Macro::clone"; } ::std::ostream& operator<<(::std::ostream& os, const PathParams& x) @@ -159,8 +200,10 @@ AST::Path::Path(TagUfcs, TypeRef type, Path trait, ::std::vector } AST::Path::Path(const Path& x): m_class() - //m_binding(x.m_binding) + //,m_bindings(x.m_bindings) { + memcpy(&m_bindings, &x.m_bindings, sizeof(Bindings)); + TU_MATCH(Class, (x.m_class), (ent), (Invalid, m_class = Class::make_Invalid({});), (Local, @@ -185,15 +228,13 @@ AST::Path::Path(const Path& x): m_class = Class::make_UFCS({ box$(ent.type->clone()), nullptr, ent.nodes }); ) ) - - memcpy(&m_binding, &x.m_binding, sizeof(PathBinding)); } void Path::bind_variable(unsigned int slot) { - m_binding = PathBinding::make_Variable({slot}); + m_bindings.value = PathBinding_Value::make_Variable({slot}); } -void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector& /*args*/) +void Path::bind_enum_var(const Enum& ent, const ::std::string& name) { auto it = ::std::find_if(ent.variants().begin(), ent.variants().end(), [&](const auto& x) { return x.m_name == name; }); if( it == ent.variants().end() ) @@ -203,10 +244,8 @@ void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std unsigned int idx = it - ent.variants().begin(); DEBUG("Bound to enum variant '" << name << "' (#" << idx << ")"); - ::AST::PathBinding::Data_EnumVar tmp = {}; - tmp.enum_ = &ent; - tmp.idx = idx; - m_binding = PathBinding::make_EnumVar( mv$(tmp) ); + m_bindings.type = PathBinding_Type::make_EnumVar({ &ent, idx }); + m_bindings.value = PathBinding_Value::make_EnumVar({ &ent, idx }); } Path& Path::operator+=(const Path& other) @@ -214,7 +253,7 @@ Path& Path::operator+=(const Path& other) for(auto& node : other.nodes()) append(node); // If the path is modified, clear the binding - m_binding = PathBinding(); + m_bindings = Bindings(); return *this; } @@ -268,13 +307,13 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context, bool is_debug) ), (Local, // Only print comment if there's no binding - if( m_binding.is_Unbound() ) + if( m_bindings.value.is_Unbound() ) { if( is_debug ) os << "/*var*/"; } else - assert( m_binding.is_Variable() ); + assert( m_bindings.value.is_Variable() ); os << ent.name; ), (Relative, @@ -334,8 +373,29 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context, bool is_debug) } ) ) - if( is_debug ) - os << "/*" << m_binding << "*/"; + if( is_debug ) { + os << "/*"; + bool printed = false; + if( !m_bindings.value.is_Unbound() ) { + if(printed) os << ","; + os << "v:" << m_bindings.value; + printed = true; + } + if( !m_bindings.type.is_Unbound() ) { + if(printed) os << ","; + os << "t:" << m_bindings.type; + printed = true; + } + if( !m_bindings.macro.is_Unbound() ) { + if(printed) os << ","; + os << "m:" << m_bindings.macro; + printed = true; + } + if( !printed ) { + os << "?"; + } + os << "*/"; + } } ::std::ostream& operator<<(::std::ostream& os, const Path& path) diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 2693a070..b1453f04 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -45,7 +45,36 @@ class Static; class Function; class ExternCrate; -TAGGED_UNION_EX(PathBinding, (), Unbound, ( +TAGGED_UNION_EX(PathBinding_Value, (), Unbound, ( + (Unbound, struct { + }), + (Struct, struct { + const Struct* struct_; + const ::HIR::Struct* hir; + }), + (Static, struct { + const Static* static_; + const ::HIR::Static* hir; // if nullptr and static_ == nullptr, points to a `const` + }), + (Function, struct { + const Function* func_; + }), + (EnumVar, struct { + const Enum* enum_; + unsigned int idx; + const ::HIR::Enum* hir; + }), + (Variable, struct { + unsigned int slot; + }) + ), + (), (), + ( + public: + PathBinding_Value clone() const; + ) + ); +TAGGED_UNION_EX(PathBinding_Type, (), Unbound, ( (Unbound, struct { }), (Crate, struct { @@ -71,13 +100,7 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( const Trait* trait_; const ::HIR::Trait* hir; }), - (Static, struct { - const Static* static_; - const ::HIR::Static* hir; // if nullptr and static_ == nullptr, points to a `const` - }), - (Function, struct { - const Function* func_; - }), + (EnumVar, struct { const Enum* enum_; unsigned int idx; @@ -86,31 +109,48 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( (TypeAlias, struct { const TypeAlias* alias_; }), - (StructMethod, struct { - const Struct* struct_; - ::std::string name; - }), - (TraitMethod, struct { - const Trait* trait_; - ::std::string name; - }), (TypeParameter, struct { unsigned int level; unsigned int idx; + }) + ), + (), (), + ( + public: + PathBinding_Type clone() const; + ) + ); +TAGGED_UNION_EX(PathBinding_Macro, (), Unbound, ( + (Unbound, struct { }), - (Variable, struct { - unsigned int slot; + (ProcMacroDerive, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (ProcMacroAttribute, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (ProcMacro, struct { + const ExternCrate* crate_; + ::std::string mac_name; + }), + (MacroRules, struct { + const ExternCrate* crate_; // Can be NULL + //const MacroRules* mac; }) ), (), (), ( public: - PathBinding clone() const; + PathBinding_Macro clone() const; ) ); -extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Value& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Type& x); +extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding_Macro& x); struct PathParams { @@ -191,23 +231,30 @@ public: public: Class m_class; -private: - PathBinding m_binding; -public: + struct Bindings { + PathBinding_Value value; + PathBinding_Type type; + PathBinding_Macro macro; + + Bindings clone() const { + return Bindings { + value.clone(), type.clone(), macro.clone() + }; + } + bool has_binding() const { + return !value.is_Unbound() || !type.is_Unbound() || !macro.is_Unbound(); + } + } m_bindings; + virtual ~Path(); // INVALID Path(): m_class() {} Path(Path&&) = default; - Path& operator=(AST::Path&& x) { - m_class = mv$(x.m_class); - m_binding = mv$(x.m_binding); - //DEBUG("Path, " << x); - return *this; - } + Path& operator=(AST::Path&& x) = default; - Path(const Path& x); + /*explicit*/ Path(const Path& x); Path& operator=(const AST::Path&) = delete; // ABSOLUTE @@ -281,7 +328,7 @@ public: //if( m_class.is_Invalid() ) // m_class = Class::make_Relative({}); nodes().push_back( mv$(node) ); - m_binding = PathBinding(); + m_bindings = Bindings(); } bool is_trivial() const { @@ -318,8 +365,6 @@ public: bool is_concrete() const; - bool is_bound() const { return !m_binding.is_Unbound(); } - const PathBinding& binding() const { return m_binding; } void bind_variable(unsigned int slot); ::std::vector& nodes() { @@ -353,14 +398,9 @@ private: void check_param_counts(const GenericParams& params, bool expect_params, PathNode& node); public: - void bind_enum_var(const Enum& ent, const ::std::string& name, const ::std::vector& args={}); - void bind_function(const Function& ent, const ::std::vector& args={}) { - (void)args; - m_binding = PathBinding::make_Function({&ent}); - } - - void bind(::AST::PathBinding pb) { - m_binding = mv$(pb); + void bind_enum_var(const Enum& ent, const ::std::string& name); + void bind_function(const Function& ent) { + m_bindings.value = PathBinding_Value::make_Function({&ent}); } }; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 1079e981..f62d097a 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -214,11 +214,10 @@ const ::AST::Crate* g_ast_crate_ptr; (StructTuple, unsigned int leading_count = e.tup_pat.start.size(); unsigned int trailing_count = e.tup_pat.end .size(); - TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), - ( + TU_MATCH_HDRA( (e.path.m_bindings.value), {) + default: BUG(pat.span(), "Encountered StructTuple pattern not pointing to a enum variant or a struct - " << e.path); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { assert( pb.enum_ || pb.hir ); unsigned int field_count; if( pb.enum_ ) { @@ -268,8 +267,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(sub_patterns) }) }; - ), - (Struct, + } + TU_ARMA(Struct, pb) { assert( pb.struct_ || pb.hir ); unsigned int field_count; if( pb.struct_ ) { @@ -317,8 +316,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(sub_patterns) }) }; - ) - ) + } + } ), (Struct, ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > sub_patterns; @@ -326,11 +325,10 @@ const ::AST::Crate* g_ast_crate_ptr; sub_patterns.push_back( ::std::make_pair(sp.first, LowerHIR_Pattern(sp.second)) ); - TU_MATCH_DEF(::AST::PathBinding, (e.path.binding()), (pb), - ( + TU_MATCH_HDRA( (e.path.m_bindings.type), {) + default: BUG(pat.span(), "Encountered Struct pattern not pointing to a enum variant or a struct - " << e.path); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_EnumStruct({ @@ -340,8 +338,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ), - (TypeAlias, + } + TU_ARMA(TypeAlias, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Struct({ @@ -351,8 +349,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ), - (Struct, + } + TU_ARMA(Struct, pb) { return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Struct({ @@ -362,8 +360,8 @@ const ::AST::Crate* g_ast_crate_ptr; e.is_exhaustive }) }; - ) - ) + } + } ), (Value, @@ -750,9 +748,9 @@ const ::AST::Crate* g_ast_crate_ptr; TU_IFLET(::AST::Path::Class, e.path.m_class, Local, l, unsigned int slot; // NOTE: TypeParameter is unused - TU_IFLET(::AST::PathBinding, e.path.binding(), Variable, p, - slot = p.slot; - ) + if( const auto* p = e.path.m_bindings.value.opt_Variable() ) { + slot = p->slot; + } else { BUG(ty.span(), "Unbound local encountered in " << e.path); } @@ -768,7 +766,7 @@ const ::AST::Crate* g_ast_crate_ptr; for(const auto& t : e.traits) { DEBUG("t = " << t.path); - const auto& tb = t.path.binding().as_Trait(); + const auto& tb = t.path.m_bindings.type.as_Trait(); assert( tb.trait_ || tb.hir ); if( (tb.trait_ ? tb.trait_->is_marker() : tb.hir->m_is_marker) ) { @@ -1361,7 +1359,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H // Populate trait list for(const auto& item : ast_mod.m_type_items) { - if( item.second.path.binding().is_Trait() ) { + if( item.second.path.m_bindings.type.is_Trait() ) { auto sp = LowerHIR_SimplePath(Span(), item.second.path); if( ::std::find(mod.m_traits.begin(), mod.m_traits.end(), sp) == mod.m_traits.end() ) mod.m_traits.push_back( mv$(sp) ); @@ -1500,16 +1498,14 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H if( ie.second.is_import ) { auto hir_path = LowerHIR_SimplePath( sp, ie.second.path ); ::HIR::TypeItem ti; - TU_MATCH_DEF( ::AST::PathBinding, (ie.second.path.binding()), (pb), - ( + if( const auto* pb = ie.second.path.m_bindings.type.opt_EnumVar() ) { + DEBUG("Import NS " << ie.first << " = " << hir_path << " (Enum Variant)"); + ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), true, pb->idx }); + } + else { DEBUG("Import NS " << ie.first << " = " << hir_path); ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), false, 0 }); - ), - (EnumVar, - DEBUG("Import NS " << ie.first << " = " << hir_path << " (Enum Variant)"); - ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), true, pb.idx }); - ) - ) + } _add_mod_ns_item(mod, ie.first, ie.second.is_pub, mv$(ti)); } } @@ -1520,16 +1516,15 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H auto hir_path = LowerHIR_SimplePath( sp, ie.second.path ); ::HIR::ValueItem vi; - TU_MATCH_DEF( ::AST::PathBinding, (ie.second.path.binding()), (pb), - ( + TU_MATCH_HDRA( (ie.second.path.m_bindings.value), {) + default: DEBUG("Import VAL " << ie.first << " = " << hir_path); vi = ::HIR::ValueItem::make_Import({ mv$(hir_path), false, 0 }); - ), - (EnumVar, + TU_ARMA(EnumVar, pb) { DEBUG("Import VAL " << ie.first << " = " << hir_path << " (Enum Variant)"); vi = ::HIR::ValueItem::make_Import({ mv$(hir_path), true, pb.idx }); - ) - ) + } + } _add_mod_val_item(mod, ie.first, ie.second.is_pub, mv$(vi)); } } @@ -1566,7 +1561,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat if( impl.def().trait().ent.is_valid() ) { - const auto& pb = impl.def().trait().ent.binding(); + const auto& pb = impl.def().trait().ent.m_bindings.type; ASSERT_BUG(Span(), pb.is_Trait(), "Binding for trait path in impl isn't a Trait - " << impl.def().trait().ent); ASSERT_BUG(Span(), pb.as_Trait().trait_ || pb.as_Trait().hir, "Trait pointer for trait path in impl isn't set"); bool is_marker = (pb.as_Trait().trait_ ? pb.as_Trait().trait_->is_marker() : pb.as_Trait().hir->m_is_marker); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 6daf49c3..cc642482 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -211,22 +211,22 @@ struct LowerHIR_ExprNode_Visitor: TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, m_rv.reset( new ::HIR::ExprNode_CallValue( v.span(), - ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( v.span(), e.name, v.m_path.binding().as_Variable().slot )), + ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( v.span(), e.name, v.m_path.m_bindings.value.as_Variable().slot )), mv$(args) ) ); ) else { - TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding_Value, (v.m_path.m_bindings.value), (e), ( m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(), LowerHIR_Path(v.span(), v.m_path), mv$( args ) ) ); ), - (TypeAlias, - TODO(v.span(), "CallPath -> TupleVariant TypeAlias"); - ), + //(TypeAlias, + // TODO(v.span(), "CallPath -> TupleVariant TypeAlias"); + // ), (EnumVar, m_rv.reset( new ::HIR::ExprNode_TupleVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), false, @@ -508,7 +508,7 @@ struct LowerHIR_ExprNode_Visitor: ) ); } virtual void visit(::AST::ExprNode_StructLiteral& v) override { - if( v.m_path.binding().is_Union() ) + if( v.m_path.m_bindings.type.is_Union() ) { if( v.m_values.size() != 1 ) ERROR(v.span(), E0000, "Union constructors can only specify a single field"); @@ -528,7 +528,7 @@ struct LowerHIR_ExprNode_Visitor: values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), - ! v.m_path.binding().is_EnumVar(), + ! v.m_path.m_bindings.type.is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) ) ); @@ -559,22 +559,14 @@ struct LowerHIR_ExprNode_Visitor: } virtual void visit(::AST::ExprNode_NamedValue& v) override { TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, - if( !v.m_path.binding().is_Variable() ) { - BUG(v.span(), "Named value was a local, but wasn't bound - " << v.m_path); - } - auto slot = v.m_path.binding().as_Variable().slot; + ASSERT_BUG(v.span(), v.m_path.m_bindings.value.is_Variable(), "Named value was a local, but wasn't bound - " << v.m_path); + auto slot = v.m_path.m_bindings.value.as_Variable().slot; m_rv.reset( new ::HIR::ExprNode_Variable( v.span(), e.name, slot ) ); ) - else { - TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), - ( - auto p = LowerHIR_Path(v.span(), v.m_path); - if( p.m_data.is_Generic() ) { - BUG(v.span(), "Unknown binding for PathValue but path is generic - " << v.m_path); - } - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), mv$(p), ::HIR::ExprNode_PathValue::UNKNOWN ) ); - ), - (Struct, + else + { + TU_MATCH_HDRA( (v.m_path.m_bindings.value), {) + TU_ARMA(Struct, e) { ASSERT_BUG(v.span(), e.struct_ || e.hir, "PathValue bound to a struct but pointer not set - " << v.m_path); // Check the form and emit a PathValue if not a unit bool is_tuple_constructor = false; @@ -604,8 +596,8 @@ struct LowerHIR_ExprNode_Visitor: else { m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), true ) ); } - ), - (EnumVar, + } + TU_ARMA(EnumVar, e) { ASSERT_BUG(v.span(), e.enum_ || e.hir, "PathValue bound to an enum but pointer not set - " << v.m_path); const auto& var_name = v.m_path.nodes().back().name(); bool is_tuple_constructor = false; @@ -646,11 +638,11 @@ struct LowerHIR_ExprNode_Visitor: else { m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), false ) ); } - ), - (Function, + } + TU_ARMA(Function, e) { m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::FUNCTION ) ); - ), - (Static, + } + TU_ARMA(Static, e) { if( e.static_ ) { if( e.static_->s_class() != ::AST::Static::CONST ) { @@ -669,8 +661,12 @@ struct LowerHIR_ExprNode_Visitor: { m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); } - ) - ) + } + break; default: + auto p = LowerHIR_Path(v.span(), v.m_path); + ASSERT_BUG(v.span(), !p.m_data.is_Generic(), "Unknown binding for PathValue but path is generic - " << v.m_path); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), mv$(p), ::HIR::ExprNode_PathValue::UNKNOWN ) ); + } } } diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 12e39fc8..d249de13 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -118,10 +118,14 @@ #define TU_MATCH_HDR(VARS, brace) TU_MATCH_HDR_(::std::remove_reference::type, VARS, brace) #define TU_MATCH_HDR_(CLASS, VARS, brace) switch( (TU_FIRST VARS).tag() ) brace case CLASS::TAGDEAD: assert(!"ERROR: destructed tagged union used"); - // Evil hack: two for loops, the inner stops the outer after it's done. #define TU_ARM(VAR, TAG, NAME) break; case ::std::remove_reference::type::TAG_##TAG: for(bool tu_lc = true; tu_lc; tu_lc=false) for(auto& NAME = (VAR).as_##TAG(); (void)NAME, tu_lc; tu_lc=false) +#define TU_MATCH_HDRA(VARS, brace) TU_MATCH_HDRA_(::std::remove_reference::type, VARS, brace) +#define TU_MATCH_HDRA_(CLASS, VARS, brace) const auto& tu_match_hdr2_v = (TU_FIRST VARS); switch( tu_match_hdr2_v.tag() ) brace case CLASS::TAGDEAD: assert(!"ERROR: destructed tagged union used"); +// Evil hack: two for loops, the inner stops the outer after it's done. +#define TU_ARMA(TAG, NAME) break; case ::std::remove_reference::type::TAG_##TAG: for(bool tu_lc = true; tu_lc; tu_lc=false) for(auto& NAME = tu_match_hdr2_v.as_##TAG(); (void)NAME, tu_lc; tu_lc=false) + //#define TU_TEST(VAL, ...) (VAL.is_##TAG() && VAL.as_##TAG() TEST) #define TU_TEST1(VAL, TAG1, TEST) (VAL.is_##TAG1() && VAL.as_##TAG1() TEST) #define TU_TEST2(VAL, TAG1, FLD1,TAG2, TEST) (VAL.is_##TAG1() && VAL.as_##TAG1() FLD1.is_##TAG2() && VAL.as_##TAG1() FLD1.as_##TAG2() TEST) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 19da5820..d0db3c13 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -313,6 +313,7 @@ namespace { auto v = mod.m_namespace_items.find(name); if( v != mod.m_namespace_items.end() ) { + DEBUG("- NS: Namespace " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -320,6 +321,7 @@ namespace { auto v = mod.m_type_items.find(name); if( v != mod.m_type_items.end() ) { + DEBUG("- NS: Type " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -327,15 +329,10 @@ namespace break; case LookupMode::Type: - //if( name == "IntoIterator" ) { - // DEBUG("lookup_in_mod(mod="<second.path); path = ::AST::Path( v->second.path ); return true; } @@ -345,14 +342,15 @@ namespace { auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { - const auto& b = v->second.path.binding(); + const auto& b = v->second.path.m_bindings.value; switch( b.tag() ) { - case ::AST::PathBinding::TAG_EnumVar: - case ::AST::PathBinding::TAG_Static: + case ::AST::PathBinding_Value::TAG_EnumVar: + case ::AST::PathBinding_Value::TAG_Static: + DEBUG("- PV: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; - case ::AST::PathBinding::TAG_Struct: + case ::AST::PathBinding_Value::TAG_Struct: // TODO: Restrict this to unit-like structs if( b.as_Struct().struct_ && !b.as_Struct().struct_->m_data.is_Unit() ) ; @@ -360,6 +358,7 @@ namespace ; else { + DEBUG("- PV: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -375,6 +374,7 @@ namespace { auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { + DEBUG("- C/V: Value " << v->second.path); path = ::AST::Path( v->second.path ); return true; } @@ -592,7 +592,7 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L { // Trait is specified, definitely a trait item // - Must resolve here - const auto& pb = ufcs.trait->binding(); + const auto& pb = ufcs.trait->m_bindings.type; if( ! pb.is_Trait() ) { ERROR(sp, E0000, "UFCS trait was not a trait - " << *ufcs.trait); } @@ -662,7 +662,7 @@ namespace { { np.nodes().push_back( mv$(nodes[i]) ); } - np.bind( path.binding().clone() ); + np.m_bindings = path.m_bindings.clone(); return np; } AST::Path split_into_ufcs_ty(const Span& sp, AST::Path path, unsigned int i /*item_name_idx*/) @@ -716,7 +716,6 @@ namespace { const auto& varname = p.m_components.back(); auto var_idx = e.find_variant(varname); ASSERT_BUG(sp, var_idx != SIZE_MAX, "Extern crate import path points to non-present variant - " << p); - auto pb = ::AST::PathBinding::make_EnumVar({nullptr, static_cast(var_idx), &e}); // Construct output path (with same set of parameters) AST::Path rv( p.m_crate_name, {} ); @@ -724,7 +723,12 @@ namespace { for(const auto& c : p.m_components) rv.nodes().push_back( AST::PathNode(c) ); rv.nodes().back().args() = mv$( path.nodes().back().args() ); - rv.bind( mv$(pb) ); + if( e.m_data.is_Data() && e.m_data.as_Data()[var_idx].is_struct ) { + rv.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, static_cast(var_idx), &e}); + } + else { + rv.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, static_cast(var_idx), &e}); + } path = mv$(rv); return ; @@ -735,7 +739,7 @@ namespace { ) } - ::AST::PathBinding pb; + ::AST::Path::Bindings pb; const auto& name = p.m_components.back(); if( is_value ) @@ -749,19 +753,19 @@ namespace { BUG(sp, "HIR Import item pointed to an import"); ), (Constant, - pb = ::AST::PathBinding::make_Static({nullptr, nullptr}); + pb.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); ), (Static, - pb = ::AST::PathBinding::make_Static({nullptr, &e}); + pb.value = ::AST::PathBinding_Value::make_Static({nullptr, &e}); ), (StructConstant, - pb = ::AST::PathBinding::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); + pb.value = ::AST::PathBinding_Value::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); ), (Function, - pb = ::AST::PathBinding::make_Function({nullptr/*, &e*/}); + pb.value = ::AST::PathBinding_Value::make_Function({nullptr/*, &e*/}); ), (StructConstructor, - pb = ::AST::PathBinding::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); + pb.value = ::AST::PathBinding_Value::make_Struct({nullptr, &ext_crate.m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct()}); ) ) } @@ -776,22 +780,22 @@ namespace { BUG(sp, "HIR Import item pointed to an import"); ), (Module, - pb = ::AST::PathBinding::make_Module({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (Trait, - pb = ::AST::PathBinding::make_Trait({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (TypeAlias, - pb = ::AST::PathBinding::make_TypeAlias({nullptr/*, &e*/}); + pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), (Struct, - pb = ::AST::PathBinding::make_Struct({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - pb = ::AST::PathBinding::make_Union({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ), (Enum, - pb = ::AST::PathBinding::make_Enum({nullptr, &e}); + pb.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ) ) } @@ -802,7 +806,7 @@ namespace { for(const auto& c : p.m_components) rv.nodes().push_back( AST::PathNode(c) ); rv.nodes().back().args() = mv$( path.nodes().back().args() ); - rv.bind( mv$(pb) ); + rv.m_bindings = mv$(pb); path = mv$(rv); } @@ -816,7 +820,7 @@ namespace { switch(mode) { case Context::LookupMode::Namespace: - path.bind( ::AST::PathBinding::make_Module({nullptr, &crate.m_hir->m_root_module}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &crate.m_hir->m_root_module}); return ; default: TODO(sp, "Looking up a non-namespace, but pointed to crate root"); @@ -862,7 +866,7 @@ namespace { trait_path.nodes().back().args().m_types.push_back( ::TypeRef(sp) ); } } - trait_path.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + trait_path.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ::AST::Path new_path; const auto& next_node = path_abs.nodes[i+1]; @@ -922,7 +926,12 @@ namespace { ERROR(sp, E0000, "Type parameters were not expected here (enum params go on the variant)"); } - path.bind( ::AST::PathBinding::make_EnumVar({nullptr, static_cast(idx), &e}) ); + if( e.m_data.is_Data() && e.m_data.as_Data()[idx].is_struct ) { + path.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, static_cast(idx), &e}); + } + else { + path.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, static_cast(idx), &e}); + } path = split_into_crate(sp, mv$(path), start, crate.m_name); return; } @@ -949,22 +958,22 @@ namespace { return ; ), (Trait, - path.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (Module, - path.bind( ::AST::PathBinding::make_Module({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (TypeAlias, - path.bind( ::AST::PathBinding::make_TypeAlias({nullptr/*, &e*/}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), (Enum, - path.bind( ::AST::PathBinding::make_Enum({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ), (Struct, - path.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - path.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); + path.m_bindings.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ) ) // Update path (trim down to `start` and set crate name) @@ -984,7 +993,7 @@ namespace { ), (StructConstant, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); path = split_into_crate(sp, mv$(path), start, crate.m_name); return ; ), @@ -994,7 +1003,7 @@ namespace { ), (Constant, // Bind and update path - path.bind( ::AST::PathBinding::make_Static({nullptr, nullptr}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); path = split_into_crate(sp, mv$(path), start, crate.m_name); return ; ) @@ -1016,22 +1025,22 @@ namespace { return ; ), (Function, - path.bind( ::AST::PathBinding::make_Function({nullptr/*, &e*/}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Function({nullptr/*, &e*/}); ), (StructConstructor, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); ), (StructConstant, auto ty_path = e.ty; - path.bind( ::AST::PathBinding::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Struct({nullptr, &crate.m_hir->get_struct_by_path(sp, ty_path)}); ), (Static, - path.bind( ::AST::PathBinding::make_Static({nullptr, &e}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, &e}); ), (Constant, // Bind - path.bind( ::AST::PathBinding::make_Static({nullptr, nullptr}) ); + path.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr, nullptr}); ) ) path = split_into_crate(sp, mv$(path), start, crate.m_name); @@ -1088,7 +1097,7 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex const auto& name_ref = it->second; DEBUG("#" << i << " \"" << n.name() << "\" = " << name_ref.path << (name_ref.is_import ? " (import)" : "") ); - TU_MATCH_DEF(::AST::PathBinding, (name_ref.path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding_Type, (name_ref.path.m_bindings.type), (e), ( ERROR(sp, E0000, "Encountered non-namespace item '" << n.name() << "' ("< Instead use the type name. if( ! p.m_class.is_Local() && coretype_fromstring(e.nodes[0].name()) != CORETYPE_INVAL ) { - TU_IFLET( ::AST::PathBinding, p.binding(), Module, pe, + if( const auto* pep = p.m_bindings.type.opt_Module() ) { + const auto& pe = *pep; bool found = false; const auto& name = e.nodes[1].name(); if( !pe.module_ ) { @@ -1340,7 +1350,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: } DEBUG("Primitive module hack yeilded " << p); - ) + } } if( e.nodes.size() > 1 ) @@ -1447,7 +1457,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: BUG(sp, "Path wasn't absolutised correctly"); ), (Local, - if( path.binding().is_Unbound() ) + if( !path.m_bindings.has_binding() ) { TODO(sp, "Bind unbound local path - " << path); } @@ -1565,7 +1575,7 @@ void Resolve_Absolute_Type(Context& context, TypeRef& type) assert( ufcs.nodes.size() == 1); ) - TU_IFLET(::AST::PathBinding, e.path.binding(), Trait, be, + TU_IFLET(::AST::PathBinding_Type, e.path.m_bindings.type, Trait, be, auto ty = ::TypeRef( type.span(), ::make_vec1(Type_TraitPath { {}, mv$(e.path)}), {} ); type = mv$(ty); return ; @@ -2157,7 +2167,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) item_context.pop(def.params()); - const_cast< ::AST::Trait*>(def.trait().ent.binding().as_Trait().trait_)->set_is_marker(); + const_cast< ::AST::Trait*>(def.trait().ent.m_bindings.type.as_Trait().trait_)->set_is_marker(); } else { diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 659bded4..148bf069 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -125,46 +125,47 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) ), // - Types/modules only (Module, - p.bind( ::AST::PathBinding::make_Module({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Module({&e}); _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Crate, ASSERT_BUG(i.data.span, crate.m_extern_crates.count(e.name) > 0, "Referenced crate '" << e.name << "' isn't loaded for `extern crate`"); - p.bind( ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) }) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Crate({ &crate.m_extern_crates.at(e.name) }); _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Enum, - p.bind( ::AST::PathBinding::make_Enum({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Union, - p.bind( ::AST::PathBinding::make_Union({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Union({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Trait, - p.bind( ::AST::PathBinding::make_Trait({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Trait({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Type, - p.bind( ::AST::PathBinding::make_TypeAlias({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({&e}); _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), // - Mixed (Struct, - p.bind( ::AST::PathBinding::make_Struct({&e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Struct({&e}); // - If the struct is a tuple-like struct (or unit-like), it presents in the value namespace if( ! e.m_data.is_Struct() ) { + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, p); } _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), // - Values only (Function, - p.bind( ::AST::PathBinding::make_Function({&e}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Function({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); ), (Static, - p.bind( ::AST::PathBinding::make_Static({&e}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({&e}); _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); ) ) @@ -182,73 +183,48 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) // TODO: Ensure that the path is canonical? const auto& sp = i_data.sp; - struct H { - static void handle_pb(const Span& sp, AST::Module& mod, const AST::Named& i, const AST::PathBinding& pb, bool allow_collide) - { - const auto& i_data = i.data.as_Use(); - TU_MATCH(::AST::PathBinding, (pb), (e), - (Unbound, - ), - (Variable, - BUG(sp, "Import was bound to variable"); - ), - (TypeParameter, - BUG(sp, "Import was bound to type parameter"); - ), - (TraitMethod, - BUG(sp, "Import was bound to trait method"); - ), - (StructMethod, - BUG(sp, "Import was bound to struct method"); - ), - - (Crate , _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), - (Module, _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); ), - (Enum, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - (Union, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - (Trait, _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - (TypeAlias,_add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - - (Struct, - _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - // - If the struct is a tuple-like struct, it presents in the value namespace - assert(e.struct_ || e.hir); - if( !(e.struct_ ? e.struct_->m_data.is_Struct() : e.hir->m_data.is_Named()) ) - { - _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - } - ), - (Static , _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - (Function, _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); ), - (EnumVar , - bool is_struct = false; - if( e.enum_ ) { - ASSERT_BUG(sp, e.idx < e.enum_->variants().size(), "Variant out of range for " << i_data.path); - is_struct = e.enum_->variants().at(e.idx).m_data.is_Struct(); - } - else { - //ASSERT_BUG(sp, e.idx < e.hir->m_variants.size(), "Variant out of range for " << i_data.path); - is_struct = TU_TEST1(e.hir->m_data, Data, .at(e.idx).is_struct); - } - if( is_struct ) - _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - else - _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - ) - ) + ASSERT_BUG(sp, i_data.path.m_bindings.has_binding(), "`use " << i_data.path << "` left unbound in module " << mod.path()); + + bool allow_collide = false; + // - Types + {TU_MATCH_HDRA( (i_data.path.m_bindings.type), {) + TU_ARMA(Unbound, _e) { + DEBUG(i.name << " - Not a type/module"); } - }; - if( i_data.path.binding().is_Unbound() ) { - BUG(sp, "`use " << i_data.path << "` left unbound in module " << mod.path()); - } - else { - H::handle_pb(sp, mod, i, i_data.path.binding(), false); - } - if( i_data.alt_binding.is_Unbound() ) { - // Doesn't matter - } - else { - H::handle_pb(sp, mod, i, i_data.alt_binding, true); + TU_ARMA(TypeParameter, e) + BUG(sp, "Import was bound to type parameter"); + TU_ARMA(Crate , e) + _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Module, e) + _add_item(sp, mod, IndexName::Namespace, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Enum, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Union, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Trait, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(TypeAlias, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Struct, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(EnumVar, e) + _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + }} + // - Values + TU_MATCH_HDRA( (i_data.path.m_bindings.value), {) + TU_ARMA(Unbound, _e) { + DEBUG(i.name << " - Not a value"); + } + TU_ARMA(Variable, e) + BUG(sp, "Import was bound to a variable"); + TU_ARMA(Struct, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(EnumVar, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Static , e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); + TU_ARMA(Function, e) + _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); } } else @@ -298,22 +274,22 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C //throw ""; ), (Module, - p.bind( ::AST::PathBinding::make_Module({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), (Trait, - p.bind( ::AST::PathBinding::make_Trait({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); ), (Struct, - p.bind( ::AST::PathBinding::make_Struct({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), (Union, - p.bind( ::AST::PathBinding::make_Union({nullptr, &e}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); ), (Enum, - p.bind( ::AST::PathBinding::make_Enum({nullptr}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr}); ), (TypeAlias, - p.bind( ::AST::PathBinding::make_TypeAlias({nullptr}) ); + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ) ) _add_item_type( sp, dst_mod, it.first, is_pub, mv$(p), false ); @@ -333,8 +309,8 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C for(unsigned int i = 0; i < spath.m_components.size()-1; i ++) { const auto& it = hmod->m_mod_items.at( spath.m_components[i] ); if(it->ent.is_Enum()) { - ASSERT_BUG(sp, i + 1 == spath.m_components.size() - 1, ""); - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, 0}) ); + ASSERT_BUG(sp, i + 1 == spath.m_components.size() - 1, "Found enum not at penultimate component of HIR import path"); + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, 0}); // TODO: What's the index? vep = nullptr; hmod = nullptr; break ; @@ -355,20 +331,20 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C throw ""; ), (Constant, - p.bind( ::AST::PathBinding::make_Static({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr}); ), (Static, - p.bind( ::AST::PathBinding::make_Static({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Static({nullptr}); ), // TODO: What if these refer to an enum variant? (StructConstant, - p.bind( ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }); ), (StructConstructor, - p.bind( ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(sp, e.ty, true).as_Struct() }); ), (Function, - p.bind( ::AST::PathBinding::make_Function({nullptr}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_Function({nullptr}); ) ) } @@ -418,14 +394,14 @@ void Resolve_Index_Module_Wildcard__submod(AST::Crate& crate, AST::Module& dst_m void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst_mod, const AST::UseStmt& i_data, bool is_pub) { const auto& sp = i_data.sp; - const auto& b = i_data.path.binding(); + const auto& b = i_data.path.m_bindings.type; - TU_IFLET(::AST::PathBinding, b, Crate, e, + TU_IFLET(::AST::PathBinding_Type, b, Crate, e, DEBUG("Glob crate " << i_data.path); const auto& hmod = e.crate_->m_hir->m_root_module; Resolve_Index_Module_Wildcard__glob_in_hir_mod(sp, crate, dst_mod, hmod, i_data.path, is_pub); ) - else TU_IFLET(::AST::PathBinding, b, Module, e, + else TU_IFLET(::AST::PathBinding_Type, b, Module, e, DEBUG("Glob mod " << i_data.path); if( !e.module_ ) { @@ -438,7 +414,7 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst Resolve_Index_Module_Wildcard__submod(crate, dst_mod, *e.module_, is_pub); } ) - else TU_IFLET(::AST::PathBinding, b, Enum, e, + else TU_IFLET(::AST::PathBinding_Type, b, Enum, e, ASSERT_BUG(sp, e.enum_ || e.hir, "Glob import but enum pointer not set - " << i_data.path); if( e.enum_ ) { @@ -446,11 +422,12 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst unsigned int idx = 0; for( const auto& ev : e.enum_->variants() ) { ::AST::Path p = i_data.path + ev.m_name; - p.bind( ::AST::PathBinding::make_EnumVar({e.enum_, idx}) ); if( ev.m_data.is_Struct() ) { + p.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({e.enum_, idx}); _add_item_type ( sp, dst_mod, ev.m_name, is_pub, mv$(p), false ); } else { + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({e.enum_, idx}); _add_item_value( sp, dst_mod, ev.m_name, is_pub, mv$(p), false ); } @@ -467,7 +444,7 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst for(const auto& ev : de->variants) { ::AST::Path p = i_data.path + ev.name; - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, idx, e.hir}) ); + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, idx, e.hir}); _add_item_value( sp, dst_mod, ev.name, is_pub, mv$(p), false ); @@ -480,12 +457,13 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst for(const auto& ev : *de) { ::AST::Path p = i_data.path + ev.name; - p.bind( ::AST::PathBinding::make_EnumVar({nullptr, idx, e.hir}) ); if( ev.is_struct ) { + p.m_bindings.type = ::AST::PathBinding_Type::make_EnumVar({nullptr, idx, e.hir}); _add_item_type ( sp, dst_mod, ev.name, is_pub, mv$(p), false ); } else { + p.m_bindings.value = ::AST::PathBinding_Value::make_EnumVar({nullptr, idx, e.hir}); _add_item_value( sp, dst_mod, ev.name, is_pub, mv$(p), false ); } @@ -598,9 +576,9 @@ void Resolve_Index_Module_Normalise_Path_ext(const ::AST::Crate& crate, const Sp { TU_IFLET( ::HIR::TypeItem, it_m->second->ent, Import, e, // Replace the path with this path (maintaining binding) - auto binding = path.binding().clone(); + auto bindings = path.m_bindings.clone(); path = hir_to_ast(e.path); - path.bind( mv$(binding) ); + path.m_bindings = mv$(bindings); ) return ; } @@ -611,9 +589,9 @@ void Resolve_Index_Module_Normalise_Path_ext(const ::AST::Crate& crate, const Sp { TU_IFLET( ::HIR::ValueItem, it_v->second->ent, Import, e, // Replace the path with this path (maintaining binding) - auto binding = path.binding().clone(); + auto bindings = path.m_bindings.clone(); path = hir_to_ast(e.path); - path.bind( mv$(binding) ); + path.m_bindings = mv$(bindings); ) return ; } @@ -648,27 +626,26 @@ bool Resolve_Index_Module_Normalise_Path(const ::AST::Crate& crate, const Span& auto new_path = ie.path; for(unsigned int j = i+1; j < info.nodes.size(); j ++) new_path.nodes().push_back( mv$(info.nodes[j]) ); - new_path.bind( path.binding().clone() ); + new_path.m_bindings = path.m_bindings.clone(); path = mv$(new_path); return Resolve_Index_Module_Normalise_Path(crate, sp, path, loc); } else { - TU_MATCH_DEF(::AST::PathBinding, (ie.path.binding()), (e), - ( + TU_MATCH_HDR( (ie.path.m_bindings.type), {) + default: BUG(sp, "Path " << path << " pointed to non-module " << ie.path); - ), - (Module, + TU_ARM( ie.path.m_bindings.type, Module, e) { mod = e.module_; - ), - (Crate, + } + TU_ARM( ie.path.m_bindings.type, Crate, e) { Resolve_Index_Module_Normalise_Path_ext(crate, sp, path, loc, *e.crate_, i+1); return false; - ), - (Enum, + } + TU_ARM( ie.path.m_bindings.type, Enum, e) { // NOTE: Just assuming that if an Enum is hit, it's sane return false; - ) - ) + } + } } } diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index db942641..a0d1aa53 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -22,8 +22,8 @@ enum class Lookup ::AST::Path Resolve_Use_AbsolutisePath(const ::AST::Path& base_path, ::AST::Path path); void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path, ::std::span< const ::AST::Module* > parent_modules={}); -::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules, Lookup allow=Lookup::Any); -::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start, Lookup allow); +::AST::Path::Bindings Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules); +::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start); void Resolve_Use(::AST::Crate& crate) @@ -117,14 +117,22 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( !use_stmt_data.path.m_class.is_Absolute() ) BUG(span, "Use path is not absolute after absolutisation"); + // NOTE: Use statements can refer to _three_ different items + // - types/modules ("type namespace") + // - values ("value namespace") + // - macros ("macro namespace") // TODO: Have Resolve_Use_GetBinding return the actual path - use_stmt_data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules) ); + use_stmt_data.path.m_bindings = Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules); + if( !use_stmt_data.path.m_bindings.has_binding() ) + { + ERROR(span, E0000, "Unable to resolve `use` target " << use_stmt_data.path); + } DEBUG("'" << use_stmt.name << "' = " << use_stmt_data.path); // - If doing a glob, ensure the item type is valid if( use_stmt.name == "" ) { - TU_MATCH_DEF(::AST::PathBinding, (use_stmt_data.path.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding_Type, (use_stmt_data.path.m_bindings.type), (e), ( ERROR(span, E0000, "Wildcard import of invalid item type - " << use_stmt_data.path); ), @@ -138,35 +146,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } else { - // TODO: Handle case where a use can resolve to two different items (one value, one type/namespace) - // - Easiest way is with an extra binding slot - Lookup allow = Lookup::Any; - switch( use_stmt_data.path.binding().tag() ) - { - case ::AST::PathBinding::TAG_Crate: - case ::AST::PathBinding::TAG_Module: - case ::AST::PathBinding::TAG_Trait: - case ::AST::PathBinding::TAG_TypeAlias: - case ::AST::PathBinding::TAG_Enum: - allow = Lookup::Value; - break; - case ::AST::PathBinding::TAG_Struct: - case ::AST::PathBinding::TAG_Union: - allow = Lookup::Value; - break; - case ::AST::PathBinding::TAG_EnumVar: - allow = Lookup::Value; - break; - case ::AST::PathBinding::TAG_Static: - case ::AST::PathBinding::TAG_Function: - allow = Lookup::Type; - break; - // DEAD, Unbound, ... - default: break; - } - ASSERT_BUG(span, allow != Lookup::Any, "Invalid path binding type in use statement - " << use_stmt_data.path); - use_stmt_data.alt_binding = Resolve_Use_GetBinding(span, crate, use_stmt_data.path, parent_modules, allow); - DEBUG("- Alt Binding: " << use_stmt_data.alt_binding); } } @@ -264,25 +243,24 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } } -::AST::PathBinding Resolve_Use_GetBinding_Mod( +::AST::Path::Bindings Resolve_Use_GetBinding_Mod( const Span& span, const ::AST::Crate& crate, const ::AST::Module& mod, const ::std::string& des_item_name, - ::std::span< const ::AST::Module* > parent_modules, - Lookup allow + ::std::span< const ::AST::Module* > parent_modules ) { + ::AST::Path::Bindings rv; // If the desired item is an anon module (starts with #) then parse and index if( des_item_name.size() > 0 && des_item_name[0] == '#' ) { unsigned int idx = 0; if( ::std::sscanf(des_item_name.c_str(), "#%u", &idx) != 1 ) { BUG(span, "Invalid anon path segment '" << des_item_name << "'"); } - if( idx >= mod.anon_mods().size() ) { - BUG(span, "Invalid anon path segment '" << des_item_name << "'"); - } + ASSERT_BUG(span, idx < mod.anon_mods().size(), "Invalid anon path segment '" << des_item_name << "'"); assert( mod.anon_mods()[idx] ); - return ::AST::PathBinding::make_Module({&*mod.anon_mods()[idx], nullptr}); + rv.type = ::AST::PathBinding_Type::make_Module({&*mod.anon_mods()[idx], nullptr}); + return rv; } // Seach for the name defined in the module. @@ -292,8 +270,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path continue ; if( item.name == des_item_name ) { - //if( allow != Lookup::Any ) - // DEBUG(mod.path() << " " << des_item_name << " " << item.data.tag_str()); TU_MATCH(::AST::Item, (item.data), (e), (None, // IMPOSSIBLE - Handled above @@ -314,46 +290,38 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path BUG(span, "Hit Extern in use resolution"); ), (Crate, - if( allow != Lookup::Value ) - ASSERT_BUG(span, crate.m_extern_crates.count(e.name), "Crate '" << e.name << "' not loaded"); - return ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) }); + ASSERT_BUG(span, crate.m_extern_crates.count(e.name), "Crate '" << e.name << "' not loaded"); + rv.type = ::AST::PathBinding_Type::make_Crate({ &crate.m_extern_crates.at(e.name) }); ), (Type, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_TypeAlias({&e}); + rv.type = ::AST::PathBinding_Type::make_TypeAlias({&e}); ), (Trait, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_Trait({&e}); + rv.type = ::AST::PathBinding_Type::make_Trait({&e}); ), (Function, - if( allow != Lookup::Type ) - return ::AST::PathBinding::make_Function({&e}); + rv.value = ::AST::PathBinding_Value::make_Function({&e}); ), (Static, - if( allow != Lookup::Type ) - return ::AST::PathBinding::make_Static({&e}); + rv.value = ::AST::PathBinding_Value::make_Static({&e}); ), (Struct, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_Struct({&e}); - if( e.m_data.is_Tuple() && allow != Lookup::Type ) - return ::AST::PathBinding::make_Struct({&e}); + if( !e.m_data.is_Struct() ) + rv.value = ::AST::PathBinding_Value::make_Struct({&e}); + rv.type = ::AST::PathBinding_Type::make_Struct({&e}); ), (Enum, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_Enum({&e}); + rv.type = ::AST::PathBinding_Type::make_Enum({&e}); ), (Union, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_Union({&e}); + rv.type = ::AST::PathBinding_Type::make_Union({&e}); ), (Module, - if( allow != Lookup::Value ) - return ::AST::PathBinding::make_Module({&e}); + rv.type = ::AST::PathBinding_Type::make_Module({&e}); ) ) + return rv; } } @@ -366,58 +334,33 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path const Span& sp2 = imp_data.sp; if( imp.name == des_item_name ) { DEBUG("- Named import " << imp.name << " = " << imp_data); - if( imp_data.path.binding().is_Unbound() ) { + if( !imp_data.path.m_bindings.has_binding() ) { DEBUG(" > Needs resolve"); // TODO: Handle possibility of recursion //out_path = imp_data.path; - return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules, allow); + return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules); } else { - if( allow != Lookup::Any && allow != Lookup::AnyOpt ) - { - switch( imp_data.path.binding().tag() ) - { - case ::AST::PathBinding::TAG_Crate: - case ::AST::PathBinding::TAG_Module: - case ::AST::PathBinding::TAG_Trait: - case ::AST::PathBinding::TAG_TypeAlias: - case ::AST::PathBinding::TAG_Enum: - if( allow != Lookup::Type ) - continue; - break; - case ::AST::PathBinding::TAG_Struct: - break; - case ::AST::PathBinding::TAG_EnumVar: - break; - case ::AST::PathBinding::TAG_Static: - case ::AST::PathBinding::TAG_Function: - if( allow != Lookup::Value ) - continue; - break; - default: - break; - } - } //out_path = imp_data.path; - return imp_data.path.binding().clone(); + return imp_data.path.m_bindings.clone(); } } if( imp.is_pub && imp.name == "" ) { DEBUG("- Search glob of " << imp_data.path); // INEFFICIENT! Resolves and throws away the result (because we can't/shouldn't mutate here) - ::AST::PathBinding binding_; - const auto* binding = &imp_data.path.binding(); - if( binding->is_Unbound() ) { + ::AST::Path::Bindings bindings_; + const auto* bindings = &imp_data.path.m_bindings; + if( bindings->type.is_Unbound() ) { DEBUG("Temp resolving wildcard " << imp_data); // Handle possibility of recursion static ::std::vector resolve_stack_ptrs; if( ::std::find(resolve_stack_ptrs.begin(), resolve_stack_ptrs.end(), &imp_data) == resolve_stack_ptrs.end() ) { resolve_stack_ptrs.push_back( &imp_data ); - binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules); + bindings_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_data.path), parent_modules); // *waves hand* I'm not evil. - const_cast< ::AST::PathBinding&>( imp_data.path.binding() ) = binding_.clone(); - binding = &binding_; + const_cast< ::AST::Path::Bindings&>( imp_data.path.m_bindings ) = bindings_.clone(); + bindings = &bindings_; resolve_stack_ptrs.pop_back(); } else { @@ -428,28 +371,27 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path //out_path = imp_data.path; } - TU_MATCH_HDR( (*binding), {) - TU_ARM(*binding, Crate, e) { + TU_MATCH_HDRA( (bindings->type), {) + TU_ARMA(Crate, e) { assert(e.crate_); const ::HIR::Module& hmod = e.crate_->m_hir->m_root_module; - auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0, allow); - if( ! rv.is_Unbound() ) { + auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0); + if( rv.has_binding() ) { return mv$(rv); } } - TU_ARM(*binding, Module, e) { - auto allow_inner = (allow == Lookup::Any ? Lookup::AnyOpt : allow); + TU_ARMA(Module, e) { if( e.module_ ) { // TODO: Prevent infinite recursion? - auto rv = Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {}, allow_inner); - if( ! rv.is_Unbound() ) { + auto rv = Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {}); + if( rv.has_binding() ) { return mv$(rv); } } else if( e.hir ) { const ::HIR::Module& hmod = *e.hir; - auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0, allow); - if( ! rv.is_Unbound() ) { + auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0); + if( rv.has_binding() ) { return mv$(rv); } } @@ -457,7 +399,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path BUG(span, "NULL module for binding on glob of " << imp_data.path); } } - TU_ARM(*binding, Enum, e) { + TU_ARMA(Enum, e) { assert(e.enum_ || e.hir); if( e.enum_ ) { const auto& enm = *e.enum_; @@ -465,7 +407,12 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path for(const auto& var : enm.variants()) { if( var.m_name == des_item_name ) { - return ::AST::PathBinding::make_EnumVar({ &enm, i }); + ::AST::Path::Bindings rv; + if( var.m_data.is_Struct() ) + rv.type = ::AST::PathBinding_Type::make_EnumVar({ &enm, i }); + else + rv.value = ::AST::PathBinding_Value::make_EnumVar({ &enm, i }); + return rv; } i ++; } @@ -475,12 +422,19 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path auto idx = enm.find_variant(des_item_name); if( idx != SIZE_MAX ) { - return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast(idx), &enm }); + ::AST::Path::Bindings rv; + if( enm.m_data.is_Data() && enm.m_data.as_Data()[idx].is_struct ) { + rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast(idx), &enm }); + } + else { + rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast(idx), &enm }); + } + return rv; } } } break; default: - BUG(sp2, "Wildcard import expanded to an invalid item class - " << binding->tag_str()); + BUG(sp2, "Wildcard import expanded to an invalid item class - " << bindings->type.tag_str()); break; } } @@ -488,13 +442,12 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( mod.path().nodes().size() > 0 && mod.path().nodes().back().name()[0] == '#' ) { assert( parent_modules.size() > 0 ); - return Resolve_Use_GetBinding_Mod(span, crate, *parent_modules.back(), des_item_name, parent_modules.subspan(0, parent_modules.size()-1), allow); + return Resolve_Use_GetBinding_Mod(span, crate, *parent_modules.back(), des_item_name, parent_modules.subspan(0, parent_modules.size()-1)); } else { - if( allow == Lookup::Any ) - ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path()); - else - return ::AST::PathBinding::make_Unbound({}); + //if( allow == Lookup::Any ) + // ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path()); + return ::AST::Path::Bindings(); } } @@ -543,8 +496,9 @@ namespace { } } -::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start, Lookup allow) +::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const ::HIR::Module& hmodr, unsigned int start) { + ::AST::Path::Bindings rv; TRACE_FUNCTION_F(path); const auto& nodes = path.nodes(); const ::HIR::Module* hmod = &hmodr; @@ -577,7 +531,13 @@ namespace { if( idx == SIZE_MAX ) { ERROR(span, E0000, "Unable to find variant " << path); } - return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast(idx), &enm }); + if( enm.m_data.is_Data() && enm.m_data.as_Data()[idx].is_struct ) { + rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast(idx), &enm }); + } + else { + rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast(idx), &enm }); + } + return rv; } else { hmod = reinterpret_cast(ptr); @@ -597,16 +557,23 @@ namespace { if(idx == SIZE_MAX) { ERROR(span, E0000, "Unable to find variant " << path); } - return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast(idx), &e }); + if( e.m_data.is_Data() && e.m_data.as_Data()[idx].is_struct ) { + rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast(idx), &e }); + } + else { + rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast(idx), &e }); + } + return rv; ) ) } - if( allow != Lookup::Value ) + // - namespace/type items { auto it = hmod->m_mod_items.find(nodes.back().name()); - if( it != hmod->m_mod_items.end() ) { + if( it != hmod->m_mod_items.end() ) + { const auto* item_ptr = &it->second->ent; - DEBUG("E : " << nodes.back().name() << " = " << item_ptr->tag_str()); + DEBUG("E : Mod " << nodes.back().name() << " = " << item_ptr->tag_str()); if( item_ptr->is_Import() ) { const auto& e = item_ptr->as_Import(); const auto& ec = crate.m_extern_crates.at( e.path.m_crate_name ); @@ -616,94 +583,117 @@ namespace { p.m_components.pop_back(); const auto& enm = ec.m_hir->get_typeitem_by_path(span, p, true).as_Enum(); assert(e.idx < enm.num_variants()); - return ::AST::PathBinding::make_EnumVar({ nullptr, e.idx, &enm }); + rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, e.idx, &enm }); + } + else if( e.path.m_components.empty() ) + { + rv.type = ::AST::PathBinding_Type::make_Module({nullptr, &ec.m_hir->m_root_module}); + } + else + { + item_ptr = &ec.m_hir->get_typeitem_by_path(span, e.path, true); // ignore_crate_name=true } - if( e.path.m_components.empty() ) - return ::AST::PathBinding::make_Module({nullptr, &ec.m_hir->m_root_module}); - item_ptr = &ec.m_hir->get_typeitem_by_path(span, e.path, true); // ignore_crate_name=true } - TU_MATCHA( (*item_ptr), (e), - (Import, - BUG(span, "Recursive import in " << path << " - " << it->second->ent.as_Import().path << " -> " << e.path); - ), - (Module, - return ::AST::PathBinding::make_Module({nullptr, &e}); - ), - (TypeAlias, - return ::AST::PathBinding::make_TypeAlias({nullptr}); - ), - (Enum, - return ::AST::PathBinding::make_Enum({nullptr, &e}); - ), - (Struct, - return ::AST::PathBinding::make_Struct({nullptr, &e}); - ), - (Union, - return ::AST::PathBinding::make_Union({nullptr, &e}); - ), - (Trait, - return ::AST::PathBinding::make_Trait({nullptr, &e}); + if( rv.type.is_Unbound() ) + { + TU_MATCHA( (*item_ptr), (e), + (Import, + BUG(span, "Recursive import in " << path << " - " << it->second->ent.as_Import().path << " -> " << e.path); + ), + (Module, + rv.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); + ), + (TypeAlias, + rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); + ), + (Enum, + rv.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); + ), + (Struct, + rv.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); + ), + (Union, + rv.type = ::AST::PathBinding_Type::make_Union({nullptr, &e}); + ), + (Trait, + rv.type = ::AST::PathBinding_Type::make_Trait({nullptr, &e}); + ) ) - ) + } + } + else + { + DEBUG("Types = " << FMT_CB(ss, for(const auto& e : hmod->m_mod_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; })); } - DEBUG("Types = " << FMT_CB(ss, for(const auto& e : hmod->m_mod_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; })); } - if( allow != Lookup::Type ) + // - Values { auto it2 = hmod->m_value_items.find(nodes.back().name()); if( it2 != hmod->m_value_items.end() ) { const auto* item_ptr = &it2->second->ent; - DEBUG("E : " << nodes.back().name() << " = " << item_ptr->tag_str()); + DEBUG("E : Value " << nodes.back().name() << " = " << item_ptr->tag_str()); if( item_ptr->is_Import() ) { const auto& e = item_ptr->as_Import(); // This doesn't need to recurse - it can just do a single layer (as no Import should refer to another) const auto& ec = crate.m_extern_crates.at( e.path.m_crate_name ); - if( e.is_variant ) { + if( e.is_variant ) + { auto p = e.path; p.m_components.pop_back(); const auto& enm = ec.m_hir->get_typeitem_by_path(span, p, true).as_Enum(); assert(e.idx < enm.num_variants()); - return ::AST::PathBinding::make_EnumVar({ nullptr, e.idx, &enm }); + rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, e.idx, &enm }); + } + else + { + item_ptr = &ec.m_hir->get_valitem_by_path(span, e.path, true); // ignore_crate_name=true } - item_ptr = &ec.m_hir->get_valitem_by_path(span, e.path, true); // ignore_crate_name=true } - TU_MATCHA( (*item_ptr), (e), - (Import, - BUG(span, "Recursive import in " << path << " - " << it2->second->ent.as_Import().path << " -> " << e.path); - ), - (Constant, - return ::AST::PathBinding::make_Static({ nullptr }); - ), - (Static, - return ::AST::PathBinding::make_Static({ nullptr }); - ), - // TODO: What happens if these two refer to an enum constructor? - (StructConstant, - ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty); - return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() }); - ), - (StructConstructor, - ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty); - return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() }); - ), - (Function, - return ::AST::PathBinding::make_Function({ nullptr }); + if( rv.value.is_Unbound() ) + { + TU_MATCHA( (*item_ptr), (e), + (Import, + BUG(span, "Recursive import in " << path << " - " << it2->second->ent.as_Import().path << " -> " << e.path); + ), + (Constant, + rv.value = ::AST::PathBinding_Value::make_Static({ nullptr }); + ), + (Static, + rv.value = ::AST::PathBinding_Value::make_Static({ nullptr }); + ), + // TODO: What happens if these two refer to an enum constructor? + (StructConstant, + ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty); + rv.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() }); + ), + (StructConstructor, + ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty); + rv.value = ::AST::PathBinding_Value::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() }); + ), + (Function, + rv.value = ::AST::PathBinding_Value::make_Function({ nullptr }); + ) ) - ) + } + } + else + { + DEBUG("Values = " << FMT_CB(ss, for(const auto& e : hmod->m_value_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; })); } - - DEBUG("Values = " << FMT_CB(ss, for(const auto& e : hmod->m_value_items){ ss << e.first << ":" << e.second->ent.tag_str() << ","; })); } - DEBUG("E : None"); - return ::AST::PathBinding::make_Unbound({}); + if( rv.type.is_Unbound() && rv.value.is_Unbound() ) + { + DEBUG("E : None"); + } + return rv; } -::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const AST::ExternCrate& ec, unsigned int start, Lookup allow) +::AST::Path::Bindings Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, const AST::ExternCrate& ec, unsigned int start) { - return Resolve_Use_GetBinding__ext(span, crate, path, ec.m_hir->m_root_module, start, allow); + return Resolve_Use_GetBinding__ext(span, crate, path, ec.m_hir->m_root_module, start); } -::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules, Lookup allow) +::AST::Path::Bindings Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules) { TRACE_FUNCTION_F(path); //::AST::Path rv; @@ -713,14 +703,17 @@ namespace { const auto& path_abs = path.m_class.as_Absolute(); ASSERT_BUG(span, crate.m_extern_crates.count(path_abs.crate), "Crate '" << path_abs.crate << "' not loaded"); - return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0, allow); + return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0); } + ::AST::Path::Bindings rv; + const AST::Module* mod = &crate.m_root_module; const auto& nodes = path.nodes(); if( nodes.size() == 0 ) { // An import of the root. - return ::AST::PathBinding::make_Module({ mod, nullptr }); + rv.type = ::AST::PathBinding_Type::make_Module({ mod, nullptr }); + return rv; } for( unsigned int i = 0; i < nodes.size()-1; i ++ ) { @@ -729,19 +722,18 @@ namespace { //rv = Resolve_Use_CanoniseAndBind_Mod(span, crate, *mod, mv$(rv), nodes[i].name(), parent_modules, Lookup::Type); //const auto& b = rv.binding(); assert(mod); - auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.at(i).name(), parent_modules, Lookup::Type); - TU_MATCH_DEF(::AST::PathBinding, (b), (e), - ( - ERROR(span, E0000, "Unexpected item type " << b.tag_str() << " in import of " << path); - ), - (Unbound, - ERROR(span, E0000, "Cannot find component " << i << " of " << path); - ), - (Crate, + auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.at(i).name(), parent_modules); + TU_MATCH_HDRA( (b.type), {) + default: + ERROR(span, E0000, "Unexpected item type " << b.type.tag_str() << " in import of " << path); + TU_ARMA(Unbound, e) { + ERROR(span, E0000, "Cannot find component " << i << " of " << path << " (" << b.type << ")"); + } + TU_ARMA(Crate, e) { // TODO: Mangle the original path (or return a new path somehow) - return Resolve_Use_GetBinding__ext(span, crate, path, *e.crate_, i+1, allow); - ), - (Enum, + return Resolve_Use_GetBinding__ext(span, crate, path, *e.crate_, i+1); + } + TU_ARMA(Enum, e) { const auto& enum_ = *e.enum_; i += 1; if( i != nodes.size() - 1 ) { @@ -750,10 +742,12 @@ namespace { const auto& node2 = nodes[i]; int variant_index = -1; + bool is_value; for( unsigned int j = 0; j < enum_.variants().size(); j ++ ) { if( enum_.variants()[j].m_name == node2.name() ) { variant_index = j; + is_value = !enum_.variants()[i].m_data.is_Struct(); break ; } } @@ -761,22 +755,32 @@ namespace { ERROR(span, E0000, "Unknown enum variant '" << node2.name() << "'"); } - return ::AST::PathBinding::make_EnumVar({&enum_, static_cast(variant_index)}); - ), - (Module, + if( is_value ) { + rv.value = ::AST::PathBinding_Value::make_EnumVar({&enum_, static_cast(variant_index)}); + } + else { + rv.type = ::AST::PathBinding_Type::make_EnumVar({&enum_, static_cast(variant_index)}); + } + return rv; + } + TU_ARMA(Module, e) { ASSERT_BUG(span, e.module_ || e.hir, "nullptr module pointer in node " << i << " of " << path); if( !e.module_ ) { assert(e.hir); // TODO: Mangle the original path (or return a new path somehow) - return Resolve_Use_GetBinding__ext(span, crate, path, *e.hir, i+1, allow); + return Resolve_Use_GetBinding__ext(span, crate, path, *e.hir, i+1); } mod = e.module_; - ) - ) + } + } } assert(mod); - return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name(), parent_modules, allow); + return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name(), parent_modules); } +//::AST::PathBinding_Macro Resolve_Use_GetBinding_Macro(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, ::std::span< const ::AST::Module* > parent_modules) +//{ +// throw ""; +//} -- cgit v1.2.3 From 4e69aee8c5f942ee25ea6583a156a7aa4bc41d5c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Dec 2018 21:34:40 +0800 Subject: Lower HIR - Rough (roughshod) handling of `repr(align(N))` --- src/hir/from_ast.cpp | 58 +++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index f62d097a..f5d841a7 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -879,56 +879,54 @@ namespace { ) ) - auto struct_repr = ::HIR::Struct::Repr::Rust; + auto rv = ::HIR::Struct { + LowerHIR_GenericParams(ent.params(), nullptr), + ::HIR::Struct::Repr::Rust, + mv$(data) + }; + if( const auto* attr_repr = attrs.get("repr") ) { - ASSERT_BUG(Span(), attr_repr->has_sub_items(), "#[repr] attribute malformed, " << *attr_repr); - bool is_c = false; - bool is_simd = false; - bool is_packed = false; - ASSERT_BUG(Span(), attr_repr->items().size() > 0, "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(attr_repr->span(), attr_repr->has_sub_items(), "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(attr_repr->span(), attr_repr->items().size() > 0, "#[repr] attribute malformed, " << *attr_repr); for( const auto& a : attr_repr->items() ) { - ASSERT_BUG(Span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); const auto& repr_str = a.name(); if( repr_str == "C" ) { - is_c = true; + ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + rv.m_repr = ::HIR::Struct::Repr::C; } else if( repr_str == "packed" ) { - is_packed = true; + ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + rv.m_repr = ::HIR::Struct::Repr::Packed; } else if( repr_str == "simd" ) { - is_simd = true; + ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + rv.m_repr = ::HIR::Struct::Repr::Simd; } else if( repr_str == "transparent" ) { + ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); // TODO: Mark so the C backend knows that it's supposed to be transparent + //rv.m_repr = ::HIR::Struct::Repr::Transparent; + } + else if( repr_str == "align" ) { + //ASSERT_BUG(a.span(), a.has_string(), "#[repr(aligned)] attribute malformed, " << *attr_repr); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + // TODO: Alignment repr + //rv.m_repr = ::HIR::Struct::Repr::Aligned; + //rv.m_align_size = ::std::stol(a.string()); } else { TODO(a.span(), "Handle struct repr '" << repr_str << "'"); } } - - if( is_packed ) { - // TODO: What if `simd` is present? - // NOTE: repr(packed,C) is treated as the same as repr(packed) in mrustc - struct_repr = ::HIR::Struct::Repr::Packed; - } - else if( is_c ) { - // TODO: What if `simd` is present? - struct_repr = ::HIR::Struct::Repr::C; - } - else if( is_simd ) { - struct_repr = ::HIR::Struct::Repr::Simd; - } - else { - } } - return ::HIR::Struct { - LowerHIR_GenericParams(ent.params(), nullptr), - struct_repr, - mv$(data) - }; + return rv; } ::HIR::Enum LowerHIR_Enum(::HIR::ItemPath path, const ::AST::Enum& ent, const ::AST::AttributeList& attrs, ::std::function push_struct) -- cgit v1.2.3 From 28a48cfe2fde578219de5e15268348897c73b0d7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 29 Dec 2018 15:00:52 +0800 Subject: HIR - Add new struct reprs (mostly stubbed) - Also cleared out some dead code in target.cpp --- src/hir/deserialise.cpp | 3 +- src/hir/from_ast.cpp | 23 ++++---- src/hir/hir.cpp | 15 ++++++ src/hir/hir.hpp | 4 ++ src/hir/serialise.cpp | 1 + src/trans/target.cpp | 136 ++---------------------------------------------- src/trans/target.hpp | 13 ----- 7 files changed, 37 insertions(+), 158 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index afce2fe4..9ce063b4 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -995,11 +995,12 @@ default: throw ""; } + auto align = static_cast(m_in.read_u64c()); auto markings = deserialise_markings(); auto str_markings = deserialise_str_markings(); return ::HIR::Struct { - mv$(params), repr, mv$(data), mv$(markings), mv$(str_markings) + mv$(params), repr, mv$(data), align, mv$(markings), mv$(str_markings) }; } ::HIR::Trait HirDeserialiser::deserialise_trait() diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index f5d841a7..23e722f4 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -894,31 +894,32 @@ namespace { const auto& repr_str = a.name(); if( repr_str == "C" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - rv.m_repr = ::HIR::Struct::Repr::C; + if( rv.m_repr != ::HIR::Struct::Repr::Packed ) + { + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::C; + } } else if( repr_str == "packed" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust || rv.m_repr == ::HIR::Struct::Repr::C, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); rv.m_repr = ::HIR::Struct::Repr::Packed; } else if( repr_str == "simd" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); rv.m_repr = ::HIR::Struct::Repr::Simd; } else if( repr_str == "transparent" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - // TODO: Mark so the C backend knows that it's supposed to be transparent - //rv.m_repr = ::HIR::Struct::Repr::Transparent; + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::Transparent; } else if( repr_str == "align" ) { //ASSERT_BUG(a.span(), a.has_string(), "#[repr(aligned)] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes"); - // TODO: Alignment repr - //rv.m_repr = ::HIR::Struct::Repr::Aligned; - //rv.m_align_size = ::std::stol(a.string()); + ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + rv.m_repr = ::HIR::Struct::Repr::Aligned; + //rv.m_forced_alignment = ::std::stol(a.string()); } else { TODO(a.span(), "Handle struct repr '" << repr_str << "'"); diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 475928a1..bd396df9 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -93,6 +93,21 @@ namespace HIR { ) return true; } + + ::std::ostream& operator<<(::std::ostream& os, const Struct::Repr& x) { + os << "repr("; + switch(x) + { + case Struct::Repr::Rust: os << "Rust"; break; + case Struct::Repr::C: os << "C"; break; + case Struct::Repr::Packed: os << "packed"; break; + case Struct::Repr::Simd: os << "simd"; break; + case Struct::Repr::Aligned: os << "align(?)"; break; + case Struct::Repr::Transparent: os << "transparent"; break; + } + os << ")"; + return os; + } } size_t HIR::Enum::find_variant(const ::std::string& name) const diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 33200e96..fc4a19e8 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -267,6 +267,8 @@ public: C, Packed, Simd, + Aligned, // Alignment stored elsewhere + Transparent, }; TAGGED_UNION(Data, Unit, (Unit, struct {}), @@ -277,10 +279,12 @@ public: GenericParams m_params; Repr m_repr; Data m_data; + unsigned m_forced_alignment = 0; TraitMarkings m_markings; StructMarkings m_struct_markings; }; +extern ::std::ostream& operator<<(::std::ostream& os, const Struct::Repr& x); class Union { public: diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 50da4453..c3a27998 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -975,6 +975,7 @@ ) ) + m_out.write_u64c(item.m_forced_alignment); serialise(item.m_markings); serialise(item.m_struct_markings); } diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 121a9134..dccc566d 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -517,139 +517,6 @@ void Target_SetCfg(const ::std::string& target_name) }); } -namespace { - // Returns NULL when the repr can't be determined - ::std::unique_ptr make_struct_repr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) - { - TRACE_FUNCTION_F(ty); - ::std::vector ents; - bool packed = false; - bool allow_sort = false; - if( const auto* te = ty.m_data.opt_Path() ) - { - const auto& str = *te->binding.as_Struct(); - auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, &te->path.m_data.as_Generic().m_params, nullptr); - auto monomorph = [&](const auto& tpl) { - auto rv = monomorphise_type_with(sp, tpl, monomorph_cb); - resolve.expand_associated_types(sp, rv); - return rv; - }; - TU_MATCHA( (str.m_data), (se), - (Unit, - ), - (Tuple, - unsigned int idx = 0; - for(const auto& e : se) - { - auto ty = monomorph(e.ent); - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, ty, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in tuple struct"); - ents.push_back(StructRepr::Ent { idx++, size, align, mv$(ty) }); - } - ), - (Named, - unsigned int idx = 0; - for(const auto& e : se) - { - auto ty = monomorph(e.second.ent); - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, ty, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in struct"); - ents.push_back(StructRepr::Ent { idx++, size, align, mv$(ty) }); - } - ) - ) - switch(str.m_repr) - { - case ::HIR::Struct::Repr::Packed: - packed = true; - TODO(sp, "make_struct_repr - repr(packed)"); // needs codegen to know to pack the structure - break; - case ::HIR::Struct::Repr::Simd: - case ::HIR::Struct::Repr::C: - // No sorting, no packing - break; - case ::HIR::Struct::Repr::Rust: - allow_sort = true; - break; - } - } - else if( const auto* te = ty.m_data.opt_Tuple() ) - { - unsigned int idx = 0; - for(const auto& t : *te) - { - size_t size, align; - if( !Target_GetSizeAndAlignOf(sp, resolve, t, size,align) ) - return nullptr; - if( size == SIZE_MAX ) - BUG(sp, "Unsized type in tuple"); - ents.push_back(StructRepr::Ent { idx++, size, align, t.clone() }); - } - } - else - { - BUG(sp, "Unexpected type in creating struct repr"); - } - - - if( allow_sort ) - { - // TODO: Sort by alignment then size (largest first) - // - Requires codegen to use this information - } - - StructRepr rv; - size_t cur_ofs = 0; - size_t max_align = 1; - for(auto& e : ents) - { - // Increase offset to fit alignment - if( !packed ) - { - while( cur_ofs % e.align != 0 ) - { - rv.ents.push_back({ ~0u, 1, 1, ::HIR::TypeRef( ::HIR::CoreType::U8 ) }); - cur_ofs ++; - } - } - max_align = ::std::max(max_align, e.align); - - rv.ents.push_back(mv$(e)); - cur_ofs += e.size; - } - if( !packed ) - { - while( cur_ofs % max_align != 0 ) - { - rv.ents.push_back({ ~0u, 1, 1, ::HIR::TypeRef( ::HIR::CoreType::U8 ) }); - cur_ofs ++; - } - } - return box$(rv); - } -} -const StructRepr* Target_GetStructRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) -{ - // TODO: Thread safety - // Map of generic paths to struct representations. - static ::std::map<::HIR::TypeRef, ::std::unique_ptr> s_cache; - - auto it = s_cache.find(ty); - if( it != s_cache.end() ) - { - return it->second.get(); - } - - auto ires = s_cache.insert(::std::make_pair( ty.clone(), make_struct_repr(sp, resolve, ty) )); - return ires.first->second.get(); -} - bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align) { TRACE_FUNCTION_FR(ty, "size=" << out_size << ", align=" << out_align); @@ -904,6 +771,9 @@ namespace { case ::HIR::Struct::Repr::Simd: // No sorting, no packing break; + case ::HIR::Struct::Repr::Aligned: + // TODO: Update the minimum alignment + case ::HIR::Struct::Repr::Transparent: case ::HIR::Struct::Repr::Rust: allow_sort = true; break; diff --git a/src/trans/target.hpp b/src/trans/target.hpp index b1ed9456..107d19e1 100644 --- a/src/trans/target.hpp +++ b/src/trans/target.hpp @@ -48,18 +48,6 @@ struct TargetSpec TargetArch m_arch; }; -struct StructRepr -{ - struct Ent { - unsigned int field_idx; - size_t size; - size_t align; - ::HIR::TypeRef ty; - }; - // List of types, including padding (indicated by a UINT_MAX field idx) - // Ordered as they would be emitted - ::std::vector ents; -}; struct TypeRepr { size_t align = 0; @@ -107,7 +95,6 @@ extern void Target_ExportCurSpec(const ::std::string& filename); extern bool Target_GetSizeOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size); extern bool Target_GetAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_align); extern bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align); -extern const StructRepr* Target_GetStructRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& struct_ty); extern const TypeRepr* Target_GetTypeRepr(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty); -- cgit v1.2.3 From cdedfd8738aa488f7b87fd65ac8ab160c0947b18 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 29 Dec 2018 16:55:27 +0800 Subject: Resolve/HIR - Rough handling of `pub use macro_path;` --- src/ast/ast.hpp | 8 +++++++- src/expand/derive.cpp | 6 +++--- src/expand/macro_rules.cpp | 4 ++-- src/expand/mod.cpp | 2 +- src/hir/from_ast.cpp | 19 +++++++++++++++++++ src/resolve/index.cpp | 20 ++++++++++++++++++-- 6 files changed, 50 insertions(+), 9 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 2d802f53..b80b5fb7 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -537,7 +537,13 @@ public: // List of macros imported from other modules (via #[macro_use], includes proc macros) // - First value is an absolute path to the macro (including crate name) - ::std::vector<::std::pair< ::std::vector<::std::string>, const MacroRules* >> m_macro_imports; + struct MacroImport { + bool is_pub; + ::std::string name; // Can be different, if `use foo as bar` is used + ::std::vector<::std::string> path; // includes the crate name + const MacroRules* macro_ptr; + }; + ::std::vector m_macro_imports; public: Module() {} diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 5e97c888..a03992da 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -2236,15 +2236,15 @@ static void derive_item(const Span& sp, const AST::Crate& crate, AST::Module& mo bool found = false; for(const auto& mac_path : mod.m_macro_imports) { - if( mac_path.first.back() == mac_name ) + if( mac_path.name == mac_name ) { - if( mac_path.second ) { + if( mac_path.macro_ptr ) { // macro_rules! based derive? TODO(sp, "Custom derive using macro_rules?"); } else { // proc_macro - Invoke the handler. - auto lex = ProcMacro_Invoke(sp, crate, mac_path.first, path.nodes().back().name(), item); + auto lex = ProcMacro_Invoke(sp, crate, mac_path.path, path.nodes().back().name(), item); if( lex ) { Parse_ModRoot_Items(*lex, mod); diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 89f394e1..3bacfcf7 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -61,8 +61,8 @@ class CMacroUseHandler: }); for(const auto& p : ec.m_hir->m_proc_macros) { - mod.m_macro_imports.push_back(::std::make_pair( p.path.m_components, nullptr )); - mod.m_macro_imports.back().first.insert( mod.m_macro_imports.back().first.begin(), p.path.m_crate_name ); + mod.m_macro_imports.push_back({ false, p.path.m_components.back(), p.path.m_components, nullptr }); + mod.m_macro_imports.back().path.insert( mod.m_macro_imports.back().path.begin(), p.path.m_crate_name ); } } ) diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 34c47455..4dfd1224 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -1044,7 +1044,7 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: } } for( const auto& mi: mod.m_macro_imports ) - DEBUG("- Imports '" << mi.first << "'"); + DEBUG("- Imports '" << mi.path << "'"); } // Insert prelude if: Enabled for this module, present for the crate, and this module is not an anon diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 23e722f4..49e5a4b6 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1803,6 +1803,25 @@ public: } } } + for( const auto& mac : crate.m_root_module.m_macro_imports ) + { + if( mac.is_pub ) + { + // TODO: Why does this to such a move? + auto v = ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast(mac.macro_ptr)) )) ); + + auto it = macros.find(mac.name); + if( it == macros.end() ) + { + auto res = macros.insert( mv$(v) ); + DEBUG("- Import " << mac.name << "! (from \"" << res.first->second->m_source_crate << "\")"); + } + else { + DEBUG("- Replace " << mac.name << "! (from \"" << it->second->m_source_crate << "\") with one from \"" << v.second->m_source_crate << "\""); + it->second = mv$( v.second ); + } + } + } } // - Proc Macros if( crate.m_crate_type == ::AST::Crate::Type::ProcMacro ) diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index bbcd7e58..48f2d0da 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -212,7 +212,7 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) _add_item_type(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); }} // - Values - TU_MATCH_HDRA( (i_data.path.m_bindings.value), {) + {TU_MATCH_HDRA( (i_data.path.m_bindings.value), {) TU_ARMA(Unbound, _e) { DEBUG(i.name << " - Not a value"); } @@ -226,7 +226,23 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); TU_ARMA(Function, e) _add_item_value(sp, mod, i.name, i.is_pub, i_data.path, !allow_collide); - } + }} + // - Macros + {TU_MATCH_HDRA( (i_data.path.m_bindings.macro), {) + TU_ARMA(Unbound, _e) { + DEBUG(i.name << " - Not a macro"); + } + TU_ARMA(MacroRules, e) { + ::std::vector<::std::string> path; + path.push_back( i_data.path.m_class.as_Absolute().crate ); + for(const auto& node : i_data.path.m_class.as_Absolute().nodes ) + path.push_back( node.name() ); + mod.m_macro_imports.push_back({ + i.is_pub, i.name, mv$(path), e.mac + }); + } + // TODO: Other imports (e.g. derives, which have different naming structures) + }} } else { -- cgit v1.2.3 From 6d0fe344e94670f2ac0e21094238181f38b0daec Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 5 Jan 2019 21:40:36 +0800 Subject: Handle MacroInv in some more places --- src/hir/from_ast.cpp | 3 +++ src/resolve/absolute.cpp | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 49e5a4b6..32561a76 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1155,6 +1155,9 @@ namespace { (None, // Ignore. ), + (MacroInv, + // Ignore. + ), (Type, bool is_sized = true; ::std::vector< ::HIR::TraitPath> trait_bounds; diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 7fa08aaf..d4147e92 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1933,7 +1933,9 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: { TU_MATCH(AST::Item, (i.data), (e), (None, ), - (MacroInv, BUG(i.data.span, "Resolve_Absolute_ImplItems - MacroInv");), + (MacroInv, + //BUG(i.data.span, "Resolve_Absolute_ImplItems - MacroInv"); + ), (ExternBlock, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), (Impl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), (NegImpl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), -- cgit v1.2.3 From aab9f94620c7d78377ffbd3fdbcb845657c86503 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 2 Feb 2019 17:34:02 +0800 Subject: HIR From AST - repr fiddling --- src/hir/from_ast.cpp | 66 ++++++++++++++++++++++++++++------------------- src/hir/from_ast_expr.cpp | 1 + src/resolve/absolute.cpp | 2 +- 3 files changed, 42 insertions(+), 27 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 32561a76..899d0b0c 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -156,28 +156,26 @@ const ::AST::Crate* g_ast_crate_ptr; } }; - TU_MATCH(::AST::Pattern::Data, (pat.data()), (e), - (MaybeBind, + TU_MATCH_HDRA( (pat.data()), {) + TU_ARMA(MaybeBind, e) { BUG(pat.span(), "Encountered MaybeBind pattern"); - ), - (Macro, + } + TU_ARMA(Macro, e) { BUG(pat.span(), "Encountered Macro pattern"); - ), - (Any, + } + TU_ARMA(Any, e) return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Any({}) }; - ), - (Box, + TU_ARMA(Box, e) return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Box({ box$(LowerHIR_Pattern( *e.sub )) }) }; - ), - (Ref, + TU_ARMA(Ref, e) return ::HIR::Pattern { mv$(binding), ::HIR::Pattern::Data::make_Ref({ @@ -185,8 +183,7 @@ const ::AST::Crate* g_ast_crate_ptr; box$(LowerHIR_Pattern( *e.sub )) }) }; - ), - (Tuple, + TU_ARMA(Tuple, e) { auto leading = H::lowerhir_patternvec( e.start ); auto trailing = H::lowerhir_patternvec( e.end ); @@ -209,9 +206,8 @@ const ::AST::Crate* g_ast_crate_ptr; }) }; } - ), - - (StructTuple, + } + TU_ARMA(StructTuple, e) { unsigned int leading_count = e.tup_pat.start.size(); unsigned int trailing_count = e.tup_pat.end .size(); TU_MATCH_HDRA( (e.path.m_bindings.value), {) @@ -318,12 +314,25 @@ const ::AST::Crate* g_ast_crate_ptr; }; } } - ), - (Struct, + } + TU_ARMA(Struct, e) { ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > sub_patterns; for(const auto& sp : e.sub_patterns) sub_patterns.push_back( ::std::make_pair(sp.first, LowerHIR_Pattern(sp.second)) ); + if( e.sub_patterns.empty() && !e.is_exhaustive ) { + if( e.path.m_bindings.value.is_EnumVar() ) { + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_EnumStruct({ + LowerHIR_GenericPath(pat.span(), e.path), + nullptr, 0, + mv$(sub_patterns), + e.is_exhaustive + }) + }; + } + } TU_MATCH_HDRA( (e.path.m_bindings.type), {) default: @@ -362,9 +371,9 @@ const ::AST::Crate* g_ast_crate_ptr; }; } } - ), + } - (Value, + TU_ARMA(Value, e) { struct H { static ::HIR::CoreType get_int_type(const Span& sp, const ::eCoreType ct) { switch(ct) @@ -448,8 +457,8 @@ const ::AST::Crate* g_ast_crate_ptr; }) }; } - ), - (Slice, + } + TU_ARMA(Slice, e) { ::std::vector< ::HIR::Pattern> leading; for(const auto& sp : e.sub_pats) leading.push_back( LowerHIR_Pattern(sp) ); @@ -459,8 +468,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(leading) }) }; - ), - (SplitSlice, + } + TU_ARMA(SplitSlice, e) { ::std::vector< ::HIR::Pattern> leading; for(const auto& sp : e.leading) leading.push_back( LowerHIR_Pattern(sp) ); @@ -483,8 +492,8 @@ const ::AST::Crate* g_ast_crate_ptr; mv$(trailing) }) }; - ) - ) + } + } throw "unreachable"; } @@ -889,12 +898,17 @@ namespace { { ASSERT_BUG(attr_repr->span(), attr_repr->has_sub_items(), "#[repr] attribute malformed, " << *attr_repr); ASSERT_BUG(attr_repr->span(), attr_repr->items().size() > 0, "#[repr] attribute malformed, " << *attr_repr); + // TODO: Change reprs to be a flag set (instead of an enum)? + // (Or at least make C be a flag) for( const auto& a : attr_repr->items() ) { const auto& repr_str = a.name(); if( repr_str == "C" ) { ASSERT_BUG(a.span(), a.has_noarg(), "#[repr] attribute malformed, " << *attr_repr); - if( rv.m_repr != ::HIR::Struct::Repr::Packed ) + if( rv.m_repr == ::HIR::Struct::Repr::Aligned ) + { + } + else if( rv.m_repr != ::HIR::Struct::Repr::Packed ) { ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); rv.m_repr = ::HIR::Struct::Repr::C; diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index cc642482..55c742ad 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -526,6 +526,7 @@ struct LowerHIR_ExprNode_Visitor: ::HIR::ExprNode_StructLiteral::t_values values; for(const auto& val : v.m_values) values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); + // TODO: What if `v.m_path` is an associated type (that's known to be a struct) m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), ! v.m_path.m_bindings.type.is_EnumVar(), diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 3652fb3a..d2609e9e 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -350,7 +350,7 @@ namespace auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { const auto& b = v->second.path.m_bindings.value; - if( b.is_EnumVar() ) { + if( const auto* be = b.opt_EnumVar() ) { DEBUG("- TY: Enum variant " << v->second.path); path = ::AST::Path( v->second.path ); return true; -- cgit v1.2.3 From 4960edb7d948e43efc58a28ecd05fa9237c8d240 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Feb 2019 13:42:13 +0800 Subject: HIR Expr - Have _StructLiteral take a HIR::Path (to allow associated types to be used) --- src/hir/expr.cpp | 2 +- src/hir/expr.hpp | 4 ++-- src/hir/from_ast.cpp | 12 ++++++++++- src/hir/from_ast_expr.cpp | 2 +- src/hir_conv/bind.cpp | 2 +- src/hir_conv/expand_type.cpp | 5 +++-- src/hir_expand/annotate_value_usage.cpp | 6 ++++-- src/hir_typeck/expr_check.cpp | 6 ++++-- src/hir_typeck/expr_cs.cpp | 15 ++++++++------ src/mir/from_hir.cpp | 35 +++++++++++++++++++-------------- 10 files changed, 56 insertions(+), 33 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 6b7c2e1a..589e2811 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -158,7 +158,7 @@ DEF_VISIT(ExprNode_PathValue, node, ) DEF_VISIT(ExprNode_Variable, , ) DEF_VISIT(ExprNode_StructLiteral, node, - visit_generic_path(::HIR::Visitor::PathContext::VALUE, node.m_path); + visit_path(::HIR::Visitor::PathContext::VALUE, node.m_path); if( node.m_base_value ) visit_node_ptr(node.m_base_value); for(auto& val : node.m_values) diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 15c0a489..140ba817 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -694,7 +694,7 @@ struct ExprNode_StructLiteral: { typedef ::std::vector< ::std::pair< ::std::string, ExprNodeP > > t_values; - ::HIR::GenericPath m_path; + ::HIR::Path m_path; bool m_is_struct; ::HIR::ExprNodeP m_base_value; t_values m_values; @@ -702,7 +702,7 @@ struct ExprNode_StructLiteral: /// Monomorphised types of each field. ::std::vector< ::HIR::TypeRef> m_value_types; - ExprNode_StructLiteral(Span sp, ::HIR::GenericPath path, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): + ExprNode_StructLiteral(Span sp, ::HIR::Path path, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): ExprNode( mv$(sp) ), m_path( mv$(path) ), m_is_struct( is_struct ), diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 899d0b0c..768593c4 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -628,7 +628,17 @@ const ::AST::Crate* g_ast_crate_ptr; return ::HIR::Path( LowerHIR_GenericPath(sp, path) ); ), (UFCS, - if( e.nodes.size() != 1 ) + if( e.nodes.size() == 0 ) + { + if( !e.trait ) + TODO(sp, "Handle UFCS inherent and no nodes - " << path); + if( e.trait->is_valid() ) + TODO(sp, "Handle UFCS w/ trait and no nodes - " << path); + auto type = LowerHIR_Type(*e.type); + ASSERT_BUG(sp, type.m_data.is_Path(), "No nodes and non-Path type - " << path); + return mv$(type.m_data.as_Path().path); + } + if( e.nodes.size() > 1 ) TODO(sp, "Handle UFCS with multiple nodes - " << path); // - No associated type bounds allowed in UFCS paths auto params = LowerHIR_PathParams(sp, e.nodes.front().args(), false); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 55c742ad..23797382 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -528,7 +528,7 @@ struct LowerHIR_ExprNode_Visitor: values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); // TODO: What if `v.m_path` is an associated type (that's known to be a struct) m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), - LowerHIR_GenericPath(v.span(), v.m_path), + LowerHIR_Path(v.span(), v.m_path), ! v.m_path.m_bindings.type.is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index c979b2e6..9b5043f4 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -645,7 +645,7 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { - upper_visitor.visit_generic_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); + upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); ::HIR::ExprVisitorDef::visit(node); } void visit(::HIR::ExprNode_ArraySized& node) override diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index dcdf79bd..6b06a748 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -255,9 +255,10 @@ public: { if( node.m_is_struct ) { - auto new_path = upper_visitor.expand_alias_gp(node.span(), node.m_path); - if( new_path.m_path.m_components.size() != 0 ) + auto new_type = ConvertHIR_ExpandAliases_GetExpansion(upper_visitor.m_crate, node.m_path, /*in_expr=*/true); + if( new_type != ::HIR::TypeRef() ) { + auto new_path = mv$(new_type.m_data.as_Path().path); DEBUG("Replacing " << node.m_path << " with " << new_path); node.m_path = mv$(new_path); } diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 491ab4c7..1754bdac 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -356,13 +356,15 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { const auto& sp = node.span(); + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); if( node.m_base_value ) { bool is_moved = false; const auto& tpb = node.m_base_value->m_res_type.m_data.as_Path().binding; const ::HIR::Struct* str; if( tpb.is_Enum() ) { const auto& enm = *tpb.as_Enum(); - auto idx = enm.find_variant(node.m_path.m_path.m_components.back()); + auto idx = enm.find_variant(ty_path.m_path.m_components.back()); ASSERT_BUG(sp, idx != SIZE_MAX, ""); const auto& var_ty = enm.m_data.as_Data()[idx].type; str = var_ty.m_data.as_Path().binding.as_Struct(); @@ -379,7 +381,7 @@ namespace { provided_mask[idx] = true; } - const auto monomorph_cb = monomorphise_type_get_cb(node.span(), nullptr, &node.m_path.m_params, nullptr); + const auto monomorph_cb = monomorphise_type_get_cb(node.span(), nullptr, &ty_path.m_params, nullptr); for( unsigned int i = 0; i < fields.size(); i ++ ) { if( ! provided_mask[i] ) { const auto& ty_o = fields[i].second.ent; diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index cd57c471..adb3c426 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -496,6 +496,8 @@ namespace { if( node.m_base_value) { check_types_equal( node.m_base_value->span(), node.m_res_type, node.m_base_value->m_res_type ); } + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); // - Create ivars in path, and set result type const auto& ty = node.m_res_type; @@ -506,7 +508,7 @@ namespace { (Unbound, ), (Opaque, ), (Enum, - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; auto idx = enm.find_variant(var_name); ASSERT_BUG(sp, idx != SIZE_MAX, ""); @@ -536,7 +538,7 @@ namespace { const ::HIR::t_struct_fields& fields = *fields_ptr; #if 1 - const auto& ty_params = node.m_path.m_params.m_types; + const auto& ty_params = ty_path.m_params.m_types; auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 8b0eedb3..4a53bd4d 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1193,7 +1193,10 @@ namespace { { const auto& sp = node.span(); TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); - this->add_ivars_generic_path(node.span(), node.m_path); + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); + + this->add_ivars_generic_path(node.span(), ty_path); for( auto& val : node.m_values ) { this->context.add_ivars( val.second->m_res_type ); } @@ -1202,7 +1205,7 @@ namespace { } // - Create ivars in path, and set result type - const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, node.m_path); + const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, ty_path); this->context.equate_types(node.span(), node.m_res_type, ty); if( node.m_base_value ) { this->context.equate_types(node.span(), node.m_base_value->m_res_type, ty); @@ -1214,7 +1217,7 @@ namespace { (Unbound, ), (Opaque, ), (Enum, - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; auto idx = enm.find_variant(var_name); ASSERT_BUG(sp, idx != SIZE_MAX, ""); @@ -1257,7 +1260,7 @@ namespace { ASSERT_BUG(node.span(), fields_ptr, ""); const ::HIR::t_struct_fields& fields = *fields_ptr; - const auto& ty_params = node.m_path.m_params.m_types; + const auto& ty_params = ty_path.m_params.m_types; auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { @@ -1281,7 +1284,7 @@ namespace { { const auto& name = val.first; auto it = ::std::find_if(fields.begin(), fields.end(), [&](const auto& v)->bool{ return v.first == name; }); - ASSERT_BUG(node.span(), it != fields.end(), "Field '" << name << "' not found in struct " << node.m_path); + ASSERT_BUG(node.span(), it != fields.end(), "Field '" << name << "' not found in struct " << ty_path); const auto& des_ty_r = it->second.ent; auto& des_ty_cache = node.m_value_types[it - fields.begin()]; const auto* des_ty = &des_ty_r; @@ -3164,7 +3167,7 @@ namespace { this->check_type_resolved_genericpath(node.span(), node.m_path); } void visit(::HIR::ExprNode_StructLiteral& node) override { - this->check_type_resolved_pp(node.span(), node.m_path.m_params, ::HIR::TypeRef()); + this->check_type_resolved_path(node.span(), node.m_path); for(auto& ty : node.m_value_types) { if( ty != ::HIR::TypeRef() ) { this->check_type_resolved_top(node.span(), ty); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index ee4cf474..9ce40a74 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -2365,13 +2365,18 @@ namespace { { TRACE_FUNCTION_F("_StructLiteral"); - TU_MATCH(::HIR::TypeRef::TypePathBinding, (node.m_res_type.m_data.as_Path().binding), (e), - (Unbound, ), - (Opaque, ), - (Enum, - auto enum_path = node.m_path.clone(); + ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); + const auto& ty_path = node.m_path.m_data.as_Generic(); + + TU_MATCH_HDRA( (node.m_res_type.m_data.as_Path().binding), {) + TU_ARMA(Unbound, _e) { + } + TU_ARMA(Opaque, _e) { + } + TU_ARMA(Enum, e) { + auto enum_path = ty_path.clone(); enum_path.m_path.m_components.pop_back(); - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; size_t idx = enm.find_variant(var_name); @@ -2381,7 +2386,7 @@ namespace { const auto& str = *var_ty.m_data.as_Path().binding.as_Struct(); // Take advantage of the identical generics to cheaply clone/monomorph the path. - ::HIR::GenericPath struct_path = node.m_path.clone(); + ::HIR::GenericPath struct_path = ty_path.clone(); struct_path.m_path = var_ty.m_data.as_Path().path.m_data.as_Generic().m_path; this->visit_sl_inner(node, str, struct_path); @@ -2396,22 +2401,22 @@ namespace { static_cast(idx), mv$(v) }) ); - ), - (Union, + } + TU_ARMA(Union, e) { BUG(node.span(), "_StructLiteral Union isn't valid?"); - ), - (Struct, + } + TU_ARMA(Struct, e) { if(e->m_data.is_Unit()) { m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({ - node.m_path.clone(), + ty_path.clone(), {} }) ); return ; } - this->visit_sl_inner(node, *e, node.m_path); - ) - ) + this->visit_sl_inner(node, *e, ty_path); + } + } } void visit(::HIR::ExprNode_UnionLiteral& node) override { -- cgit v1.2.3 From 42b9c8704fe4aab25e8f9d0cca15a74b025eee43 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Feb 2019 17:48:32 +0800 Subject: HIR - Minimally-tested support for `extern { type }` --- src/hir/from_ast.cpp | 10 ++++++++ src/hir/hir.hpp | 8 +++++++ src/hir/serialise.cpp | 9 ++++++++ src/hir/type.cpp | 2 ++ src/hir/type.hpp | 2 ++ src/hir/visitor.cpp | 3 +++ src/hir_conv/bind.cpp | 4 ++++ src/hir_conv/constant_evaluation.cpp | 2 ++ src/hir_conv/markings.cpp | 1 + src/hir_typeck/expr_check.cpp | 9 ++++++++ src/hir_typeck/expr_cs.cpp | 18 +++++++++++++++ src/hir_typeck/helpers.cpp | 13 +++++++++++ src/hir_typeck/outer.cpp | 4 ++++ src/hir_typeck/static.cpp | 15 ++++++++++++ src/mir/from_hir.cpp | 3 +++ src/mir/from_hir_match.cpp | 15 ++++++++++++ src/resolve/absolute.cpp | 44 +++++++++++++++++------------------- src/resolve/index.cpp | 13 ++++++++++- src/resolve/use.cpp | 3 +++ src/trans/auto_impls.cpp | 6 ++--- src/trans/codegen.cpp | 3 +++ src/trans/codegen_c.cpp | 11 +++++++++ src/trans/enumerate.cpp | 16 ++++++------- 23 files changed, 178 insertions(+), 36 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 768593c4..fb8096f7 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1187,6 +1187,7 @@ namespace { ::std::vector< ::HIR::TraitPath> trait_bounds; ::std::string lifetime_bound; auto gps = LowerHIR_GenericParams(i.params(), &is_sized); + for(auto& b : gps.m_bounds) { TU_MATCH(::HIR::GenericBound, (b), (be), @@ -1463,6 +1464,15 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_Import({ ::HIR::SimplePath(e.name, {}), false, 0} ) ); ), (Type, + if( e.type().m_data.is_Any() ) + { + if( !e.params().lft_params().empty() || !e.params().ty_params().empty() || !e.params().bounds().empty() ) + { + ERROR(item.data.span, E0000, "Generics on extern type"); + } + _add_mod_ns_item(mod, item.name, item.is_pub, ::HIR::ExternType {}); + break; + } _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_TypeAlias( LowerHIR_TypeAlias(e) ) ); ), (Struct, diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index fc4a19e8..48787583 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -215,6 +215,13 @@ struct StructMarkings unsigned int coerce_param = ~0u; }; +class ExternType +{ +public: + // TODO: do extern types need any associated data? + TraitMarkings m_markings; +}; + class Enum { public: @@ -367,6 +374,7 @@ TAGGED_UNION(TypeItem, Import, (Import, struct { ::HIR::SimplePath path; bool is_variant; unsigned int idx; }), (Module, Module), (TypeAlias, TypeAlias), // NOTE: These don't introduce new values + (ExternType, ExternType), (Enum, Enum), (Struct, Struct), (Union, Union), diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index c91cf93f..e5fe8ed5 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -834,6 +834,10 @@ (Union, m_out.write_tag(6); serialise(e); + ), + (ExternType, + m_out.write_tag(7); + serialise(e); ) ) } @@ -1020,6 +1024,11 @@ serialise(item.m_markings); } + void serialise(const ::HIR::ExternType& item) + { + TRACE_FUNCTION_F("ExternType"); + serialise(item.m_markings); + } void serialise(const ::HIR::Trait& item) { TRACE_FUNCTION_F("_trait:"); diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 2c24e3e1..981ed0b3 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -85,6 +85,7 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const TU_MATCH(::HIR::TypeRef::TypePathBinding, (e.binding), (be), (Unbound, os << "/*?*/";), (Opaque, os << "/*O*/";), + (ExternType, os << "/*X*/";), (Struct, os << "/*S*/";), (Union, os << "/*U*/";), (Enum, os << "/*E*/";) @@ -782,6 +783,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x TU_MATCH(::HIR::TypeRef::TypePathBinding, (*this), (e), (Unbound, return ::HIR::TypeRef::TypePathBinding::make_Unbound({}); ), (Opaque , return ::HIR::TypeRef::TypePathBinding::make_Opaque({}); ), + (ExternType, return ::HIR::TypeRef::TypePathBinding(e); ), (Struct, return ::HIR::TypeRef::TypePathBinding(e); ), (Union , return ::HIR::TypeRef::TypePathBinding(e); ), (Enum , return ::HIR::TypeRef::TypePathBinding(e); ) diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 480b32c4..0c98773f 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -19,6 +19,7 @@ namespace HIR { +class ExternType; class Struct; class Union; class Enum; @@ -152,6 +153,7 @@ public: TAGGED_UNION_EX(TypePathBinding, (), Unbound, ( (Unbound, struct {}), // Not yet bound, either during lowering OR during resolution (when associated and still being resolved) (Opaque, struct {}), // Opaque, i.e. An associated type of a generic (or Self in a trait) + (ExternType, const ::HIR::ExternType*), (Struct, const ::HIR::Struct*), (Union, const ::HIR::Union*), (Enum, const ::HIR::Enum*) diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 5c9c0dfa..f23bae88 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -47,6 +47,9 @@ void ::HIR::Visitor::visit_module(::HIR::ItemPath p, ::HIR::Module& mod) DEBUG("type " << name); this->visit_type_alias(p + name, e); ), + (ExternType, + DEBUG("extern type " << name); + ), (Enum, DEBUG("enum " << name); this->visit_enum(p + name, e); diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 9b5043f4..b616a64f 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -456,6 +456,10 @@ namespace { (TypeAlias, BUG(sp, "TypeAlias encountered after `Resolve Type Aliases` - " << ty); ), + (ExternType, + e.binding = ::HIR::TypeRef::TypePathBinding::make_ExternType(&e3); + DEBUG("- " << ty); + ), (Struct, fix_param_count(sp, pe, e3.m_params, pe.m_params); e.binding = ::HIR::TypeRef::TypePathBinding::make_Struct(&e3); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 43a64bbb..3d1bf4a5 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -169,6 +169,8 @@ namespace { ), (Enum, ), + (ExternType, + ), (TypeAlias, ) ) diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp index df7fbd36..d43db2b5 100644 --- a/src/hir_conv/markings.cpp +++ b/src/hir_conv/markings.cpp @@ -333,6 +333,7 @@ public: TU_MATCHA( (te.binding), (tpb), (Unbound, ), (Opaque, ), + (ExternType, markings_ptr = &tpb->m_markings; ), (Struct, markings_ptr = &tpb->m_markings; ), (Union , markings_ptr = &tpb->m_markings; ), (Enum , markings_ptr = &tpb->m_markings; ) diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index adb3c426..7d5a9c6f 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -462,6 +462,9 @@ namespace { (Union, BUG(sp, "Union in TupleVariant"); ), + (ExternType, + BUG(sp, "ExternType in TupleVariant"); + ), (Struct, ASSERT_BUG(sp, e->m_data.is_Tuple(), "Pointed struct in TupleVariant (" << node.m_path << ") isn't a Tuple"); fields_ptr = &e->m_data.as_Tuple(); @@ -522,6 +525,9 @@ namespace { (Union, TODO(sp, "Union in StructLiteral"); ), + (ExternType, + BUG(sp, "ExternType in StructLiteral"); + ), (Struct, if( e->m_data.is_Unit() ) { @@ -611,6 +617,9 @@ namespace { (Union, BUG(sp, "Union with _UnitVariant"); ), + (ExternType, + BUG(sp, "ExternType with _UnitVariant"); + ), (Struct, assert( e->m_data.is_Unit() ); ) diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 4a53bd4d..291dcd84 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1144,6 +1144,9 @@ namespace { ), (Union, BUG(sp, "TupleVariant pointing to a union"); + ), + (ExternType, + BUG(sp, "TupleVariant pointing to a extern type"); ) ) assert(fields_ptr); @@ -1216,6 +1219,7 @@ namespace { TU_MATCH(::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (e), (Unbound, ), (Opaque, ), + (ExternType, ), // Error? (Enum, const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; @@ -4900,6 +4904,10 @@ void Context::require_sized(const Span& sp, const ::HIR::TypeRef& ty_) // Already checked by type_is_sized params_def = nullptr; ), + (ExternType, + static ::HIR::GenericParams empty_params; + params_def = &empty_params; + ), (Enum, params_def = &pb->m_params; ), @@ -5551,6 +5559,13 @@ namespace { (Opaque, // Handled above in bounded ), + (ExternType, + // Must be equal + if( sbe == dbe ) + { + return CoerceResult::Equality; + } + ), (Enum, // Must be equal if( sbe == dbe ) @@ -6474,6 +6489,9 @@ namespace { // TODO: Check bounds? return false; ), + (ExternType, + return false; + ), (Struct, if(pbe_a != pbe_b) return false; if( !pbe_a->m_struct_markings.can_unsize ) diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 1af269ad..5c0696e3 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -2477,6 +2477,9 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ), (Opaque, ), + (ExternType, + markings = &tpb->m_markings; + ), (Struct, markings = &tpb->m_markings; ), @@ -2710,6 +2713,9 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ), (Union, TODO(sp, "Check auto trait destructure on union " << type); + ), + (ExternType, + TODO(sp, "Check auto trait destructure on extern type " << type); ) ) DEBUG("- Nothing failed, calling callback"); @@ -3141,6 +3147,10 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa (Opaque, // TODO: Check bounds ), + (ExternType, + // Is it sized? No. + return ::HIR::Compare::Unequal; + ), (Enum, // HAS to be Sized ), @@ -4323,6 +4333,9 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const (Enum, // No fields on enums either ), + (ExternType, + // No fields on extern types + ), (Union, const auto& unm = *be; const auto& params = e.path.m_data.as_Generic().m_params; diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index 63e92d8b..6a8e8b35 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -52,6 +52,10 @@ namespace { (TypeAlias, BUG(sp, "Type path pointed to type alias - " << path); ), + (ExternType, + static ::HIR::GenericParams empty_params; + return empty_params; + ), (Module, BUG(sp, "Type path pointed to module - " << path); ), diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 457bd44e..ce7faf6c 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -851,6 +851,9 @@ bool StaticTraitResolve::find_impl__check_crate( ), (Union, TODO(sp, "Check auto trait destructure on union " << type); + ), + (ExternType, + TODO(sp, "Check auto trait destructure on extern type " << type); ) ) DEBUG("- Nothing failed, calling callback"); @@ -1629,6 +1632,10 @@ bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) return false; } ), + (ExternType, + // Extern types aren't Sized + return false; + ), (Enum, ), (Union, @@ -1732,6 +1739,10 @@ bool StaticTraitResolve::type_is_impossible(const Span& sp, const ::HIR::TypeRef (Union, // TODO: Check all variants? Or just one? TODO(sp, "type_is_impossible for union " << ty); + ), + (ExternType, + // Extern types are possible, just not usable + return false; ) ) return true; @@ -2032,6 +2043,10 @@ bool StaticTraitResolve::type_needs_drop_glue(const Span& sp, const ::HIR::TypeR (Union, // Unions don't have drop glue unless they impl Drop return false; + ), + (ExternType, + // Extern types don't have drop glue + return false; ) ) ), diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 9ce40a74..fb214dda 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -2405,6 +2405,9 @@ namespace { TU_ARMA(Union, e) { BUG(node.span(), "_StructLiteral Union isn't valid?"); } + TU_ARMA(ExternType, e) { + BUG(node.span(), "_StructLiteral ExternType isn't valid?"); + } TU_ARMA(Struct, e) { if(e->m_data.is_Unit()) { m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({ diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 264c74c5..6fb77a3b 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -802,6 +802,9 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal ) ) ), + (ExternType, + TODO(sp, "Match extern type"); + ), (Union, TODO(sp, "Match union"); ), @@ -1217,6 +1220,9 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa (Union, TODO(sp, "Match over union - " << ty); ), + (ExternType, + TODO(sp, "Match over extern type - " << ty); + ), (Enum, auto monomorph = [&](const auto& ty) { auto rv = monomorphise_type(sp, pbe->m_params, e.path.m_data.as_Generic().m_params, ty); @@ -1738,6 +1744,9 @@ namespace { (Opaque, BUG(sp, "Destructuring an opaque type - " << *cur_ty); ), + (ExternType, + BUG(sp, "Destructuring an extern type - " << *cur_ty); + ), (Struct, // TODO: Should this do a call to expand_associated_types? auto monomorph = [&](const auto& ty) { @@ -2173,6 +2182,9 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& (Union, TODO(sp, "Match over Union"); ), + (ExternType, + TODO(sp, "Match over ExternType"); + ), (Enum, auto monomorph = [&](const auto& ty) { auto rv = monomorphise_type(sp, pbe->m_params, te.path.m_data.as_Generic().m_params, ty); @@ -2827,6 +2839,9 @@ void MatchGenGrouped::gen_dispatch(const ::std::vector& rules, s (Union, TODO(sp, "Match over Union"); ), + (ExternType, + TODO(sp, "Match over ExternType - " << ty); + ), (Enum, ) ) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index d2609e9e..75a0857f 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -350,7 +350,7 @@ namespace auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { const auto& b = v->second.path.m_bindings.value; - if( const auto* be = b.opt_EnumVar() ) { + if( /*const auto* be =*/ b.opt_EnumVar() ) { DEBUG("- TY: Enum variant " << v->second.path); path = ::AST::Path( v->second.path ); return true; @@ -832,6 +832,9 @@ namespace { (TypeAlias, pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), + (ExternType, + pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); + ), (Struct, pb.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), @@ -880,8 +883,8 @@ namespace { if( it == hmod->m_mod_items.end() ) ERROR(sp, E0000, "Couldn't find path component '" << n.name() << "' of " << path); - TU_MATCH(::HIR::TypeItem, (it->second->ent), (e), - (Import, + TU_MATCH_HDRA( (it->second->ent), {) + TU_ARMA(Import, e) { // - Update path then restart auto newpath = AST::Path(e.path.m_crate_name, {}); for(const auto& n : e.path.m_components) @@ -892,11 +895,11 @@ namespace { // TODO: Recursion limit Resolve_Absolute_Path_BindAbsolute(context, sp, mode, path); return ; - ), - (Module, + } + TU_ARMA(Module, e) { hmod = &e; - ), - (Trait, + } + TU_ARMA(Trait, e) { auto trait_path = ::AST::Path( crate.m_name, {} ); for(unsigned int j = start; j <= i; j ++) trait_path.nodes().push_back( path_abs.nodes[j].name() ); @@ -940,23 +943,15 @@ namespace { path = mv$(new_path); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (TypeAlias, - path = split_into_crate(sp, mv$(path), start, crate.m_name); - path = split_into_ufcs_ty(sp, mv$(path), i-start); - return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Struct, - path = split_into_crate(sp, mv$(path), start, crate.m_name); - path = split_into_ufcs_ty(sp, mv$(path), i-start); - return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Union, + } + case ::HIR::TypeItem::TAG_ExternType: + case ::HIR::TypeItem::TAG_TypeAlias: + case ::HIR::TypeItem::TAG_Struct: + case ::HIR::TypeItem::TAG_Union: path = split_into_crate(sp, mv$(path), start, crate.m_name); path = split_into_ufcs_ty(sp, mv$(path), i-start); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Enum, + TU_ARMA(Enum, e) { const auto& last_node = path_abs.nodes.back(); // If this refers to an enum variant, return the full path auto idx = e.find_variant(last_node.name()); @@ -982,8 +977,8 @@ namespace { path = split_into_crate(sp, mv$(path), start, crate.m_name); path = split_into_ufcs_ty(sp, mv$(path), i-start); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ) - ) + } + } } const auto& name = path_abs.nodes.back().name(); @@ -1007,6 +1002,9 @@ namespace { (Module, path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), + (ExternType, + path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); + ), (TypeAlias, path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index ec1fcd8d..ddeffa0c 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -241,7 +241,15 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) i.is_pub, i_data.name, mv$(path), e.mac }); } - // TODO: Other imports (e.g. derives, which have different naming structures) + TU_ARMA(ProcMacro, e) { + TODO(sp, "ProcMacro import"); + } + TU_ARMA(ProcMacroAttribute, e) { + TODO(sp, "ProcMacroAttribute import"); + } + TU_ARMA(ProcMacroDerive, e) { + TODO(sp, "ProcMacroDerive import"); + } }} } else @@ -318,6 +326,9 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr}); ), (TypeAlias, + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); + ), + (ExternType, p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ) ) diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 8c9266a2..95e6d2c1 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -645,6 +645,9 @@ namespace { (TypeAlias, rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ), + (ExternType, + rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); // Lazy. + ), (Enum, rv.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ), diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index 418a338b..877659b2 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -74,7 +74,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) // For each field of the tuple, create a clone (either using Copy if posible, or calling Clone::clone) for(const auto& subty : te) { - auto fld_lvalue = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({ 0 })) })), values.size() }); + auto fld_lvalue = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({ 0 })) })), static_cast(values.size()) }); if( state.resolve.type_is_copy(sp, subty) ) { values.push_back( ::std::move(fld_lvalue) ); @@ -94,8 +94,8 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) ::MIR::RValue::make_Borrow({ 0, ::HIR::BorrowType::Shared, mv$(fld_lvalue) }) })); bb.terminator = ::MIR::Terminator::make_Call({ - mir_fcn.blocks.size() + 2, // return block (after the panic block below) - mir_fcn.blocks.size() + 1, // panic block (next block) + static_cast(mir_fcn.blocks.size() + 2), // return block (after the panic block below) + static_cast(mir_fcn.blocks.size() + 1), // panic block (next block) res_lv.clone(), ::MIR::CallTarget( ::HIR::Path(subty.clone(), lang_Clone, "clone") ), ::make_vec1<::MIR::Param>( ::std::move(borrow_lv) ) diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 9e93caba..b2b614a9 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -43,6 +43,9 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const TU_MATCHA( (te.binding), (tpb), (Unbound, throw ""; ), (Opaque, throw ""; ), + (ExternType, + //codegen->emit_extern_type(sp, te.path.m_data.as_Generic(), *tpb); + ), (Struct, codegen->emit_struct(sp, te.path.m_data.as_Generic(), *tpb); ), diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 2c40c991..979da88d 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1013,6 +1013,9 @@ namespace { (Struct, m_of << "struct s_" << Trans_Mangle(te.path) << ";\n"; ), + (ExternType, + m_of << "struct x_" << Trans_Mangle(te.path) << ";\n"; + ), (Union, m_of << "union u_" << Trans_Mangle(te.path) << ";\n"; ), @@ -1837,6 +1840,7 @@ namespace { TU_MATCHA((te.binding), (pbe), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path " << ty); ), (Opaque, MIR_BUG(*m_mir_res, "Opaque type path " << ty); ), + (ExternType, MIR_BUG(*m_mir_res, "Extern type literal " << ty); ), (Struct, TU_MATCHA( (pbe->m_data), (se), (Unit, @@ -5351,6 +5355,9 @@ namespace { TU_MATCHA((te.binding), (pbe), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path " << ty); ), (Opaque, MIR_BUG(*m_mir_res, "Opaque type path " << ty); ), + (ExternType, + MIR_BUG(*m_mir_res, "Extern type literal"); + ), (Struct, TU_MATCHA( (pbe->m_data), (se), (Unit, @@ -5835,6 +5842,10 @@ namespace { (Enum, m_of << "struct e_" << Trans_Mangle(te.path); ), + (ExternType, + m_of << "struct x_" << Trans_Mangle(te.path); + //return ; + ), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path in trans - " << ty); ), diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 6aeb3485..c326d125 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -570,6 +570,9 @@ namespace { (Opaque, BUG(Span(), "Opaque type hit in enumeration - " << ty); ), + (ExternType, + // No innards to visit + ), (Struct, visit_struct(te.path.m_data.as_Generic(), *tpb); ), @@ -1064,15 +1067,10 @@ void Trans_Enumerate_Types(EnumState& state) TU_MATCHA( (te.binding), (tpb), (Unbound, ), (Opaque, ), - (Struct, - markings_ptr = &tpb->m_markings; - ), - (Union, - markings_ptr = &tpb->m_markings; - ), - (Enum, - markings_ptr = &tpb->m_markings; - ) + (ExternType, markings_ptr = &tpb->m_markings; ), + (Struct, markings_ptr = &tpb->m_markings; ), + (Union, markings_ptr = &tpb->m_markings; ), + (Enum, markings_ptr = &tpb->m_markings; ) ) ASSERT_BUG(Span(), markings_ptr, "Path binding not set correctly - " << ty); -- cgit v1.2.3 From 866ae6ef036fe26026a0247decb2f8cd67aafcd9 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 24 Mar 2019 10:57:31 +0800 Subject: HIR Macro Export - Hacky workarounds and defensive asserts with macro exports --- src/hir/from_ast.cpp | 6 ++++++ src/hir/serialise.cpp | 1 + src/macro_rules/eval.cpp | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index fb8096f7..014b744c 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1834,6 +1834,9 @@ public: auto res = macros.insert( mv$(v) ); DEBUG("- Import " << mac.name << "! (from \"" << res.first->second->m_source_crate << "\")"); } + else if( v.second->m_rules.empty() ) { + // Skip + } else { DEBUG("- Replace " << mac.name << "! (from \"" << it->second->m_source_crate << "\") with one from \"" << v.second->m_source_crate << "\""); it->second = mv$( v.second ); @@ -1853,6 +1856,9 @@ public: auto res = macros.insert( mv$(v) ); DEBUG("- Import " << mac.name << "! (from \"" << res.first->second->m_source_crate << "\")"); } + else if( v.second->m_rules.empty() ) { + // Skip + } else { DEBUG("- Replace " << mac.name << "! (from \"" << it->second->m_source_crate << "\") with one from \"" << v.second->m_source_crate << "\""); it->second = mv$( v.second ); diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index e5fe8ed5..0d01ed25 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -400,6 +400,7 @@ void serialise(const ::MacroRules& mac) { //m_exported: IGNORE, should be set + assert(mac.m_rules.size() > 0); serialise_vec(mac.m_rules); m_out.write_string(mac.m_source_crate); } diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 03c5609c..9caff7b8 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -352,8 +352,10 @@ void MacroPatternStream::if_succeeded() TU_MATCH_HDRA( (m_simple_ents[m_cur_pos-1]), {) default: BUG(Span(), "Unexpected " << m_simple_ents[m_cur_pos-1]); - TU_ARMA(If, e) + TU_ARMA(If, e) { + ASSERT_BUG(Span(), e.jump_target < m_simple_ents.size(), "Jump target " << e.jump_target << " out of range " << m_simple_ents.size()); m_cur_pos = e.jump_target; + } } m_condition_met = true; } @@ -1724,6 +1726,7 @@ namespace unsigned int Macro_InvokeRules_MatchPattern(const Span& sp, const MacroRules& rules, TokenTree input, AST::Module& mod, ParameterMappings& bound_tts) { TRACE_FUNCTION; + ASSERT_BUG(sp, rules.m_rules.size() > 0, "Empty macro_rules set"); ::std::vector< ::std::pair> > matches; for(size_t i = 0; i < rules.m_rules.size(); i ++) @@ -1812,6 +1815,7 @@ unsigned int Macro_InvokeRules_MatchPattern(const Span& sp, const MacroRules& ru if( matches.size() == 0 ) { // ERROR! + // TODO: Keep track of where each arm failed. TODO(sp, "No arm matched"); } else -- cgit v1.2.3 From 7a1a685ef5e0d831f6762f1bc9171de66d933e32 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 25 Apr 2019 12:38:17 +0800 Subject: HIR - Add more complete privacy handling (allowing for autoderef to skip private fields) --- src/hir/deserialise.cpp | 10 +++-- src/hir/dump.cpp | 4 +- src/hir/expr_ptr.cpp | 6 +++ src/hir/expr_state.hpp | 3 +- src/hir/from_ast.cpp | 78 +++++++++++++++++++++++------------- src/hir/hir.hpp | 64 ++++++++++++++++++++++++++++- src/hir/hir_ops.cpp | 1 + src/hir/serialise.cpp | 6 +-- src/hir_conv/bind.cpp | 28 +++++++++---- src/hir_conv/constant_evaluation.cpp | 3 +- src/hir_expand/closures.cpp | 8 ++-- src/hir_expand/vtable.cpp | 10 ++--- src/hir_typeck/expr_cs.cpp | 7 ++-- src/hir_typeck/expr_visit.cpp | 8 ++-- src/hir_typeck/expr_visit.hpp | 6 ++- src/hir_typeck/helpers.cpp | 10 ++--- src/hir_typeck/helpers.hpp | 4 +- src/resolve/index.cpp | 4 +- src/trans/enumerate.cpp | 4 +- 19 files changed, 189 insertions(+), 75 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index cc376474..9933255f 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -101,10 +101,14 @@ rv.push_back( cb() ); return rv; } + ::HIR::Publicity deserialise_pub() + { + return (m_in.read_bool() ? ::HIR::Publicity::new_global() : ::HIR::Publicity::new_none()); + } template ::HIR::VisEnt deserialise_visent() { - return ::HIR::VisEnt { m_in.read_bool(), D::des(*this) }; + return ::HIR::VisEnt { deserialise_pub(), D::des(*this) }; } template @@ -153,7 +157,7 @@ { auto name = m_in.read_string(); rv.m_methods.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { - m_in.read_bool(), m_in.read_bool(), deserialise_function() + deserialise_pub(), m_in.read_bool(), deserialise_function() } ) ); } size_t const_count = m_in.read_count(); @@ -161,7 +165,7 @@ { auto name = m_in.read_string(); rv.m_constants.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> { - m_in.read_bool(), m_in.read_bool(), deserialise_constant() + deserialise_pub(), m_in.read_bool(), deserialise_constant() } ) ); } // m_src_module doesn't matter after typeck diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp index a60ec643..3b981e26 100644 --- a/src/hir/dump.cpp +++ b/src/hir/dump.cpp @@ -152,7 +152,7 @@ namespace { m_os << "("; for(const auto& fld : flds) { - m_os << (fld.is_public ? "pub " : "") << fld.ent << ", "; + m_os << fld.publicity << " " << fld.ent << ", "; } if( item.m_params.m_bounds.empty() ) { @@ -175,7 +175,7 @@ namespace { inc_indent(); for(const auto& fld : flds) { - m_os << indent() << (fld.second.is_public ? "pub " : "") << fld.first << ": " << fld.second.ent << ",\n"; + m_os << indent() << fld.second.publicity << " " << fld.first << ": " << fld.second.ent << ",\n"; } dec_indent(); m_os << indent() << "}\n"; diff --git a/src/hir/expr_ptr.cpp b/src/hir/expr_ptr.cpp index 7b3a6811..0c219e0f 100644 --- a/src/hir/expr_ptr.cpp +++ b/src/hir/expr_ptr.cpp @@ -90,6 +90,12 @@ void HIR::ExprPtr::set_mir(::MIR::FunctionPointer mir) { assert( !this->m_mir ); m_mir = ::std::move(mir); + // Reset the HIR tree to be a placeholder node (thus freeing the backing memory) + //if( node ) + //{ + // auto sp = node->span(); + // node = ExprPtrInner(::std::unique_ptr(new ::HIR::ExprNode_Tuple(sp, {}))); + //} } diff --git a/src/hir/expr_state.hpp b/src/hir/expr_state.hpp index 5491b4d3..11fffe67 100644 --- a/src/hir/expr_state.hpp +++ b/src/hir/expr_state.hpp @@ -10,8 +10,9 @@ namespace HIR { -struct ExprState +class ExprState { +public: ::HIR::SimplePath m_mod_path; const ::HIR::Module& m_module; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 014b744c..af6bc9cb 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -868,9 +868,20 @@ const ::AST::Crate* g_ast_crate_ptr; namespace { template - ::HIR::VisEnt new_visent(bool pub, T v) { + ::HIR::VisEnt new_visent(HIR::Publicity pub, T v) { return ::HIR::VisEnt { pub, mv$(v) }; } + + ::HIR::SimplePath get_parent_module(const ::HIR::ItemPath& p) { + const ::HIR::ItemPath* parent_ip = p.parent; + assert(parent_ip); + while(parent_ip->name && parent_ip->name[0] == '#') + { + parent_ip = parent_ip->parent; + assert(parent_ip); + } + return parent_ip->get_simple_path(); + } } ::HIR::Struct LowerHIR_Struct(::HIR::ItemPath path, const ::AST::Struct& ent, const ::AST::AttributeList& attrs) @@ -878,6 +889,9 @@ namespace { TRACE_FUNCTION_F(path); ::HIR::Struct::Data data; + auto priv_path = ::HIR::Publicity::new_priv( get_parent_module(path) ); + auto get_pub = [&](bool is_pub){ return is_pub ? ::HIR::Publicity::new_global() : priv_path; }; + TU_MATCH(::AST::StructData, (ent.m_data), (e), (Unit, data = ::HIR::Struct::Data::make_Unit({}); @@ -886,14 +900,14 @@ namespace { ::HIR::Struct::Data::Data_Tuple fields; for(const auto& field : e.ents) - fields.push_back( { field.m_is_public, LowerHIR_Type(field.m_type) } ); + fields.push_back( { get_pub(field.m_is_public), LowerHIR_Type(field.m_type) } ); data = ::HIR::Struct::Data::make_Tuple( mv$(fields) ); ), (Struct, ::HIR::Struct::Data::Data_Named fields; for(const auto& field : e.ents) - fields.push_back( ::std::make_pair( field.m_name, new_visent(field.m_is_public, LowerHIR_Type(field.m_type)) ) ); + fields.push_back( ::std::make_pair( field.m_name, new_visent( get_pub(field.m_is_public), LowerHIR_Type(field.m_type)) ) ); data = ::HIR::Struct::Data::make_Named( mv$(fields) ); ) ) @@ -956,7 +970,6 @@ namespace { ::HIR::Enum LowerHIR_Enum(::HIR::ItemPath path, const ::AST::Enum& ent, const ::AST::AttributeList& attrs, ::std::function push_struct) { - // 1. Figure out what sort of enum this is (value or data) bool has_value = false; bool has_data = false; @@ -1053,14 +1066,14 @@ namespace { { ::HIR::Struct::Data::Data_Tuple fields; for(const auto& field : ve->m_sub_types) - fields.push_back( new_visent(true, LowerHIR_Type(field)) ); + fields.push_back( new_visent(::HIR::Publicity::new_global(), LowerHIR_Type(field)) ); data = ::HIR::Struct::Data::make_Tuple( mv$(fields) ); } else if( const auto* ve = var.m_data.opt_Struct() ) { ::HIR::Struct::Data::Data_Named fields; for(const auto& field : ve->m_fields) - fields.push_back( ::std::make_pair( field.m_name, new_visent(true, LowerHIR_Type(field.m_type)) ) ); + fields.push_back( ::std::make_pair( field.m_name, new_visent(::HIR::Publicity::new_global(), LowerHIR_Type(field.m_type)) ) ); data = ::HIR::Struct::Data::make_Named( mv$(fields) ); } else @@ -1106,6 +1119,9 @@ namespace { } ::HIR::Union LowerHIR_Union(::HIR::ItemPath path, const ::AST::Union& f, const ::AST::AttributeList& attrs) { + auto priv_path = ::HIR::Publicity::new_priv( get_parent_module(path) ); + auto get_pub = [&](bool is_pub){ return is_pub ? ::HIR::Publicity::new_global() : priv_path; }; + auto repr = ::HIR::Union::Repr::Rust; if( const auto* attr_repr = attrs.get("repr") ) @@ -1124,7 +1140,7 @@ namespace { ::HIR::Struct::Data::Data_Named variants; for(const auto& field : f.m_variants) - variants.push_back( ::std::make_pair( field.m_name, new_visent(field.m_is_public, LowerHIR_Type(field.m_type)) ) ); + variants.push_back( ::std::make_pair( field.m_name, new_visent(get_pub(field.m_is_public), LowerHIR_Type(field.m_type)) ) ); return ::HIR::Union { LowerHIR_GenericParams(f.m_params, nullptr), @@ -1369,10 +1385,10 @@ namespace { }; } -void _add_mod_ns_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::HIR::TypeItem ti) { +void _add_mod_ns_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity is_pub, ::HIR::TypeItem ti) { mod.m_mod_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::TypeItem> { is_pub, mv$(ti) }) ) ); } -void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::HIR::ValueItem ti) { +void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity is_pub, ::HIR::ValueItem ti) { mod.m_value_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::ValueItem> { is_pub, mv$(ti) }) ) ); } @@ -1383,6 +1399,9 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H mod.m_traits = mv$(traits); + auto priv_path = ::HIR::Publicity::new_priv( path.get_simple_path() ); + auto get_pub = [&](bool is_pub)->::HIR::Publicity{ return (is_pub ? ::HIR::Publicity::new_global() : priv_path); }; + // Populate trait list for(const auto& item : ast_mod.m_type_items) { @@ -1402,7 +1421,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H ::std::string name = FMT("#" << i); auto item_path = ::HIR::ItemPath(path, name.c_str()); auto ti = ::HIR::TypeItem::make_Module( LowerHIR_Module(submod, item_path, mod.m_traits) ); - _add_mod_ns_item( mod, mv$(name), false, mv$(ti) ); + _add_mod_ns_item( mod, mv$(name), get_pub(false), mv$(ti) ); } } @@ -1456,12 +1475,12 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H // Ignore - The index is used to add `Import`s ), (Module, - _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Module(e, mv$(item_path)) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Module(e, mv$(item_path)) ); ), (Crate, // All 'extern crate' items should be normalised into a list in the crate root // - If public, add a namespace import here referring to the root of the imported crate - _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_Import({ ::HIR::SimplePath(e.name, {}), false, 0} ) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), ::HIR::TypeItem::make_Import({ ::HIR::SimplePath(e.name, {}), false, 0} ) ); ), (Type, if( e.type().m_data.is_Any() ) @@ -1470,39 +1489,39 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H { ERROR(item.data.span, E0000, "Generics on extern type"); } - _add_mod_ns_item(mod, item.name, item.is_pub, ::HIR::ExternType {}); + _add_mod_ns_item(mod, item.name, get_pub(item.is_pub), ::HIR::ExternType {}); break; } - _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_TypeAlias( LowerHIR_TypeAlias(e) ) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), ::HIR::TypeItem::make_TypeAlias( LowerHIR_TypeAlias(e) ) ); ), (Struct, /// Add value reference if( e.m_data.is_Unit() ) { - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstant({item_path.get_simple_path()}) ); + _add_mod_val_item( mod, item.name, get_pub(item.is_pub), ::HIR::ValueItem::make_StructConstant({item_path.get_simple_path()}) ); } else if( e.m_data.is_Tuple() ) { - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstructor({item_path.get_simple_path()}) ); + _add_mod_val_item( mod, item.name, get_pub(item.is_pub), ::HIR::ValueItem::make_StructConstructor({item_path.get_simple_path()}) ); } else { } - _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Struct(item_path, e, item.data.attrs) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Struct(item_path, e, item.data.attrs) ); ), (Enum, - auto enm = LowerHIR_Enum(item_path, e, item.data.attrs, [&](auto name, auto str){ _add_mod_ns_item(mod, name, item.is_pub, mv$(str)); }); - _add_mod_ns_item( mod, item.name, item.is_pub, mv$(enm) ); + auto enm = LowerHIR_Enum(item_path, e, item.data.attrs, [&](auto name, auto str){ _add_mod_ns_item(mod, name, get_pub(item.is_pub), mv$(str)); }); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), mv$(enm) ); ), (Union, - _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Union(item_path, e, item.data.attrs) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Union(item_path, e, item.data.attrs) ); ), (Trait, - _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Trait(item_path.get_simple_path(), e) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Trait(item_path.get_simple_path(), e) ); ), (Function, - _add_mod_val_item(mod, item.name, item.is_pub, LowerHIR_Function(item_path, item.data.attrs, e, ::HIR::TypeRef{})); + _add_mod_val_item(mod, item.name, get_pub(item.is_pub), LowerHIR_Function(item_path, item.data.attrs, e, ::HIR::TypeRef{})); ), (Static, if( e.s_class() == ::AST::Static::CONST ) - _add_mod_val_item(mod, item.name, item.is_pub, ::HIR::ValueItem::make_Constant(::HIR::Constant { + _add_mod_val_item(mod, item.name, get_pub(item.is_pub), ::HIR::ValueItem::make_Constant(::HIR::Constant { ::HIR::GenericParams {}, LowerHIR_Type( e.type() ), LowerHIR_Expr( e.value() ) @@ -1516,7 +1535,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H linkage.name = item.name; } - _add_mod_val_item(mod, item.name, item.is_pub, ::HIR::ValueItem::make_Static(::HIR::Static { + _add_mod_val_item(mod, item.name, get_pub(item.is_pub), ::HIR::ValueItem::make_Static(::HIR::Static { mv$(linkage), (e.s_class() == ::AST::Static::MUT), LowerHIR_Type( e.type() ), @@ -1542,7 +1561,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H DEBUG("Import NS " << ie.first << " = " << hir_path); ti = ::HIR::TypeItem::make_Import({ mv$(hir_path), false, 0 }); } - _add_mod_ns_item(mod, ie.first, ie.second.is_pub, mv$(ti)); + _add_mod_ns_item(mod, ie.first, get_pub(ie.second.is_pub), mv$(ti)); } } for( const auto& ie : ast_mod.m_value_items ) @@ -1561,7 +1580,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H vi = ::HIR::ValueItem::make_Import({ mv$(hir_path), true, pb.idx }); } } - _add_mod_val_item(mod, ie.first, ie.second.is_pub, mv$(vi)); + _add_mod_val_item(mod, ie.first, get_pub(ie.second.is_pub), mv$(vi)); } } @@ -1687,6 +1706,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto type = LowerHIR_Type(impl.def().type()); ::HIR::ItemPath path(type); + auto priv_path = ::HIR::Publicity::new_priv( LowerHIR_SimplePath(Span(), ast_mod.path()) ); // TODO: Does this need to consume anon modules? + auto get_pub = [&](bool is_pub){ return is_pub ? ::HIR::Publicity::new_global() : priv_path; }; + ::std::map< ::std::string, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> > methods; ::std::map< ::std::string, ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> > constants; @@ -1703,7 +1725,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ), (Static, if( e.s_class() == ::AST::Static::CONST ) { - constants.insert( ::std::make_pair(item.name, ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> { item.is_pub, item.is_specialisable, ::HIR::Constant { + constants.insert( ::std::make_pair(item.name, ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> { get_pub(item.is_pub), item.is_specialisable, ::HIR::Constant { ::HIR::GenericParams {}, LowerHIR_Type( e.type() ), LowerHIR_Expr( e.value() ) @@ -1715,7 +1737,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ), (Function, methods.insert( ::std::make_pair(item.name, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { - item.is_pub, item.is_specialisable, LowerHIR_Function(item_path, item.data->attrs, e, type) + get_pub(item.is_pub), item.is_specialisable, LowerHIR_Function(item_path, item.data->attrs, e, type) } ) ); ) ) diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 48787583..f0844580 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -41,10 +41,70 @@ class TypeItem; class ItemPath; +class Publicity +{ + ::std::shared_ptr<::HIR::SimplePath> vis_path; + + Publicity(::std::shared_ptr<::HIR::SimplePath> p) + :vis_path(p) + { + } +public: + + static Publicity new_global() { + return Publicity({}); + } + static Publicity new_none() { + static ::std::shared_ptr<::HIR::SimplePath> none_path = ::std::make_shared(); + return Publicity(none_path); + } + static Publicity new_priv(::HIR::SimplePath p) { + return Publicity(::std::make_shared(::std::move(p))); + } + + bool is_global() const { + return !vis_path; + } + bool is_visible(const ::HIR::SimplePath& p) const { + // No path = global public + if( !vis_path ) + return true; + // Empty simple path = full private + if( *vis_path == ::HIR::SimplePath() ) { + return false; + } + // Crate names must match + if(p.m_crate_name != vis_path->m_crate_name) + return false; + // `p` must be a child of vis_path + if(p.m_components.size() < vis_path->m_components.size()) + return false; + for(size_t i = 0; i < vis_path->m_components.size(); i ++) + { + if(p.m_components[i] != vis_path->m_components[i]) + return false; + } + return true; + } + + friend ::std::ostream& operator<<(::std::ostream& os, const Publicity& x) { + if( !x.vis_path ) { + os << "pub"; + } + else if( *x.vis_path == ::HIR::SimplePath() ) { + os << "priv"; + } + else { + os << "pub(" << *x.vis_path << ")"; + } + return os; + } +}; + template struct VisEnt { - bool is_public; + Publicity publicity; Ent ent; }; @@ -396,7 +456,7 @@ class TypeImpl public: template struct VisImplEnt { - bool is_pub; + Publicity publicity; bool is_specialisable; T data; }; diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index b09dbdf7..89e48c80 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -1036,6 +1036,7 @@ const ::MIR::Function* HIR::Crate::get_or_gen_mir(const ::HIR::ItemPath& ip, con ms.m_impl_generics = ep.m_state->m_impl_generics; ms.m_item_generics = ep.m_state->m_item_generics; ms.m_traits = ep.m_state->m_traits; + ms.m_mod_paths.push_back(ep.m_state->m_mod_path); Typecheck_Code(ms, const_cast<::HIR::Function::args_t&>(args), ret_ty, ep_mut); //Debug_SetStagePre("Expand HIR Annotate"); HIR_Expand_AnnotateUsage_Expr(*this, ep_mut); diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 0d01ed25..dd81596f 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -60,7 +60,7 @@ template void serialise(const ::HIR::VisEnt& e) { - m_out.write_bool(e.is_public); + m_out.write_bool(e.publicity.is_global()); // At this stage, we only care if the item is visible outside the crate or not serialise(e.ent); } template @@ -322,14 +322,14 @@ m_out.write_count(impl.m_methods.size()); for(const auto& v : impl.m_methods) { m_out.write_string(v.first); - m_out.write_bool(v.second.is_pub); + m_out.write_bool(v.second.publicity.is_global()); m_out.write_bool(v.second.is_specialisable); serialise(v.second.data); } m_out.write_count(impl.m_constants.size()); for(const auto& v : impl.m_constants) { m_out.write_string(v.first); - m_out.write_bool(v.second.is_pub); + m_out.write_bool(v.second.publicity.is_global()); m_out.write_bool(v.second.is_specialisable); serialise(v.second.data); } diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index c26ae03f..a3b0041b 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -120,7 +120,7 @@ namespace { m_cur_module.ptr = &mod; m_cur_module.path = &p; - m_ms.push_traits(mod); + m_ms.push_traits(p, mod); ::HIR::Visitor::visit_module(p, mod); m_ms.pop_traits(mod); @@ -512,12 +512,16 @@ namespace { void visit_type_impl(::HIR::TypeImpl& impl) override { - TRACE_FUNCTION_F("impl " << impl.m_type); + TRACE_FUNCTION_F("impl " << impl.m_type << " - from " << impl.m_src_module); auto _ = this->m_ms.set_impl_generics(impl.m_params); + auto mod_ip = ::HIR::ItemPath(impl.m_src_module); const auto* mod = (impl.m_src_module != ::HIR::SimplePath() ? &this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module) : nullptr); - if(mod) - m_ms.push_traits(*mod); + if(mod) { + m_ms.push_traits(impl.m_src_module, *mod); + m_cur_module.ptr = mod; + m_cur_module.path = &mod_ip; + } ::HIR::Visitor::visit_type_impl(impl); if(mod) m_ms.pop_traits(*mod); @@ -527,9 +531,13 @@ namespace { TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type); auto _ = this->m_ms.set_impl_generics(impl.m_params); + auto mod_ip = ::HIR::ItemPath(impl.m_src_module); const auto* mod = (impl.m_src_module != ::HIR::SimplePath() ? &this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module) : nullptr); - if(mod) - m_ms.push_traits(*mod); + if(mod) { + m_ms.push_traits(impl.m_src_module, *mod); + m_cur_module.ptr = mod; + m_cur_module.path = &mod_ip; + } m_ms.m_traits.push_back( ::std::make_pair( &trait_path, &this->m_ms.m_crate.get_trait_by_path(Span(), trait_path) ) ); ::HIR::Visitor::visit_trait_impl(trait_path, impl); m_ms.m_traits.pop_back( ); @@ -541,9 +549,13 @@ namespace { TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type << " { }"); auto _ = this->m_ms.set_impl_generics(impl.m_params); + auto mod_ip = ::HIR::ItemPath(impl.m_src_module); const auto* mod = (impl.m_src_module != ::HIR::SimplePath() ? &this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module) : nullptr); - if(mod) - m_ms.push_traits(*mod); + if(mod) { + m_ms.push_traits(impl.m_src_module, *mod); + m_cur_module.ptr = mod; + m_cur_module.path = &mod_ip; + } ::HIR::Visitor::visit_marker_impl(trait_path, impl); if(mod) m_ms.pop_traits(*mod); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 3d1bf4a5..6049056c 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -1035,6 +1035,7 @@ namespace { tp.pp_impl = ms.pp_impl->clone(); ep.m_mir = Trans_Monomorphise(resolve, mv$(tp), template_const.m_value.m_mir); ep.m_state = ::HIR::ExprStatePtr( ::HIR::ExprState(*m_mod, m_mod_path->get_simple_path()) ); + DEBUG("TMP TMP " << trait_path << " - " << ep.m_state->m_mod_path); ep.m_state->stage = ::HIR::ExprState::Stage::Mir; impl.m_constants.insert(::std::make_pair( vi.first, @@ -1211,7 +1212,7 @@ namespace { { // ::std::unique_ptr> ::std::unique_ptr<::HIR::VisEnt<::HIR::ValueItem>> iv; - iv.reset( new ::HIR::VisEnt<::HIR::ValueItem> { false, ::HIR::ValueItem::make_Static(mv$(v.second)) } ); + iv.reset( new ::HIR::VisEnt<::HIR::ValueItem> { ::HIR::Publicity::new_none(), ::HIR::ValueItem::make_Static(mv$(v.second)) } ); mod.m_value_items.insert(::std::make_pair( v.first, mv$(iv) )); } mod.m_inline_statics.clear(); diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index ee0cff08..d7d476e5 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -720,7 +720,7 @@ namespace { // - Fix type to replace closure types with known paths ExprVisitor_Fixup fixup { m_resolve.m_crate, ¶ms, monomorph_cb }; fixup.visit_type(ty_mono); - capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { false, mv$(ty_mono) } ); + capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { ::HIR::Publicity::new_none(), mv$(ty_mono) } ); } auto closure_struct_path = m_new_type( ::HIR::Struct { @@ -1182,7 +1182,7 @@ namespace { m_new_type = [&](auto s)->auto { auto name = FMT("closure#I_" << closure_count); closure_count += 1; - auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { false, ::HIR::TypeItem( mv$(s) ) } )); + auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { ::HIR::Publicity::new_none(), ::HIR::TypeItem( mv$(s) ) } )); crate.m_root_module.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) ); return ::HIR::SimplePath(crate.m_crate_name, {}) + name; }; @@ -1209,7 +1209,7 @@ namespace { crate.m_type_impls.push_back( ::HIR::TypeImpl { mv$(impl.second.m_params), mv$(impl.second.m_type), - make_map1(impl.second.m_methods.begin()->first, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { true, false, mv$(impl.second.m_methods.begin()->second.data) }), + make_map1(impl.second.m_methods.begin()->first, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { ::HIR::Publicity::new_global(), false, mv$(impl.second.m_methods.begin()->second.data) }), {}, mv$(impl.second.m_src_module) } ); @@ -1233,7 +1233,7 @@ namespace { m_new_type = [&](auto s)->auto { auto name = FMT("closure#" << closure_count); closure_count += 1; - auto boxed = box$( (::HIR::VisEnt< ::HIR::TypeItem> { false, ::HIR::TypeItem( mv$(s) ) }) ); + auto boxed = box$( (::HIR::VisEnt< ::HIR::TypeItem> { ::HIR::Publicity::new_none(), ::HIR::TypeItem( mv$(s) ) }) ); mod.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) ); return (p + name).get_simple_path(); }; diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index 79e163ac..2b3dcfb4 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -32,7 +32,7 @@ namespace { ::std::vector< decltype(mod.m_mod_items)::value_type> new_types; m_new_type = [&](bool pub, auto name, auto s)->auto { - auto boxed = box$( (::HIR::VisEnt< ::HIR::TypeItem> { pub, ::HIR::TypeItem( mv$(s) ) }) ); + auto boxed = box$( (::HIR::VisEnt< ::HIR::TypeItem> { (pub ? ::HIR::Publicity::new_global() : ::HIR::Publicity::new_none()), ::HIR::TypeItem( mv$(s) ) }) ); auto ret = (p + name).get_simple_path(); new_types.push_back( ::std::make_pair( mv$(name), mv$(boxed)) ); return ret; @@ -173,7 +173,7 @@ namespace { DEBUG("- '" << vi.first << "' is @" << fields.size()); fields.push_back( ::std::make_pair( vi.first, - ::HIR::VisEnt< ::HIR::TypeRef> { true, mv$(fcn_type) } + ::HIR::VisEnt< ::HIR::TypeRef> { ::HIR::Publicity::new_global(), mv$(fcn_type) } ) ); ), (Static, @@ -204,11 +204,11 @@ namespace { ft.m_abi = ABI_RUST; ft.m_rettype.reset( new ::HIR::TypeRef(::HIR::TypeRef::new_unit()) ); ft.m_arg_types.push_back( ::HIR::TypeRef::new_pointer(::HIR::BorrowType::Owned, ::HIR::TypeRef::new_unit()) ); - vtc.fields.push_back(::std::make_pair( "#drop_glue", ::HIR::VisEnt<::HIR::TypeRef> { false, ::HIR::TypeRef(mv$(ft)) } )); + vtc.fields.push_back(::std::make_pair( "#drop_glue", ::HIR::VisEnt<::HIR::TypeRef> { ::HIR::Publicity::new_none(), ::HIR::TypeRef(mv$(ft)) } )); // - Size of data - vtc.fields.push_back(::std::make_pair( "#size", ::HIR::VisEnt<::HIR::TypeRef> { false, ::HIR::CoreType::Usize } )); + vtc.fields.push_back(::std::make_pair( "#size", ::HIR::VisEnt<::HIR::TypeRef> { ::HIR::Publicity::new_none(), ::HIR::CoreType::Usize } )); // - Alignment of data - vtc.fields.push_back(::std::make_pair( "#align", ::HIR::VisEnt<::HIR::TypeRef> { false, ::HIR::CoreType::Usize } )); + vtc.fields.push_back(::std::make_pair( "#align", ::HIR::VisEnt<::HIR::TypeRef> { ::HIR::Publicity::new_none(), ::HIR::CoreType::Usize } )); // - Add methods if( ! vtc.add_ents_from_trait(tr, trait_path) ) { diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 762adf5a..1fd44698 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -156,9 +156,9 @@ struct Context const ::HIR::SimplePath m_lang_Box; - Context(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params): + Context(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params, const ::HIR::SimplePath& mod_path): m_crate(crate), - m_resolve(m_ivars, crate, impl_params, item_params) + m_resolve(m_ivars, crate, impl_params, item_params, mod_path) ,next_rule_idx( 0 ) ,m_lang_Box( crate.get_lang_item_path_opt("owned_box") ) { @@ -8062,7 +8062,8 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: TRACE_FUNCTION; auto root_ptr = expr.into_unique(); - Context context { ms.m_crate, ms.m_impl_generics, ms.m_item_generics }; + assert(!ms.m_mod_paths.empty()); + Context context { ms.m_crate, ms.m_impl_generics, ms.m_item_generics, ms.m_mod_paths.back() }; for( auto& arg : args ) { context.handle_pattern( Span(), arg.first, arg.second ); diff --git a/src/hir_typeck/expr_visit.cpp b/src/hir_typeck/expr_visit.cpp index 1a153aaf..d713c135 100644 --- a/src/hir_typeck/expr_visit.cpp +++ b/src/hir_typeck/expr_visit.cpp @@ -36,7 +36,7 @@ namespace { public: void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override { - m_ms.push_traits(mod); + m_ms.push_traits(p, mod); ::HIR::Visitor::visit_module(p, mod); m_ms.pop_traits(mod); } @@ -58,7 +58,7 @@ namespace { auto _ = this->m_ms.set_impl_generics(impl.m_params); const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module); - m_ms.push_traits(mod); + m_ms.push_traits(impl.m_src_module, mod); ::HIR::Visitor::visit_type_impl(impl); m_ms.pop_traits(mod); } @@ -68,7 +68,7 @@ namespace { auto _ = this->m_ms.set_impl_generics(impl.m_params); const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module); - m_ms.push_traits(mod); + m_ms.push_traits(impl.m_src_module, mod); m_ms.m_traits.push_back( ::std::make_pair( &trait_path, &this->m_ms.m_crate.get_trait_by_path(Span(), trait_path) ) ); ::HIR::Visitor::visit_trait_impl(trait_path, impl); m_ms.m_traits.pop_back( ); @@ -80,7 +80,7 @@ namespace { auto _ = this->m_ms.set_impl_generics(impl.m_params); const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module); - m_ms.push_traits(mod); + m_ms.push_traits(impl.m_src_module, mod); ::HIR::Visitor::visit_marker_impl(trait_path, impl); m_ms.pop_traits(mod); } diff --git a/src/hir_typeck/expr_visit.hpp b/src/hir_typeck/expr_visit.hpp index 21a775dc..9388b1dd 100644 --- a/src/hir_typeck/expr_visit.hpp +++ b/src/hir_typeck/expr_visit.hpp @@ -5,6 +5,7 @@ * hir_typeck/expr_visit.hpp * - Helpers for the HIR typecheck expression visiting */ +#include namespace typeck { struct ModuleState @@ -15,6 +16,7 @@ namespace typeck { ::HIR::GenericParams* m_item_generics; ::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > m_traits; + ::std::vector m_mod_paths; ModuleState(const ::HIR::Crate& crate): m_crate(crate), @@ -44,8 +46,9 @@ namespace typeck { return NullOnDrop< ::HIR::GenericParams>(m_item_generics); } - void push_traits(const ::HIR::Module& mod) { + void push_traits(::HIR::ItemPath p, const ::HIR::Module& mod) { auto sp = Span(); + m_mod_paths.push_back( p.get_simple_path() ); DEBUG("Module has " << mod.m_traits.size() << " in-scope traits"); // - Push a NULL entry to prevent parent module import lists being searched m_traits.push_back( ::std::make_pair(nullptr, nullptr) ); @@ -59,6 +62,7 @@ namespace typeck { for(unsigned int i = 0; i < mod.m_traits.size(); i ++ ) m_traits.pop_back(); m_traits.pop_back(); + m_mod_paths.pop_back(); } }; } diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index f94cdf26..0ebb9c07 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -4334,8 +4334,8 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const (Tuple, for( unsigned int i = 0; i < se.size(); i ++ ) { - // TODO: Privacy - if( FMT(i) == name ) { + DEBUG(i << ": " << se[i].publicity); + if( se[i].publicity.is_visible(this->m_vis_path) && FMT(i) == name ) { field_ty = monomorphise_type_with(sp, se[i].ent, monomorph); return true; } @@ -4344,8 +4344,8 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const (Named, for( const auto& fld : se ) { - // TODO: Privacy - if( fld.first == name ) { + DEBUG(fld.first << ": " << fld.second.publicity << ", " << this->m_vis_path); + if( fld.second.publicity.is_visible(this->m_vis_path) && fld.first == name ) { field_ty = monomorphise_type_with(sp, fld.second.ent, monomorph); return true; } @@ -4379,7 +4379,7 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const for( const auto& fld : unm.m_variants ) { // TODO: Privacy - if( fld.first == name ) { + if( fld.second.publicity.is_visible(this->m_vis_path) && fld.first == name ) { field_ty = monomorphise_type_with(sp, fld.second.ent, monomorph); return true; } diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp index 651a36c8..dd9a1581 100644 --- a/src/hir_typeck/helpers.hpp +++ b/src/hir_typeck/helpers.hpp @@ -150,17 +150,19 @@ class TraitResolution const ::HIR::Crate& m_crate; const ::HIR::GenericParams* m_impl_params; const ::HIR::GenericParams* m_item_params; + const ::HIR::SimplePath& m_vis_path; ::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities; ::HIR::SimplePath m_lang_Box; mutable ::std::vector< ::HIR::TypeRef> m_eat_active_stack; public: - TraitResolution(const HMTypeInferrence& ivars, const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params): + TraitResolution(const HMTypeInferrence& ivars, const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params, const ::HIR::SimplePath& vis_path): m_ivars(ivars), m_crate(crate), m_impl_params( impl_params ), m_item_params( item_params ) + ,m_vis_path(vis_path) { prep_indexes(); m_lang_Box = crate.get_lang_item_path_opt("owned_box"); diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index f010b420..f38219ef 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -286,7 +286,7 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C { for(const auto& it : hmod.m_mod_items) { const auto& ve = *it.second; - if( ve.is_public ) { + if( ve.publicity.is_global() ) { const auto* vep = &ve.ent; AST::Path p; if( vep->is_Import() ) { @@ -346,7 +346,7 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C } for(const auto& it : hmod.m_value_items) { const auto& ve = *it.second; - if( ve.is_public ) { + if( ve.publicity.is_global() ) { AST::Path p; const auto* vep = &ve.ent; if( ve.ent.is_Import() ) { diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index e1e2bbd5..afdbd626 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -152,14 +152,14 @@ namespace { const bool EMIT_ALL = true; for(auto& vi : mod.m_value_items) { - Trans_Enumerate_ValItem(state, vi.second->ent, EMIT_ALL || (is_visible && vi.second->is_public), [&](){ return mod_path + vi.first; }); + Trans_Enumerate_ValItem(state, vi.second->ent, EMIT_ALL || (is_visible && vi.second->publicity.is_global()), [&](){ return mod_path + vi.first; }); } for(auto& ti : mod.m_mod_items) { if(auto* e = ti.second->ent.opt_Module() ) { - Trans_Enumerate_Public_Mod(state, *e, mod_path + ti.first, ti.second->is_public); + Trans_Enumerate_Public_Mod(state, *e, mod_path + ti.first, ti.second->publicity.is_global()); } } } -- cgit v1.2.3 From 7a5cd835703fdfac0634b975392f915e0230c2a7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 5 May 2019 20:12:58 +0800 Subject: parse/expand/resolve - `macro` macros use their own module as the resolve root --- src/ast/ast.cpp | 3 +++ src/ast/ast.hpp | 1 + src/expand/mod.cpp | 3 +++ src/hir/from_ast.cpp | 2 ++ src/ident.cpp | 5 ++++- src/include/ident.hpp | 20 ++++++++++++++++++- src/macro_rules/eval.cpp | 1 + src/macro_rules/macro_rules.hpp | 4 ++++ src/macro_rules/parse.cpp | 20 +++++++++++-------- src/parse/paths.cpp | 1 + src/parse/root.cpp | 43 +++++++++++++++++++++-------------------- src/resolve/absolute.cpp | 27 ++++++++++++++++++++++++++ src/resolve/index.cpp | 4 ++++ 13 files changed, 103 insertions(+), 31 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 9893e87f..03257fc6 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -315,6 +315,9 @@ Item Item::clone() const (MacroInv, TODO(this->span, "Clone on Item::MacroInv"); ), + (Macro, + TODO(this->span, "Clone on Item::Macro"); + ), (Use, return AST::Item(e.clone()); ), diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 43a0e027..f6f97fce 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -607,6 +607,7 @@ TAGGED_UNION_EX(Item, (), None, (Impl, Impl), (NegImpl, ImplDef), + (Macro, MacroRulesPtr), (Module, Module), (Crate, struct { ::std::string name; diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index fd851c89..bc51e1ff 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -1113,6 +1113,9 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: } dat.as_MacroInv() = mv$(mi_owned); } + TU_ARMA(Macro, e) { + mod.add_macro(i.is_pub, i.name, mv$(e)); + } TU_ARMA(Use, e) { // No inner expand. } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index af6bc9cb..2393cadd 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1433,6 +1433,8 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity TU_MATCH(::AST::Item, (item.data), (e), (None, ), + (Macro, + ), (MacroInv, // Valid. //BUG(sp, "Stray macro invocation in " << path); diff --git a/src/ident.cpp b/src/ident.cpp index da029e21..63fe57ed 100644 --- a/src/ident.cpp +++ b/src/ident.cpp @@ -34,7 +34,10 @@ bool Ident::Hygiene::is_visible(const Hygiene& src) const } ::std::ostream& operator<<(::std::ostream& os, const Ident::Hygiene& x) { - os << "{" << x.contexts << "}"; + os << "{" << x.contexts; + if( x.search_module ) + os << " " << x.search_module->ents; + os << "}"; return os; } diff --git a/src/include/ident.hpp b/src/include/ident.hpp index b9a6dec5..ec42c582 100644 --- a/src/include/ident.hpp +++ b/src/include/ident.hpp @@ -8,14 +8,21 @@ #pragma once #include #include +#include struct Ident { + struct ModPath + { + //::std::vector ents; + ::std::vector<::std::string> ents; + }; class Hygiene { static unsigned g_next_scope; ::std::vector contexts; + ::std::shared_ptr search_module; Hygiene(unsigned int index): contexts({index}) @@ -32,6 +39,7 @@ struct Ident static Hygiene new_scope_chained(const Hygiene& parent) { Hygiene rv; + rv.search_module = parent.search_module; rv.contexts.reserve( parent.contexts.size() + 1 ); rv.contexts.insert( rv.contexts.begin(), parent.contexts.begin(), parent.contexts.end() ); rv.contexts.push_back( ++g_next_scope ); @@ -45,12 +53,22 @@ struct Ident return rv; } + bool has_mod_path() const { + return this->search_module != 0; + } + const ModPath& mod_path() const { + return *this->search_module; + } + void set_mod_path(ModPath p) { + this->search_module.reset( new ModPath(::std::move(p)) ); + } + Hygiene(Hygiene&& x) = default; Hygiene(const Hygiene& x) = default; Hygiene& operator=(Hygiene&& x) = default; Hygiene& operator=(const Hygiene& x) = default; - // Returns true if an ident with hygine `souce` can see an ident with this hygine + // Returns true if an ident with hygine `source` can see an ident with this hygine bool is_visible(const Hygiene& source) const; //bool operator==(const Hygiene& x) const { return scope_index == x.scope_index; } //bool operator!=(const Hygiene& x) const { return scope_index != x.scope_index; } diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 9caff7b8..c40eb810 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -502,6 +502,7 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type ::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod) { TRACE_FUNCTION_F("'" << name << "', " << input); + DEBUG("rules.m_hygiene = " << rules.m_hygiene); ParameterMappings bound_tts; unsigned int rule_index = Macro_InvokeRules_MatchPattern(sp, rules, mv$(input), mod, bound_tts); diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp index 02b302d8..9e408fd5 100644 --- a/src/macro_rules/macro_rules.hpp +++ b/src/macro_rules/macro_rules.hpp @@ -181,4 +181,8 @@ public: extern ::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod); extern MacroRulesPtr Parse_MacroRules(TokenStream& lex); +extern ::std::vector Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector< ::std::string>& names); +extern ::std::vector Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector< ::std::string>& var_names, ::std::map* var_set_ptr=nullptr); +extern MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector pattern, ::std::vector contents); + #endif // MACROS_HPP_INCLUDED diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 98163998..4bd8a577 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -40,6 +40,7 @@ public: int depth = 0; while( GET_TOK(tok, lex) != close || depth > 0 ) { + DEBUG("tok = " << tok); if( tok.type() == open ) { depth ++; @@ -142,7 +143,7 @@ public: TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector< ::std::string>& var_names, - ::std::map* var_set_ptr=nullptr + ::std::map* var_set_ptr/*=nullptr*/ ) { TRACE_FUNCTION; @@ -310,6 +311,15 @@ void enumerate_names(const ::std::vector& pats, ::std::vector< ::st } } +MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector pattern, ::std::vector contents) +{ + // - Convert the rule into an instruction stream + auto rule_sequence = macro_pattern_to_simple(pat_sp, pattern); + auto arm = MacroRulesArm( mv$(rule_sequence), mv$(contents) ); + enumerate_names(pattern, arm.m_param_names); + return arm; +} + /// Parse an entire macro_rules! block into a format that exec.cpp can use MacroRulesPtr Parse_MacroRules(TokenStream& lex) { @@ -336,13 +346,7 @@ MacroRulesPtr Parse_MacroRules(TokenStream& lex) // Re-parse the patterns into a unified form for(auto& rule : rules) { - // TODO: Transform the pattern into a DFA or similar here (seekable instruction stream?) - - auto rule_sequence = macro_pattern_to_simple(rule.m_pat_span, rule.m_pattern); - MacroRulesArm arm = MacroRulesArm( mv$(rule_sequence), mv$(rule.m_contents) ); - enumerate_names(rule.m_pattern, arm.m_param_names); - - rule_arms.push_back( mv$(arm) ); + rule_arms.push_back( Parse_MacroRules_MakeArm(rule.m_pat_span, mv$(rule.m_pattern), mv$(rule.m_contents)) ); } auto rv = new MacroRules( ); diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp index cb704f85..5c99e049 100644 --- a/src/parse/paths.cpp +++ b/src/parse/paths.cpp @@ -103,6 +103,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi // TODO: TOK_INTERPOLATED_IDENT? GET_CHECK_TOK(tok, lex, TOK_IDENT); auto hygine = lex.getHygiene(); + DEBUG("hygine = " << hygine); PUTBACK(tok, lex); return AST::Path(AST::Path::TagRelative(), mv$(hygine), Parse_PathNodes(lex, generic_mode)); } diff --git a/src/parse/root.cpp b/src/parse/root.cpp index c055c190..b0c37a21 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -20,6 +20,7 @@ #include "lex.hpp" // New file lexer #include #include +#include template Spanned get_spanned(TokenStream& lex, ::std::function f) { @@ -1931,31 +1932,31 @@ namespace { GET_TOK(tok, lex); throw ParseError::Unexpected(lex, tok); } + DEBUG("name = " << name); - //::std::vector< ::std::string> names; - //auto arm_pat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names); - auto args_tt = Parse_TT(lex, false); - if( lex.lookahead(0) != TOK_BRACE_OPEN ) + ::std::vector< ::std::string> names; + auto ps = lex.start_span(); + GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN); + auto arm_pat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names); + auto pat_span = lex.end_span(ps); + GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN); + // TODO: Pass a flag that annotates all idents with the current module? + auto body = Parse_MacroRules_Cont(lex, TOK_BRACE_OPEN, TOK_BRACE_CLOSE, names); + + auto mr = new MacroRules( ); + mr->m_hygiene = lex.getHygiene(); { - GET_TOK(tok, lex); - throw ParseError::Unexpected(lex, tok); + Ident::ModPath mp; + for(const auto& node : mod_path.nodes()) + { + mp.ents.push_back(node.name()); + } + mr->m_hygiene.set_mod_path(::std::move(mp)); } - //auto body = Parse_MacroRules_Cont(lex, TOK_BRACE_OPEN, TOK_BRACE_CLOSE, names); - auto body_tt = Parse_TT(lex, false); - - // TODO: Invoke the macro_rules parsers here - // - Could also do the same level of parsing when `macro_rules! foo {` is seen (i.e. parse macros at parse - // time, instead of during expand). - // - That would simplify some of the expand logic... + mr->m_rules.push_back(Parse_MacroRules_MakeArm(pat_span, ::std::move(arm_pat), ::std::move(body))); - // Lazy option: create a TT - ::std::vector out; - out.push_back(mv$(args_tt)); - out.push_back(TokenTree( Token(TOK_FATARROW) )); - out.push_back(mv$(body_tt)); - - item_name = ""; - item_data = ::AST::Item( AST::MacroInvocation(lex.end_span(ps), "macro_rules", name, TokenTree({}, mv$(out))) ); + item_name = name; + item_data = ::AST::Item( MacroRulesPtr(mr) ); } else { diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 95e01d18..c2dedfcb 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -424,6 +424,29 @@ namespace } AST::Path lookup_opt(const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { DEBUG("name=" << name <<", src_context=" << src_context); + // NOTE: src_context may provide a module to search + if( src_context.has_mod_path() ) + { + DEBUG(src_context.mod_path().ents); + const AST::Module* mod = &m_crate.root_module(); + for(const auto& node : src_context.mod_path().ents) + { + const AST::Module* next = nullptr; + for(const auto& i : mod->items()) + { + if( i.name == node ) { + next = &i.data.as_Module(); + break; + } + } + assert(next); + mod = next; + } + ::AST::Path rv; + if( this->lookup_in_mod(*mod, name, mode, rv) ) { + return rv; + } + } for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) { TU_MATCH(Ent, (*it), (e), @@ -2012,6 +2035,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: (ExternBlock, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), (Impl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), (NegImpl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), + (Macro, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), (Use, BUG(i.data.span, "Resolve_Absolute_ImplItems - Use");), (Module, BUG(i.data.span, "Resolve_Absolute_ImplItems - Module");), (Crate , BUG(i.data.span, "Resolve_Absolute_ImplItems - Crate");), @@ -2056,6 +2080,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Im (Impl , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (NegImpl, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (ExternBlock, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Macro , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Use , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Module, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Crate , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), @@ -2221,6 +2246,8 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) ), (Use, ), + (Macro, + ), (ExternBlock, for(auto& i2 : e.items()) { diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index f38219ef..43182faf 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -121,6 +121,10 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) (NegImpl, ), + (Macro, + // TODO: Add to a macro list + ), + (Use, // Skip for now ), -- cgit v1.2.3 From b48167dec0c1c05b463991a8db5a8db70a5ae604 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 19 May 2019 22:15:02 +0800 Subject: All - Switch to using interned (de-duplicated) RcString-s instead of std::string for paths/identifiers --- src/ast/ast.cpp | 26 ++-- src/ast/ast.hpp | 59 ++++---- src/ast/attrs.hpp | 10 +- src/ast/crate.cpp | 23 +-- src/ast/crate.hpp | 18 +-- src/ast/dump.cpp | 4 +- src/ast/expr.hpp | 24 +-- src/ast/generics.hpp | 6 +- src/ast/item.hpp | 4 +- src/ast/macro.hpp | 10 +- src/ast/path.cpp | 4 +- src/ast/path.hpp | 39 ++--- src/ast/pattern.cpp | 2 +- src/ast/pattern.hpp | 4 +- src/ast/types.cpp | 7 +- src/ast/types.hpp | 11 +- src/coretypes.hpp | 2 +- src/expand/asm.cpp | 4 +- src/expand/assert.cpp | 8 +- src/expand/cfg.cpp | 12 +- src/expand/concat.cpp | 4 +- src/expand/derive.cpp | 276 ++++++++++++++++++----------------- src/expand/env.cpp | 20 +-- src/expand/file_line.cpp | 14 +- src/expand/format_args.cpp | 63 ++++---- src/expand/include.cpp | 15 +- src/expand/macro_rules.cpp | 15 +- src/expand/mod.cpp | 19 ++- src/expand/proc_macro.cpp | 16 +- src/expand/proc_macro.hpp | 8 +- src/expand/rustc_diagnostics.cpp | 14 +- src/expand/stringify.cpp | 2 +- src/expand/test.cpp | 2 +- src/expand/test_harness.cpp | 4 +- src/hir/crate_post_load.cpp | 2 +- src/hir/deserialise.cpp | 139 +++++++++++++----- src/hir/expr.hpp | 26 ++-- src/hir/from_ast.cpp | 55 +++---- src/hir/from_ast.hpp | 2 +- src/hir/from_ast_expr.cpp | 8 +- src/hir/generic_params.cpp | 2 +- src/hir/generic_params.hpp | 16 +- src/hir/hir.cpp | 2 +- src/hir/hir.hpp | 52 +++---- src/hir/hir_ops.cpp | 14 +- src/hir/item_path.hpp | 11 +- src/hir/main_bindings.hpp | 2 +- src/hir/path.cpp | 6 +- src/hir/path.hpp | 26 ++-- src/hir/pattern.cpp | 5 +- src/hir/pattern.hpp | 8 +- src/hir/serialise.cpp | 51 ++++++- src/hir/serialise_lowlevel.cpp | 56 ++++++- src/hir/serialise_lowlevel.hpp | 29 +++- src/hir/type.hpp | 8 +- src/hir_conv/constant_evaluation.cpp | 2 +- src/hir_expand/closures.cpp | 26 ++-- src/hir_expand/vtable.cpp | 11 +- src/hir_typeck/expr_check.cpp | 4 +- src/hir_typeck/expr_cs.cpp | 19 +-- src/hir_typeck/helpers.cpp | 49 +++---- src/hir_typeck/helpers.hpp | 14 +- src/hir_typeck/impl_ref.hpp | 8 +- src/hir_typeck/outer.cpp | 5 +- src/hir_typeck/static.cpp | 22 +-- src/hir_typeck/static.hpp | 4 +- src/include/ident.hpp | 12 +- src/include/rc_string.hpp | 81 +++++++--- src/include/synext_macro.hpp | 5 +- src/macro_rules/eval.cpp | 14 +- src/macro_rules/macro_rules.hpp | 12 +- src/macro_rules/parse.cpp | 14 +- src/main.cpp | 4 +- src/mir/check.cpp | 7 +- src/mir/cleanup.cpp | 6 +- src/mir/from_hir.cpp | 10 +- src/mir/mir.hpp | 4 +- src/parse/common.hpp | 2 +- src/parse/expr.cpp | 44 +++--- src/parse/lex.cpp | 14 +- src/parse/paths.cpp | 10 +- src/parse/pattern.cpp | 12 +- src/parse/root.cpp | 139 +++++++++--------- src/parse/token.cpp | 13 +- src/parse/token.hpp | 4 + src/parse/tokenstream.cpp | 4 +- src/parse/types.cpp | 9 +- src/rc_string.cpp | 113 ++++++++++++-- src/resolve/absolute.cpp | 26 ++-- src/resolve/index.cpp | 10 +- src/resolve/use.cpp | 19 ++- src/trans/auto_impls.cpp | 2 +- src/trans/codegen_c.cpp | 11 +- src/trans/codegen_mmir.cpp | 7 +- src/trans/enumerate.cpp | 10 +- src/trans/mangling.cpp | 15 +- 96 files changed, 1202 insertions(+), 864 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 03257fc6..f1a68680 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -107,16 +107,16 @@ Function Function::clone() const return rv; } -void Trait::add_type(::std::string name, AttributeList attrs, TypeRef type) { +void Trait::add_type(RcString name, AttributeList attrs, TypeRef type) { m_items.push_back( Named(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) ); m_items.back().data.attrs = mv$(attrs); } -void Trait::add_function(::std::string name, AttributeList attrs, Function fcn) { +void Trait::add_function(RcString name, AttributeList attrs, Function fcn) { DEBUG("trait fn " << name); m_items.push_back( Named(mv$(name), Item::make_Function({mv$(fcn)}), true) ); m_items.back().data.attrs = mv$(attrs); } -void Trait::add_static(::std::string name, AttributeList attrs, Static v) { +void Trait::add_static(RcString name, AttributeList attrs, Static v) { m_items.push_back( Named(mv$(name), Item::make_Static({mv$(v)}), true) ); m_items.back().data.attrs = mv$(attrs); } @@ -126,7 +126,7 @@ void Trait::set_is_marker() { bool Trait::is_marker() const { return m_is_marker; } -bool Trait::has_named_item(const ::std::string& name, bool& out_is_fcn) const +bool Trait::has_named_item(const RcString& name, bool& out_is_fcn) const { for( const auto& i : m_items ) { @@ -208,16 +208,16 @@ Union Union::clone() const return os << "impl<" << impl.m_params << "> " << impl.m_trait.ent << " for " << impl.m_type << ""; } -void Impl::add_function(bool is_public, bool is_specialisable, ::std::string name, Function fcn) +void Impl::add_function(bool is_public, bool is_specialisable, RcString name, Function fcn) { DEBUG("impl fn " << name); m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Function(mv$(fcn)) ) } ); } -void Impl::add_type(bool is_public, bool is_specialisable, ::std::string name, TypeRef type) +void Impl::add_type(bool is_public, bool is_specialisable, RcString name, TypeRef type) { m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Type(TypeAlias(GenericParams(), mv$(type))) ) } ); } -void Impl::add_static(bool is_public, bool is_specialisable, ::std::string name, Static v) +void Impl::add_static(bool is_public, bool is_specialisable, RcString name, Static v) { m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Static(mv$(v)) ) } ); } @@ -225,7 +225,7 @@ void Impl::add_macro_invocation(MacroInvocation item) { m_items.push_back( ImplItem { false, false, "", box$( Item::make_MacroInv(mv$(item)) ) } ); } -bool Impl::has_named_item(const ::std::string& name) const +bool Impl::has_named_item(const RcString& name) const { for( const auto& it : this->items() ) { @@ -271,7 +271,7 @@ ExternBlock ExternBlock::clone() const } ::std::shared_ptr Module::add_anon() { - auto rv = ::std::shared_ptr( new Module(m_my_path + FMT("#" << m_anon_modules.size())) ); + auto rv = ::std::shared_ptr( new Module(m_my_path + RcString::new_interned(FMT("#" << m_anon_modules.size()))) ); DEBUG("New anon " << rv->m_my_path); rv->m_file_info = m_file_info; @@ -289,20 +289,20 @@ void Module::add_item( Named named_item ) { DEBUG(m_my_path << "::" << i.name << " = " << i.data.tag_str() << ", attrs = " << i.data.attrs); } } -void Module::add_item(bool is_pub, ::std::string name, Item it, AttributeList attrs) { +void Module::add_item(bool is_pub, RcString name, Item it, AttributeList attrs) { it.attrs = mv$(attrs); add_item( Named( mv$(name), mv$(it), is_pub ) ); } -void Module::add_ext_crate(bool is_public, ::std::string ext_name, ::std::string imp_name, AttributeList attrs) { +void Module::add_ext_crate(bool is_public, RcString ext_name, RcString imp_name, AttributeList attrs) { this->add_item( is_public, imp_name, Item::make_Crate({mv$(ext_name)}), mv$(attrs) ); } void Module::add_macro_invocation(MacroInvocation item) { this->add_item( false, "", Item( mv$(item) ), ::AST::AttributeList {} ); } -void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) { +void Module::add_macro(bool is_exported, RcString name, MacroRulesPtr macro) { m_macros.push_back( Named( mv$(name), mv$(macro), is_exported ) ); } -void Module::add_macro_import(::std::string name, const MacroRules& mr) { +void Module::add_macro_import(RcString name, const MacroRules& mr) { m_macro_import_res.push_back( Named( mv$(name), &mr, false ) ); } diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index f6f97fce..bfef9cff 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -58,12 +58,12 @@ struct StructItem { ::AST::AttributeList m_attrs; bool m_is_public; - ::std::string m_name; + RcString m_name; TypeRef m_type; //StructItem() {} - StructItem(::AST::AttributeList attrs, bool is_pub, ::std::string name, TypeRef ty): + StructItem(::AST::AttributeList attrs, bool is_pub, RcString name, TypeRef ty): m_attrs( mv$(attrs) ), m_is_public(is_pub), m_name( mv$(name) ), @@ -222,16 +222,16 @@ public: const NamedList& items() const { return m_items; } NamedList& items() { return m_items; } - void add_type(::std::string name, AttributeList attrs, TypeRef type); - void add_function(::std::string name, AttributeList attrs, Function fcn); - void add_static(::std::string name, AttributeList attrs, Static v); + void add_type(RcString name, AttributeList attrs, TypeRef type); + void add_function(RcString name, AttributeList attrs, Function fcn); + void add_static(RcString name, AttributeList attrs, Static v); void set_is_marker(); bool is_marker() const; void set_is_unsafe() { m_is_unsafe = true; } bool is_unsafe() const { return m_is_unsafe; } - bool has_named_item(const ::std::string& name, bool& out_is_fcn) const; + bool has_named_item(const RcString& name, bool& out_is_fcn) const; Trait clone() const; }; @@ -257,28 +257,28 @@ TAGGED_UNION_EX(EnumVariantData, (), Value, struct EnumVariant { AttributeList m_attrs; - ::std::string m_name; + RcString m_name; EnumVariantData m_data; EnumVariant() { } - EnumVariant(AttributeList attrs, ::std::string name, Expr&& value): + EnumVariant(AttributeList attrs, RcString name, Expr&& value): m_attrs( mv$(attrs) ), m_name( mv$(name) ), m_data( EnumVariantData::make_Value({mv$(value)}) ) { } - EnumVariant(AttributeList attrs, ::std::string name, ::std::vector sub_types): + EnumVariant(AttributeList attrs, RcString name, ::std::vector sub_types): m_attrs( mv$(attrs) ), m_name( ::std::move(name) ), m_data( EnumVariantData::make_Tuple( {mv$(sub_types)} ) ) { } - EnumVariant(AttributeList attrs, ::std::string name, ::std::vector fields): + EnumVariant(AttributeList attrs, RcString name, ::std::vector fields): m_attrs( mv$(attrs) ), m_name( ::std::move(name) ), m_data( EnumVariantData::make_Struct( {mv$(fields)} ) ) @@ -425,7 +425,7 @@ public: struct ImplItem { bool is_pub; // Ignored for trait impls bool is_specialisable; - ::std::string name; + RcString name; ::std::unique_ptr data; }; @@ -445,9 +445,9 @@ public: {} Impl& operator=(Impl&&) = default; - void add_function(bool is_public, bool is_specialisable, ::std::string name, Function fcn); - void add_type(bool is_public, bool is_specialisable, ::std::string name, TypeRef type); - void add_static(bool is_public, bool is_specialisable, ::std::string name, Static v); + void add_function(bool is_public, bool is_specialisable, RcString name, Function fcn); + void add_type(bool is_public, bool is_specialisable, RcString name, TypeRef type); + void add_static(bool is_public, bool is_specialisable, RcString name, Static v); void add_macro_invocation( MacroInvocation inv ); const ImplDef& def() const { return m_def; } @@ -455,7 +455,7 @@ public: const ::std::vector& items() const { return m_items; } ::std::vector& items() { return m_items; } - bool has_named_item(const ::std::string& name) const; + bool has_named_item(const RcString& name) const; friend ::std::ostream& operator<<(::std::ostream& os, const Impl& impl); @@ -468,7 +468,7 @@ struct UseItem struct Ent { Span sp; // Span covering just the path (final component) ::AST::Path path; - ::std::string name; // If "", this is a glob/wildcard use + RcString name; // If "", this is a glob/wildcard use }; ::std::vector entries; @@ -533,23 +533,23 @@ public: }; // TODO: Document difference between namespace and Type - ::std::unordered_map< ::std::string, IndexEnt > m_namespace_items; - ::std::unordered_map< ::std::string, IndexEnt > m_type_items; - ::std::unordered_map< ::std::string, IndexEnt > m_value_items; + ::std::unordered_map< RcString, IndexEnt > m_namespace_items; + ::std::unordered_map< RcString, IndexEnt > m_type_items; + ::std::unordered_map< RcString, IndexEnt > m_value_items; // List of macros imported from other modules (via #[macro_use], includes proc macros) // - First value is an absolute path to the macro (including crate name) struct MacroImport { bool is_pub; - ::std::string name; // Can be different, if `use foo as bar` is used - ::std::vector<::std::string> path; // includes the crate name + RcString name; // Can be different, if `use foo as bar` is used + ::std::vector path; // includes the crate name const MacroRules* macro_ptr; }; ::std::vector m_macro_imports; struct Import { bool is_pub; - ::std::string name; + RcString name; ::AST::Path path; // If `name` is "", then this is a module/enum to glob }; ::std::vector m_item_imports; @@ -562,19 +562,19 @@ public: } bool is_anon() const { - return m_my_path.nodes().size() > 0 && m_my_path.nodes().back().name()[0] == '#'; + return m_my_path.nodes().size() > 0 && m_my_path.nodes().back().name().c_str()[0] == '#'; } /// Create an anon module (for use inside expressions) ::std::shared_ptr add_anon(); void add_item(Named item); - void add_item(bool is_pub, ::std::string name, Item it, AttributeList attrs); - void add_ext_crate(bool is_public, ::std::string ext_name, ::std::string imp_name, AttributeList attrs); + void add_item(bool is_pub, RcString name, Item it, AttributeList attrs); + void add_ext_crate(bool is_public, RcString ext_name, RcString imp_name, AttributeList attrs); void add_macro_invocation(MacroInvocation item); - void add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro); - void add_macro_import(::std::string name, const MacroRules& mr); + void add_macro(bool is_exported, RcString name, MacroRulesPtr macro); + void add_macro_import(RcString name, const MacroRules& mr); @@ -590,9 +590,6 @@ public: NamedList& macros() { return m_macros; } const NamedList& macros() const { return m_macros; } const ::std::vector > macro_imports_res() const { return m_macro_import_res; } - -private: - void resolve_macro_import(const Crate& crate, const ::std::string& modname, const ::std::string& macro_name); }; TAGGED_UNION_EX(Item, (), None, @@ -610,7 +607,7 @@ TAGGED_UNION_EX(Item, (), None, (Macro, MacroRulesPtr), (Module, Module), (Crate, struct { - ::std::string name; + RcString name; }), (Type, TypeAlias), diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp index a15b4175..04328130 100644 --- a/src/ast/attrs.hpp +++ b/src/ast/attrs.hpp @@ -74,24 +74,24 @@ TAGGED_UNION(AttributeData, None, class Attribute { Span m_span; - ::std::string m_name; + RcString m_name; AttributeData m_data; mutable bool m_is_used; // TODO: Parse as a TT then expand? public: - Attribute(Span sp, ::std::string name): + Attribute(Span sp, RcString name): m_span(::std::move(sp)), m_name(name), m_data( AttributeData::make_None({}) ) { } - Attribute(Span sp, ::std::string name, ::std::string str_val): + Attribute(Span sp, RcString name, ::std::string str_val): m_span(::std::move(sp)), m_name(name), m_data( AttributeData::make_String({mv$(str_val)}) ) { } - Attribute(Span sp, ::std::string name, ::std::vector items): + Attribute(Span sp, RcString name, ::std::vector items): m_span(::std::move(sp)), m_name(name), m_data( AttributeData::make_List({mv$(items)}) ) @@ -123,7 +123,7 @@ public: bool is_used() const { return m_is_used; } const Span& span() const { return m_span; } - const ::std::string& name() const { return m_name; } + const RcString& name() const { return m_name; } const AttributeData& data() const { return m_data; } // Legacy accessors/checkers diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index 5717cbdb..c9856781 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -64,7 +64,7 @@ void Crate::load_externs() TU_IFLET(AST::Item, it.data, Crate, c, if( check_item_cfg(it.data.attrs) ) { - c.name = load_extern_crate( it.data.span, c.name ); + c.name = load_extern_crate( it.data.span, c.name.c_str() ); } ) } @@ -109,12 +109,12 @@ void Crate::load_externs() } // TODO: Handle disambiguating crates with the same name (e.g. libc in std and crates.io libc) // - Crates recorded in rlibs should specify a hash/tag that's passed in to this function. -::std::string Crate::load_extern_crate(Span sp, const ::std::string& name, const ::std::string& basename/*=""*/) +RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::string& basename/*=""*/) { DEBUG("Loading crate '" << name << "'"); ::std::string path; - auto it = g_crate_overrides.find(name); + auto it = g_crate_overrides.find(name.c_str()); if(basename == "" && it != g_crate_overrides.end()) { path = it->second; @@ -140,18 +140,19 @@ void Crate::load_externs() else { ::std::vector<::std::string> paths; - auto name_prefix = "lib"+name+"-"; + auto direct_filename = FMT("lib" << name.c_str() << ".hir"); + auto name_prefix = FMT("lib" << name.c_str() << "-"); // Search a list of load paths for the crate for(const auto& p : g_crate_load_dirs) { - path = p + "/lib" + name + ".hir"; - // TODO: Search for `p+"/lib"+name+"-*.hir" (which would match e.g. libnum-0.11.hir) + path = p + "/" + direct_filename; if( ::std::ifstream(path).good() ) { paths.push_back(path); } path = ""; + // Search for `p+"/lib"+name+"-*.hir" (which would match e.g. libnum-0.11.hir) auto dp = opendir(p.c_str()); if( !dp ) { continue ; @@ -187,7 +188,7 @@ void Crate::load_externs() // NOTE: Creating `ExternCrate` loads the crate from the specified path auto ec = ExternCrate { name, path }; auto real_name = ec.m_hir->m_crate_name; - assert(!real_name.empty()); + assert(real_name != ""); auto res = m_extern_crates.insert(::std::make_pair( real_name, mv$(ec) )); if( !res.second ) { // Crate already loaded? @@ -214,26 +215,26 @@ void Crate::load_externs() return real_name; } -ExternCrate::ExternCrate(const ::std::string& name, const ::std::string& path): +ExternCrate::ExternCrate(const RcString& name, const ::std::string& path): m_name(name), m_short_name(name), m_filename(path) { TRACE_FUNCTION_F("name=" << name << ", path='" << path << "'"); - m_hir = HIR_Deserialise(path, name); + m_hir = HIR_Deserialise(path); m_hir->post_load_update(name); m_name = m_hir->m_crate_name; } -void ExternCrate::with_all_macros(::std::function cb) const +void ExternCrate::with_all_macros(::std::function cb) const { for(const auto& m : m_hir->m_exported_macros) { cb(m.first, *m.second); } } -const MacroRules* ExternCrate::find_macro_rules(const ::std::string& name) const +const MacroRules* ExternCrate::find_macro_rules(const RcString& name) const { auto i = m_hir->m_exported_macros.find(name); if(i != m_hir->m_exported_macros.end()) diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index 79cb9cd7..c4e1d5df 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -36,7 +36,7 @@ public: class ProcMacroDef { public: - ::std::string name; + RcString name; ::AST::Path path; ::std::vector<::std::string> attributes; }; @@ -49,9 +49,9 @@ public: ::std::map< ::std::string, ::AST::Path> m_lang_items; public: Module m_root_module; - ::std::map< ::std::string, ExternCrate> m_extern_crates; + ::std::map< RcString, ExternCrate> m_extern_crates; // Mapping filled by searching for (?visible) macros with is_pub=true - ::std::map< ::std::string, const MacroRules*> m_exported_macros; + ::std::map< RcString, const MacroRules*> m_exported_macros; // List of tests (populated in expand if --test is passed) bool m_test_harness = false; @@ -91,27 +91,27 @@ public: /// Load the named crate and returns the crate's unique name /// If the parameter `file` is non-empty, only that particular filename will be loaded (from any of the search paths) - ::std::string load_extern_crate(Span sp, const ::std::string& name, const ::std::string& file=""); + RcString load_extern_crate(Span sp, const RcString& name, const ::std::string& file=""); }; /// Representation of an imported crate class ExternCrate { public: - ::std::string m_name; - ::std::string m_short_name; + RcString m_name; + RcString m_short_name; ::std::string m_filename; ::HIR::CratePtr m_hir; - ExternCrate(const ::std::string& name, const ::std::string& path); + ExternCrate(const RcString& name, const ::std::string& path); ExternCrate(ExternCrate&&) = default; ExternCrate& operator=(ExternCrate&&) = default; ExternCrate(const ExternCrate&) = delete; ExternCrate& operator=(const ExternCrate& ) = delete; - void with_all_macros(::std::function cb) const; - const MacroRules* find_macro_rules(const ::std::string& name) const; + void with_all_macros(::std::function cb) const; + const MacroRules* find_macro_rules(const RcString& name) const; }; extern ::std::vector<::std::string> g_crate_load_dirs; diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp index 00848fb5..9fb34099 100644 --- a/src/ast/dump.cpp +++ b/src/ast/dump.cpp @@ -36,7 +36,7 @@ public: void handle_enum(const AST::Enum& s); void handle_trait(const AST::Trait& s); - void handle_function(bool is_pub, const ::std::string& name, const AST::Function& f); + void handle_function(bool is_pub, const RcString& name, const AST::Function& f); virtual bool is_const() const override { return true; } virtual void visit(AST::ExprNode_Block& n) override { @@ -1133,7 +1133,7 @@ void RustPrinter::handle_trait(const AST::Trait& s) m_os << "\n"; } -void RustPrinter::handle_function(bool is_pub, const ::std::string& name, const AST::Function& f) +void RustPrinter::handle_function(bool is_pub, const RcString& name, const AST::Function& f) { m_os << indent(); m_os << (is_pub ? "pub " : ""); diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 7675b29a..a9c82efa 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -90,11 +90,11 @@ struct ExprNode_Try: struct ExprNode_Macro: public ExprNode { - ::std::string m_name; - ::std::string m_ident; + RcString m_name; + RcString m_ident; ::TokenTree m_tokens; - ExprNode_Macro(::std::string name, ::std::string ident, ::TokenTree&& tokens): + ExprNode_Macro(RcString name, RcString ident, ::TokenTree&& tokens): m_name(name), m_ident(ident), m_tokens( move(tokens) ) @@ -140,10 +140,10 @@ struct ExprNode_Flow: CONTINUE, BREAK, } m_type; - ::std::string m_target; + RcString m_target; unique_ptr m_value; - ExprNode_Flow(Type type, ::std::string target, unique_ptr&& value): + ExprNode_Flow(Type type, RcString target, unique_ptr&& value): m_type(type), m_target( move(target) ), m_value( move(value) ) @@ -245,24 +245,24 @@ struct ExprNode_Loop: WHILELET, FOR, } m_type; - ::std::string m_label; + RcString m_label; AST::Pattern m_pattern; unique_ptr m_cond; // if NULL, loop is a 'loop' unique_ptr m_code; ExprNode_Loop(): m_type(LOOP) {} - ExprNode_Loop(::std::string label, unique_ptr code): + ExprNode_Loop(RcString label, unique_ptr code): m_type(LOOP), m_label( ::std::move(label) ), m_code( ::std::move(code) ) {} - ExprNode_Loop(::std::string label, unique_ptr cond, unique_ptr code): + ExprNode_Loop(RcString label, unique_ptr cond, unique_ptr code): m_type(WHILE), m_label( ::std::move(label) ), m_cond( ::std::move(cond) ), m_code( ::std::move(code) ) {} - ExprNode_Loop(::std::string label, Type type, AST::Pattern pattern, unique_ptr val, unique_ptr code): + ExprNode_Loop(RcString label, Type type, AST::Pattern pattern, unique_ptr val, unique_ptr code): m_type(type), m_label( ::std::move(label) ), m_pattern( ::std::move(pattern) ), @@ -430,7 +430,7 @@ struct ExprNode_StructLiteral: { struct Ent { AttributeList attrs; - ::std::string name; + RcString name; unique_ptr value; }; typedef ::std::vector t_values; @@ -493,9 +493,9 @@ struct ExprNode_Field: public ExprNode { ::std::unique_ptr m_obj; - ::std::string m_name; + RcString m_name; - ExprNode_Field(::std::unique_ptr&& obj, ::std::string name): + ExprNode_Field(::std::unique_ptr&& obj, RcString name): m_obj( ::std::move(obj) ), m_name( ::std::move(name) ) { diff --git a/src/ast/generics.hpp b/src/ast/generics.hpp index c222044c..bfc7080b 100644 --- a/src/ast/generics.hpp +++ b/src/ast/generics.hpp @@ -17,7 +17,7 @@ class TypeParam ::AST::AttributeList m_attrs; Span m_span; // TODO: use an Ident? - ::std::string m_name; + RcString m_name; ::TypeRef m_default; public: TypeParam(TypeParam&& x) = default; @@ -30,7 +30,7 @@ public: { } - TypeParam(Span sp, ::AST::AttributeList attrs, ::std::string name): + TypeParam(Span sp, ::AST::AttributeList attrs, RcString name): m_attrs( ::std::move(attrs) ), m_span( ::std::move(sp) ), m_name( ::std::move(name) ), @@ -44,7 +44,7 @@ public: const ::AST::AttributeList& attrs() const { return m_attrs; } const Span& span() const { return m_span; } - const ::std::string& name() const { return m_name; } + const RcString& name() const { return m_name; } const TypeRef& get_default() const { return m_default; } TypeRef& get_default() { return m_default; } diff --git a/src/ast/item.hpp b/src/ast/item.hpp index 0074ce9a..ee83a8db 100644 --- a/src/ast/item.hpp +++ b/src/ast/item.hpp @@ -15,7 +15,7 @@ namespace AST { template struct Named { - ::std::string name; + RcString name; T data; bool is_pub; @@ -25,7 +25,7 @@ struct Named Named(Named&&) = default; Named(const Named&) = default; Named& operator=(Named&&) = default; - Named(::std::string name, T data, bool is_pub): + Named(RcString name, T data, bool is_pub): name( ::std::move(name) ), data( ::std::move(data) ), is_pub( is_pub ) diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp index 5b2223ce..e94de8f1 100644 --- a/src/ast/macro.hpp +++ b/src/ast/macro.hpp @@ -18,8 +18,8 @@ class MacroInvocation { Span m_span; - ::std::string m_macro_name; - ::std::string m_ident; + RcString m_macro_name; + RcString m_ident; TokenTree m_input; public: MacroInvocation(MacroInvocation&&) = default; @@ -31,7 +31,7 @@ public: { } - MacroInvocation(Span span, ::std::string macro, ::std::string ident, TokenTree input): + MacroInvocation(Span span, RcString macro, RcString ident, TokenTree input): m_span( mv$(span) ), m_macro_name( mv$(macro) ), m_ident( mv$(ident) ), @@ -48,9 +48,9 @@ public: } const Span& span() const { return m_span; } - const ::std::string& name() const { return m_macro_name; } + const RcString& name() const { return m_macro_name; } - const ::std::string& input_ident() const { return m_ident; } + const RcString& input_ident() const { return m_ident; } const TokenTree& input_tt() const { return m_input; } TokenTree& input_tt() { return m_input; } diff --git a/src/ast/path.cpp b/src/ast/path.cpp index d156f465..830e7372 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -148,7 +148,7 @@ Ordering PathParams::ord(const PathParams& x) const } // --- AST::PathNode -PathNode::PathNode(::std::string name, PathParams args): +PathNode::PathNode(RcString name, PathParams args): m_name( mv$(name) ), m_params( mv$(args) ) { @@ -256,7 +256,7 @@ void Path::bind_variable(unsigned int slot) { m_bindings.value = PathBinding_Value::make_Variable({slot}); } -void Path::bind_enum_var(const Enum& ent, const ::std::string& name) +void Path::bind_enum_var(const Enum& ent, const RcString& name) { auto it = ::std::find_if(ent.variants().begin(), ent.variants().end(), [&](const auto& x) { return x.m_name == name; }); if( it == ent.variants().end() ) diff --git a/src/ast/path.hpp b/src/ast/path.hpp index faa1ffe6..c611c819 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -127,15 +127,15 @@ TAGGED_UNION_EX(PathBinding_Macro, (), Unbound, ( }), (ProcMacroDerive, struct { const ExternCrate* crate_; - ::std::string mac_name; + RcString mac_name; }), (ProcMacroAttribute, struct { const ExternCrate* crate_; - ::std::string mac_name; + RcString mac_name; }), (ProcMacro, struct { const ExternCrate* crate_; - ::std::string mac_name; + RcString mac_name; }), (MacroRules, struct { const ExternCrate* crate_; // Can be NULL @@ -157,12 +157,12 @@ struct PathParams { ::std::vector< LifetimeRef > m_lifetimes; ::std::vector< TypeRef > m_types; - ::std::vector< ::std::pair< ::std::string, TypeRef> > m_assoc; + ::std::vector< ::std::pair< RcString, TypeRef> > m_assoc; PathParams(PathParams&& x) = default; PathParams(const PathParams& x); PathParams() {} - PathParams(::std::vector lfts, ::std::vector tys, ::std::vector<::std::pair<::std::string,TypeRef>> a): + PathParams(::std::vector lfts, ::std::vector tys, ::std::vector<::std::pair> a): m_lifetimes(mv$(lfts)), m_types(mv$(tys)), m_assoc(mv$(a)) @@ -182,12 +182,12 @@ struct PathParams class PathNode { - ::std::string m_name; + RcString m_name; PathParams m_params; public: PathNode() {} - PathNode(::std::string name, PathParams args = {}); - const ::std::string& name() const { return m_name; } + PathNode(RcString name, PathParams args = {}); + const RcString& name() const { return m_name; } const ::AST::PathParams& args() const { return m_params; } ::AST::PathParams& args() { return m_params; } @@ -205,7 +205,7 @@ public: TAGGED_UNION(Class, Invalid, (Invalid, struct {}), (Local, struct { // Variable / Type param (resolved) - ::std::string name; + RcString name; } ), (Relative, struct { // General relative Ident::Hygiene hygiene; @@ -219,7 +219,7 @@ public: ::std::vector nodes; } ), (Absolute, struct { // Absolute - ::std::string crate; + RcString crate; ::std::vector nodes; } ), (UFCS, struct { // Type-relative @@ -267,7 +267,7 @@ public: Path& operator=(const AST::Path&) = delete; // ABSOLUTE - Path(::std::string crate, ::std::vector nodes): + Path(RcString crate, ::std::vector nodes): m_class( Class::make_Absolute({ mv$(crate), mv$(nodes)}) ) {} @@ -278,10 +278,10 @@ public: // VARIABLE struct TagLocal {}; - Path(TagLocal, ::std::string name): + Path(TagLocal, RcString name): m_class( Class::make_Local({ mv$(name) }) ) {} - Path(::std::string name): + Path(RcString name): m_class( Class::make_Local({ mv$(name) }) ) {} @@ -301,14 +301,6 @@ public: m_class( Class::make_Super({ count, mv$(nodes) }) ) {} - //void set_crate(::std::string crate) { - // if( m_crate == "" ) { - // m_crate = crate; - // DEBUG("crate set to " << m_crate); - // } - //} - - Class::Tag class_tag() const { return m_class.tag(); } @@ -318,7 +310,7 @@ public: tmp.nodes().push_back( mv$(pn) ); return tmp; } - Path operator+(const ::std::string& s) const { + Path operator+(const RcString& s) const { Path tmp = Path(*this); tmp.append(PathNode(s, {})); return tmp; @@ -370,7 +362,6 @@ public: ) throw ::std::runtime_error("Path::nodes() fell off"); } - //const ::std::string& crate() const { return m_crate; } bool is_parent_of(const Path& x) const; @@ -407,7 +398,7 @@ private: void check_param_counts(const GenericParams& params, bool expect_params, PathNode& node); public: - void bind_enum_var(const Enum& ent, const ::std::string& name); + void bind_enum_var(const Enum& ent, const RcString& name); void bind_function(const Function& ent) { m_bindings.value = PathBinding_Value::make_Function({&ent}); } diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp index 72087d95..e13662fe 100644 --- a/src/ast/pattern.cpp +++ b/src/ast/pattern.cpp @@ -223,7 +223,7 @@ AST::Pattern AST::Pattern::clone() const rv.m_data = Data::make_StructTuple({ ::AST::Path(e.path), H::clone_tup(e.tup_pat) }); ), (Struct, - ::std::vector< ::std::pair< ::std::string, Pattern> > sps; + ::std::vector< ::std::pair< RcString, Pattern> > sps; for(const auto& sp : e.sub_patterns) sps.push_back( ::std::make_pair(sp.first, sp.second.clone()) ); rv.m_data = Data::make_Struct({ ::AST::Path(e.path), mv$(sps) }); diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 40cfa927..81c1126a 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -88,7 +88,7 @@ public: (Value, struct { Value start; Value end; } ), (Tuple, TuplePat ), (StructTuple, struct { Path path; TuplePat tup_pat; } ), - (Struct, struct { Path path; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; bool is_exhaustive; } ), + (Struct, struct { Path path; ::std::vector< ::std::pair< RcString, Pattern> > sub_patterns; bool is_exhaustive; } ), (Slice, struct { ::std::vector sub_pats; }), (SplitSlice, struct { ::std::vector leading; PatternBinding extra_bind; ::std::vector trailing; } ) ); @@ -171,7 +171,7 @@ public: {} struct TagStruct {}; - Pattern(TagStruct, Span sp, Path path, ::std::vector< ::std::pair< ::std::string,Pattern> > sub_patterns, bool is_exhaustive): + Pattern(TagStruct, Span sp, Path path, ::std::vector< ::std::pair< RcString,Pattern> > sub_patterns, bool is_exhaustive): m_span( mv$(sp) ), m_data( Data::make_Struct( { ::std::move(path), ::std::move(sub_patterns), is_exhaustive } ) ) {} diff --git a/src/ast/types.cpp b/src/ast/types.cpp index f9103b37..496cf694 100644 --- a/src/ast/types.cpp +++ b/src/ast/types.cpp @@ -40,13 +40,14 @@ static const struct { {"usize", CORETYPE_UINT}, }; -enum eCoreType coretype_fromstring(const ::std::string& name) +enum eCoreType coretype_fromstring(const char* name) { for(unsigned int i = 0; i < sizeof(CORETYPES)/sizeof(CORETYPES[0]); i ++) { - if( name < CORETYPES[i].name ) + int cmp = strcmp(name, CORETYPES[i].name); + if( cmp < 0 ) break; - if( name == CORETYPES[i].name ) + if( cmp == 0 ) return CORETYPES[i].type; } return CORETYPE_INVAL; diff --git a/src/ast/types.hpp b/src/ast/types.hpp index 0b0f205e..15cb1383 100644 --- a/src/ast/types.hpp +++ b/src/ast/types.hpp @@ -73,6 +73,7 @@ namespace AST { bool is_infer() const { return m_binding == BINDING_INFER; } const Ident& name() const { return m_name; } + uint16_t binding() const { return m_binding; } Ordering ord(const LifetimeRef& x) const { return ::ord(m_name.name, x.m_name.name); } bool operator==(const LifetimeRef& x) const { return ord(x) == OrdEqual; } bool operator!=(const LifetimeRef& x) const { return ord(x) != OrdEqual; } @@ -97,7 +98,7 @@ public: struct TypeArgRef { - ::std::string name; + RcString name; unsigned int level; const AST::GenericParams* params; }; @@ -165,7 +166,7 @@ TAGGED_UNION(TypeData, None, ::std::shared_ptr size; }), (Generic, struct { - ::std::string name; + RcString name; unsigned int index; }), (Path, struct { @@ -276,11 +277,11 @@ public: {} struct TagArg {}; - TypeRef(TagArg, Span sp, ::std::string name, unsigned int binding = ~0u): + TypeRef(TagArg, Span sp, RcString name, unsigned int binding = ~0u): m_span( mv$(sp) ), m_data(TypeData::make_Generic({ name, binding })) {} - TypeRef(Span sp, ::std::string name, unsigned int binding = ~0u): + TypeRef(Span sp, RcString name, unsigned int binding = ~0u): TypeRef(TagArg(), mv$(sp), mv$(name), binding) {} @@ -314,7 +315,7 @@ public: AST::Path& path() { return m_data.as_Path().path; } bool is_type_param() const { return m_data.is_Generic(); } - const ::std::string& type_param() const { return m_data.as_Generic().name; } + const RcString& type_param() const { return m_data.as_Generic().name; } bool is_reference() const { return m_data.is_Borrow(); } bool is_pointer() const { return m_data.is_Pointer(); } diff --git a/src/coretypes.hpp b/src/coretypes.hpp index 7665f5ba..692473e5 100644 --- a/src/coretypes.hpp +++ b/src/coretypes.hpp @@ -24,7 +24,7 @@ enum eCoreType CORETYPE_F64, }; -extern enum eCoreType coretype_fromstring(const ::std::string& name); +extern enum eCoreType coretype_fromstring(const char* name); extern const char* coretype_name(const eCoreType ct); #endif // CORETYPES_HPP_INCLUDED diff --git a/src/expand/asm.cpp b/src/expand/asm.cpp index d895c32d..f8b3984d 100644 --- a/src/expand/asm.cpp +++ b/src/expand/asm.cpp @@ -35,12 +35,10 @@ namespace class CAsmExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; auto lex = TTStream(sp, tt); - if( ident != "" ) - ERROR(sp, E0000, "asm! doesn't take an ident"); auto template_text = get_string(sp, lex, crate, mod); ::std::vector<::AST::ExprNode_Asm::ValRef> outputs; diff --git a/src/expand/assert.cpp b/src/expand/assert.cpp index 5bb23bde..ffba7b98 100644 --- a/src/expand/assert.cpp +++ b/src/expand/assert.cpp @@ -15,14 +15,12 @@ class CExpander_assert: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; auto lex = TTStream(sp, tt); lex.parse_state().module = &mod; - if( ident != "" ) - ERROR(sp, E0000, "format_args! doesn't take an ident"); // assertion condition auto n = Parse_Expr0(lex); @@ -39,7 +37,7 @@ class CExpander_assert: toks.push_back( Token(InterpolatedFragment(InterpolatedFragment::EXPR, n.release())) ); toks.push_back( Token(TOK_BRACE_OPEN) ); // User-provided message - toks.push_back( Token(TOK_IDENT, "panic") ); + toks.push_back( Token(TOK_IDENT, RcString::new_interned("panic")) ); toks.push_back( Token(TOK_EXCLAM) ); toks.push_back( Token(TOK_PAREN_OPEN) ); while(lex.lookahead(0) != TOK_EOF ) @@ -63,7 +61,7 @@ class CExpander_assert: toks.push_back( Token(TOK_BRACE_OPEN) ); // Auto-generated message - toks.push_back( Token(TOK_IDENT, "panic") ); + toks.push_back( Token(TOK_IDENT, RcString::new_interned("panic")) ); toks.push_back( Token(TOK_EXCLAM) ); toks.push_back( Token(TOK_PAREN_OPEN) ); toks.push_back( Token(TOK_STRING, ss.str()) ); diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index 773a38c4..7e922779 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -60,7 +60,7 @@ bool check_cfg(const Span& sp, const ::AST::Attribute& mi) { } else if( mi.has_string() ) { // Equaliy - auto its = g_cfg_values.equal_range(mi.name()); + auto its = g_cfg_values.equal_range(mi.name().c_str()); for(auto it = its.first; it != its.second; ++it) { DEBUG(""<second<<"' == '"< expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) { - ERROR(sp, E0000, "cfg! doesn't take an identifier"); - } - auto lex = TTStream(sp, tt); auto attrs = Parse_MetaItem(lex); DEBUG("cfg!() - " << attrs); diff --git a/src/expand/concat.cpp b/src/expand/concat.cpp index 29a066df..bd741e2f 100644 --- a/src/expand/concat.cpp +++ b/src/expand/concat.cpp @@ -16,13 +16,11 @@ class CConcatExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; auto lex = TTStream(sp, tt); - if( ident != "" ) - ERROR(sp, E0000, "format_args! doesn't take an ident"); ::std::string rv; do { diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index dddd82b6..6dea3028 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -58,6 +58,15 @@ static inline ::std::vector vec$(T v1, T v2, T v3, T v4, T v5) { tmp.push_back( mv$(v5) ); return mv$(tmp); } +static AST::Path get_path(const RcString& core_name, ::std::string c1, ::std::string c2) +{ + return AST::Path(core_name, { AST::PathNode(RcString::new_interned(c1), {}), AST::PathNode(RcString::new_interned(c2), {}) }); +} +static AST::Path get_path(const RcString& core_name, ::std::string c1, ::std::string c2, ::std::string c3) +{ + return AST::Path(core_name, { AST::PathNode(RcString::new_interned(c1), {}), AST::PathNode(RcString::new_interned(c2), {}), AST::PathNode(RcString::new_interned(c3), {}) }); +} + static inline AST::ExprNodeP mk_exprnodep(AST::ExprNode* en){ return AST::ExprNodeP(en); } //#define NEWNODE(type, ...) mk_exprnodep(new type(__VA_ARGS__)) @@ -65,7 +74,7 @@ static inline AST::ExprNodeP mk_exprnodep(AST::ExprNode* en){ return AST::ExprNo struct DeriveOpts { - ::std::string core_name; + RcString core_name; const ::std::vector<::AST::Attribute>& derive_items; }; @@ -288,7 +297,7 @@ class Deriver_Debug: // throw CompileError::Todo("derive(Debug) - _try"); //} - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path debug_trait = AST::Path(core_name, { AST::PathNode("fmt", {}), AST::PathNode("Debug", {}) }); TypeRef f_type(TypeRef::TagReference(), sp, AST::LifetimeRef(), true, @@ -319,7 +328,7 @@ public: AST::Impl handle_item(Span sp, const DeriveOpts& opts, const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const override { - const ::std::string& name = type.path().nodes().back().name(); + ::std::string name = type.path().nodes().back().name().c_str(); // Generate code for Debug AST::ExprNodeP node; @@ -342,7 +351,7 @@ public: node = NEWNODE(CallMethod, mv$(node), AST::PathNode("field",{}), vec$( - NEWNODE(String, fld.m_name), + NEWNODE(String, fld.m_name.c_str()), NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), @@ -368,7 +377,7 @@ public: NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), - FMT(idx) + RcString::new_interned(FMT(idx)) ) )) ) @@ -396,7 +405,7 @@ public: code = NEWNODE(CallMethod, NEWNODE(NamedValue, AST::Path("f")), AST::PathNode("write_str",{}), - vec$( NEWNODE(String, v.m_name) ) + vec$( NEWNODE(String, v.m_name.c_str()) ) ); pat_a = AST::Pattern(AST::Pattern::TagValue(), sp, AST::Pattern::Value::make_Named(base_path + v.m_name)); ), @@ -407,12 +416,12 @@ public: node = NEWNODE(NamedValue, AST::Path("f")); node = NEWNODE(CallMethod, mv$(node), AST::PathNode("debug_tuple",{}), - vec$( NEWNODE(String, v.m_name) ) + vec$( NEWNODE(String, v.m_name.c_str()) ) ); for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); node = NEWNODE(CallMethod, @@ -427,24 +436,24 @@ public: pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); ), (Struct, - ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_a; AST::ExprNodeP node; node = NEWNODE(NamedValue, AST::Path("f")); node = NEWNODE(CallMethod, mv$(node), AST::PathNode("debug_struct",{}), - vec$( NEWNODE(String, v.m_name) ) + vec$( NEWNODE(String, v.m_name.c_str()) ) ); for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); node = NEWNODE(CallMethod, mv$(node), AST::PathNode("field",{}), vec$( - NEWNODE(String, fld.m_name), + NEWNODE(String, fld.m_name.c_str()), NEWNODE(NamedValue, AST::Path(name_a)) ) ); @@ -476,7 +485,7 @@ public: class Deriver_PartialEq: public Deriver { - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("PartialEq", {}) }); @@ -498,7 +507,7 @@ class Deriver_PartialEq: rv.add_function(false, false, "eq", mv$(fcn)); return mv$(rv); } - AST::ExprNodeP compare_and_ret(Span sp, const ::std::string& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const + AST::ExprNodeP compare_and_ret(Span sp, const RcString& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const { return NEWNODE(If, NEWNODE(BinOp, AST::ExprNode_BinOp::CMPNEQU, mv$(v1), mv$(v2)), @@ -528,7 +537,7 @@ public: (Tuple, for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) { - auto fld_name = FMT(idx); + auto fld_name = RcString::new_interned(FMT(idx)); nodes.push_back(this->compare_and_ret( sp, opts.core_name, NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), fld_name), NEWNODE(Field, NEWNODE(NamedValue, AST::Path("v" )), fld_name) @@ -566,8 +575,8 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); + auto name_b = RcString::new_interned(FMT("b" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); nodes.push_back(this->compare_and_ret(sp, opts.core_name, @@ -582,14 +591,14 @@ public: code = NEWNODE(Block, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; - ::std::vector< ::std::pair > pats_b; + ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_b; ::std::vector nodes; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); - auto name_b = FMT("b" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); + auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); nodes.push_back(this->compare_and_ret(sp, opts.core_name, @@ -642,16 +651,7 @@ public: class Deriver_PartialOrd: public Deriver { - AST::Path get_path(const ::std::string core_name, ::std::string c1, ::std::string c2) const - { - return AST::Path(core_name, { AST::PathNode(c1, {}), AST::PathNode(c2, {}) }); - } - AST::Path get_path(const ::std::string core_name, ::std::string c1, ::std::string c2, ::std::string c3) const - { - return AST::Path(core_name, { AST::PathNode(c1, {}), AST::PathNode(c2, {}), AST::PathNode(c3, {}) }); - } - - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("PartialOrd", {}) }); const AST::Path path_ordering(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ordering", {}) }); @@ -678,10 +678,10 @@ class Deriver_PartialOrd: return mv$(rv); } - AST::ExprNodeP make_compare_and_ret(Span sp, const ::std::string& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const + AST::ExprNodeP make_compare_and_ret(Span sp, const RcString& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const { return NEWNODE(Match, - NEWNODE(CallPath, this->get_path(core_name, "cmp", "PartialOrd", "partial_cmp"), + NEWNODE(CallPath, get_path(core_name, "cmp", "PartialOrd", "partial_cmp"), ::make_vec2( NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(v1)), NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(v2)) @@ -689,13 +689,13 @@ class Deriver_PartialOrd: ), ::make_vec3( ::AST::ExprNode_Match_Arm( - ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, this->get_path(core_name, "option", "Option", "None")) ), + ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, get_path(core_name, "option", "Option", "None")) ), nullptr, - NEWNODE(Flow, AST::ExprNode_Flow::RETURN, "", NEWNODE(NamedValue, this->get_path(core_name, "option", "Option", "None"))) + NEWNODE(Flow, AST::ExprNode_Flow::RETURN, "", NEWNODE(NamedValue, get_path(core_name, "option", "Option", "None"))) ), ::AST::ExprNode_Match_Arm( - ::make_vec1( AST::Pattern(AST::Pattern::TagNamedTuple(), sp, this->get_path(core_name, "option", "Option", "Some"), - ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, this->get_path(core_name, "cmp", "Ordering", "Equal")) ) + ::make_vec1( AST::Pattern(AST::Pattern::TagNamedTuple(), sp, get_path(core_name, "option", "Option", "Some"), + ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, get_path(core_name, "cmp", "Ordering", "Equal")) ) ) ), nullptr, NEWNODE(Tuple, ::std::vector()) @@ -708,10 +708,10 @@ class Deriver_PartialOrd: ) ); } - AST::ExprNodeP make_ret_equal(const ::std::string& core_name) const + AST::ExprNodeP make_ret_equal(const RcString& core_name) const { - return NEWNODE(CallPath, this->get_path(core_name, "option", "Option", "Some"), - ::make_vec1( NEWNODE(NamedValue, this->get_path(core_name, "cmp", "Ordering", "Equal")) ) + return NEWNODE(CallPath, get_path(core_name, "option", "Option", "Some"), + ::make_vec1( NEWNODE(NamedValue, get_path(core_name, "cmp", "Ordering", "Equal")) ) ); } public: @@ -736,7 +736,7 @@ public: (Tuple, for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) { - auto fld_name = FMT(idx); + auto fld_name = RcString::new_interned(FMT(idx)); nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), fld_name), NEWNODE(Field, NEWNODE(NamedValue, AST::Path("v" )), fld_name) @@ -774,8 +774,8 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); + auto name_b = RcString::new_interned(FMT("b" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); @@ -791,14 +791,14 @@ public: code = NEWNODE(Block, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; - ::std::vector< ::std::pair > pats_b; + ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_b; ::std::vector nodes; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); - auto name_b = FMT("b" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); + auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); @@ -834,10 +834,10 @@ public: // - Requires a way of emitting said intrinsic into the AST // - LAZY WAY - hard-code ::"core"::intrinsics::discriminant_value { - auto code = NEWNODE(CallPath, this->get_path(opts.core_name, "cmp", "PartialOrd", "partial_cmp"), + auto code = NEWNODE(CallPath, get_path(opts.core_name, "cmp", "PartialOrd", "partial_cmp"), ::make_vec2( - NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, this->get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("self")) )) ), - NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, this->get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("v")) )) ) + NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("self")) )) ), + NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("v")) )) ) ) ); ::std::vector< AST::Pattern> pats = make_vec1( AST::Pattern() ); @@ -862,11 +862,11 @@ public: class Deriver_Eq: public Deriver { - AST::Path get_trait_path(const ::std::string& core_name) const { + AST::Path get_trait_path(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Eq", {}) }); } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(core_name); @@ -894,6 +894,9 @@ class Deriver_Eq: ); } AST::ExprNodeP field(const ::std::string& name) const { + return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), RcString::new_interned(name)); + } + AST::ExprNodeP field(const RcString& name) const { return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), name); } @@ -949,7 +952,7 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); } @@ -958,12 +961,12 @@ public: code = NEWNODE(Block, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_a; ::std::vector nodes; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); } @@ -1007,16 +1010,7 @@ public: class Deriver_Ord: public Deriver { - AST::Path get_path(const ::std::string core_name, ::std::string c1, ::std::string c2) const - { - return AST::Path(core_name, { AST::PathNode(c1, {}), AST::PathNode(c2, {}) }); - } - AST::Path get_path(const ::std::string core_name, ::std::string c1, ::std::string c2, ::std::string c3) const - { - return AST::Path(core_name, { AST::PathNode(c1, {}), AST::PathNode(c2, {}), AST::PathNode(c3, {}) }); - } - - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ord", {}) }); const AST::Path path_ordering(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ordering", {}) }); @@ -1040,10 +1034,10 @@ class Deriver_Ord: return mv$(rv); } - AST::ExprNodeP make_compare_and_ret(Span sp, const ::std::string& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const + AST::ExprNodeP make_compare_and_ret(Span sp, const RcString& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const { return NEWNODE(Match, - NEWNODE(CallPath, this->get_path(core_name, "cmp", "Ord", "cmp"), + NEWNODE(CallPath, get_path(core_name, "cmp", "Ord", "cmp"), // TODO: Optional Ref? ::make_vec2( NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(v1)), @@ -1052,7 +1046,7 @@ class Deriver_Ord: ), ::make_vec2( ::AST::ExprNode_Match_Arm( - ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, this->get_path(core_name, "cmp", "Ordering", "Equal")) ), + ::make_vec1( AST::Pattern(AST::Pattern::TagValue(), sp, get_path(core_name, "cmp", "Ordering", "Equal")) ), nullptr, NEWNODE(Tuple, ::std::vector()) ), @@ -1064,9 +1058,9 @@ class Deriver_Ord: ) ); } - AST::ExprNodeP make_ret_equal(const ::std::string& core_name) const + AST::ExprNodeP make_ret_equal(const RcString& core_name) const { - return NEWNODE(NamedValue, this->get_path(core_name, "cmp", "Ordering", "Equal")); + return NEWNODE(NamedValue, get_path(core_name, "cmp", "Ordering", "Equal")); } public: const char* trait_name() const override { return "Ord"; } @@ -1090,7 +1084,7 @@ public: (Tuple, for( unsigned int idx = 0; idx < e.ents.size(); idx ++ ) { - auto fld_name = FMT(idx); + auto fld_name = RcString::new_interned(FMT(idx)); nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), fld_name), NEWNODE(Field, NEWNODE(NamedValue, AST::Path("v" )), fld_name) @@ -1128,8 +1122,8 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); - auto name_b = FMT("b" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); + auto name_b = RcString::new_interned(FMT("b" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); @@ -1145,14 +1139,14 @@ public: code = NEWNODE(Block, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; - ::std::vector< ::std::pair > pats_b; + ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_b; ::std::vector nodes; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); - auto name_b = FMT("b" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); + auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); @@ -1186,10 +1180,10 @@ public: { - auto code = NEWNODE(CallPath, this->get_path(opts.core_name, "cmp", "Ord", "cmp"), + auto code = NEWNODE(CallPath, get_path(opts.core_name, "cmp", "Ord", "cmp"), ::make_vec2( - NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, this->get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("self")) )) ), - NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, this->get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("v")) )) ) + NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("self")) )) ), + NEWNODE(UniOp, AST::ExprNode_UniOp::REF, NEWNODE(CallPath, get_path(opts.core_name, "intrinsics", "discriminant_value"), make_vec1( NEWNODE(NamedValue, AST::Path("v")) )) ) ) ); ::std::vector< AST::Pattern> pats = make_vec1( AST::Pattern() ); @@ -1214,14 +1208,14 @@ public: class Deriver_Clone: public Deriver { - AST::Path get_trait_path(const ::std::string& core_name) const { + AST::Path get_trait_path(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("clone", {}), AST::PathNode("Clone", {}) }); } - AST::Path get_method_path(const ::std::string& core_name) const { + AST::Path get_method_path(const RcString& core_name) const { return get_trait_path(core_name) + "clone"; } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(core_name); @@ -1242,22 +1236,25 @@ class Deriver_Clone: rv.add_function(false, false, "clone", mv$(fcn)); return mv$(rv); } - AST::ExprNodeP clone_val_ref(const ::std::string& core_name, AST::ExprNodeP val) const { + AST::ExprNodeP clone_val_ref(const RcString& core_name, AST::ExprNodeP val) const { // TODO: Hack for zero-sized arrays? (Not a 1.19 feature) return NEWNODE(CallPath, this->get_method_path(core_name), vec$( NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(val) ) ) ); } - AST::ExprNodeP clone_val_direct(const ::std::string& core_name, AST::ExprNodeP val) const { + AST::ExprNodeP clone_val_direct(const RcString& core_name, AST::ExprNodeP val) const { return NEWNODE(CallPath, this->get_method_path(core_name), vec$( mv$(val) ) ); } - AST::ExprNodeP field(const ::std::string& name) const { + AST::ExprNodeP field(const RcString& name) const { return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), name); } + AST::ExprNodeP field(const ::std::string& name) const { + return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), RcString::new_interned(name)); + } public: const char* trait_name() const override { return "Clone"; } @@ -1314,7 +1311,7 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); nodes.push_back( this->clone_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); } @@ -1323,12 +1320,12 @@ public: code = NEWNODE(CallPath, base_path + v.m_name, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_a; ::AST::ExprNode_StructLiteral::t_values vals; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); vals.push_back({ {}, fld.m_name, this->clone_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) }); } @@ -1383,11 +1380,11 @@ private: class Deriver_Copy: public Deriver { - AST::Path get_trait_path(const ::std::string& core_name) const { + AST::Path get_trait_path(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("marker", {}), AST::PathNode("Copy", {}) }); } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(core_name); @@ -1418,14 +1415,14 @@ public: class Deriver_Default: public Deriver { - AST::Path get_trait_path(const ::std::string& core_name) const { + AST::Path get_trait_path(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("default", {}), AST::PathNode("Default", {}) }); } - AST::Path get_method_path(const ::std::string& core_name) const { + AST::Path get_method_path(const RcString& core_name) const { return AST::Path(AST::Path::TagUfcs(), ::TypeRef(Span()), get_trait_path(core_name), { AST::PathNode("default", {}) } ); } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(core_name); @@ -1444,7 +1441,7 @@ class Deriver_Default: rv.add_function(false, false, "default", mv$(fcn)); return mv$(rv); } - AST::ExprNodeP default_call(const ::std::string& core_name) const { + AST::ExprNodeP default_call(const RcString& core_name) const { return NEWNODE(CallPath, this->get_method_path(core_name), {} @@ -1493,17 +1490,17 @@ public: class Deriver_Hash: public Deriver { - AST::Path get_trait_path(const ::std::string& core_name) const { + AST::Path get_trait_path(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("hash", {}), AST::PathNode("Hash", {}) }); } - AST::Path get_trait_path_Hasher(const ::std::string& core_name) const { + AST::Path get_trait_path_Hasher(const RcString& core_name) const { return AST::Path(core_name, { AST::PathNode("hash", {}), AST::PathNode("Hasher", {}) }); } - AST::Path get_method_path(const ::std::string& core_name) const { + AST::Path get_method_path(const RcString& core_name) const { return get_trait_path(core_name) + "hash"; } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(core_name); @@ -1530,18 +1527,21 @@ class Deriver_Hash: rv.add_function(false, false, "hash", mv$(fcn)); return mv$(rv); } - AST::ExprNodeP hash_val_ref(const ::std::string& core_name, AST::ExprNodeP val) const { + AST::ExprNodeP hash_val_ref(const RcString& core_name, AST::ExprNodeP val) const { return this->hash_val_direct(core_name, NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(val)) ); } - AST::ExprNodeP hash_val_direct(const ::std::string& core_name, AST::ExprNodeP val) const { + AST::ExprNodeP hash_val_direct(const RcString& core_name, AST::ExprNodeP val) const { return NEWNODE(CallPath, this->get_method_path(core_name), vec$( mv$(val), NEWNODE(NamedValue, AST::Path("state")) ) ); } - AST::ExprNodeP field(const ::std::string& name) const { + AST::ExprNodeP field(const RcString& name) const { return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), name); } + AST::ExprNodeP field(const std::string& name) const { + return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), RcString::new_interned(name)); + } public: const char* trait_name() const override { return "Hash"; } @@ -1596,7 +1596,7 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); nodes.push_back( this->hash_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); } @@ -1605,13 +1605,13 @@ public: code = NEWNODE(Block, mv$(nodes)); ), (Struct, - ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_a; ::std::vector< AST::ExprNodeP > nodes; nodes.push_back( mv$(var_idx_hash) ); for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); nodes.push_back( this->hash_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); } @@ -1652,7 +1652,7 @@ class Deriver_RustcEncodable: return get_trait_path() + "encode"; } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(); @@ -1689,9 +1689,12 @@ class Deriver_RustcEncodable: AST::ExprNodeP enc_val_ref(AST::ExprNodeP val) const { return this->enc_val_direct(NEWNODE(UniOp, AST::ExprNode_UniOp::REF, mv$(val)) ); } - AST::ExprNodeP field(const ::std::string& name) const { + AST::ExprNodeP field(const RcString& name) const { return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), name); } + AST::ExprNodeP field(::std::string name) const { + return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), RcString::new_interned(name)); + } AST::ExprNodeP enc_closure(Span sp, AST::ExprNodeP code) const { return NEWNODE(Closure, @@ -1699,7 +1702,7 @@ class Deriver_RustcEncodable: mv$(code), false ); } - AST::ExprNodeP get_val_ok(const ::std::string& core_name) const { + AST::ExprNodeP get_val_ok(const RcString& core_name) const { return NEWNODE(CallPath, AST::Path(core_name, {AST::PathNode("result",{}), AST::PathNode("Result",{}), AST::PathNode("Ok",{})}), vec$( NEWNODE(Tuple, {})) ); } @@ -1708,7 +1711,7 @@ public: AST::Impl handle_item(Span sp, const DeriveOpts& opts, const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const override { - const ::std::string& struct_name = type.m_data.as_Path().path.nodes().back().name(); + ::std::string struct_name = type.m_data.as_Path().path.nodes().back().name().c_str(); ::std::vector nodes; TU_MATCH(AST::StructData, (str.m_data), (e), @@ -1720,7 +1723,12 @@ public: { nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_struct_field", - vec$( NEWNODE(NamedValue, AST::Path("s")), NEWNODE(String, fld.m_name), NEWNODE(Integer, idx, CORETYPE_UINT), this->enc_closure( sp, this->enc_val_ref(this->field(fld.m_name)) ) ) + vec$( + NEWNODE(NamedValue, AST::Path("s")), + NEWNODE(String, fld.m_name.c_str()), + NEWNODE(Integer, idx, CORETYPE_UINT), + this->enc_closure( sp, this->enc_val_ref(this->field(fld.m_name)) ) + ) ) ); idx ++; } @@ -1778,7 +1786,7 @@ public: code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", vec$( NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, v.m_name), + NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, 0, CORETYPE_UINT), this->enc_closure(sp, this->get_val_ok(opts.core_name)) @@ -1792,7 +1800,7 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); + auto name_a = RcString::new_interned(FMT("a" << idx)); pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant_arg", vec$( @@ -1807,7 +1815,7 @@ public: code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", vec$( NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, v.m_name), + NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, e.m_sub_types.size(), CORETYPE_UINT), this->enc_closure(sp, NEWNODE(Block, mv$(nodes))) @@ -1816,19 +1824,19 @@ public: pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); ), (Struct, - ::std::vector< ::std::pair > pats_a; + ::std::vector< ::std::pair > pats_a; ::std::vector< AST::ExprNodeP > nodes; unsigned int idx = 0; for( const auto& fld : e.m_fields ) { - auto name_a = Ident( FMT("a" << fld.m_name) ); + auto name_a = Ident( RcString::new_interned(FMT("a" << fld.m_name)) ); pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, Ident(name_a), ::AST::PatternBinding::Type::REF)) ); nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_struct_variant_field", vec$( NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, fld.m_name), + NEWNODE(String, fld.m_name.c_str()), NEWNODE(Integer, idx, CORETYPE_UINT), this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a.name)))) ) @@ -1841,7 +1849,7 @@ public: code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_struct_variant", vec$( NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, v.m_name), + NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, e.m_fields.size(), CORETYPE_UINT), this->enc_closure(sp, NEWNODE(Block, mv$(nodes))) @@ -1862,7 +1870,7 @@ public: auto node_match = NEWNODE(Match, NEWNODE(NamedValue, AST::Path("self")), mv$(arms)); - const ::std::string& enum_name = type.m_data.as_Path().path.nodes().back().name(); + ::std::string enum_name = type.m_data.as_Path().path.nodes().back().name().c_str(); auto node = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum", vec$( NEWNODE(NamedValue, AST::Path("s")), NEWNODE(String, enum_name), this->enc_closure(sp, mv$(node_match)) ) ); @@ -1885,11 +1893,11 @@ class Deriver_RustcDecodable: return get_trait_path() + "decode"; } - AST::Impl make_ret(Span sp, const ::std::string& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const + AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { const AST::Path trait_path = this->get_trait_path(); - AST::Path result_path = AST::Path(core_name, { AST::PathNode("result", {}), AST::PathNode("Result", {}) }); + AST::Path result_path = AST::Path(core_name, { AST::PathNode(RcString::new_interned("result"), {}), AST::PathNode(RcString::new_interned("Result"), {}) }); result_path.nodes()[1].args().m_types.push_back( TypeRef(sp, "Self", 0xFFFF) ); result_path.nodes()[1].args().m_types.push_back( TypeRef(sp, AST::Path(AST::Path::TagUfcs(), TypeRef(sp, "D", 0x100|0), this->get_trait_path_Decoder(), { AST::PathNode("Error",{}) })) ); @@ -1920,7 +1928,7 @@ class Deriver_RustcDecodable: return NEWNODE(CallPath, this->get_method_path(), vec$( NEWNODE(NamedValue, AST::Path("d")) )); } AST::ExprNodeP field(const ::std::string& name) const { - return NEWNODE(Field, NEWNODE(NamedValue, AST::Path("self")), name); + return NEWNODE(Field, NEWNODE(NamedValue, AST::Path(RcString::new_interned("self"))), RcString::new_interned(name)); } AST::ExprNodeP dec_closure(Span sp, AST::ExprNodeP code) const { @@ -1929,8 +1937,8 @@ class Deriver_RustcDecodable: mv$(code), false ); } - AST::ExprNodeP get_val_err_str(const ::std::string& core_name, ::std::string err_str) const { - return NEWNODE(CallPath, AST::Path(core_name, {AST::PathNode("result",{}), AST::PathNode("Result",{}), AST::PathNode("Err",{})}), vec$( + AST::ExprNodeP get_val_err_str(const RcString& core_name, ::std::string err_str) const { + return NEWNODE(CallPath, get_path(core_name, "result", "Result", "Err"), vec$( NEWNODE(CallMethod, NEWNODE(NamedValue, AST::Path("d")), AST::PathNode("error"), @@ -1938,10 +1946,10 @@ class Deriver_RustcDecodable: ) ) ); } - AST::ExprNodeP get_val_ok(const ::std::string& core_name, AST::ExprNodeP inner) const { - return NEWNODE(CallPath, AST::Path(core_name, {AST::PathNode("result",{}), AST::PathNode("Result",{}), AST::PathNode("Ok",{})}), vec$( mv$(inner) ) ); + AST::ExprNodeP get_val_ok(const RcString& core_name, AST::ExprNodeP inner) const { + return NEWNODE(CallPath, get_path(core_name, "result", "Result", "Ok"), vec$( mv$(inner) ) ); } - AST::ExprNodeP get_val_ok_unit(const ::std::string& core_name) const { + AST::ExprNodeP get_val_ok_unit(const RcString& core_name) const { return get_val_ok(core_name, NEWNODE(Tuple, {})); } @@ -1951,7 +1959,7 @@ public: AST::Impl handle_item(Span sp, const DeriveOpts& opts, const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const override { AST::Path base_path = type.m_data.as_Path().path; - const ::std::string& struct_name = type.m_data.as_Path().path.nodes().back().name(); + ::std::string struct_name = type.m_data.as_Path().path.nodes().back().name().c_str(); AST::ExprNodeP node_v; TU_MATCH(AST::StructData, (str.m_data), (e), @@ -1964,7 +1972,7 @@ public: { vals.push_back({ {}, fld.m_name, NEWNODE(UniOp, ::AST::ExprNode_UniOp::QMARK, NEWNODE(CallPath, this->get_trait_path_Decoder() + "read_struct_field", - vec$( NEWNODE(NamedValue, AST::Path("d")), NEWNODE(String, fld.m_name), NEWNODE(Integer, idx, CORETYPE_UINT), this->dec_closure( sp, this->dec_val() ) ) + vec$( NEWNODE(NamedValue, AST::Path("d")), NEWNODE(String, fld.m_name.c_str()), NEWNODE(Integer, idx, CORETYPE_UINT), this->dec_closure( sp, this->dec_val() ) ) )) }); idx ++; } @@ -2053,7 +2061,7 @@ public: vals.push_back({ {}, fld.m_name, NEWNODE(UniOp, ::AST::ExprNode_UniOp::QMARK, NEWNODE(CallPath, this->get_trait_path_Decoder() + "read_enum_struct_variant_field", vec$( NEWNODE(NamedValue, AST::Path("d")), - NEWNODE(String, fld.m_name), + NEWNODE(String, fld.m_name.c_str()), NEWNODE(Integer, idx, CORETYPE_UINT), this->dec_closure(sp, this->dec_val()) ) @@ -2073,7 +2081,7 @@ public: nullptr, this->get_val_ok(opts.core_name, mv$(code)) )); - var_name_strs.push_back( NEWNODE(String, v.m_name) ); + var_name_strs.push_back( NEWNODE(String, v.m_name.c_str()) ); } // Default arm @@ -2095,7 +2103,7 @@ public: mv$(node_match), false ); - const ::std::string& enum_name = type.m_data.as_Path().path.nodes().back().name(); + ::std::string enum_name = type.m_data.as_Path().path.nodes().back().name().c_str(); auto node_rev = NEWNODE(CallPath, this->get_trait_path_Decoder() + "read_enum_variant", vec$( @@ -2117,7 +2125,7 @@ public: // -------------------------------------------------------------------- // Select and dispatch the correct derive() handler // -------------------------------------------------------------------- -static const Deriver* find_impl(const ::std::string& trait_name) +static const Deriver* find_impl(const RcString& trait_name) { #define _(obj) if(trait_name == obj.trait_name()) return &obj; _(g_derive_debug) @@ -2158,7 +2166,7 @@ static void derive_item(const Span& sp, const AST::Crate& crate, AST::Module& mo attr.items() }; - ::std::vector< ::std::string> missing_handlers; + ::std::vector< RcString> missing_handlers; for( const auto& trait : attr.items() ) { DEBUG("- " << trait.name()); @@ -2182,7 +2190,7 @@ static void derive_item(const Span& sp, const AST::Crate& crate, AST::Module& mo } else { // proc_macro - Invoke the handler. - auto lex = ProcMacro_Invoke(sp, crate, mac_path.path, path.nodes().back().name(), item); + auto lex = ProcMacro_Invoke(sp, crate, mac_path.path, path.nodes().back().name().c_str(), item); if( lex ) { Parse_ModRoot_Items(*lex, mod); diff --git a/src/expand/env.cpp b/src/expand/env.cpp index f4577ef1..825c895a 100644 --- a/src/expand/env.cpp +++ b/src/expand/env.cpp @@ -34,48 +34,44 @@ namespace { class CExpanderEnv: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "env! doesn't take an ident"); ::std::string varname = get_string(sp, crate, mod, tt); const char* var_val_cstr = getenv(varname.c_str()); if( !var_val_cstr ) { ERROR(sp, E0000, "Environment variable '" << varname << "' not defined"); } - return box$( TTStreamO(sp, TokenTree(Token(TOK_STRING, var_val_cstr))) ); + return box$( TTStreamO(sp, TokenTree(Token(TOK_STRING, ::std::string(var_val_cstr)))) ); } }; class CExpanderOptionEnv: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "option_env! doesn't take an ident"); ::std::string varname = get_string(sp, crate, mod, tt); const char* var_val_cstr = getenv(varname.c_str()); if( !var_val_cstr ) { ::std::vector< TokenTree> rv; rv.reserve(7); - rv.push_back( Token(TOK_IDENT, "None") ); + rv.push_back( Token(TOK_IDENT, RcString::new_interned("None")) ); rv.push_back( Token(TOK_DOUBLE_COLON) ); rv.push_back( Token(TOK_LT) ); rv.push_back( Token(TOK_AMP) ); - rv.push_back( Token(TOK_LIFETIME, "static") ); - rv.push_back( Token(TOK_IDENT, "str") ); + rv.push_back( Token(TOK_LIFETIME, RcString::new_interned("static")) ); + rv.push_back( Token(TOK_IDENT, RcString::new_interned("str")) ); rv.push_back( Token(TOK_GT) ); return box$( TTStreamO(sp, TokenTree( {}, mv$(rv) )) ); } else { ::std::vector< TokenTree> rv; rv.reserve(4); - rv.push_back( Token(TOK_IDENT, "Some") ); + rv.push_back( Token(TOK_IDENT, RcString::new_interned("Some")) ); rv.push_back( Token(TOK_PAREN_OPEN) ); - rv.push_back( Token(TOK_STRING, var_val_cstr) ); + rv.push_back( Token(TOK_STRING, ::std::string(var_val_cstr)) ); rv.push_back( Token(TOK_PAREN_CLOSE) ); return box$( TTStreamO(sp, TokenTree( {}, mv$(rv) )) ); } diff --git a/src/expand/file_line.cpp b/src/expand/file_line.cpp index 2bf85ffd..09d3e6b2 100644 --- a/src/expand/file_line.cpp +++ b/src/expand/file_line.cpp @@ -23,16 +23,16 @@ namespace { class CExpanderFile: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - return box$( TTStreamO(sp, TokenTree(Token(TOK_STRING, get_top_span(sp).filename.c_str()))) ); + return box$( TTStreamO(sp, TokenTree(Token(TOK_STRING, ::std::string(get_top_span(sp).filename.c_str())))) ); } }; class CExpanderLine: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { return box$( TTStreamO(sp, TokenTree(Token((uint64_t)get_top_span(sp).start_line, CORETYPE_U32))) ); } @@ -41,7 +41,7 @@ class CExpanderLine: class CExpanderColumn: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { return box$( TTStreamO(sp, TokenTree(Token((uint64_t)get_top_span(sp).start_ofs, CORETYPE_U32))) ); } @@ -49,7 +49,7 @@ class CExpanderColumn: class CExpanderUnstableColumn: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { return box$( TTStreamO(sp, TokenTree(Token((uint64_t)get_top_span(sp).start_ofs, CORETYPE_U32))) ); } @@ -58,13 +58,13 @@ class CExpanderUnstableColumn: class CExpanderModulePath: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { ::std::string path_str; for(const auto& comp : mod.path().nodes()) { if( &comp != &mod.path().nodes().front() ) path_str += "::"; - path_str += comp.name(); + path_str += comp.name().c_str(); } return box$( TTStreamO(sp, TokenTree( Token(TOK_STRING, mv$(path_str)) )) ); } diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index d79fd9d5..7f33eb6d 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -189,11 +189,11 @@ namespace { ::std::tuple< ::std::vector, ::std::string> parse_format_string( const Span& sp, const ::std::string& format_string, - const ::std::map< ::std::string,unsigned int>& named, + const ::std::map& named, unsigned int n_free ) { - unsigned int n_named = named.size(); + //unsigned int n_named = named.size(); unsigned int next_free = 0; ::std::vector frags; @@ -256,7 +256,7 @@ namespace { while( isalnum(*s) || *s == '_' || (*s < 0 || *s > 127) ) { s ++; } - ::std::string ident { start, s }; + auto ident = RcString(start, s - start); auto it = named.find(ident); if( it == named.end() ) ERROR(sp, E0000, "Named argument '"<& toks, const AST::Crate& crate, ::std::initializer_list il) { switch(crate.m_load_std) @@ -472,17 +475,17 @@ namespace { break; case ::AST::Crate::LOAD_CORE: toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_IDENT, "core") ); + toks.push_back( ident("core") ); break; case ::AST::Crate::LOAD_STD: toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_IDENT, "std") ); + toks.push_back( ident("std") ); break; } for(auto ent : il) { toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_IDENT, ent) ); + toks.push_back( ident(ent) ); } } void push_toks(::std::vector& toks, Token t1) { @@ -519,7 +522,7 @@ namespace { const auto& format_string_sp = format_string_np->span(); const auto& format_string = format_string_np->m_value; - ::std::map< ::std::string, unsigned int> named_args_index; + ::std::map named_args_index; ::std::vector named_args; ::std::vector free_args; @@ -535,7 +538,7 @@ namespace { if( lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_EQUAL ) { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_EQUAL); @@ -600,7 +603,7 @@ namespace { toks.push_back( TokenTree(TOK_PAREN_OPEN) ); for(unsigned int i = 0; i < free_args.size() + named_args.size(); i ++ ) { - toks.push_back( Token(TOK_IDENT, FMT("a" << i)) ); + toks.push_back( ident(FMT("a" << i).c_str()) ); toks.push_back( TokenTree(TOK_COMMA) ); } toks.push_back( TokenTree(TOK_PAREN_CLOSE) ); @@ -612,13 +615,13 @@ namespace { // - Contains N+1 entries, where N is the number of fragments { toks.push_back( TokenTree(TOK_RWORD_STATIC) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( ident("FRAGMENTS") ); toks.push_back( TokenTree(TOK_COLON) ); toks.push_back( TokenTree(TOK_SQUARE_OPEN) ); toks.push_back( Token(TOK_AMP) ); - toks.push_back( Token(TOK_LIFETIME, "static") ); - toks.push_back( Token(TOK_IDENT, "str") ); + toks.push_back( Token(TOK_LIFETIME, RcString::new_interned("static")) ); + toks.push_back( ident("str") ); toks.push_back( Token(TOK_SEMICOLON) ); toks.push_back( Token(static_cast(fragments.size() + 1), CORETYPE_UINT) ); toks.push_back( TokenTree(TOK_SQUARE_CLOSE) ); @@ -644,7 +647,7 @@ namespace { toks.push_back( TokenTree(TOK_PAREN_OPEN) ); { toks.push_back( TokenTree(TOK_AMP) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( ident("FRAGMENTS") ); toks.push_back( TokenTree(TOK_COMMA) ); toks.push_back( TokenTree(TOK_AMP) ); @@ -653,7 +656,7 @@ namespace { { push_path(toks, crate, {"fmt", "ArgumentV1", "new"}); toks.push_back( Token(TOK_PAREN_OPEN) ); - toks.push_back( Token(TOK_IDENT, FMT("a" << frag.arg_index)) ); + toks.push_back( ident( FMT("a" << frag.arg_index).c_str() ) ); toks.push_back( TokenTree(TOK_COMMA) ); @@ -678,7 +681,7 @@ namespace { toks.push_back( TokenTree(TOK_PAREN_OPEN) ); { toks.push_back( TokenTree(TOK_AMP) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( ident("FRAGMENTS") ); toks.push_back( TokenTree(TOK_COMMA) ); // TODO: Fragments to format @@ -689,7 +692,7 @@ namespace { { push_path(toks, crate, {"fmt", "ArgumentV1", "new"}); toks.push_back( Token(TOK_PAREN_OPEN) ); - toks.push_back( Token(TOK_IDENT, FMT("a" << frag.arg_index)) ); + toks.push_back( ident(FMT("a" << frag.arg_index).c_str()) ); toks.push_back( TokenTree(TOK_COMMA) ); @@ -707,17 +710,17 @@ namespace { push_path(toks, crate, {"fmt", "rt", "v1", "Argument"}); toks.push_back( TokenTree(TOK_BRACE_OPEN) ); - push_toks(toks, Token(TOK_IDENT, "position"), TOK_COLON ); + push_toks(toks, ident("position"), TOK_COLON ); push_path(toks, crate, {"fmt", "rt", "v1", "Position", "Next"}); push_toks(toks, TOK_COMMA); - push_toks(toks, Token(TOK_IDENT, "format"), TOK_COLON ); + push_toks(toks, ident("format"), TOK_COLON ); push_path(toks, crate, {"fmt", "rt", "v1", "FormatSpec"}); toks.push_back( TokenTree(TOK_BRACE_OPEN) ); { - push_toks(toks, Token(TOK_IDENT, "fill"), TOK_COLON, Token(uint64_t(frag.args.align_char), CORETYPE_CHAR), TOK_COMMA ); + push_toks(toks, ident("fill"), TOK_COLON, Token(uint64_t(frag.args.align_char), CORETYPE_CHAR), TOK_COMMA ); - push_toks(toks, Token(TOK_IDENT, "align"), TOK_COLON); + push_toks(toks, ident("align"), TOK_COLON); const char* align_var_name = nullptr; switch( frag.args.align ) { @@ -729,19 +732,19 @@ namespace { push_path(toks, crate, {"fmt", "rt", "v1", "Alignment", align_var_name}); push_toks(toks, TOK_COMMA); - push_toks(toks, Token(TOK_IDENT, "flags"), TOK_COLON); + push_toks(toks, ident("flags"), TOK_COLON); uint64_t flags = 0; if(frag.args.alternate) flags |= 1 << 2; push_toks(toks, Token(uint64_t(flags), CORETYPE_U32)); push_toks(toks, TOK_COMMA); - push_toks(toks, Token(TOK_IDENT, "precision"), TOK_COLON ); + push_toks(toks, ident("precision"), TOK_COLON ); if( frag.args.prec_is_arg || frag.args.prec != 0 ) { push_path(toks, crate, {"fmt", "rt", "v1", "Count", "Is"}); push_toks(toks, TOK_PAREN_OPEN); if( frag.args.prec_is_arg ) { - push_toks(toks, TOK_STAR, Token(TOK_IDENT, FMT("a" << frag.args.prec)) ); + push_toks(toks, TOK_STAR, ident(FMT("a" << frag.args.prec).c_str()) ); } else { push_toks(toks, Token(uint64_t(frag.args.prec), CORETYPE_UINT) ); @@ -753,12 +756,12 @@ namespace { } toks.push_back( TokenTree(TOK_COMMA) ); - push_toks(toks, Token(TOK_IDENT, "width"), TOK_COLON ); + push_toks(toks, ident("width"), TOK_COLON ); if( frag.args.width_is_arg || frag.args.width != 0 ) { push_path(toks, crate, {"fmt", "rt", "v1", "Count", "Is"}); push_toks(toks, TOK_PAREN_OPEN); if( frag.args.width_is_arg ) { - push_toks(toks, TOK_STAR, Token(TOK_IDENT, FMT("a" << frag.args.width)) ); + push_toks(toks, TOK_STAR, ident(FMT("a" << frag.args.width).c_str()) ); } else { push_toks(toks, Token(uint64_t(frag.args.width), CORETYPE_UINT) ); @@ -791,14 +794,12 @@ namespace { class CFormatArgsExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; auto lex = TTStream(sp, tt); lex.parse_state().module = &mod; - if( ident != "" ) - ERROR(sp, E0000, "format_args! doesn't take an ident"); return expand_format_args(sp, crate, lex, /*add_newline=*/false); } @@ -807,14 +808,12 @@ class CFormatArgsExpander: class CFormatArgsNlExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; auto lex = TTStream(sp, tt); lex.parse_state().module = &mod; - if( ident != "" ) - ERROR(sp, E0000, "format_args_nl! doesn't take an ident"); return expand_format_args(sp, crate, lex, /*add_newline=*/true); } diff --git a/src/expand/include.cpp b/src/expand/include.cpp index 8078d5d0..14a7bc7b 100644 --- a/src/expand/include.cpp +++ b/src/expand/include.cpp @@ -64,11 +64,8 @@ namespace { class CIncludeExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "include! doesn't take an ident"); - Token tok; auto lex = TTStream(sp, tt); @@ -91,11 +88,8 @@ class CIncludeExpander: class CIncludeBytesExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "include_bytes! doesn't take an ident"); - Token tok; auto lex = TTStream(sp, tt); @@ -121,11 +115,8 @@ class CIncludeBytesExpander: class CIncludeStrExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "include_str! doesn't take an ident"); - Token tok; auto lex = TTStream(sp, tt); diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 3bacfcf7..88b7fc88 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -21,11 +21,12 @@ class CMacroRulesExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override + { + ERROR(sp, E0000, "macro_rules! requires an identifier" ); + } + ::std::unique_ptr expand_ident(const Span& sp, const ::AST::Crate& crate, const RcString& ident, const TokenTree& tt, AST::Module& mod) override { - if( ident == "" ) - ERROR(sp, E0000, "macro_rules! requires an identifier" ); - DEBUG("Parsing macro_rules! " << ident); TTStream lex(sp, tt); auto mac = Parse_MacroRules(lex); @@ -48,7 +49,7 @@ class CMacroUseHandler: // Just ignore ) else TU_IFLET( ::AST::Item, i, Crate, ec_name, - const auto& ec = crate.m_extern_crates.at(ec_name.name); + const auto& ec = crate.m_extern_crates.at(ec_name.name.c_str()); if( mi.has_sub_items() ) { TODO(sp, "Named import from extern crate"); @@ -61,7 +62,7 @@ class CMacroUseHandler: }); for(const auto& p : ec.m_hir->m_proc_macros) { - mod.m_macro_imports.push_back({ false, p.path.m_components.back(), p.path.m_components, nullptr }); + mod.m_macro_imports.push_back(AST::Module::MacroImport{ false, p.path.m_components.back(), p.path.m_components, nullptr }); mod.m_macro_imports.back().path.insert( mod.m_macro_imports.back().path.begin(), p.path.m_crate_name ); } } @@ -153,7 +154,7 @@ class CMacroReexportHandler: } const auto& crate_name = i.as_Crate().name; - auto& ext_crate = *crate.m_extern_crates.at(crate_name).m_hir; + auto& ext_crate = *crate.m_extern_crates.at(crate_name.c_str()).m_hir; if( mi.has_sub_items() ) { diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index bc51e1ff..e3cef375 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -56,7 +56,7 @@ void ExpandDecorator::unexpected(const Span& sp, const AST::Attribute& mi, const void Expand_Attr(const Span& sp, const ::AST::Attribute& a, AttrStage stage, ::std::function f) { for( auto& d : g_decorators ) { - if( d.first == a.name() ) { + if( a.name() == d.first ) { DEBUG("#[" << d.first << "] " << (int)d.second->stage() << "-" << (int)stage); if( d.second->stage() == stage ) { f(sp, *d.second, a); @@ -94,7 +94,7 @@ void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& c ::std::unique_ptr Expand_Macro_Inner( const ::AST::Crate& crate, LList modstack, ::AST::Module& mod, - Span mi_span, const ::std::string& name, const ::std::string& input_ident, TokenTree& input_tt + Span mi_span, const RcString& name, const RcString& input_ident, TokenTree& input_tt ) { if( name == "" ) { @@ -105,7 +105,10 @@ void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& c { if( name == m.first ) { - auto e = m.second->expand(mi_span, crate, input_ident, input_tt, mod); + auto e = input_ident == "" + ? m.second->expand(mi_span, crate, input_tt, mod) + : m.second->expand_ident(mi_span, crate, input_ident, input_tt, mod) + ; return e; } } @@ -152,7 +155,7 @@ void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& c } ::std::unique_ptr Expand_Macro( const ::AST::Crate& crate, LList modstack, ::AST::Module& mod, - Span mi_span, const ::std::string& name, const ::std::string& input_ident, TokenTree& input_tt + Span mi_span, const RcString& name, const RcString& input_ident, TokenTree& input_tt ) { auto rv = Expand_Macro_Inner(crate, modstack, mod, mi_span, name, input_ident, input_tt); @@ -348,7 +351,7 @@ struct CExpandExpr: ::std::unique_ptr<::AST::ExprNode> replacement; // Stack of `try { ... }` blocks (the string is the loop label for the desugaring) - ::std::vector< ::std::string> m_try_stack; + ::std::vector m_try_stack; unsigned m_try_index = 0; AST::ExprNode_Block* current_block = nullptr; @@ -559,7 +562,7 @@ struct CExpandExpr: // } // ``` // NOTE: MIR lowering and HIR typecheck need to know to skip these (OR resolve should handle naming all loop blocks) - m_try_stack.push_back(FMT("#try" << m_try_index++)); + m_try_stack.push_back(RcString::new_interned(FMT("#try" << m_try_index++))); this->visit_nodelete(node, node.m_inner); auto loop_name = mv$(m_try_stack.back()); m_try_stack.pop_back(); @@ -858,7 +861,7 @@ struct CExpandExpr: nullptr, ::AST::ExprNodeP(new ::AST::ExprNode_Flow( (m_try_stack.empty() ? ::AST::ExprNode_Flow::RETURN : ::AST::ExprNode_Flow::BREAK), // NOTE: uses `break 'tryblock` instead of return if in a try block. - (m_try_stack.empty() ? "" : m_try_stack.back()), + (m_try_stack.empty() ? RcString("") : m_try_stack.back()), ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( ::AST::Path(path_Try_from_error), ::make_vec1( @@ -1415,7 +1418,7 @@ void Expand(::AST::Crate& crate) for( auto& a : crate.m_attrs.m_items ) { for( auto& d : g_decorators ) { - if( d.first == a.name() && d.second->stage() == AttrStage::Pre ) { + if( a.name() == d.first && d.second->stage() == AttrStage::Pre ) { //d.second->handle(a, crate, ::AST::Path(), crate.m_root_module, crate.m_root_module); } } diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp index f0f28f5a..24cd41d9 100644 --- a/src/expand/proc_macro.cpp +++ b/src/expand/proc_macro.cpp @@ -49,13 +49,13 @@ public: { if( attr.items()[i].name() == "attributes") { for(const auto& si : attr.items()[i].items()) { - attributes.push_back( si.name() ); + attributes.push_back( si.name().c_str() ); } } } // TODO: Store attributes for later use. - crate.m_proc_macros.push_back(AST::ProcMacroDef { FMT("derive#" << trait_name), path, mv$(attributes) }); + crate.m_proc_macros.push_back(AST::ProcMacroDef { RcString::new_interned(FMT("derive#" << trait_name)), path, mv$(attributes) }); } }; @@ -100,7 +100,7 @@ void Expand_ProcMacro(::AST::Crate& crate) { ::AST::ExprNode_StructLiteral::t_values desc_vals; // `name: "foo",` - desc_vals.push_back({ {}, "name", NEWNODE(_String, desc.name) }); + desc_vals.push_back({ {}, "name", NEWNODE(_String, desc.name.c_str()) }); // `handler`: ::foo desc_vals.push_back({ {}, "handler", NEWNODE(_NamedValue, AST::Path(desc.path)) }); @@ -211,7 +211,7 @@ public: void send_float(eCoreType ct, double v); //void send_fragment(); - bool attr_is_used(const ::std::string& n) const { + bool attr_is_used(const RcString& n) const { return ::std::find(m_proc_macro_desc.attributes.begin(), m_proc_macro_desc.attributes.end(), n) != m_proc_macro_desc.attributes.end(); } @@ -229,7 +229,7 @@ private: uint64_t recv_v128u(); }; -ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path) +ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path) { // 1. Locate macro in HIR list const auto& crate_name = mac_path.front(); @@ -745,7 +745,7 @@ namespace { } }; } -::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Struct& i) +::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& item_name, const ::AST::Struct& i) { // 1. Create ProcMacroInv instance auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path); @@ -757,7 +757,7 @@ namespace { // 3. Return boxed invocation instance return box$(pmi); } -::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Enum& i) +::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& item_name, const ::AST::Enum& i) { // 1. Create ProcMacroInv instance auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path); @@ -769,7 +769,7 @@ namespace { // 3. Return boxed invocation instance return box$(pmi); } -::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& item_name, const ::AST::Union& i) +::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& item_name, const ::AST::Union& i) { // 1. Create ProcMacroInv instance auto pmi = ProcMacro_Invoke_int(sp, crate, mac_path); diff --git a/src/expand/proc_macro.hpp b/src/expand/proc_macro.hpp index 8c5b71c7..e66bf037 100644 --- a/src/expand/proc_macro.hpp +++ b/src/expand/proc_macro.hpp @@ -8,8 +8,8 @@ #pragma once #include -extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& name, const ::AST::Struct& i); -extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& name, const ::AST::Enum& i); -extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const ::std::string& name, const ::AST::Union& i); -//extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const TokenStream& tt); +extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& name, const ::AST::Struct& i); +extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& name, const ::AST::Enum& i); +extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const ::std::string& name, const ::AST::Union& i); +//extern ::std::unique_ptr ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector& mac_path, const TokenStream& tt); diff --git a/src/expand/rustc_diagnostics.cpp b/src/expand/rustc_diagnostics.cpp index 0e95bb7c..b36bf586 100644 --- a/src/expand/rustc_diagnostics.cpp +++ b/src/expand/rustc_diagnostics.cpp @@ -13,7 +13,7 @@ class CExpanderRegisterDiagnostic: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { return box$( TTStreamO(sp, TokenTree()) ); } @@ -21,7 +21,7 @@ class CExpanderRegisterDiagnostic: class CExpanderDiagnosticUsed: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { return box$( TTStreamO(sp, TokenTree()) ); } @@ -29,10 +29,8 @@ class CExpanderDiagnosticUsed: class CExpanderBuildDiagnosticArray: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { - if( ident != "" ) - ERROR(sp, E0000, "__build_diagnostic_array! doesn't take an ident"); auto lex = TTStream(sp, tt); Token tok; @@ -41,7 +39,7 @@ class CExpanderBuildDiagnosticArray: //auto crate_name = mv$(tok.str()); GET_CHECK_TOK(tok, lex, TOK_COMMA); GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto item_name = mv$(tok.str()); + auto item_name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_EOF); ::std::vector toks; @@ -51,9 +49,9 @@ class CExpanderBuildDiagnosticArray: toks.push_back( TOK_COLON ); toks.push_back( TOK_SQUARE_OPEN ); toks.push_back( TOK_PAREN_OPEN ); - toks.push_back( TOK_AMP ); toks.push_back( Token(TOK_LIFETIME, "static") ); toks.push_back( Token(TOK_IDENT, "str") ); + toks.push_back( TOK_AMP ); toks.push_back( Token(TOK_LIFETIME, RcString::new_interned("static")) ); toks.push_back( Token(TOK_IDENT, RcString::new_interned("str")) ); toks.push_back( TOK_COMMA ); - toks.push_back( TOK_AMP ); toks.push_back( Token(TOK_LIFETIME, "static") ); toks.push_back( Token(TOK_IDENT, "str") ); + toks.push_back( TOK_AMP ); toks.push_back( Token(TOK_LIFETIME, RcString::new_interned("static")) ); toks.push_back( Token(TOK_IDENT, RcString::new_interned("str")) ); toks.push_back( TOK_PAREN_CLOSE ); toks.push_back( TOK_SEMICOLON ); toks.push_back( Token(static_cast(0), CORETYPE_UINT) ); diff --git a/src/expand/stringify.cpp b/src/expand/stringify.cpp index f552ffd4..561177ef 100644 --- a/src/expand/stringify.cpp +++ b/src/expand/stringify.cpp @@ -12,7 +12,7 @@ class CExpander: public ExpandProcMacro { - ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override { Token tok; ::std::string rv; diff --git a/src/expand/test.cpp b/src/expand/test.cpp index 9497c692..ac536228 100644 --- a/src/expand/test.cpp +++ b/src/expand/test.cpp @@ -25,7 +25,7 @@ class CTestHandler: for(const auto& node : path.nodes()) { td.name += "::"; - td.name += node.name(); + td.name += node.name().c_str(); } td.path = ::AST::Path(path); diff --git a/src/expand/test_harness.cpp b/src/expand/test_harness.cpp index f720cac7..36b60632 100644 --- a/src/expand/test_harness.cpp +++ b/src/expand/test_harness.cpp @@ -89,10 +89,10 @@ void Expand_TestHarness(::AST::Crate& crate) auto desc_expr = NEWNODE(_StructLiteral, ::AST::Path("test", { ::AST::PathNode("TestDesc")}), nullptr, mv$(desc_vals)); ::AST::ExprNode_StructLiteral::t_values descandfn_vals; - descandfn_vals.push_back({ {}, ::std::string("desc"), mv$(desc_expr) }); + descandfn_vals.push_back({ {}, RcString::new_interned("desc"), mv$(desc_expr) }); auto test_type_var_name = test.is_benchmark ? "StaticBenchFn" : "StaticTestFn"; - descandfn_vals.push_back({ {}, ::std::string("testfn"), NEWNODE(_CallPath, + descandfn_vals.push_back({ {}, RcString::new_interned("testfn"), NEWNODE(_CallPath, ::AST::Path("test", { ::AST::PathNode(test_type_var_name) }), ::make_vec1( NEWNODE(_NamedValue, AST::Path(test.path)) ) ) }); diff --git a/src/hir/crate_post_load.cpp b/src/hir/crate_post_load.cpp index 81c5b029..a0733987 100644 --- a/src/hir/crate_post_load.cpp +++ b/src/hir/crate_post_load.cpp @@ -9,7 +9,7 @@ #include // Used to update the crate name -void HIR::Crate::post_load_update(const ::std::string& name) +void HIR::Crate::post_load_update(const RcString& name) { // TODO: Do a pass across m_hir that // 1. Updates all absolute paths with the crate name diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index c5350b55..56671a04 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -22,13 +22,14 @@ class HirDeserialiser { - ::std::string m_crate_name; + RcString m_crate_name; ::HIR::serialise::Reader& m_in; public: HirDeserialiser(::HIR::serialise::Reader& in): m_in(in) {} + RcString read_istring() { return m_in.read_istring(); } ::std::string read_string() { return m_in.read_string(); } bool read_bool() { return m_in.read_bool(); } size_t deserialise_count() { return m_in.read_count(); } @@ -78,6 +79,51 @@ return rv; } + template + ::std::map< RcString,V> deserialise_istrmap() + { + TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); + size_t n = m_in.read_count(); + ::std::map< RcString, V> rv; + //rv.reserve(n); + for(size_t i = 0; i < n; i ++) + { + auto s = m_in.read_istring(); + rv.insert( ::std::make_pair( mv$(s), D::des(*this) ) ); + } + return rv; + } + template + ::std::unordered_map< RcString,V> deserialise_istrumap() + { + TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); + size_t n = m_in.read_count(); + ::std::unordered_map rv; + //rv.reserve(n); + for(size_t i = 0; i < n; i ++) + { + auto s = m_in.read_istring(); + DEBUG("- " << s); + rv.insert( ::std::make_pair( mv$(s), D::des(*this) ) ); + } + return rv; + } + template + ::std::unordered_multimap deserialise_istrummap() + { + TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); + size_t n = m_in.read_count(); + ::std::unordered_multimap rv; + //rv.reserve(n); + for(size_t i = 0; i < n; i ++) + { + auto s = m_in.read_istring(); + DEBUG("- " << s); + rv.insert( ::std::make_pair( mv$(s), D::des(*this) ) ); + } + return rv; + } + template ::std::vector deserialise_vec() { @@ -117,6 +163,7 @@ } + ::HIR::LifetimeDef deserialise_lifetimedef(); ::HIR::LifetimeRef deserialise_lifetimeref(); ::HIR::TypeRef deserialise_type(); ::HIR::SimplePath deserialise_simplepath(); @@ -137,7 +184,7 @@ { ::HIR::ProcMacro pm; TRACE_FUNCTION_FR("", "ProcMacro { " << pm.name << ", " << pm.path << ", [" << pm.attributes << "]}"); - pm.name = m_in.read_string(); + pm.name = m_in.read_istring(); pm.path = deserialise_simplepath(); pm.attributes = deserialise_vec< ::std::string>(); DEBUG("pm = ProcMacro { " << pm.name << ", " << pm.path << ", [" << pm.attributes << "]}"); @@ -155,7 +202,7 @@ size_t method_count = m_in.read_count(); for(size_t i = 0; i < method_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); rv.m_methods.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { deserialise_pub(), m_in.read_bool(), deserialise_function() } ) ); @@ -163,7 +210,7 @@ size_t const_count = m_in.read_count(); for(size_t i = 0; i < const_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); rv.m_constants.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> { deserialise_pub(), m_in.read_bool(), deserialise_constant() } ) ); @@ -184,7 +231,7 @@ size_t method_count = m_in.read_count(); for(size_t i = 0; i < method_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); auto is_spec = m_in.read_bool(); rv.m_methods.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { is_spec, deserialise_function() @@ -193,7 +240,7 @@ size_t const_count = m_in.read_count(); for(size_t i = 0; i < const_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); auto is_spec = m_in.read_bool(); rv.m_constants.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Constant> { is_spec, deserialise_constant() @@ -202,7 +249,7 @@ size_t static_count = m_in.read_count(); for(size_t i = 0; i < static_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); auto is_spec = m_in.read_bool(); rv.m_statics.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Static> { is_spec, deserialise_static() @@ -211,7 +258,7 @@ size_t type_count = m_in.read_count(); for(size_t i = 0; i < type_count; i ++) { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); auto is_spec = m_in.read_bool(); rv.m_types.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { is_spec, deserialise_type() @@ -240,10 +287,10 @@ // NOTE: This is set after loading. //rv.m_exported = true; rv.m_rules = deserialise_vec_c< ::MacroRulesArm>( [&](){ return deserialise_macrorulesarm(); }); - rv.m_source_crate = m_in.read_string(); + rv.m_source_crate = m_in.read_istring(); if(rv.m_source_crate == "") { - assert(!m_crate_name.empty()); + assert(m_crate_name != ""); rv.m_source_crate = m_crate_name; } return rv; @@ -288,7 +335,7 @@ } } ::MacroPatEnt deserialise_macropatent() { - auto s = m_in.read_string(); + auto s = m_in.read_istring(); auto n = static_cast(m_in.read_count()); auto type = static_cast< ::MacroPatEnt::Type>(m_in.read_tag()); ::MacroPatEnt rv { mv$(s), mv$(n), mv$(type) }; @@ -320,7 +367,7 @@ } ::MacroRulesArm deserialise_macrorulesarm() { ::MacroRulesArm rv; - rv.m_param_names = deserialise_vec< ::std::string>(); + rv.m_param_names = deserialise_vec(); rv.m_pattern = deserialise_vec_c< ::SimplePatEnt>( [&](){ return deserialise_simplepatent(); } ); rv.m_contents = deserialise_vec_c< ::MacroExpansionEnt>( [&](){ return deserialise_macroexpansionent(); } ); return rv; @@ -366,6 +413,8 @@ return ::Token::Data::make_None({}); case ::Token::Data::TAG_String: return ::Token::Data::make_String( m_in.read_string() ); + case ::Token::Data::TAG_IString: + return ::Token::Data::make_IString( m_in.read_istring() ); case ::Token::Data::TAG_Integer: { auto dty = static_cast(m_in.read_tag()); return ::Token::Data::make_Integer({ dty, m_in.read_u64c() }); @@ -723,7 +772,7 @@ { return ::HIR::AssociatedType { m_in.read_bool(), - "", // TODO: Better lifetime type + deserialise_lifetimeref(), deserialise_vec< ::HIR::TraitPath>(), deserialise_type() }; @@ -737,6 +786,9 @@ DEF_D( ::std::string, return d.read_string(); ); template<> + DEF_D( RcString, + return d.read_istring(); ); + template<> DEF_D( bool, return d.read_bool(); ); @@ -754,6 +806,8 @@ DEF_D( ::HIR::VisEnt, return d.deserialise_visent(); ) + template<> DEF_D( ::HIR::LifetimeDef, return d.deserialise_lifetimedef(); ) + template<> DEF_D( ::HIR::LifetimeRef, return d.deserialise_lifetimeref(); ) template<> DEF_D( ::HIR::TypeRef, return d.deserialise_type(); ) template<> DEF_D( ::HIR::SimplePath, return d.deserialise_simplepath(); ) template<> DEF_D( ::HIR::GenericPath, return d.deserialise_genericpath(); ) @@ -784,6 +838,12 @@ template<> DEF_D( ::HIR::ExternLibrary, return d.deserialise_extlib(); ) + ::HIR::LifetimeDef HirDeserialiser::deserialise_lifetimedef() + { + ::HIR::LifetimeDef rv; + rv.m_name = m_in.read_istring(); + return rv; + } ::HIR::LifetimeRef HirDeserialiser::deserialise_lifetimeref() { ::HIR::LifetimeRef rv; @@ -808,7 +868,7 @@ {} }) _(Generic, { - m_in.read_string(), + m_in.read_istring(), m_in.read_u16() }) _(TraitObject, { @@ -859,11 +919,11 @@ { TRACE_FUNCTION; // HACK! If the read crate name is empty, replace it with the name we're loaded with - auto crate_name = m_in.read_string(); - auto components = deserialise_vec< ::std::string>(); + auto crate_name = m_in.read_istring(); + auto components = deserialise_vec< RcString>(); if( crate_name == "" && components.size() > 0) { - assert(!m_crate_name.empty()); + assert(m_crate_name != ""); crate_name = m_crate_name; } return ::HIR::SimplePath { @@ -889,7 +949,7 @@ ::HIR::TraitPath HirDeserialiser::deserialise_traitpath() { auto gpath = deserialise_genericpath(); - auto tys = deserialise_strmap< ::HIR::TypeRef>(); + auto tys = deserialise_istrmap< ::HIR::TypeRef>(); return ::HIR::TraitPath { mv$(gpath), {}, mv$(tys) }; } ::HIR::Path HirDeserialiser::deserialise_path() @@ -904,7 +964,7 @@ DEBUG("Inherent"); return ::HIR::Path( ::HIR::Path::Data::Data_UfcsInherent { box$( deserialise_type() ), - m_in.read_string(), + m_in.read_istring(), deserialise_pathparams(), deserialise_pathparams() } ); @@ -913,7 +973,7 @@ return ::HIR::Path( ::HIR::Path::Data::Data_UfcsKnown { box$( deserialise_type() ), deserialise_genericpath(), - m_in.read_string(), + m_in.read_istring(), deserialise_pathparams() } ); default: @@ -926,7 +986,7 @@ TRACE_FUNCTION; ::HIR::GenericParams params; params.m_types = deserialise_vec< ::HIR::TypeParamDef>(); - params.m_lifetimes = deserialise_vec< ::std::string>(); + params.m_lifetimes = deserialise_vec< ::HIR::LifetimeDef>(); params.m_bounds = deserialise_vec< ::HIR::GenericBound>(); DEBUG("params = " << params.fmt_args() << ", " << params.fmt_bounds()); return params; @@ -934,7 +994,7 @@ ::HIR::TypeParamDef HirDeserialiser::deserialise_typaramdef() { auto rv = ::HIR::TypeParamDef { - m_in.read_string(), + m_in.read_istring(), deserialise_type(), m_in.read_bool() }; @@ -991,7 +1051,7 @@ } ::HIR::Enum::DataVariant HirDeserialiser::deserialise_enumdatavariant() { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); DEBUG("Enum::DataVariant " << name); return ::HIR::Enum::DataVariant { mv$(name), @@ -1001,7 +1061,7 @@ } ::HIR::Enum::ValueVariant HirDeserialiser::deserialise_enumvaluevariant() { - auto name = m_in.read_string(); + auto name = m_in.read_istring(); DEBUG("Enum::ValueVariant " << name); return ::HIR::Enum::ValueVariant { mv$(name), @@ -1014,7 +1074,7 @@ TRACE_FUNCTION; auto params = deserialise_genericparams(); auto repr = static_cast< ::HIR::Union::Repr>( m_in.read_tag() ); - auto variants = deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >(); + auto variants = deserialise_vec< ::std::pair< RcString, ::HIR::VisEnt< ::HIR::TypeRef> > >(); auto markings = deserialise_markings(); return ::HIR::Union { @@ -1041,7 +1101,7 @@ break; case ::HIR::Struct::Data::TAG_Named: DEBUG("Named"); - data = ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() ); + data = ::HIR::Struct::Data( deserialise_vec< ::std::pair< RcString, ::HIR::VisEnt< ::HIR::TypeRef> > >() ); break; default: BUG(Span(), "Bad tag for HIR::Struct::Data - " << tag); @@ -1061,15 +1121,16 @@ ::HIR::Trait rv { deserialise_genericparams(), - "", // TODO: Better type for lifetime + ::HIR::LifetimeRef(), // TODO: Better type for lifetime {} }; rv.m_is_marker = m_in.read_bool(); - rv.m_types = deserialise_strumap< ::HIR::AssociatedType>(); - rv.m_values = deserialise_strumap< ::HIR::TraitValueItem>(); - rv.m_value_indexes = deserialise_strummap< ::std::pair >(); - rv.m_type_indexes = deserialise_strumap< unsigned int>(); + rv.m_types = deserialise_istrumap< ::HIR::AssociatedType>(); + rv.m_values = deserialise_istrumap< ::HIR::TraitValueItem>(); + rv.m_value_indexes = deserialise_istrummap< ::std::pair >(); + rv.m_type_indexes = deserialise_istrumap< unsigned int>(); rv.m_all_parent_traits = deserialise_vec< ::HIR::TraitPath>(); + rv.m_vtable_path = deserialise_simplepath(); return rv; } @@ -1225,7 +1286,7 @@ _(Value, deserialise_mir_lvalue() ) _(Path, deserialise_path() ) _(Intrinsic, { - m_in.read_string(), + m_in.read_istring(), deserialise_pathparams() }) #undef _ @@ -1241,8 +1302,8 @@ ::HIR::Module rv; // m_traits doesn't need to be serialised - rv.m_value_items = deserialise_strumap< ::std::unique_ptr< ::HIR::VisEnt< ::HIR::ValueItem> > >(); - rv.m_mod_items = deserialise_strumap< ::std::unique_ptr< ::HIR::VisEnt< ::HIR::TypeItem> > >(); + rv.m_value_items = deserialise_istrumap< ::std::unique_ptr< ::HIR::VisEnt< ::HIR::ValueItem> > >(); + rv.m_mod_items = deserialise_istrumap< ::std::unique_ptr< ::HIR::VisEnt< ::HIR::TypeItem> > >(); return rv; } @@ -1256,8 +1317,8 @@ { ::HIR::Crate rv; - this->m_crate_name = m_in.read_string(); - assert(!this->m_crate_name.empty() && "Empty crate name loaded from metadata"); + this->m_crate_name = m_in.read_istring(); + assert(this->m_crate_name != "" && "Empty crate name loaded from metadata"); rv.m_crate_name = this->m_crate_name; rv.m_root_module = deserialise_module(); @@ -1280,14 +1341,14 @@ } } - rv.m_exported_macros = deserialise_strumap< ::MacroRulesPtr>(); + rv.m_exported_macros = deserialise_istrumap< ::MacroRulesPtr>(); rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>(); { size_t n = m_in.read_count(); for(size_t i = 0; i < n; i ++) { - auto ext_crate_name = m_in.read_string(); + auto ext_crate_name = m_in.read_istring(); auto ext_crate_file = m_in.read_string(); auto ext_crate = ::HIR::ExternCrate {}; ext_crate.m_basename = ext_crate_file; @@ -1304,7 +1365,7 @@ } //} -::HIR::CratePtr HIR_Deserialise(const ::std::string& filename, const ::std::string& loaded_name) +::HIR::CratePtr HIR_Deserialise(const ::std::string& filename) { try { diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 140ba817..d099ecb4 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -133,11 +133,11 @@ struct ExprNode_Return: struct ExprNode_Loop: public ExprNode { - ::std::string m_label; + RcString m_label; ::HIR::ExprNodeP m_code; bool m_diverges = false; - ExprNode_Loop(Span sp, ::std::string label, ::HIR::ExprNodeP code): + ExprNode_Loop(Span sp, RcString label, ::HIR::ExprNodeP code): //ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()), ExprNode(mv$(sp), ::HIR::TypeRef()), m_label( mv$(label) ), @@ -149,11 +149,11 @@ struct ExprNode_Loop: struct ExprNode_LoopControl: public ExprNode { - ::std::string m_label; + RcString m_label; bool m_continue; ::HIR::ExprNodeP m_value; - ExprNode_LoopControl(Span sp, ::std::string label, bool cont, ::HIR::ExprNodeP value={}): + ExprNode_LoopControl(Span sp, RcString label, bool cont, ::HIR::ExprNodeP value={}): ExprNode(mv$(sp), ::HIR::TypeRef::new_diverge()), m_label( mv$(label) ), m_continue( cont ), @@ -539,7 +539,7 @@ struct ExprNode_CallMethod: public ExprNode { ::HIR::ExprNodeP m_value; - ::std::string m_method; + RcString m_method; ::HIR::PathParams m_params; ::std::vector< ::HIR::ExprNodeP> m_args; @@ -553,7 +553,7 @@ struct ExprNode_CallMethod: // - A pool of ivars to use for searching for trait impls ::std::vector m_trait_param_ivars; - ExprNode_CallMethod(Span sp, ::HIR::ExprNodeP val, ::std::string method_name, ::HIR::PathParams params, ::std::vector< ::HIR::ExprNodeP> args): + ExprNode_CallMethod(Span sp, ::HIR::ExprNodeP val, RcString method_name, ::HIR::PathParams params, ::std::vector< ::HIR::ExprNodeP> args): ExprNode( mv$(sp) ), m_value( mv$(val) ), m_method( mv$(method_name) ), @@ -570,9 +570,9 @@ struct ExprNode_Field: public ExprNode { ::HIR::ExprNodeP m_value; - ::std::string m_field; + RcString m_field; - ExprNode_Field(Span sp, ::HIR::ExprNodeP val, ::std::string field): + ExprNode_Field(Span sp, ::HIR::ExprNodeP val, RcString field): ExprNode(mv$(sp)), m_value( mv$(val) ), m_field( mv$(field) ) @@ -677,10 +677,10 @@ struct ExprNode_PathValue: struct ExprNode_Variable: public ExprNode { - ::std::string m_name; + RcString m_name; unsigned int m_slot; - ExprNode_Variable(Span sp, ::std::string name, unsigned int slot): + ExprNode_Variable(Span sp, RcString name, unsigned int slot): ExprNode(mv$(sp)), m_name( mv$(name) ), m_slot( slot ) @@ -692,7 +692,7 @@ struct ExprNode_Variable: struct ExprNode_StructLiteral: public ExprNode { - typedef ::std::vector< ::std::pair< ::std::string, ExprNodeP > > t_values; + typedef ::std::vector< ::std::pair< RcString, ExprNodeP > > t_values; ::HIR::Path m_path; bool m_is_struct; @@ -719,12 +719,12 @@ struct ExprNode_UnionLiteral: public ExprNode { ::HIR::GenericPath m_path; - ::std::string m_variant_name; + RcString m_variant_name; ::HIR::ExprNodeP m_value; unsigned int m_variant_index = ~0; - ExprNode_UnionLiteral(Span sp, ::HIR::GenericPath path, ::std::string name, ::HIR::ExprNodeP value): + ExprNode_UnionLiteral(Span sp, ::HIR::GenericPath path, RcString name, ::HIR::ExprNodeP value): ExprNode( mv$(sp) ), m_path( mv$(path) ), m_variant_name( mv$(name) ), diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 2393cadd..84980818 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -23,15 +23,18 @@ ::HIR::TraitPath LowerHIR_TraitPath(const Span& sp, const ::AST::Path& path); ::HIR::SimplePath path_Sized; -::std::string g_core_crate; -::std::string g_crate_name; +RcString g_core_crate; +RcString g_crate_name; ::HIR::Crate* g_crate_ptr = nullptr; const ::AST::Crate* g_ast_crate_ptr; // -------------------------------------------------------------------- -::std::string LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) +HIR::LifetimeRef LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) { - return r.name().name; + return HIR::LifetimeRef { + // TODO: names? + r.binding() + }; } ::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp, bool* self_is_sized) @@ -48,7 +51,7 @@ const ::AST::Crate* g_ast_crate_ptr; if( gp.lft_params().size() > 0 ) { for(const auto& lft_def : gp.lft_params()) - rv.m_lifetimes.push_back( lft_def.name().name ); + rv.m_lifetimes.push_back( HIR::LifetimeDef { lft_def.name().name } ); } if( gp.bounds().size() > 0 ) { @@ -316,7 +319,7 @@ const ::AST::Crate* g_ast_crate_ptr; } } TU_ARMA(Struct, e) { - ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > sub_patterns; + ::std::vector< ::std::pair< RcString, ::HIR::Pattern> > sub_patterns; for(const auto& sp : e.sub_patterns) sub_patterns.push_back( ::std::make_pair(sp.first, LowerHIR_Pattern(sp.second)) ); @@ -968,7 +971,7 @@ namespace { return rv; } -::HIR::Enum LowerHIR_Enum(::HIR::ItemPath path, const ::AST::Enum& ent, const ::AST::AttributeList& attrs, ::std::function push_struct) +::HIR::Enum LowerHIR_Enum(::HIR::ItemPath path, const ::AST::Enum& ent, const ::AST::AttributeList& attrs, ::std::function push_struct) { // 1. Figure out what sort of enum this is (value or data) bool has_value = false; @@ -1081,7 +1084,7 @@ namespace { throw ""; } - auto ty_name = FMT(path.name << "#" << var.m_name); + auto ty_name = RcString::new_interned(FMT(path.name << "#" << var.m_name)); push_struct( ty_name, ::HIR::Struct { @@ -1156,14 +1159,14 @@ namespace { bool trait_reqires_sized = false; auto params = LowerHIR_GenericParams(f.params(), &trait_reqires_sized); - ::std::string lifetime; + ::HIR::LifetimeRef lifetime; ::std::vector< ::HIR::TraitPath> supertraits; for(const auto& st : f.supertraits()) { if( st.ent.path.is_valid() ) { supertraits.push_back( LowerHIR_TraitPath(st.sp, st.ent.path) ); } else { - lifetime = "static"; + lifetime = ::HIR::LifetimeRef::new_static(); } } ::HIR::Trait rv { @@ -1201,7 +1204,7 @@ namespace { (Type, bool is_sized = true; ::std::vector< ::HIR::TraitPath> trait_bounds; - ::std::string lifetime_bound; + ::HIR::LifetimeRef lifetime_bound; auto gps = LowerHIR_GenericParams(i.params(), &is_sized); for(auto& b : gps.m_bounds) @@ -1385,10 +1388,10 @@ namespace { }; } -void _add_mod_ns_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity is_pub, ::HIR::TypeItem ti) { +void _add_mod_ns_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pub, ::HIR::TypeItem ti) { mod.m_mod_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::TypeItem> { is_pub, mv$(ti) }) ) ); } -void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity is_pub, ::HIR::ValueItem ti) { +void _add_mod_val_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pub, ::HIR::ValueItem ti) { mod.m_value_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::ValueItem> { is_pub, mv$(ti) }) ) ); } @@ -1418,7 +1421,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity if( submod_ptr ) { auto& submod = *submod_ptr; - ::std::string name = FMT("#" << i); + auto name = RcString::new_interned(FMT("#" << i)); auto item_path = ::HIR::ItemPath(path, name.c_str()); auto ti = ::HIR::TypeItem::make_Module( LowerHIR_Module(submod, item_path, mod.m_traits) ); _add_mod_ns_item( mod, mv$(name), get_pub(false), mv$(ti) ); @@ -1534,7 +1537,7 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity // If there's no code, demangle the name (TODO: By ABI) and set linkage. if( linkage.name == "" && ! e.value().is_valid() ) { - linkage.name = item.name; + linkage.name = item.name.c_str(); } _add_mod_val_item(mod, item.name, get_pub(item.is_pub), ::HIR::ValueItem::make_Static(::HIR::Static { @@ -1633,9 +1636,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ::HIR::ItemPath path(type, trait_name, trait_args); DEBUG(path); - ::std::map< ::std::string, ::HIR::TraitImpl::ImplEnt< ::HIR::Function> > methods; - ::std::map< ::std::string, ::HIR::TraitImpl::ImplEnt< ::HIR::Constant> > constants; - ::std::map< ::std::string, ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> > types; + ::std::map< RcString, ::HIR::TraitImpl::ImplEnt< ::HIR::Function> > methods; + ::std::map< RcString, ::HIR::TraitImpl::ImplEnt< ::HIR::Constant> > constants; + ::std::map< RcString, ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> > types; for(const auto& item : impl.items()) { @@ -1711,8 +1714,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto priv_path = ::HIR::Publicity::new_priv( LowerHIR_SimplePath(Span(), ast_mod.path()) ); // TODO: Does this need to consume anon modules? auto get_pub = [&](bool is_pub){ return is_pub ? ::HIR::Publicity::new_global() : priv_path; }; - ::std::map< ::std::string, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> > methods; - ::std::map< ::std::string, ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> > constants; + ::std::map< RcString, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> > methods; + ::std::map< RcString, ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> > constants; for(const auto& item : impl.items()) { @@ -1809,18 +1812,20 @@ public: if(crate.m_crate_type != ::AST::Crate::Type::Executable) { - rv.m_crate_name = crate.m_crate_name; if(crate.m_crate_name_suffix != "") { - rv.m_crate_name += "-"; - rv.m_crate_name += crate.m_crate_name_suffix; + rv.m_crate_name = RcString::new_interned(FMT(crate.m_crate_name + "-" + crate.m_crate_name_suffix)); + } + else + { + rv.m_crate_name = RcString::new_interned(crate.m_crate_name); } } g_crate_ptr = &rv; g_ast_crate_ptr = &crate; g_crate_name = rv.m_crate_name; - g_core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? rv.m_crate_name : "core"); + g_core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? rv.m_crate_name : RcString::new_interned("core")); auto& macros = rv.m_exported_macros; // - Extract exported macros @@ -1896,7 +1901,7 @@ public: for(const auto& ent : crate.m_proc_macros) { // Register under an invalid simplepath - rv.m_proc_macros.push_back( ::HIR::ProcMacro { ent.name, ::HIR::SimplePath("", { ent.name}), ent.attributes } ); + rv.m_proc_macros.push_back( ::HIR::ProcMacro { ent.name, ::HIR::SimplePath(RcString(""), { ent.name }), ent.attributes } ); } } else diff --git a/src/hir/from_ast.hpp b/src/hir/from_ast.hpp index 4625f479..3eeaaa48 100644 --- a/src/hir/from_ast.hpp +++ b/src/hir/from_ast.hpp @@ -16,5 +16,5 @@ extern ::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Pat extern ::HIR::TypeRef LowerHIR_Type(const ::TypeRef& ty); extern ::HIR::Pattern LowerHIR_Pattern(const ::AST::Pattern& pat); -extern ::std::string g_core_crate; +extern RcString g_core_crate; extern ::HIR::Crate* g_crate_ptr; diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index fdb2b867..baca8d75 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -332,16 +332,16 @@ struct LowerHIR_ExprNode_Visitor: break; } - // TODO: Iterate the constructed loop and determine if there are any `break` statements pointing to it + // Iterate the constructed loop and determine if there are any `break` statements pointing to it { struct LoopVisitor: public ::HIR::ExprVisitorDef { - const ::std::string& top_label; + const RcString& top_label; bool top_is_broken; - ::std::vector< const ::std::string*> name_stack; + ::std::vector< const RcString*> name_stack; - LoopVisitor(const ::std::string& top_label): + LoopVisitor(const RcString& top_label): top_label(top_label), top_is_broken(false), name_stack() diff --git a/src/hir/generic_params.cpp b/src/hir/generic_params.cpp index 381277fc..3f6559a7 100644 --- a/src/hir/generic_params.cpp +++ b/src/hir/generic_params.cpp @@ -33,7 +33,7 @@ namespace HIR { { os << "<"; for(const auto& lft : x.gp.m_lifetimes) { - os << "'" << lft << ","; + os << "'" << lft.m_name << ","; } for(const auto& typ : x.gp.m_types) { os << typ.m_name; diff --git a/src/hir/generic_params.hpp b/src/hir/generic_params.hpp index ef83bda7..afa1c682 100644 --- a/src/hir/generic_params.hpp +++ b/src/hir/generic_params.hpp @@ -15,19 +15,23 @@ namespace HIR { struct TypeParamDef { - ::std::string m_name; + RcString m_name; ::HIR::TypeRef m_default; bool m_is_sized; }; +struct LifetimeDef +{ + RcString m_name; +}; TAGGED_UNION(GenericBound, Lifetime, (Lifetime, struct { - ::std::string test; - ::std::string valid_for; + LifetimeRef test; + LifetimeRef valid_for; }), (TypeLifetime, struct { ::HIR::TypeRef type; - ::std::string valid_for; + LifetimeRef valid_for; }), (TraitBound, struct { ::HIR::TypeRef type; @@ -47,8 +51,8 @@ extern ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x); class GenericParams { public: - ::std::vector m_types; - ::std::vector< ::std::string> m_lifetimes; + ::std::vector m_types; + ::std::vector m_lifetimes; ::std::vector m_bounds; diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 2a8ac8bf..88b1cb8c 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -149,7 +149,7 @@ bool HIR::Publicity::is_visible(const ::HIR::SimplePath& p) const return true; } -size_t HIR::Enum::find_variant(const ::std::string& name) const +size_t HIR::Enum::find_variant(const RcString& name) const { if( m_data.is_Value() ) { diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index cc66a9e7..3f045dd2 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -192,7 +192,7 @@ struct TypeAlias }; typedef ::std::vector< VisEnt<::HIR::TypeRef> > t_tuple_fields; -typedef ::std::vector< ::std::pair< ::std::string, VisEnt<::HIR::TypeRef> > > t_struct_fields; +typedef ::std::vector< ::std::pair< RcString, VisEnt<::HIR::TypeRef> > > t_struct_fields; /// Cache of the state of various language traits on an enum/struct struct TraitMarkings @@ -258,7 +258,7 @@ class Enum { public: struct DataVariant { - ::std::string name; + RcString name; bool is_struct; // Indicates that the variant does not show up in the value namespace ::HIR::TypeRef type; }; @@ -269,7 +269,7 @@ public: Usize, U8, U16, U32, U64, }; struct ValueVariant { - ::std::string name; + RcString name; ::HIR::ExprPtr expr; // TODO: Signed. uint64_t val; @@ -290,7 +290,7 @@ public: size_t num_variants() const { return (m_data.is_Data() ? m_data.as_Data().size() : m_data.as_Value().variants.size()); } - size_t find_variant(const ::std::string& ) const; + size_t find_variant(const RcString& ) const; /// Returns true if this enum is a C-like enum (has values only) bool is_value() const; @@ -343,7 +343,7 @@ public: struct AssociatedType { bool is_sized; - ::std::string m_lifetime_bound; + LifetimeRef m_lifetime_bound; ::std::vector< ::HIR::TraitPath> m_trait_bounds; ::HIR::TypeRef m_default; }; @@ -356,23 +356,25 @@ class Trait { public: GenericParams m_params; - ::std::string m_lifetime; + LifetimeRef m_lifetime; ::std::vector< ::HIR::TraitPath > m_parent_traits; bool m_is_marker; // aka OIBIT - ::std::unordered_map< ::std::string, AssociatedType > m_types; - ::std::unordered_map< ::std::string, TraitValueItem > m_values; + ::std::unordered_map< RcString, AssociatedType > m_types; + ::std::unordered_map< RcString, TraitValueItem > m_values; // Indexes into the vtable for each present method and value - ::std::unordered_multimap< ::std::string, ::std::pair > m_value_indexes; + ::std::unordered_multimap< RcString, ::std::pair > m_value_indexes; // Indexes in the vtable parameter list for each associated type - ::std::unordered_map< ::std::string, unsigned int > m_type_indexes; + ::std::unordered_map< RcString, unsigned int > m_type_indexes; // Flattend set of parent traits (monomorphised and associated types fixed) ::std::vector< ::HIR::TraitPath > m_all_parent_traits; + // VTable path + ::HIR::SimplePath m_vtable_path; - Trait( GenericParams gps, ::std::string lifetime, ::std::vector< ::HIR::TraitPath> parents): + Trait( GenericParams gps, LifetimeRef lifetime, ::std::vector< ::HIR::TraitPath> parents): m_params( mv$(gps) ), m_lifetime( mv$(lifetime) ), m_parent_traits( mv$(parents) ), @@ -387,11 +389,11 @@ public: ::std::vector< ::HIR::SimplePath> m_traits; // Contains all values and functions (including type constructors) - ::std::unordered_map< ::std::string, ::std::unique_ptr> > m_value_items; + ::std::unordered_map< RcString, ::std::unique_ptr> > m_value_items; // Contains types, traits, and modules - ::std::unordered_map< ::std::string, ::std::unique_ptr> > m_mod_items; + ::std::unordered_map< RcString, ::std::unique_ptr> > m_mod_items; - ::std::vector< ::std::pair<::std::string, Static> > m_inline_statics; + ::std::vector< ::std::pair > m_inline_statics; Module() {} Module(const Module&) = delete; @@ -436,8 +438,8 @@ public: ::HIR::GenericParams m_params; ::HIR::TypeRef m_type; - ::std::map< ::std::string, VisImplEnt< ::HIR::Function> > m_methods; - ::std::map< ::std::string, VisImplEnt< ::HIR::Constant> > m_constants; + ::std::map< RcString, VisImplEnt< ::HIR::Function> > m_methods; + ::std::map< RcString, VisImplEnt< ::HIR::Constant> > m_constants; ::HIR::SimplePath m_src_module; @@ -460,11 +462,11 @@ public: ::HIR::PathParams m_trait_args; ::HIR::TypeRef m_type; - ::std::map< ::std::string, ImplEnt< ::HIR::Function> > m_methods; - ::std::map< ::std::string, ImplEnt< ::HIR::Constant> > m_constants; - ::std::map< ::std::string, ImplEnt< ::HIR::Static> > m_statics; + ::std::map< RcString, ImplEnt< ::HIR::Function> > m_methods; + ::std::map< RcString, ImplEnt< ::HIR::Constant> > m_constants; + ::std::map< RcString, ImplEnt< ::HIR::Static> > m_statics; - ::std::map< ::std::string, ImplEnt< ::HIR::TypeRef> > m_types; + ::std::map< RcString, ImplEnt< ::HIR::TypeRef> > m_types; ::HIR::SimplePath m_src_module; @@ -512,7 +514,7 @@ class ProcMacro { public: // Name of the macro - ::std::string name; + RcString name; // Path to the handler ::HIR::SimplePath path; // A list of attributes to hand to the handler @@ -521,7 +523,7 @@ public: class Crate { public: - ::std::string m_crate_name; + RcString m_crate_name; Module m_root_module; @@ -532,7 +534,7 @@ public: ::std::multimap< ::HIR::SimplePath, ::HIR::MarkerImpl > m_marker_impls; /// Macros exported by this crate - ::std::unordered_map< ::std::string, ::MacroRulesPtr > m_exported_macros; + ::std::unordered_map< RcString, ::MacroRulesPtr > m_exported_macros; /// Procedural macros presented ::std::vector< ::HIR::ProcMacro> m_proc_macros; @@ -540,7 +542,7 @@ public: ::std::unordered_map< ::std::string, ::HIR::SimplePath> m_lang_items; /// Referenced crates - ::std::unordered_map< ::std::string, ExternCrate> m_ext_crates; + ::std::unordered_map< RcString, ExternCrate> m_ext_crates; /// Referenced system libraries ::std::vector m_ext_libs; /// Extra paths for the linker @@ -548,7 +550,7 @@ public: /// Method called to populate runtime state after deserialisation /// See hir/crate_post_load.cpp - void post_load_update(const ::std::string& loaded_name); + void post_load_update(const RcString& loaded_name); const ::HIR::SimplePath& get_lang_item_path(const Span& sp, const char* name) const; const ::HIR::SimplePath& get_lang_item_path_opt(const char* name) const; diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index 89e48c80..32c70a72 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -825,6 +825,7 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& static Span sp; for(const auto& tb : id.m_params.m_bounds) { + DEBUG(tb); if(tb.is_TraitBound()) { ::HIR::TypeRef tmp_ty; @@ -851,7 +852,7 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& } } else if( TU_TEST1(ty.m_data, Path, .binding.is_Opaque()) ) { - TODO(Span(), "Check bound " << ty << " : " << trait << " in source bounds or trait bounds"); + TODO(sp, "Check bound " << ty << " : " << trait << " in source bounds or trait bounds"); } else { // Search the crate for an impl @@ -889,9 +890,14 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& // 4. Check ATY bounds on the trait path for(const auto& atyb : trait.m_type_bounds) { - const auto& aty = ti.m_types.at(atyb.first); - if( !aty.data.match_test_generics(sp, atyb.second, cb_ident, cb_match) ) - return false; + if( ti.m_types.count(atyb.first) == 0 ) { + DEBUG("Associated type '" << atyb.first << "' not in trait impl, assuming good"); + } + else { + const auto& aty = ti.m_types.at(atyb.first); + if( !aty.data.match_test_generics(sp, atyb.second, cb_ident, cb_match) ) + return false; + } } // All those pass? It's good. return true; diff --git a/src/hir/item_path.hpp b/src/hir/item_path.hpp index d93df9e8..290bf23b 100644 --- a/src/hir/item_path.hpp +++ b/src/hir/item_path.hpp @@ -54,12 +54,12 @@ public: } else if( parent ) { assert(name); - return parent->get_simple_path() + name; + return parent->get_simple_path() + RcString::new_interned(name); } else { assert(!name); assert(crate_name); - return ::HIR::SimplePath(crate_name); + return ::HIR::SimplePath(RcString::new_interned(crate_name)); } } ::HIR::Path get_full_path() const { @@ -76,11 +76,11 @@ public: else if( parent->trait ) { assert(parent->ty); assert(parent->trait_params); - return ::HIR::Path( parent->ty->clone(), ::HIR::GenericPath(parent->trait->clone(), parent->trait_params->clone()), ::std::string(name) ); + return ::HIR::Path( parent->ty->clone(), ::HIR::GenericPath(parent->trait->clone(), parent->trait_params->clone()), RcString::new_interned(name) ); } else { assert(parent->ty); - return ::HIR::Path( parent->ty->clone(), ::std::string(name) ); + return ::HIR::Path( parent->ty->clone(), RcString::new_interned(name) ); } } const char* get_name() const { @@ -95,6 +95,9 @@ public: ItemPath operator+(const ::std::string& name) const { return ItemPath(*this, name.c_str()); } + ItemPath operator+(const RcString& name) const { + return ItemPath(*this, name.c_str()); + } bool operator==(const ::HIR::SimplePath& sp) const { if( sp.m_crate_name != "" ) return false; diff --git a/src/hir/main_bindings.hpp b/src/hir/main_bindings.hpp index 622d8e2e..89896df0 100644 --- a/src/hir/main_bindings.hpp +++ b/src/hir/main_bindings.hpp @@ -18,4 +18,4 @@ namespace AST { extern void HIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate); extern ::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate); extern void HIR_Serialise(const ::std::string& filename, const ::HIR::Crate& crate); -extern ::HIR::CratePtr HIR_Deserialise(const ::std::string& filename, const ::std::string& loaded_name); +extern ::HIR::CratePtr HIR_Deserialise(const ::std::string& filename); diff --git a/src/hir/path.cpp b/src/hir/path.cpp index e6dab41f..a867c245 100644 --- a/src/hir/path.cpp +++ b/src/hir/path.cpp @@ -8,7 +8,7 @@ #include #include -::HIR::SimplePath HIR::SimplePath::operator+(const ::std::string& s) const +::HIR::SimplePath HIR::SimplePath::operator+(const RcString& s) const { ::HIR::SimplePath ret(m_crate_name); ret.m_components = m_components; @@ -193,11 +193,11 @@ bool ::HIR::TraitPath::operator==(const ::HIR::TraitPath& x) const m_data( ::HIR::Path::Data::make_Generic(::HIR::GenericPath(mv$(sp))) ) { } -::HIR::Path::Path(TypeRef ty, ::std::string item, PathParams item_params): +::HIR::Path::Path(TypeRef ty, RcString item, PathParams item_params): m_data(Data::make_UfcsInherent({ box$(ty), mv$(item), mv$(item_params) })) { } -::HIR::Path::Path(TypeRef ty, GenericPath trait, ::std::string item, PathParams item_params): +::HIR::Path::Path(TypeRef ty, GenericPath trait, RcString item, PathParams item_params): m_data( Data::make_UfcsKnown({ box$(mv$(ty)), mv$(trait), mv$(item), mv$(item_params) }) ) { } diff --git a/src/hir/path.hpp b/src/hir/path.hpp index f2bec6ee..86fe725e 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -25,7 +25,7 @@ enum Compare { }; typedef ::std::function t_cb_resolve_type; -typedef ::std::function< ::HIR::Compare(unsigned int, const ::std::string&, const ::HIR::TypeRef&) > t_cb_match_generics; +typedef ::std::function< ::HIR::Compare(unsigned int, const RcString&, const ::HIR::TypeRef&) > t_cb_match_generics; static inline ::std::ostream& operator<<(::std::ostream& os, const Compare& x) { switch(x) @@ -54,18 +54,18 @@ static inline Compare& operator &=(Compare& x, const Compare& y) { /// Simple path - Absolute with no generic parameters struct SimplePath { - ::std::string m_crate_name; - ::std::vector< ::std::string> m_components; + RcString m_crate_name; + ::std::vector< RcString> m_components; SimplePath(): m_crate_name("") { } - SimplePath(::std::string crate): + SimplePath(RcString crate): m_crate_name( mv$(crate) ) { } - SimplePath(::std::string crate, ::std::vector< ::std::string> components): + SimplePath(RcString crate, ::std::vector< RcString> components): m_crate_name( mv$(crate) ), m_components( mv$(components) ) { @@ -73,7 +73,7 @@ struct SimplePath SimplePath clone() const; - SimplePath operator+(const ::std::string& s) const; + SimplePath operator+(const RcString& s) const; bool operator==(const SimplePath& x) const { return m_crate_name == x.m_crate_name && m_components == x.m_components; } @@ -158,9 +158,9 @@ class TraitPath { public: GenericPath m_path; - ::std::vector< ::std::string> m_hrls; + ::std::vector< RcString> m_hrls; // TODO: Each bound should list its origin trait - ::std::map< ::std::string, ::HIR::TypeRef> m_type_bounds; + ::std::map< RcString, ::HIR::TypeRef> m_type_bounds; const ::HIR::Trait* m_trait_ptr; @@ -190,20 +190,20 @@ public: (Generic, GenericPath), (UfcsInherent, struct { ::std::unique_ptr type; - ::std::string item; + RcString item; PathParams params; PathParams impl_params; }), (UfcsKnown, struct { ::std::unique_ptr type; GenericPath trait; - ::std::string item; + RcString item; PathParams params; }), (UfcsUnknown, struct { ::std::unique_ptr type; //GenericPath ??; - ::std::string item; + RcString item; PathParams params; }) ); @@ -216,8 +216,8 @@ public: Path(GenericPath _); Path(SimplePath _); - Path(TypeRef ty, ::std::string item, PathParams item_params=PathParams()); - Path(TypeRef ty, GenericPath trait, ::std::string item, PathParams item_params=PathParams()); + Path(TypeRef ty, RcString item, PathParams item_params=PathParams()); + Path(TypeRef ty, GenericPath trait, RcString item, PathParams item_params=PathParams()); Path clone() const; Compare compare_with_placeholders(const Span& sp, const Path& x, t_cb_resolve_type resolve_placeholder) const; diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp index d25b25e7..063ed1b3 100644 --- a/src/hir/pattern.cpp +++ b/src/hir/pattern.cpp @@ -154,8 +154,9 @@ namespace { rv.push_back( pat.clone() ); return rv; } - ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > clone_pat_fields(const ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> >& pats) { - ::std::vector< ::std::pair< ::std::string, ::HIR::Pattern> > rv; + typedef ::std::vector< ::std::pair< RcString, ::HIR::Pattern> > pat_fields_t; + pat_fields_t clone_pat_fields(const pat_fields_t& pats) { + pat_fields_t rv; rv.reserve( pats.size() ); for(const auto& field : pats) rv.push_back( ::std::make_pair(field.first, field.second.clone()) ); diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index d16fd942..136bd587 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -29,7 +29,7 @@ struct PatternBinding bool m_mutable; Type m_type; - ::std::string m_name; + RcString m_name; unsigned int m_slot; unsigned m_implicit_deref_count = 0; @@ -43,7 +43,7 @@ struct PatternBinding m_slot(0), m_implicit_deref_count(0) {} - PatternBinding(bool mut, Type type, ::std::string name, unsigned int slot): + PatternBinding(bool mut, Type type, RcString name, unsigned int slot): m_mutable(mut), m_type(type), m_name( mv$(name) ), @@ -104,7 +104,7 @@ struct Pattern (Struct, struct { GenericPath path; const Struct* binding; - ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; + ::std::vector< ::std::pair > sub_patterns; bool is_exhaustive; bool is_wildcard() const { @@ -129,7 +129,7 @@ struct Pattern GenericPath path; const Enum* binding_ptr; unsigned binding_idx; - ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; + ::std::vector< ::std::pair > sub_patterns; bool is_exhaustive; } ), (Slice, struct { diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 2c72c801..c15630d9 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -20,6 +20,15 @@ m_out( out ) {} + template + void serialise_strmap(const ::std::map& map) + { + m_out.write_count(map.size()); + for(const auto& v : map) { + m_out.write_string(v.first); + serialise(v.second); + } + } template void serialise_strmap(const ::std::map< ::std::string,V>& map) { @@ -30,6 +39,16 @@ } } template + void serialise_strmap(const ::std::unordered_map& map) + { + m_out.write_count(map.size()); + for(const auto& v : map) { + DEBUG("- " << v.first); + m_out.write_string(v.first); + serialise(v.second); + } + } + template void serialise_strmap(const ::std::unordered_map< ::std::string,V>& map) { m_out.write_count(map.size()); @@ -40,6 +59,16 @@ } } template + void serialise_strmap(const ::std::unordered_multimap& map) + { + m_out.write_count(map.size()); + for(const auto& v : map) { + DEBUG("- " << v.first); + m_out.write_string(v.first); + serialise(v.second); + } + } + template void serialise_strmap(const ::std::unordered_multimap< ::std::string,V>& map) { m_out.write_count(map.size()); @@ -73,6 +102,11 @@ serialise(e.second); } template + void serialise(const ::std::pair< RcString, T>& e) { + m_out.write_string(e.first); + serialise(e.second); + } + template void serialise(const ::std::pair& e) { m_out.write_count(e.first); serialise(e.second); @@ -86,6 +120,10 @@ void serialise(uint64_t v) { m_out.write_u64c(v); }; void serialise(int64_t v) { m_out.write_i64c(v); }; + void serialise(const ::HIR::LifetimeDef& ld) + { + m_out.write_string(ld.m_name); + } void serialise(const ::HIR::LifetimeRef& lr) { m_out.write_count(lr.binding); @@ -392,6 +430,9 @@ void serialise(const ::std::string& v) { m_out.write_string(v); } + void serialise(const RcString& v) { + m_out.write_string(v); + } void serialise(const ::MacroRulesPtr& mac) { @@ -488,6 +529,9 @@ TU_ARM(td, String, e) { m_out.write_string(e); } break; + TU_ARM(td, IString, e) { + m_out.write_string(e); + } break; TU_ARM(td, Integer, e) { m_out.write_tag(e.m_datatype); m_out.write_u64c(e.m_intval); @@ -1041,6 +1085,7 @@ serialise_strmap( item.m_value_indexes ); serialise_strmap( item.m_type_indexes ); serialise_vec( item.m_all_parent_traits ); + serialise( item.m_vtable_path ); } void serialise(const ::HIR::TraitValueItem& tvi) { @@ -1063,7 +1108,7 @@ void serialise(const ::HIR::AssociatedType& at) { m_out.write_bool(at.is_sized); - //m_out.write_string(at.m_lifetime_bound); // TODO: better type for lifetime + serialise(at.m_lifetime_bound); serialise_vec(at.m_trait_bounds); serialise_type(at.m_default); } @@ -1072,8 +1117,10 @@ void HIR_Serialise(const ::std::string& filename, const ::HIR::Crate& crate) { - ::HIR::serialise::Writer out { filename }; + ::HIR::serialise::Writer out; HirSerialiser s { out }; s.serialise_crate(crate); + out.open(filename); + s.serialise_crate(crate); } diff --git a/src/hir/serialise_lowlevel.cpp b/src/hir/serialise_lowlevel.cpp index e69ff848..5c4b0df2 100644 --- a/src/hir/serialise_lowlevel.cpp +++ b/src/hir/serialise_lowlevel.cpp @@ -11,6 +11,7 @@ #include #include // memcpy #include +#include namespace HIR { namespace serialise { @@ -29,17 +30,58 @@ public: void write(const void* buf, size_t len); }; -Writer::Writer(const ::std::string& filename): - m_inner( new WriterInner(filename) ) +Writer::Writer(): + m_inner(nullptr) { } Writer::~Writer() { delete m_inner, m_inner = nullptr; } +void Writer::open(const ::std::string& filename) +{ + // 1. Sort strings by frequency + ::std::vector<::std::pair> sorted; + sorted.reserve(m_istring_cache.size()); + for(const auto& e : m_istring_cache) + sorted.push_back( e ); + // 2. Write out string table + ::std::sort(sorted.begin(), sorted.end(), [](const auto& a, const auto& b){ return a.second > b.second; }); + + m_inner = new WriterInner(filename); + // 3. Reset m_istring_cache to use the same value + this->write_count(sorted.size()); + for(size_t i = 0; i < sorted.size(); i ++) + { + const auto& s = sorted[i].first; + this->write_string(s.size(), s.c_str()); + DEBUG(i << " = " << m_istring_cache[s] << " '" << s << "'"); + m_istring_cache[s] = i; + } + for(const auto& e : m_istring_cache) + { + assert(e.second < sorted.size()); + } +} void Writer::write(const void* buf, size_t len) { - m_inner->write(buf, len); + if( m_inner ) { + m_inner->write(buf, len); + } + else { + // No-op, pre caching + } +} +void Writer::write_string(const RcString& v) +{ + if( m_inner ) { + // Emit ID from the cache + this->write_count( m_istring_cache.at(v) ); + } + else { + // Find/add in cache + m_istring_cache.insert(::std::make_pair(v, 0)).first->second += 1; + } } @@ -189,6 +231,14 @@ Reader::Reader(const ::std::string& filename): m_buffer(1024), m_pos(0) { + size_t n_strings = read_count(); + m_strings.reserve(n_strings); + DEBUG("n_strings = " << n_strings); + for(size_t i = 0; i < n_strings; i ++) + { + auto s = read_string(); + m_strings.push_back( RcString::new_interned(s) ); + } } Reader::~Reader() { diff --git a/src/hir/serialise_lowlevel.hpp b/src/hir/serialise_lowlevel.hpp index a35b8e98..b3633d54 100644 --- a/src/hir/serialise_lowlevel.hpp +++ b/src/hir/serialise_lowlevel.hpp @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include namespace HIR { namespace serialise { @@ -21,12 +23,14 @@ class ReaderInner; class Writer { WriterInner* m_inner; + ::std::map m_istring_cache; public: - Writer(const ::std::string& path); + Writer(); Writer(const Writer&) = delete; Writer(Writer&&) = delete; ~Writer(); + void open(const ::std::string& filename); void write(const void* data, size_t count); void write_u8(uint8_t v) { @@ -114,16 +118,20 @@ public: write_u16( static_cast(c) ); } } - void write_string(const ::std::string& v) { - if(v.size() < 128) { - write_u8( static_cast(v.size()) ); + void write_string(const RcString& v); + void write_string(size_t len, const char* s) { + if(len < 128) { + write_u8( static_cast(len) ); } else { - assert(v.size() < (1u<<(16+7))); - write_u8( static_cast(128 + (v.size() >> 16)) ); - write_u16( static_cast(v.size() & 0xFFFF) ); + assert(len < (1u<<(16+7))); + write_u8( static_cast(128 + (len >> 16)) ); + write_u16( static_cast(len & 0xFFFF) ); } - this->write(v.data(), v.size()); + this->write(s, len); + } + void write_string(const ::std::string& v) { + write_string(v.size(), v.c_str()); } void write_bool(bool v) { write_u8(v ? 0xFF : 0x00); @@ -148,6 +156,7 @@ class Reader ReaderInner* m_inner; ReadBuffer m_buffer; size_t m_pos; + ::std::vector m_strings; public: Reader(const ::std::string& path); Reader(const Writer&) = delete; @@ -251,6 +260,10 @@ public: return ~0u; } } + RcString read_istring() { + size_t idx = read_count(); + return m_strings.at(idx); + } ::std::string read_string() { size_t len = read_u8(); if( len < 128 ) { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 2fc1179d..38196a55 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -88,6 +88,7 @@ struct LifetimeRef static const uint32_t UNKNOWN = 0; static const uint32_t STATIC = 0xFFFF; + //RcString name; // Values below 2^16 are parameters/static, values above are per-function region IDs allocated during region inferrence. uint32_t binding = UNKNOWN; @@ -97,6 +98,9 @@ struct LifetimeRef return rv; } + Ordering ord(const LifetimeRef& x) const { + return ::ord(binding, x.binding); + } bool operator==(const LifetimeRef& x) const { return binding == x.binding; } @@ -191,7 +195,7 @@ public: TypePathBinding binding; }), (Generic, struct { - ::std::string name; + RcString name; // 0xFFFF = Self, 0-255 = Type/Trait, 256-511 = Method, 512-767 = Placeholder unsigned int binding; @@ -254,7 +258,7 @@ public: TypeRef(::std::vector< ::HIR::TypeRef> sts): m_data( Data::make_Tuple(mv$(sts)) ) {} - TypeRef(::std::string name, unsigned int slot): + TypeRef(RcString name, unsigned int slot): m_data( Data::make_Generic({ mv$(name), slot }) ) {} TypeRef(::HIR::TypeRef::Data x): diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 22909cdc..b97a6ae0 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -40,7 +40,7 @@ namespace { virtual ::HIR::Path new_static(::HIR::TypeRef type, ::HIR::Literal value) override { - auto name = FMT(name_prefix << next_item_idx); + auto name = RcString::new_interned(FMT(name_prefix << next_item_idx)); next_item_idx ++; DEBUG("mod_path = " << mod_path); auto rv = mod_path.get_simple_path() + name.c_str(); diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index ace154ff..94f272f8 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -147,7 +147,7 @@ namespace { { m_replacement = NEWNODE(node.m_res_type.clone(), Field, node.span(), get_self(node.span()), - FMT(binding_it - m_captures.begin()) + RcString::new_interned(FMT(binding_it - m_captures.begin())) ); if( binding_it->second != ::HIR::ValueUsage::Move ) { auto bt = (binding_it->second == ::HIR::ValueUsage::Mutate ? ::HIR::BorrowType::Unique : ::HIR::BorrowType::Shared); @@ -355,7 +355,7 @@ namespace { return ::HIR::TraitImpl { mv$(params), {}, mv$(closure_type), make_map1( - ::std::string("call_free"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + RcString::new_interned("call_free"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { false, ::HIR::Linkage {}, ::HIR::Function::Receiver::Free, ABI_RUST, false, false, @@ -385,7 +385,7 @@ namespace { return ::HIR::TraitImpl { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( - ::std::string("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + RcString::new_interned("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { false, ::HIR::Linkage {}, ::HIR::Function::Receiver::Value, ABI_RUST, false, false, @@ -404,7 +404,7 @@ namespace { {}, {}, make_map1( - ::std::string("Output"), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { false, mv$(ret_ty) } + RcString::new_interned("Output"), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { false, mv$(ret_ty) } ), ::HIR::SimplePath() }; @@ -423,7 +423,7 @@ namespace { return ::HIR::TraitImpl { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( - ::std::string("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + RcString::new_interned("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { false, ::HIR::Linkage {}, ::HIR::Function::Receiver::BorrowUnique, ABI_RUST, false, false, @@ -459,7 +459,7 @@ namespace { return ::HIR::TraitImpl { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( - ::std::string("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + RcString::new_interned("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { false, ::HIR::Linkage {}, ::HIR::Function::Receiver::BorrowShared, ABI_RUST, false, false, @@ -801,11 +801,11 @@ namespace { for(size_t i = 0; i < args_tup_inner.size(); i ++) { const auto& ty = args_tup_inner[i]; - dispatch_args.push_back( NEWNODE(ty.clone(), Field, sp, NEWNODE(args_ty.clone(), Variable, sp, "arg", 1), FMT(i)) ); + dispatch_args.push_back( NEWNODE(ty.clone(), Field, sp, NEWNODE(args_ty.clone(), Variable, sp, RcString::new_interned("arg"), 1), RcString::new_interned(FMT(i))) ); dispatch_node_args_cache.push_back( ty.clone() ); } dispatch_node_args_cache.push_back( ret_type.clone() ); - auto path = ::HIR::Path(closure_type.clone(), "call_free"); + auto path = ::HIR::Path(closure_type.clone(), RcString::new_interned("call_free")); path.m_data.as_UfcsInherent().impl_params = closure_type.m_data.as_Path().path.m_data.as_Generic().m_params.clone(); HIR::ExprNodeP dispatch_node = NEWNODE(ret_type.clone(), CallPath, sp, mv$(path), @@ -814,7 +814,7 @@ namespace { dynamic_cast<::HIR::ExprNode_CallPath&>(*dispatch_node).m_cache.m_arg_types = mv$(dispatch_node_args_cache); auto args_arg = ::std::make_pair( - ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, "args", 1}, {} }, + ::HIR::Pattern { {false, ::HIR::PatternBinding::Type::Move, RcString::new_interned("args"), 1}, {} }, args_ty.clone() ); HIR::TraitImpl fcn; @@ -863,9 +863,9 @@ namespace { // - FnOnce { auto dispatch_node = NEWNODE(ret_type.clone(), CallPath, sp, - ::HIR::Path(closure_type.clone(), ::HIR::GenericPath(lang_Fn, trait_params.clone()), "call"), + ::HIR::Path(closure_type.clone(), ::HIR::GenericPath(lang_Fn, trait_params.clone()), RcString::new_interned("call")), make_vec2( - NEWNODE(method_self_ty.clone(), Borrow, sp, ::HIR::BorrowType::Shared, NEWNODE(closure_type.clone(), Variable, sp, "self", 0)), + NEWNODE(method_self_ty.clone(), Borrow, sp, ::HIR::BorrowType::Shared, NEWNODE(closure_type.clone(), Variable, sp, RcString::new_interned("self"), 0)), NEWNODE(args_ty.clone(), Variable, sp, "arg", 1) ) ); @@ -1181,7 +1181,7 @@ namespace { ::HIR::SimplePath root_mod_path(crate.m_crate_name,{}); m_cur_mod_path = &root_mod_path; m_new_type = [&](auto s)->auto { - auto name = FMT("closure#I_" << closure_count); + auto name = RcString::new_interned(FMT("closure#I_" << closure_count)); closure_count += 1; auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { ::HIR::Publicity::new_none(), ::HIR::TypeItem( mv$(s) ) } )); crate.m_root_module.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) ); @@ -1374,7 +1374,7 @@ void HIR_Expand_Closures_Expr(const ::HIR::Crate& crate_ro, ::HIR::ExprPtr& exp) static int closure_count = 0; out_impls_t new_trait_impls; new_type_cb_t new_type_cb = [&](auto s)->::HIR::SimplePath { - auto name = FMT("closure#C_" << closure_count); + auto name = RcString::new_interned(FMT("closure#C_" << closure_count)); closure_count += 1; auto boxed = box$(( ::HIR::VisEnt< ::HIR::TypeItem> { ::HIR::Publicity::new_none(), ::HIR::TypeItem( mv$(s) ) } )); crate.m_root_module.m_mod_items.insert( ::std::make_pair(name, mv$(boxed)) ); diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index 2b3dcfb4..cd7b3413 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -17,7 +17,7 @@ namespace { { const ::HIR::Crate& m_crate; //StaticTraitResolve m_resolve; - ::std::function<::HIR::SimplePath(bool, ::std::string, ::HIR::Struct)> m_new_type; + ::std::function<::HIR::SimplePath(bool, RcString, ::HIR::Struct)> m_new_type; ::HIR::SimplePath m_lang_Sized; public: OuterVisitor(const ::HIR::Crate& crate): @@ -72,7 +72,7 @@ namespace { //TODO(Span(), "Handle conflicting associated types - '" << ty.first << "'"); } else { - params.m_types.push_back( ::HIR::TypeParamDef { "a#"+ty.first, {}, ty.second.is_sized } ); + params.m_types.push_back( ::HIR::TypeParamDef { RcString::new_interned(FMT("a#" << ty.first)), {}, ty.second.is_sized } ); } i ++; } @@ -98,14 +98,14 @@ namespace { auto clone_cb = [&](const auto& t, auto& o) { if(t.m_data.is_Path() && t.m_data.as_Path().path.m_data.is_UfcsKnown()) { const auto& pe = t.m_data.as_Path().path.m_data.as_UfcsKnown(); - bool is_self = (*pe.type == ::HIR::TypeRef("Self", 0xFFFF)); + bool is_self = (*pe.type == ::HIR::TypeRef(RcString::new_interned("Self"), 0xFFFF)); auto it = trait_ptr->m_type_indexes.find(pe.item); bool has_item = (it != trait_ptr->m_type_indexes.end()); // TODO: Check the trait against m_type_indexes if( is_self /*&& pe.trait == trait_path*/ && has_item ) { DEBUG("[clone_cb] t=" << t << " -> " << it->second); // Replace with a new type param, need to know the index of it - o = ::HIR::TypeRef("a#"+pe.item, it->second); + o = ::HIR::TypeRef( RcString::new_interned(FMT("a#" << pe.item)), it->second); return true; } else { @@ -231,12 +231,13 @@ namespace { } } // TODO: Would like to have access to the publicity marker - auto item_path = m_new_type(true, FMT(p.get_name() << "#vtable"), ::HIR::Struct { + auto item_path = m_new_type(true, RcString::new_interned(FMT(p.get_name() << "#vtable")), ::HIR::Struct { mv$(args), ::HIR::Struct::Repr::Rust, ::HIR::Struct::Data(mv$(fields)), {} }); + tr.m_vtable_path = item_path; DEBUG("Vtable structure created - " << item_path); ::HIR::GenericPath path( mv$(item_path), mv$(params) ); diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index 0d3bc8ab..aa26ae1f 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -832,7 +832,7 @@ namespace { // TODO: Either - Don't include the above impl bound, or change the below trait to the one that has that type for( const auto& assoc : be.trait.m_type_bounds ) { ::HIR::GenericPath type_trait_path; - bool has_ty = m_resolve.trait_contains_type(sp, real_trait, *be.trait.m_trait_ptr, assoc.first, type_trait_path); + bool has_ty = m_resolve.trait_contains_type(sp, real_trait, *be.trait.m_trait_ptr, assoc.first.c_str(), type_trait_path); ASSERT_BUG(sp, has_ty, "Type " << assoc.first << " not found in chain of " << real_trait); auto other_ty = monomorphise_type_with(sp, assoc.second, cache.m_monomorph_cb, true); @@ -934,7 +934,7 @@ namespace { const auto& sp = node.span(); const auto& str_ty = node.m_value->m_res_type; - bool is_index = ( '0' <= node.m_field[0] && node.m_field[0] <= '9' ); + bool is_index = ( '0' <= node.m_field.c_str()[0] && node.m_field.c_str()[0] <= '9' ); if( str_ty.m_data.is_Tuple() ) { ASSERT_BUG(sp, is_index, "Non-index _Field on tuple"); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index cda8edd0..ecaae208 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -53,7 +53,7 @@ struct Context struct Binding { - ::std::string name; + RcString name; ::HIR::TypeRef ty; //unsigned int ivar; }; @@ -79,7 +79,7 @@ struct Context ::HIR::SimplePath trait; ::HIR::PathParams params; ::HIR::TypeRef impl_ty; - ::std::string name; // if "", no type is used (and left is ignored) - Just does trait selection + RcString name; // if "", no type is used (and left is ignored) - Just does trait selection // HACK: operators are special - the result when both types are primitives is ALWAYS the lefthand side bool is_operator; @@ -252,7 +252,7 @@ struct Context void handle_pattern_direct_inner(const Span& sp, ::HIR::Pattern& pat, const ::HIR::TypeRef& type); void add_binding_inner(const Span& sp, const ::HIR::PatternBinding& pb, ::HIR::TypeRef type); - void add_var(const Span& sp, unsigned int index, const ::std::string& name, ::HIR::TypeRef type); + void add_var(const Span& sp, unsigned int index, const RcString& name, ::HIR::TypeRef type); const ::HIR::TypeRef& get_var(const Span& sp, unsigned int idx) const; // - Add a revisit entry @@ -304,7 +304,7 @@ namespace { ::HIR::GenericPath type_trait_path; ASSERT_BUG(sp, be.trait.m_trait_ptr, "Trait pointer not set in " << be.trait.m_path); // TODO: Store the source trait for this bound in the the bound list? - if( !context.m_resolve.trait_contains_type(sp, real_trait, *be.trait.m_trait_ptr, assoc.first, type_trait_path) ) + if( !context.m_resolve.trait_contains_type(sp, real_trait, *be.trait.m_trait_ptr, assoc.first.c_str(), type_trait_path) ) BUG(sp, "Couldn't find associated type " << assoc.first << " in trait " << real_trait); auto other_ty = monomorphise_type_with(sp, assoc.second, monomorph_cb, true); @@ -1480,7 +1480,7 @@ namespace { } // - Search in-scope trait list for traits that provide a method of this name - const ::std::string& method_name = node.m_method; + const RcString& method_name = node.m_method; ::HIR::t_trait_list possible_traits; unsigned int max_num_params = 0; for(const auto& trait_ref : ::reverse(m_traits)) @@ -2772,7 +2772,7 @@ namespace { // - If running in a mode after stablise (before defaults), fall // back to trait if the inherent is still ambigious. ::std::vector<::std::pair> possible_methods; - unsigned int deref_count = this->context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, ty, node.m_method, possible_methods); + unsigned int deref_count = this->context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, ty, node.m_method.c_str(), possible_methods); try_again: if( deref_count != ~0u ) { @@ -3003,6 +3003,7 @@ namespace { const auto* current_ty = &node.m_value->m_res_type; ::std::vector< ::HIR::TypeRef> deref_res_types; + // TODO: autoderef_find_field? do { const auto& ty = this->context.m_ivars.get_type(*current_ty); if( ty.m_data.is_Infer() ) { @@ -3013,7 +3014,7 @@ namespace { DEBUG("Hit unbound path, returning early"); return ; } - if( this->context.m_resolve.find_field(node.span(), ty, field_name, out_type) ) { + if( this->context.m_resolve.find_field(node.span(), ty, field_name.c_str(), out_type) ) { this->context.equate_types(node.span(), node.m_res_type, out_type); break; } @@ -5439,7 +5440,7 @@ void Context::possible_equate_type_disable_strong(const Span& sp, unsigned int i ent.force_disable = true; } -void Context::add_var(const Span& sp, unsigned int index, const ::std::string& name, ::HIR::TypeRef type) { +void Context::add_var(const Span& sp, unsigned int index, const RcString& name, ::HIR::TypeRef type) { DEBUG("(" << index << " " << name << " : " << type << ")"); assert(index != ~0u); if( m_bindings.size() <= index ) @@ -6923,7 +6924,7 @@ namespace { DEBUG("Check <" << t << ">::" << node.m_method); ::std::vector<::std::pair> possible_methods; - unsigned int deref_count = context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, t, node.m_method, possible_methods); + unsigned int deref_count = context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, t, node.m_method.c_str(), possible_methods); DEBUG("> deref_count = " << deref_count << ", " << possible_methods); if( !t.m_data.is_Infer() && possible_methods.empty() ) { diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 0ebb9c07..629b8bba 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -960,7 +960,7 @@ void TraitResolution::prep_indexes() // Locate the source trait ::HIR::GenericPath source_trait_path; - bool rv = this->trait_contains_type(sp, be.trait.m_path, m_crate.get_trait_by_path(sp, be.trait.m_path.m_path), tb.first, source_trait_path); + bool rv = this->trait_contains_type(sp, be.trait.m_path, m_crate.get_trait_by_path(sp, be.trait.m_path.m_path), tb.first.c_str(), source_trait_path); ASSERT_BUG(sp, rv, "Can't find `" << tb.first << "` in " << be.trait.m_path); auto ty_l = ::HIR::TypeRef( ::HIR::Path( be.type.clone(), mv$(source_trait_path), tb.first ) ); @@ -1005,7 +1005,7 @@ void TraitResolution::prep_indexes() // Find the source trait for this associated type ::HIR::GenericPath source_trait_path; - bool rv = this->trait_contains_type(sp, trait_mono.m_path, itrait, tb.first, source_trait_path); + bool rv = this->trait_contains_type(sp, trait_mono.m_path, itrait, tb.first.c_str(), source_trait_path); ASSERT_BUG(sp, rv, "Can't find `" << tb.first << "` in " << trait_mono.m_path); auto ty_l = ::HIR::TypeRef( ::HIR::Path( ty_a.clone(), mv$(source_trait_path), tb.first ) ); @@ -1091,7 +1091,7 @@ bool TraitResolution::iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data { ::HIR::GenericPath trait_path; DEBUG("Checking ATY bounds on " << pe.trait << " :: " << pe.item); - if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item, trait_path) ) + if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item.c_str(), trait_path) ) BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait); DEBUG("trait_path=" << trait_path); const auto& trait_ref = m_crate.get_trait_by_path(sp, trait_path.m_path); @@ -1133,7 +1133,7 @@ bool TraitResolution::find_trait_impls_magic(const Span& sp, ) const { static ::HIR::PathParams null_params; - static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; + static ::std::map null_assoc; const auto& lang_Sized = this->m_crate.get_lang_item_path(sp, "sized"); const auto& lang_Copy = this->m_crate.get_lang_item_path(sp, "copy"); @@ -1235,7 +1235,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, ) const { static ::HIR::PathParams null_params; - static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; + static ::std::map null_assoc; const auto& type = this->m_ivars.get_type(ty); TRACE_FUNCTION_F("trait = " << trait << params << ", type = " << type); @@ -1295,7 +1295,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, ::HIR::PathParams pp; pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) ); - ::std::map< ::std::string, ::HIR::TypeRef> types; + ::std::map types; types.insert( ::std::make_pair( "Output", e.m_rettype->clone() ) ); return callback( ImplRef(type.clone(), mv$(pp), mv$(types)), cmp ); } @@ -1337,7 +1337,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, ::HIR::PathParams pp; pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) ); - ::std::map< ::std::string, ::HIR::TypeRef> types; + ::std::map types; types.insert( ::std::make_pair( "Output", e.m_rettype->clone() ) ); return callback( ImplRef(type.clone(), mv$(pp), mv$(types)), cmp ); } @@ -1362,7 +1362,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, { ::HIR::PathParams pp; pp.m_types.push_back( mv$(ty_usize) ); - ::std::map< ::std::string, ::HIR::TypeRef> types; + ::std::map types; types.insert( ::std::make_pair( "Output", e.inner->clone() ) ); return callback( ImplRef(type.clone(), mv$(pp), mv$(types)), cmp ); } @@ -1402,8 +1402,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, if( trait == mt.m_path ) { auto cmp = compare_pp(sp, mt.m_params, params); if( cmp != ::HIR::Compare::Unequal ) { - static ::std::map< ::std::string, ::HIR::TypeRef> types; - return callback( ImplRef(&type, &mt.m_params, &types), cmp ); + return callback( ImplRef(&type, &mt.m_params, &null_assoc), cmp ); } } } @@ -1417,7 +1416,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, auto cmp = this->compare_pp(sp, i_params, params); if( cmp != ::HIR::Compare::Unequal ) { // Invoke callback with a proper ImplRef - ::std::map< ::std::string, ::HIR::TypeRef> assoc_clone; + ::std::map assoc_clone; for(const auto& e : i_assoc) assoc_clone.insert( ::std::make_pair(e.first, e.second.clone()) ); auto ir = ImplRef(i_ty.clone(), i_params.clone(), mv$(assoc_clone)); @@ -1454,7 +1453,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, auto cmp = this->compare_pp(sp, i_params, params); if( cmp != ::HIR::Compare::Unequal ) { // Invoke callback with a proper ImplRef - ::std::map< ::std::string, ::HIR::TypeRef> assoc_clone; + ::std::map assoc_clone; for(const auto& e : i_assoc) assoc_clone.insert( ::std::make_pair(e.first, e.second.clone()) ); auto ir = ImplRef(i_ty.clone(), i_params.clone(), mv$(assoc_clone)); @@ -1498,7 +1497,7 @@ bool TraitResolution::find_trait_impls(const Span& sp, ::HIR::PathParams params_mono_o; const auto& b_params_mono = (monomorphise_pathparams_needed(b_params) ? params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false) : b_params); // TODO: Monormophise and EAT associated types - ::std::map< ::std::string, ::HIR::TypeRef> b_atys; + ::std::map b_atys; for(const auto& aty : bound.m_type_bounds) b_atys.insert(::std::make_pair( aty.first, monomorphise_type_with(sp, aty.second, monomorph_cb) )); @@ -2080,7 +2079,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, // - Does simplification of complex associated types // ::HIR::GenericPath trait_path; - if( !this->trait_contains_type(sp, pe_inner.trait, this->m_crate.get_trait_by_path(sp, pe_inner.trait.m_path), pe_inner.item, trait_path) ) + if( !this->trait_contains_type(sp, pe_inner.trait, this->m_crate.get_trait_by_path(sp, pe_inner.trait.m_path), pe_inner.item.c_str(), trait_path) ) BUG(sp, "Cannot find associated type " << pe_inner.item << " anywhere in trait " << pe_inner.trait); const auto& trait_ptr = this->m_crate.get_trait_by_path(sp, trait_path.m_path); const auto& assoc_ty = trait_ptr.m_types.at(pe_inner.item); @@ -2150,7 +2149,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, // TODO: Search for the actual trait containing this associated type ::HIR::GenericPath trait_path; //if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), *pe.type, pe.item, trait_path) ) - if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item, trait_path) ) + if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item.c_str(), trait_path) ) BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait); //pe.trait = mv$(trait_path); @@ -2350,7 +2349,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple type, [&](const auto& ty, const auto& b_params, const auto& assoc) { // TODO: Avoid duplicating this map every time - ::std::map< ::std::string,::HIR::TypeRef> assoc2; + ::std::map< RcString,::HIR::TypeRef> assoc2; for(const auto& i : assoc) { assoc2.insert( ::std::make_pair(i.first, i.second.clone()) ); } @@ -2447,7 +2446,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, { // TODO: Have a global cache of impls that don't reference either generics or ivars - static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; + static ::std::map null_assoc; TRACE_FUNCTION_F(trait << FMT_CB(ss, if(params_ptr) { ss << *params_ptr; } else { ss << ""; }) << " for " << type); // Handle auto traits (aka OIBITs) @@ -2832,7 +2831,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, // TODO: Some impl blocks have type params used as part of type bounds. // - A rough idea is to have monomorph return a third class of generic for params that are not yet bound. // - compare_with_placeholders gets called on both ivars and generics, so that can be used to replace it once known. - ::std::string placeholder_name = FMT("impl_?_" << &impl_params); + auto placeholder_name = RcString::new_interned(FMT("impl_?_" << &impl_params)); for(unsigned int i = 0; i < impl_params.size(); i ++ ) { if( !impl_params[i] ) { if( placeholders.size() == 0 ) @@ -3061,7 +3060,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, } namespace { - bool trait_contains_method_inner(const ::HIR::Trait& trait_ptr, const ::std::string& name, const ::HIR::Function*& out_fcn_ptr) + bool trait_contains_method_inner(const ::HIR::Trait& trait_ptr, const char* name, const ::HIR::Function*& out_fcn_ptr) { auto it = trait_ptr.m_values.find(name); if( it != trait_ptr.m_values.end() ) @@ -3076,7 +3075,7 @@ namespace { } } -const ::HIR::Function* TraitResolution::trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const ::std::string& name, ::HIR::GenericPath& out_path) const +const ::HIR::Function* TraitResolution::trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const char* name, ::HIR::GenericPath& out_path) const { TRACE_FUNCTION_FR("trait_path=" << trait_path << ",name=" << name, out_path); const ::HIR::Function* rv = nullptr; @@ -3101,7 +3100,7 @@ const ::HIR::Function* TraitResolution::trait_contains_method(const Span& sp, co } return nullptr; } -bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const +bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const char* name, ::HIR::GenericPath& out_path) const { TRACE_FUNCTION_FR(trait_path << " has " << name, out_path); @@ -3698,7 +3697,7 @@ const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::Ty } unsigned int TraitResolution::autoderef_find_method(const Span& sp, - const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, + const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& top_ty, const char* method_name, /* Out -> */::std::vector<::std::pair>& possibilities ) const { @@ -3906,7 +3905,7 @@ const ::HIR::TypeRef* TraitResolution::check_method_receiver(const Span& sp, con } bool TraitResolution::find_method(const Span& sp, - const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, MethodAccess access, + const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& ty, const char* method_name, MethodAccess access, AutoderefBorrow borrow_type, /* Out -> */::std::vector<::std::pair>& possibilities ) const { @@ -4259,7 +4258,7 @@ bool TraitResolution::find_method(const Span& sp, return rv; } -unsigned int TraitResolution::autoderef_find_field(const Span& sp, const ::HIR::TypeRef& top_ty, const ::std::string& field_name, /* Out -> */::HIR::TypeRef& field_type) const +unsigned int TraitResolution::autoderef_find_field(const Span& sp, const ::HIR::TypeRef& top_ty, const char* field_name, /* Out -> */::HIR::TypeRef& field_type) const { unsigned int deref_count = 0; ::HIR::TypeRef tmp_type; // Temporary type used for handling Deref @@ -4299,7 +4298,7 @@ unsigned int TraitResolution::autoderef_find_field(const Span& sp, const ::HIR:: this->m_ivars.dump(); TODO(sp, "Error when no field could be found, but type is known - (: " << top_ty << ")." << field_name); } -bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const ::std::string& name, /* Out -> */::HIR::TypeRef& field_ty) const +bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const char* name, /* Out -> */::HIR::TypeRef& field_ty) const { TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Path, e, TU_MATCH(::HIR::TypeRef::TypePathBinding, (e.binding), (be), diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp index dd9a1581..00befd63 100644 --- a/src/hir_typeck/helpers.hpp +++ b/src/hir_typeck/helpers.hpp @@ -207,7 +207,7 @@ public: bool iterate_bounds_traits(const Span& sp, ::std::function cb) const; bool iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data::Data_UfcsKnown& pe, ::std::function cb) const; - typedef ::std::function&)> t_cb_trait_impl; + typedef ::std::function&)> t_cb_trait_impl; typedef ::std::function t_cb_trait_impl_r; /// Searches for a trait impl that matches the provided trait name and type @@ -250,17 +250,17 @@ public: /// Locate the named method by applying auto-dereferencing. /// \return Number of times deref was applied (or ~0 if _ was hit) unsigned int autoderef_find_method(const Span& sp, - const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, + const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& top_ty, const char* method_name, /* Out -> */::std::vector<::std::pair>& possibilities ) const; /// Locate the named field by applying auto-dereferencing. /// \return Number of times deref was applied (or ~0 if _ was hit) - unsigned int autoderef_find_field(const Span& sp, const ::HIR::TypeRef& top_ty, const ::std::string& name, /* Out -> */::HIR::TypeRef& field_type) const; + unsigned int autoderef_find_field(const Span& sp, const ::HIR::TypeRef& top_ty, const char* name, /* Out -> */::HIR::TypeRef& field_type) const; /// Apply an automatic dereference const ::HIR::TypeRef* autoderef(const Span& sp, const ::HIR::TypeRef& ty, ::HIR::TypeRef& tmp_type) const; - bool find_field(const Span& sp, const ::HIR::TypeRef& ty, const ::std::string& name, /* Out -> */::HIR::TypeRef& field_type) const; + bool find_field(const Span& sp, const ::HIR::TypeRef& ty, const char* name, /* Out -> */::HIR::TypeRef& field_type) const; enum class MethodAccess { Shared, @@ -279,13 +279,13 @@ public: }; friend ::std::ostream& operator<<(::std::ostream& os, const AllowedReceivers& x); bool find_method(const Span& sp, - const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, MethodAccess access, + const HIR::t_trait_list& traits, const ::std::vector& ivars, const ::HIR::TypeRef& ty, const char* method_name, MethodAccess access, AutoderefBorrow borrow_type, /* Out -> */::std::vector<::std::pair>& possibilities ) const; /// Locates a named method in a trait, and returns the path of the trait that contains it (with fixed parameters) - const ::HIR::Function* trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const ::std::string& name, ::HIR::GenericPath& out_path) const; - bool trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const; + const ::HIR::Function* trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const char* name, ::HIR::GenericPath& out_path) const; + bool trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const char* name, ::HIR::GenericPath& out_path) const; ::HIR::Compare type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const; ::HIR::Compare type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const; diff --git a/src/hir_typeck/impl_ref.hpp b/src/hir_typeck/impl_ref.hpp index 84d0b404..c67c8a81 100644 --- a/src/hir_typeck/impl_ref.hpp +++ b/src/hir_typeck/impl_ref.hpp @@ -27,12 +27,12 @@ struct ImplRef (BoundedPtr, struct { const ::HIR::TypeRef* type; const ::HIR::PathParams* trait_args; - const ::std::map< ::std::string, ::HIR::TypeRef>* assoc; + const ::std::map< RcString, ::HIR::TypeRef>* assoc; }), (Bounded, struct { ::HIR::TypeRef type; ::HIR::PathParams trait_args; - ::std::map< ::std::string, ::HIR::TypeRef> assoc; + ::std::map< RcString, ::HIR::TypeRef> assoc; }) ); @@ -45,10 +45,10 @@ struct ImplRef m_data(Data::make_TraitImpl({ mv$(params), mv$(params_ph), &trait, &impl })) {} - ImplRef(const ::HIR::TypeRef* type, const ::HIR::PathParams* args, const ::std::map< ::std::string, ::HIR::TypeRef>* assoc): + ImplRef(const ::HIR::TypeRef* type, const ::HIR::PathParams* args, const ::std::map< RcString, ::HIR::TypeRef>* assoc): m_data(Data::make_BoundedPtr({ type, mv$(args), mv$(assoc) })) {} - ImplRef(::HIR::TypeRef type, ::HIR::PathParams args, ::std::map< ::std::string, ::HIR::TypeRef> assoc): + ImplRef(::HIR::TypeRef type, ::HIR::PathParams args, ::std::map< RcString, ::HIR::TypeRef> assoc): m_data(Data::make_Bounded({ mv$(type), mv$(args), mv$(assoc) })) {} diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index 6a8e8b35..c2b216d4 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -322,8 +322,9 @@ namespace { else if( m_fcn_ptr ) { size_t idx = m_fcn_ptr->m_params.m_types.size(); - auto new_ty = ::HIR::TypeRef( FMT("impl$" << idx), 256 + idx ); - m_fcn_ptr->m_params.m_types.push_back({ FMT("impl$" << idx), ::HIR::TypeRef(), true }); + auto name = RcString::new_interned(FMT("impl$" << idx)); + auto new_ty = ::HIR::TypeRef( name, 256 + idx ); + m_fcn_ptr->m_params.m_types.push_back({ name, ::HIR::TypeRef(), true }); for( const auto& trait : e.m_traits ) { m_fcn_ptr->m_params.m_bounds.push_back(::HIR::GenericBound::make_TraitBound({ diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index c71e71d7..0c0f1859 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -97,7 +97,7 @@ bool StaticTraitResolve::find_impl( 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; + static ::std::map null_assoc; if( !dont_handoff_to_specialised ) { if( trait_path == m_lang_Copy ) { @@ -159,7 +159,7 @@ bool StaticTraitResolve::find_impl( { trait_params = &null_params; } - ::std::map< ::std::string, ::HIR::TypeRef> assoc; + ::std::map< RcString, ::HIR::TypeRef> assoc; assoc.insert( ::std::make_pair("Output", e.m_rettype->clone()) ); return found_cb( ImplRef(type.clone(), trait_params->clone(), mv$(assoc)), false ); } @@ -200,7 +200,7 @@ bool StaticTraitResolve::find_impl( case ::HIR::ExprNode_Closure::Class::Shared: break; } - ::std::map< ::std::string, ::HIR::TypeRef> assoc; + ::std::map< RcString, ::HIR::TypeRef> assoc; assoc.insert( ::std::make_pair("Output", e->m_rettype->clone()) ); return found_cb( ImplRef(type.clone(), trait_params->clone(), mv$(assoc)), false ); } @@ -223,7 +223,7 @@ bool StaticTraitResolve::find_impl( if( trait_path == mt.m_path ) { if( !trait_params || mt.m_params == *trait_params ) { - static ::std::map< ::std::string, ::HIR::TypeRef> types; + static ::std::map< RcString, ::HIR::TypeRef> types; return found_cb( ImplRef(&type, &mt.m_params, &types), false ); } } @@ -235,7 +235,7 @@ bool StaticTraitResolve::find_impl( bool is_supertrait = trait_params && this->find_named_trait_in_trait(sp, trait_path,*trait_params, *e.m_trait.m_trait_ptr, e.m_trait.m_path.m_path,e.m_trait.m_path.m_params, type, [&](const auto& i_params, const auto& i_assoc) { // Invoke callback with a proper ImplRef - ::std::map< ::std::string, ::HIR::TypeRef> assoc_clone; + ::std::map< RcString, ::HIR::TypeRef> assoc_clone; for(const auto& e : i_assoc) assoc_clone.insert( ::std::make_pair(e.first, e.second.clone()) ); // HACK! Just add all the associated type bounds (only inserted if not already present) @@ -265,7 +265,7 @@ bool StaticTraitResolve::find_impl( bool is_supertrait = trait_params && this->find_named_trait_in_trait(sp, trait_path,*trait_params, *trait.m_trait_ptr, trait.m_path.m_path,trait.m_path.m_params, type, [&](const auto& i_params, const auto& i_assoc) { // Invoke callback with a proper ImplRef - ::std::map< ::std::string, ::HIR::TypeRef> assoc_clone; + ::std::map< RcString, ::HIR::TypeRef> assoc_clone; for(const auto& e : i_assoc) assoc_clone.insert( ::std::make_pair(e.first, e.second.clone()) ); // HACK! Just add all the associated type bounds (only inserted if not already present) @@ -312,7 +312,7 @@ bool StaticTraitResolve::find_impl( { if( &b_params_mono == ¶ms_mono_o || ::std::any_of(bound.m_type_bounds.begin(), bound.m_type_bounds.end(), [&](const auto& x){ return monomorphise_type_needed(x.second); }) ) { - ::std::map< ::std::string, ::HIR::TypeRef> atys; + ::std::map< RcString, ::HIR::TypeRef> atys; if( ! bound.m_type_bounds.empty() ) { for(const auto& tb : bound.m_type_bounds) @@ -722,7 +722,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( const ::HIR::TypeRef& exp = assoc_bound.second; ::HIR::GenericPath aty_src_trait; - trait_contains_type(sp, b_tp_mono.m_path, *e.trait.m_trait_ptr, aty_name, aty_src_trait); + trait_contains_type(sp, b_tp_mono.m_path, *e.trait.m_trait_ptr, aty_name.c_str(), aty_src_trait); bool rv = false; if( b_ty_mono.m_data.is_Generic() && (b_ty_mono.m_data.as_Generic().binding >> 8) == 2 ) { @@ -1241,7 +1241,7 @@ bool StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI // - Search for the actual trait containing this associated type ::HIR::GenericPath trait_path; - if( !this->trait_contains_type(sp, e2.trait, this->m_crate.get_trait_by_path(sp, e2.trait.m_path), e2.item, trait_path) ) + if( !this->trait_contains_type(sp, e2.trait, this->m_crate.get_trait_by_path(sp, e2.trait.m_path), e2.item.c_str(), trait_path) ) BUG(sp, "Cannot find associated type " << e2.item << " anywhere in trait " << e2.trait); //e2.trait = mv$(trait_path); @@ -1382,7 +1382,7 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp, const ::HIR::SimplePath& des, const ::HIR::PathParams& des_params, const ::HIR::Trait& trait_ptr, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& pp, const ::HIR::TypeRef& target_type, - ::std::function)> callback + ::std::function)> callback ) const { TRACE_FUNCTION_F(des << des_params << " from " << trait_path << pp); @@ -1423,7 +1423,7 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp, return false; } -bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const +bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const char* name, ::HIR::GenericPath& out_path) const { TRACE_FUNCTION_FR("name="<~RcString(); m_ptr = x.m_ptr; - m_len = x.m_len; if( m_ptr ) *m_ptr += 1; } return *this; @@ -62,27 +60,76 @@ public: { this->~RcString(); m_ptr = x.m_ptr; - m_len = x.m_len; x.m_ptr = nullptr; - x.m_len = 0; } return *this; } + const char* begin() const { return c_str(); } + const char* end() const { return c_str() + size(); } + size_t size() const { return m_ptr ? m_ptr[1] : 0; } const char* c_str() const { - if( m_len > 0 ) + if( m_ptr ) { - return reinterpret_cast(m_ptr + 1); + return reinterpret_cast(m_ptr + 2); } else { return ""; } } - bool operator==(const RcString& s) const { return *this == s.c_str(); } + + char back() const { + assert(size() > 0 ); + return *(c_str() + size() - 1); + } + + Ordering ord(const RcString& s) const; + bool operator==(const RcString& s) const { + if(s.size() != this->size()) + return false; + return this->ord(s) == OrdEqual; + } + bool operator!=(const RcString& s) const { + if(s.size() != this->size()) + return true; + return this->ord(s) != OrdEqual; + } + bool operator<(const RcString& s) const { return this->ord(s) == OrdLess; } + bool operator>(const RcString& s) const { return this->ord(s) == OrdGreater; } + + Ordering ord(const std::string& s) const; + bool operator==(const std::string& s) const { return this->ord(s) == OrdEqual; } + bool operator!=(const std::string& s) const { return this->ord(s) != OrdEqual; } + bool operator<(const std::string& s) const { return this->ord(s) == OrdLess; } + bool operator>(const std::string& s) const { return this->ord(s) == OrdGreater; } bool operator==(const char* s) const; - friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x) { - return os << x.c_str(); + bool operator!=(const char* s) const { return !(*this == s); } + friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x); + + friend bool operator==(const char* a, const RcString& b) { + return b == a; + } + friend bool operator!=(const char* a, const RcString& b) { + return b != a; + } + + int compare(size_t o, size_t l, const char* s) const { + assert(o <= this->size()); + return memcmp(this->c_str() + o, s, l); } }; + +namespace std { + static inline bool operator==(const string& a, const ::RcString& b) { + return b == a; + } + static inline bool operator!=(const string& a, const ::RcString& b) { + return b != a; + } + template<> struct hash + { + size_t operator()(const RcString& s) const noexcept; + }; +} diff --git a/src/include/synext_macro.hpp b/src/include/synext_macro.hpp index d414ceb0..e62a6126 100644 --- a/src/include/synext_macro.hpp +++ b/src/include/synext_macro.hpp @@ -27,7 +27,10 @@ class TokenStream; class ExpandProcMacro { public: - virtual ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; + virtual ::std::unique_ptr expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) = 0; + virtual ::std::unique_ptr expand_ident(const Span& sp, const AST::Crate& crate, const RcString& ident, const TokenTree& tt, AST::Module& mod) { + ERROR(sp, E0000, "macro doesn't take an identifier"); + } }; struct MacroDef; diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index c40eb810..2d1b6bb1 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -405,7 +405,7 @@ class MacroExpander: { const RcString m_macro_filename; - const ::std::string m_crate_name; + const RcString m_crate_name; ::std::shared_ptr m_invocation_span; ParameterMappings m_mappings; @@ -418,7 +418,7 @@ class MacroExpander: public: MacroExpander(const MacroExpander& x) = delete; - MacroExpander(const ::std::string& macro_name, const Span& sp, const Ident::Hygiene& parent_hygiene, const ::std::vector& contents, ParameterMappings mappings, ::std::string crate_name): + MacroExpander(const ::std::string& macro_name, const Span& sp, const Ident::Hygiene& parent_hygiene, const ::std::vector& contents, ParameterMappings mappings, RcString crate_name): m_macro_filename( FMT("Macro:" << macro_name) ), m_crate_name( mv$(crate_name) ), m_invocation_span( new Span(sp) ), @@ -841,7 +841,7 @@ namespace case TOK_SQUARE_OPEN: return consume_tt(lex); case TOK_IDENT: - if( TARGETVER_1_29 && lex.next_tok().str() == "dyn" ) + if( TARGETVER_1_29 && lex.next_tok().istr() == "dyn" ) lex.consume(); case TOK_RWORD_SUPER: case TOK_RWORD_SELF: @@ -1345,7 +1345,7 @@ namespace return true; // Macro invocation // TODO: What about `union!` as a macro? Needs to be handled below - if( (lex.next() == TOK_IDENT && lex.next_tok().str() != "union") + if( (lex.next() == TOK_IDENT && lex.next_tok().istr() != "union") || lex.next() == TOK_RWORD_SELF || lex.next() == TOK_RWORD_SUPER || lex.next() == TOK_DOUBLE_COLON @@ -1481,7 +1481,7 @@ namespace return false; return consume_tt(lex); case TOK_IDENT: - if( lex.next_tok().str() == "union" ) + if( lex.next_tok().istr() == "union" ) { lex.consume(); if( lex.next() == TOK_EXCLAM ) @@ -1506,7 +1506,7 @@ namespace return consume_tt(lex); } } - else if( lex.next_tok().str() == "auto" ) + else if( lex.next_tok().istr() == "auto" ) { lex.consume(); if( lex.consume_if(TOK_RWORD_TRAIT) ) @@ -1960,7 +1960,7 @@ Token MacroExpander::realGetToken() DEBUG("Crate name hack"); if( m_crate_name != "" ) { - m_next_token = Token(TOK_STRING, m_crate_name); + m_next_token = Token(TOK_STRING, ::std::string(m_crate_name.c_str())); return Token(TOK_DOUBLE_COLON); } break; diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp index 9e408fd5..05b1e065 100644 --- a/src/macro_rules/macro_rules.hpp +++ b/src/macro_rules/macro_rules.hpp @@ -41,7 +41,7 @@ extern ::std::ostream& operator<<(::std::ostream& os, const MacroExpansionEnt& x /// Matching pattern entry struct MacroPatEnt { - ::std::string name; + RcString name; unsigned int name_index = 0; // TODO: Include a point span for the token? Token tok; @@ -77,7 +77,7 @@ struct MacroPatEnt { } - MacroPatEnt(::std::string name, unsigned int name_index, Type type): + MacroPatEnt(RcString name, unsigned int name_index, Type type): name( mv$(name) ), name_index( name_index ), tok(), @@ -134,7 +134,7 @@ extern::std::ostream& operator<<(::std::ostream& os, const SimplePatEnt& x); struct MacroRulesArm { /// Names for the parameters - ::std::vector< ::std::string> m_param_names; + ::std::vector m_param_names; /// Patterns ::std::vector m_pattern; @@ -164,7 +164,7 @@ public: /// Crate that defined this macro /// - Populated on deserialise if not already set - ::std::string m_source_crate; + RcString m_source_crate; Ident::Hygiene m_hygiene; @@ -181,8 +181,8 @@ public: extern ::std::unique_ptr Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod); extern MacroRulesPtr Parse_MacroRules(TokenStream& lex); -extern ::std::vector Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector< ::std::string>& names); -extern ::std::vector Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector< ::std::string>& var_names, ::std::map* var_set_ptr=nullptr); +extern ::std::vector Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector& names); +extern ::std::vector Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector& var_names, ::std::map* var_set_ptr=nullptr); extern MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector pattern, ::std::vector contents); #endif // MACROS_HPP_INCLUDED diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 4bd8a577..97e1f8f9 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -30,7 +30,7 @@ public: }; /// Parse the pattern of a macro_rules! arm -::std::vector Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector< ::std::string>& names) +::std::vector Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector& names) { TRACE_FUNCTION; Token tok; @@ -60,10 +60,10 @@ public: // TODO: Allow any reserved word case TOK_RWORD_PUB ... TOK_RWORD_UNSIZED: case TOK_IDENT: { - ::std::string name = tok.type() == TOK_IDENT ? mv$(tok.str()) : FMT(tok); + auto name = tok.type() == TOK_IDENT ? tok.istr() : RcString::new_interned(FMT(tok)); GET_CHECK_TOK(tok, lex, TOK_COLON); GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string type = mv$(tok.str()); + RcString type = tok.istr(); unsigned int idx = ::std::find( names.begin(), names.end(), name ) - names.begin(); if( idx == names.size() ) @@ -142,7 +142,7 @@ public: ::std::vector Parse_MacroRules_Cont( TokenStream& lex, enum eTokenType open, enum eTokenType close, - const ::std::vector< ::std::string>& var_names, + const ::std::vector& var_names, ::std::map* var_set_ptr/*=nullptr*/ ) { @@ -221,7 +221,7 @@ public: else if( tok.type() == TOK_IDENT || tok.type() >= TOK_RWORD_PUB ) { // Look up the named parameter in the list of param names for this arm - auto name = tok.type() == TOK_IDENT ? tok.str() : FMT(tok); + auto name = tok.type() == TOK_IDENT ? tok.istr() : RcString::new_interned(FMT(tok)); unsigned int idx = ::std::find(var_names.begin(), var_names.end(), name) - var_names.begin(); if( idx == var_names.size() ) { // TODO: `error-chain`'s quick_error macro has an arm which refers to an undefined metavar. @@ -269,7 +269,7 @@ MacroRule Parse_MacroRules_Var(TokenStream& lex) throw ParseError::Unexpected(lex, tok); } // - Pattern entries - ::std::vector< ::std::string> names; + ::std::vector names; { auto ps = lex.start_span(); rule.m_pattern = Parse_MacroRules_Pat(lex, tok.type(), close, names); @@ -294,7 +294,7 @@ MacroRule Parse_MacroRules_Var(TokenStream& lex) } // TODO: Also count the number of times each variable is used? -void enumerate_names(const ::std::vector& pats, ::std::vector< ::std::string>& names) +void enumerate_names(const ::std::vector& pats, ::std::vector& names) { for( const auto& pat : pats ) { diff --git a/src/main.cpp b/src/main.cpp index 5ffc195a..28d34da4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -351,9 +351,9 @@ int main(int argc, char *argv[]) if( crate.m_crate_type == ::AST::Crate::Type::Executable || params.test_harness || crate.m_crate_type == ::AST::Crate::Type::ProcMacro ) { bool allocator_crate_loaded = false; - ::std::string alloc_crate_name; + RcString alloc_crate_name; bool panic_runtime_loaded = false; - ::std::string panic_crate_name; + RcString panic_crate_name; bool panic_runtime_needed = false; for(const auto& ec : crate.m_extern_crates) { diff --git a/src/mir/check.cpp b/src/mir/check.cpp index b5abdb0a..0b032bbc 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -19,7 +19,6 @@ namespace { if( const auto* tep = unsized_ty.m_data.opt_TraitObject() ) { const auto& trait_path = tep->m_trait; - const auto& trait = *tep->m_trait.m_trait_ptr; if( trait_path.m_path.m_path == ::HIR::SimplePath() ) { @@ -27,8 +26,10 @@ namespace { } else { - auto vtable_ty_spath = trait_path.m_path.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; + const auto& trait = *tep->m_trait.m_trait_ptr; + + const auto& vtable_ty_spath = trait.m_vtable_path; + MIR_ASSERT(state, vtable_ty_spath != ::HIR::SimplePath(), "Trait with no vtable - " << trait_path); const auto& vtable_ref = state.m_resolve.m_crate.get_struct_by_path(state.sp, vtable_ty_spath); // Copy the param set from the trait in the trait object ::HIR::PathParams vtable_params = trait_path.m_path.m_params.clone(); diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index dd5332b6..5d32d0c8 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -75,8 +75,7 @@ namespace { { const auto& trait = *te.m_trait.m_trait_ptr; - auto vtable_ty_spath = te.m_trait.m_path.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; + const auto& vtable_ty_spath = trait.m_vtable_path; const auto& vtable_ref = resolve.m_crate.get_struct_by_path(sp, vtable_ty_spath); // Copy the param set from the trait in the trait object ::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone(); @@ -676,8 +675,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator& const auto& trait = *de.m_trait.m_trait_ptr; // Obtain vtable type `::"path"::to::Trait#vtable` - auto vtable_ty_spath = trait_path.m_path.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; + const auto& vtable_ty_spath = trait.m_vtable_path; const auto& vtable_ref = state.m_crate.get_struct_by_path(state.sp, vtable_ty_spath); // Copy the param set from the trait in the trait object ::HIR::PathParams vtable_params = trait_path.m_path.m_params.clone(); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index b8549f8a..9e749811 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -51,7 +51,7 @@ namespace { struct LoopDesc { ScopeHandle scope; - ::std::string label; + RcString label; unsigned int cur; unsigned int next; ::MIR::LValue res_value; @@ -679,7 +679,7 @@ namespace { target_block = &*it; } else { - if( target_block->label != "" && target_block->label[0] == '#' ) { + if( target_block->label != "" && target_block->label.c_str()[0] == '#' ) { TODO(node.span(), "Break within try block, want to break parent loop instead"); } } @@ -1952,7 +1952,7 @@ namespace { { m_builder.end_block(::MIR::Terminator::make_Call({ next_block, panic_block, - res.clone(), ::MIR::CallTarget::make_Intrinsic({ "platform:"+gpath.m_path.m_components.back(), gpath.m_params.clone() }), + res.clone(), ::MIR::CallTarget::make_Intrinsic({ RcString(FMT("platform:" << gpath.m_path.m_components.back())), gpath.m_params.clone() }), mv$(values) })); } @@ -2054,8 +2054,8 @@ namespace { const auto& val_ty = node.m_value->m_res_type; unsigned int idx; - if( '0' <= node.m_field[0] && node.m_field[0] <= '9' ) { - ::std::stringstream(node.m_field) >> idx; + if( ::std::isdigit(node.m_field.c_str()[0]) ) { + ::std::stringstream(node.m_field.c_str()) >> idx; m_builder.set_result( node.span(), ::MIR::LValue::make_Field({ box$(val), idx }) ); } else if( const auto* bep = val_ty.m_data.as_Path().binding.opt_Struct() ) { diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index ebef039a..63acf89d 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -311,7 +311,7 @@ TAGGED_UNION(CallTarget, Intrinsic, (Value, LValue), (Path, ::HIR::Path), (Intrinsic, struct { - ::std::string name; + RcString name; ::HIR::PathParams params; }) ); @@ -419,7 +419,7 @@ class Function { public: ::std::vector< ::HIR::TypeRef> locals; - //::std::vector< ::std::string> local_names; + //::std::vector< RcString> local_names; ::std::vector drop_flags; ::std::vector blocks; diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 6ee0d3f4..d4a1d59a 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -46,7 +46,7 @@ extern ::AST::HigherRankedBounds Parse_HRB_Opt(TokenStream& lex); extern AST::AttributeList Parse_ItemAttrs(TokenStream& lex); extern void Parse_ParentAttrs(TokenStream& lex, AST::AttributeList& out); extern AST::Attribute Parse_MetaItem(TokenStream& lex); -extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::std::string name, TokenStream& lex); +extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, RcString name, TokenStream& lex); extern TypeRef Parse_Type(TokenStream& lex, bool allow_trait_list = true); extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable); diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 6cc94d74..2735c39e 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -32,8 +32,8 @@ ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool& has_semicolon); ExprNodeP Parse_Stmt_Let(TokenStream& lex); ExprNodeP Parse_Expr0(TokenStream& lex); ExprNodeP Parse_IfStmt(TokenStream& lex); -ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime); -ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime); +ExprNodeP Parse_WhileStmt(TokenStream& lex, RcString lifetime); +ExprNodeP Parse_ForStmt(TokenStream& lex, RcString lifetime); ExprNodeP Parse_Expr_Match(TokenStream& lex); ExprNodeP Parse_Expr1(TokenStream& lex); ExprNodeP Parse_ExprMacro(TokenStream& lex, AST::Path tok); @@ -108,7 +108,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptrgetc(); } this->ungetc(); - return Token(TOK_LIFETIME, str); + return Token(TOK_LIFETIME, RcString::new_interned(str)); } else { throw ParseError::Todo("Lex Fail - Expected ' after character constant"); @@ -728,7 +728,7 @@ Token Lexer::getTokenInt() str += ch; } } - return Token(TOK_STRING, str); + return Token(TOK_STRING, mv$(str)); } default: assert(!"bugcheck"); @@ -806,7 +806,7 @@ Token Lexer::getTokenInt_RawString(bool is_byte) } } } - return Token(is_byte ? TOK_BYTESTRING : TOK_STRING, val); + return Token(is_byte ? TOK_BYTESTRING : TOK_STRING, mv$(val)); } Token Lexer::getTokenInt_Identifier(Codepoint leader, Codepoint leader2) { @@ -826,7 +826,7 @@ Token Lexer::getTokenInt_Identifier(Codepoint leader, Codepoint leader2) if( str < RWORDS[i].chars ) break; if( str == RWORDS[i].chars ) return Token((enum eTokenType)RWORDS[i].type); } - return Token(TOK_IDENT, mv$(str)); + return Token(TOK_IDENT, RcString::new_interned(str)); } // Takes the VERY lazy way of reading the float into a string then passing to strtod diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp index 5c99e049..8bfd20de 100644 --- a/src/parse/paths.cpp +++ b/src/parse/paths.cpp @@ -90,7 +90,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi return AST::Path("", Parse_PathNodes(lex, generic_mode)); } else if( GET_TOK(tok, lex) == TOK_STRING ) { - ::std::string cratename = tok.str(); + auto cratename = RcString::new_interned(tok.str()); GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); return AST::Path(cratename, Parse_PathNodes(lex, generic_mode)); } @@ -122,7 +122,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi ::AST::PathParams params; CHECK_TOK(tok, TOK_IDENT); - auto component = mv$( tok.str() ); + auto component = mv$( tok.istr() ); GET_TOK(tok, lex); if( generic_mode == PATH_GENERIC_TYPE ) @@ -166,7 +166,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi params = ::AST::PathParams { {}, ::make_vec1( TypeRef(TypeRef::TagTuple(), lex.end_span(ps), mv$(args)) ), - ::make_vec1( ::std::make_pair( ::std::string("Output"), mv$(ret_type) ) ) + ::make_vec1( ::std::make_pair( RcString::new_interned("Output"), mv$(ret_type) ) ) }; GET_TOK(tok, lex); @@ -210,7 +210,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi ::std::vector types; ::std::vector lifetimes; - ::std::vector< ::std::pair< ::std::string, TypeRef > > assoc_bounds; + ::std::vector< ::std::pair< RcString, TypeRef > > assoc_bounds; do { if( LOOK_AHEAD(lex) == TOK_GT || LOOK_AHEAD(lex) == TOK_DOUBLE_GT || LOOK_AHEAD(lex) == TOK_GTE || LOOK_AHEAD(lex) == TOK_DOUBLE_GT_EQUAL ) { @@ -225,7 +225,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi case TOK_IDENT: if( LOOK_AHEAD(lex) == TOK_EQUAL ) { - ::std::string name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_EQUAL); assoc_bounds.push_back( ::std::make_pair( mv$(name), Parse_Type(lex,false) ) ); break; diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index 239bac80..37b78123 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -46,7 +46,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) if( tok.type() == TOK_IDENT && lex.lookahead(0) == TOK_EXCLAM ) { lex.getToken(); - return AST::Pattern( AST::Pattern::TagMacro(), lex.end_span(ps), box$(Parse_MacroInvocation(ps, tok.str(), lex))); + return AST::Pattern( AST::Pattern::TagMacro(), lex.end_span(ps), box$(Parse_MacroInvocation(ps, tok.istr(), lex))); } if( tok.type() == TOK_INTERPOLATED_PATTERN ) { @@ -87,7 +87,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) if( expect_bind ) { CHECK_TOK(tok, TOK_IDENT); - auto bind_name = Ident(lex.getHygiene(), mv$(tok.str())); + auto bind_name = lex.get_ident(mv$(tok)); // If there's no '@' after it, it's a name binding only (_ pattern) if( GET_TOK(tok, lex) != TOK_AT ) { @@ -117,12 +117,12 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) break; // Known binding `ident @` case TOK_AT: - binding = AST::PatternBinding( Ident(lex.getHygiene(), mv$(tok.str())), bind_type/*MOVE*/, is_mut/*false*/ ); + binding = AST::PatternBinding( lex.get_ident(mv$(tok)), bind_type/*MOVE*/, is_mut/*false*/ ); GET_TOK(tok, lex); // '@' GET_TOK(tok, lex); // Match lex.putback() below break; default: { // Maybe bind - Ident name = Ident(lex.getHygiene(), mv$(tok.str())); + auto name = lex.get_ident(mv$(tok)); // if the pattern can be refuted (i.e this could be an enum variant), return MaybeBind if( is_refutable ) { assert(bind_type == ::AST::PatternBinding::Type::MOVE); @@ -459,7 +459,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, ProtoSpan ps, AST::Path path, } bool is_exhaustive = true; - ::std::vector< ::std::pair< ::std::string, AST::Pattern> > subpats; + ::std::vector< ::std::pair< RcString, AST::Pattern> > subpats; do { GET_TOK(tok, lex); DEBUG("tok = " << tok); @@ -500,7 +500,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, ProtoSpan ps, AST::Path path, CHECK_TOK(tok, TOK_IDENT); auto field_ident = lex.get_ident(mv$(tok)); - ::std::string field_name; + RcString field_name; GET_TOK(tok, lex); AST::Pattern pat; diff --git a/src/parse/root.cpp b/src/parse/root.cpp index b0c37a21..677dbe26 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -21,6 +21,7 @@ #include #include #include +#include template Spanned get_spanned(TokenStream& lex, ::std::function f) { @@ -36,7 +37,7 @@ Spanned get_spanned(TokenStream& lex, ::std::function f) { // Check the next two tokens #define LOOKAHEAD2(lex, tok1, tok2) ((lex).lookahead(0) == (tok1) && (lex).lookahead(1) == (tok2)) -::std::string dirname(::std::string input) { +::helpers::path dirname(::std::string input) { while( input.size() > 0 && input.back() != '/' && input.back() != '\\' ) { input.pop_back(); } @@ -110,12 +111,12 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) GET_CHECK_TOK(tok, lex, TOK_IDENT); case TOK_RWORD_IN: GET_CHECK_TOK(tok, lex, TOK_IDENT); - path.nodes().push_back( AST::PathNode(tok.str()) ); + path.nodes().push_back( AST::PathNode(tok.istr()) ); while( LOOK_AHEAD(lex) == TOK_DOUBLE_COLON ) { GET_TOK(tok, lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - path.nodes().push_back( AST::PathNode(tok.str()) ); + path.nodes().push_back( AST::PathNode(tok.istr()) ); } break; default: @@ -149,7 +150,7 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) switch(GET_TOK(tok, lex)) { case TOK_LIFETIME: - rv.m_lifetimes.push_back(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), tok.str()))); + rv.m_lifetimes.push_back(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), lex.get_ident(mv$(tok)))); break; default: throw ParseError::Unexpected(lex, tok, Token(TOK_LIFETIME)); @@ -175,7 +176,7 @@ namespace { AST::LifetimeRef get_LifetimeRef(TokenStream& lex, Token tok) { CHECK_TOK(tok, TOK_LIFETIME); - return AST::LifetimeRef(/*lex.point_span(), */Ident(lex.getHygiene(), mv$(tok.str()))); + return AST::LifetimeRef(/*lex.point_span(), */lex.get_ident(mv$(tok))); } } /// Parse type parameters in a definition @@ -242,7 +243,7 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) GET_TOK(tok, lex); if( tok.type() == TOK_IDENT ) { - ::std::string param_name = mv$(tok.str()); + auto param_name = tok.istr(); ret.add_ty_param( AST::TypeParam( lex.point_span(), ::std::move(attrs), param_name ) ); auto param_ty = TypeRef(lex.point_span(), param_name); @@ -260,7 +261,7 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) } else if( tok.type() == TOK_LIFETIME ) { - auto param_name = tok.str(); + auto param_name = tok.istr(); auto ref = get_LifetimeRef(lex, mv$(tok)); ret.add_lft_param(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), param_name) )); if( GET_TOK(tok, lex) == TOK_COLON ) @@ -621,7 +622,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::AttributeList& meta_items) bool is_pub = Parse_Publicity(lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); TypeRef type = Parse_Type(lex); @@ -658,7 +659,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) GET_TOK(tok, lex); bool is_specialisable = false; - if( tok.type() == TOK_IDENT && tok.str() == "default" ) { + if( tok.type() == TOK_IDENT && tok.istr() == "default" ) { is_specialisable = true; GET_TOK(tok, lex); } @@ -669,13 +670,13 @@ AST::Named Parse_Trait_Item(TokenStream& lex) bool fn_is_unsafe = false; ::std::string abi = ABI_RUST; - ::std::string name; + RcString name; ::AST::Item rv; switch(tok.type()) { case TOK_RWORD_STATIC: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto ty = Parse_Type(lex); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); @@ -691,7 +692,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) break; } case TOK_RWORD_CONST: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto ty = Parse_Type(lex); @@ -708,7 +709,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) case TOK_RWORD_TYPE: { auto atype_params = ::AST::GenericParams { }; GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); if( GET_TOK(tok, lex) == TOK_COLON ) { // Bounded associated type @@ -746,7 +747,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) CHECK_TOK(tok, TOK_RWORD_FN); case TOK_RWORD_FN: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); // Self allowed, prototype-form allowed (optional names and no code) auto fcn = Parse_FunctionDef(lex, abi, true, true, fn_is_unsafe, fn_is_const); if( GET_TOK(tok, lex) == TOK_BRACE_OPEN ) @@ -863,7 +864,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::AttributeList& meta_items) SET_ATTRS(lex, item_attrs); GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = mv$(tok.str()); + auto name = tok.istr(); // Tuple-like variants if( GET_TOK(tok, lex) == TOK_PAREN_OPEN ) { @@ -901,7 +902,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::AttributeList& meta_items) auto field_attrs = Parse_ItemAttrs(lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto ty = Parse_Type(lex); fields.push_back( ::AST::StructItem(mv$(field_attrs), true, mv$(name), mv$(ty)) ); @@ -966,7 +967,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::AttributeList& meta_items) bool is_pub = Parse_Publicity(lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto ty = Parse_Type(lex); @@ -1029,7 +1030,7 @@ AST::Attribute Parse_MetaItem(TokenStream& lex) throw ParseError::Unexpected(lex, tok, {TOK_IDENT, TOK_INTEGER}); } - ::std::string name = mv$(tok.str()); + auto name = tok.istr(); switch(GET_TOK(tok, lex)) { case TOK_EQUAL: @@ -1199,7 +1200,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) GET_TOK(tok, lex); bool is_specialisable = false; - if( tok.type() == TOK_IDENT && tok.str() == "default" ) { + if( tok.type() == TOK_IDENT && tok.istr() == "default" ) { is_specialisable = true; GET_TOK(tok, lex); } @@ -1211,7 +1212,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) { case TOK_RWORD_TYPE: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_EQUAL); impl.add_type(is_public, is_specialisable, name, Parse_Type(lex)); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); @@ -1226,7 +1227,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) if( tok.type() != TOK_RWORD_FN && tok.type() != TOK_RWORD_UNSAFE && !fn_is_unsafe ) { CHECK_TOK(tok, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto ty = Parse_Type(lex); GET_CHECK_TOK(tok, lex, TOK_EQUAL); @@ -1261,7 +1262,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) case TOK_RWORD_FN: { GET_CHECK_TOK(tok, lex, TOK_IDENT); // TODO: Hygine on function names? - Not in impl blocks? - ::std::string name = mv$(tok.str()); + auto name = tok.istr(); DEBUG("Function " << name); // - Self allowed, can't be prototype-form auto fcn = Parse_FunctionDefWithCode(lex, abi, true, fn_is_unsafe, fn_is_const); @@ -1298,7 +1299,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A { case TOK_RWORD_FN: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); // parse function as prototype // - no self, is prototype, is unsafe and not const auto i = ::AST::Item( Parse_FunctionDef(lex, abi, false, true, true,false) ); @@ -1316,7 +1317,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A else PUTBACK(tok, lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); auto type = Parse_Type(lex); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); @@ -1328,7 +1329,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A break; } case TOK_RWORD_TYPE: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); auto sp = lex.end_span(ps); //TODO(sp, "Extern type"); @@ -1355,7 +1356,7 @@ void Parse_Use_Inner(TokenStream& lex, ::std::vector& entries switch( GET_TOK(tok, lex) ) { case TOK_IDENT: - path.append( AST::PathNode( mv$(tok.str()), {}) ); + path.append( AST::PathNode( tok.istr(), {}) ); break; case TOK_BRACE_OPEN: // Can't be an empty list @@ -1376,7 +1377,7 @@ void Parse_Use_Inner(TokenStream& lex, ::std::vector& entries if( LOOK_AHEAD(lex) == TOK_RWORD_AS ) { GET_TOK(tok, lex); GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); } entries.push_back({ lex.point_span(), AST::Path(path), ::std::move(name) }); } @@ -1399,13 +1400,13 @@ void Parse_Use_Inner(TokenStream& lex, ::std::vector& entries } } while( GET_TOK(tok, lex) == TOK_DOUBLE_COLON ); - ::std::string name; + RcString name; // NOTE: The above loop has to run once, so the last token HAS to have been an ident if( tok.type() == TOK_RWORD_AS ) { GET_CHECK_TOK(tok, lex, TOK_IDENT); - name = mv$(tok.str()); + name = tok.istr(); } else { @@ -1455,7 +1456,7 @@ void Parse_Use_Inner(TokenStream& lex, ::std::vector& entries if( LOOK_AHEAD(lex) == TOK_STRING ) { GET_CHECK_TOK(tok, lex, TOK_STRING); - path = ::AST::Path(tok.str(), {}); + path = ::AST::Path(RcString::new_interned(tok.str()), {}); } else { @@ -1478,12 +1479,12 @@ void Parse_Use_Inner(TokenStream& lex, ::std::vector& entries } -::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan span_start, ::std::string name, TokenStream& lex) +::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan span_start, RcString name, TokenStream& lex) { Token tok; - ::std::string ident; + RcString ident; if( GET_TOK(tok, lex) == TOK_IDENT ) { - ident = mv$(tok.str()); + ident = tok.istr(); } else { PUTBACK(tok, lex); @@ -1648,7 +1649,7 @@ namespace { auto ps = lex.start_span(); - ::std::string item_name; + RcString item_name; ::AST::Item item_data; { @@ -1684,7 +1685,7 @@ namespace { // `extern "" fn ...` case TOK_RWORD_FN: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, abi, false, false,false) ); break; } // `extern "ABI" {` @@ -1699,7 +1700,7 @@ namespace { // `extern fn ...` case TOK_RWORD_FN: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, "C", false, false,false) ); break; @@ -1718,20 +1719,20 @@ namespace { // `extern crate "crate-name" as crate_name;` // NOTE: rustc doesn't allow this, keep in mrustc for for reparse support case TOK_STRING: - item_data = ::AST::Item::make_Crate({ tok.str() }); + item_data = ::AST::Item::make_Crate({ RcString::new_interned(tok.str()) }); GET_CHECK_TOK(tok, lex, TOK_RWORD_AS); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); break; // `extern crate crate_name;` // `extern crate crate_name as other_name;` case TOK_IDENT: - item_name = mv$(tok.str()); + item_name = tok.istr(); if(GET_TOK(tok, lex) == TOK_RWORD_AS) { item_data = ::AST::Item::make_Crate({ mv$(item_name) }); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); } else { PUTBACK(tok, lex); @@ -1754,7 +1755,7 @@ namespace { switch( GET_TOK(tok, lex) ) { case TOK_IDENT: { - item_name = mv$(tok.str()); + item_name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); TypeRef type = Parse_Type(lex); @@ -1766,12 +1767,12 @@ namespace { case TOK_RWORD_UNSAFE: GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, true,true/*unsafe,const*/) ); break; case TOK_RWORD_FN: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); // - self not allowed, not prototype item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, false,true/*unsafe,const*/) ); break; @@ -1788,7 +1789,7 @@ namespace { GET_TOK(tok, lex); } CHECK_TOK(tok, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_COLON); TypeRef type = Parse_Type(lex); @@ -1818,20 +1819,20 @@ namespace { } GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, abi, false, true,false/*unsafe,const*/) ); break; } // `unsafe fn` case TOK_RWORD_FN: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); // - self not allowed, not prototype item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, true,false/*unsafe,const*/) ); break; // `unsafe trait` case TOK_RWORD_TRAIT: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); auto tr = Parse_TraitDef(lex, meta_items); tr.set_is_unsafe(); item_data = ::AST::Item( ::std::move(tr) ); @@ -1852,10 +1853,10 @@ namespace { } // `unsafe auto trait` case TOK_IDENT: - if( TARGETVER_1_29 && tok.str() == "auto" ) { + if( TARGETVER_1_29 && tok.istr() == "auto" ) { GET_CHECK_TOK(tok, lex, TOK_RWORD_TRAIT); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); auto tr = Parse_TraitDef(lex, meta_items); tr.set_is_unsafe(); tr.set_is_marker(); @@ -1870,40 +1871,40 @@ namespace { // `fn` case TOK_RWORD_FN: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); // - self not allowed, not prototype item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, false,false/*unsafe,const*/) ); break; // `type` case TOK_RWORD_TYPE: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_TypeAlias(lex) ); break; // `struct` case TOK_RWORD_STRUCT: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_Struct(lex, meta_items) ); break; // `enum` case TOK_RWORD_ENUM: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_EnumDef(lex, meta_items) ); break; // Contextual keywords case TOK_IDENT: - if( tok.str() == "union" ) { + if( tok.istr() == "union" ) { GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_Union(lex, meta_items) ); } // `auto trait` - else if( TARGETVER_1_29 && tok.str() == "auto" ) { + else if( TARGETVER_1_29 && tok.istr() == "auto" ) { GET_CHECK_TOK(tok, lex, TOK_RWORD_TRAIT); GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); auto tr = Parse_TraitDef(lex, meta_items); tr.set_is_marker(); item_data = ::AST::Item( ::std::move(tr) ); @@ -1918,7 +1919,7 @@ namespace { // `trait` case TOK_RWORD_TRAIT: GET_CHECK_TOK(tok, lex, TOK_IDENT); - item_name = mv$(tok.str()); + item_name = tok.istr(); item_data = ::AST::Item( Parse_TraitDef(lex, meta_items) ); break; @@ -1926,7 +1927,7 @@ namespace { if( TARGETVER_1_29 ) { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = tok.str(); + auto name = tok.istr(); if( lex.lookahead(0) != TOK_PAREN_OPEN ) { GET_TOK(tok, lex); @@ -1934,7 +1935,7 @@ namespace { } DEBUG("name = " << name); - ::std::vector< ::std::string> names; + ::std::vector names; auto ps = lex.start_span(); GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN); auto arm_pat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names); @@ -1966,7 +1967,7 @@ namespace { case TOK_RWORD_MOD: { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = tok.istr(); DEBUG("Sub module '" << name << "'"); AST::Module submod( mod_path + name ); @@ -1992,7 +1993,7 @@ namespace { //submod.m_file_info = get_submod_file(lex.end_span(ps), mod_fileinfo, name, path_attr, LOOK_AHEAD(lex) == TOK_SEMICOLON, H::check_item_cfg(meta_items)); - ::std::string sub_path; + ::helpers::path sub_path; bool sub_file_controls_dir = true; if( mod_fileinfo.path == "-" ) { if( path_attr.size() ) { @@ -2002,15 +2003,15 @@ namespace { } else if( path_attr.size() > 0 ) { - sub_path = dirname(mod_fileinfo.path) + path_attr; + sub_path = dirname(mod_fileinfo.path) / path_attr.c_str(); } else if( mod_fileinfo.controls_dir ) { - sub_path = dirname(mod_fileinfo.path) + name; + sub_path = dirname(mod_fileinfo.path) / name.c_str(); } else { - sub_path = dirname(mod_fileinfo.path) + mod_path.nodes().back().name() + "/" + name; + sub_path = dirname(mod_fileinfo.path) / mod_path.nodes().back().name().c_str() / name.c_str(); //sub_path = mod_fileinfo.path; sub_file_controls_dir = false; } @@ -2022,14 +2023,14 @@ namespace { switch( GET_TOK(tok, lex) ) { case TOK_BRACE_OPEN: - submod.m_file_info.path = sub_path + "/"; + submod.m_file_info.path = sub_path.str() + "/"; // TODO: If cfg fails, just eat the TT until a matching #[cfg]? // - Or, mark the file infor as not being valid (so child modules don't try to load) Parse_ModRoot(lex, submod, meta_items); GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE); break; case TOK_SEMICOLON: - if( sub_path == "-" ) { + if( sub_path.str() == "-" ) { ERROR(lex.point_span(), E0000, "Cannot load module from file when reading stdin"); } else if( !H::check_item_cfg(meta_items) ) { @@ -2042,7 +2043,7 @@ namespace { { // TODO: Also search for curmod/submod.rs //::std::string newpath_file = (mod_path.nodes().size() > 1 ? dirname(mod_fileinfo.path) + mod_path.nodes()[mod_path.nodes().size()-2].name() + "/" + name + ".rs" : ""); - ::std::string newpath_file = (mod_path.nodes().size() >= 1 ? dirname(mod_fileinfo.path) + mod_path.nodes()[mod_path.nodes().size()-1].name() + "/" + name + ".rs" : ""); + ::std::string newpath_file = (mod_path.nodes().size() >= 1 ? dirname(mod_fileinfo.path) / mod_path.nodes()[mod_path.nodes().size()-1].name().c_str() / name.c_str() + ".rs" : ""); DEBUG("newpath_file = '" << newpath_file << "' " << mod_fileinfo.path << " " << mod_path); ::std::ifstream ifs_file(newpath_file); if( ifs_file.is_open() ) @@ -2061,7 +2062,7 @@ namespace { } else { - ::std::string newpath_dir = sub_path + "/"; + ::std::string newpath_dir = sub_path.str() + "/"; ::std::string newpath_file = path_attr.size() > 0 ? sub_path : sub_path + ".rs"; DEBUG("newpath_dir = '" << newpath_dir << "', newpath_file = '" << newpath_file << "'"); ::std::ifstream ifs_dir (newpath_dir + "mod.rs"); diff --git a/src/parse/token.cpp b/src/parse/token.cpp index d8a68d88..73ae7d93 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -52,6 +52,11 @@ Token::Token(enum eTokenType type): m_type(type) { } +Token::Token(enum eTokenType type, RcString str): + m_type(type), + m_data(Data::make_IString(mv$(str))) +{ +} Token::Token(enum eTokenType type, ::std::string str): m_type(type), m_data(Data::make_String(mv$(str))) @@ -163,6 +168,7 @@ Token::Token(const Token& t): assert( t.m_data.tag() != Data::TAGDEAD ); TU_MATCH(Data, (t.m_data), (e), (None, ), + (IString, m_data = Data::make_IString(e); ), (String, m_data = Data::make_String(e); ), (Integer, m_data = Data::make_Integer(e);), (Float, m_data = Data::make_Float(e);), @@ -178,6 +184,9 @@ Token Token::clone() const TU_MATCH(Data, (m_data), (e), (None, ), + (IString, + rv.m_data = Data::make_IString(e); + ), (String, rv.m_data = Data::make_String(e); ), @@ -333,8 +342,8 @@ struct EscapedString { case TOK_INTERPOLATED_IDENT: return "/*:ident*/"; case TOK_INTERPOLATED_VIS: return "/*:vis*/"; // Value tokens - case TOK_IDENT: return m_data.as_String(); - case TOK_LIFETIME: return "'" + m_data.as_String(); + case TOK_IDENT: return m_data.as_IString().c_str(); + case TOK_LIFETIME: return FMT("'" << m_data.as_IString().c_str()); case TOK_INTEGER: if( m_data.as_Integer().m_datatype == CORETYPE_ANY ) { return FMT(m_data.as_Integer().m_intval); diff --git a/src/parse/token.hpp b/src/parse/token.hpp index d5e7a6db..0d9a8015 100644 --- a/src/parse/token.hpp +++ b/src/parse/token.hpp @@ -64,6 +64,7 @@ class Token TAGGED_UNION(Data, None, (None, struct {}), + (IString, RcString), (String, ::std::string), (Integer, struct { enum eCoreType m_datatype; @@ -108,6 +109,7 @@ public: Token(enum eTokenType type); Token(enum eTokenType type, ::std::string str); + Token(enum eTokenType type, RcString str); Token(uint64_t val, enum eCoreType datatype); Token(double val, enum eCoreType datatype); Token(const InterpolatedFragment& ); @@ -115,6 +117,7 @@ public: Token(TagTakeIP, InterpolatedFragment ); enum eTokenType type() const { return m_type; } + const RcString& istr() const { return m_data.as_IString(); } ::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;)) throw ""; } @@ -135,6 +138,7 @@ public: return false; TU_MATCH(Data, (m_data, r.m_data), (e, re), (None, return true;), + (IString, return e == re; ), (String, return e == re; ), (Integer, return e.m_datatype == re.m_datatype && e.m_intval == re.m_intval;), (Float, return e.m_datatype == re.m_datatype && e.m_floatval == re.m_floatval;), diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp index 611df2ff..957bc673 100644 --- a/src/parse/tokenstream.cpp +++ b/src/parse/tokenstream.cpp @@ -138,11 +138,11 @@ Span TokenStream::point_span() const Ident TokenStream::get_ident(Token tok) const { if(tok.type() == TOK_IDENT) { - return Ident(getHygiene(), tok.str()); + return Ident(getHygiene(), tok.istr()); } else if(tok.type() == TOK_LIFETIME) { // TODO: Maybe only when it's explicitly asked for? - return Ident(getHygiene(), tok.str()); + return Ident(getHygiene(), tok.istr()); } else if( tok.type() == TOK_INTERPOLATED_IDENT ) { TODO(getPosition(), "get_ident from TOK_INTERPOLATED_IDENT"); diff --git a/src/parse/types.cpp b/src/parse/types.cpp index d261c403..979a8045 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -83,9 +83,9 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list) { lex.getToken(); // TODO: path macros - return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(ps, mv$(tok.str()), lex)); + return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(ps, tok.istr(), lex)); } - if( TARGETVER_1_29 && tok.str() == "dyn" ) + if( TARGETVER_1_29 && tok.istr() == "dyn" ) { if( lex.lookahead(0) == TOK_PAREN_OPEN ) { GET_TOK(tok, lex); @@ -283,16 +283,17 @@ TypeRef Parse_Type_Path(TokenStream& lex, ::AST::HigherRankedBounds hrbs, bool a auto ps = lex.start_span(); + auto path = Parse_Path(lex, PATH_GENERIC_TYPE); if( hrbs.empty() && !allow_trait_list ) { - return TypeRef(TypeRef::TagPath(), lex.end_span(ps), Parse_Path(lex, PATH_GENERIC_TYPE)); + return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(path)); } else { ::std::vector traits; ::std::vector lifetimes; - traits.push_back(Type_TraitPath { mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) }); + traits.push_back(Type_TraitPath { mv$(hrbs), mv$(path) }); if( allow_trait_list ) { diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 46f36923..0d7e253a 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -7,17 +7,18 @@ */ #include #include +#include #include RcString::RcString(const char* s, unsigned int len): - m_ptr(nullptr), - m_len(len) + m_ptr(nullptr) { if( len > 0 ) { - m_ptr = new unsigned int[1 + (len+1 + sizeof(unsigned int)-1) / sizeof(unsigned int)]; - *m_ptr = 1; - char* data_mut = reinterpret_cast(m_ptr + 1); + m_ptr = new unsigned int[2 + (len+1 + sizeof(unsigned int)-1) / sizeof(unsigned int)]; + m_ptr[0] = 1; + m_ptr[1] = len; + char* data_mut = reinterpret_cast(m_ptr + 2); for(unsigned int j = 0; j < len; j ++ ) data_mut[j] = s[j]; data_mut[len] = '\0'; @@ -36,14 +37,104 @@ RcString::~RcString() } } } +Ordering RcString::ord(const RcString& x) const +{ + if( m_ptr == x.m_ptr ) + return OrdEqual; + // Both can't be empty/null + if( m_ptr == nullptr ) + return OrdLess; + if( x.m_ptr == nullptr ) + return OrdGreater; + + assert(x.size() > 0); + assert(this->size() > 0); + + auto xp = x.c_str(); + auto tp = this->c_str(); + for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) + { + if( *xp != *tp ) + return ::ord((unsigned)*xp, (unsigned)*tp); + xp ++; + tp ++; + } + return ::ord((unsigned)this->size(), (unsigned)x.size()); +} +Ordering RcString::ord(const std::string& x) const +{ + if( m_ptr == nullptr && x.size() == 0 ) + return OrdEqual; + // Both can't be empty/null + if( m_ptr == nullptr ) + return OrdLess; + if( x.empty() ) + return OrdGreater; + + assert(x.size() > 0); + assert(this->size() > 0); + + auto xp = x.c_str(); + auto tp = this->c_str(); + for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) + { + if( *xp != *tp ) + return ::ord((unsigned)*xp, (unsigned)*tp); + xp ++; + tp ++; + } + return ::ord((unsigned)this->size(), (unsigned)x.size()); +} bool RcString::operator==(const char* s) const { - if( m_len == 0 ) + if( m_ptr == nullptr ) return *s == '\0'; - auto m = this->c_str(); - do { - if( *m != *s ) + const char* ts = this->c_str(); + const char* end = ts + this->size(); + // Loop while not at the end of either + while(s && ts != end) + { + if( *s != *ts ) return false; - } while( *m++ != '\0' && *s++ != '\0' ); - return true; + s ++; + ts ++; + } + // Only equal if we're at the end of both strings + return *s == '\0' && ts == end; +} + +::std::ostream& operator<<(::std::ostream& os, const RcString& x) +{ + for(size_t i = 0; i < x.size(); i ++) + { + os << x.c_str()[i]; + } + return os; +} + + +::std::set RcString_interned_strings; + +RcString RcString::new_interned(const ::std::string& s) +{ +#if 0 + auto it = RcString_interned_strings.find(s); + if( it == RcString_interned_strings.end() ) + { + it = RcString_interned_strings.insert(RcString(s)).first; + } + return *it; +#else + return *RcString_interned_strings.insert(RcString(s)).first; +#endif +} + +size_t std::hash::operator()(const RcString& s) const noexcept +{ + size_t h = 5381; + for(auto c : s) { + h = h * 33 + (unsigned)c; + } + return h; + //return hash(s.c_str(), s.size()); } diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index c2dedfcb..d26bb699 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -41,7 +41,7 @@ namespace template struct Named { - ::std::string name; + RcString name; Val value; }; template @@ -300,7 +300,7 @@ namespace } return ""; } - AST::Path lookup(const Span& sp, const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { + AST::Path lookup(const Span& sp, const RcString& name, const Ident::Hygiene& src_context, LookupMode mode) const { auto rv = this->lookup_opt(name, src_context, mode); if( !rv.is_valid() ) { switch(mode) @@ -314,7 +314,7 @@ namespace } return rv; } - static bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) { + static bool lookup_in_mod(const ::AST::Module& mod, const RcString& name, LookupMode mode, ::AST::Path& path) { switch(mode) { case LookupMode::Namespace: @@ -422,7 +422,7 @@ namespace } return false; } - AST::Path lookup_opt(const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { + AST::Path lookup_opt(const RcString& name, const Ident::Hygiene& src_context, LookupMode mode) const { DEBUG("name=" << name <<", src_context=" << src_context); // NOTE: src_context may provide a module to search if( src_context.has_mod_path() ) @@ -513,7 +513,7 @@ namespace case LookupMode::Namespace: case LookupMode::Type: { // Look up primitive types - auto ct = coretype_fromstring(name); + auto ct = coretype_fromstring(name.c_str()); if( ct != CORETYPE_INVAL ) { return ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(Span("-",0,0,0,0), ct), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); @@ -538,7 +538,7 @@ namespace return AST::Path(); } - unsigned int lookup_local(const Span& sp, const ::std::string name, LookupMode mode) { + unsigned int lookup_local(const Span& sp, const RcString name, LookupMode mode) { for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) { TU_MATCH(Ent, (*it), (e), @@ -732,7 +732,7 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L } namespace { - AST::Path split_into_crate(const Span& sp, AST::Path path, unsigned int start, const ::std::string& crate_name) + AST::Path split_into_crate(const Span& sp, AST::Path path, unsigned int start, const RcString& crate_name) { auto& nodes = path.nodes(); AST::Path np = AST::Path(crate_name, {}); @@ -1146,7 +1146,7 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex { auto& n = path_abs.nodes[i]; - if( n.name()[0] == '#' ) { + if( n.name().c_str()[0] == '#' ) { if( ! n.args().is_empty() ) { ERROR(sp, E0000, "Type parameters were not expected here"); } @@ -1157,7 +1157,7 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex char c; unsigned int idx; - ::std::stringstream ss( n.name() ); + ::std::stringstream ss( n.name().c_str() ); ss >> c; ss >> idx; assert( idx < mod->anon_mods().size() ); @@ -1367,7 +1367,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: // HACK: If this is a primitive name, and resolved to a module. // - If the next component isn't found in the located module // > Instead use the type name. - if( ! p.m_class.is_Local() && coretype_fromstring(e.nodes[0].name()) != CORETYPE_INVAL ) { + if( ! p.m_class.is_Local() && coretype_fromstring(e.nodes[0].name().c_str()) != CORETYPE_INVAL ) { if( const auto* pep = p.m_bindings.type.opt_Module() ) { const auto& pe = *pep; bool found = false; @@ -1421,7 +1421,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: } if( !found ) { - auto ct = coretype_fromstring(e.nodes[0].name()); + auto ct = coretype_fromstring(e.nodes[0].name().c_str()); p = ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(Span("-",0,0,0,0), ct), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); } @@ -1467,7 +1467,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: const auto& mp_nodes = context.m_mod.path().nodes(); // Ignore any leading anon modules unsigned int start_len = mp_nodes.size(); - while( start_len > 0 && mp_nodes[start_len-1].name()[0] == '#' ) + while( start_len > 0 && mp_nodes[start_len-1].name().c_str()[0] == '#' ) start_len --; // - Create a new path @@ -1491,7 +1491,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: assert( e.count >= 1 ); // TODO: The first super should ignore any anon modules. unsigned int start_len = e.count > mp_nodes.size() ? 0 : mp_nodes.size() - e.count; - while( start_len > 0 && mp_nodes[start_len-1].name()[0] == '#' ) + while( start_len > 0 && mp_nodes[start_len-1].name().c_str()[0] == '#' ) start_len --; // - Create a new path diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 43182faf..45fb58f5 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -32,7 +32,7 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst } throw ""; } -::std::unordered_map< ::std::string, ::AST::Module::IndexEnt >& get_mod_index(::AST::Module& mod, IndexName location) { +::std::unordered_map< RcString, ::AST::Module::IndexEnt >& get_mod_index(::AST::Module& mod, IndexName location) { switch(location) { case IndexName::Namespace: @@ -57,7 +57,7 @@ namespace { } } // namespace -void _add_item(const Span& sp, AST::Module& mod, IndexName location, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) +void _add_item(const Span& sp, AST::Module& mod, IndexName location, const RcString& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) { ASSERT_BUG(sp, ir.m_bindings.has_binding(), ""); auto& list = get_mod_index(mod, location); @@ -90,12 +90,12 @@ void _add_item(const Span& sp, AST::Module& mod, IndexName location, const ::std assert(rec.second); } } -void _add_item_type(const Span& sp, AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) +void _add_item_type(const Span& sp, AST::Module& mod, const RcString& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) { _add_item(sp, mod, IndexName::Namespace, name, is_pub, ::AST::Path(ir), error_on_collision); _add_item(sp, mod, IndexName::Type, name, is_pub, mv$(ir), error_on_collision); } -void _add_item_value(const Span& sp, AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) +void _add_item_value(const Span& sp, AST::Module& mod, const RcString& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true) { _add_item(sp, mod, IndexName::Value, name, is_pub, mv$(ir), error_on_collision); } @@ -237,7 +237,7 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) DEBUG(i_data.name << " - Not a macro"); } TU_ARMA(MacroRules, e) { - ::std::vector<::std::string> path; + ::std::vector path; path.push_back( i_data.path.m_class.as_Absolute().crate ); for(const auto& node : i_data.path.m_class.as_Absolute().nodes ) path.push_back( node.name() ); diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 95e6d2c1..cde9cd5f 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -51,7 +51,7 @@ void Resolve_Use(::AST::Crate& crate) // How can this happen? DEBUG("Relative " << path); // EVIL HACK: If the current module is an anon module, refer to the parent - if( base_path.nodes().size() > 0 && base_path.nodes().back().name()[0] == '#' ) { + if( base_path.nodes().size() > 0 && base_path.nodes().back().name().c_str()[0] == '#' ) { AST::Path np("", {}); for( unsigned int i = 0; i < base_path.nodes().size() - 1; i ++ ) np.nodes().push_back( base_path.nodes()[i] ); @@ -65,7 +65,7 @@ void Resolve_Use(::AST::Crate& crate) (Self, DEBUG("Self " << path); // EVIL HACK: If the current module is an anon module, refer to the parent - if( base_path.nodes().size() > 0 && base_path.nodes().back().name()[0] == '#' ) { + if( base_path.nodes().size() > 0 && base_path.nodes().back().name().c_str()[0] == '#' ) { AST::Path np("", {}); for( unsigned int i = 0; i < base_path.nodes().size() - 1; i ++ ) np.nodes().push_back( base_path.nodes()[i] ); @@ -86,7 +86,7 @@ void Resolve_Use(::AST::Crate& crate) // TODO: Do this in a cleaner manner. unsigned int n_anon = 0; // Skip any anon modules in the way (i.e. if the current module is an anon, go to the parent) - while( base_path.nodes().size() > n_anon && base_path.nodes()[ base_path.nodes().size()-1-n_anon ].name()[0] == '#' ) + while( base_path.nodes().size() > n_anon && base_path.nodes()[ base_path.nodes().size()-1-n_anon ].name().c_str()[0] == '#' ) n_anon ++; for( unsigned int i = 0; i < base_path.nodes().size() - e.count - n_anon; i ++ ) np.nodes().push_back( base_path.nodes()[i] ); @@ -252,13 +252,13 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path ::AST::Path::Bindings Resolve_Use_GetBinding_Mod( const Span& span, const ::AST::Crate& crate, const ::AST::Path& source_mod_path, const ::AST::Module& mod, - const ::std::string& des_item_name, + const RcString& des_item_name, ::std::span< const ::AST::Module* > parent_modules ) { ::AST::Path::Bindings rv; // If the desired item is an anon module (starts with #) then parse and index - if( des_item_name.size() > 0 && des_item_name[0] == '#' ) { + if( des_item_name.size() > 0 && des_item_name.c_str()[0] == '#' ) { unsigned int idx = 0; if( ::std::sscanf(des_item_name.c_str(), "#%u", &idx) != 1 ) { BUG(span, "Invalid anon path segment '" << des_item_name << "'"); @@ -283,6 +283,9 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path (MacroInv, BUG(span, "Hit MacroInv in use resolution"); ), + (Macro, + //rv.macro = ::AST::PathBinding_Macro::make_MacroRules({nullptr, e.get()}); + ), (Use, continue; // Skip for now ), @@ -479,7 +482,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path return rv; } - if( mod.path().nodes().size() > 0 && mod.path().nodes().back().name()[0] == '#' ) { + if( mod.path().nodes().size() > 0 && mod.path().nodes().back().name().c_str()[0] == '#' ) { assert( parent_modules.size() > 0 ); return Resolve_Use_GetBinding_Mod(span, crate, source_mod_path, *parent_modules.back(), des_item_name, parent_modules.subspan(0, parent_modules.size()-1)); } @@ -754,8 +757,8 @@ namespace { if( path.m_class.is_Absolute() && path.m_class.as_Absolute().crate != "" ) { const auto& path_abs = path.m_class.as_Absolute(); - ASSERT_BUG(span, crate.m_extern_crates.count(path_abs.crate), "Crate '" << path_abs.crate << "' not loaded"); - return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0); + ASSERT_BUG(span, crate.m_extern_crates.count(path_abs.crate.c_str()), "Crate '" << path_abs.crate << "' not loaded"); + return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate.c_str() ), 0); } ::AST::Path::Bindings rv; diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index ec4b8a42..07a52857 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -199,7 +199,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) // Impl ::HIR::TraitImpl impl; impl.m_type = mv$(ty); - impl.m_methods.insert(::std::make_pair( ::std::string("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); + impl.m_methods.insert(::std::make_pair( RcString::new_interned("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); // Add impl to the crate state.crate.m_trait_impls.insert(::std::make_pair( state.lang_Clone, ::std::move(impl) )); diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index b229db8b..09b63f44 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -2187,8 +2187,7 @@ namespace { } { - auto vtable_sp = trait_path.m_path; - vtable_sp.m_components.back() += "#vtable"; + const auto& vtable_sp = trait.m_vtable_path; auto vtable_params = trait_path.m_params.clone(); for(const auto& ty : trait.m_type_indexes) { auto aty = ::HIR::TypeRef( ::HIR::Path( type.clone(), trait_path.clone(), ty.first ) ); @@ -4055,7 +4054,7 @@ namespace { } } - void emit_intrinsic_call(const ::std::string& name, const ::HIR::PathParams& params, const ::MIR::Terminator::Data_Call& e) + void emit_intrinsic_call(const RcString& name, const ::HIR::PathParams& params, const ::MIR::Terminator::Data_Call& e) { const auto& mir_res = *m_mir_res; enum class Ordering @@ -4088,7 +4087,7 @@ namespace { } throw ""; }; - auto get_atomic_ordering = [&](const ::std::string& name, size_t prefix_len)->Ordering { + auto get_atomic_ordering = [&](const RcString& name, size_t prefix_len)->Ordering { if( name.size() < prefix_len ) { return Ordering::SeqCst; @@ -5024,7 +5023,7 @@ namespace { || name == "atomic_min" || name.compare(0, 7+3+1, "atomic_min_") == 0 ) { auto ordering = get_atomic_ordering(name, 7+3+1); const auto& ty = params.m_types.at(0); - const char* op = (name[7+1] == 'a' ? "imax" : "imin"); // m'a'x vs m'i'n + const char* op = (name.c_str()[7+1] == 'a' ? "imax" : "imin"); // m'a'x vs m'i'n emit_lvalue(e.ret_val); m_of << " = __mrustc_atomicloop" << get_prim_size(ty) << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ", " << get_atomic_ty_gcc(ordering) << ", __mrustc_op_" << op << get_prim_size(ty); m_of << ")"; @@ -5033,7 +5032,7 @@ namespace { || name == "atomic_umin" || name.compare(0, 7+4+1, "atomic_umin_") == 0 ) { auto ordering = get_atomic_ordering(name, 7+4+1); const auto& ty = params.m_types.at(0); - const char* op = (name[7+2] == 'a' ? "umax" : "umin"); // m'a'x vs m'i'n + const char* op = (name.c_str()[7+2] == 'a' ? "umax" : "umin"); // m'a'x vs m'i'n emit_lvalue(e.ret_val); m_of << " = __mrustc_atomicloop" << get_prim_size(ty) << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ", " << get_atomic_ty_gcc(ordering) << ", __mrustc_op_" << op << get_prim_size(ty); m_of << ")"; diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index 032e6afa..50d36a8a 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -328,9 +328,9 @@ namespace const auto& te = t.m_data.as_TraitObject(); //auto vtp = t.m_data.as_TraitObject().m_trait.m_path; - auto vtable_gp = te.m_trait.m_path.clone(); - vtable_gp.m_path.m_components.back() += "#vtable"; const auto& trait = resolve.m_crate.get_trait_by_path(sp, te.m_trait.m_path.m_path); + auto vtable_gp = ::HIR::GenericPath(trait.m_vtable_path); + vtable_gp.m_params = te.m_trait.m_path.m_params.clone(); vtable_gp.m_params.m_types.resize( vtable_gp.m_params.m_types.size() + trait.m_type_indexes.size() ); for(const auto& ty : trait.m_type_indexes) { auto aty = te.m_trait.m_type_bounds.at(ty.first).clone(); @@ -948,8 +948,7 @@ namespace ::HIR::TypeRef vtable_ty; { - auto vtable_sp = trait_path.m_path; - vtable_sp.m_components.back() += "#vtable"; + const auto& vtable_sp = trait.m_vtable_path; auto vtable_params = trait_path.m_params.clone(); for(const auto& ty : trait.m_type_indexes) { auto aty = ::HIR::TypeRef( ::HIR::Path( type.clone(), trait_path.clone(), ty.first ) ); diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 4567c0e7..a2ecb408 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -592,8 +592,7 @@ namespace { const auto& trait = *te.m_trait.m_trait_ptr; ASSERT_BUG(Span(), ! te.m_trait.m_path.m_path.m_components.empty(), "TODO: Data trait is empty, what can be done?"); - auto vtable_ty_spath = te.m_trait.m_path.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; + const auto& vtable_ty_spath = trait.m_vtable_path; const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_ty_spath); // Copy the param set from the trait in the trait object ::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone(); @@ -1039,8 +1038,7 @@ void Trans_Enumerate_Types(EnumState& state) const auto& gpath = ent.first.m_data.as_UfcsKnown().trait; const auto& trait = state.crate.get_trait_by_path(sp, gpath.m_path); - auto vtable_ty_spath = gpath.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; + const auto& vtable_ty_spath = trait.m_vtable_path; const auto& vtable_ref = state.crate.get_struct_by_path(sp, vtable_ty_spath); // Copy the param set from the trait in the trait object ::HIR::PathParams vtable_params = gpath.m_params.clone(); @@ -1775,7 +1773,7 @@ namespace { TU_IFLET( ::HIR::ValueItem, vi.second->ent, Function, i, if( i.m_code.m_mir && i.m_linkage.name != "" && i.m_linkage.name == name ) { - out_path = (mod_path + vi.first.c_str()).get_simple_path(); + out_path = (mod_path + vi.first).get_simple_path(); return &i; } ) @@ -1784,7 +1782,7 @@ namespace { for(const auto& ti : mod.m_mod_items) { TU_IFLET( ::HIR::TypeItem, ti.second->ent, Module, i, - if( auto rv = find_function_by_link_name(i, mod_path + ti.first.c_str(), name, out_path) ) + if( auto rv = find_function_by_link_name(i, mod_path + ti.first, name, out_path) ) return rv; ) } diff --git a/src/trans/mangling.cpp b/src/trans/mangling.cpp index 741d13dd..5d7584ed 100644 --- a/src/trans/mangling.cpp +++ b/src/trans/mangling.cpp @@ -22,18 +22,27 @@ #include namespace { - ::std::string escape_str(const ::std::string& s) { + ::std::string escape_str(const char* s, size_t len) { ::std::string output; - output.reserve(s.size() + 1); - for(auto v : s) + output.reserve(len + 1); + for(auto vp = s; vp != s + len; vp ++) + { + auto v= *vp; if( v == '#' ) output += "$H"; else if( v == '-' ) output += "_"; else output += v; + } return output; } + ::std::string escape_str(const RcString& s) { + return escape_str(s.c_str(), s.size()); + } + ::std::string escape_str(const ::std::string& s) { + return escape_str(s.c_str(), s.size()); + } ::FmtLambda emit_params(const ::HIR::PathParams& params) { return FMT_CB(ss, -- cgit v1.2.3 From 6343f85577b2a28fe2476860420a6d7f394a98d1 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 4 Jun 2019 07:35:15 +0800 Subject: HIR - Use maps-of-vectors for impl lists for faster lookup, optimise Trans_Enumerate --- src/hir/deserialise.cpp | 41 +++--- src/hir/from_ast.cpp | 16 +- src/hir/hir.hpp | 14 +- src/hir/hir_ops.cpp | 162 ++++++++++++++------- src/hir/serialise.cpp | 48 ++++-- src/hir/visitor.cpp | 27 +++- src/hir_conv/resolve_ufcs_outer.cpp | 43 ++++++ src/hir_expand/closures.cpp | 103 ++++++------- src/hir_typeck/outer.cpp | 13 +- src/trans/auto_impls.cpp | 11 +- src/trans/enumerate.cpp | 281 +++++++++++++++++++++--------------- src/trans/trans_list.cpp | 2 +- src/trans/trans_list.hpp | 4 +- 13 files changed, 477 insertions(+), 288 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 35aeacca..9d5b6cd2 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -123,6 +123,20 @@ } return rv; } + template + ::std::map< ::HIR::SimplePath,V> deserialise_pathmap() + { + TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); + size_t n = m_in.read_count(); + ::std::map< ::HIR::SimplePath, V> rv; + //rv.reserve(n); + for(size_t i = 0; i < n; i ++) + { + auto s = deserialise_simplepath(); + rv.insert( ::std::make_pair( mv$(s), D::des(*this) ) ); + } + return rv; + } template ::std::vector deserialise_vec() @@ -779,6 +793,9 @@ DEF_D( ::std::unique_ptr, return d.deserialise_ptr(); ) + template + DEF_D( ::std::vector, + return d.deserialise_vec(); ) template struct D< ::std::pair > { static ::std::pair des(HirDeserialiser& d) { auto a = D::des(d); @@ -817,6 +834,8 @@ template<> DEF_D( ::HIR::ProcMacro, return d.deserialise_procmacro(); ) template<> DEF_D( ::HIR::TypeImpl, return d.deserialise_typeimpl(); ) + template<> DEF_D( ::HIR::TraitImpl, return d.deserialise_traitimpl(); ) + template<> DEF_D( ::HIR::MarkerImpl, return d.deserialise_markerimpl(); ) template<> DEF_D( ::MacroRulesPtr, return d.deserialise_macrorulesptr(); ) template<> DEF_D( unsigned int, return static_cast(d.deserialise_count()); ) @@ -1306,24 +1325,12 @@ rv.m_crate_name = this->m_crate_name; rv.m_root_module = deserialise_module(); - rv.m_type_impls = deserialise_vec< ::HIR::TypeImpl>(); + rv.m_named_type_impls = deserialise_pathmap< ::std::vector<::HIR::TypeImpl>>(); + rv.m_primitive_type_impls = deserialise_vec< ::HIR::TypeImpl>(); + rv.m_generic_type_impls = deserialise_vec< ::HIR::TypeImpl>(); - { - size_t n = m_in.read_count(); - for(size_t i = 0; i < n; i ++) - { - auto p = deserialise_simplepath(); - rv.m_trait_impls.insert( ::std::make_pair( mv$(p), deserialise_traitimpl() ) ); - } - } - { - size_t n = m_in.read_count(); - for(size_t i = 0; i < n; i ++) - { - auto p = deserialise_simplepath(); - rv.m_marker_impls.insert( ::std::make_pair( mv$(p), deserialise_markerimpl() ) ); - } - } + rv.m_trait_impls = deserialise_pathmap< ::std::vector<::HIR::TraitImpl>>(); + rv.m_marker_impls = deserialise_pathmap< ::std::vector<::HIR::MarkerImpl>>(); rv.m_exported_macros = deserialise_istrumap< ::MacroRulesPtr>(); rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>(); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 84980818..cb8438bf 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1615,6 +1615,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat { if( !i.data.is_Impl() ) continue; const auto& impl = i.data.as_Impl(); + const Span impl_span; auto params = LowerHIR_GenericParams(impl.def().params(), nullptr); TRACE_FUNCTION_F("IMPL " << impl.def()); @@ -1675,7 +1676,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ) } - hir_crate.m_trait_impls.insert( ::std::make_pair(mv$(trait_name), ::HIR::TraitImpl { + hir_crate.m_trait_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::TraitImpl>()) ).first->second.push_back( ::HIR::TraitImpl { mv$(params), mv$(trait_args), mv$(type), @@ -1686,7 +1687,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat mv$(types), LowerHIR_SimplePath(Span(), ast_mod.path()) - }) ); + } ); } else if( impl.def().type().m_data.is_None() ) { @@ -1695,14 +1696,14 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat else { auto type = LowerHIR_Type(impl.def().type()); - hir_crate.m_marker_impls.insert( ::std::make_pair( mv$(trait_name), ::HIR::MarkerImpl { + hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), true, mv$(type), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ) ); + } ); } } else @@ -1748,7 +1749,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ) } - hir_crate.m_type_impls.push_back( ::HIR::TypeImpl { + // Sorted later on + hir_crate.m_generic_type_impls.push_back( ::HIR::TypeImpl { mv$(params), mv$(type), mv$(methods), @@ -1769,14 +1771,14 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto trait_name = mv$(trait.m_path); auto trait_args = mv$(trait.m_params); - hir_crate.m_marker_impls.insert( ::std::make_pair( mv$(trait_name), ::HIR::MarkerImpl { + hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), false, mv$(type), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ) ); + } ); } } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 3f045dd2..12b874a7 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -527,11 +527,17 @@ public: Module m_root_module; - /// Impl blocks on just a type - ::std::vector< ::HIR::TypeImpl > m_type_impls; + /// Impl blocks on just a type, split into three groups + // - Named type (sorted on the path) + // - Primitive types + // - Unsorted (generics, and everything before outer type resolution) + ::std::map<::HIR::SimplePath, ::std::vector<::HIR::TypeImpl>> m_named_type_impls; + ::std::vector< ::HIR::TypeImpl> m_primitive_type_impls; + ::std::vector< ::HIR::TypeImpl> m_generic_type_impls; + /// Impl blocks - ::std::multimap< ::HIR::SimplePath, ::HIR::TraitImpl > m_trait_impls; - ::std::multimap< ::HIR::SimplePath, ::HIR::MarkerImpl > m_marker_impls; + ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::TraitImpl> > m_trait_impls; + ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::MarkerImpl> > m_marker_impls; /// Macros exported by this crate ::std::unordered_map< RcString, ::MacroRulesPtr > m_exported_macros; diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index 32c70a72..a484b5eb 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -15,9 +15,9 @@ #include namespace { - bool matches_genericpath(const ::HIR::GenericParams& params, const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic); + bool matches_genericpath(const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic); - bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) + bool matches_type_int(const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) { assert(! left.m_data.is_Infer() ); const auto& right = (right_in.m_data.is_Infer() || (right_in.m_data.is_Generic() && expand_generic) ? ty_res(right_in) : right_in); @@ -97,7 +97,7 @@ namespace { return false; ), (Generic, - return matches_genericpath(params, ple, pre, ty_res, expand_generic); + return matches_genericpath( ple, pre, ty_res, expand_generic); ) ) ), @@ -105,7 +105,7 @@ namespace { throw ""; ), (TraitObject, - if( !matches_genericpath(params, le.m_trait.m_path, re.m_trait.m_path, ty_res, expand_generic) ) + if( !matches_genericpath(le.m_trait.m_path, re.m_trait.m_path, ty_res, expand_generic) ) return false; if( le.m_markers.size() != re.m_markers.size() ) return false; @@ -113,7 +113,7 @@ namespace { { const auto& lm = le.m_markers[i]; const auto& rm = re.m_markers[i]; - if( !matches_genericpath(params, lm, rm, ty_res, expand_generic) ) + if( !matches_genericpath(lm, rm, ty_res, expand_generic) ) return false; } return true; @@ -122,32 +122,32 @@ namespace { throw "Unexpected ErasedType in matches_type_int"; ), (Array, - if( ! matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic) ) + if( ! matches_type_int(*le.inner, *re.inner, ty_res, expand_generic) ) return false; if( le.size_val != re.size_val ) return false; return true; ), (Slice, - return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); + return matches_type_int(*le.inner, *re.inner, ty_res, expand_generic); ), (Tuple, if( le.size() != re.size() ) return false; for( unsigned int i = 0; i < le.size(); i ++ ) - if( !matches_type_int(params, le[i], re[i], ty_res, expand_generic) ) + if( !matches_type_int(le[i], re[i], ty_res, expand_generic) ) return false; return true; ), (Borrow, if( le.type != re.type ) return false; - return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); + return matches_type_int(*le.inner, *re.inner, ty_res, expand_generic); ), (Pointer, if( le.type != re.type ) return false; - return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); + return matches_type_int(*le.inner, *re.inner, ty_res, expand_generic); ), (Function, if( le.is_unsafe != re.is_unsafe ) @@ -157,9 +157,9 @@ namespace { if( le.m_arg_types.size() != re.m_arg_types.size() ) return false; for( unsigned int i = 0; i < le.m_arg_types.size(); i ++ ) - if( !matches_type_int(params, le.m_arg_types[i], re.m_arg_types[i], ty_res, expand_generic) ) + if( !matches_type_int(le.m_arg_types[i], re.m_arg_types[i], ty_res, expand_generic) ) return false; - return matches_type_int(params, *le.m_rettype, *re.m_rettype, ty_res, expand_generic); + return matches_type_int(*le.m_rettype, *re.m_rettype, ty_res, expand_generic); ), (Closure, return le.node == re.node; @@ -167,7 +167,7 @@ namespace { ) return false; } - bool matches_genericpath(const ::HIR::GenericParams& params, const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) + bool matches_genericpath(const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) { if( left.m_path.m_crate_name != right.m_path.m_crate_name ) return false; @@ -188,7 +188,7 @@ namespace { } for( unsigned int i = 0; i < right.m_params.m_types.size(); i ++ ) { - if( ! matches_type_int(params, left.m_params.m_types[i], right.m_params.m_types[i], ty_res, expand_generic) ) + if( ! matches_type_int(left.m_params.m_types[i], right.m_params.m_types[i], ty_res, expand_generic) ) return false; } } @@ -196,23 +196,6 @@ namespace { } } -//::HIR::TypeRef HIR::Function::make_ty(const Span& sp, const ::HIR::PathParams& params) const -//{ -// // TODO: Obtain function type for this function (i.e. a type that is specifically for this function) -// auto fcn_ty_data = ::HIR::FunctionType { -// m_is_unsafe, -// m_abi, -// box$( monomorphise_type(sp, m_params, params, m_return) ), -// {} -// }; -// fcn_ty_data.m_arg_types.reserve( m_args.size() ); -// for(const auto& arg : m_args) -// { -// fcn_ty_data.m_arg_types.push_back( monomorphise_type(sp, m_params, params, arg.second) ); -// } -// return ::HIR::TypeRef( mv$(fcn_ty_data) ); -//} - namespace { bool is_unbounded_infer(const ::HIR::TypeRef& type) { if( const auto* e = type.m_data.opt_Infer() ) { @@ -234,21 +217,21 @@ bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_reso if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } - return matches_type_int(m_params, m_type, type, ty_res, true); + return matches_type_int(m_type, type, ty_res, true); } bool ::HIR::TypeImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } - return matches_type_int(m_params, m_type, type, ty_res, true); + return matches_type_int(m_type, type, ty_res, true); } bool ::HIR::MarkerImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } - return matches_type_int(m_params, m_type, type, ty_res, true); + return matches_type_int(m_type, type, ty_res, true); } namespace { @@ -954,13 +937,15 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const { - auto its = this->m_trait_impls.equal_range( trait ); - for( auto it = its.first; it != its.second; ++ it ) + auto it = this->m_trait_impls.find( trait ); + if( it != this->m_trait_impls.end() ) { - const auto& impl = it->second; - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { - return true; + for(const auto& impl : it->second) + { + if( impl.matches_type(type, ty_res) ) { + if( callback(impl) ) { + return true; + } } } } @@ -974,13 +959,15 @@ bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR: } bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const { - auto its = this->m_marker_impls.equal_range( trait ); - for( auto it = its.first; it != its.second; ++ it ) + auto it = this->m_marker_impls.find( trait ); + if( it != this->m_marker_impls.end() ) { - const auto& impl = it->second; - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { - return true; + for(const auto& impl : it->second) + { + if( impl.matches_type(type, ty_res) ) { + if( callback(impl) ) { + return true; + } } } } @@ -992,21 +979,90 @@ bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const : } return false; } -bool ::HIR::Crate::find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +namespace { - // TODO: Restrict which crate is searched based on the type. - for( const auto& impl : this->m_type_impls ) + bool find_type_impls_list(const ::std::vector& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) { - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { - return true; + for(const auto& impl : impl_list) + { + if( impl.matches_type(type, ty_res) ) + { + if( callback(impl) ) + { + return true; + } } } + return false; + } + bool find_type_impls_int(const ::HIR::Crate& crate, const ::HIR::SimplePath* sort_path, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) + { + // 1. Find named impls (associated with named types) + if( sort_path ) + { + // TODO: This fails if the type is marked as #[fundamental] + //if( sort_path->m_crate_name != crate.m_crate_name ) { + // return false; + //} + + auto impl_list_it = crate.m_named_type_impls.find(*sort_path); + if( impl_list_it != crate.m_named_type_impls.end() ) + { + if( find_type_impls_list(impl_list_it->second, type, ty_res, callback) ) + return true; + } + } + // - If this type has no associated path, look in the primitives list + else + { + if( find_type_impls_list(crate.m_primitive_type_impls, type, ty_res, callback) ) + return true; + } + + // 2. Search fully generic list? + if( find_type_impls_list(crate.m_generic_type_impls, type, ty_res, callback) ) + return true; + + return false; + } +} +bool ::HIR::Crate::find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +{ + const ::HIR::SimplePath* path = nullptr; + // - Generic paths get sorted + if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) + { + path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; + } + // - So do trait objects + else if( type.m_data.is_TraitObject() ) + { + path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; + } + else + { + // Keep as nullptr, will search primitive list + } + + if( path ) + { + DEBUG(type << ", path=" << *path); + } + else + { + DEBUG(type << ", no path"); + } + + // > Current crate + if( find_type_impls_int(*this, path, type, ty_res, callback) ) + { + return true; } for( const auto& ec : this->m_ext_crates ) { //DEBUG("- " << ec.first); - if( ec.second.m_data->find_type_impls(type, ty_res, callback) ) { + if( find_type_impls_int(*ec.second.m_data, path, type, ty_res, callback) ) + { return true; } } diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index fc53e245..83e6d016 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -39,6 +39,16 @@ } } template + void serialise_pathmap(const ::std::map< ::HIR::SimplePath,V>& map) + { + m_out.write_count(map.size()); + for(const auto& v : map) { + DEBUG("- " << v.first); + serialise(v.first); + serialise(v.second); + } + } + template void serialise_strmap(const ::std::unordered_map& map) { m_out.write_count(map.size()); @@ -87,6 +97,11 @@ serialise(i); } template + void serialise(const ::std::vector& vec) + { + serialise_vec(vec); + } + template void serialise(const ::HIR::VisEnt& e) { m_out.write_bool(e.publicity.is_global()); // At this stage, we only care if the item is visible outside the crate or not @@ -299,20 +314,13 @@ m_out.write_string(crate.m_crate_name); serialise_module(crate.m_root_module); - m_out.write_count(crate.m_type_impls.size()); - for(const auto& impl : crate.m_type_impls) { - serialise_typeimpl(impl); - } - m_out.write_count(crate.m_trait_impls.size()); - for(const auto& tr_impl : crate.m_trait_impls) { - serialise_simplepath(tr_impl.first); - serialise_traitimpl(tr_impl.second); - } - m_out.write_count(crate.m_marker_impls.size()); - for(const auto& tr_impl : crate.m_marker_impls) { - serialise_simplepath(tr_impl.first); - serialise_markerimpl(tr_impl.second); - } + //std::map> + serialise_pathmap(crate.m_named_type_impls); + serialise_vec(crate.m_primitive_type_impls); + serialise_vec(crate.m_generic_type_impls); + + serialise_pathmap(crate.m_trait_impls); + serialise_pathmap(crate.m_marker_impls); serialise_strmap(crate.m_exported_macros); { @@ -373,6 +381,10 @@ } // m_src_module doesn't matter after typeck } + void serialise(const ::HIR::TypeImpl& impl) + { + serialise_typeimpl(impl); + } void serialise_traitimpl(const ::HIR::TraitImpl& impl) { TRACE_FUNCTION_F("impl" << impl.m_params.fmt_args() << " ?" << impl.m_trait_args << " for " << impl.m_type); @@ -410,6 +422,10 @@ } // m_src_module doesn't matter after typeck } + void serialise(const ::HIR::TraitImpl& impl) + { + serialise_traitimpl(impl); + } void serialise_markerimpl(const ::HIR::MarkerImpl& impl) { serialise_generics(impl.m_params); @@ -417,6 +433,10 @@ m_out.write_bool(impl.is_positive); serialise_type(impl.m_type); } + void serialise(const ::HIR::MarkerImpl& impl) + { + serialise_markerimpl(impl); + } void serialise(const ::HIR::TypeRef& ty) { serialise_type(ty); diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index f23bae88..8bf674b3 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -16,17 +16,34 @@ void ::HIR::Visitor::visit_crate(::HIR::Crate& crate) { this->visit_module(::HIR::ItemPath(crate.m_crate_name), crate.m_root_module ); - for( auto& ty_impl : crate.m_type_impls ) + for( auto& ty_impl_group : crate.m_named_type_impls ) + { + for( auto& ty_impl : ty_impl_group.second ) + { + this->visit_type_impl(ty_impl); + } + } + for( auto& ty_impl : crate.m_primitive_type_impls ) { this->visit_type_impl(ty_impl); } - for( auto& impl : crate.m_trait_impls ) + for( auto& ty_impl : crate.m_generic_type_impls ) { - this->visit_trait_impl(impl.first, impl.second); + this->visit_type_impl(ty_impl); } - for( auto& impl : crate.m_marker_impls ) + for( auto& impl_group : crate.m_trait_impls ) { - this->visit_marker_impl(impl.first, impl.second); + for( auto& impl : impl_group.second ) + { + this->visit_trait_impl(impl_group.first, impl); + } + } + for( auto& impl_group : crate.m_marker_impls ) + { + for( auto& impl : impl_group.second ) + { + this->visit_marker_impl(impl_group.first, impl); + } } } diff --git a/src/hir_conv/resolve_ufcs_outer.cpp b/src/hir_conv/resolve_ufcs_outer.cpp index a8accf4d..285f6e55 100644 --- a/src/hir_conv/resolve_ufcs_outer.cpp +++ b/src/hir_conv/resolve_ufcs_outer.cpp @@ -13,6 +13,7 @@ #include #include #include // monomorphise_genericpath_needed +#include namespace { class Visitor: @@ -342,4 +343,46 @@ void ConvertHIR_ResolveUFCS_Outer(::HIR::Crate& crate) { Visitor exp { crate }; exp.visit_crate( crate ); + + // Sort impls! + auto new_end = ::std::remove_if(crate.m_generic_type_impls.begin(), crate.m_generic_type_impls.end(), [&crate](::HIR::TypeImpl& ty_impl) { + const auto& type = ty_impl.m_type; + const ::HIR::SimplePath* path = nullptr; + // - Generic paths get sorted + if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) + { + path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; + } + // - So do trait objects + else if( type.m_data.is_TraitObject() ) + { + path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; + } + else + { + // Keep as nullptr, will search primitive list + } + + if( path ) + { + auto it = crate.m_named_type_impls.find(*path); + if( it == crate.m_named_type_impls.end() ) + { + it = crate.m_named_type_impls.insert( ::std::make_pair(*path, ::std::vector<::HIR::TypeImpl>()) ).first; + } + it->second.push_back(mv$(ty_impl)); + } + else if( type.m_data.is_Path() || type.m_data.is_Generic() ) + { + return false; + } + else + { + crate.m_primitive_type_impls.push_back(mv$(ty_impl)); + } + return true; + }); + crate.m_generic_type_impls.erase(new_end, crate.m_generic_type_impls.end()); + + DEBUG("Impl counts: " << crate.m_named_type_impls.size() << " path groups, " << crate.m_primitive_type_impls.size() << " primitive, " << crate.m_generic_type_impls.size() << " ungrouped"); } diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 94f272f8..b4ab564c 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -46,6 +46,48 @@ namespace { return rv; } + void push_new_impls(const Span& sp, ::HIR::Crate& crate, out_impls_t new_trait_impls) + { + for(auto& impl : new_trait_impls) + { + switch(impl.first) + { + case ::HIR::ExprNode_Closure::Class::Once: + crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_once")].push_back( mv$(impl.second) ); + break; + case ::HIR::ExprNode_Closure::Class::Mut: + crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_mut" )].push_back( mv$(impl.second) ); + break; + case ::HIR::ExprNode_Closure::Class::Shared: + crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].push_back( mv$(impl.second) ); + break; + case ::HIR::ExprNode_Closure::Class::NoCapture: { + assert(impl.second.m_methods.size() == 1); + assert(impl.second.m_types.empty()); + assert(impl.second.m_constants.empty()); + // NOTE: This should always have a name + const auto& path = impl.second.m_type.m_data.as_Path().path.m_data.as_Generic().m_path; + DEBUG("Adding type impl " << path); + auto list_it = crate.m_named_type_impls.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; + list_it->second.push_back( ::HIR::TypeImpl { + mv$(impl.second.m_params), + mv$(impl.second.m_type), + make_map1( + impl.second.m_methods.begin()->first, + ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { ::HIR::Publicity::new_global(), false, mv$(impl.second.m_methods.begin()->second.data) } + ), + {}, + mv$(impl.second.m_src_module) + } ); + } break; + case ::HIR::ExprNode_Closure::Class::Unknown: + BUG(Span(), "Encountered Unkown closure type in new impls"); + break; + } + } + new_trait_impls.resize(0); + } + /// Mutate the contents of a closure to update captures, variables, and types class ExprVisitor_Mutate: public ::HIR::ExprVisitorDef @@ -1190,37 +1232,8 @@ namespace { ::HIR::Visitor::visit_crate(crate); - for(auto& impl : m_new_trait_impls) - { - switch(impl.first) - { - case ::HIR::ExprNode_Closure::Class::Once: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_once"), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::Mut: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_mut" ), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::Shared: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn" ), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::NoCapture: - assert(impl.second.m_methods.size() == 1); - assert(impl.second.m_types.empty()); - assert(impl.second.m_constants.empty()); - crate.m_type_impls.push_back( ::HIR::TypeImpl { - mv$(impl.second.m_params), - mv$(impl.second.m_type), - make_map1(impl.second.m_methods.begin()->first, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { ::HIR::Publicity::new_global(), false, mv$(impl.second.m_methods.begin()->second.data) }), - {}, - mv$(impl.second.m_src_module) - } ); - break; - case ::HIR::ExprNode_Closure::Class::Unknown: - BUG(Span(), "Encountered Unkown closure type in new impls"); - break; - } - } - m_new_trait_impls.resize(0); + push_new_impls(sp, crate, mv$(m_new_trait_impls)); + m_new_trait_impls.clear(); } void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override @@ -1399,34 +1412,8 @@ void HIR_Expand_Closures_Expr(const ::HIR::Crate& crate_ro, ::HIR::ExprPtr& exp) m.second.data.m_code.m_state->stage = ::HIR::ExprState::Stage::Typecheck; } impl.second.m_src_module = exp.m_state->m_mod_path; - switch(impl.first) - { - case ::HIR::ExprNode_Closure::Class::Once: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_once"), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::Mut: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn_mut" ), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::Shared: - crate.m_trait_impls.insert( ::std::make_pair(crate.get_lang_item_path(sp, "fn" ), mv$(impl.second)) ); - break; - case ::HIR::ExprNode_Closure::Class::NoCapture: - assert(impl.second.m_methods.size() == 1); - assert(impl.second.m_types.empty()); - assert(impl.second.m_constants.empty()); - crate.m_type_impls.push_back( ::HIR::TypeImpl { - mv$(impl.second.m_params), - mv$(impl.second.m_type), - make_map1(impl.second.m_methods.begin()->first, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { ::HIR::Publicity::new_global(), false, mv$(impl.second.m_methods.begin()->second.data) }), - {}, - mv$(impl.second.m_src_module) - } ); - break; - case ::HIR::ExprNode_Closure::Class::Unknown: - BUG(Span(), "Encountered Unkown closure type in new impls"); - break; - } } + push_new_impls(sp, crate, mv$(new_trait_impls)); } void HIR_Expand_Closures(::HIR::Crate& crate) diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index c2b216d4..38c6f652 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -506,26 +506,25 @@ namespace { ) else { // 1. Search for applicable inherent methods (COMES FIRST!) - for( const auto& impl : this->crate.m_type_impls ) - { - if( !impl.matches_type(*e.type) ) { - continue ; - } + if( this->crate.find_type_impls(*e.type, [](const auto& ty)->const auto&{return ty;}, [&](const auto& impl) { DEBUG("- matched inherent impl " << *e.type); // Search for item in this block switch( pc ) { case ::HIR::Visitor::PathContext::VALUE: if( impl.m_methods.find(e.item) == impl.m_methods.end() ) { - continue ; + return false; } // Found it, just keep going (don't care about details here) break; case ::HIR::Visitor::PathContext::TRAIT: case ::HIR::Visitor::PathContext::TYPE: - continue ; + return false; } + return true; + }) ) + { auto new_data = ::HIR::Path::Data::make_UfcsInherent({ mv$(e.type), mv$(e.item), mv$(e.params)} ); p.m_data = mv$(new_data); DEBUG("- Resolved, replace with " << p); diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index ea10c8e2..ced322a4 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -202,7 +202,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) impl.m_methods.insert(::std::make_pair( RcString::new_interned("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); // Add impl to the crate - state.crate.m_trait_impls.insert(::std::make_pair( state.lang_Clone, ::std::move(impl) )); + state.crate.m_trait_impls[state.lang_Clone].push_back( ::std::move(impl) ); } void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) @@ -227,18 +227,19 @@ void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) Trans_AutoImpl_Clone(state, mv$(ty)); } - const auto impl_range = crate.m_trait_impls.equal_range( state.lang_Clone ); + auto impl_list_it = crate.m_trait_impls.find(state.lang_Clone); for(const auto& ty : state.done_list) { + assert(impl_list_it != crate.m_trait_impls.end()); // TODO: Find a way of turning a set into a vector so items can be erased. auto p = ::HIR::Path(ty.clone(), ::HIR::GenericPath(state.lang_Clone), "clone"); //DEBUG("add_function(" << p << ")"); auto e = trans_list.add_function(::std::move(p)); - auto it = ::std::find_if( impl_range.first, impl_range.second, [&](const auto& i){ return i.second.m_type == ty; }); - assert( it->second.m_methods.size() == 1 ); - e->ptr = &it->second.m_methods.begin()->second.data; + auto it = ::std::find_if( impl_list_it->second.begin(), impl_list_it->second.end(), [&](const auto& i){ return i.m_type == ty; }); + assert( it->m_methods.size() == 1 ); + e->ptr = &it->m_methods.begin()->second.data; } } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index dfc566c0..7ef605b9 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -48,6 +48,7 @@ namespace { TransList Trans_Enumerate_CommonPost(EnumState& state); void Trans_Enumerate_Types(EnumState& state); void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, const Trans_Params& pp); +void Trans_Enumerate_FillFrom_PathMono(EnumState& state, ::HIR::Path path); void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Function& function, const Trans_Params& pp); void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Static& stat, TransList_Static& stat_out, Trans_Params pp={}); void Trans_Enumerate_FillFrom_VTable (EnumState& state, ::HIR::Path vtable_path, const Trans_Params& pp); @@ -176,100 +177,125 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) // Impl blocks StaticTraitResolve resolve { crate }; - for(auto& impl : crate.m_trait_impls) + for(auto& impl_group : crate.m_trait_impls) { - const auto& impl_ty = impl.second.m_type; - TRACE_FUNCTION_F("Impl " << impl.first << impl.second.m_trait_args << " for " << impl_ty); - if( impl.second.m_params.m_types.size() == 0 ) + const auto& trait_path = impl_group.first; + for(auto& impl : impl_group.second) { - auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.second.m_trait_args, nullptr); - - // Emit each method/static (in the trait itself) - const auto& trait = crate.get_trait_by_path(sp, impl.first); - for(const auto& vi : trait.m_values) + const auto& impl_ty = impl.m_type; + TRACE_FUNCTION_F("Impl " << trait_path << impl.m_trait_args << " for " << impl_ty); + if( impl.m_params.m_types.size() == 0 ) { - TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); - // Constant, no codegen - if( vi.second.is_Constant() ) - ; - // Generic method, no codegen - else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) - ; - // VTable, magic - else if( vi.first == "vtable#" ) - ; - else + auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.m_trait_args, nullptr); + + // Emit each method/static (in the trait itself) + const auto& trait = crate.get_trait_by_path(sp, trait_path); + for(const auto& vi : trait.m_values) { - // Check bounds before queueing for codegen - if( vi.second.is_Function() ) + TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); + // Constant, no codegen + if( vi.second.is_Constant() ) + ; + // Generic method, no codegen + else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) + ; + // VTable, magic + else if( vi.first == "vtable#" ) + ; + else { - bool rv = true; - for(const auto& b : vi.second.as_Function().m_params.m_bounds) + // Check bounds before queueing for codegen + if( vi.second.is_Function() ) { - if( !b.is_TraitBound() ) continue; - const auto& be = b.as_TraitBound(); + bool rv = true; + for(const auto& b : vi.second.as_Function().m_params.m_bounds) + { + if( !b.is_TraitBound() ) continue; + const auto& be = b.as_TraitBound(); - auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); - auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); - for(auto& ty : b_tp_mono.m_path.m_params.m_types) { - resolve.expand_associated_types(sp, ty); - } - for(auto& assoc_bound : b_tp_mono.m_type_bounds) { - resolve.expand_associated_types(sp, assoc_bound.second); - } + auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); + auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); + for(auto& ty : b_tp_mono.m_path.m_params.m_types) { + resolve.expand_associated_types(sp, ty); + } + for(auto& assoc_bound : b_tp_mono.m_type_bounds) { + resolve.expand_associated_types(sp, assoc_bound.second); + } - rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { - return true; - }); + rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { + return true; + }); + if( !rv ) + break; + } if( !rv ) - break; + continue ; } - if( !rv ) - continue ; + auto path = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(trait_path, impl.m_trait_args.clone()), vi.first); + Trans_Enumerate_FillFrom_PathMono(state, mv$(path)); + //state.enum_fcn(mv$(path), fcn.second.data, {}); } - auto p = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(impl.first, impl.second.m_trait_args.clone()), vi.first); - Trans_Enumerate_FillFrom_Path(state, p, {}); + } + for(auto& m : impl.m_methods) + { + if( m.second.data.m_params.m_types.size() > 0 ) + m.second.data.m_save_code = true; } } - for(auto& m : impl.second.m_methods) + else { - if( m.second.data.m_params.m_types.size() > 0 ) + for(auto& m : impl.m_methods) + { m.second.data.m_save_code = true; - } - } - else - { - for(auto& m : impl.second.m_methods) - { - m.second.data.m_save_code = true; + } } } } - for(auto& impl : crate.m_type_impls) + struct H1 { - if( impl.m_params.m_types.size() == 0 ) + static void enumerate_type_impl(EnumState& state, ::HIR::TypeImpl& impl) { - for(auto& fcn : impl.m_methods) + TRACE_FUNCTION_F("impl" << impl.m_params.fmt_args() << " " << impl.m_type); + if( impl.m_params.m_types.size() == 0 ) { - if( fcn.second.data.m_params.m_types.size() == 0 ) + for(auto& fcn : impl.m_methods) { - auto p = ::HIR::Path(impl.m_type.clone(), fcn.first); - Trans_Enumerate_FillFrom_Path(state, p, {}); + DEBUG("fn " << fcn.first << fcn.second.data.m_params.fmt_args()); + if( fcn.second.data.m_params.m_types.size() == 0 ) + { + auto path = ::HIR::Path(impl.m_type.clone(), fcn.first); + state.enum_fcn(mv$(path), fcn.second.data, {}); + } + else + { + fcn.second.data.m_save_code = true; + } } - else + } + else + { + for(auto& m : impl.m_methods) { - fcn.second.data.m_save_code = true; + m.second.data.m_save_code = true; } } } - else + }; + for(auto& impl_grp : crate.m_named_type_impls) + { + for(auto& impl : impl_grp.second) { - for(auto& m : impl.m_methods) - { - m.second.data.m_save_code = true; - } + H1::enumerate_type_impl(state, impl); } } + for(auto& impl : crate.m_primitive_type_impls) + { + H1::enumerate_type_impl(state, impl); + } + for(auto& impl : crate.m_generic_type_impls) + { + H1::enumerate_type_impl(state, impl); + } auto rv = Trans_Enumerate_CommonPost(state); @@ -407,7 +433,8 @@ TransList Trans_Enumerate_CommonPost(EnumState& state) return mv$(state.rv); } -namespace { +namespace +{ struct PtrComp { template @@ -420,7 +447,8 @@ namespace { ::StaticTraitResolve m_resolve; ::std::vector< ::std::pair< ::HIR::TypeRef, bool> >& out_list; - ::std::map< ::HIR::TypeRef, bool > visited; + // TODO: Have a list of indexes into `out_list`, sorted by typeref ordering + ::std::vector visited_map; ::std::set< const ::HIR::TypeRef*, PtrComp> active_set; TypeVisitor(const ::HIR::Crate& crate, ::std::vector< ::std::pair< ::HIR::TypeRef, bool > >& out_list): @@ -429,6 +457,11 @@ namespace { out_list(out_list) {} + ~TypeVisitor() + { + DEBUG("Visited a total of " << visited_map.size()); + } + void visit_struct(const ::HIR::GenericPath& path, const ::HIR::Struct& item) { static Span sp; ::HIR::TypeRef tmp; @@ -506,16 +539,16 @@ namespace { { // If the type has already been visited, AND either this is a shallow visit, or the previous wasn't { - auto it = visited.find(ty); - if( it != visited.end() ) + auto idx_it = ::std::lower_bound(visited_map.begin(), visited_map.end(), ty, [&](size_t i, const ::HIR::TypeRef& t){ return out_list[i].first < t; }); + if( idx_it != visited_map.end() && out_list[*idx_it].first == ty) { + auto it = &out_list[*idx_it]; if( it->second == false || mode == Mode::Shallow ) { // Return early return ; } DEBUG("-- " << ty << " already visited as shallow"); - it->second = false; } } TRACE_FUNCTION_F(ty << " - " << (mode == Mode::Shallow ? "Shallow" : (mode == Mode::Normal ? "Normal" : "Deep"))); @@ -635,37 +668,30 @@ namespace { bool shallow = (mode == Mode::Shallow); { - auto rv = visited.insert( ::std::make_pair(ty.clone(), shallow) ); - if( !rv.second && ! shallow ) + auto idx_it = ::std::lower_bound(visited_map.begin(), visited_map.end(), ty, [&](size_t i, const ::HIR::TypeRef& t){ return out_list[i].first < t; }); + if( idx_it == visited_map.end() || out_list[*idx_it].first != ty ) { - rv.first->second = false; + // Add a new entry + visited_map.insert(idx_it, out_list.size()); + } + else + { + // Previous visit was shallow, but this one isn't + // - Update the entry to the to-be-pushed entry with shallow=false + if( !shallow && out_list[*idx_it].second ) + { + *idx_it = out_list.size(); + } } } out_list.push_back( ::std::make_pair(ty.clone(), shallow) ); DEBUG("Add type " << ty << (shallow ? " (Shallow)": "")); } - }; -} - -// Enumerate types required for the enumerated items -void Trans_Enumerate_Types(EnumState& state) -{ - static Span sp; - TypeVisitor tv { state.crate, state.rv.m_types }; - unsigned int types_count = 0; - bool constructors_added; - do - { - // Visit all functions that haven't been type-visited yet - for(unsigned int i = 0; i < state.fcns_to_type_visit.size(); i++) + void __attribute__ ((noinline)) visit_function(const ::HIR::Path& path, const ::HIR::Function& fcn, const Trans_Params& pp) { - auto* p = state.fcns_to_type_visit[i]; - auto& fcn_path = ::std::find_if(state.rv.m_functions.begin(), state.rv.m_functions.end(), [&](const auto&x){ return x.second.get() == p; })->first; - TRACE_FUNCTION_F("Function " << fcn_path); - assert(p->ptr); - const auto& fcn = *p->ptr; - const auto& pp = p->pp; + Span sp; + auto& tv = *this; ::HIR::TypeRef tmp; auto monomorph = [&](const auto& ty)->const auto& { @@ -909,8 +935,35 @@ void Trans_Enumerate_Types(EnumState& state) } } } + }; // struct TypeVisitor +} // namespace + +// Enumerate types required for the enumerated items +void Trans_Enumerate_Types(EnumState& state) +{ + static Span sp; + TypeVisitor tv { state.crate, state.rv.m_types }; + + unsigned int types_count = 0; + bool constructors_added; + do + { + // Visit all functions that haven't been type-visited yet + for(unsigned int i = 0; i < state.fcns_to_type_visit.size(); i++) + { + auto* p = state.fcns_to_type_visit[i]; + assert(p->path); + assert(p->ptr); + auto& fcn_path = *p->path; + const auto& fcn = *p->ptr; + const auto& pp = p->pp; + + TRACE_FUNCTION_F("Function " << fcn_path); + tv.visit_function(fcn_path, fcn, pp); + } state.fcns_to_type_visit.clear(); // TODO: Similarly restrict revisiting of statics. + // - Challenging, as they're stored as a std::map for(const auto& ent : state.rv.m_statics) { TRACE_FUNCTION_F("Enumerate static " << ent.first); @@ -957,22 +1010,16 @@ void Trans_Enumerate_Types(EnumState& state) if( ty.m_data.is_Path() ) { const auto& te = ty.m_data.as_Path(); - const ::HIR::TraitMarkings* markings_ptr = nullptr; - TU_MATCHA( (te.binding), (tpb), - (Unbound, ), - (Opaque, ), - (ExternType, markings_ptr = &tpb->m_markings; ), - (Struct, markings_ptr = &tpb->m_markings; ), - (Union, markings_ptr = &tpb->m_markings; ), - (Enum, markings_ptr = &tpb->m_markings; ) - ) - ASSERT_BUG(Span(), markings_ptr, "Path binding not set correctly - " << ty); + ASSERT_BUG(sp, te.path.m_data.is_Generic(), "Non-Generic type path after enumeration - " << ty); + const auto& gp = te.path.m_data.as_Generic(); + const ::HIR::TraitMarkings* markings_ptr = te.binding.get_trait_markings(); + ASSERT_BUG(sp, markings_ptr, "Path binding not set correctly - " << ty); // If the type has a drop impl, and it's either defined in this crate or has params (and thus was monomorphised) - if( markings_ptr->has_drop_impl && (te.path.m_data.as_Generic().m_path.m_crate_name == state.crate.m_crate_name || te.path.m_data.as_Generic().m_params.has_params()) ) + if( markings_ptr->has_drop_impl && (gp.m_path.m_crate_name == state.crate.m_crate_name || gp.m_params.has_params()) ) { // Add the Drop impl to the codegen list - Trans_Enumerate_FillFrom_Path(state, ::HIR::Path( ty.clone(), state.crate.get_lang_item_path(sp, "drop"), "drop"), {}); + Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path( ty.clone(), state.crate.get_lang_item_path(sp, "drop"), "drop")); constructors_added = true; } } @@ -982,7 +1029,7 @@ void Trans_Enumerate_Types(EnumState& state) // Reqire drop glue for inner type. // - Should that already exist? // Requires box_free lang item - Trans_Enumerate_FillFrom_Path(state, ::HIR::GenericPath( state.crate.get_lang_item_path(sp, "box_free"), { ity->clone() } ), {});; + Trans_Enumerate_FillFrom_PathMono(state, ::HIR::GenericPath( state.crate.get_lang_item_path(sp, "box_free"), { ity->clone() } )); } } types_count = state.rv.m_types.size(); @@ -1278,24 +1325,27 @@ namespace MIR { void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, const Trans_Params& pp) { - TRACE_FUNCTION_F(path); - Span sp; auto path_mono = pp.monomorph(state.crate, path); - DEBUG("- " << path_mono); + Trans_Enumerate_FillFrom_PathMono(state, mv$(path_mono)); +} +void Trans_Enumerate_FillFrom_PathMono(EnumState& state, ::HIR::Path path_mono) +{ + TRACE_FUNCTION_F(path_mono); + Span sp; // TODO: If already in the list, return early - if( state.rv.m_functions.count(path) ) { + if( state.rv.m_functions.count(path_mono) ) { DEBUG("> Already done function"); return ; } - if( state.rv.m_statics.count(path) ) { + if( state.rv.m_statics.count(path_mono) ) { DEBUG("> Already done static"); return ; } - if( state.rv.m_constants.count(path) ) { + if( state.rv.m_constants.count(path_mono) ) { DEBUG("> Already done constant"); return ; } - if( state.rv.m_vtables.count(path) ) { + if( state.rv.m_vtables.count(path_mono) ) { DEBUG("> Already done vtable"); return ; } @@ -1315,7 +1365,7 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co sub_pp.self_type = pe.type->clone(); ), (UfcsUnknown, - BUG(sp, "UfcsUnknown - " << path); + BUG(sp, "UfcsUnknown - " << path_mono); ) ) // Get the item type @@ -1368,8 +1418,7 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co auto enum_impl = [&](const ::HIR::TypeRef& ity) { if( !resolve.type_is_copy(sp, ity) ) { - auto p = ::HIR::Path(ity.clone(), pe.trait.clone(), pe.item); - Trans_Enumerate_FillFrom_Path(state, p, {}); + Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path(ity.clone(), pe.trait.clone(), pe.item)); } }; if( const auto* te = inner_ty.m_data.opt_Tuple() ) { @@ -1599,7 +1648,7 @@ void Trans_Enumerate_FillFrom_VTable(EnumState& state, ::HIR::Path vtable_path, { DEBUG("- " << m.second.first << " = " << m.second.second << " :: " << m.first); auto gpath = monomorphise_genericpath_with(sp, m.second.second, monomorph_cb_trait, false); - Trans_Enumerate_FillFrom_Path(state, ::HIR::Path(type.clone(), mv$(gpath), m.first), {}); + Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path(type.clone(), mv$(gpath), m.first)); } } diff --git a/src/trans/trans_list.cpp b/src/trans/trans_list.cpp index 54ae8011..3d8aa86f 100644 --- a/src/trans/trans_list.cpp +++ b/src/trans/trans_list.cpp @@ -15,7 +15,7 @@ TransList_Function* TransList::add_function(::HIR::Path p) { DEBUG("Function " << rv.first->first); assert( !rv.first->second ); - rv.first->second.reset( new TransList_Function {} ); + rv.first->second.reset( new TransList_Function(rv.first->first) ); return &*rv.first->second; } else diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp index df550925..7009111f 100644 --- a/src/trans/trans_list.hpp +++ b/src/trans/trans_list.hpp @@ -49,12 +49,14 @@ struct CachedFunction { }; struct TransList_Function { + const ::HIR::Path* path; // Pointer into the list (std::map pointers are stable) const ::HIR::Function* ptr; Trans_Params pp; // If `pp.has_types` is true, the below is valid CachedFunction monomorphised; - TransList_Function(): + TransList_Function(const ::HIR::Path& path): + path(&path), ptr(nullptr) {} }; -- cgit v1.2.3 From a9f501bde9d8ff5e714d0ef2663177b0949f95cc Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 9 Jun 2019 20:31:41 +0800 Subject: HIR - Sort trait impls too --- src/hir/deserialise.cpp | 17 ++-- src/hir/from_ast.cpp | 10 ++- src/hir/hir.hpp | 39 +++++++-- src/hir/hir_ops.cpp | 145 ++++++++++++++++----------------- src/hir/serialise.cpp | 13 +-- src/hir/type.hpp | 18 +++++ src/hir/visitor.cpp | 47 +++++------ src/hir_conv/resolve_ufcs_outer.cpp | 76 +++++++++--------- src/hir_expand/closures.cpp | 14 ++-- src/trans/auto_impls.cpp | 6 +- src/trans/enumerate.cpp | 155 ++++++++++++++++++++---------------- 11 files changed, 308 insertions(+), 232 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 9d5b6cd2..f2794f29 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -839,6 +839,14 @@ template<> DEF_D( ::MacroRulesPtr, return d.deserialise_macrorulesptr(); ) template<> DEF_D( unsigned int, return static_cast(d.deserialise_count()); ) + template + DEF_D( ::HIR::Crate::ImplGroup, + ::HIR::Crate::ImplGroup rv; + rv.named = d.deserialise_pathmap< ::std::vector>(); + rv.non_named = d.deserialise_vec(); + rv.generic = d.deserialise_vec(); + return rv; + ) template<> DEF_D( ::HIR::ExternLibrary, return d.deserialise_extlib(); ) ::HIR::LifetimeDef HirDeserialiser::deserialise_lifetimedef() @@ -1325,12 +1333,9 @@ rv.m_crate_name = this->m_crate_name; rv.m_root_module = deserialise_module(); - rv.m_named_type_impls = deserialise_pathmap< ::std::vector<::HIR::TypeImpl>>(); - rv.m_primitive_type_impls = deserialise_vec< ::HIR::TypeImpl>(); - rv.m_generic_type_impls = deserialise_vec< ::HIR::TypeImpl>(); - - rv.m_trait_impls = deserialise_pathmap< ::std::vector<::HIR::TraitImpl>>(); - rv.m_marker_impls = deserialise_pathmap< ::std::vector<::HIR::MarkerImpl>>(); + rv.m_type_impls = D< ::HIR::Crate::ImplGroup<::HIR::TypeImpl> >::des(*this); + rv.m_trait_impls = deserialise_pathmap< ::HIR::Crate::ImplGroup<::HIR::TraitImpl>>(); + rv.m_marker_impls = deserialise_pathmap< ::HIR::Crate::ImplGroup<::HIR::MarkerImpl>>(); rv.m_exported_macros = deserialise_istrumap< ::MacroRulesPtr>(); rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>(); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index cb8438bf..0ad59d56 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1676,7 +1676,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ) } - hir_crate.m_trait_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::TraitImpl>()) ).first->second.push_back( ::HIR::TraitImpl { + // Sorted later on + hir_crate.m_trait_impls[mv$(trait_name)].generic.push_back( ::HIR::TraitImpl { mv$(params), mv$(trait_args), mv$(type), @@ -1696,7 +1697,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat else { auto type = LowerHIR_Type(impl.def().type()); - hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), true, @@ -1750,7 +1751,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } // Sorted later on - hir_crate.m_generic_type_impls.push_back( ::HIR::TypeImpl { + hir_crate.m_type_impls.generic.push_back( ::HIR::TypeImpl { mv$(params), mv$(type), mv$(methods), @@ -1771,7 +1772,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto trait_name = mv$(trait.m_path); auto trait_args = mv$(trait.m_params); - hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { + // Sorting done later + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), false, diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 12b874a7..2169c0c3 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -527,17 +527,46 @@ public: Module m_root_module; + template + struct ImplGroup + { + ::std::map<::HIR::SimplePath, ::std::vector> named; + ::std::vector non_named; // TODO: use a map of HIR::TypeRef::Data::Tag + ::std::vector generic; + + const ::std::vector* get_list_for_type(const ::HIR::TypeRef& ty) const { + static ::std::vector empty; + if( const auto* p = ty.get_sort_path() ) { + auto it = named.find(*p); + if( it != named.end() ) + return &it->second; + else + return nullptr; + } + else { + // TODO: Sort these by type tag, use the `Primitive` group if `ty` is Infer + return &non_named; + } + } + ::std::vector& get_list_for_type_mut(const ::HIR::TypeRef& ty) { + if( const auto* p = ty.get_sort_path() ) { + return named[*p]; + } + else { + // TODO: Ivars match with core types + return non_named; + } + } + }; /// Impl blocks on just a type, split into three groups // - Named type (sorted on the path) // - Primitive types // - Unsorted (generics, and everything before outer type resolution) - ::std::map<::HIR::SimplePath, ::std::vector<::HIR::TypeImpl>> m_named_type_impls; - ::std::vector< ::HIR::TypeImpl> m_primitive_type_impls; - ::std::vector< ::HIR::TypeImpl> m_generic_type_impls; + ImplGroup<::HIR::TypeImpl> m_type_impls; /// Impl blocks - ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::TraitImpl> > m_trait_impls; - ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::MarkerImpl> > m_marker_impls; + ::std::map< ::HIR::SimplePath, ImplGroup<::HIR::TraitImpl> > m_trait_impls; + ::std::map< ::HIR::SimplePath, ImplGroup<::HIR::MarkerImpl> > m_marker_impls; /// Macros exported by this crate ::std::unordered_map< RcString, ::MacroRulesPtr > m_exported_macros; diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index 9e867980..14533fb4 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -935,45 +935,60 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& } } -bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +namespace { - auto it = this->m_trait_impls.find( trait ); - if( it != this->m_trait_impls.end() ) + template + bool find_impls_list(const ::std::vector& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) { - for(const auto& impl : it->second) + for(const auto& impl : impl_list) { - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { + if( impl.matches_type(type, ty_res) ) + { + if( callback(impl) ) + { return true; } } } + return false; } - for( const auto& ec : this->m_ext_crates ) - { - if( ec.second.m_data->find_trait_impls(trait, type, ty_res, callback) ) { - return true; - } - } - return false; } -bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +namespace { - auto it = this->m_marker_impls.find( trait ); - if( it != this->m_marker_impls.end() ) + bool find_trait_impls_int( + const ::HIR::Crate& crate, const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, + ::HIR::t_cb_resolve_type ty_res, ::std::function callback + ) { - for(const auto& impl : it->second) + auto it = crate.m_trait_impls.find( trait ); + if( it != crate.m_trait_impls.end() ) { - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { + // 1. Find named impls (associated with named types) + if( const auto* impl_list = it->second.get_list_for_type(type) ) + { + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; - } } + + // 2. Search fully generic list. + if( find_impls_list(it->second.generic, type, ty_res, callback) ) + return true; } + + return false; + } +} + +bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +{ + if( find_trait_impls_int(*this, trait, type, ty_res, callback) ) + { + return true; } for( const auto& ec : this->m_ext_crates ) { - if( ec.second.m_data->find_auto_trait_impls(trait, type, ty_res, callback) ) { + if( find_trait_impls_int(*ec.second.m_data, trait, type, ty_res, callback) ) + { return true; } } @@ -981,46 +996,57 @@ bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const : } namespace { - bool find_type_impls_list(const ::std::vector& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) + bool find_auto_trait_impls_int( + const ::HIR::Crate& crate, const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, + ::HIR::t_cb_resolve_type ty_res, ::std::function callback + ) { - for(const auto& impl : impl_list) + auto it = crate.m_marker_impls.find( trait ); + if( it != crate.m_marker_impls.end() ) { - if( impl.matches_type(type, ty_res) ) + // 1. Find named impls (associated with named types) + if( const auto* impl_list = it->second.get_list_for_type(type) ) { - if( callback(impl) ) - { + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; - } } + + // 2. Search fully generic list. + if( find_impls_list(it->second.generic, type, ty_res, callback) ) + return true; } + return false; } - bool find_type_impls_int(const ::HIR::Crate& crate, const ::HIR::SimplePath* sort_path, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) +} +bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const +{ + if( find_auto_trait_impls_int(*this, trait, type, ty_res, callback) ) + { + return true; + } + for( const auto& ec : this->m_ext_crates ) { - // 1. Find named impls (associated with named types) - if( sort_path ) + if( find_auto_trait_impls_int(*ec.second.m_data, trait, type, ty_res, callback) ) { - // TODO: This fails if the type is marked as #[fundamental] - //if( sort_path->m_crate_name != crate.m_crate_name ) { - // return false; - //} - - auto impl_list_it = crate.m_named_type_impls.find(*sort_path); - if( impl_list_it != crate.m_named_type_impls.end() ) - { - if( find_type_impls_list(impl_list_it->second, type, ty_res, callback) ) - return true; - } + return true; } - // - If this type has no associated path, look in the primitives list - else + } + return false; +} +namespace +{ + bool find_type_impls_int(const ::HIR::Crate& crate, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) + { + // 1. Find named impls (associated with named types) + if( const auto* impl_list = crate.m_type_impls.get_list_for_type(type) ) { - if( find_type_impls_list(crate.m_primitive_type_impls, type, ty_res, callback) ) + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; } // 2. Search fully generic list? - if( find_type_impls_list(crate.m_generic_type_impls, type, ty_res, callback) ) + if( find_impls_list(crate.m_type_impls.generic, type, ty_res, callback) ) return true; return false; @@ -1028,40 +1054,15 @@ namespace } bool ::HIR::Crate::find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function callback) const { - const ::HIR::SimplePath* path = nullptr; - // - Generic paths get sorted - if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) - { - path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; - } - // - So do trait objects - else if( type.m_data.is_TraitObject() ) - { - path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; - } - else - { - // Keep as nullptr, will search primitive list - } - - if( path ) - { - DEBUG(type << ", path=" << *path); - } - else - { - DEBUG(type << ", no path"); - } - // > Current crate - if( find_type_impls_int(*this, path, type, ty_res, callback) ) + if( find_type_impls_int(*this, type, ty_res, callback) ) { return true; } for( const auto& ec : this->m_ext_crates ) { //DEBUG("- " << ec.first); - if( find_type_impls_int(*ec.second.m_data, path, type, ty_res, callback) ) + if( find_type_impls_int(*ec.second.m_data, type, ty_res, callback) ) { return true; } diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 83e6d016..7725d49f 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -308,17 +308,20 @@ serialise(pm.path); serialise_vec(pm.attributes); } + template + void serialise(const ::HIR::Crate::ImplGroup& ig) + { + serialise_pathmap(ig.named); + serialise_vec(ig.non_named); + serialise_vec(ig.generic); + } void serialise_crate(const ::HIR::Crate& crate) { m_out.write_string(crate.m_crate_name); serialise_module(crate.m_root_module); - //std::map> - serialise_pathmap(crate.m_named_type_impls); - serialise_vec(crate.m_primitive_type_impls); - serialise_vec(crate.m_generic_type_impls); - + serialise(crate.m_type_impls); serialise_pathmap(crate.m_trait_impls); serialise_pathmap(crate.m_marker_impls); diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 7a5a0a1c..13300bbc 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -328,6 +328,24 @@ public: // Compares this type with another, using `resolve_placeholder` to get replacements for generics/infers in `x` Compare compare_with_placeholders(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder) const; + + const ::HIR::SimplePath* get_sort_path() const { + // - Generic paths get sorted + if( TU_TEST1(this->m_data, Path, .path.m_data.is_Generic()) ) + { + return &this->m_data.as_Path().path.m_data.as_Generic().m_path; + } + // - So do trait objects + else if( this->m_data.is_TraitObject() ) + { + return &this->m_data.as_TraitObject().m_trait.m_path.m_path; + } + else + { + // Keep as nullptr, will search primitive list + return nullptr; + } + } }; extern ::std::ostream& operator<<(::std::ostream& os, const ::HIR::TypeRef& ty); diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 8bf674b3..1cc54090 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -12,38 +12,39 @@ { } +namespace { + template + void visit_impls(::HIR::Crate::ImplGroup& g, ::std::function cb) { + for( auto& impl_group : g.named ) + { + for( auto& impl : impl_group.second ) + { + cb(impl); + } + } + for( auto& impl : g.non_named ) + { + cb(impl); + } + for( auto& impl : g.generic ) + { + cb(impl); + } + } +} + void ::HIR::Visitor::visit_crate(::HIR::Crate& crate) { this->visit_module(::HIR::ItemPath(crate.m_crate_name), crate.m_root_module ); - for( auto& ty_impl_group : crate.m_named_type_impls ) - { - for( auto& ty_impl : ty_impl_group.second ) - { - this->visit_type_impl(ty_impl); - } - } - for( auto& ty_impl : crate.m_primitive_type_impls ) - { - this->visit_type_impl(ty_impl); - } - for( auto& ty_impl : crate.m_generic_type_impls ) - { - this->visit_type_impl(ty_impl); - } + visit_impls<::HIR::TypeImpl>(crate.m_type_impls, [&](::HIR::TypeImpl& ty_impl){ this->visit_type_impl(ty_impl); }); for( auto& impl_group : crate.m_trait_impls ) { - for( auto& impl : impl_group.second ) - { - this->visit_trait_impl(impl_group.first, impl); - } + visit_impls<::HIR::TraitImpl>(impl_group.second, [&](::HIR::TraitImpl& ty_impl){ this->visit_trait_impl(impl_group.first, ty_impl); }); } for( auto& impl_group : crate.m_marker_impls ) { - for( auto& impl : impl_group.second ) - { - this->visit_marker_impl(impl_group.first, impl); - } + visit_impls<::HIR::MarkerImpl>(impl_group.second, [&](::HIR::MarkerImpl& ty_impl){ this->visit_marker_impl(impl_group.first, ty_impl); }); } } diff --git a/src/hir_conv/resolve_ufcs_outer.cpp b/src/hir_conv/resolve_ufcs_outer.cpp index 285f6e55..1f245a0d 100644 --- a/src/hir_conv/resolve_ufcs_outer.cpp +++ b/src/hir_conv/resolve_ufcs_outer.cpp @@ -339,50 +339,46 @@ namespace { } +namespace { + template + void sort_impl_group(::HIR::Crate::ImplGroup& ig) + { + auto new_end = ::std::remove_if(ig.generic.begin(), ig.generic.end(), [&ig](T& ty_impl) { + const auto& type = ty_impl.m_type; // Using field accesses in templates feels so dirty + const ::HIR::SimplePath* path = type.get_sort_path(); + + if( path ) + { + ig.named[*path].push_back(mv$(ty_impl)); + } + else if( type.m_data.is_Path() || type.m_data.is_Generic() ) + { + return false; + } + else + { + ig.non_named.push_back(mv$(ty_impl)); + } + return true; + }); + ig.generic.erase(new_end, ig.generic.end()); + } +} + void ConvertHIR_ResolveUFCS_Outer(::HIR::Crate& crate) { Visitor exp { crate }; exp.visit_crate( crate ); // Sort impls! - auto new_end = ::std::remove_if(crate.m_generic_type_impls.begin(), crate.m_generic_type_impls.end(), [&crate](::HIR::TypeImpl& ty_impl) { - const auto& type = ty_impl.m_type; - const ::HIR::SimplePath* path = nullptr; - // - Generic paths get sorted - if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) - { - path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; - } - // - So do trait objects - else if( type.m_data.is_TraitObject() ) - { - path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; - } - else - { - // Keep as nullptr, will search primitive list - } - - if( path ) - { - auto it = crate.m_named_type_impls.find(*path); - if( it == crate.m_named_type_impls.end() ) - { - it = crate.m_named_type_impls.insert( ::std::make_pair(*path, ::std::vector<::HIR::TypeImpl>()) ).first; - } - it->second.push_back(mv$(ty_impl)); - } - else if( type.m_data.is_Path() || type.m_data.is_Generic() ) - { - return false; - } - else - { - crate.m_primitive_type_impls.push_back(mv$(ty_impl)); - } - return true; - }); - crate.m_generic_type_impls.erase(new_end, crate.m_generic_type_impls.end()); - - DEBUG("Impl counts: " << crate.m_named_type_impls.size() << " path groups, " << crate.m_primitive_type_impls.size() << " primitive, " << crate.m_generic_type_impls.size() << " ungrouped"); + sort_impl_group(crate.m_type_impls); + DEBUG("Type impl counts: " << crate.m_type_impls.named.size() << " path groups, " << crate.m_type_impls.non_named.size() << " primitive, " << crate.m_type_impls.generic.size() << " ungrouped"); + for(auto& impl_group : crate.m_trait_impls) + { + sort_impl_group(impl_group.second); + } + for(auto& impl_group : crate.m_marker_impls) + { + sort_impl_group(impl_group.second); + } } diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index b4ab564c..f09917de 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -50,16 +50,18 @@ namespace { { for(auto& impl : new_trait_impls) { + ::std::vector<::HIR::TraitImpl>* trait_impl_list; switch(impl.first) { case ::HIR::ExprNode_Closure::Class::Once: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_once")].push_back( mv$(impl.second) ); - break; + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_once")].get_list_for_type_mut(impl.second.m_type); + if(0) case ::HIR::ExprNode_Closure::Class::Mut: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_mut" )].push_back( mv$(impl.second) ); - break; + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_mut" )].get_list_for_type_mut(impl.second.m_type); + if(0) case ::HIR::ExprNode_Closure::Class::Shared: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].push_back( mv$(impl.second) ); + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].get_list_for_type_mut(impl.second.m_type); + trait_impl_list->push_back( mv$(impl.second) ); break; case ::HIR::ExprNode_Closure::Class::NoCapture: { assert(impl.second.m_methods.size() == 1); @@ -68,7 +70,7 @@ namespace { // NOTE: This should always have a name const auto& path = impl.second.m_type.m_data.as_Path().path.m_data.as_Generic().m_path; DEBUG("Adding type impl " << path); - auto list_it = crate.m_named_type_impls.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; + auto list_it = crate.m_type_impls.named.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; list_it->second.push_back( ::HIR::TypeImpl { mv$(impl.second.m_params), mv$(impl.second.m_type), diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index ced322a4..f7f85b23 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -202,7 +202,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) impl.m_methods.insert(::std::make_pair( RcString::new_interned("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); // Add impl to the crate - state.crate.m_trait_impls[state.lang_Clone].push_back( ::std::move(impl) ); + state.crate.m_trait_impls[state.lang_Clone].get_list_for_type_mut(impl.m_type).push_back( ::std::move(impl) ); } void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) @@ -237,7 +237,9 @@ void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) //DEBUG("add_function(" << p << ")"); auto e = trans_list.add_function(::std::move(p)); - auto it = ::std::find_if( impl_list_it->second.begin(), impl_list_it->second.end(), [&](const auto& i){ return i.m_type == ty; }); + const auto* impl_list = impl_list_it->second.get_list_for_type(ty); + assert(impl_list); + auto it = ::std::find_if( impl_list->begin(), impl_list->end(), [&](const auto& i){ return i.m_type == ty; }); assert( it->m_methods.size() == 1 ); e->ptr = &it->m_methods.begin()->second.data; } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 7ef605b9..91b00084 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -165,6 +165,78 @@ namespace { } } } + + void Trans_Enumerate_Public_TraitImpl(EnumState& state, StaticTraitResolve& resolve, const ::HIR::SimplePath& trait_path, /*const*/ ::HIR::TraitImpl& impl) + { + static Span sp; + const auto& impl_ty = impl.m_type; + TRACE_FUNCTION_F("Impl " << trait_path << impl.m_trait_args << " for " << impl_ty); + if( impl.m_params.m_types.size() == 0 ) + { + auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.m_trait_args, nullptr); + + // Emit each method/static (in the trait itself) + const auto& trait = resolve.m_crate.get_trait_by_path(sp, trait_path); + for(const auto& vi : trait.m_values) + { + TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); + // Constant, no codegen + if( vi.second.is_Constant() ) + ; + // Generic method, no codegen + else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) + ; + // VTable, magic + else if( vi.first == "vtable#" ) + ; + else + { + // Check bounds before queueing for codegen + if( vi.second.is_Function() ) + { + bool rv = true; + for(const auto& b : vi.second.as_Function().m_params.m_bounds) + { + if( !b.is_TraitBound() ) continue; + const auto& be = b.as_TraitBound(); + + auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); + auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); + for(auto& ty : b_tp_mono.m_path.m_params.m_types) { + resolve.expand_associated_types(sp, ty); + } + for(auto& assoc_bound : b_tp_mono.m_type_bounds) { + resolve.expand_associated_types(sp, assoc_bound.second); + } + + rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { + return true; + }); + if( !rv ) + break; + } + if( !rv ) + continue ; + } + auto path = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(trait_path, impl.m_trait_args.clone()), vi.first); + Trans_Enumerate_FillFrom_PathMono(state, mv$(path)); + //state.enum_fcn(mv$(path), fcn.second.data, {}); + } + } + for(auto& m : impl.m_methods) + { + if( m.second.data.m_params.m_types.size() > 0 ) + m.second.data.m_save_code = true; + } + } + else + { + for(auto& m : impl.m_methods) + { + m.second.data.m_save_code = true; + } + } + } } /// Enumerate trans items for all public non-generic items (library crate) @@ -180,76 +252,21 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) for(auto& impl_group : crate.m_trait_impls) { const auto& trait_path = impl_group.first; - for(auto& impl : impl_group.second) + for(auto& impl_list : impl_group.second.named) { - const auto& impl_ty = impl.m_type; - TRACE_FUNCTION_F("Impl " << trait_path << impl.m_trait_args << " for " << impl_ty); - if( impl.m_params.m_types.size() == 0 ) + for(auto& impl : impl_list.second) { - auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.m_trait_args, nullptr); - - // Emit each method/static (in the trait itself) - const auto& trait = crate.get_trait_by_path(sp, trait_path); - for(const auto& vi : trait.m_values) - { - TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); - // Constant, no codegen - if( vi.second.is_Constant() ) - ; - // Generic method, no codegen - else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) - ; - // VTable, magic - else if( vi.first == "vtable#" ) - ; - else - { - // Check bounds before queueing for codegen - if( vi.second.is_Function() ) - { - bool rv = true; - for(const auto& b : vi.second.as_Function().m_params.m_bounds) - { - if( !b.is_TraitBound() ) continue; - const auto& be = b.as_TraitBound(); - - auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); - auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); - for(auto& ty : b_tp_mono.m_path.m_params.m_types) { - resolve.expand_associated_types(sp, ty); - } - for(auto& assoc_bound : b_tp_mono.m_type_bounds) { - resolve.expand_associated_types(sp, assoc_bound.second); - } - - rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { - return true; - }); - if( !rv ) - break; - } - if( !rv ) - continue ; - } - auto path = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(trait_path, impl.m_trait_args.clone()), vi.first); - Trans_Enumerate_FillFrom_PathMono(state, mv$(path)); - //state.enum_fcn(mv$(path), fcn.second.data, {}); - } - } - for(auto& m : impl.m_methods) - { - if( m.second.data.m_params.m_types.size() > 0 ) - m.second.data.m_save_code = true; - } - } - else - { - for(auto& m : impl.m_methods) - { - m.second.data.m_save_code = true; - } + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); } } + for(auto& impl : impl_group.second.non_named) + { + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + } + for(auto& impl : impl_group.second.generic) + { + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + } } struct H1 { @@ -281,18 +298,18 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) } } }; - for(auto& impl_grp : crate.m_named_type_impls) + for(auto& impl_grp : crate.m_type_impls.named) { for(auto& impl : impl_grp.second) { H1::enumerate_type_impl(state, impl); } } - for(auto& impl : crate.m_primitive_type_impls) + for(auto& impl : crate.m_type_impls.non_named) { H1::enumerate_type_impl(state, impl); } - for(auto& impl : crate.m_generic_type_impls) + for(auto& impl : crate.m_type_impls.generic) { H1::enumerate_type_impl(state, impl); } -- cgit v1.2.3 From d896ae84c2a890bcb7b7700dd4b4a69620499642 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 22 Jun 2019 14:32:49 +0800 Subject: HIR - Wrap impls in unique_ptr to keep pointer stability hack --- src/hir/deserialise.cpp | 6 +++--- src/hir/from_ast.cpp | 16 ++++++++-------- src/hir/hir.hpp | 13 +++++++------ src/hir/hir_ops.cpp | 6 +++--- src/hir/visitor.cpp | 6 +++--- src/hir_conv/resolve_ufcs_outer.cpp | 4 ++-- src/hir_expand/closures.cpp | 10 +++++----- src/trans/auto_impls.cpp | 11 ++++++----- src/trans/enumerate.cpp | 12 ++++++------ 9 files changed, 43 insertions(+), 41 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index f2794f29..9a353986 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -842,9 +842,9 @@ template DEF_D( ::HIR::Crate::ImplGroup, ::HIR::Crate::ImplGroup rv; - rv.named = d.deserialise_pathmap< ::std::vector>(); - rv.non_named = d.deserialise_vec(); - rv.generic = d.deserialise_vec(); + rv.named = d.deserialise_pathmap< ::std::vector<::std::unique_ptr > >(); + rv.non_named = d.deserialise_vec< ::std::unique_ptr >(); + rv.generic = d.deserialise_vec< ::std::unique_ptr >(); return rv; ) template<> DEF_D( ::HIR::ExternLibrary, return d.deserialise_extlib(); ) diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 0ad59d56..3976aa9d 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1677,7 +1677,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } // Sorted later on - hir_crate.m_trait_impls[mv$(trait_name)].generic.push_back( ::HIR::TraitImpl { + hir_crate.m_trait_impls[mv$(trait_name)].generic.push_back(box$(::HIR::TraitImpl { mv$(params), mv$(trait_args), mv$(type), @@ -1688,7 +1688,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat mv$(types), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ); + })); } else if( impl.def().type().m_data.is_None() ) { @@ -1697,14 +1697,14 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat else { auto type = LowerHIR_Type(impl.def().type()); - hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(box$(::HIR::MarkerImpl { mv$(params), mv$(trait_args), true, mv$(type), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ); + })); } } else @@ -1751,14 +1751,14 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } // Sorted later on - hir_crate.m_type_impls.generic.push_back( ::HIR::TypeImpl { + hir_crate.m_type_impls.generic.push_back( box$(::HIR::TypeImpl { mv$(params), mv$(type), mv$(methods), mv$(constants), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ); + }) ); } } for( const auto& i : ast_mod.items() ) @@ -1773,14 +1773,14 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto trait_args = mv$(trait.m_params); // Sorting done later - hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(box$(::HIR::MarkerImpl { mv$(params), mv$(trait_args), false, mv$(type), LowerHIR_SimplePath(Span(), ast_mod.path()) - } ); + }) ); } } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 2169c0c3..35373b51 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -530,12 +530,13 @@ public: template struct ImplGroup { - ::std::map<::HIR::SimplePath, ::std::vector> named; - ::std::vector non_named; // TODO: use a map of HIR::TypeRef::Data::Tag - ::std::vector generic; + typedef ::std::vector<::std::unique_ptr> list_t; + ::std::map<::HIR::SimplePath, list_t> named; + list_t non_named; // TODO: use a map of HIR::TypeRef::Data::Tag + list_t generic; - const ::std::vector* get_list_for_type(const ::HIR::TypeRef& ty) const { - static ::std::vector empty; + const list_t* get_list_for_type(const ::HIR::TypeRef& ty) const { + static list_t empty; if( const auto* p = ty.get_sort_path() ) { auto it = named.find(*p); if( it != named.end() ) @@ -548,7 +549,7 @@ public: return &non_named; } } - ::std::vector& get_list_for_type_mut(const ::HIR::TypeRef& ty) { + list_t& get_list_for_type_mut(const ::HIR::TypeRef& ty) { if( const auto* p = ty.get_sort_path() ) { return named[*p]; } diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index d9b1fb07..a548b725 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -938,13 +938,13 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& namespace { template - bool find_impls_list(const ::std::vector& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) + bool find_impls_list(const typename ::HIR::Crate::ImplGroup::list_t& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function callback) { for(const auto& impl : impl_list) { - if( impl.matches_type(type, ty_res) ) + if( impl->matches_type(type, ty_res) ) { - if( callback(impl) ) + if( callback(*impl) ) { return true; } diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 1cc54090..664d34ad 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -19,16 +19,16 @@ namespace { { for( auto& impl : impl_group.second ) { - cb(impl); + cb(*impl); } } for( auto& impl : g.non_named ) { - cb(impl); + cb(*impl); } for( auto& impl : g.generic ) { - cb(impl); + cb(*impl); } } } diff --git a/src/hir_conv/resolve_ufcs_outer.cpp b/src/hir_conv/resolve_ufcs_outer.cpp index 1f245a0d..4e90f4f2 100644 --- a/src/hir_conv/resolve_ufcs_outer.cpp +++ b/src/hir_conv/resolve_ufcs_outer.cpp @@ -343,8 +343,8 @@ namespace { template void sort_impl_group(::HIR::Crate::ImplGroup& ig) { - auto new_end = ::std::remove_if(ig.generic.begin(), ig.generic.end(), [&ig](T& ty_impl) { - const auto& type = ty_impl.m_type; // Using field accesses in templates feels so dirty + auto new_end = ::std::remove_if(ig.generic.begin(), ig.generic.end(), [&ig](::std::unique_ptr& ty_impl) { + const auto& type = ty_impl->m_type; // Using field accesses in templates feels so dirty const ::HIR::SimplePath* path = type.get_sort_path(); if( path ) diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index f09917de..0d6efd4c 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -50,7 +50,7 @@ namespace { { for(auto& impl : new_trait_impls) { - ::std::vector<::HIR::TraitImpl>* trait_impl_list; + ::HIR::Crate::ImplGroup<::HIR::TraitImpl>::list_t* trait_impl_list; switch(impl.first) { case ::HIR::ExprNode_Closure::Class::Once: @@ -61,7 +61,7 @@ namespace { if(0) case ::HIR::ExprNode_Closure::Class::Shared: trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].get_list_for_type_mut(impl.second.m_type); - trait_impl_list->push_back( mv$(impl.second) ); + trait_impl_list->push_back( box$(impl.second) ); break; case ::HIR::ExprNode_Closure::Class::NoCapture: { assert(impl.second.m_methods.size() == 1); @@ -70,8 +70,8 @@ namespace { // NOTE: This should always have a name const auto& path = impl.second.m_type.m_data.as_Path().path.m_data.as_Generic().m_path; DEBUG("Adding type impl " << path); - auto list_it = crate.m_type_impls.named.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; - list_it->second.push_back( ::HIR::TypeImpl { + auto* list_it = &crate.m_type_impls.named[path]; + list_it->push_back(box$(::HIR::TypeImpl { mv$(impl.second.m_params), mv$(impl.second.m_type), make_map1( @@ -80,7 +80,7 @@ namespace { ), {}, mv$(impl.second.m_src_module) - } ); + })); } break; case ::HIR::ExprNode_Closure::Class::Unknown: BUG(Span(), "Encountered Unkown closure type in new impls"); diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index f7f85b23..351c93e4 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -202,7 +202,8 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) impl.m_methods.insert(::std::make_pair( RcString::new_interned("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); // Add impl to the crate - state.crate.m_trait_impls[state.lang_Clone].get_list_for_type_mut(impl.m_type).push_back( ::std::move(impl) ); + auto& list = state.crate.m_trait_impls[state.lang_Clone].get_list_for_type_mut(impl.m_type); + list.push_back( box$(impl) ); } void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) @@ -238,10 +239,10 @@ void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) auto e = trans_list.add_function(::std::move(p)); const auto* impl_list = impl_list_it->second.get_list_for_type(ty); - assert(impl_list); - auto it = ::std::find_if( impl_list->begin(), impl_list->end(), [&](const auto& i){ return i.m_type == ty; }); - assert( it->m_methods.size() == 1 ); - e->ptr = &it->m_methods.begin()->second.data; + ASSERT_BUG(Span(), impl_list, "No impl list of Clone for " << ty); + auto& impl = **::std::find_if( impl_list->begin(), impl_list->end(), [&](const auto& i){ return i->m_type == ty; }); + assert( impl.m_methods.size() == 1 ); + e->ptr = &impl.m_methods.begin()->second.data; } } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 91b00084..d8426022 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -256,16 +256,16 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) { for(auto& impl : impl_list.second) { - Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, *impl); } } for(auto& impl : impl_group.second.non_named) { - Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, *impl); } for(auto& impl : impl_group.second.generic) { - Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, *impl); } } struct H1 @@ -302,16 +302,16 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) { for(auto& impl : impl_grp.second) { - H1::enumerate_type_impl(state, impl); + H1::enumerate_type_impl(state, *impl); } } for(auto& impl : crate.m_type_impls.non_named) { - H1::enumerate_type_impl(state, impl); + H1::enumerate_type_impl(state, *impl); } for(auto& impl : crate.m_type_impls.generic) { - H1::enumerate_type_impl(state, impl); + H1::enumerate_type_impl(state, *impl); } auto rv = Trans_Enumerate_CommonPost(state); -- cgit v1.2.3 From 9bc9346b6acb96838a6144c9bd96c4370e14b0ec Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 29 Jun 2019 13:22:41 +0800 Subject: HIR Gen - Improved error message with integer overflow --- src/hir/from_ast.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 3976aa9d..0ce55478 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -751,8 +751,9 @@ HIR::LifetimeRef LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) { if( ptr->m_datatype == CORETYPE_UINT || ptr->m_datatype == CORETYPE_ANY ) { + // TODO: Chage the HIR format to support very large arrays if( ptr->m_value > UINT_MAX ) { - ERROR(ty.span(), E0000, "Array size out of bounds - " << ptr->m_value << " > " << UINT_MAX); + ERROR(ty.span(), E0000, "Array size out of bounds - 0x" << ::std::hex << ptr->m_value << " > 0x" << UINT_MAX); } auto size_val = static_cast( ptr->m_value ); return ::HIR::TypeRef::new_array( mv$(inner), size_val ); -- cgit v1.2.3 From 0a45ac7c93e4e8584fef15b6f2896528a9dbffdd Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 21 Jul 2019 12:15:42 +0800 Subject: HIR - Partial support for large arrays (may fail downstream with overflows) --- src/hir/from_ast.cpp | 4 ++-- src/hir/type.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 0ce55478..dde40e03 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -752,8 +752,8 @@ HIR::LifetimeRef LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) if( ptr->m_datatype == CORETYPE_UINT || ptr->m_datatype == CORETYPE_ANY ) { // TODO: Chage the HIR format to support very large arrays - if( ptr->m_value > UINT_MAX ) { - ERROR(ty.span(), E0000, "Array size out of bounds - 0x" << ::std::hex << ptr->m_value << " > 0x" << UINT_MAX); + if( ptr->m_value >= UINT64_MAX ) { + ERROR(ty.span(), E0000, "Array size out of bounds - 0x" << ::std::hex << ptr->m_value << " > 0x" << UINT64_MAX << " in " << ::std::dec << ty); } auto size_val = static_cast( ptr->m_value ); return ::HIR::TypeRef::new_array( mv$(inner), size_val ); diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 13300bbc..e61c9ec7 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -220,7 +220,7 @@ public: (Array, struct { ::std::unique_ptr inner; ::std::shared_ptr<::HIR::ExprPtr> size; - size_t size_val; + uint64_t size_val; }), (Slice, struct { ::std::unique_ptr inner; -- cgit v1.2.3 From 47b61b93c2ac841fe44d6cc8ca8fd91bd00b0e10 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 24 Aug 2019 16:50:04 +0800 Subject: HIR/Expand - Hack in proc_macro re-exports (this needs to be cleaner) --- src/expand/macro_rules.cpp | 5 +++++ src/hir/deserialise.cpp | 7 +++++++ src/hir/from_ast.cpp | 19 +++++++++++++++++++ src/hir/hir.hpp | 35 +++++++++++++++++++++++++---------- src/hir/serialise.cpp | 5 +++++ src/resolve/index.cpp | 7 +++++++ src/resolve/use.cpp | 8 ++++++++ 7 files changed, 76 insertions(+), 10 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 88b7fc88..7a49bcf6 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -65,6 +65,11 @@ class CMacroUseHandler: mod.m_macro_imports.push_back(AST::Module::MacroImport{ false, p.path.m_components.back(), p.path.m_components, nullptr }); mod.m_macro_imports.back().path.insert( mod.m_macro_imports.back().path.begin(), p.path.m_crate_name ); } + for(const auto& p : ec.m_hir->m_proc_macro_reexports) + { + mod.m_macro_imports.push_back(AST::Module::MacroImport{ /*is_pub=*/ false, p.first, p.second.path.m_components, nullptr }); + mod.m_macro_imports.back().path.insert( mod.m_macro_imports.back().path.begin(), p.second.path.m_crate_name ); + } } ) else TU_IFLET( ::AST::Item, i, Module, submod, diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 5795c809..23b8fdf1 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -849,6 +849,12 @@ rv.generic = d.deserialise_vec< ::std::unique_ptr >(); return rv; ) + template<> + DEF_D( ::HIR::Crate::MacroImport, + ::HIR::Crate::MacroImport rv; + rv.path = d.deserialise_simplepath(); + return rv; + ) template<> DEF_D( ::HIR::ExternLibrary, return d.deserialise_extlib(); ) ::HIR::LifetimeDef HirDeserialiser::deserialise_lifetimedef() @@ -1340,6 +1346,7 @@ rv.m_marker_impls = deserialise_pathmap< ::HIR::Crate::ImplGroup<::HIR::MarkerImpl>>(); rv.m_exported_macros = deserialise_istrumap< ::MacroRulesPtr>(); + rv.m_proc_macro_reexports = deserialise_istrumap< ::HIR::Crate::MacroImport>(); rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>(); { diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index dde40e03..e271a809 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1395,6 +1395,9 @@ void _add_mod_ns_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pub void _add_mod_val_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pub, ::HIR::ValueItem ti) { mod.m_value_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::ValueItem> { is_pub, mv$(ti) }) ) ); } +void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pub, ::HIR::MacroItem ti) { + mod.m_macro_items.insert( ::std::make_pair( mv$(name), ::make_unique_ptr(::HIR::VisEnt< ::HIR::MacroItem> { is_pub, mv$(ti) }) ) ); +} ::HIR::Module LowerHIR_Module(const ::AST::Module& ast_mod, ::HIR::ItemPath path, ::std::vector< ::HIR::SimplePath> traits) { @@ -1590,6 +1593,16 @@ void _add_mod_val_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu } } + for( const auto& ie : ast_mod.m_macro_imports ) + { + //const auto& sp = mod_span; + if( ie.is_pub ) + { + auto mi = ::HIR::MacroItem::make_Import({ ::HIR::SimplePath(ie.path.front(), ::std::vector(ie.path.begin()+1, ie.path.end())) }); + _add_mod_mac_item( mod, ie.name, get_pub(true), mv$(mi) ); + } + } + return mod; } @@ -1881,6 +1894,12 @@ public: { if( mac.is_pub ) { + if( !mac.macro_ptr ) { + // Add to the re-export list + auto path = ::HIR::SimplePath(mac.path.front(), ::std::vector(mac.path.begin()+1, mac.path.end()));; + rv.m_proc_macro_reexports.insert( ::std::make_pair( mac.name, ::HIR::Crate::MacroImport { path } )); + continue ; + } // TODO: Why does this to such a move? auto v = ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast(mac.macro_ptr)) )) ); diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 35373b51..06c6f740 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -38,6 +38,7 @@ class Static; class ValueItem; class TypeItem; +class MacroItem; class ItemPath; @@ -382,6 +383,17 @@ public: {} }; +class ProcMacro +{ +public: + // Name of the macro + RcString name; + // Path to the handler + ::HIR::SimplePath path; + // A list of attributes to hand to the handler + ::std::vector<::std::string> attributes; +}; + class Module { public: @@ -392,6 +404,8 @@ public: ::std::unordered_map< RcString, ::std::unique_ptr> > m_value_items; // Contains types, traits, and modules ::std::unordered_map< RcString, ::std::unique_ptr> > m_mod_items; + // Macros! + ::std::unordered_map< RcString, ::std::unique_ptr> > m_macro_items; ::std::vector< ::std::pair > m_inline_statics; @@ -422,6 +436,11 @@ TAGGED_UNION(ValueItem, Import, (Function, Function), (StructConstructor, struct { ::HIR::SimplePath ty; }) ); +TAGGED_UNION(MacroItem, Import, + (Import, struct { ::HIR::SimplePath path; }), + (MacroRules, MacroRulesPtr), + (ProcMacro, ProcMacro) + ); // -------------------------------------------------------------------- @@ -510,16 +529,6 @@ class ExternLibrary public: ::std::string name; }; -class ProcMacro -{ -public: - // Name of the macro - RcString name; - // Path to the handler - ::HIR::SimplePath path; - // A list of attributes to hand to the handler - ::std::vector<::std::string> attributes; -}; class Crate { public: @@ -571,6 +580,12 @@ public: /// Macros exported by this crate ::std::unordered_map< RcString, ::MacroRulesPtr > m_exported_macros; + /// Macros re-exported by this crate + struct MacroImport { + ::HIR::SimplePath path; + //bool is_proc_macro; + }; + ::std::unordered_map< RcString, MacroImport > m_proc_macro_reexports; /// Procedural macros presented ::std::vector< ::HIR::ProcMacro> m_proc_macros; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 272e176f..9acb6193 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -315,6 +315,10 @@ serialise_vec(ig.non_named); serialise_vec(ig.generic); } + void serialise(const ::HIR::Crate::MacroImport& e) + { + serialise(e.path); + } void serialise_crate(const ::HIR::Crate& crate) { @@ -326,6 +330,7 @@ serialise_pathmap(crate.m_marker_impls); serialise_strmap(crate.m_exported_macros); + serialise_strmap(crate.m_proc_macro_reexports); { decltype(crate.m_lang_items) lang_items_filtered; for(const auto& ent : crate.m_lang_items) diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 45fb58f5..bde59da8 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -456,6 +456,13 @@ void Resolve_Index_Module_Wildcard__use_stmt(AST::Crate& crate, AST::Module& dst DEBUG("Glob crate " << i_data.path); const auto& hmod = e.crate_->m_hir->m_root_module; Resolve_Index_Module_Wildcard__glob_in_hir_mod(sp, crate, dst_mod, hmod, i_data.path, is_pub); + // TODO: Macros too + for(const auto& pm : e.crate_->m_hir->m_proc_macros) + { + dst_mod.m_macro_imports.push_back({ + is_pub, pm.name, make_vec2(e.crate_->m_hir->m_crate_name, pm.name), nullptr + }); + } ) else TU_IFLET(::AST::PathBinding_Type, b, Module, e, DEBUG("Glob mod " << i_data.path); diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index d1b96280..8a9a3167 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -751,6 +751,14 @@ namespace { { rv.macro = ::AST::PathBinding_Macro::make_MacroRules({ &ec, &*it->second }); } + + { + auto it = ::std::find_if( ec.m_hir->m_proc_macros.begin(), ec.m_hir->m_proc_macros.end(), [&](const auto& pm){ return pm.name == name;} ); + if( it != ec.m_hir->m_proc_macros.end() ) + { + rv.macro = ::AST::PathBinding_Macro::make_ProcMacro({ &ec, name }); + } + } } return rv; } -- cgit v1.2.3 From 848aa5c4dc438aedaaf5e1146e4788a1f0c43eff Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 6 Oct 2019 12:23:25 +0800 Subject: AST - Clean up location of attributes and span on mod-level items --- src/ast/ast.cpp | 68 +++++++++++++++++++++------------------------ src/ast/ast.hpp | 24 ++++++++-------- src/ast/attrs.hpp | 1 + src/ast/crate.cpp | 18 ++++++------ src/ast/dump.cpp | 16 +++++------ src/ast/item.hpp | 13 ++++++--- src/expand/derive.cpp | 22 +++++++-------- src/expand/mod.cpp | 30 ++++++++++---------- src/expand/proc_macro.cpp | 9 +++--- src/expand/test_harness.cpp | 10 +++---- src/hir/from_ast.cpp | 40 +++++++++++++------------- src/parse/root.cpp | 47 ++++++++++--------------------- src/parse/token.cpp | 4 +-- src/resolve/absolute.cpp | 52 +++++++++++++++++----------------- src/resolve/index.cpp | 24 ++++++++-------- 15 files changed, 182 insertions(+), 196 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f1a68680..827ac2d1 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -107,18 +107,15 @@ Function Function::clone() const return rv; } -void Trait::add_type(RcString name, AttributeList attrs, TypeRef type) { - m_items.push_back( Named(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) ); - m_items.back().data.attrs = mv$(attrs); +void Trait::add_type(Span sp, RcString name, AttributeList attrs, TypeRef type) { + m_items.push_back( Named(sp, mv$(attrs), true, mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))})) ); } -void Trait::add_function(RcString name, AttributeList attrs, Function fcn) { +void Trait::add_function(Span sp, RcString name, AttributeList attrs, Function fcn) { DEBUG("trait fn " << name); - m_items.push_back( Named(mv$(name), Item::make_Function({mv$(fcn)}), true) ); - m_items.back().data.attrs = mv$(attrs); + m_items.push_back( Named(sp, mv$(attrs), true, mv$(name), Item::make_Function({mv$(fcn)})) ); } -void Trait::add_static(RcString name, AttributeList attrs, Static v) { - m_items.push_back( Named(mv$(name), Item::make_Static({mv$(v)}), true) ); - m_items.back().data.attrs = mv$(attrs); +void Trait::add_static(Span sp, RcString name, AttributeList attrs, Static v) { + m_items.push_back( Named(sp, mv$(attrs), true, mv$(name), Item::make_Static({mv$(v)})) ); } void Trait::set_is_marker() { m_is_marker = true; @@ -143,7 +140,7 @@ Trait Trait::clone() const auto rv = Trait(m_params.clone(), m_supertraits); for(const auto& item : m_items) { - rv.m_items.push_back( Named { item.name, item.data.clone(), item.is_pub } ); + rv.m_items.push_back( Named { item.span, item.attrs.clone(), item.is_pub, item.name, item.data.clone() } ); } return rv; } @@ -208,21 +205,21 @@ Union Union::clone() const return os << "impl<" << impl.m_params << "> " << impl.m_trait.ent << " for " << impl.m_type << ""; } -void Impl::add_function(bool is_public, bool is_specialisable, RcString name, Function fcn) +void Impl::add_function(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, Function fcn) { DEBUG("impl fn " << name); - m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Function(mv$(fcn)) ) } ); + m_items.push_back( ImplItem { sp, mv$(attrs), is_public, is_specialisable, mv$(name), box$( Item::make_Function(mv$(fcn)) ) } ); } -void Impl::add_type(bool is_public, bool is_specialisable, RcString name, TypeRef type) +void Impl::add_type(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, TypeRef type) { - m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Type(TypeAlias(GenericParams(), mv$(type))) ) } ); + m_items.push_back( ImplItem { sp, mv$(attrs), is_public, is_specialisable, mv$(name), box$( Item::make_Type(TypeAlias(GenericParams(), mv$(type))) ) } ); } -void Impl::add_static(bool is_public, bool is_specialisable, RcString name, Static v) +void Impl::add_static(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, Static v) { - m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Static(mv$(v)) ) } ); + m_items.push_back( ImplItem { sp, mv$(attrs), is_public, is_specialisable, mv$(name), box$( Item::make_Static(mv$(v)) ) } ); } void Impl::add_macro_invocation(MacroInvocation item) { - m_items.push_back( ImplItem { false, false, "", box$( Item::make_MacroInv(mv$(item)) ) } ); + m_items.push_back( ImplItem { item.span(), {}, false, false, "", box$( Item::make_MacroInv(mv$(item)) ) } ); } bool Impl::has_named_item(const RcString& name) const @@ -262,7 +259,7 @@ UseItem UseItem::clone() const void ExternBlock::add_item(Named named_item) { - ASSERT_BUG(named_item.data.span, named_item.data.is_Function() || named_item.data.is_Static() || named_item.data.is_Type(), "Incorrect item type for ExternBlock - " << named_item.data.tag_str()); + ASSERT_BUG(named_item.span, named_item.data.is_Function() || named_item.data.is_Static() || named_item.data.is_Type(), "Incorrect item type for ExternBlock - " << named_item.data.tag_str()); m_items.push_back( mv$(named_item) ); } ExternBlock ExternBlock::clone() const @@ -286,55 +283,54 @@ void Module::add_item( Named named_item ) { if( i.name == "" ) { } else { - DEBUG(m_my_path << "::" << i.name << " = " << i.data.tag_str() << ", attrs = " << i.data.attrs); + DEBUG(m_my_path << "::" << i.name << " = " << i.data.tag_str() << ", attrs = " << i.attrs); } } -void Module::add_item(bool is_pub, RcString name, Item it, AttributeList attrs) { - it.attrs = mv$(attrs); - add_item( Named( mv$(name), mv$(it), is_pub ) ); +void Module::add_item(Span sp, bool is_pub, RcString name, Item it, AttributeList attrs) { + add_item( Named( mv$(sp), mv$(attrs), is_pub, mv$(name), mv$(it) ) ); } -void Module::add_ext_crate(bool is_public, RcString ext_name, RcString imp_name, AttributeList attrs) { - this->add_item( is_public, imp_name, Item::make_Crate({mv$(ext_name)}), mv$(attrs) ); +void Module::add_ext_crate(Span sp, bool is_pub, RcString ext_name, RcString imp_name, AttributeList attrs) { + this->add_item( mv$(sp), is_pub, imp_name, Item::make_Crate({mv$(ext_name)}), mv$(attrs) ); } void Module::add_macro_invocation(MacroInvocation item) { - this->add_item( false, "", Item( mv$(item) ), ::AST::AttributeList {} ); + this->add_item( item.span(), false, "", Item( mv$(item) ), ::AST::AttributeList {} ); } void Module::add_macro(bool is_exported, RcString name, MacroRulesPtr macro) { - m_macros.push_back( Named( mv$(name), mv$(macro), is_exported ) ); + m_macros.push_back( Named( Span(), {}, /*is_pub=*/is_exported, mv$(name), mv$(macro) ) ); } void Module::add_macro_import(RcString name, const MacroRules& mr) { - m_macro_import_res.push_back( Named( mv$(name), &mr, false ) ); + m_macro_import_res.push_back( Named( Span(), /*attrs=*/{}, /*is_pub=*/false, mv$(name), &mr) ); } Item Item::clone() const { TU_MATCHA( (*this), (e), (None, - return AST::Item(e); + return Item(e); ), (MacroInv, - TODO(this->span, "Clone on Item::MacroInv"); + TODO(Span(), "Clone on Item::MacroInv"); ), (Macro, - TODO(this->span, "Clone on Item::Macro"); + TODO(Span(), "Clone on Item::Macro"); ), (Use, - return AST::Item(e.clone()); + return Item(e.clone()); ), (ExternBlock, - TODO(this->span, "Clone on Item::" << this->tag_str()); + TODO(Span(), "Clone on Item::" << this->tag_str()); ), (Impl, - TODO(this->span, "Clone on Item::Impl"); + TODO(Span(), "Clone on Item::" << this->tag_str()); ), (NegImpl, - TODO(this->span, "Clone on Item::NegImpl"); + TODO(Span(), "Clone on Item::" << this->tag_str()); ), (Module, - TODO(this->span, "Clone on Item::Module"); + TODO(Span(), "Clone on Item::" << this->tag_str()); ), (Crate, - return AST::Item(e); + return Item(e); ), (Type, return AST::Item(e.clone()); diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index a6c06e76..1f42a764 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -223,9 +223,9 @@ public: const NamedList& items() const { return m_items; } NamedList& items() { return m_items; } - void add_type(RcString name, AttributeList attrs, TypeRef type); - void add_function(RcString name, AttributeList attrs, Function fcn); - void add_static(RcString name, AttributeList attrs, Static v); + void add_type(Span sp, RcString name, AttributeList attrs, TypeRef type); + void add_function(Span sp, RcString name, AttributeList attrs, Function fcn); + void add_static(Span sp, RcString name, AttributeList attrs, Static v); void set_is_marker(); bool is_marker() const; @@ -424,6 +424,8 @@ class Impl { public: struct ImplItem { + Span sp; + AttributeList attrs; bool is_pub; // Ignored for trait impls bool is_specialisable; RcString name; @@ -446,9 +448,9 @@ public: {} Impl& operator=(Impl&&) = default; - void add_function(bool is_public, bool is_specialisable, RcString name, Function fcn); - void add_type(bool is_public, bool is_specialisable, RcString name, TypeRef type); - void add_static(bool is_public, bool is_specialisable, RcString name, Static v); + void add_function(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, Function fcn); + void add_type(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, TypeRef type); + void add_static(Span sp, AttributeList attrs, bool is_public, bool is_specialisable, RcString name, Static v); void add_macro_invocation( MacroInvocation inv ); const ImplDef& def() const { return m_def; } @@ -570,8 +572,8 @@ public: ::std::shared_ptr add_anon(); void add_item(Named item); - void add_item(bool is_pub, RcString name, Item it, AttributeList attrs); - void add_ext_crate(bool is_public, RcString ext_name, RcString imp_name, AttributeList attrs); + void add_item(Span sp, bool is_pub, RcString name, Item it, AttributeList attrs); + void add_ext_crate(Span sp, bool is_pub, RcString ext_name, RcString imp_name, AttributeList attrs); void add_macro_invocation(MacroInvocation item); void add_macro(bool is_exported, RcString name, MacroRulesPtr macro); @@ -621,12 +623,8 @@ TAGGED_UNION_EX(Item, (), None, (Static, Static) ), - (, attrs(mv$(x.attrs))), (attrs = mv$(x.attrs);), + (), (), ( - public: - AttributeList attrs; - Span span; - Item clone() const; ) ); diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp index 04328130..7a6ce864 100644 --- a/src/ast/attrs.hpp +++ b/src/ast/attrs.hpp @@ -8,6 +8,7 @@ #ifndef _AST_ATTRS_HPP_ #define _AST_ATTRS_HPP_ +#include namespace AST { diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index 726a00c6..e788f6e0 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -32,12 +32,13 @@ namespace { fcn(mod); for( auto& sm : mod.items() ) { - TU_IFLET(::AST::Item, sm.data, Module, e, - if( check_item_cfg(sm.data.attrs) ) + if( auto* e = sm.data.opt_Module() ) + { + if( check_item_cfg(sm.attrs) ) { - iterate_module(e, fcn); + iterate_module(*e, fcn); } - ) + } } // TODO: What about if an anon mod has been #[cfg]-d out? // - For now, disable @@ -61,12 +62,13 @@ void Crate::load_externs() auto cb = [this](Module& mod) { for( /*const*/ auto& it : mod.items() ) { - TU_IFLET(AST::Item, it.data, Crate, c, - if( check_item_cfg(it.data.attrs) ) + if( auto* c = it.data.opt_Crate() ) + { + if( check_item_cfg(it.attrs) ) { - c.name = load_extern_crate( it.data.span, c.name.c_str() ); + c->name = load_extern_crate( it.span, c->name.c_str() ); } - ) + } } }; iterate_module(m_root_module, cb); diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp index 9fb34099..4e880a76 100644 --- a/src/ast/dump.cpp +++ b/src/ast/dump.cpp @@ -653,7 +653,7 @@ void RustPrinter::handle_module(const AST::Module& mod) if( !item.data.is_Crate() ) continue ; const auto& e = item.data.as_Crate(); - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << "extern crate \"" << e.name << "\" as " << item.name << ";\n"; } @@ -662,7 +662,7 @@ void RustPrinter::handle_module(const AST::Module& mod) if( !item.data.is_ExternBlock() ) continue ; const auto& e = item.data.as_ExternBlock(); - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << "extern \"" << e.abi() << "\" {}\n"; } @@ -690,7 +690,7 @@ void RustPrinter::handle_module(const AST::Module& mod) m_os << "\n"; need_nl = false; } - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << (item.is_pub ? "pub " : "") << "type " << item.name; print_params(e.params()); m_os << " = " << e.type(); @@ -705,7 +705,7 @@ void RustPrinter::handle_module(const AST::Module& mod) const auto& e = item.data.as_Struct(); m_os << "\n"; - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << (item.is_pub ? "pub " : "") << "struct " << item.name; handle_struct(e); } @@ -716,7 +716,7 @@ void RustPrinter::handle_module(const AST::Module& mod) const auto& e = item.data.as_Enum(); m_os << "\n"; - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << (item.is_pub ? "pub " : "") << "enum " << item.name; handle_enum(e); } @@ -727,7 +727,7 @@ void RustPrinter::handle_module(const AST::Module& mod) const auto& e = item.data.as_Trait(); m_os << "\n"; - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << (item.is_pub ? "pub " : "") << "trait " << item.name; handle_trait(e); } @@ -741,7 +741,7 @@ void RustPrinter::handle_module(const AST::Module& mod) m_os << "\n"; need_nl = false; } - print_attrs(item.data.attrs); + print_attrs(item.attrs); m_os << indent() << (item.is_pub ? "pub " : ""); switch( e.s_class() ) { @@ -760,7 +760,7 @@ void RustPrinter::handle_module(const AST::Module& mod) const auto& e = item.data.as_Function(); m_os << "\n"; - print_attrs(item.data.attrs); + print_attrs(item.attrs); handle_function(item.is_pub, item.name, e); } diff --git a/src/ast/item.hpp b/src/ast/item.hpp index ee83a8db..a5b0b1a5 100644 --- a/src/ast/item.hpp +++ b/src/ast/item.hpp @@ -9,15 +9,18 @@ #include #include +#include "attrs.hpp" namespace AST { template struct Named { + Span span; + AttributeList attrs; + bool is_pub; RcString name; T data; - bool is_pub; Named(): is_pub(false) @@ -25,10 +28,12 @@ struct Named Named(Named&&) = default; Named(const Named&) = default; Named& operator=(Named&&) = default; - Named(RcString name, T data, bool is_pub): + Named(Span sp, AttributeList attrs, bool is_pub, RcString name, T data): + span(sp), + attrs( ::std::move(attrs) ), + is_pub( is_pub ), name( ::std::move(name) ), - data( ::std::move(data) ), - is_pub( is_pub ) + data( ::std::move(data) ) { } }; diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 25523fa4..d92cbe79 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -393,7 +393,7 @@ class Deriver_Debug: AST::GenericParams params = get_params_with_bounds(sp, p, debug_trait, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, debug_trait), type.clone() ) ); - rv.add_function(false, false, "fmt", mv$(fcn)); + rv.add_function(sp, {}, false, false, "fmt", mv$(fcn)); return mv$(rv); } @@ -564,7 +564,7 @@ class Deriver_PartialEq: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "eq", mv$(fcn)); + rv.add_function(sp, {}, false, false, "eq", mv$(fcn)); return mv$(rv); } AST::ExprNodeP compare_and_ret(Span sp, const RcString& core_name, AST::ExprNodeP v1, AST::ExprNodeP v2) const @@ -716,7 +716,7 @@ class Deriver_PartialOrd: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "partial_cmp", mv$(fcn)); + rv.add_function(sp, {}, false, false, "partial_cmp", mv$(fcn)); return mv$(rv); } @@ -906,7 +906,7 @@ class Deriver_Eq: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "assert_receiver_is_total_eq", mv$(fcn)); + rv.add_function(sp, {}, false, false, "assert_receiver_is_total_eq", mv$(fcn)); return mv$(rv); } AST::ExprNodeP assert_is_eq(const AST::Path& method_path, AST::ExprNodeP val) const { @@ -1042,7 +1042,7 @@ class Deriver_Ord: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "cmp", mv$(fcn)); + rv.add_function(sp, {}, false, false, "cmp", mv$(fcn)); return mv$(rv); } @@ -1225,7 +1225,7 @@ class Deriver_Clone: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "clone", mv$(fcn)); + rv.add_function(sp, {}, false, false, "clone", mv$(fcn)); return mv$(rv); } AST::ExprNodeP clone_val_ref(const RcString& core_name, AST::ExprNodeP val) const { @@ -1425,7 +1425,7 @@ class Deriver_Default: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "default", mv$(fcn)); + rv.add_function(sp, {}, false, false, "default", mv$(fcn)); return mv$(rv); } AST::ExprNodeP default_call(const RcString& core_name) const { @@ -1511,7 +1511,7 @@ class Deriver_Hash: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "hash", mv$(fcn)); + rv.add_function(sp, {}, false, false, "hash", mv$(fcn)); return mv$(rv); } AST::ExprNodeP hash_val_ref(const RcString& core_name, AST::ExprNodeP val) const { @@ -1657,7 +1657,7 @@ class Deriver_RustcEncodable: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "encode", mv$(fcn)); + rv.add_function(sp, {}, false, false, "encode", mv$(fcn)); return mv$(rv); } AST::ExprNodeP enc_val_direct(AST::ExprNodeP val) const { @@ -1887,7 +1887,7 @@ class Deriver_RustcDecodable: AST::GenericParams params = get_params_with_bounds(sp, p, trait_path, mv$(types_to_bound)); AST::Impl rv( AST::ImplDef( AST::AttributeList(), mv$(params), make_spanned(sp, trait_path), type.clone() ) ); - rv.add_function(false, false, "decode", mv$(fcn)); + rv.add_function(sp, {}, false, false, "decode", mv$(fcn)); return mv$(rv); } AST::ExprNodeP dec_val() const { @@ -2135,7 +2135,7 @@ static void derive_item(const Span& sp, const AST::Crate& crate, AST::Module& mo DEBUG("- " << trait.name()); auto dp = find_impl(trait.name()); if( dp ) { - mod.add_item(false, "", dp->handle_item(sp, opts, params, type, item), {} ); + mod.add_item(sp, false, "", dp->handle_item(sp, opts, params, type, item), {} ); continue ; } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index d9a19b2c..41308611 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -976,13 +976,13 @@ void Expand_Impl(::AST::Crate& crate, LList modstack, ::AST: for( unsigned int idx = 0; idx < impl.items().size(); idx ++ ) { auto& i = impl.items()[idx]; - DEBUG(" - " << i.name << " :: " << i.data->attrs); + DEBUG(" - " << i.name << " :: " << i.attrs); // TODO: Make a path from the impl definition? Requires having the impl def resolved to be correct // - Does it? the namespace is essentially the same. There may be issues with wherever the path is used though //::AST::Path path = modpath + i.name; - auto attrs = mv$(i.data->attrs); + auto attrs = mv$(i.attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, AST::Path(), mod, *i.data); TU_MATCH_DEF(AST::Item, (*i.data), (e), @@ -1037,8 +1037,8 @@ void Expand_Impl(::AST::Crate& crate, LList modstack, ::AST: auto& i = impl.items()[idx]; Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, *i.data); // TODO: How would this be populated? It got moved out? - if( i.data->attrs.m_items.size() == 0 ) - i.data->attrs = mv$(attrs); + if( i.attrs.m_items.size() == 0 ) + i.attrs = mv$(attrs); } } @@ -1085,7 +1085,7 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: if( crate.m_prelude_path != AST::Path() ) { if( mod.m_insert_prelude && ! mod.is_anon() ) { - mod.add_item(false, "", ::AST::UseItem { Span(), ::make_vec1(::AST::UseItem::Ent { Span(), crate.m_prelude_path, "" }) }, {}); + mod.add_item(Span(), false, "", ::AST::UseItem { Span(), ::make_vec1(::AST::UseItem::Ent { Span(), crate.m_prelude_path, "" }) }, {}); } } @@ -1094,10 +1094,10 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: { auto& i = mod.items()[idx]; - DEBUG("- " << modpath << "::" << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.data.attrs); + DEBUG("- " << modpath << "::" << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.attrs); ::AST::Path path = modpath + i.name; - auto attrs = mv$(i.data.attrs); + auto attrs = mv$(i.attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, path, mod, i.data); auto dat = mv$(i.data); @@ -1159,7 +1159,7 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: // Can't recurse into an `extern crate` if(crate.m_extern_crates.count(e.name) == 0) { - e.name = crate.load_extern_crate( i.data.span, e.name ); + e.name = crate.load_extern_crate( i.span, e.name ); } } @@ -1257,7 +1257,7 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: { auto& ti = trait_items[idx]; DEBUG(" - " << ti.name << " " << ti.data.tag_str()); - auto attrs = mv$(ti.data.attrs); + auto attrs = mv$(ti.attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, AST::Path(), mod, ti.data); TU_MATCH_DEF(AST::Item, (ti.data), (e), @@ -1312,8 +1312,8 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: auto& ti = trait_items[idx]; Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, ti.data); - if( ti.data.attrs.m_items.size() == 0 ) - ti.data.attrs = mv$(attrs); + if( ti.attrs.m_items.size() == 0 ) + ti.attrs = mv$(attrs); } } } @@ -1344,8 +1344,8 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: i.data = mv$(dat); } // TODO: When would this _not_ be empty? - if( i.data.attrs.m_items.size() == 0 ) - i.data.attrs = mv$(attrs); + if( i.attrs.m_items.size() == 0 ) + i.attrs = mv$(attrs); } } @@ -1408,7 +1408,7 @@ void Expand(::AST::Crate& crate) crate.m_extern_crates.at("std").with_all_macros([&](const auto& name, const auto& mac) { crate.m_root_module.add_macro_import( name, mac ); }); - crate.m_root_module.add_ext_crate(false, "std", "std", ::AST::AttributeList {}); + crate.m_root_module.add_ext_crate(Span(), /*is_pub=*/false, "std", "std", /*attrs=*/{}); break; case ::AST::Crate::LOAD_CORE: if( crate.m_prelude_path == AST::Path() ) @@ -1416,7 +1416,7 @@ void Expand(::AST::Crate& crate) crate.m_extern_crates.at("core").with_all_macros([&](const auto& name, const auto& mac) { crate.m_root_module.add_macro_import( name, mac ); }); - crate.m_root_module.add_ext_crate(false, "core", "core", ::AST::AttributeList {}); + crate.m_root_module.add_ext_crate(Span(), /*is_pub=*/false, "core", "core", /*attrs=*/{}); break; case ::AST::Crate::LOAD_NONE: break; diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp index fa515702..6914f8df 100644 --- a/src/expand/proc_macro.cpp +++ b/src/expand/proc_macro.cpp @@ -121,12 +121,12 @@ void Expand_ProcMacro(::AST::Crate& crate) auto newmod = ::AST::Module { ::AST::Path("", { ::AST::PathNode("proc_macro#") }) }; // - TODO: These need to be loaded too. // > They don't actually need to exist here, just be loaded (and use absolute paths) - newmod.add_ext_crate(false, "proc_macro", "proc_macro", {}); + newmod.add_ext_crate(Span(), false, "proc_macro", "proc_macro", {}); - newmod.add_item(false, "main", mv$(main_fn), {}); - newmod.add_item(false, "MACROS", mv$(tests_list), {}); + newmod.add_item(Span(), false, "main", mv$(main_fn), {}); + newmod.add_item(Span(), false, "MACROS", mv$(tests_list), {}); - crate.m_root_module.add_item(false, "proc_macro#", mv$(newmod), {}); + crate.m_root_module.add_item(Span(), false, "proc_macro#", mv$(newmod), {}); crate.m_lang_items["mrustc-main"] = ::AST::Path("", { AST::PathNode("proc_macro#"), AST::PathNode("main") }); } @@ -757,6 +757,7 @@ namespace { if( !pmi.check_good() ) return ::std::unique_ptr(); // 2. Feed item as a token stream. + // TODO: Get attributes from the caller, filter based on the macro's options then pass to the child. Visitor(sp, pmi).visit_struct(item_name, false, i); pmi.send_done(); // 3. Return boxed invocation instance diff --git a/src/expand/test_harness.cpp b/src/expand/test_harness.cpp index 36b60632..456f90e4 100644 --- a/src/expand/test_harness.cpp +++ b/src/expand/test_harness.cpp @@ -114,12 +114,12 @@ void Expand_TestHarness(::AST::Crate& crate) auto newmod = ::AST::Module { ::AST::Path("", { ::AST::PathNode("test#") }) }; // - TODO: These need to be loaded too. // > They don't actually need to exist here, just be loaded (and use absolute paths) - newmod.add_ext_crate(false, "std", "std", {}); - newmod.add_ext_crate(false, "test", "test", {}); + newmod.add_ext_crate(Span(), false, "std", "std", {}); + newmod.add_ext_crate(Span(), false, "test", "test", {}); - newmod.add_item(false, "main", mv$(main_fn), {}); - newmod.add_item(false, "TESTS", mv$(tests_list), {}); + newmod.add_item(Span(), false, "main", mv$(main_fn), {}); + newmod.add_item(Span(), false, "TESTS", mv$(tests_list), {}); - crate.m_root_module.add_item(false, "test#", mv$(newmod), {}); + crate.m_root_module.add_item(Span(), false, "test#", mv$(newmod), {}); crate.m_lang_items["mrustc-main"] = ::AST::Path("", { AST::PathNode("test#"), AST::PathNode("main") }); } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index e271a809..54644806 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1194,7 +1194,7 @@ namespace { TU_MATCH_DEF(::AST::Item, (item.data), (i), ( - BUG(item.data.span, "Encountered unexpected item type in trait"); + BUG(item.span, "Encountered unexpected item type in trait"); ), (None, // Ignore. @@ -1212,18 +1212,18 @@ namespace { { TU_MATCH(::HIR::GenericBound, (b), (be), (TypeLifetime, - ASSERT_BUG(item.data.span, be.type == ::HIR::TypeRef("Self", 0xFFFF), "Invalid lifetime bound on associated type"); + ASSERT_BUG(item.span, be.type == ::HIR::TypeRef("Self", 0xFFFF), "Invalid lifetime bound on associated type"); lifetime_bound = mv$(be.valid_for); ), (TraitBound, - ASSERT_BUG(item.data.span, be.type == ::HIR::TypeRef("Self", 0xFFFF), "Invalid trait bound on associated type"); + ASSERT_BUG(item.span, be.type == ::HIR::TypeRef("Self", 0xFFFF), "Invalid trait bound on associated type"); trait_bounds.push_back( mv$(be.trait) ); ), (Lifetime, - BUG(item.data.span, "Unexpected lifetime-lifetime bound on associated type"); + BUG(item.span, "Unexpected lifetime-lifetime bound on associated type"); ), (TypeEquality, - BUG(item.data.span, "Unexpected type equality bound on associated type"); + BUG(item.span, "Unexpected type equality bound on associated type"); ) ) } @@ -1236,7 +1236,7 @@ namespace { ), (Function, ::HIR::TypeRef self_type {"Self", 0xFFFF}; - auto fcn = LowerHIR_Function(item_path, item.data.attrs, i, self_type); + auto fcn = LowerHIR_Function(item_path, item.attrs, i, self_type); fcn.m_save_code = true; rv.m_values.insert( ::std::make_pair(item.name, ::HIR::TraitValueItem::make_Function( mv$(fcn) )) ); ), @@ -1434,7 +1434,7 @@ void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu for( const auto& item : ast_mod.items() ) { - const auto& sp = item.data.span; + const auto& sp = item.span; auto item_path = ::HIR::ItemPath(path, item.name.c_str()); DEBUG(item_path << " " << item.data.tag_str()); TU_MATCH(::AST::Item, (item.data), (e), @@ -1452,7 +1452,7 @@ void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu TODO(sp, "Expand ExternBlock"); } // Insert a record of the `link` attribute - for(const auto& a : item.data.attrs.m_items) + for(const auto& a : item.attrs.m_items) { if( a.name() != "link" ) continue ; @@ -1484,7 +1484,7 @@ void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu // Ignore - The index is used to add `Import`s ), (Module, - _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Module(e, mv$(item_path)) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Module(e, mv$(item_path)) ); ), (Crate, // All 'extern crate' items should be normalised into a list in the crate root @@ -1496,7 +1496,7 @@ void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu { if( !e.params().lft_params().empty() || !e.params().ty_params().empty() || !e.params().bounds().empty() ) { - ERROR(item.data.span, E0000, "Generics on extern type"); + ERROR(item.span, E0000, "Generics on extern type"); } _add_mod_ns_item(mod, item.name, get_pub(item.is_pub), ::HIR::ExternType {}); break; @@ -1513,20 +1513,20 @@ void _add_mod_mac_item(::HIR::Module& mod, RcString name, ::HIR::Publicity is_pu } else { } - _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Struct(item_path, e, item.data.attrs) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Struct(item_path, e, item.attrs) ); ), (Enum, - auto enm = LowerHIR_Enum(item_path, e, item.data.attrs, [&](auto name, auto str){ _add_mod_ns_item(mod, name, get_pub(item.is_pub), mv$(str)); }); + auto enm = LowerHIR_Enum(item_path, e, item.attrs, [&](auto name, auto str){ _add_mod_ns_item(mod, name, get_pub(item.is_pub), mv$(str)); }); _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), mv$(enm) ); ), (Union, - _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Union(item_path, e, item.data.attrs) ); + _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Union(item_path, e, item.attrs) ); ), (Trait, _add_mod_ns_item( mod, item.name, get_pub(item.is_pub), LowerHIR_Trait(item_path.get_simple_path(), e) ); ), (Function, - _add_mod_val_item(mod, item.name, get_pub(item.is_pub), LowerHIR_Function(item_path, item.data.attrs, e, ::HIR::TypeRef{})); + _add_mod_val_item(mod, item.name, get_pub(item.is_pub), LowerHIR_Function(item_path, item.attrs, e, ::HIR::TypeRef{})); ), (Static, if( e.s_class() == ::AST::Static::CONST ) @@ -1660,7 +1660,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ::HIR::ItemPath item_path(path, item.name.c_str()); TU_MATCH_DEF(::AST::Item, (*item.data), (e), ( - BUG(item.data->span, "Unexpected item type in trait impl - " << item.data->tag_str()); + BUG(item.sp, "Unexpected item type in trait impl - " << item.data->tag_str()); ), (None, ), @@ -1676,7 +1676,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } }) ); } else { - TODO(item.data->span, "Associated statics in trait impl"); + TODO(item.sp, "Associated statics in trait impl"); } ), (Type, @@ -1685,7 +1685,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ), (Function, DEBUG("- method " << item.name); - methods.insert( ::std::make_pair(item.name, ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { item.is_specialisable, LowerHIR_Function(item_path, item.data->attrs, e, type) }) ); + methods.insert( ::std::make_pair(item.name, ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { item.is_specialisable, LowerHIR_Function(item_path, item.attrs, e, type) }) ); ) ) } @@ -1738,7 +1738,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ::HIR::ItemPath item_path(path, item.name.c_str()); TU_MATCH_DEF(::AST::Item, (*item.data), (e), ( - BUG(item.data->span, "Unexpected item type in inherent impl - " << item.data->tag_str()); + BUG(item.sp, "Unexpected item type in inherent impl - " << item.data->tag_str()); ), (None, ), @@ -1753,12 +1753,12 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } }) ); } else { - TODO(item.data->span, "Associated statics in inherent impl"); + TODO(item.sp, "Associated statics in inherent impl"); } ), (Function, methods.insert( ::std::make_pair(item.name, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { - get_pub(item.is_pub), item.is_specialisable, LowerHIR_Function(item_path, item.data->attrs, e, type) + get_pub(item.is_pub), item.is_specialisable, LowerHIR_Function(item_path, item.attrs, e, type) } ) ); ) ) diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 064e127f..e81055ec 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -653,7 +653,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) ::AST::MacroInvocation inv; if( Parse_MacroInvocation_Opt(lex, inv) ) { - return AST::Named( "", AST::Item(mv$(inv)), false ); + return AST::Named( lex.end_span(ps), mv$(item_attrs), false, "", AST::Item(mv$(inv)) ); } } @@ -772,8 +772,7 @@ AST::Named Parse_Trait_Item(TokenStream& lex) throw ParseError::Unexpected(lex, tok); } - rv.attrs = ::std::move( item_attrs ); - return ::AST::Named<::AST::Item>( mv$(name), mv$(rv), true ); + return ::AST::Named<::AST::Item>( lex.end_span(ps), mv$(item_attrs), true, mv$(name), mv$(rv) ); } AST::Trait Parse_TraitDef(TokenStream& lex, const AST::AttributeList& meta_items) @@ -1189,7 +1188,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) if( Parse_MacroInvocation_Opt(lex, inv) ) { impl.add_macro_invocation( mv$(inv) ); - impl.items().back().data->attrs = mv$(item_attrs); + impl.items().back().attrs = mv$(item_attrs); return ; } } @@ -1214,8 +1213,9 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) GET_CHECK_TOK(tok, lex, TOK_IDENT); auto name = tok.istr(); GET_CHECK_TOK(tok, lex, TOK_EQUAL); - impl.add_type(is_public, is_specialisable, name, Parse_Type(lex)); + auto ty = Parse_Type(lex); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + impl.add_type(lex.end_span(ps), mv$(item_attrs), is_public, is_specialisable, name, mv$(ty)); break; } case TOK_RWORD_UNSAFE: fn_is_unsafe = true; @@ -1235,7 +1235,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); auto i = ::AST::Static(AST::Static::CONST, mv$(ty), mv$(val)); - impl.add_static( is_public, is_specialisable, mv$(name), mv$(i) ); + impl.add_static( lex.end_span(ps), mv$(item_attrs), is_public, is_specialisable, mv$(name), mv$(i) ); break ; } else if( tok.type() == TOK_RWORD_UNSAFE ) @@ -1266,15 +1266,12 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) DEBUG("Function " << name); // - Self allowed, can't be prototype-form auto fcn = Parse_FunctionDefWithCode(lex, abi, true, fn_is_unsafe, fn_is_const); - impl.add_function(is_public, is_specialisable, mv$(name), mv$(fcn)); + impl.add_function(lex.end_span(ps), mv$(item_attrs), is_public, is_specialisable, mv$(name), mv$(fcn)); break; } default: throw ParseError::Unexpected(lex, tok); } - - impl.items().back().data->span = lex.end_span(ps); - impl.items().back().data->attrs = mv$(item_attrs); // Empty for functions } AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::AttributeList& block_attrs) @@ -1305,10 +1302,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A auto i = ::AST::Item( Parse_FunctionDef(lex, abi, false, true, true,false) ); GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - i.attrs = mv$(meta_items); - i.span = lex.end_span(ps); - - rv.add_item( AST::Named { mv$(name), mv$(i), is_public } ); + rv.add_item( AST::Named { lex.end_span(ps), mv$(meta_items), is_public, mv$(name), mv$(i) } ); break; } case TOK_RWORD_STATIC: { bool is_mut = false; @@ -1323,9 +1317,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); auto i = ::AST::Item(::AST::Static( (is_mut ? ::AST::Static::MUT : ::AST::Static::STATIC), mv$(type), ::AST::Expr() )); - i.attrs = mv$(meta_items); - i.span = lex.end_span(ps); - rv.add_item( AST::Named { mv$(name), mv$(i), is_public } ); + rv.add_item( AST::Named { lex.end_span(ps), mv$(meta_items), is_public, mv$(name), mv$(i) } ); break; } case TOK_RWORD_TYPE: { GET_CHECK_TOK(tok, lex, TOK_IDENT); @@ -1334,9 +1326,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::A auto sp = lex.end_span(ps); //TODO(sp, "Extern type"); auto i = ::AST::Item(::AST::TypeAlias( ::AST::GenericParams(), ::TypeRef(sp) )); - i.attrs = mv$(meta_items); - i.span = mv$(sp); - rv.add_item( AST::Named { mv$(name), mv$(i), is_public } ); + rv.add_item( AST::Named { mv$(sp), mv$(meta_items), is_public, mv$(name), mv$(i) } ); break; } default: throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_RWORD_STATIC, TOK_RWORD_TYPE}); @@ -1643,7 +1633,7 @@ namespace { auto rv = tok.take_frag_item(); // Transfer new attributes onto the item for(auto& mi : meta_items.m_items) - rv.data.attrs.m_items.push_back( mv$(mi) ); + rv.attrs.m_items.push_back( mv$(mi) ); return rv; } @@ -1656,11 +1646,7 @@ namespace { ::AST::MacroInvocation inv; if( Parse_MacroInvocation_Opt(lex, inv) ) { - item_data = ::AST::Item( mv$(inv) ); - item_data.attrs = mv$(meta_items); - item_data.span = lex.end_span(ps); - - return ::AST::Named< ::AST::Item> { "", mv$(item_data), false }; + return ::AST::Named< ::AST::Item> { lex.end_span(ps), mv$(meta_items), false, "", ::AST::Item( mv$(inv) ) }; } } @@ -1849,7 +1835,7 @@ namespace { else { BUG(lex.point_span(), "Parse_Impl returned a variant other than Impl or NegImpl"); } - return ::AST::Named< ::AST::Item> { "", mv$(impl), false }; + return ::AST::Named< ::AST::Item> { Span(), {}, false, "", mv$(impl) }; } // `unsafe auto trait` case TOK_IDENT: @@ -1915,7 +1901,7 @@ namespace { break; // `impl` case TOK_RWORD_IMPL: - return ::AST::Named< ::AST::Item> { "", Parse_Impl(lex, mv$(meta_items)), false }; + return ::AST::Named< ::AST::Item> { Span(), {}, false, "", Parse_Impl(lex, mv$(meta_items)) }; // `trait` case TOK_RWORD_TRAIT: GET_CHECK_TOK(tok, lex, TOK_IDENT); @@ -2121,10 +2107,7 @@ namespace { throw ParseError::Unexpected(lex, tok); } - item_data.attrs = mv$(meta_items); - item_data.span = lex.end_span(ps); - - return ::AST::Named< ::AST::Item> { mv$(item_name), mv$(item_data), is_public }; + return ::AST::Named< ::AST::Item> { lex.end_span(ps), mv$(meta_items), is_public, mv$(item_name), mv$(item_data) }; } void Parse_Mod_Item(TokenStream& lex, AST::Module& mod, AST::AttributeList meta_items) diff --git a/src/parse/token.cpp b/src/parse/token.cpp index 73ae7d93..900108ab 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -110,8 +110,8 @@ Token::Token(const InterpolatedFragment& frag) case InterpolatedFragment::ITEM: { m_type = TOK_INTERPOLATED_ITEM; const auto& named = *reinterpret_cast*>(frag.m_ptr); - ::AST::Item item = named.data.clone(); - m_data = new AST::Named( named.name, mv$(item), named.is_pub ); + auto item = named.data.clone(); + m_data = new AST::Named( named.span, named.attrs.clone(), named.is_pub, named.name, mv$(item) ); break; } } } diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index d26bb699..ae094f7e 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -2030,19 +2030,19 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: TU_MATCH(AST::Item, (i.data), (e), (None, ), (MacroInv, - //BUG(i.data.span, "Resolve_Absolute_ImplItems - MacroInv"); + //BUG(i.span, "Resolve_Absolute_ImplItems - MacroInv"); ), - (ExternBlock, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), - (Impl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), - (NegImpl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), - (Macro, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), - (Use, BUG(i.data.span, "Resolve_Absolute_ImplItems - Use");), - (Module, BUG(i.data.span, "Resolve_Absolute_ImplItems - Module");), - (Crate , BUG(i.data.span, "Resolve_Absolute_ImplItems - Crate");), - (Enum , BUG(i.data.span, "Resolve_Absolute_ImplItems - Enum");), - (Trait , BUG(i.data.span, "Resolve_Absolute_ImplItems - Trait");), - (Struct, BUG(i.data.span, "Resolve_Absolute_ImplItems - Struct");), - (Union , BUG(i.data.span, "Resolve_Absolute_ImplItems - Union");), + (ExternBlock, BUG(i.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), + (Impl, BUG(i.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), + (NegImpl, BUG(i.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), + (Macro, BUG(i.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());), + (Use, BUG(i.span, "Resolve_Absolute_ImplItems - Use");), + (Module, BUG(i.span, "Resolve_Absolute_ImplItems - Module");), + (Crate , BUG(i.span, "Resolve_Absolute_ImplItems - Crate");), + (Enum , BUG(i.span, "Resolve_Absolute_ImplItems - Enum");), + (Trait , BUG(i.span, "Resolve_Absolute_ImplItems - Trait");), + (Struct, BUG(i.span, "Resolve_Absolute_ImplItems - Struct");), + (Union , BUG(i.span, "Resolve_Absolute_ImplItems - Union");), (Type, DEBUG("Type - " << i.name); assert( e.params().ty_params().size() == 0 ); @@ -2077,17 +2077,17 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Im (None, ), (MacroInv, ), - (Impl , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (NegImpl, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (ExternBlock, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Macro , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Use , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Module, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Crate , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Enum , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Trait , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Struct, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), - (Union , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Impl , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (NegImpl, BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (ExternBlock, BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Macro , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Use , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Module, BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Crate , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Enum , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Trait , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Struct, BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), + (Union , BUG(i.sp, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (Type, DEBUG("Type - " << i.name); assert( e.params().ty_params().size() == 0 ); @@ -2253,7 +2253,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) { TU_MATCH_DEF(AST::Item, (i2.data), (e2), ( - BUG(i2.data.span, "Unexpected item in ExternBlock - " << i2.data.tag_str()); + BUG(i.span, "Unexpected item in ExternBlock - " << i2.data.tag_str()); ), (None, ), @@ -2281,7 +2281,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) Resolve_Absolute_Generic(item_context, def.params()); if( e.items().size() != 0 ) { - ERROR(i.data.span, E0000, "impl Trait for .. with methods"); + ERROR(i.span, E0000, "impl Trait for .. with methods"); } item_context.pop(def.params()); @@ -2318,7 +2318,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) item_context.m_ibl_target_generics = &impl_def.params(); Resolve_Absolute_Type(item_context, impl_def.type()); if( !impl_def.trait().ent.is_valid() ) - BUG(i.data.span, "Encountered negative impl with no trait"); + BUG(i.span, "Encountered negative impl with no trait"); Resolve_Absolute_Path(item_context, impl_def.trait().sp, Context::LookupMode::Type, impl_def.trait().ent); item_context.m_ibl_target_generics = nullptr; diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index bde59da8..1511583e 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -131,28 +131,28 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) // - Types/modules only (Module, p.m_bindings.type = ::AST::PathBinding_Type::make_Module({&e}); - _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); + _add_item(i.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Crate, - ASSERT_BUG(i.data.span, crate.m_extern_crates.count(e.name) > 0, "Referenced crate '" << e.name << "' isn't loaded for `extern crate`"); + ASSERT_BUG(i.span, crate.m_extern_crates.count(e.name) > 0, "Referenced crate '" << e.name << "' isn't loaded for `extern crate`"); p.m_bindings.type = ::AST::PathBinding_Type::make_Crate({ &crate.m_extern_crates.at(e.name) }); - _add_item(i.data.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); + _add_item(i.span, mod, IndexName::Namespace, i.name, i.is_pub, mv$(p)); ), (Enum, p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({&e}); - _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_type(i.span, mod, i.name, i.is_pub, mv$(p)); ), (Union, p.m_bindings.type = ::AST::PathBinding_Type::make_Union({&e}); - _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_type(i.span, mod, i.name, i.is_pub, mv$(p)); ), (Trait, p.m_bindings.type = ::AST::PathBinding_Type::make_Trait({&e}); - _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_type(i.span, mod, i.name, i.is_pub, mv$(p)); ), (Type, p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({&e}); - _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_type(i.span, mod, i.name, i.is_pub, mv$(p)); ), // - Mixed (Struct, @@ -160,18 +160,18 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) // - If the struct is a tuple-like struct (or unit-like), it presents in the value namespace if( ! e.m_data.is_Struct() ) { p.m_bindings.value = ::AST::PathBinding_Value::make_Struct({&e}); - _add_item_value(i.data.span, mod, i.name, i.is_pub, p); + _add_item_value(i.span, mod, i.name, i.is_pub, p); } - _add_item_type(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_type(i.span, mod, i.name, i.is_pub, mv$(p)); ), // - Values only (Function, p.m_bindings.value = ::AST::PathBinding_Value::make_Function({&e}); - _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_value(i.span, mod, i.name, i.is_pub, mv$(p)); ), (Static, p.m_bindings.value = ::AST::PathBinding_Value::make_Static({&e}); - _add_item_value(i.data.span, mod, i.name, i.is_pub, mv$(p)); + _add_item_value(i.span, mod, i.name, i.is_pub, mv$(p)); ) ) } @@ -761,7 +761,7 @@ void Resolve_Index_Module_Normalise(const ::AST::Crate& crate, const Span& mod_s for( auto& item : mod.items() ) { TU_IFLET(AST::Item, item.data, Module, e, - Resolve_Index_Module_Normalise(crate, item.data.span, e); + Resolve_Index_Module_Normalise(crate, item.span, e); ) } -- cgit v1.2.3 From 9ce35b65e5be4ce75b3b7aabe29c432128a17279 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 26 Oct 2019 16:09:24 +0800 Subject: All - Compilation fixes on VS2015 (constructors, warnings, missing files, class/struct disagreement, ) --- src/ast/crate.cpp | 38 ++++++++++++++++++---- src/hir/from_ast.cpp | 4 +-- src/hir/hir.hpp | 16 +++++++++ src/hir/type.hpp | 9 +++++ src/hir_expand/vtable.cpp | 11 +++---- src/hir_typeck/expr_visit.cpp | 7 ++++ src/include/span.hpp | 3 +- src/macro_rules/parse.cpp | 6 ++-- src/mir/from_hir.cpp | 1 + src/mir/mir.cpp | 1 + src/mir/mir.hpp | 2 +- src/rc_string.cpp | 1 + tools/standalone_miri/hir_sim.cpp | 2 ++ tools/standalone_miri/mir.cpp | 1 + tools/standalone_miri/miri.cpp | 13 ++++---- tools/standalone_miri/value.hpp | 5 ++- tools/testrunner/main.cpp | 3 ++ vsproject/minicargo/minicargo.vcxproj | 9 +++++ vsproject/minicargo/minicargo.vcxproj.filters | 3 ++ vsproject/mrustc.vcxproj | 7 ++-- vsproject/mrustc.vcxproj.filters | 21 ++++++++---- vsproject/standalone_miri/standalone_miri.vcxproj | 9 +++-- .../standalone_miri.vcxproj.filters | 3 ++ 23 files changed, 138 insertions(+), 37 deletions(-) (limited to 'src/hir/from_ast.cpp') diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index e788f6e0..19a19381 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -12,7 +12,12 @@ #include // HIR::Crate #include // HIR_Deserialise #include -#include +#ifdef _WIN32 +# define NOGDI // prevent ERROR from being defined +# include +#else +# include +#endif ::std::vector<::std::string> AST::g_crate_load_dirs = { }; ::std::map<::std::string, ::std::string> AST::g_crate_overrides; @@ -167,6 +172,17 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st path = ""; // Search for `p+"/lib"+name+"-*.rlib" (which would match e.g. libnum-0.11.rlib) +#ifdef _WIN32 + WIN32_FIND_DATA find_data; + auto mask = p + "\\*"; + HANDLE find_handle = FindFirstFile( mask.c_str(), &find_data ); + if( find_handle == INVALID_HANDLE_VALUE ) { + continue ; + } + do + { + const auto* fname = find_data.cFileName; +#else auto dp = opendir(p.c_str()); if( !dp ) { continue ; @@ -174,12 +190,15 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st struct dirent *ent; while( (ent = readdir(dp)) != nullptr && path == "" ) { + const auto* fname = ent->d_name; +#endif + // AND the start is "lib"+name - size_t len = strlen(ent->d_name); - if( len > (sizeof(RLIB_SUFFIX)-1) && strcmp(ent->d_name + len - (sizeof(RLIB_SUFFIX)-1), RLIB_SUFFIX) == 0 ) + size_t len = strlen(fname); + if( len > (sizeof(RLIB_SUFFIX)-1) && strcmp(fname + len - (sizeof(RLIB_SUFFIX)-1), RLIB_SUFFIX) == 0 ) { } - else if( len > (sizeof(RDYLIB_SUFFIX)-1) && strcmp(ent->d_name + len - (sizeof(RDYLIB_SUFFIX)-1), RDYLIB_SUFFIX) == 0 ) + else if( len > (sizeof(RDYLIB_SUFFIX)-1) && strcmp(fname + len - (sizeof(RDYLIB_SUFFIX)-1), RDYLIB_SUFFIX) == 0 ) { } else @@ -187,14 +206,19 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st continue ; } - DEBUG(ent->d_name << " vs " << name_prefix); + DEBUG(fname << " vs " << name_prefix); // Check if the entry ends with .rlib - if( strncmp(name_prefix.c_str(), ent->d_name, name_prefix.size()) != 0 ) + if( strncmp(name_prefix.c_str(), fname, name_prefix.size()) != 0 ) continue ; - paths.push_back( p + "/" + ent->d_name ); + paths.push_back( p + "/" + fname ); +#ifdef _WIN32 + } while( FindNextFile(find_handle, &find_data) ); + FindClose(find_handle); +#else } closedir(dp); +#endif if( paths.size() > 0 ) break; } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 54644806..4cde40fc 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -31,10 +31,10 @@ const ::AST::Crate* g_ast_crate_ptr; // -------------------------------------------------------------------- HIR::LifetimeRef LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) { - return HIR::LifetimeRef { + return HIR::LifetimeRef( // TODO: names? r.binding() - }; + ); } ::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp, bool* self_is_sized) diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index bdfc8d0b..8b718b4f 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -323,6 +323,22 @@ public: (Named, t_struct_fields) ); + Struct(GenericParams params, Repr repr, Data data) + :m_params(mv$(params)) + ,m_repr(mv$(repr)) + ,m_data(mv$(data)) + { + } + Struct(GenericParams params, Repr repr, Data data, unsigned align, TraitMarkings tm, StructMarkings sm) + :m_params(mv$(params)) + ,m_repr(mv$(repr)) + ,m_data(mv$(data)) + ,m_forced_alignment(align) + ,m_markings(mv$(tm)) + ,m_struct_markings(mv$(sm)) + { + } + GenericParams m_params; Repr m_repr; Data m_data; diff --git a/src/hir/type.hpp b/src/hir/type.hpp index fe28deed..cbc2e94a 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -93,6 +93,15 @@ struct LifetimeRef // Values below 2^16 are parameters/static, values above are per-function region IDs allocated during region inferrence. uint32_t binding = UNKNOWN; + LifetimeRef() + :binding(UNKNOWN) + { + } + LifetimeRef(uint32_t binding) + :binding(binding) + { + } + static LifetimeRef new_static() { LifetimeRef rv; rv.binding = STATIC; diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index cd7b3413..d2afff5d 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -231,12 +231,11 @@ namespace { } } // TODO: Would like to have access to the publicity marker - auto item_path = m_new_type(true, RcString::new_interned(FMT(p.get_name() << "#vtable")), ::HIR::Struct { - mv$(args), - ::HIR::Struct::Repr::Rust, - ::HIR::Struct::Data(mv$(fields)), - {} - }); + auto item_path = m_new_type( + true, + RcString::new_interned(FMT(p.get_name() << "#vtable")), + ::HIR::Struct(mv$(args), ::HIR::Struct::Repr::Rust, ::HIR::Struct::Data(mv$(fields))) + ); tr.m_vtable_path = item_path; DEBUG("Vtable structure created - " << item_path); ::HIR::GenericPath path( mv$(item_path), mv$(params) ); diff --git a/src/hir_typeck/expr_visit.cpp b/src/hir_typeck/expr_visit.cpp index c655bc52..df27b7d7 100644 --- a/src/hir_typeck/expr_visit.cpp +++ b/src/hir_typeck/expr_visit.cpp @@ -65,6 +65,12 @@ namespace typeck { TU_ARMA(Function, e) { m_item_generics = &e.m_params; } + TU_ARMA(Constant, e) { + m_item_generics = &e.m_params; + } + TU_ARMA(Static, e) { + m_item_generics = nullptr; + } } } else if( ip.parent->ty ) @@ -91,6 +97,7 @@ namespace typeck { } TU_ARMA(StructConstant, _e) BUG(sp, ip << " is StructConstant"); TU_ARMA(StructConstructor, _e) BUG(sp, ip << " is StructConstructor"); + TU_ARMA(Import, _e) BUG(sp, ip << " is Import"); } } } diff --git a/src/include/span.hpp b/src/include/span.hpp index 68d6bfdf..51c3440c 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -29,8 +29,9 @@ struct ProtoSpan unsigned int start_line; unsigned int start_ofs; }; -struct Span +class Span { +public: ::std::shared_ptr outer_span; // Expansion target for macros RcString filename; diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 97e1f8f9..43ffb097 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -58,7 +58,9 @@ public: switch( GET_TOK(tok, lex) ) { // TODO: Allow any reserved word - case TOK_RWORD_PUB ... TOK_RWORD_UNSIZED: + default: + if( !(TOK_RWORD_PUB <= tok.type() && tok.type() <= TOK_RWORD_UNSIZED) ) + throw ParseError::Unexpected(lex, tok); case TOK_IDENT: { auto name = tok.type() == TOK_IDENT ? tok.istr() : RcString::new_interned(FMT(tok)); GET_CHECK_TOK(tok, lex, TOK_COLON); @@ -123,8 +125,6 @@ public: throw ParseError::Unexpected(lex, tok); } break; } - default: - throw ParseError::Unexpected(lex, tok); } break; case TOK_EOF: diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 4ab1bf00..697f8141 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -19,6 +19,7 @@ #include #include #include // Target_GetSizeAndAlignOf - for `box` +#include // isdigit namespace { diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 8e3045d6..a0def040 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -6,6 +6,7 @@ * - MIR (Middle Intermediate Representation) definitions */ #include +#include // std::min namespace MIR { ::std::ostream& operator<<(::std::ostream& os, const Constant& v) { diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index f3d61dfa..99698134 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -655,7 +655,7 @@ public: ~EnumCachePtr(); EnumCachePtr(EnumCachePtr&& x): p(x.p) { x.p = nullptr; } EnumCachePtr& operator=(EnumCachePtr&& x) { this->~EnumCachePtr(); p = x.p; x.p = nullptr; return *this; } - operator bool() { return p; } + operator bool() { return p != nullptr; } const EnumCache& operator*() const { return *p; } const EnumCache* operator->() const { return p; } }; diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 38f6b15d..260ba90a 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // std::max RcString::RcString(const char* s, unsigned int len): m_ptr(nullptr) diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp index 135ea214..9d497054 100644 --- a/tools/standalone_miri/hir_sim.cpp +++ b/tools/standalone_miri/hir_sim.cpp @@ -156,6 +156,8 @@ size_t HIR::TypeRef::get_align(size_t ofs) const case RawType::USize: case RawType::ISize: return POINTER_SIZE; + case RawType::Unreachable: + LOG_BUG("Getting alignment of unreachable type"); } throw ""; } diff --git a/tools/standalone_miri/mir.cpp b/tools/standalone_miri/mir.cpp index 4a5df067..bc456ca6 100644 --- a/tools/standalone_miri/mir.cpp +++ b/tools/standalone_miri/mir.cpp @@ -9,6 +9,7 @@ #include "../../src/mir/mir.hpp" #include "hir_sim.hpp" #include +#include // std::min #if 0 namespace std { diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp index 21c39a1e..4eadac66 100644 --- a/tools/standalone_miri/miri.cpp +++ b/tools/standalone_miri/miri.cpp @@ -5,6 +5,7 @@ * miri.cpp * - Interpreter core */ +#define _CRT_SECURE_NO_WARNINGS #include #include "module_tree.hpp" #include "value.hpp" @@ -15,13 +16,14 @@ #include "miri.hpp" // VVV FFI #include // memrchr +#include +#include #ifdef _WIN32 # define NOMINMAX # include +#else +# include #endif -#include -#include -#include #undef DEBUG unsigned ThreadState::s_next_tls_key = 1; @@ -2082,7 +2084,6 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c } else if( link_name == "GetModuleHandleW" ) { - LOG_ASSERT(args.at(0).allocation, ""); const auto& tgt_alloc = args.at(0).get_relocation(0); const void* arg0 = (tgt_alloc ? tgt_alloc.alloc().data_ptr() : nullptr); //extern void* GetModuleHandleW(const void* s); @@ -2096,7 +2097,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c auto ret = GetModuleHandleW(static_cast(arg0)); if(ret) { - rv = Value::new_ffiptr(FFIPointer { "GetModuleHandleW", ret, 0 }); + rv = Value::new_ffiptr(FFIPointer::new_void("GetModuleHandleW", ret)); } else { @@ -2121,7 +2122,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c if( ret ) { - rv = Value::new_ffiptr(FFIPointer { "GetProcAddress", ret, 0 }); + rv = Value::new_ffiptr(FFIPointer::new_void("GetProcAddress", ret)); } else { diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp index a76e922b..03a21970 100644 --- a/tools/standalone_miri/value.hpp +++ b/tools/standalone_miri/value.hpp @@ -57,6 +57,9 @@ struct FFIPointer const char* tag_name; ::std::shared_ptr layout; + static FFIPointer new_void(const char* name, const void* v) { + return FFIPointer { const_cast(v), name, ::std::make_shared() }; + } static FFIPointer new_const_bytes(const char* name, const void* s, size_t size) { return FFIPointer { const_cast(s), name, ::std::make_shared(FfiLayout::new_const_bytes(size)) }; }; @@ -511,7 +514,7 @@ struct ValueRef: LOG_NOTICE("ValueRef exceeds bounds of FFI buffer - " << ofs << "+" << size << " > " << m_alloc.ffi().get_size()); } break; - default: + case RelocationPtr::Ty::Function: LOG_TODO(""); } } diff --git a/tools/testrunner/main.cpp b/tools/testrunner/main.cpp index 148fff9d..a634d87a 100644 --- a/tools/testrunner/main.cpp +++ b/tools/testrunner/main.cpp @@ -170,12 +170,15 @@ int main(int argc, const char* argv[]) return v; } +#ifdef _WIN32 +#else { struct sigaction sa = {0}; sa.sa_handler = sigalrm_handler; sigaction(SIGALRM, &sa, NULL); signal(SIGINT, sigint_handler); } +#endif ::std::vector<::std::string> skip_list; // > Filter out tests listed in an exceptions file (newline separated, supports comments) diff --git a/vsproject/minicargo/minicargo.vcxproj b/vsproject/minicargo/minicargo.vcxproj index 25ffbe03..c632cee2 100644 --- a/vsproject/minicargo/minicargo.vcxproj +++ b/vsproject/minicargo/minicargo.vcxproj @@ -75,6 +75,8 @@ Disabled true ..\..\tools\common + + $(OutDir) @@ -87,6 +89,8 @@ Disabled true ..\..\tools\common + + $(OutDir) @@ -101,6 +105,8 @@ true true ..\..\tools\common + + true @@ -117,6 +123,8 @@ true true ..\..\tools\common + + true @@ -127,6 +135,7 @@ + diff --git a/vsproject/minicargo/minicargo.vcxproj.filters b/vsproject/minicargo/minicargo.vcxproj.filters index 8fcee797..b9066a85 100644 --- a/vsproject/minicargo/minicargo.vcxproj.filters +++ b/vsproject/minicargo/minicargo.vcxproj.filters @@ -27,6 +27,9 @@ Source Files + + Source Files + diff --git a/vsproject/mrustc.vcxproj b/vsproject/mrustc.vcxproj index 13c4a23e..6cd135f4 100644 --- a/vsproject/mrustc.vcxproj +++ b/vsproject/mrustc.vcxproj @@ -157,6 +157,8 @@ + + @@ -166,6 +168,7 @@ + @@ -193,6 +196,7 @@ + @@ -204,9 +208,9 @@ + - @@ -259,7 +263,6 @@ - diff --git a/vsproject/mrustc.vcxproj.filters b/vsproject/mrustc.vcxproj.filters index 755013af..9d9dbcb4 100644 --- a/vsproject/mrustc.vcxproj.filters +++ b/vsproject/mrustc.vcxproj.filters @@ -98,9 +98,6 @@ Source Files\hir_expand - - Source Files\hir_expand - Source Files\hir_conv @@ -212,9 +209,6 @@ Source Files\trans - - Source Files\trans - Source Files\expand @@ -392,6 +386,21 @@ Source Files + + Source Files\trans + + + Source Files\trans + + + Source Files\hir_conv + + + Source Files\hir + + + Source Files\expand + diff --git a/vsproject/standalone_miri/standalone_miri.vcxproj b/vsproject/standalone_miri/standalone_miri.vcxproj index 5c235353..6b3c317c 100644 --- a/vsproject/standalone_miri/standalone_miri.vcxproj +++ b/vsproject/standalone_miri/standalone_miri.vcxproj @@ -90,7 +90,8 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) - 4062;4061;%(TreatSpecificWarningsAsErrors) + 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -106,7 +107,8 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) - 4062;4061;%(TreatSpecificWarningsAsErrors) + 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -125,6 +127,7 @@ true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -145,6 +148,7 @@ true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -165,6 +169,7 @@ + diff --git a/vsproject/standalone_miri/standalone_miri.vcxproj.filters b/vsproject/standalone_miri/standalone_miri.vcxproj.filters index 3b25bbfb..5e7af341 100644 --- a/vsproject/standalone_miri/standalone_miri.vcxproj.filters +++ b/vsproject/standalone_miri/standalone_miri.vcxproj.filters @@ -62,5 +62,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3 From dc806b29ce79d6ba40aca85bbdc5640261070910 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 27 Oct 2019 19:33:59 +0800 Subject: MSVC - General compilation fixes, `hello.exe` building and running --- .gitignore | 1 + .../build_compiler_builtins.txt | 1 + .../stable-1.29.0-windows/build_libc.txt | 2 + .../stable-1.29.0-windows/build_rustc_asan.txt | 0 .../stable-1.29.0-windows/build_rustc_lsan.txt | 0 .../stable-1.29.0-windows/build_rustc_msan.txt | 0 .../stable-1.29.0-windows/build_rustc_tsan.txt | 0 .../stable-1.29.0-windows/build_std.txt | 5 ++ .../stable-1.29.0-windows/build_unwind.txt | 1 + src/expand/asm.cpp | 2 +- src/hir/from_ast.cpp | 4 +- src/trans/codegen_c.cpp | 57 ++++------------------ vsproject/build_cargo_minicargo.cmd | 11 ++--- vsproject/build_std.cmd | 21 ++++---- vsproject/run_hello.cmd | 13 +++-- 15 files changed, 43 insertions(+), 75 deletions(-) create mode 100644 script-overrides/stable-1.29.0-windows/build_compiler_builtins.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_libc.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_rustc_asan.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_rustc_lsan.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_rustc_msan.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_rustc_tsan.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_std.txt create mode 100644 script-overrides/stable-1.29.0-windows/build_unwind.txt (limited to 'src/hir/from_ast.cpp') diff --git a/.gitignore b/.gitignore index e6040167..85e154ff 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ /vsproject/*/*.opendb /vsproject/*/*.user /vsproject/output +/vsproject/output-* /vsproject/output_mmir /vsproject/*.obj /vsproject/*.pdb diff --git a/script-overrides/stable-1.29.0-windows/build_compiler_builtins.txt b/script-overrides/stable-1.29.0-windows/build_compiler_builtins.txt new file mode 100644 index 00000000..06ae3dbf --- /dev/null +++ b/script-overrides/stable-1.29.0-windows/build_compiler_builtins.txt @@ -0,0 +1 @@ +# NOTE: mrustc doesn't need this built fully \ No newline at end of file diff --git a/script-overrides/stable-1.29.0-windows/build_libc.txt b/script-overrides/stable-1.29.0-windows/build_libc.txt new file mode 100644 index 00000000..aa2eb983 --- /dev/null +++ b/script-overrides/stable-1.29.0-windows/build_libc.txt @@ -0,0 +1,2 @@ +cargo:rustc-cfg=stdbuild +cargo:rerun-if-changed=build.rs \ No newline at end of file diff --git a/script-overrides/stable-1.29.0-windows/build_rustc_asan.txt b/script-overrides/stable-1.29.0-windows/build_rustc_asan.txt new file mode 100644 index 00000000..e69de29b diff --git a/script-overrides/stable-1.29.0-windows/build_rustc_lsan.txt b/script-overrides/stable-1.29.0-windows/build_rustc_lsan.txt new file mode 100644 index 00000000..e69de29b diff --git a/script-overrides/stable-1.29.0-windows/build_rustc_msan.txt b/script-overrides/stable-1.29.0-windows/build_rustc_msan.txt new file mode 100644 index 00000000..e69de29b diff --git a/script-overrides/stable-1.29.0-windows/build_rustc_tsan.txt b/script-overrides/stable-1.29.0-windows/build_rustc_tsan.txt new file mode 100644 index 00000000..e69de29b diff --git a/script-overrides/stable-1.29.0-windows/build_std.txt b/script-overrides/stable-1.29.0-windows/build_std.txt new file mode 100644 index 00000000..062afd95 --- /dev/null +++ b/script-overrides/stable-1.29.0-windows/build_std.txt @@ -0,0 +1,5 @@ +# TODO: THis is the windows set +cargo:rustc-link-lib=advapi32 +cargo:rustc-link-lib=ws2_32 +cargo:rustc-link-lib=userenv +cargo:rustc-link-lib=shell32 \ No newline at end of file diff --git a/script-overrides/stable-1.29.0-windows/build_unwind.txt b/script-overrides/stable-1.29.0-windows/build_unwind.txt new file mode 100644 index 00000000..aba1574a --- /dev/null +++ b/script-overrides/stable-1.29.0-windows/build_unwind.txt @@ -0,0 +1 @@ +# On both windows (MSVC) and linux (glibc), nothing is needed \ No newline at end of file diff --git a/src/expand/asm.cpp b/src/expand/asm.cpp index f8b3984d..90612758 100644 --- a/src/expand/asm.cpp +++ b/src/expand/asm.cpp @@ -166,7 +166,7 @@ class CAsmExpander: { GET_TOK(tok, lex); - if( GET_TOK(tok, lex) == TOK_IDENT && tok.str() == "volatile" ) + if( GET_TOK(tok, lex) == TOK_IDENT && tok.istr() == "volatile" ) { flags.push_back( "volatile" ); } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 4cde40fc..e3cba9e9 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -959,8 +959,8 @@ namespace { } else if( repr_str == "align" ) { //ASSERT_BUG(a.span(), a.has_string(), "#[repr(aligned)] attribute malformed, " << *attr_repr); - ASSERT_BUG(a.span(), rv.m_repr == ::HIR::Struct::Repr::Rust, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); - rv.m_repr = ::HIR::Struct::Repr::Aligned; + ASSERT_BUG(a.span(), rv.m_repr != ::HIR::Struct::Repr::Packed, "Conflicting #[repr] attributes - " << rv.m_repr << ", " << repr_str); + //rv.m_repr = ::HIR::Struct::Repr::Aligned; //rv.m_forced_alignment = ::std::stol(a.string()); } else { diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index dc7f0fee..4131c820 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -416,6 +416,7 @@ namespace { << "static inline uint8_t InterlockedExchangeNoFence8(volatile uint8_t* v, uint8_t n){ return InterlockedExchange8(v, n); }\n" << "static inline uint8_t InterlockedExchangeAcquire8(volatile uint8_t* v, uint8_t n){ return InterlockedExchange8(v, n); }\n" << "static inline uint8_t InterlockedExchangeRelease8(volatile uint8_t* v, uint8_t n){ return InterlockedExchange8(v, n); }\n" + << "static inline uint8_t InterlockedCompareExchange32(volatile uint32_t* v, uint32_t n, uint32_t e){ return InterlockedCompareExchange(v, n, e); }\n" ; // Atomic hackery for(int sz = 8; sz <= 64; sz *= 2) @@ -717,7 +718,7 @@ namespace { H::ty_args(args, method.args[j]); H::emit_proto(m_of, method, "__rust_", args); m_of << " {\n"; m_of << "\textern "; H::emit_proto(m_of, method, alloc_prefix, args); m_of << ";\n"; - m_of << "\t" << alloc_prefix << method.name << "("; + m_of << "\treturn " << alloc_prefix << method.name << "("; for(size_t j = 0; j < args.size(); j ++) { if( j != 0 ) @@ -938,6 +939,8 @@ namespace { { case CodegenOutput::Executable: case CodegenOutput::DynamicLibrary: + args.push_back(FMT("/Fe" << m_outfile_path)); + switch(out_ty) { case CodegenOutput::Executable: @@ -950,8 +953,6 @@ namespace { throw "bug"; } - args.push_back(FMT("/Fe" << m_outfile_path)); - for( const auto& crate : m_crate.m_ext_crates ) { args.push_back(crate.second.m_path + ".obj"); @@ -1873,7 +1874,7 @@ namespace { // Handled with asm() later break; case Compiler::Msvc: - //m_of << "#pragma comment(linker, \"/alternatename:_" << Trans_Mangle(p) << "=" << item.m_linkage.name << "\")\n"; + //m_of << "#pragma comment(linker, \"/alternatename:" << Trans_Mangle(p) << "=" << item.m_linkage.name << "\")\n"; m_of << "#define " << Trans_Mangle(p) << " " << item.m_linkage.name << "\n"; break; //case Compiler::Std11: @@ -2394,7 +2395,8 @@ namespace { } else if( item.m_linkage.name != "" && m_compiler == Compiler::Msvc ) { - m_of << "static "; + m_of << "#pragma comment(linker, \"/alternatename:" << Trans_Mangle(p) << "=" << item.m_linkage.name << "\")\n"; + m_of << "extern "; } else if( item.m_linkage.name == "_Unwind_RaiseException" ) { @@ -2422,48 +2424,6 @@ namespace { m_of << " asm(\"" << item.m_linkage.name << "\")"; break; case Compiler::Msvc: - m_of << " {\n"; - // A few hacky hard-coded signatures - if( item.m_linkage.name == "SetFilePointerEx" ) - { - // LARGE_INTEGER - m_of << "\tLARGE_INTEGER arg1_v;\n"; - m_of << "\targ1_v.QuadPart = arg1;\n"; - m_of << "\treturn SetFilePointerEx(arg0, arg1_v, arg2, arg3);\n"; - } - else if( item.m_linkage.name == "CopyFileExW" ) - { - // Not field access to undo an Option - m_of << "\treturn CopyFileExW(arg0, arg1, arg2.DATA.var_1._0, arg3, arg4, arg5);\n"; - } - // BUG: libtest defines this as returning an i32, but it's void - else if( item.m_linkage.name == "GetSystemInfo" ) - { - m_of << "\tGetSystemInfo(arg0);\n"; - m_of << "\treturn 0;\n"; - } - else - { - m_of << "\t"; - if( TU_TEST1(item.m_return.m_data, Tuple, .size() == 0) ) - ; - else if( item.m_return.m_data.is_Diverge() ) - ; - else { - m_of << "return "; - if( item.m_return.m_data.is_Pointer() ) - m_of << "(void*)"; - } - m_of << item.m_linkage.name << "("; - for(size_t i = 0; i < item.m_args.size(); i ++ ) - { - if( i > 0 ) - m_of << ", "; - m_of << "arg" << i; - } - m_of << ");\n"; - } - m_of << "}"; break; } } @@ -2481,6 +2441,7 @@ namespace { m_of << "// PROTO extern \"" << item.m_abi << "\" " << p << "\n"; if( item.m_linkage.name != "" ) { + // If this function is implementing an external ABI, just rename it (don't bother with per-compiler trickery). m_of << "#define " << Trans_Mangle(p) << " " << item.m_linkage.name << "\n"; } if( is_extern_def ) @@ -4123,7 +4084,7 @@ namespace { } else if( matches_template("pushq $0; popfq", /*input=*/{"r"}, /*output=*/{}) ) { - m_of << indent << "__writeflags("; emit_lvalue(e.inputs[0].second); m_of << ");\n"; + m_of << indent << "__writeeflags("; emit_lvalue(e.inputs[0].second); m_of << ");\n"; return ; } else if( matches_template("xgetbv", /*input=*/{"{ecx}"}, /*output=*/{"={eax}", "={edx}"}) ) diff --git a/vsproject/build_cargo_minicargo.cmd b/vsproject/build_cargo_minicargo.cmd index 33725f4e..ce878e48 100644 --- a/vsproject/build_cargo_minicargo.cmd +++ b/vsproject/build_cargo_minicargo.cmd @@ -1,7 +1,6 @@ -@echo off -call build_std.cmd -if %errorlevel% neq 0 exit /b %errorlevel% +@call build_std.cmd +@if %errorlevel% neq 0 exit /b %errorlevel% -mkdir output\cargo-build -x64\Release\minicargo.exe ..\rustc-1.19.0-src\src\tools\cargo -L output --output-dir output\cargo-build --vendor-dir ..\rustc-1.19.0-src\src\vendor -if %errorlevel% neq 0 exit /b %errorlevel% \ No newline at end of file +@mkdir %OUTDIR%\cargo-build +x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\tools\cargo -L %OUTDIR% --output-dir %OUTDIR%\cargo-build --vendor-dir ..\rustc-%RUSTC_VERSION%-src\src\vendor +@if %errorlevel% neq 0 exit /b %errorlevel% \ No newline at end of file diff --git a/vsproject/build_std.cmd b/vsproject/build_std.cmd index 786648ec..ff09a0b6 100644 --- a/vsproject/build_std.cmd +++ b/vsproject/build_std.cmd @@ -1,12 +1,11 @@ -@echo off -set RUSTC_VERSION=1.29.0 -set OUTDIR=output-%RUSTC_VERSION% -mkdir %OUTDIR% -x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libstd --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION% -if %errorlevel% neq 0 exit /b %errorlevel% -x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libpanic_unwind --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION% -if %errorlevel% neq 0 exit /b %errorlevel% -x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libtest --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION% -if %errorlevel% neq 0 exit /b %errorlevel% +@set RUSTC_VERSION=1.29.0 +@set OUTDIR=output-%RUSTC_VERSION% +@mkdir %OUTDIR% +x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libstd --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION%-windows +@if %errorlevel% neq 0 exit /b %errorlevel% +x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libpanic_unwind --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION%-windows +@if %errorlevel% neq 0 exit /b %errorlevel% +x64\Release\minicargo.exe ..\rustc-%RUSTC_VERSION%-src\src\libtest --vendor-dir ..\rustc-%RUSTC_VERSION%-src\src\vendor --output-dir %OUTDIR% --script-overrides ..\script-overrides\stable-%RUSTC_VERSION%-windows +@if %errorlevel% neq 0 exit /b %errorlevel% x64\Release\minicargo.exe ..\lib\libproc_macro --output-dir %OUTDIR% -if %errorlevel% neq 0 exit /b %errorlevel% +@if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/vsproject/run_hello.cmd b/vsproject/run_hello.cmd index b419bbc1..894e8240 100644 --- a/vsproject/run_hello.cmd +++ b/vsproject/run_hello.cmd @@ -1,8 +1,7 @@ -@echo off -call build_std.cmd -if %errorlevel% neq 0 exit /b %errorlevel% +@call build_std.cmd +@if %errorlevel% neq 0 exit /b %errorlevel% -x64\Release\mrustc.exe ..\rustc-1.19.0-src\src\test\run-pass\hello.rs -L output -o output\hello.exe -g -if %errorlevel% neq 0 exit /b %errorlevel% -output\hello.exe -if %errorlevel% neq 0 exit /b %errorlevel% \ No newline at end of file +x64\Release\mrustc.exe ..\rustc-%RUSTC_VERSION%-src\src\test\run-pass\hello.rs -L %OUTDIR% -o %OUTDIR%\hello.exe -g +@if %errorlevel% neq 0 exit /b %errorlevel% +%OUTDIR%\hello.exe +@if %errorlevel% neq 0 exit /b %errorlevel% \ No newline at end of file -- cgit v1.2.3