diff options
author | John Hodge <tpg@mutabah.net> | 2018-07-29 12:47:44 +0100 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-07-29 12:47:44 +0100 |
commit | c971a6fa8375598ecf9c99ee6b086e8cf957f568 (patch) | |
tree | f7f431cbac52e6b25d311bedd503b6584c51bd37 /src/parse/root.cpp | |
parent | 5d4bf9e96d795623f1b32b2f1f2e57c4f74419fe (diff) | |
download | mrust-c971a6fa8375598ecf9c99ee6b086e8cf957f568.tar.gz |
All - Initial work on supporting 1.29 as a target version
Diffstat (limited to 'src/parse/root.cpp')
-rw-r--r-- | src/parse/root.cpp | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 68ad570b..ef1fb439 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -18,6 +18,7 @@ #include <expand/cfg.hpp> // check_cfg - for `mod nonexistant;` #include <fstream> // Used by directory path #include "lex.hpp" // New file lexer +#include <parse/interpolated_fragment.hpp> #include <ast/expr.hpp> template<typename T> @@ -649,9 +650,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::AttributeList& meta_items // TODO: Just add these as `where Self: <foo>` (would that break typecheck?) do { if( GET_TOK(tok, lex) == TOK_LIFETIME ) { - // TODO: Need a better way of indiciating 'static than just an invalid path - ASSERT_BUG(lex.point_span(), tok.str() == "static", "TODO: Support lifetimes other than 'static in trait bounds"); - supertraits.push_back( make_spanned( Span(tok.get_pos()), Type_TraitPath{ {}, AST::Path() } ) ); + params.add_bound(::AST::GenericBound::make_TypeLifetime({ TypeRef(lex.point_span(), "Self"), ::AST::LifetimeRef(lex.get_ident(tok)) })); } else if( tok.type() == TOK_BRACE_OPEN ) { break; @@ -988,14 +987,26 @@ AST::Attribute Parse_MetaItem(TokenStream& lex) { TRACE_FUNCTION; Token tok; - GET_TOK(tok, lex); - if( tok.type() == TOK_INTERPOLATED_META ) { + if( lex.lookahead(0) == TOK_INTERPOLATED_META ) { + GET_TOK(tok, lex); return mv$(tok.frag_meta()); } auto ps = lex.start_span(); - CHECK_TOK(tok, TOK_IDENT); + GET_TOK(tok, lex); + + switch(tok.type()) + { + case TOK_IDENT: + break; + case TOK_INTEGER: + if( TARGETVER_1_29 ) + return AST::Attribute(lex.end_span(ps), "", tok.to_str()); + default: + throw ParseError::Unexpected(lex, tok, {TOK_IDENT, TOK_INTEGER}); + } + ::std::string name = mv$(tok.str()); switch(GET_TOK(tok, lex)) { @@ -1006,6 +1017,10 @@ AST::Attribute Parse_MetaItem(TokenStream& lex) return AST::Attribute(lex.end_span(ps), name, tok.str()); case TOK_INTERPOLATED_EXPR: { auto n = tok.take_frag_node(); + void Expand_BareExpr(const AST::Crate& , const AST::Module&, ::std::unique_ptr<AST::ExprNode>& n); + assert( lex.parse_state().crate ); + assert( lex.parse_state().module ); + Expand_BareExpr(*lex.parse_state().crate, *lex.parse_state().module, n); if( auto* v = dynamic_cast<::AST::ExprNode_String*>(&*n) ) { return AST::Attribute(lex.end_span(ps), name, mv$(v->m_value)); @@ -1013,9 +1028,15 @@ AST::Attribute Parse_MetaItem(TokenStream& lex) else { // - Force an error. - CHECK_TOK(tok, TOK_STRING); + throw ParseError::Unexpected(lex, Token(InterpolatedFragment(InterpolatedFragment::EXPR, n.release())), TOK_STRING); } break; } + case TOK_INTEGER: + if( TARGETVER_1_29 ) + return AST::Attribute(lex.end_span(ps), name, tok.to_str()); + case TOK_IDENT: + if( TARGETVER_1_29 ) + return AST::Attribute(lex.end_span(ps), name, tok.to_str()); default: // - Force an error. CHECK_TOK(tok, TOK_STRING); @@ -1311,8 +1332,19 @@ void Parse_Use_Set(TokenStream& lex, const ProtoSpan& ps, const AST::Path& base_ break ; } else { - CHECK_TOK(tok, TOK_IDENT); - path = base_path + AST::PathNode(tok.str(), {}); + path = ::AST::Path(base_path); + + while(1) + { + CHECK_TOK(tok, TOK_IDENT); + path += AST::PathNode(tok.str(), {}); + if( !TARGETVER_1_29 ) + break; + if( lex.lookahead(0) != TOK_DOUBLE_COLON ) + break; + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); + GET_TOK(tok, lex); + } name = mv$(tok.str()); } @@ -1706,6 +1738,19 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) } return ::AST::Named< ::AST::Item> { "", mv$(impl), false }; } + // `unsafe auto trait` + case TOK_IDENT: + if( TARGETVER_1_29 && tok.str() == "auto" ) { + GET_CHECK_TOK(tok, lex, TOK_RWORD_TRAIT); + GET_CHECK_TOK(tok, lex, TOK_IDENT); + item_name = mv$(tok.str()); + auto tr = Parse_TraitDef(lex, meta_items); + tr.set_is_unsafe(); + tr.set_is_marker(); + item_data = ::AST::Item( ::std::move(tr) ); + break; + } + //goto default; default: throw ParseError::Unexpected(lex, tok, {TOK_RWORD_FN, TOK_RWORD_TRAIT, TOK_RWORD_IMPL}); } @@ -1742,6 +1787,15 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) item_name = mv$(tok.str()); item_data = ::AST::Item( Parse_Union(lex, meta_items) ); } + // `auto trait` + else if( TARGETVER_1_29 && tok.str() == "auto" ) { + GET_CHECK_TOK(tok, lex, TOK_RWORD_TRAIT); + GET_CHECK_TOK(tok, lex, TOK_IDENT); + item_name = mv$(tok.str()); + auto tr = Parse_TraitDef(lex, meta_items); + tr.set_is_marker(); + item_data = ::AST::Item( ::std::move(tr) ); + } else { throw ParseError::Unexpected(lex, tok); } @@ -1959,6 +2013,7 @@ AST::Crate Parse_Crate(::std::string mainfile) crate.root_module().m_file_info.path = mainpath; crate.root_module().m_file_info.controls_dir = true; + lex.parse_state().crate = &crate; Parse_ModRoot(lex, crate.root_module(), crate.m_attrs); return crate; |