From d631637ae467843ffd969c6003b6c187f498ef5c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 8 Mar 2016 11:41:47 +0800 Subject: Spans on MacroInvocation, re-enable span in ERROR reporting --- src/ast/macro.hpp | 7 ++++++- src/ast/path.hpp | 4 ++++ src/expand/mod.cpp | 2 +- src/include/span.hpp | 2 +- src/parse/common.hpp | 2 +- src/parse/pattern.cpp | 3 ++- src/parse/root.cpp | 10 ++++++---- src/parse/types.cpp | 3 ++- src/types.hpp | 5 ++++- 9 files changed, 27 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp index 4696c732..4804f52b 100644 --- a/src/ast/macro.hpp +++ b/src/ast/macro.hpp @@ -3,6 +3,7 @@ #define _AST_MACRO_HPP_ #include "../parse/tokentree.hpp" +#include #include "attrs.hpp" namespace AST { @@ -10,6 +11,8 @@ namespace AST { class MacroInvocation: public Serialisable { + Span m_span; + ::AST::MetaItems m_attrs; ::std::string m_macro_name; ::std::string m_ident; @@ -19,7 +22,8 @@ public: { } - MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + MacroInvocation(Span span, MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + m_span( mv$(span) ), m_attrs( mv$(attrs) ), m_macro_name( mv$(macro) ), m_ident( mv$(ident) ), @@ -39,6 +43,7 @@ public: m_input = TokenTree(); } + const Span& span() const { return m_span; } const ::std::string& name() const { return m_macro_name; } const ::std::string& input_ident() const { return m_ident; } diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 1260ece3..4fc08bb1 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -130,6 +130,7 @@ public: private: /// The crate defining the root of this path (used for path resolution) ::std::string m_crate; + Span m_span; public: Class m_class; @@ -197,6 +198,9 @@ public: } + const Span& span() const { + return m_span; + } Class::Tag class_tag() const { return m_class.tag(); } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 3f35d4dc..c6d5eec2 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -80,7 +80,7 @@ AST::Expr Expand_Macro(bool is_early, LList modstack, ::AST: if( ! is_early ) { // TODO: Error - Unknown macro name // TODO: Get a span via MacroInvocation and emit a good error - throw ::std::runtime_error( FMT("Unknown macro '" << mi.name() << "'") ); + ERROR(mi.span(), E0000, "Unknown macro '" << mi.name() << "'"); } // Leave valid and return an empty expression diff --git a/src/include/span.hpp b/src/include/span.hpp index 7603b080..49169e5b 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -59,7 +59,7 @@ struct Spanned T m_item; }; -#define ERROR(span, code, msg) do { (Span()/*span*/).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) +#define ERROR(span, code, msg) do { (span).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) #define BUG(span, msg) do { (span).bug([&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0) #define TODO(span, msg) do { (span).bug([&](::std::ostream& os) { os << "TODO: " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0) diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 4b6ceb54..ed052a33 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -39,7 +39,7 @@ extern ::std::vector Parse_Path_GenericList(TokenStream& lex); extern AST::MetaItem Parse_MetaItem(TokenStream& lex); -extern ::AST::MacroInvocation Parse_MacroInvocation(::AST::MetaItems meta_items, ::std::string name, TokenStream& lex); +extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::AST::MetaItems meta_items, ::std::string name, TokenStream& lex); extern TypeRef Parse_Type(TokenStream& lex); extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable); diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index e8ccd962..dcbc8c5d 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -37,13 +37,14 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable); AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) { TRACE_FUNCTION; + auto ps = lex.start_span(); Token tok; tok = lex.getToken(); if( tok.type() == TOK_MACRO ) { - return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(AST::MetaItems(), tok.str(), lex))); + return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(ps, AST::MetaItems(), tok.str(), lex))); } bool expect_bind = false; diff --git a/src/parse/root.cpp b/src/parse/root.cpp index faa2b9bb..0860a008 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -917,9 +917,10 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i // A sequence of method implementations while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) { + auto ps = lex.start_span(); if( tok.type() == TOK_MACRO ) { - impl.add_macro_invocation( Parse_MacroInvocation( AST::MetaItems(), mv$(tok.str()), lex ) ); + impl.add_macro_invocation( Parse_MacroInvocation( ps, AST::MetaItems(), mv$(tok.str()), lex ) ); // - Silently consume ';' after the macro if( GET_TOK(tok, lex) != TOK_SEMICOLON ) lex.putback(tok); @@ -1206,7 +1207,7 @@ void Parse_Use(TokenStream& lex, ::std::function } -::AST::MacroInvocation Parse_MacroInvocation(::AST::MetaItems meta_items, ::std::string name, TokenStream& lex) +::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan span_start, ::AST::MetaItems meta_items, ::std::string name, TokenStream& lex) { Token tok; ::std::string ident; @@ -1217,7 +1218,7 @@ void Parse_Use(TokenStream& lex, ::std::function lex.putback(tok); } TokenTree tt = Parse_TT(lex, true); - return ::AST::MacroInvocation( mv$(meta_items), mv$(name), mv$(ident), mv$(tt)); + return ::AST::MacroInvocation( lex.end_span(span_start), mv$(meta_items), mv$(name), mv$(ident), mv$(tt)); } void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items) @@ -1598,10 +1599,11 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList DEBUG("meta_items = " << meta_items); // root-level macros + auto ps = lex.start_span(); if( GET_TOK(tok, lex) == TOK_MACRO ) { ::std::string name = mv$(tok.str()); - mod.add_macro_invocation( Parse_MacroInvocation( mv$(meta_items), mv$(name), lex ) ); + mod.add_macro_invocation( Parse_MacroInvocation( ps, mv$(meta_items), mv$(name), lex ) ); // - Silently consume ';' after the macro // TODO: Check the tt next token before parsing to tell if this is needed if( GET_TOK(tok, lex) != TOK_SEMICOLON ) diff --git a/src/parse/types.cpp b/src/parse/types.cpp index e6aadbbe..16e95f6d 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -28,13 +28,14 @@ TypeRef Parse_Type(TokenStream& lex) TypeRef Parse_Type_Int(TokenStream& lex) { //TRACE_FUNCTION; + auto ps = lex.start_span(); Token tok; switch( GET_TOK(tok, lex) ) { case TOK_MACRO: - return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(AST::MetaItems(), mv$(tok.str()), lex)); + return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(ps, AST::MetaItems(), mv$(tok.str()), lex)); // '!' - Only ever used as part of function prototypes, but is kinda a type... not allowed here though case TOK_EXCLAM: throw ParseError::Generic(lex, "! is not a real type"); diff --git a/src/types.hpp b/src/types.hpp index 24c0d9ea..5b19d036 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -103,6 +103,7 @@ TAGGED_UNION(TypeData, None, class TypeRef: public Serialisable { + Span m_span; public: TypeData m_data; @@ -215,7 +216,9 @@ public: m_data(TypeData::make_TraitObject({ mv$(hrls), ::std::move(traits) })) {} - + + const Span& span() const { return m_span; } + /// Dereference the type (return the result of *type_instance) bool deref(bool is_implicit); /// Merge with another type (combines known aspects, conflitcs cause an exception) -- cgit v1.2.3