improve span of erroneous empty macro invocation

The ideas is to use the span of the complete macro invocation if the span of a
macro error is `DUMMY_SP`.

fixes #7970
This commit is contained in:
Tim Neumann 2015-08-07 16:36:56 +02:00
parent 11deb083f5
commit c115c51363
4 changed files with 55 additions and 22 deletions

View file

@ -249,22 +249,6 @@ pub enum ParseResult<T> {
pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>;
pub fn parse_or_else(sess: &ParseSess,
cfg: ast::CrateConfig,
rdr: TtReader,
ms: Vec<TokenTree> )
-> HashMap<Ident, Rc<NamedMatch>> {
match parse(sess, cfg, rdr, &ms[..]) {
Success(m) => m,
Failure(sp, str) => {
panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
}
Error(sp, str) => {
panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
}
}
}
/// Perform a token equality check, ignoring syntax context (that is, an
/// unhygienic comparison)
pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {

View file

@ -14,7 +14,7 @@ use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
use ext::base::{NormalTT, TTMacroExpander};
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::{parse, parse_or_else};
use ext::tt::macro_parser::parse;
use parse::lexer::new_tt_reader;
use parse::parser::Parser;
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
@ -211,12 +211,23 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
best_fail_spot = sp;
best_fail_msg = (*msg).clone();
},
Error(sp, ref msg) => panic!(cx.span_fatal(sp, &msg[..]))
Error(mut spp, ref msg) => {
if spp == DUMMY_SP {
spp = sp;
}
panic!(cx.span_fatal(spp, &msg[..]))
}
}
}
_ => cx.bug("non-matcher found in parsed lhses")
}
}
if best_fail_spot == DUMMY_SP {
best_fail_spot = sp;
}
panic!(cx.span_fatal(best_fail_spot, &best_fail_msg[..]));
}
@ -266,10 +277,20 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
None,
None,
def.body.clone());
let argument_map = parse_or_else(cx.parse_sess(),
cx.cfg(),
arg_reader,
argument_gram);
let argument_map = match parse(cx.parse_sess(),
cx.cfg(),
arg_reader,
&argument_gram) {
Success(m) => m,
Failure(mut sp, str) | Error(mut sp, str) => {
if sp == DUMMY_SP {
sp = def.span;
}
panic!(cx.parse_sess().span_diagnostic.span_fatal(sp, &str[..]));
}
};
// Extract the arguments:
let lhses = match **argument_map.get(&lhs_nm).unwrap() {

View file

@ -0,0 +1,14 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
println!();
//~^ ERROR unexpected end of macro invocation
}

View file

@ -0,0 +1,14 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {}
macro_rules! test {}
//~^ ERROR unexpected end of macro invocation