diff options
| author | John Hodge <tpg@ucc.asn.au> | 2019-05-19 22:15:02 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@ucc.asn.au> | 2019-05-19 22:15:02 +0800 | 
| commit | b48167dec0c1c05b463991a8db5a8db70a5ae604 (patch) | |
| tree | eadc95ab546a617d298fb3a16fb080e1bc4355e8 | |
| parent | dab5cf5462d8fce6d6fcaa1343df8f5f3b763b8a (diff) | |
| download | mrust-b48167dec0c1c05b463991a8db5a8db70a5ae604.tar.gz | |
All - Switch to using interned (de-duplicated) RcString-s instead of std::string for paths/identifiers
96 files changed, 1202 insertions, 864 deletions
| 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<Item>(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<Item>(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<Item>(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<AST::Module> Module::add_anon() { -    auto rv = ::std::shared_ptr<AST::Module>( new Module(m_my_path + FMT("#" << m_anon_modules.size())) ); +    auto rv = ::std::shared_ptr<AST::Module>( 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<Item> 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<Item>( 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<MacroRulesPtr>( 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<const MacroRules*>( 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<Item>& items() const { return m_items; }            NamedList<Item>& 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<TypeRef> sub_types): +    EnumVariant(AttributeList attrs, RcString name, ::std::vector<TypeRef> 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<StructItem> fields): +    EnumVariant(AttributeList attrs, RcString name, ::std::vector<StructItem> 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<Item> 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<ImplItem>& items() const { return m_items; }            ::std::vector<ImplItem>& 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<Ent>  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<RcString>    path;   // includes the crate name          const MacroRules*   macro_ptr;      };      ::std::vector<MacroImport>  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<Import>   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<AST::Module> add_anon();      void add_item(Named<Item> 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<MacroRulesPtr>&    macros()        { return m_macros; }      const NamedList<MacroRulesPtr>&    macros()  const { return m_macros; }      const ::std::vector<Named<const MacroRules*> >  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<Attribute> items): +    Attribute(Span sp, RcString name, ::std::vector<Attribute> 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<void(const ::std::string& , const MacroRules&)> cb) const +void ExternCrate::with_all_macros(::std::function<void(const RcString& , const MacroRules&)> 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<void(const ::std::string& , const MacroRules&)> cb) const; -    const MacroRules* find_macro_rules(const ::std::string& name) const; +    void with_all_macros(::std::function<void(const RcString& , const MacroRules&)> 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<ExprNode>    m_value; -    ExprNode_Flow(Type type, ::std::string target, unique_ptr<ExprNode>&& value): +    ExprNode_Flow(Type type, RcString target, unique_ptr<ExprNode>&& 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<ExprNode>    m_cond; // if NULL, loop is a 'loop'      unique_ptr<ExprNode>    m_code;      ExprNode_Loop(): m_type(LOOP) {} -    ExprNode_Loop(::std::string label, unique_ptr<ExprNode> code): +    ExprNode_Loop(RcString label, unique_ptr<ExprNode> code):          m_type(LOOP),          m_label( ::std::move(label) ),          m_code( ::std::move(code) )      {} -    ExprNode_Loop(::std::string label, unique_ptr<ExprNode> cond, unique_ptr<ExprNode> code): +    ExprNode_Loop(RcString label, unique_ptr<ExprNode> cond, unique_ptr<ExprNode> 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<ExprNode> val, unique_ptr<ExprNode> code): +    ExprNode_Loop(RcString label, Type type, AST::Pattern pattern, unique_ptr<ExprNode> val, unique_ptr<ExprNode> 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<ExprNode>    value;      };      typedef ::std::vector<Ent> t_values; @@ -493,9 +493,9 @@ struct ExprNode_Field:      public ExprNode  {      ::std::unique_ptr<ExprNode> m_obj; -    ::std::string   m_name; +    RcString   m_name; -    ExprNode_Field(::std::unique_ptr<ExprNode>&& obj, ::std::string name): +    ExprNode_Field(::std::unique_ptr<ExprNode>&& 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 <typename T>  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<LifetimeRef> lfts, ::std::vector<TypeRef> tys, ::std::vector<::std::pair<::std::string,TypeRef>> a): +    PathParams(::std::vector<LifetimeRef> lfts, ::std::vector<TypeRef> tys, ::std::vector<::std::pair<RcString,TypeRef>> 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<PathNode> nodes;              } ),          (Absolute, struct {    // Absolute -            ::std::string   crate; +            RcString    crate;              ::std::vector<PathNode> nodes;              } ),          (UFCS, struct {    // Type-relative @@ -267,7 +267,7 @@ public:      Path& operator=(const AST::Path&) = delete;      // ABSOLUTE -    Path(::std::string crate, ::std::vector<PathNode> nodes): +    Path(RcString crate, ::std::vector<PathNode> 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<Pattern> sub_pats; }),          (SplitSlice, struct { ::std::vector<Pattern> leading; PatternBinding extra_bind; ::std::vector<Pattern> 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<AST::ExprNode> 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<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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(""<<mi.name()<<": '"<<it->second<<"' == '"<<mi.string()<<"'"); @@ -70,7 +70,7 @@ bool check_cfg(const Span& sp, const ::AST::Attribute& mi) {          if( its.first != its.second )              return false; -        auto it2 = g_cfg_value_fcns.find(mi.name()); +        auto it2 = g_cfg_value_fcns.find(mi.name().c_str());          if(it2 != g_cfg_value_fcns.end() )          {              DEBUG(""<<mi.name()<<": ('"<<mi.string()<<"')?"); @@ -82,7 +82,7 @@ bool check_cfg(const Span& sp, const ::AST::Attribute& mi) {      }      else {          // Flag -        auto it = g_cfg_flags.find(mi.name()); +        auto it = g_cfg_flags.find(mi.name().c_str());          return (it != g_cfg_flags.end());      }      BUG(sp, "Fell off the end of check_cfg"); @@ -91,12 +91,8 @@ bool check_cfg(const Span& sp, const ::AST::Attribute& mi) {  class CCfgExpander:      public ExpandProcMacro  { -    ::std::unique_ptr<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<T> 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<TypeRef> 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<TypeRef> 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<std::string, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > 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<TypeRef> 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<TypeRef> 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<std::string, AST::Pattern> > pats_a; -                ::std::vector< ::std::pair<std::string, AST::Pattern> > pats_b; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_b;                  ::std::vector<AST::ExprNodeP>   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<TypeRef> 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<TypeRef> 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<AST::ExprNodeP>()) @@ -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<std::string, AST::Pattern> > pats_a; -                ::std::vector< ::std::pair<std::string, AST::Pattern> > pats_b; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_b;                  ::std::vector<AST::ExprNodeP>   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<TypeRef> 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<TypeRef> 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<std::string, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_a;                  ::std::vector<AST::ExprNodeP>   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<TypeRef> 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<TypeRef> 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<AST::ExprNodeP>())                      ), @@ -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<std::string, AST::Pattern> > pats_a; -                ::std::vector< ::std::pair<std::string, AST::Pattern> > pats_b; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > pats_b;                  ::std::vector<AST::ExprNodeP>   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<TypeRef> 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<TypeRef> 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<std::string, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > 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<TypeRef> 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<TypeRef> 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<TypeRef> 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<TypeRef> 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<TypeRef> 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<TypeRef> 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<std::string, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > 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<TypeRef> 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<TypeRef> 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<AST::ExprNodeP>   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<std::string, AST::Pattern> > pats_a; +                ::std::vector< ::std::pair<RcString, AST::Pattern> > 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<TypeRef> 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<TypeRef> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<FmtFrag>, ::std::string> parse_format_string(          const Span& sp,          const ::std::string& format_string, -        const ::std::map< ::std::string,unsigned int>& named, +        const ::std::map<RcString,unsigned int>& named,          unsigned int n_free          )      { -        unsigned int n_named = named.size(); +        //unsigned int n_named = named.size();          unsigned int next_free = 0;          ::std::vector<FmtFrag>  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 '"<<ident<<"' not found"); @@ -359,7 +359,7 @@ namespace {                          }                          if( *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 '"<<ident<<"' not found"); @@ -464,6 +464,9 @@ namespace {  }  namespace { +    Token ident(const char* s) { +        return Token(TOK_IDENT, RcString::new_interned(s)); +    }      void push_path(::std::vector<TokenTree>& toks, const AST::Crate& crate, ::std::initializer_list<const char*> 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<TokenTree>& 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<RcString, unsigned int>   named_args_index;          ::std::vector<TokenTree>    named_args;          ::std::vector<TokenTree>    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<uint64_t>(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<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> 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<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> 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<TokenStream> Expand_Macro_Inner(      const ::AST::Crate& crate, LList<const AST::Module*> 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<TokenStream> Expand_Macro(      const ::AST::Crate& crate, LList<const AST::Module*> 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<RcString>   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<RcString>& mac_path)  {      // 1. Locate macro in HIR list      const auto& crate_name = mac_path.front(); @@ -745,7 +745,7 @@ namespace {          }      };  } -::std::unique_ptr<TokenStream> 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<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& 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<TokenStream> 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<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& 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<TokenStream> 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<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& 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 <parse/tokenstream.hpp> -extern ::std::unique_ptr<TokenStream> 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<TokenStream> 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<TokenStream> 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<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<::std::string>& mac_path, const TokenStream& tt); +extern ::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, const ::std::string& name, const ::AST::Struct& i); +extern ::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, const ::std::string& name, const ::AST::Enum& i); +extern ::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& mac_path, const ::std::string& name, const ::AST::Union& i); +//extern ::std::unique_ptr<TokenStream> ProcMacro_Invoke(const Span& sp, const ::AST::Crate& crate, const ::std::vector<RcString>& 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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<TokenTree>    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<uint64_t>(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<TokenStream> expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override +    ::std::unique_ptr<TokenStream> 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 <macro_rules/macro_rules.hpp>  // 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<typename V> +        ::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<V>::des(*this) ) ); +            } +            return rv; +        } +        template<typename V> +        ::std::unordered_map< RcString,V> deserialise_istrumap() +        { +            TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); +            size_t n = m_in.read_count(); +            ::std::unordered_map<RcString, V>   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<V>::des(*this) ) ); +            } +            return rv; +        } +        template<typename V> +        ::std::unordered_multimap<RcString,V> deserialise_istrummap() +        { +            TRACE_FUNCTION_F("<" << typeid(V).name() << ">"); +            size_t n = m_in.read_count(); +            ::std::unordered_multimap<RcString, V>   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<V>::des(*this) ) ); +            } +            return rv; +        } +          template<typename T>          ::std::vector<T> 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<unsigned int>(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<RcString>();              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<eCoreType>(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<T>,          return d.deserialise_visent<T>(); ) +    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<unsigned int, ::HIR::GenericPath> >(); -        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<unsigned int, ::HIR::GenericPath> >(); +        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<unsigned int> 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<void(::std::string, ::HIR::Struct)> push_struct) +::HIR::Enum LowerHIR_Enum(::HIR::ItemPath path, const ::AST::Enum& ent, const ::AST::AttributeList& attrs, ::std::function<void(RcString, ::HIR::Struct)> 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<TypeParamDef>   m_types; -    ::std::vector< ::std::string>   m_lifetimes; +    ::std::vector<TypeParamDef> m_types; +    ::std::vector<LifetimeDef>  m_lifetimes;      ::std::vector<GenericBound>    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<unsigned int,::HIR::GenericPath> > m_value_indexes; +    ::std::unordered_multimap< RcString, ::std::pair<unsigned int,::HIR::GenericPath> > 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<VisEnt<ValueItem>> > m_value_items; +    ::std::unordered_map< RcString, ::std::unique_ptr<VisEnt<ValueItem>> > m_value_items;      // Contains types, traits, and modules -    ::std::unordered_map< ::std::string, ::std::unique_ptr<VisEnt<TypeItem>> > m_mod_items; +    ::std::unordered_map< RcString, ::std::unique_ptr<VisEnt<TypeItem>> > m_mod_items; -    ::std::vector< ::std::pair<::std::string, Static> >  m_inline_statics; +    ::std::vector< ::std::pair<RcString, Static> >  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<ExternLibrary>    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 <hir/path.hpp>  #include <hir/type.hpp> -::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<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> 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<TypeRef>  type; -        ::std::string   item; +        RcString   item;          PathParams  params;          PathParams  impl_params;          }),      (UfcsKnown, struct {          ::std::unique_ptr<TypeRef>  type;          GenericPath trait; -        ::std::string   item; +        RcString   item;          PathParams  params;          }),      (UfcsUnknown, struct {          ::std::unique_ptr<TypeRef>  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<RcString, Pattern> > 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<RcString, Pattern> > 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 @@ -21,6 +21,15 @@          {}          template<typename V> +        void serialise_strmap(const ::std::map<RcString,V>& map) +        { +            m_out.write_count(map.size()); +            for(const auto& v : map) { +                m_out.write_string(v.first); +                serialise(v.second); +            } +        } +        template<typename V>          void serialise_strmap(const ::std::map< ::std::string,V>& map)          {              m_out.write_count(map.size()); @@ -30,6 +39,16 @@              }          }          template<typename V> +        void serialise_strmap(const ::std::unordered_map<RcString,V>& 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<typename V>          void serialise_strmap(const ::std::unordered_map< ::std::string,V>& map)          {              m_out.write_count(map.size()); @@ -40,6 +59,16 @@              }          }          template<typename V> +        void serialise_strmap(const ::std::unordered_multimap<RcString,V>& 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<typename V>          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<typename T> +        void serialise(const ::std::pair< RcString, T>& e) { +            m_out.write_string(e.first); +            serialise(e.second); +        } +        template<typename T>          void serialise(const ::std::pair<unsigned int, T>& 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 <fstream>  #include <string.h>   // memcpy  #include <common.hpp> +#include <algorithm>  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<RcString, unsigned>> 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 <vector>  #include <string> +#include <map>  #include <stddef.h>  #include <assert.h> +#include <rc_string.hpp>  namespace HIR {  namespace serialise { @@ -21,12 +23,14 @@ class ReaderInner;  class Writer  {      WriterInner*    m_inner; +    ::std::map<RcString, unsigned>  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<uint16_t>(c) );          }      } -    void write_string(const ::std::string& v) { -        if(v.size() < 128) { -            write_u8( static_cast<uint8_t>(v.size()) ); +    void write_string(const RcString& v); +    void write_string(size_t len, const char* s) { +        if(len < 128) { +            write_u8( static_cast<uint8_t>(len) );          }          else { -            assert(v.size() < (1u<<(16+7))); -            write_u8( static_cast<uint8_t>(128 + (v.size() >> 16)) ); -            write_u16( static_cast<uint16_t>(v.size() & 0xFFFF) ); +            assert(len < (1u<<(16+7))); +            write_u8( static_cast<uint8_t>(128 + (len >> 16)) ); +            write_u16( static_cast<uint16_t>(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<RcString> 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<TraitResolution::AutoderefBorrow, ::HIR::Path>> 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<TraitResolution::AutoderefBorrow, ::HIR::Path>> 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<RcString, ::HIR::TypeRef>    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<RcString, ::HIR::TypeRef>    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<RcString, ::HIR::TypeRef>  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<RcString, ::HIR::TypeRef>  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<RcString, ::HIR::TypeRef>  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<RcString, ::HIR::TypeRef> 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<RcString, ::HIR::TypeRef> 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<RcString, ::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) )); @@ -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<RcString, ::HIR::TypeRef>    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<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, +        const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const char* method_name,          /* Out -> */::std::vector<::std::pair<AutoderefBorrow,::HIR::Path>>& 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<unsigned>& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, MethodAccess access, +    const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& ty, const char* method_name, MethodAccess access,      AutoderefBorrow borrow_type, /* Out -> */::std::vector<::std::pair<AutoderefBorrow,::HIR::Path>>& 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<bool(const ::HIR::TypeRef&, const ::HIR::TraitPath& trait)> cb) const;      bool iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data::Data_UfcsKnown& pe, ::std::function<bool(const ::HIR::TraitPath&)> cb) const; -    typedef ::std::function<bool(const ::HIR::TypeRef&, const ::HIR::PathParams&, const ::std::map< ::std::string,::HIR::TypeRef>&)> t_cb_trait_impl; +    typedef ::std::function<bool(const ::HIR::TypeRef&, const ::HIR::PathParams&, const ::std::map< RcString,::HIR::TypeRef>&)> t_cb_trait_impl;      typedef ::std::function<bool(ImplRef, ::HIR::Compare)> 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<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, +            const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const char* method_name,              /* Out -> */::std::vector<::std::pair<AutoderefBorrow,::HIR::Path>>& 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<unsigned>& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, MethodAccess access, +            const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& ty, const char* method_name, MethodAccess access,              AutoderefBorrow borrow_type, /* Out -> */::std::vector<::std::pair<AutoderefBorrow,::HIR::Path>>& 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<RcString, ::HIR::TypeRef>    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<void(const ::HIR::PathParams&, ::std::map< ::std::string, ::HIR::TypeRef>)> callback +        ::std::function<void(const ::HIR::PathParams&, ::std::map<RcString, ::HIR::TypeRef>)> 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="<<name << ", trait=" << trait_path, out_path);      auto it = trait_ptr.m_types.find(name); diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index 564d2110..781db3b3 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -187,10 +187,10 @@ public:              const ::HIR::SimplePath& des, const ::HIR::PathParams& params,              const ::HIR::Trait& trait_ptr, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& pp,              const ::HIR::TypeRef& self_type, -            ::std::function<void(const ::HIR::PathParams&, ::std::map< ::std::string, ::HIR::TypeRef>)> callback +            ::std::function<void(const ::HIR::PathParams&, ::std::map< RcString, ::HIR::TypeRef>)> callback              ) 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; +    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;      bool iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data::Data_UfcsKnown& pe, ::std::function<bool(const ::HIR::TraitPath&)> cb) const; diff --git a/src/include/ident.hpp b/src/include/ident.hpp index ec42c582..e8cc4e12 100644 --- a/src/include/ident.hpp +++ b/src/include/ident.hpp @@ -9,13 +9,13 @@  #include <vector>  #include <string>  #include <memory> +#include <rc_string.hpp>  struct Ident  {      struct ModPath      { -        //::std::vector<RcString> ents; -        ::std::vector<::std::string> ents; +        ::std::vector<RcString> ents;      };      class Hygiene      { @@ -77,17 +77,17 @@ struct Ident      };      Hygiene hygiene; -    ::std::string   name; +    RcString   name;      Ident(const char* name):          hygiene(),          name(name)      { } -    Ident(::std::string name): +    Ident(RcString name):          hygiene(),          name(::std::move(name))      { } -    Ident(Hygiene hygiene, ::std::string name): +    Ident(Hygiene hygiene, RcString name):          hygiene(::std::move(hygiene)), name(::std::move(name))      { } @@ -96,7 +96,7 @@ struct Ident      Ident& operator=(Ident&& x) = default;      Ident& operator=(const Ident& x) = default; -    ::std::string into_string() { +    RcString into_string() {          return ::std::move(name);      } diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index eec47d80..94b6d9e7 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -9,38 +9,37 @@  #include <cstring>  #include <ostream> +#include "../common.hpp"  class RcString  {      unsigned int*   m_ptr; -    unsigned int    m_len;  public:      RcString(): -        m_ptr(nullptr), -        m_len(0) +        m_ptr(nullptr)      {}      RcString(const char* s, unsigned int len);      RcString(const char* s):          RcString(s, ::std::strlen(s))      {      } -    RcString(const ::std::string& s): +    explicit RcString(const ::std::string& s):          RcString(s.data(), s.size())      {      } +    static RcString new_interned(const ::std::string& s); +    //static new_interned(const char* s); +      RcString(const RcString& x): -        m_ptr(x.m_ptr), -        m_len(x.m_len) +        m_ptr(x.m_ptr)      {          if( m_ptr ) *m_ptr += 1;      }      RcString(RcString&& x): -        m_ptr(x.m_ptr), -        m_len(x.m_len) +        m_ptr(x.m_ptr)      {          x.m_ptr = nullptr; -        x.m_len = 0;      }      ~RcString(); @@ -51,7 +50,6 @@ public:          {              this->~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<const char*>(m_ptr + 1); +            return reinterpret_cast<const char*>(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<RcString> +    { +        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<TokenStream>  expand(const Span& sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; +    virtual ::std::unique_ptr<TokenStream>  expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) = 0; +    virtual ::std::unique_ptr<TokenStream>  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<Span> 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<MacroExpansionEnt>& contents, ParameterMappings mappings, ::std::string crate_name): +    MacroExpander(const ::std::string& macro_name, const Span& sp, const Ident::Hygiene& parent_hygiene, const ::std::vector<MacroExpansionEnt>& 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<RcString>   m_param_names;      /// Patterns      ::std::vector<SimplePatEnt> 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<TokenStream>   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<MacroPatEnt> Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close,  ::std::vector< ::std::string>& names); -extern ::std::vector<MacroExpansionEnt> Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector< ::std::string>& var_names, ::std::map<unsigned int,bool>* var_set_ptr=nullptr); +extern ::std::vector<MacroPatEnt> Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close,  ::std::vector<RcString>& names); +extern ::std::vector<MacroExpansionEnt> Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector<RcString>& var_names, ::std::map<unsigned int,bool>* var_set_ptr=nullptr);  extern MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector<MacroPatEnt> pattern, ::std::vector<MacroExpansionEnt> 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<MacroPatEnt> Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close,  ::std::vector< ::std::string>& names) +::std::vector<MacroPatEnt> Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close,  ::std::vector<RcString>& 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<MacroExpansionEnt> Parse_MacroRules_Cont(      TokenStream& lex,      enum eTokenType open, enum eTokenType close, -    const ::std::vector< ::std::string>& var_names, +    const ::std::vector<RcString>& var_names,      ::std::map<unsigned int,bool>* 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<RcString>   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<MacroPatEnt>& pats, ::std::vector< ::std::string>& names) +void enumerate_names(const ::std::vector<MacroPatEnt>& pats, ::std::vector<RcString>& 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<bool> drop_flags;      ::std::vector<BasicBlock>   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_ptr<AST:      GET_TOK(tok, lex);      // `union Ident` - contextual keyword -    if( tok.type() == TOK_IDENT && tok.str() == "union" && lex.lookahead(0) == TOK_IDENT ) { +    if( tok.type() == TOK_IDENT && tok.istr() == "union" && lex.lookahead(0) == TOK_IDENT ) {          PUTBACK(tok, lex);          if( !local_mod ) {              local_mod = lex.parse_state().get_current_mod().add_anon(); @@ -117,7 +117,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST:          return ExprNodeP();      } -    if( tok.type() == TOK_IDENT && tok.str() == "macro_rules" && lex.lookahead(0) == TOK_EXCLAM ) +    if( tok.type() == TOK_IDENT && tok.istr() == "macro_rules" && lex.lookahead(0) == TOK_EXCLAM )      {          // Special case - create a local module if macro_rules! is seen          // - Allows correct scoping of defined macros @@ -191,7 +191,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)      if( GET_TOK(tok, lex) == TOK_LIFETIME )      {          // Lifetimes can only precede loops... and blocks? -        ::std::string lifetime = tok.str(); +        auto lifetime = tok.istr();          GET_CHECK_TOK(tok, lex, TOK_COLON);          switch( GET_TOK(tok, lex) ) @@ -291,7 +291,7 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)                  // If a braced macro invocation is the first part of a statement, don't expect a semicolon                  if( lex.lookahead(1) == TOK_BRACE_OPEN || (lex.lookahead(1) == TOK_IDENT && lex.lookahead(2) == TOK_BRACE_OPEN) ) {                      lex.getToken(); -                    return Parse_ExprMacro(lex, tok.str()); +                    return Parse_ExprMacro(lex, tok.istr());                  }              }          // Fall through to the statement code @@ -323,7 +323,7 @@ ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool& has_semicolon)  }  /// While loop (either as a statement, or as part of an expression) -ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime) +ExprNodeP Parse_WhileStmt(TokenStream& lex, RcString lifetime)  {      Token   tok; @@ -349,12 +349,12 @@ ExprNodeP Parse_WhileStmt(TokenStream& lex, ::std::string lifetime)      }  }  /// For loop (either as a statement, or as part of an expression) -ExprNodeP Parse_ForStmt(TokenStream& lex, ::std::string lifetime) +ExprNodeP Parse_ForStmt(TokenStream& lex, RcString lifetime)  {      Token   tok;      // Irrefutable pattern -    AST::Pattern    pat = Parse_Pattern(lex, false); +    auto pat = Parse_Pattern(lex, false);      GET_CHECK_TOK(tok, lex, TOK_RWORD_IN);      ExprNodeP val;      { @@ -524,10 +524,10 @@ ExprNodeP Parse_Stmt(TokenStream& lex)          case TOK_RWORD_BREAK:    type = AST::ExprNode_Flow::BREAK;    break;          default:    throw ParseError::BugCheck(/*lex,*/ "continue/break");          } -        ::std::string   lifetime; +        RcString lifetime;          if( GET_TOK(tok, lex) == TOK_LIFETIME )          { -            lifetime = tok.str(); +            lifetime = tok.istr();  // TODO: Hygine?              GET_TOK(tok, lex);          }          ExprNodeP   val; @@ -948,26 +948,26 @@ ExprNodeP Parse_ExprFC(TokenStream& lex)              switch(GET_TOK(tok, lex))              {              case TOK_IDENT: { -                AST::PathNode   path( mv$(tok.str()) , {}); +                AST::PathNode   pn( tok.istr() , {});                  switch( GET_TOK(tok, lex) )                  {                  case TOK_PAREN_OPEN:                      PUTBACK(tok, lex); -                    val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(path), Parse_ParenList(lex) ); +                    val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(pn), Parse_ParenList(lex) );                      break;                  case TOK_DOUBLE_COLON:                      GET_CHECK_TOK(tok, lex, TOK_LT); -                    path.args() = Parse_Path_GenericList(lex); -                    val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(path), Parse_ParenList(lex) ); +                    pn.args() = Parse_Path_GenericList(lex); +                    val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), ::std::move(pn), Parse_ParenList(lex) );                      break;                  default: -                    val = NEWNODE( AST::ExprNode_Field, ::std::move(val), ::std::string(path.name()) ); +                    val = NEWNODE( AST::ExprNode_Field, ::std::move(val), pn.name() );                      PUTBACK(tok, lex);                      break;                  }                  break; }              case TOK_INTEGER: -                val = NEWNODE( AST::ExprNode_Field, ::std::move(val), FMT(tok.intval()) ); +                val = NEWNODE( AST::ExprNode_Field, ::std::move(val), RcString::new_interned(FMT(tok.intval())) );                  break;              default:                  throw ParseError::Unexpected(lex, mv$(tok)); @@ -1033,7 +1033,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path)          }          CHECK_TOK(tok, TOK_IDENT);          auto h = lex.getHygiene(); -        auto name = mv$(tok.str()); +        auto name = tok.istr();          ExprNodeP   val;          if( lex.lookahead(0) != TOK_COLON ) @@ -1142,7 +1142,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)          if( TARGETVER_1_29 )          {              // `do catch` - stabilised later as `try` -            if( GET_TOK(tok, lex) == TOK_IDENT && tok.str() == "catch" ) +            if( GET_TOK(tok, lex) == TOK_IDENT && tok.istr() == "catch" )              {                  return Parse_Expr_Try(lex);              } @@ -1320,10 +1320,10 @@ ExprNodeP Parse_ExprMacro(TokenStream& lex, AST::Path path)      }      Token   tok; -    ::std::string name = path.m_class.is_Local() ? path.m_class.as_Local().name : path.nodes()[0].name(); -    ::std::string ident; +    auto name = path.m_class.is_Local() ? path.m_class.as_Local().name : path.nodes()[0].name(); +    RcString ident;      if( GET_TOK(tok, lex) == TOK_IDENT ) { -        ident = mv$(tok.str()); +        ident = tok.istr();      }      else {          PUTBACK(tok, lex); diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 477ff9af..90c8ccbe 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -536,7 +536,7 @@ Token Lexer::getTokenInt()                                  str += ch;                              }                          } -                        return Token(TOK_BYTESTRING, str); +                        return Token(TOK_BYTESTRING, mv$(str));                      }                      // Byte constant                      else if( ch == '\'' ) { @@ -608,7 +608,7 @@ Token Lexer::getTokenInt()                      m_next_tokens.push_back(TOK_SQUARE_CLOSE);                      m_next_tokens.push_back(Token(TOK_STRING, mv$(str)));                      m_next_tokens.push_back(TOK_EQUAL); -                    m_next_tokens.push_back(Token(TOK_IDENT, "doc")); +                    m_next_tokens.push_back(Token(TOK_IDENT, RcString::new_interned("doc")));                      m_next_tokens.push_back(TOK_SQUARE_OPEN);                      if(is_pdoc)                          m_next_tokens.push_back(TOK_EXCLAM); @@ -671,7 +671,7 @@ Token Lexer::getTokenInt()                      m_next_tokens.push_back(TOK_SQUARE_CLOSE);                      m_next_tokens.push_back(Token(TOK_STRING, mv$(str)));                      m_next_tokens.push_back(TOK_EQUAL); -                    m_next_tokens.push_back(Token(TOK_IDENT, "doc")); +                    m_next_tokens.push_back(Token(TOK_IDENT, RcString::new_interned("doc")));                      m_next_tokens.push_back(TOK_SQUARE_OPEN);                      if(is_pdoc)                          m_next_tokens.push_back(TOK_EXCLAM); @@ -704,7 +704,7 @@ Token Lexer::getTokenInt()                              ch = this->getc();                          }                          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<TypeRef>  types;      ::std::vector<AST::LifetimeRef>   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 <parse/interpolated_fragment.hpp>  #include <ast/expr.hpp>  #include <macro_rules/macro_rules.hpp> +#include <path.h>  template<typename T>  Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> f) { @@ -36,7 +37,7 @@ Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> 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<AST::Item> 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<AST::Item> 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<AST::Item> 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<AST::Item> 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<AST::Item> 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<AST::UseItem::Ent>& 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<AST::UseItem::Ent>& 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<AST::UseItem::Ent>& 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<AST::UseItem::Ent>& 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<AST::UseItem::Ent>& 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 "<ABI>" 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<RcString>   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<Type_TraitPath>   traits;          ::std::vector<AST::LifetimeRef> 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 <rc_string.hpp>  #include <cstring> +#include <string>  #include <iostream>  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<char*>(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<char*>(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>    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<RcString>::operator()(const RcString& s) const noexcept +{ +    size_t h = 5381; +    for(auto c : s) { +        h = h * 33 + (unsigned)c; +    } +    return h; +    //return hash<std::string_view>(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<typename Val>      struct Named      { -        ::std::string   name; +        RcString    name;          Val value;      };      template<typename Val> @@ -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<RcString>    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 <hir/path.hpp>  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, | 
