about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-10-30 18:00:54 +0900
committerGitHub <noreply@github.com>2020-10-30 18:00:54 +0900
commitf8539221d073cf0f4b28ba3dff5cae8a63ae5243 (patch)
treeb21143b87edf2ca020bcfa464e98e99ae4848818
parent8111706c18aebe273457b0967e076bf5e105a382 (diff)
parenta15e0dc4991a6c06dd5108d72163fb9809db2b07 (diff)
downloadrust-f8539221d073cf0f4b28ba3dff5cae8a63ae5243.tar.gz
rust-f8539221d073cf0f4b28ba3dff5cae8a63ae5243.zip
Rollup merge of #78524 - tmiasko:source-files-borrow, r=Aaron1011
Avoid BorrowMutError with RUSTC_LOG=debug

```console
$ touch empty.rs
$ env RUSTC_LOG=debug rustc +stage1 --crate-type=lib empty.rs
```

Fails with a `BorrowMutError` because source map files are already
borrowed while `features_query` attempts to format a log message
containing a span.

Release the borrow before the query to avoid the issue.
-rw-r--r--compiler/rustc_data_structures/src/sync.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs9
-rw-r--r--compiler/rustc_span/src/source_map.rs8
-rw-r--r--src/test/ui/auxiliary/rustc-rust-log-aux.rs1
-rw-r--r--src/test/ui/rustc-rust-log.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs5
6 files changed, 18 insertions, 9 deletions
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index d22f3adfb01..26706cd2b1b 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -512,7 +512,7 @@ impl<T: Clone> Clone for Lock<T> {
     }
 }
 
-#[derive(Debug)]
+#[derive(Debug, Default)]
 pub struct RwLock<T>(InnerRwLock<T>);
 
 impl<T> RwLock<T> {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7e33a479228..2a81737e168 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2042,6 +2042,10 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
     encoder.emit_raw_bytes(&[0, 0, 0, 0]);
 
     let source_map_files = tcx.sess.source_map().files();
+    let source_file_cache = (source_map_files[0].clone(), 0);
+    let required_source_files = Some(GrowableBitSet::with_capacity(source_map_files.len()));
+    drop(source_map_files);
+
     let hygiene_ctxt = HygieneEncodeContext::default();
 
     let mut ecx = EncodeContext {
@@ -2052,13 +2056,12 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
         lazy_state: LazyState::NoNode,
         type_shorthands: Default::default(),
         predicate_shorthands: Default::default(),
-        source_file_cache: (source_map_files[0].clone(), 0),
+        source_file_cache,
         interpret_allocs: Default::default(),
-        required_source_files: Some(GrowableBitSet::with_capacity(source_map_files.len())),
+        required_source_files,
         is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
         hygiene_ctxt: &hygiene_ctxt,
     };
-    drop(source_map_files);
 
     // Encode the rustc version string in a predictable location.
     rustc_version().encode(&mut ecx).unwrap();
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 3b929c4acb9..f067cdb7308 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -12,7 +12,7 @@ pub use crate::*;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{AtomicU32, Lock, LockGuard, Lrc, MappedLockGuard};
+use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
 use std::cmp;
 use std::convert::TryFrom;
 use std::hash::Hash;
@@ -168,7 +168,7 @@ pub struct SourceMap {
     /// The address space below this value is currently used by the files in the source map.
     used_address_space: AtomicU32,
 
-    files: Lock<SourceMapFiles>,
+    files: RwLock<SourceMapFiles>,
     file_loader: Box<dyn FileLoader + Sync + Send>,
     // This is used to apply the file path remapping as specified via
     // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
@@ -236,8 +236,8 @@ impl SourceMap {
 
     // By returning a `MonotonicVec`, we ensure that consumers cannot invalidate
     // any existing indices pointing into `files`.
-    pub fn files(&self) -> MappedLockGuard<'_, monotonic::MonotonicVec<Lrc<SourceFile>>> {
-        LockGuard::map(self.files.borrow(), |files| &mut files.source_files)
+    pub fn files(&self) -> MappedReadGuard<'_, monotonic::MonotonicVec<Lrc<SourceFile>>> {
+        ReadGuard::map(self.files.borrow(), |files| &files.source_files)
     }
 
     pub fn source_file_by_stable_id(
diff --git a/src/test/ui/auxiliary/rustc-rust-log-aux.rs b/src/test/ui/auxiliary/rustc-rust-log-aux.rs
new file mode 100644
index 00000000000..daa8e9f495e
--- /dev/null
+++ b/src/test/ui/auxiliary/rustc-rust-log-aux.rs
@@ -0,0 +1 @@
+// rustc-env:RUSTC_LOG=debug
diff --git a/src/test/ui/rustc-rust-log.rs b/src/test/ui/rustc-rust-log.rs
index 1c4252b23ea..8ceb24dd2af 100644
--- a/src/test/ui/rustc-rust-log.rs
+++ b/src/test/ui/rustc-rust-log.rs
@@ -8,7 +8,7 @@
 // dont-check-compiler-stdout
 // dont-check-compiler-stderr
 // compile-flags: --error-format human
-
+// aux-build: rustc-rust-log-aux.rs
 // rustc-env:RUSTC_LOG=debug
 
 fn main() {}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index d85558ea2f5..666e5d402ef 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1775,6 +1775,11 @@ impl<'test> TestCx<'test> {
         let mut aux_rustc =
             aux_cx.make_compile_args(input_file, aux_output, EmitMetadata::No, AllowUnused::No);
 
+        for key in &aux_props.unset_rustc_env {
+            aux_rustc.env_remove(key);
+        }
+        aux_rustc.envs(aux_props.rustc_env.clone());
+
         let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
             (true, None)
         } else if self.config.target.contains("cloudabi")