1
Fork 0

macros: fix the expected paths for a non-inline module matched by an item fragment.

This commit is contained in:
Jeffrey Seyfried 2016-12-07 00:28:51 +00:00
parent daf8c1dfce
commit fd98a8d795
8 changed files with 63 additions and 23 deletions

View file

@ -650,7 +650,7 @@ fn string_to_tts(text: String, parse_sess: &ParseSess) -> Vec<TokenTree> {
.new_filemap(String::from("<macro expansion>"), None, text); .new_filemap(String::from("<macro expansion>"), None, text);
let lexer = lexer::StringReader::new(&parse_sess.span_diagnostic, filemap); let lexer = lexer::StringReader::new(&parse_sess.span_diagnostic, filemap);
let mut parser = Parser::new(parse_sess, Box::new(lexer)); let mut parser = Parser::new(parse_sess, Box::new(lexer), None, false);
panictry!(parser.parse_all_token_trees()) panictry!(parser.parse_all_token_trees())
} }

View file

@ -83,7 +83,7 @@ use syntax_pos::{self, BytePos, mk_sp, Span};
use codemap::Spanned; use codemap::Spanned;
use errors::FatalError; use errors::FatalError;
use parse::lexer::*; //resolve bug? use parse::lexer::*; //resolve bug?
use parse::ParseSess; use parse::{Directory, ParseSess};
use parse::parser::{PathStyle, Parser}; use parse::parser::{PathStyle, Parser};
use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{DocComment, MatchNt, SubstNt};
use parse::token::{Token, Nonterminal}; use parse::token::{Token, Nonterminal};
@ -407,8 +407,9 @@ fn inner_parse_loop(cur_eis: &mut SmallVector<Box<MatcherPos>>,
Success(()) Success(())
} }
pub fn parse(sess: &ParseSess, rdr: TtReader, ms: &[TokenTree]) -> NamedParseResult { pub fn parse(sess: &ParseSess, rdr: TtReader, ms: &[TokenTree], directory: Option<Directory>)
let mut parser = Parser::new_with_doc_flag(sess, Box::new(rdr), true); -> NamedParseResult {
let mut parser = Parser::new(sess, Box::new(rdr), directory, true);
let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), parser.span.lo)); let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), parser.span.lo));
let mut next_eis = Vec::new(); // or proceed normally let mut next_eis = Vec::new(); // or proceed normally

View file

@ -17,7 +17,7 @@ use ext::placeholders;
use ext::tt::macro_parser::{Success, Error, Failure}; use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::{parse, parse_failure_msg}; use ext::tt::macro_parser::{parse, parse_failure_msg};
use parse::ParseSess; use parse::{Directory, ParseSess};
use parse::lexer::new_tt_reader; use parse::lexer::new_tt_reader;
use parse::parser::Parser; use parse::parser::Parser;
use parse::token::{self, NtTT, Token}; use parse::token::{self, NtTT, Token};
@ -116,12 +116,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
// rhs has holes ( `$id` and `$(...)` that need filled) // rhs has holes ( `$id` and `$(...)` that need filled)
let trncbr = let trncbr =
new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs); new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs);
let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr)); let directory = Directory {
let module = &cx.current_expansion.module; path: cx.current_expansion.module.directory.clone(),
p.directory.path = module.directory.clone(); ownership: cx.current_expansion.directory_ownership,
p.directory.ownership = cx.current_expansion.directory_ownership; };
p.root_module_name = let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr), Some(directory), false);
module.mod_path.last().map(|id| (*id.name.as_str()).to_owned()); p.root_module_name = cx.current_expansion.module.mod_path.last()
.map(|id| (*id.name.as_str()).to_owned());
p.check_unknown_macro_variable(); p.check_unknown_macro_variable();
// Let the context choose how to interpret the result. // Let the context choose how to interpret the result.
@ -222,7 +223,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
// Parse the macro_rules! invocation (`none` is for no interpolations): // Parse the macro_rules! invocation (`none` is for no interpolations):
let arg_reader = new_tt_reader(&sess.span_diagnostic, None, def.body.clone()); let arg_reader = new_tt_reader(&sess.span_diagnostic, None, def.body.clone());
let argument_map = match parse(sess, arg_reader, &argument_gram) { let argument_map = match parse(sess, arg_reader, &argument_gram, None) {
Success(m) => m, Success(m) => m,
Failure(sp, tok) => { Failure(sp, tok) => {
let s = parse_failure_msg(tok); let s = parse_failure_msg(tok);

View file

@ -222,14 +222,14 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
// it appears to me that the cfg doesn't matter here... indeed, // it appears to me that the cfg doesn't matter here... indeed,
// parsing tt's probably shouldn't require a parser at all. // parsing tt's probably shouldn't require a parser at all.
let srdr = lexer::StringReader::new(&sess.span_diagnostic, filemap); let srdr = lexer::StringReader::new(&sess.span_diagnostic, filemap);
let mut p1 = Parser::new(sess, Box::new(srdr)); let mut p1 = Parser::new(sess, Box::new(srdr), None, false);
panictry!(p1.parse_all_token_trees()) panictry!(p1.parse_all_token_trees())
} }
/// Given tts and the ParseSess, produce a parser /// Given tts and the ParseSess, produce a parser
pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>) -> Parser<'a> { pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>) -> Parser<'a> {
let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts); let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
let mut p = Parser::new(sess, Box::new(trdr)); let mut p = Parser::new(sess, Box::new(trdr), None, false);
p.check_unknown_macro_variable(); p.check_unknown_macro_variable();
p p
} }

View file

@ -267,12 +267,11 @@ impl From<P<Expr>> for LhsExpr {
} }
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
pub fn new(sess: &'a ParseSess, rdr: Box<Reader+'a>) -> Self { pub fn new(sess: &'a ParseSess,
Parser::new_with_doc_flag(sess, rdr, false) rdr: Box<Reader+'a>,
} directory: Option<Directory>,
desugar_doc_comments: bool)
pub fn new_with_doc_flag(sess: &'a ParseSess, rdr: Box<Reader+'a>, desugar_doc_comments: bool) -> Self {
-> Self {
let mut parser = Parser { let mut parser = Parser {
reader: rdr, reader: rdr,
sess: sess, sess: sess,
@ -298,7 +297,9 @@ impl<'a> Parser<'a> {
let tok = parser.next_tok(); let tok = parser.next_tok();
parser.token = tok.tok; parser.token = tok.tok;
parser.span = tok.sp; parser.span = tok.sp;
if parser.span != syntax_pos::DUMMY_SP { if let Some(directory) = directory {
parser.directory = directory;
} else if parser.span != syntax_pos::DUMMY_SP {
parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span)); parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span));
parser.directory.path.pop(); parser.directory.path.pop();
} }

View file

@ -31,7 +31,7 @@ use ext::base;
use ext::tt::macro_parser; use ext::tt::macro_parser;
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use parse::lexer; use parse::lexer;
use parse; use parse::{self, Directory};
use parse::token::{self, Token, Lit, Nonterminal}; use parse::token::{self, Token, Lit, Nonterminal};
use print::pprust; use print::pprust;
use symbol::Symbol; use symbol::Symbol;
@ -218,7 +218,11 @@ impl TokenTree {
let diag = &cx.parse_sess().span_diagnostic; let diag = &cx.parse_sess().span_diagnostic;
// `None` is because we're not interpolating // `None` is because we're not interpolating
let arg_rdr = lexer::new_tt_reader(diag, None, tts.iter().cloned().collect()); let arg_rdr = lexer::new_tt_reader(diag, None, tts.iter().cloned().collect());
macro_parser::parse(cx.parse_sess(), arg_rdr, mtch) let directory = Directory {
path: cx.current_expansion.module.directory.clone(),
ownership: cx.current_expansion.directory_ownership,
};
macro_parser::parse(cx.parse_sess(), arg_rdr, mtch, Some(directory))
} }
/// Check if this TokenTree is equal to the other, regardless of span information. /// Check if this TokenTree is equal to the other, regardless of span information.

View file

@ -0,0 +1,12 @@
// Copyright 2016 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.
#[macro_export]
macro_rules! m { ([$i:item]) => {} }

View file

@ -0,0 +1,21 @@
// Copyright 2016 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.
// aux-build:issue_38190.rs
// ignore-pretty issue #37195
#[macro_use]
extern crate issue_38190;
mod auxiliary {
m!([mod issue_38190;]);
}
fn main() {}