Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,43 @@ impl DiagStyledString {
pub fn content(&self) -> String {
self.0.iter().map(|x| x.content.as_str()).collect::<String>()
}

/// Merge segments of the same style.
pub fn compact(&mut self) {
let segments = std::mem::take(&mut self.0);
let mut iter = segments.into_iter();
let Some(mut prev) = iter.next() else { return };
while let Some(segment) = iter.next() {
if prev.style == segment.style {
prev.content.push_str(&segment.content);
} else {
self.0.push(prev);
prev = segment;
}
}
self.0.push(prev);
}

/// Remove the middle of all long segments for shorter rendering.
pub fn shorten(&mut self) {
self.compact();
/// The marker for removed text.
const ELLIPSIS: &str = "...";
/// How many chars at the start and end will remain.
const PADDING: usize = 6;
/// The distance after which it is not worth it to reduce the text.
const DELTA: usize = 3;

for segment in self.0.iter_mut() {
let char_len = segment.content.chars().count();
if char_len > PADDING * 2 + ELLIPSIS.chars().count() + DELTA
&& let Some((left, _)) = segment.content.char_indices().nth(PADDING)
&& let Some((right, _)) = segment.content.char_indices().nth(char_len - PADDING)
{
segment.content.replace_range(left..right, ELLIPSIS);
}
}
}
}

#[derive(Debug, PartialEq, Eq)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse_format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ impl<'input> Parser<'input> {
return spec;
};

spec.ty = self.string(self.input_vec_index);
spec.ty = self.string(self.input_vec_index2pos(self.input_vec_index));
spec.ty_span = {
let end = self.input_vec_index2range(self.input_vec_index).start;
Some(start..end)
Expand Down
389 changes: 276 additions & 113 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions library/alloc/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ pub use core::io::{
stream_len_default, take,
};

#[unstable(feature = "alloc_io", issue = "154046")]
pub use self::{read::Read, util::Bytes};
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub use self::{
Expand All @@ -38,3 +36,8 @@ pub use self::{
},
util::{SpecReadByte, bytes, uninlined_slow_read_byte},
};
#[unstable(feature = "alloc_io", issue = "154046")]
pub use self::{
read::{Read, read_to_string},
util::Bytes,
};
65 changes: 65 additions & 0 deletions library/alloc/src/io/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,71 @@ pub trait Read {
}
}

/// Reads all bytes from a [reader][Read] into a new [`String`].
///
/// This is a convenience function for [`Read::read_to_string`]. Using this
/// function avoids having to create a variable first and provides more type
/// safety since you can only get the buffer out if there were no errors. (If you
/// use [`Read::read_to_string`] you have to remember to check whether the read
/// succeeded because otherwise your buffer will be empty or only partially full.)
///
/// # Performance
///
/// The downside of this function's increased ease of use and type safety is
/// that it gives you less control over performance. For example, you can't
/// pre-allocate memory like you can using [`String::with_capacity`] and
/// [`Read::read_to_string`]. Also, you can't re-use the buffer if an error
/// occurs while reading.
///
/// In many cases, this function's performance will be adequate and the ease of use
/// and type safety tradeoffs will be worth it. However, there are cases where you
/// need more control over performance, and in those cases you should definitely use
/// [`Read::read_to_string`] directly.
///
/// Note that in some special cases, such as when reading files, this function will
/// pre-allocate memory based on the size of the input it is reading. In those
/// cases, the performance should be as good as if you had used
/// [`Read::read_to_string`] with a manually pre-allocated buffer.
///
/// # Errors
///
/// This function forces you to handle errors because the output (the `String`)
/// is wrapped in a [`Result`]. See [`Read::read_to_string`] for the errors
/// that can occur. If any error occurs, you will get an [`Err`], so you
/// don't have to worry about your buffer being empty or partially full.
///
/// # Examples
///
/// ```no_run
/// # use std::io;
/// fn main() -> io::Result<()> {
/// let stdin = io::read_to_string(io::stdin())?;
/// println!("Stdin was:");
/// println!("{stdin}");
/// Ok(())
/// }
/// ```
///
/// # Usage Notes
///
/// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams
/// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input
/// is one such stream which may be finite if piped, but is typically continuous. For example,
/// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat.
/// Reading user input or running programs that remain open indefinitely will never terminate
/// the stream with `EOF` (e.g. `yes | my-rust-program`).
///
/// Using `.lines()` with a `BufReader` or using [`read`] can provide a better solution
///
/// [`read`]: Read::read
///
#[stable(feature = "io_read_to_string", since = "1.65.0")]
pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
Ok(buf)
}

/// Bare metal platforms usually have very small amounts of RAM
/// (in the order of hundreds of KB)
#[doc(hidden)]
Expand Down
67 changes: 2 additions & 65 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ pub use alloc_crate::io::RawOsError;
pub use alloc_crate::io::SimpleMessage;
#[unstable(feature = "io_const_error", issue = "133448")]
pub use alloc_crate::io::const_error;
#[stable(feature = "io_read_to_string", since = "1.65.0")]
pub use alloc_crate::io::read_to_string;
#[unstable(feature = "read_buf", issue = "78485")]
pub use alloc_crate::io::{BorrowedBuf, BorrowedCursor};
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -359,71 +361,6 @@ mod util;

pub(crate) use stdio::cleanup;

/// Reads all bytes from a [reader][Read] into a new [`String`].
///
/// This is a convenience function for [`Read::read_to_string`]. Using this
/// function avoids having to create a variable first and provides more type
/// safety since you can only get the buffer out if there were no errors. (If you
/// use [`Read::read_to_string`] you have to remember to check whether the read
/// succeeded because otherwise your buffer will be empty or only partially full.)
///
/// # Performance
///
/// The downside of this function's increased ease of use and type safety is
/// that it gives you less control over performance. For example, you can't
/// pre-allocate memory like you can using [`String::with_capacity`] and
/// [`Read::read_to_string`]. Also, you can't re-use the buffer if an error
/// occurs while reading.
///
/// In many cases, this function's performance will be adequate and the ease of use
/// and type safety tradeoffs will be worth it. However, there are cases where you
/// need more control over performance, and in those cases you should definitely use
/// [`Read::read_to_string`] directly.
///
/// Note that in some special cases, such as when reading files, this function will
/// pre-allocate memory based on the size of the input it is reading. In those
/// cases, the performance should be as good as if you had used
/// [`Read::read_to_string`] with a manually pre-allocated buffer.
///
/// # Errors
///
/// This function forces you to handle errors because the output (the `String`)
/// is wrapped in a [`Result`]. See [`Read::read_to_string`] for the errors
/// that can occur. If any error occurs, you will get an [`Err`], so you
/// don't have to worry about your buffer being empty or partially full.
///
/// # Examples
///
/// ```no_run
/// # use std::io;
/// fn main() -> io::Result<()> {
/// let stdin = io::read_to_string(io::stdin())?;
/// println!("Stdin was:");
/// println!("{stdin}");
/// Ok(())
/// }
/// ```
///
/// # Usage Notes
///
/// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams
/// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input
/// is one such stream which may be finite if piped, but is typically continuous. For example,
/// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat.
/// Reading user input or running programs that remain open indefinitely will never terminate
/// the stream with `EOF` (e.g. `yes | my-rust-program`).
///
/// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution
///
///[`read`]: Read::read
///
#[stable(feature = "io_read_to_string", since = "1.65.0")]
pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
Ok(buf)
}

fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> Result<usize> {
let mut read = 0;
loop {
Expand Down
Loading
Loading