diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index ffe68289d5224..416634c2960ae 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -26,6 +26,7 @@ use parse::token::Token::*; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; +use std::borrow::Cow; use std::collections::HashMap; use std::collections::hash_map::Entry; @@ -141,7 +142,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, } let directory = Directory { - path: cx.current_expansion.module.directory.clone(), + path: Cow::from(cx.current_expansion.module.directory.as_path()), ownership: cx.current_expansion.directory_ownership, }; let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f26a6a5307401..0abedb99bd037 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -23,6 +23,7 @@ use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use diagnostics::plugin::ErrorMap; +use std::borrow::Cow; use std::collections::HashSet; use std::iter; use std::path::{Path, PathBuf}; @@ -89,8 +90,8 @@ impl ParseSess { } #[derive(Clone)] -pub struct Directory { - pub path: PathBuf, +pub struct Directory<'a> { + pub path: Cow<'a, Path>, pub ownership: DirectoryOwnership, } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 49b30c6f460fe..3a53665a03283 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -57,6 +57,7 @@ use tokenstream::{self, Delimited, ThinTokenStream, TokenTree, TokenStream}; use symbol::{Symbol, keywords}; use util::ThinVec; +use std::borrow::Cow; use std::cmp; use std::mem; use std::path::{self, Path, PathBuf}; @@ -228,7 +229,7 @@ pub struct Parser<'a> { prev_token_kind: PrevTokenKind, pub restrictions: Restrictions, /// Used to determine the path to externally loaded source files - pub directory: Directory, + pub directory: Directory<'a>, /// Whether to parse sub-modules in other files. pub recurse_into_file_modules: bool, /// Name of the root module this parser originated from. If `None`, then the @@ -535,7 +536,7 @@ enum TokenExpectType { impl<'a> Parser<'a> { pub fn new(sess: &'a ParseSess, tokens: TokenStream, - directory: Option, + directory: Option>, recurse_into_file_modules: bool, desugar_doc_comments: bool) -> Self { @@ -549,7 +550,7 @@ impl<'a> Parser<'a> { restrictions: Restrictions::empty(), recurse_into_file_modules, directory: Directory { - path: PathBuf::new(), + path: Cow::from(PathBuf::new()), ownership: DirectoryOwnership::Owned { relative: None } }, root_module_name: None, @@ -572,9 +573,9 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; } else if !parser.span.source_equal(&DUMMY_SP) { - if let FileName::Real(path) = sess.codemap().span_to_unmapped_path(parser.span) { - parser.directory.path = path; - parser.directory.path.pop(); + if let FileName::Real(mut path) = sess.codemap().span_to_unmapped_path(parser.span) { + path.pop(); + parser.directory.path = Cow::from(path); } } @@ -6000,10 +6001,10 @@ impl<'a> Parser<'a> { fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") { - self.directory.path.push(&path.as_str()); + self.directory.path.to_mut().push(&path.as_str()); self.directory.ownership = DirectoryOwnership::Owned { relative: None }; } else { - self.directory.path.push(&id.name.as_str()); + self.directory.path.to_mut().push(&id.name.as_str()); } } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index e2b5c4e1adfdb..455cc4391dd3b 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -31,6 +31,7 @@ use print::pprust; use serialize::{Decoder, Decodable, Encoder, Encodable}; use util::RcSlice; +use std::borrow::Cow; use std::{fmt, iter, mem}; use std::hash::{self, Hash}; @@ -106,7 +107,7 @@ impl TokenTree { -> macro_parser::NamedParseResult { // `None` is because we're not interpolating let directory = Directory { - path: cx.current_expansion.module.directory.clone(), + path: Cow::from(cx.current_expansion.module.directory.as_path()), ownership: cx.current_expansion.directory_ownership, }; macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true)