diff options
| author | bors <bors@rust-lang.org> | 2018-03-17 08:54:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-03-17 08:54:22 +0000 |
| commit | c3fd5d0ddead5b14ce5321b06bc5bed60d0cdf2f (patch) | |
| tree | f4fd63a65fc416b01bd812f528c8758642d56ac6 /src/libsyntax/codemap.rs | |
| parent | 8cabda4ce8d675868acff69e69250ad0b08d059b (diff) | |
| parent | 65b49902538b319f9fb07532beff9d02efd3197f (diff) | |
| download | rust-c3fd5d0ddead5b14ce5321b06bc5bed60d0cdf2f.tar.gz rust-c3fd5d0ddead5b14ce5321b06bc5bed60d0cdf2f.zip | |
Auto merge of #48904 - Zoxc:code-and-file-maps, r=michaelwoerister
Make CodeMap and FileMap thread-safe r? @michaelwoerister
Diffstat (limited to 'src/libsyntax/codemap.rs')
| -rw-r--r-- | src/libsyntax/codemap.rs | 78 |
1 files changed, 40 insertions, 38 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 951f8a871ca..a1aec052088 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -24,8 +24,7 @@ pub use self::ExpnFormat::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::sync::Lrc; -use std::cell::{RefCell, Ref}; +use rustc_data_structures::sync::{Lrc, Lock, LockGuard}; use std::cmp; use std::hash::Hash; use std::path::{Path, PathBuf}; @@ -125,13 +124,17 @@ impl StableFilemapId { // CodeMap // +pub(super) struct CodeMapFiles { + pub(super) file_maps: Vec<Lrc<FileMap>>, + stable_id_to_filemap: FxHashMap<StableFilemapId, Lrc<FileMap>> +} + pub struct CodeMap { - pub(super) files: RefCell<Vec<Lrc<FileMap>>>, - file_loader: Box<FileLoader>, + pub(super) files: Lock<CodeMapFiles>, + file_loader: Box<FileLoader + Sync + Send>, // This is used to apply the file path remapping as specified via // --remap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, - stable_id_to_filemap: RefCell<FxHashMap<StableFilemapId, Lrc<FileMap>>>, /// In case we are in a doctest, replace all file names with the PathBuf, /// and add the given offsets to the line info doctest_offset: Option<(FileName, isize)>, @@ -140,10 +143,12 @@ pub struct CodeMap { impl CodeMap { pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), + files: Lock::new(CodeMapFiles { + file_maps: Vec::new(), + stable_id_to_filemap: FxHashMap(), + }), file_loader: Box::new(RealFileLoader), path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), doctest_offset: None, } } @@ -157,14 +162,16 @@ impl CodeMap { } - pub fn with_file_loader(file_loader: Box<FileLoader>, + pub fn with_file_loader(file_loader: Box<FileLoader + Sync + Send>, path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), - file_loader, + files: Lock::new(CodeMapFiles { + file_maps: Vec::new(), + stable_id_to_filemap: FxHashMap(), + }), + file_loader: file_loader, path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), doctest_offset: None, } } @@ -187,17 +194,16 @@ impl CodeMap { Ok(self.new_filemap(filename, src)) } - pub fn files(&self) -> Ref<Vec<Lrc<FileMap>>> { - self.files.borrow() + pub fn files(&self) -> LockGuard<Vec<Lrc<FileMap>>> { + LockGuard::map(self.files.borrow(), |files| &mut files.file_maps) } pub fn filemap_by_stable_id(&self, stable_id: StableFilemapId) -> Option<Lrc<FileMap>> { - self.stable_id_to_filemap.borrow().get(&stable_id).map(|fm| fm.clone()) + self.files.borrow().stable_id_to_filemap.get(&stable_id).map(|fm| fm.clone()) } fn next_start_pos(&self) -> usize { - let files = self.files.borrow(); - match files.last() { + match self.files.borrow().file_maps.last() { None => 0, // Add one so there is some space between files. This lets us distinguish // positions in the codemap, even in the presence of zero-length files. @@ -207,9 +213,9 @@ 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. + /// This does not ensure that only one FileMap exists per file name. pub fn new_filemap(&self, filename: FileName, src: String) -> Lrc<FileMap> { let start_pos = self.next_start_pos(); - let mut files = self.files.borrow_mut(); // The path is used to determine the directory for loading submodules and // include files, so it must be before remapping. @@ -233,16 +239,16 @@ impl CodeMap { Pos::from_usize(start_pos), )); - files.push(filemap.clone()); + let mut files = self.files.borrow_mut(); - self.stable_id_to_filemap - .borrow_mut() - .insert(StableFilemapId::new(&filemap), filemap.clone()); + files.file_maps.push(filemap.clone()); + files.stable_id_to_filemap.insert(StableFilemapId::new(&filemap), filemap.clone()); filemap } /// Creates a new filemap and sets its line information. + /// This does not ensure that only one FileMap exists per file name. pub fn new_filemap_and_lines(&self, filename: &Path, src: &str) -> Lrc<FileMap> { let fm = self.new_filemap(filename.to_owned().into(), src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; @@ -273,7 +279,6 @@ impl CodeMap { mut file_local_non_narrow_chars: Vec<NonNarrowChar>) -> Lrc<FileMap> { let start_pos = self.next_start_pos(); - let mut files = self.files.borrow_mut(); let end_pos = Pos::from_usize(start_pos + source_len); let start_pos = Pos::from_usize(start_pos); @@ -297,20 +302,19 @@ impl CodeMap { crate_of_origin, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), + external_src: Lock::new(ExternalSource::AbsentOk), start_pos, end_pos, - lines: RefCell::new(file_local_lines), - multibyte_chars: RefCell::new(file_local_multibyte_chars), - non_narrow_chars: RefCell::new(file_local_non_narrow_chars), + lines: Lock::new(file_local_lines), + multibyte_chars: Lock::new(file_local_multibyte_chars), + non_narrow_chars: Lock::new(file_local_non_narrow_chars), name_hash, }); - files.push(filemap.clone()); + let mut files = self.files.borrow_mut(); - self.stable_id_to_filemap - .borrow_mut() - .insert(StableFilemapId::new(&filemap), filemap.clone()); + files.file_maps.push(filemap.clone()); + files.stable_id_to_filemap.insert(StableFilemapId::new(&filemap), filemap.clone()); filemap } @@ -401,8 +405,7 @@ impl CodeMap { pub fn lookup_line(&self, pos: BytePos) -> Result<FileMapAndLine, Lrc<FileMap>> { let idx = self.lookup_filemap_idx(pos); - let files = self.files.borrow(); - let f = (*files)[idx].clone(); + let f = (*self.files.borrow().file_maps)[idx].clone(); match f.lookup_line(pos) { Some(line) => Ok(FileMapAndLine { fm: f, line: line }), @@ -456,7 +459,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().is_empty() && sp.source_equal(&DUMMY_SP) { + if self.files.borrow().file_maps.is_empty() && sp.source_equal(&DUMMY_SP) { return "no-location".to_string(); } @@ -799,7 +802,7 @@ impl CodeMap { } pub fn get_filemap(&self, filename: &FileName) -> Option<Lrc<FileMap>> { - for fm in self.files.borrow().iter() { + for fm in self.files.borrow().file_maps.iter() { if *filename == fm.name { return Some(fm.clone()); } @@ -810,7 +813,7 @@ impl CodeMap { /// For a global BytePos compute the local offset within the containing FileMap pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); - let fm = (*self.files.borrow())[idx].clone(); + let fm = (*self.files.borrow().file_maps)[idx].clone(); let offset = bpos - fm.start_pos; FileMapAndBytePos {fm: fm, pos: offset} } @@ -818,8 +821,7 @@ impl CodeMap { /// Converts an absolute BytePos to a CharPos relative to the filemap. pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { let idx = self.lookup_filemap_idx(bpos); - let files = self.files.borrow(); - let map = &(*files)[idx]; + let map = &(*self.files.borrow().file_maps)[idx]; // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; @@ -845,7 +847,7 @@ impl CodeMap { // Return the index of the filemap (in self.files) which contains pos. pub fn lookup_filemap_idx(&self, pos: BytePos) -> usize { let files = self.files.borrow(); - let files = &*files; + let files = &files.file_maps; let count = files.len(); // Binary search for the filemap. |
