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:
parent
11deb083f5
commit
c115c51363
4 changed files with 55 additions and 22 deletions
|
@ -249,22 +249,6 @@ pub enum ParseResult<T> {
|
||||||
pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
|
pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
|
||||||
pub type PositionalParseResult = ParseResult<Vec<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
|
/// Perform a token equality check, ignoring syntax context (that is, an
|
||||||
/// unhygienic comparison)
|
/// unhygienic comparison)
|
||||||
pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
|
pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
|
||||||
use ext::base::{NormalTT, TTMacroExpander};
|
use ext::base::{NormalTT, TTMacroExpander};
|
||||||
use ext::tt::macro_parser::{Success, Error, Failure};
|
use ext::tt::macro_parser::{Success, Error, Failure};
|
||||||
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
|
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::lexer::new_tt_reader;
|
||||||
use parse::parser::Parser;
|
use parse::parser::Parser;
|
||||||
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
|
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_spot = sp;
|
||||||
best_fail_msg = (*msg).clone();
|
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")
|
_ => 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[..]));
|
panic!(cx.span_fatal(best_fail_spot, &best_fail_msg[..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,10 +277,20 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
def.body.clone());
|
def.body.clone());
|
||||||
let argument_map = parse_or_else(cx.parse_sess(),
|
|
||||||
|
let argument_map = match parse(cx.parse_sess(),
|
||||||
cx.cfg(),
|
cx.cfg(),
|
||||||
arg_reader,
|
arg_reader,
|
||||||
argument_gram);
|
&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:
|
// Extract the arguments:
|
||||||
let lhses = match **argument_map.get(&lhs_nm).unwrap() {
|
let lhses = match **argument_map.get(&lhs_nm).unwrap() {
|
||||||
|
|
14
src/test/compile-fail/issue-7970a.rs
Normal file
14
src/test/compile-fail/issue-7970a.rs
Normal 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
|
||||||
|
}
|
14
src/test/compile-fail/issue-7970b.rs
Normal file
14
src/test/compile-fail/issue-7970b.rs
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue