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 /src/parse | |
| parent | dab5cf5462d8fce6d6fcaa1343df8f5f3b763b8a (diff) | |
| download | mrust-b48167dec0c1c05b463991a8db5a8db70a5ae604.tar.gz | |
All - Switch to using interned (de-duplicated) RcString-s instead of std::string for paths/identifiers
Diffstat (limited to 'src/parse')
| -rw-r--r-- | src/parse/common.hpp | 2 | ||||
| -rw-r--r-- | src/parse/expr.cpp | 44 | ||||
| -rw-r--r-- | src/parse/lex.cpp | 14 | ||||
| -rw-r--r-- | src/parse/paths.cpp | 10 | ||||
| -rw-r--r-- | src/parse/pattern.cpp | 12 | ||||
| -rw-r--r-- | src/parse/root.cpp | 139 | ||||
| -rw-r--r-- | src/parse/token.cpp | 13 | ||||
| -rw-r--r-- | src/parse/token.hpp | 4 | ||||
| -rw-r--r-- | src/parse/tokenstream.cpp | 4 | ||||
| -rw-r--r-- | src/parse/types.cpp | 9 |
10 files changed, 133 insertions, 118 deletions
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 ) { |
