summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_serialize/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_serialize/src
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_serialize/src')
-rw-r--r--compiler/rustc_serialize/src/lib.rs6
-rw-r--r--compiler/rustc_serialize/src/opaque.rs43
2 files changed, 39 insertions, 10 deletions
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index cfa54072e..352758214 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -5,9 +5,9 @@
html_playground_url = "https://play.rust-lang.org/",
test(attr(allow(unused_variables), deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
#![feature(allocator_api)]
#![feature(associated_type_bounds)]
#![feature(const_option)]
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 552554390..cc8d1c250 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -5,12 +5,13 @@ use std::io::{self, Write};
use std::marker::PhantomData;
use std::ops::Range;
use std::path::Path;
+use std::path::PathBuf;
// -----------------------------------------------------------------------------
// Encoder
// -----------------------------------------------------------------------------
-pub type FileEncodeResult = Result<usize, io::Error>;
+pub type FileEncodeResult = Result<usize, (PathBuf, io::Error)>;
/// The size of the buffer in `FileEncoder`.
const BUF_SIZE: usize = 8192;
@@ -34,6 +35,9 @@ pub struct FileEncoder {
// This is used to implement delayed error handling, as described in the
// comment on `trait Encoder`.
res: Result<(), io::Error>,
+ path: PathBuf,
+ #[cfg(debug_assertions)]
+ finished: bool,
}
impl FileEncoder {
@@ -41,14 +45,18 @@ impl FileEncoder {
// File::create opens the file for writing only. When -Zmeta-stats is enabled, the metadata
// encoder rewinds the file to inspect what was written. So we need to always open the file
// for reading and writing.
- let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?;
+ let file =
+ File::options().read(true).write(true).create(true).truncate(true).open(&path)?;
Ok(FileEncoder {
buf: vec![0u8; BUF_SIZE].into_boxed_slice().try_into().unwrap(),
+ path: path.as_ref().into(),
buffered: 0,
flushed: 0,
file,
res: Ok(()),
+ #[cfg(debug_assertions)]
+ finished: false,
})
}
@@ -63,6 +71,10 @@ impl FileEncoder {
#[cold]
#[inline(never)]
pub fn flush(&mut self) {
+ #[cfg(debug_assertions)]
+ {
+ self.finished = false;
+ }
if self.res.is_ok() {
self.res = self.file.write_all(&self.buf[..self.buffered]);
}
@@ -74,6 +86,10 @@ impl FileEncoder {
&self.file
}
+ pub fn path(&self) -> &Path {
+ &self.path
+ }
+
#[inline]
fn buffer_empty(&mut self) -> &mut [u8] {
// SAFETY: self.buffered is inbounds as an invariant of the type
@@ -97,6 +113,10 @@ impl FileEncoder {
#[inline]
fn write_all(&mut self, buf: &[u8]) {
+ #[cfg(debug_assertions)]
+ {
+ self.finished = false;
+ }
if let Some(dest) = self.buffer_empty().get_mut(..buf.len()) {
dest.copy_from_slice(buf);
self.buffered += buf.len();
@@ -121,6 +141,10 @@ impl FileEncoder {
/// with one instruction, so while this does in some sense do wasted work, we come out ahead.
#[inline]
pub fn write_with<const N: usize>(&mut self, visitor: impl FnOnce(&mut [u8; N]) -> usize) {
+ #[cfg(debug_assertions)]
+ {
+ self.finished = false;
+ }
let flush_threshold = const { BUF_SIZE.checked_sub(N).unwrap() };
if std::intrinsics::unlikely(self.buffered > flush_threshold) {
self.flush();
@@ -152,20 +176,25 @@ impl FileEncoder {
})
}
- pub fn finish(mut self) -> Result<usize, io::Error> {
+ pub fn finish(&mut self) -> FileEncodeResult {
self.flush();
+ #[cfg(debug_assertions)]
+ {
+ self.finished = true;
+ }
match std::mem::replace(&mut self.res, Ok(())) {
Ok(()) => Ok(self.position()),
- Err(e) => Err(e),
+ Err(e) => Err((self.path.clone(), e)),
}
}
}
+#[cfg(debug_assertions)]
impl Drop for FileEncoder {
fn drop(&mut self) {
- // Likely to be a no-op, because `finish` should have been called and
- // it also flushes. But do it just in case.
- self.flush();
+ if !std::thread::panicking() {
+ assert!(self.finished);
+ }
}
}