From fd98a8d795b17b76ea6d1edcae55d4450efd466f Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 7 Dec 2016 00:28:51 +0000 Subject: [PATCH] macros: fix the expected paths for a non-inline module matched by an `item` fragment. --- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 7 ++++--- src/libsyntax/ext/tt/macro_rules.rs | 17 +++++++++-------- src/libsyntax/parse/mod.rs | 4 ++-- src/libsyntax/parse/parser.rs | 15 ++++++++------- src/libsyntax/tokenstream.rs | 8 ++++++-- src/test/run-pass/auxiliary/issue_38190.rs | 12 ++++++++++++ src/test/run-pass/issue-38190.rs | 21 +++++++++++++++++++++ 8 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 src/test/run-pass/auxiliary/issue_38190.rs create mode 100644 src/test/run-pass/issue-38190.rs diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4138acafac69a..89865d89baeb1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -650,7 +650,7 @@ fn string_to_tts(text: String, parse_sess: &ParseSess) -> Vec { .new_filemap(String::from(""), None, text); 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()) } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 39ffab4dc17a7..2de31166070e7 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -83,7 +83,7 @@ use syntax_pos::{self, BytePos, mk_sp, Span}; use codemap::Spanned; use errors::FatalError; use parse::lexer::*; //resolve bug? -use parse::ParseSess; +use parse::{Directory, ParseSess}; use parse::parser::{PathStyle, Parser}; use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{Token, Nonterminal}; @@ -407,8 +407,9 @@ fn inner_parse_loop(cur_eis: &mut SmallVector>, Success(()) } -pub fn parse(sess: &ParseSess, rdr: TtReader, ms: &[TokenTree]) -> NamedParseResult { - let mut parser = Parser::new_with_doc_flag(sess, Box::new(rdr), true); +pub fn parse(sess: &ParseSess, rdr: TtReader, ms: &[TokenTree], directory: Option) + -> 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 next_eis = Vec::new(); // or proceed normally diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 4164b4a93ec91..ca18e580ecdfb 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -17,7 +17,7 @@ use ext::placeholders; use ext::tt::macro_parser::{Success, Error, Failure}; use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::{parse, parse_failure_msg}; -use parse::ParseSess; +use parse::{Directory, ParseSess}; use parse::lexer::new_tt_reader; use parse::parser::Parser; 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) let trncbr = new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs); - let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr)); - let module = &cx.current_expansion.module; - p.directory.path = module.directory.clone(); - p.directory.ownership = cx.current_expansion.directory_ownership; - p.root_module_name = - module.mod_path.last().map(|id| (*id.name.as_str()).to_owned()); + let directory = Directory { + path: cx.current_expansion.module.directory.clone(), + ownership: cx.current_expansion.directory_ownership, + }; + let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr), Some(directory), false); + p.root_module_name = cx.current_expansion.module.mod_path.last() + .map(|id| (*id.name.as_str()).to_owned()); p.check_unknown_macro_variable(); // 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): 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, Failure(sp, tok) => { let s = parse_failure_msg(tok); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index bfaf00a3d3f08..9263e5e3e4dae 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -222,14 +222,14 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc) // it appears to me that the cfg doesn't matter here... indeed, // parsing tt's probably shouldn't require a parser at all. 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()) } /// Given tts and the ParseSess, produce a parser pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec) -> Parser<'a> { 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 } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bdd1606805fef..4367f93348577 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -267,12 +267,11 @@ impl From> for LhsExpr { } impl<'a> Parser<'a> { - pub fn new(sess: &'a ParseSess, rdr: Box) -> Self { - Parser::new_with_doc_flag(sess, rdr, false) - } - - pub fn new_with_doc_flag(sess: &'a ParseSess, rdr: Box, desugar_doc_comments: bool) - -> Self { + pub fn new(sess: &'a ParseSess, + rdr: Box, + directory: Option, + desugar_doc_comments: bool) + -> Self { let mut parser = Parser { reader: rdr, sess: sess, @@ -298,7 +297,9 @@ impl<'a> Parser<'a> { let tok = parser.next_tok(); parser.token = tok.tok; 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.pop(); } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 0d5dcaf339feb..e352e7853c71c 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -31,7 +31,7 @@ use ext::base; use ext::tt::macro_parser; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::lexer; -use parse; +use parse::{self, Directory}; use parse::token::{self, Token, Lit, Nonterminal}; use print::pprust; use symbol::Symbol; @@ -218,7 +218,11 @@ impl TokenTree { let diag = &cx.parse_sess().span_diagnostic; // `None` is because we're not interpolating 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. diff --git a/src/test/run-pass/auxiliary/issue_38190.rs b/src/test/run-pass/auxiliary/issue_38190.rs new file mode 100644 index 0000000000000..7fc4390d6dcfb --- /dev/null +++ b/src/test/run-pass/auxiliary/issue_38190.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_export] +macro_rules! m { ([$i:item]) => {} } diff --git a/src/test/run-pass/issue-38190.rs b/src/test/run-pass/issue-38190.rs new file mode 100644 index 0000000000000..ed9bf9e809520 --- /dev/null +++ b/src/test/run-pass/issue-38190.rs @@ -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 or the MIT license +// , 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() {}