@@ -47,6 +47,7 @@ use fs_err as fs;
4747
4848use serde:: { Deserialize , Serialize } ;
4949use std:: fmt;
50+ use std:: fs:: File ;
5051use std:: io:: { self , Cursor , Read , Seek , Write } ;
5152use std:: path:: { Path , PathBuf } ;
5253use std:: sync:: Arc ;
@@ -218,15 +219,30 @@ impl CacheRead {
218219 // Write the cache entry to a tempfile and then atomically
219220 // move it to its final location so that other rustc invocations
220221 // happening in parallel don't see a partially-written file.
221- let mut tmp = NamedTempFile :: new_in ( dir) ?;
222- match ( self . get_object ( & key, & mut tmp) , optional) {
223- ( Ok ( mode) , _) => {
224- tmp. persist ( & path) ?;
222+ match ( NamedTempFile :: new_in ( dir) , optional) {
223+ ( Ok ( mut tmp) , _) => {
224+ match ( self . get_object ( & key, & mut tmp) , optional) {
225+ ( Ok ( mode) , _) => {
226+ tmp. persist ( & path) ?;
227+ if let Some ( mode) = mode {
228+ set_file_mode ( & path, mode) ?;
229+ }
230+ }
231+ ( Err ( e) , false ) => return Err ( e) ,
232+ // skip if no object found and it's optional
233+ ( Err ( _) , true ) => continue ,
234+ }
235+ }
236+ ( Err ( e) , false ) => {
237+ // Fall back to writing directly to the final location
238+ warn ! ( "Failed to create temp file on the same file system: {e}" ) ;
239+ let mut f = File :: create ( & path) ?;
240+ // `optional`` is false in this branch, so do not ignore errors
241+ let mode = self . get_object ( & key, & mut f) ?;
225242 if let Some ( mode) = mode {
226243 set_file_mode ( & path, mode) ?;
227244 }
228245 }
229- ( Err ( e) , false ) => return Err ( e) ,
230246 // skip if no object found and it's optional
231247 ( Err ( _) , true ) => continue ,
232248 }
0 commit comments