From 39ffea31df73b20d5549330d446713e56e60e801 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Apr 2017 19:01:19 +0200 Subject: Implement a file-path remapping feature in support of debuginfo and reproducible builds. --- src/libsyntax/codemap.rs | 101 +++++++++++++++++++++++----------- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/source_util.rs | 4 +- src/libsyntax/json.rs | 5 +- src/libsyntax/parse/lexer/comments.rs | 4 +- src/libsyntax/parse/lexer/mod.rs | 32 +++++------ src/libsyntax/parse/mod.rs | 16 +++--- src/libsyntax/test_snippet.rs | 6 +- src/libsyntax/util/parser_testing.rs | 15 ++--- 9 files changed, 112 insertions(+), 73 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index da2d0a33d1a..8a88ec3a672 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -104,32 +104,42 @@ impl FileLoader for RealFileLoader { pub struct CodeMap { pub files: RefCell>>, - file_loader: Box + file_loader: Box, + // This is used to apply the file path remapping as specified via + // -Zremap-path-prefix to all FileMaps allocated within this CodeMap. + path_mapping: FilePathMapping, } impl CodeMap { - pub fn new() -> CodeMap { + pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), - file_loader: Box::new(RealFileLoader) + file_loader: Box::new(RealFileLoader), + path_mapping: path_mapping, } } - pub fn with_file_loader(file_loader: Box) -> CodeMap { + pub fn with_file_loader(file_loader: Box, + path_mapping: FilePathMapping) + -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), - file_loader: file_loader + file_loader: file_loader, + path_mapping: path_mapping, } } + pub fn path_mapping(&self) -> &FilePathMapping { + &self.path_mapping + } + pub fn file_exists(&self, path: &Path) -> bool { self.file_loader.file_exists(path) } pub fn load_file(&self, path: &Path) -> io::Result> { let src = self.file_loader.read_file(path)?; - let abs_path = self.file_loader.abs_path(path).map(|p| p.to_str().unwrap().to_string()); - Ok(self.new_filemap(path.to_str().unwrap().to_string(), abs_path, src)) + Ok(self.new_filemap(path.to_str().unwrap().to_string(), src)) } fn next_start_pos(&self) -> usize { @@ -144,8 +154,7 @@ impl CodeMap { /// Creates a new filemap without setting its line information. If you don't /// intend to set the line information yourself, you should use new_filemap_and_lines. - pub fn new_filemap(&self, filename: FileName, abs_path: Option, - mut src: String) -> Rc { + pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); @@ -156,9 +165,11 @@ impl CodeMap { let end_pos = start_pos + src.len(); + let (filename, was_remapped) = self.path_mapping.map_prefix(filename); + let filemap = Rc::new(FileMap { name: filename, - abs_path: abs_path, + name_was_remapped: was_remapped, src: Some(Rc::new(src)), start_pos: Pos::from_usize(start_pos), end_pos: Pos::from_usize(end_pos), @@ -172,11 +183,8 @@ impl CodeMap { } /// Creates a new filemap and sets its line information. - pub fn new_filemap_and_lines(&self, filename: &str, abs_path: Option<&str>, - src: &str) -> Rc { - let fm = self.new_filemap(filename.to_string(), - abs_path.map(|s| s.to_owned()), - src.to_owned()); + pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc { + let fm = self.new_filemap(filename.to_string(), src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; for line in src.lines() { // register the start of this line @@ -195,7 +203,7 @@ impl CodeMap { /// information for things inlined from other crates. pub fn new_imported_filemap(&self, filename: FileName, - abs_path: Option, + name_was_remapped: bool, source_len: usize, mut file_local_lines: Vec, mut file_local_multibyte_chars: Vec) @@ -216,7 +224,7 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, - abs_path: abs_path, + name_was_remapped: name_was_remapped, src: None, start_pos: start_pos, end_pos: end_pos, @@ -550,6 +558,42 @@ impl CodeMapper for CodeMap { } } +#[derive(Clone)] +pub struct FilePathMapping { + mapping: Vec<(String, String)>, +} + +impl FilePathMapping { + pub fn empty() -> FilePathMapping { + FilePathMapping { + mapping: vec![] + } + } + + pub fn new(mapping: Vec<(String, String)>) -> FilePathMapping { + FilePathMapping { + mapping: mapping + } + } + + /// Applies any path prefix substitution as defined by the mapping. + /// The return value is the remapped path and a boolean indicating whether + /// the path was affected by the mapping. + pub fn map_prefix(&self, path: String) -> (String, bool) { + // NOTE: We are iterating over the mapping entries from last to first + // because entries specified later on the command line should + // take precedence. + for &(ref from, ref to) in self.mapping.iter().rev() { + if path.starts_with(from) { + let mapped = path.replacen(from, to, 1); + return (mapped, true); + } + } + + (path, false) + } +} + // _____________________________________________________________________________ // Tests // @@ -561,9 +605,8 @@ mod tests { #[test] fn t1 () { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let fm = cm.new_filemap("blork.rs".to_string(), - None, "first line.\nsecond line".to_string()); fm.next_line(BytePos(0)); // Test we can get lines with partial line info. @@ -578,9 +621,8 @@ mod tests { #[test] #[should_panic] fn t2 () { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let fm = cm.new_filemap("blork.rs".to_string(), - None, "first line.\nsecond line".to_string()); // TESTING *REALLY* BROKEN BEHAVIOR: fm.next_line(BytePos(0)); @@ -589,15 +631,12 @@ mod tests { } fn init_code_map() -> CodeMap { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let fm1 = cm.new_filemap("blork.rs".to_string(), - None, "first line.\nsecond line".to_string()); let fm2 = cm.new_filemap("empty.rs".to_string(), - None, "".to_string()); let fm3 = cm.new_filemap("blork2.rs".to_string(), - None, "first line.\nsecond line".to_string()); fm1.next_line(BytePos(0)); @@ -656,14 +695,12 @@ mod tests { } fn init_code_map_mbc() -> CodeMap { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); // € is a three byte utf8 char. let fm1 = cm.new_filemap("blork.rs".to_string(), - None, "fir€st €€€€ line.\nsecond line".to_string()); let fm2 = cm.new_filemap("blork2.rs".to_string(), - None, "first line€€.\n€ second line".to_string()); fm1.next_line(BytePos(0)); @@ -728,10 +765,10 @@ mod tests { /// lines in the middle of a file. #[test] fn span_to_snippet_and_lines_spanning_multiple_lines() { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); + cm.new_filemap_and_lines("blork.rs", inputtext); let span = span_from_selection(inputtext, selection); // check that we are extracting the text we thought we were extracting @@ -770,11 +807,11 @@ mod tests { /// Test failing to merge two spans on different lines #[test] fn span_merging_fail() { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let inputtext = "bbbb BB\ncc CCC\n"; let selection1 = " ~~\n \n"; let selection2 = " \n ~~~\n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); + cm.new_filemap_and_lines("blork.rs", inputtext); let span1 = span_from_selection(inputtext, selection1); let span2 = span_from_selection(inputtext, selection2); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 842398ea02b..2db295d0136 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -783,7 +783,7 @@ fn stream_for_item(item: &Annotatable, parse_sess: &ParseSess) -> TokenStream { fn string_to_stream(text: String, parse_sess: &ParseSess) -> TokenStream { let filename = String::from(""); - filemap_to_stream(parse_sess, parse_sess.codemap().new_filemap(filename, None, text)) + filemap_to_stream(parse_sess, parse_sess.codemap().new_filemap(filename, text)) } impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 0103d6ea959..22a5776315a 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -142,7 +142,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT // Add this input file to the code map to make it available as // dependency information let filename = format!("{}", file.display()); - cx.codemap().new_filemap_and_lines(&filename, None, &src); + cx.codemap().new_filemap_and_lines(&filename, &src); base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&src))) } @@ -173,7 +173,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Toke // Add this input file to the code map to make it available as // dependency information, but don't enter it's contents let filename = format!("{}", file.display()); - cx.codemap().new_filemap_and_lines(&filename, None, ""); + cx.codemap().new_filemap_and_lines(&filename, ""); base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Rc::new(bytes)))) } diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index dec1b7d1d87..47b60f0e080 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -19,7 +19,7 @@ // FIXME spec the JSON output properly. -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan}; use errors::registry::Registry; use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper}; @@ -48,7 +48,8 @@ impl JsonEmitter { } pub fn basic() -> JsonEmitter { - JsonEmitter::stderr(None, Rc::new(CodeMap::new())) + let file_path_mapping = FilePathMapping::empty(); + JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping))) } pub fn new(dst: Box, diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index c97b8ddf919..7ac322b144c 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -348,8 +348,8 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: String, srdr: &mut R let mut src = Vec::new(); srdr.read_to_end(&mut src).unwrap(); let src = String::from_utf8(src).unwrap(); - let cm = CodeMap::new(); - let filemap = cm.new_filemap(path, None, src); + let cm = CodeMap::new(sess.codemap().path_mapping().clone()); + let filemap = cm.new_filemap(path, src); let mut rdr = lexer::StringReader::new_raw(sess, filemap); let mut comments: Vec = Vec::new(); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 920b2c401e2..c2e5763237d 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -10,7 +10,7 @@ use ast::{self, Ident}; use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION}; -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use errors::{FatalError, DiagnosticBuilder}; use parse::{token, ParseSess}; use str::char_at; @@ -563,7 +563,7 @@ impl<'a> StringReader<'a> { // I guess this is the only way to figure out if // we're at the beginning of the file... - let cmap = CodeMap::new(); + let cmap = CodeMap::new(FilePathMapping::empty()); cmap.files.borrow_mut().push(self.filemap.clone()); let loc = cmap.lookup_char_pos_adj(self.pos); debug!("Skipping a shebang"); @@ -1718,13 +1718,13 @@ mod tests { sess: &'a ParseSess, teststr: String) -> StringReader<'a> { - let fm = cm.new_filemap("zebra.rs".to_string(), None, teststr); + let fm = cm.new_filemap("zebra.rs".to_string(), teststr); StringReader::new(sess, fm) } #[test] fn t1() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut string_reader = setup(&cm, &sh, @@ -1776,7 +1776,7 @@ mod tests { #[test] fn doublecolonparsing() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a b".to_string()), vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); @@ -1784,7 +1784,7 @@ mod tests { #[test] fn dcparsing_2() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a::b".to_string()), vec![mk_ident("a"), token::ModSep, mk_ident("b")]); @@ -1792,7 +1792,7 @@ mod tests { #[test] fn dcparsing_3() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a ::b".to_string()), vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); @@ -1800,7 +1800,7 @@ mod tests { #[test] fn dcparsing_4() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a:: b".to_string()), vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); @@ -1808,7 +1808,7 @@ mod tests { #[test] fn character_a() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern("a")), None)); @@ -1816,7 +1816,7 @@ mod tests { #[test] fn character_space() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern(" ")), None)); @@ -1824,7 +1824,7 @@ mod tests { #[test] fn character_escaped() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern("\\n")), None)); @@ -1832,7 +1832,7 @@ mod tests { #[test] fn lifetime_name() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok, token::Lifetime(Ident::from_str("'abc"))); @@ -1840,7 +1840,7 @@ mod tests { #[test] fn raw_string() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()) .next_token() @@ -1850,7 +1850,7 @@ mod tests { #[test] fn literal_suffixes() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); macro_rules! test { ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ @@ -1894,7 +1894,7 @@ mod tests { #[test] fn nested_block_comments() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut lexer = setup(&cm, &sh, "/* /* */ */'a'".to_string()); match lexer.next_token().tok { @@ -1907,7 +1907,7 @@ mod tests { #[test] fn crlf_comments() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut lexer = setup(&cm, &sh, "// test\r\n/// test\r\n".to_string()); let comment = lexer.next_token(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index c63a6524f74..9d8f3b3d039 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -11,7 +11,7 @@ //! The main parser interface use ast::{self, CrateConfig}; -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, Span, FileMap, NO_EXPANSION}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; use feature_gate::UnstableFeatures; @@ -53,8 +53,8 @@ pub struct ParseSess { } impl ParseSess { - pub fn new() -> Self { - let cm = Rc::new(CodeMap::new()); + pub fn new(file_path_mapping: FilePathMapping) -> Self { + let cm = Rc::new(CodeMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, @@ -143,13 +143,13 @@ pub fn parse_stmt_from_source_str<'a>(name: String, source: String, sess: &'a Pa pub fn parse_stream_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) -> TokenStream { - filemap_to_stream(sess, sess.codemap().new_filemap(name, None, source)) + filemap_to_stream(sess, sess.codemap().new_filemap(name, source)) } // Create a new parser from a source string pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String) -> Parser<'a> { - filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source)) + filemap_to_parser(sess, sess.codemap().new_filemap(name, source)) } /// Create a new parser, handling errors as appropriate @@ -828,7 +828,7 @@ mod tests { } #[test] fn parse_ident_pat () { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let mut parser = string_to_parser(&sess, "b".to_string()); assert!(panictry!(parser.parse_pat()) == P(ast::Pat{ @@ -998,7 +998,7 @@ mod tests { } #[test] fn crlf_doc_comments() { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let name = "".to_string(); let source = "/// doc comment\r\nfn foo() {}".to_string(); @@ -1023,7 +1023,7 @@ mod tests { #[test] fn ttdelim_span() { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let expr = parse::parse_expr_from_source_str("foo".to_string(), "foo!( fn main() { body } )".to_string(), &sess).unwrap(); diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index dc9b22c37e2..b3fa1e97376 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use errors::Handler; use errors::emitter::EmitterWriter; use std::io; @@ -47,8 +47,8 @@ impl Write for Shared { fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { let output = Arc::new(Mutex::new(Vec::new())); - let code_map = Rc::new(CodeMap::new()); - code_map.new_filemap_and_lines("test.rs", None, &file_text); + let code_map = Rc::new(CodeMap::new(FilePathMapping::empty())); + code_map.new_filemap_and_lines("test.rs", &file_text); let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); let mut msp = MultiSpan::from_span(primary_span); diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 51eb295b502..2727ab79ebf 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -9,6 +9,7 @@ // except according to those terms. use ast::{self, Ident}; +use codemap::FilePathMapping; use parse::{ParseSess, PResult, filemap_to_stream}; use parse::{lexer, new_parser_from_source_str}; use parse::parser::Parser; @@ -18,8 +19,8 @@ use std::iter::Peekable; /// Map a string to tts, using a made-up filename: pub fn string_to_stream(source_str: String) -> TokenStream { - let ps = ParseSess::new(); - filemap_to_stream(&ps, ps.codemap().new_filemap("bogofile".to_string(), None, source_str)) + let ps = ParseSess::new(FilePathMapping::empty()); + filemap_to_stream(&ps, ps.codemap().new_filemap("bogofile".to_string(), source_str)) } /// Map string to parser (via tts) @@ -38,7 +39,7 @@ fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T /// Parse a string, return a crate. pub fn string_to_crate (source_str : String) -> ast::Crate { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_crate_mod() }) @@ -46,7 +47,7 @@ pub fn string_to_crate (source_str : String) -> ast::Crate { /// Parse a string, return an expr pub fn string_to_expr (source_str : String) -> P { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_expr() }) @@ -54,7 +55,7 @@ pub fn string_to_expr (source_str : String) -> P { /// Parse a string, return an item pub fn string_to_item (source_str : String) -> Option> { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_item() }) @@ -62,7 +63,7 @@ pub fn string_to_item (source_str : String) -> Option> { /// Parse a string, return a stmt pub fn string_to_stmt(source_str : String) -> Option { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_stmt() }) @@ -71,7 +72,7 @@ pub fn string_to_stmt(source_str : String) -> Option { /// Parse a string, return a pat. Uses "irrefutable"... which doesn't /// (currently) affect parsing. pub fn string_to_pat(source_str: String) -> P { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_pat() }) -- cgit 1.4.1-3-g733a5