Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
721e0a8
modify `asm_experimental_reg` example to not need x86_64
folkertdev Jul 18, 2026
b68b9bc
stabilize passing 128-bit integers via vector registers with `asm!` o…
folkertdev Jul 18, 2026
dcf4a3d
allocations are allowed to grow
RalfJung Jul 22, 2026
56f6073
Allow only implementing `Read::read_buf`
WaffleLapkin Jan 9, 2023
39429fd
Fix links to `std::io::Read::read`
joshtriplett Jul 28, 2026
7d0aafd
Specialize `advance_by` method of `Fuse`
a1phyr Aug 1, 2026
e5b6364
fix: Do not stop `visible_parent_map` breadth-first search reaching c…
zalanlevai Jul 25, 2026
c4d12cb
Setup `core::io::prelude`
bushrat011899 May 21, 2026
0791c08
Setup `alloc::io::prelude`
bushrat011899 May 21, 2026
d951987
Expand documentation for `alloc::io`
bushrat011899 Jul 19, 2026
32117cd
Move general IO tests to `alloctests`
bushrat011899 May 21, 2026
125be4b
Move `std::io::util` tests to `alloctests`
bushrat011899 May 21, 2026
39bf757
Move `std::io::cursor` tests to `alloctests`
bushrat011899 May 21, 2026
f67f57d
Move `std::io::buffered` tests to `alloctests`
bushrat011899 May 21, 2026
29da936
Move `std::io::impls` benchmarks to `alloctests`
bushrat011899 May 25, 2026
5b49a9d
Move `std::io::copy` tests to `alloctests`
bushrat011899 Aug 1, 2026
7e750c4
Rollup merge of #156527 - bushrat011899:core_io_test_merge, r=clarfon…
jhpratt Aug 2, 2026
46034b5
Rollup merge of #159525 - folkertdev:stabilize-x86-i128-asm, r=Amanieu
jhpratt Aug 2, 2026
9a0f2a9
Rollup merge of #160342 - a1phyr:fuse_advnce_by, r=joboet
jhpratt Aug 2, 2026
57058bb
Rollup merge of #106643 - WaffleLapkin:read_recursive, r=joshtriplett
jhpratt Aug 2, 2026
349dfbc
Rollup merge of #159729 - RalfJung:alloc-grow, r=Darksonn
jhpratt Aug 2, 2026
c43b1f6
Rollup merge of #159881 - zalanlevai:fix-incomplete-visible-parent-ma…
jhpratt Aug 2, 2026
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
32 changes: 21 additions & 11 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,14 +501,14 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
}

if let Some(def_id) = child.res.opt_def_id() {
let mut fallback = false;

if child.ident.name == kw::Underscore {
fallback_map.push((def_id, parent));
return;
fallback = true;
}

if tcx.is_doc_hidden(parent) {
fallback_map.push((def_id, parent));
return;
fallback = true;
}

// If the re-export itself is `#[doc(hidden)]`, deprioritize it.
Expand All @@ -519,20 +519,30 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
.and_then(|r| r.id())
.is_some_and(|id| tcx.is_doc_hidden(id))
{
fallback_map.push((def_id, parent));
return;
fallback = true;
}

match visible_parent_map.entry(def_id) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if def_id.is_local() && entry.get().is_local() {
entry.insert(parent);
if !fallback {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if def_id.is_local() && entry.get().is_local() {
entry.insert(parent);
}
}
}
Entry::Vacant(entry) => {
entry.insert(parent);
if fallback {
// We do all of the same steps to fallback entries as to
// preferred entries, except for recording them in a separate map.
// It is important to not return early in the fallback cases to
// ensure that we extend the BFS to the children of fallback items.
fallback_map.push((def_id, parent));
} else {
entry.insert(parent);
}

if child.res.module_like_def_id().is_some() {
bfs_queue.push_back(def_id);
}
Expand Down
44 changes: 10 additions & 34 deletions compiler/rustc_target/src/asm/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl X86InlineAsmRegClass {
pub fn supported_types(
self,
arch: InlineAsmArch,
allow_experimental_reg: bool,
_allow_experimental_reg: bool,
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::reg | Self::reg_abcd => {
Expand All @@ -117,48 +117,24 @@ impl X86InlineAsmRegClass {
}
Self::reg_byte => types! { _: I8; },
Self::xmm_reg => {
if allow_experimental_reg {
types! {
sse: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
}
} else {
types! {
sse: I32, I64, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
}
types! {
sse: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
}
}
Self::ymm_reg => {
if allow_experimental_reg {
types! {
avx: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2),
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF16(16), VecF32(8), VecF64(4);
}
} else {
types! {
avx: I32, I64, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2),
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF16(16), VecF32(8), VecF64(4);
}
types! {
avx: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2),
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF16(16), VecF32(8), VecF64(4);
}
}
Self::zmm_reg => {
if allow_experimental_reg {
types! {
avx512f: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2),
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF16(16), VecF32(8), VecF64(4),
VecI8(64), VecI16(32), VecI32(16), VecI64(8), VecF16(32), VecF32(16), VecF64(8);
}
} else {
types! {
avx512f: I32, I64, F16, F32, F64, F128,
types! {
avx512f: I32, I64, I128, F16, F32, F64, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2),
VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF16(16), VecF32(8), VecF64(4),
VecI8(64), VecI16(32), VecI32(16), VecI64(8), VecF16(32), VecF32(16), VecF64(8);
}
}
}

Expand Down
177 changes: 177 additions & 0 deletions library/alloc/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,188 @@
//! Traits, helpers, and type definitions for core I/O functionality.
//!
//! The `io` module contains a number of common things you'll need
//! when doing input and output. The most core part of this module is
//! the [`Read`] and [`Write`] traits, which provide the
//! most general interface for reading and writing input and output.
//!
//! ## Read and Write
//!
//! Because they are traits, [`Read`] and [`Write`] are implemented by a number
//! of other types, and you can implement them for your types too. As such,
//! you'll see a few different types of I/O throughout the documentation in
//! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
//! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on
//! [`File`]s:
//!
//! ```no_run
//! use std::io;
//! use std::io::prelude::*;
//! use std::fs::File;
//!
//! fn main() -> io::Result<()> {
//! let mut f = File::open("foo.txt")?;
//! let mut buffer = [0; 10];
//!
//! // read up to 10 bytes
//! let n = f.read(&mut buffer)?;
//!
//! println!("The bytes: {:?}", &buffer[..n]);
//! Ok(())
//! }
//! ```
//!
//! [`Read`] and [`Write`] are so important, implementors of the two traits have a
//! nickname: readers and writers. So you'll sometimes see 'a reader' instead
//! of 'a type that implements the [`Read`] trait'. Much easier!
//!
//! ## Seek and BufRead
//!
//! Beyond that, there are two important traits that are provided: [`Seek`]
//! and [`BufRead`]. Both of these build on top of a reader to control
//! how the reading happens. [`Seek`] lets you control where the next byte is
//! coming from:
//!
//! ```no_run
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::SeekFrom;
//! use std::fs::File;
//!
//! fn main() -> io::Result<()> {
//! let mut f = File::open("foo.txt")?;
//! let mut buffer = [0; 10];
//!
//! // skip to the last 10 bytes of the file
//! f.seek(SeekFrom::End(-10))?;
//!
//! // read up to 10 bytes
//! let n = f.read(&mut buffer)?;
//!
//! println!("The bytes: {:?}", &buffer[..n]);
//! Ok(())
//! }
//! ```
//!
//! [`BufRead`] uses an internal buffer to provide a number of other ways to read, but
//! to show it off, we'll need to talk about buffers in general. Keep reading!
//!
//! ## BufReader and BufWriter
//!
//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
//! making near-constant calls to the operating system. To help with this,
//! `std::io` comes with two structs, [`BufReader`] and [`BufWriter`], which wrap
//! readers and writers. The wrapper uses a buffer, reducing the number of
//! calls and providing nicer methods for accessing exactly what you want.
//!
//! For example, [`BufReader`] works with the [`BufRead`] trait to add extra
//! methods to any reader:
//!
//! ```no_run
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufReader;
//! use std::fs::File;
//!
//! fn main() -> io::Result<()> {
//! let f = File::open("foo.txt")?;
//! let mut reader = BufReader::new(f);
//! let mut buffer = String::new();
//!
//! // read a line into buffer
//! reader.read_line(&mut buffer)?;
//!
//! println!("{buffer}");
//! Ok(())
//! }
//! ```
//!
//! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
//! to [`write`][`Write::write`]:
//!
//! ```no_run
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufWriter;
//! use std::fs::File;
//!
//! fn main() -> io::Result<()> {
//! let f = File::create("foo.txt")?;
//! {
//! let mut writer = BufWriter::new(f);
//!
//! // write a byte to the buffer
//! writer.write(&[42])?;
//!
//! } // the buffer is flushed once writer goes out of scope
//!
//! Ok(())
//! }
//! ```
//!
//! ## Iterator types
//!
//! A large number of the structures provided by `std::io` are for various
//! ways of iterating over I/O. For example, [`Lines`] is used to split over
//! lines:
//!
//! ```no_run
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufReader;
//! use std::fs::File;
//!
//! fn main() -> io::Result<()> {
//! let f = File::open("foo.txt")?;
//! let reader = BufReader::new(f);
//!
//! for line in reader.lines() {
//! println!("{}", line?);
//! }
//! Ok(())
//! }
//! ```
//!
//! ## io::Result
//!
//! Last, but certainly not least, is [`io::Result`]. This type is used
//! as the return type of many `std::io` functions that can cause an error, and
//! can be returned from your own functions as well. Many of the examples in this
//! module use the [`?` operator]:
//!
//! ```no_run
//! use std::io;
//!
//! # #[allow(dead_code)]
//! fn read_input() -> io::Result<()> {
//! let mut input = String::new();
//!
//! io::stdin().read_line(&mut input)?;
//!
//! println!("You typed: {}", input.trim());
//!
//! Ok(())
//! }
//! ```
//!
//! The return type of `read_input()`, [`io::Result<()>`][`io::Result`], is a very
//! common type for functions which don't have a 'real' return value, but do want to
//! return errors if they happen. In this case, the only purpose of this function is
//! to read the line and print it, so we use `()`.
//!
//! [`File`]: ../../std/fs/struct.File.html
//! [`TcpStream`]: ../../std/net/struct.TcpStream.html
//! [`Vec<T>`]: crate::vec::Vec
//! [`io::Result`]: self::Result
//! [`?` operator]: ../../book/appendix-02-operators.html

mod buf_read;
mod buffered;
mod copy;
mod cursor;
mod error;
mod impls;
#[unstable(feature = "alloc_io", issue = "154046")]
pub mod prelude;
mod read;
mod util;

Expand Down
12 changes: 12 additions & 0 deletions library/alloc/src/io/prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! The I/O Prelude.
//!
//! The purpose of this module is to alleviate imports of many common I/O traits
//! by adding a glob import to the top of I/O heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use std::io::prelude::*;
//! ```

#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::io::{BufRead, Read, Seek, Write};
6 changes: 5 additions & 1 deletion library/alloc/src/io/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ use crate::vec::Vec;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(notable_trait)]
#[cfg_attr(not(test), rustc_diagnostic_item = "IoRead")]
#[rustc_must_implement_one_of(read, read_buf)]
pub trait Read {
/// Pull some bytes from this source into the specified buffer, returning
/// how many bytes were read.
Expand Down Expand Up @@ -164,7 +165,10 @@ pub trait Read {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut buf = BorrowedBuf::from(buf);
self.read_buf(buf.unfilled()).map(|()| buf.len())
}

/// Like `read`, except that it reads into a slice of buffers.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::io::prelude::*;
use std::io::prelude::*;

#[bench]
fn bench_read_slice(b: &mut test::Bencher) {
Expand Down Expand Up @@ -55,3 +55,26 @@ fn bench_write_vec(b: &mut test::Bencher) {
}
})
}

#[bench]
#[cfg(unix)]
#[cfg_attr(target_os = "emscripten", ignore)] // no /dev
fn bench_copy_buf_reader(b: &mut test::Bencher) {
use std::fs::{File, OpenOptions};

let mut file_in = File::open("/dev/zero").expect("opening /dev/zero failed");
// use dyn to avoid specializations unrelated to readbuf
let dyn_in = &mut file_in as &mut dyn Read;
let mut reader = std::io::BufReader::with_capacity(256 * 1024, dyn_in.take(0));
let mut writer =
OpenOptions::new().write(true).open("/dev/null").expect("opening /dev/null failed");

const BYTES: u64 = 1024 * 1024;

b.bytes = BYTES;

b.iter(|| {
reader.get_mut().set_limit(BYTES);
std::io::copy(&mut reader, &mut writer).unwrap()
});
}
1 change: 1 addition & 0 deletions library/alloctests/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extern crate test;

mod binary_heap;
mod btree;
mod io;
mod linked_list;
mod slice;
mod str;
Expand Down
Loading
Loading