From f26293dca4a4bc2fa6158964546617a6a34da639 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 27 Aug 2023 18:16:12 -0400 Subject: [PATCH] Load include_bytes! directly into an Lrc --- .../rustc_builtin_macros/src/source_util.rs | 2 +- compiler/rustc_span/src/lib.rs | 2 ++ compiler/rustc_span/src/source_map.rs | 21 +++++++++++++++---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 433da74231f..953d957a4ac 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -217,7 +217,7 @@ pub fn expand_include_bytes( }; match cx.source_map().load_binary_file(&file) { Ok(bytes) => { - let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes.into())); + let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes)); base::MacEager::expr(expr) } Err(e) => { diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index efaed0f68ce..62fe49fe2a2 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -21,6 +21,8 @@ #![feature(rustc_attrs)] #![feature(let_chains)] #![feature(round_char_boundary)] +#![feature(read_buf)] +#![feature(new_uninit)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![allow(internal_features)] diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 983b2ab04a4..1cff021ba41 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -24,6 +24,8 @@ use std::fs; use std::io; +use std::io::BorrowedBuf; +use std::io::Read; #[cfg(test)] mod tests; @@ -101,10 +103,13 @@ pub trait FileLoader { fn file_exists(&self, path: &Path) -> bool; /// Read the contents of a UTF-8 file into memory. + /// This function must return a String because we normalize + /// source files, which may require resizing. fn read_file(&self, path: &Path) -> io::Result; /// Read the contents of a potentially non-UTF-8 file into memory. - fn read_binary_file(&self, path: &Path) -> io::Result>; + /// We don't normalize binary files, so we can start in an Lrc. + fn read_binary_file(&self, path: &Path) -> io::Result>; } /// A FileLoader that uses std::fs to load real files. @@ -119,8 +124,16 @@ fn read_file(&self, path: &Path) -> io::Result { fs::read_to_string(path) } - fn read_binary_file(&self, path: &Path) -> io::Result> { - fs::read(path) + fn read_binary_file(&self, path: &Path) -> io::Result> { + let mut file = fs::File::open(path)?; + let len = file.metadata()?.len(); + + let mut bytes = Lrc::new_uninit_slice(len as usize); + let mut buf = BorrowedBuf::from(Lrc::get_mut(&mut bytes).unwrap()); + file.read_buf_exact(buf.unfilled())?; + // SAFETY: If the read_buf_exact call returns Ok(()), then we have + // read len bytes and initialized the buffer. + Ok(unsafe { bytes.assume_init() }) } } @@ -228,7 +241,7 @@ pub fn load_file(&self, path: &Path) -> io::Result> { /// /// Unlike `load_file`, guarantees that no normalization like BOM-removal /// takes place. - pub fn load_binary_file(&self, path: &Path) -> io::Result> { + pub fn load_binary_file(&self, path: &Path) -> io::Result> { let bytes = self.file_loader.read_binary_file(path)?; // We need to add file to the `SourceMap`, so that it is present