about summary refs log tree commit diff
path: root/compiler/rustc_interface/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-03-08 14:59:20 +0000
committerbors <bors@rust-lang.org>2021-03-08 14:59:20 +0000
commit8f349be27815d43d462a32faeb270a22a68486b6 (patch)
tree37413af1348b05c9f8e65925c614ee369c16a3f5 /compiler/rustc_interface/src
parent1d6b0f626aad4ee9f2eaec4d5582f45620ccab80 (diff)
parent3b0a02a26b6db7a2f997cd32ca352e141ec795eb (diff)
downloadrust-8f349be27815d43d462a32faeb270a22a68486b6.tar.gz
rust-8f349be27815d43d462a32faeb270a22a68486b6.zip
Auto merge of #82896 - Dylan-DPC:rollup-9setmme, r=Dylan-DPC
Rollup of 10 pull requests

Successful merges:

 - #82047 (bypass auto_da_alloc for metadata files)
 - #82415 (expand: Refactor module loading)
 - #82557 (Add natvis for Result, NonNull, CString, CStr, and Cow)
 - #82613 (Remove Item::kind, use tagged enum. Rename variants to match)
 - #82642 (Fix jemalloc usage on OSX)
 - #82682 (Implement built-in attribute macro `#[cfg_eval]` + some refactoring)
 - #82684 (Disable destination propagation on all mir-opt-levels)
 - #82755 (Refactor confirm_builtin_call, remove partial if)
 - #82857 (Edit ructc_ast_lowering docs)
 - #82862 (Generalize Write impl for Vec<u8> to Vec<u8, A>)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_interface/src')
-rw-r--r--compiler/rustc_interface/src/passes.rs8
-rw-r--r--compiler/rustc_interface/src/util.rs18
2 files changed, 23 insertions, 3 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 5217066bbef..94be7a03a93 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -302,8 +302,10 @@ fn configure_and_expand_inner<'a>(
             ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
         };
 
-        let extern_mod_loaded = |k: &ast::Crate, ident: Ident| {
-            pre_expansion_lint(sess, lint_store, k, &*ident.name.as_str())
+        let extern_mod_loaded = |ident: Ident, attrs, items, span| {
+            let krate = ast::Crate { attrs, items, span, proc_macros: vec![] };
+            pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str());
+            (krate.attrs, krate.items)
         };
         let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded));
 
@@ -988,7 +990,7 @@ fn encode_and_write_metadata(
             .unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
         let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
         let metadata_filename = emit_metadata(tcx.sess, &metadata, &metadata_tmpdir);
-        if let Err(e) = fs::rename(&metadata_filename, &out_filename) {
+        if let Err(e) = util::non_durable_rename(&metadata_filename, &out_filename) {
             tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
         }
         if tcx.sess.opts.json_artifact_notifications {
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 798996263c7..0a30eda1ec4 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -694,6 +694,24 @@ pub fn build_output_filenames(
     }
 }
 
+#[cfg(not(target_os = "linux"))]
+pub fn non_durable_rename(src: &Path, dst: &Path) -> std::io::Result<()> {
+    std::fs::rename(src, dst)
+}
+
+/// This function attempts to bypass the auto_da_alloc heuristic implemented by some filesystems
+/// such as btrfs and ext4. When renaming over a file that already exists then they will "helpfully"
+/// write back the source file before committing the rename in case a developer forgot some of
+/// the fsyncs in the open/write/fsync(file)/rename/fsync(dir) dance for atomic file updates.
+///
+/// To avoid triggering this heuristic we delete the destination first, if it exists.
+/// The cost of an extra syscall is much lower than getting descheduled for the sync IO.
+#[cfg(target_os = "linux")]
+pub fn non_durable_rename(src: &Path, dst: &Path) -> std::io::Result<()> {
+    let _ = std::fs::remove_file(dst);
+    std::fs::rename(src, dst)
+}
+
 // Note: Also used by librustdoc, see PR #43348. Consider moving this struct elsewhere.
 //
 // FIXME: Currently the `everybody_loops` transformation is not applied to: