From c17d33f1df9492ad993da3d8b0ddfcfe08bd652e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 6 Nov 2023 21:29:08 +0000 Subject: [PATCH 1/7] Extend builtin/auto trait args with error when they have >1 argument --- .../src/traits/select/mod.rs | 21 +++++++++++++------ tests/ui/auto-traits/has-arguments.rs | 10 +++++++++ tests/ui/auto-traits/has-arguments.stderr | 11 ++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 tests/ui/auto-traits/has-arguments.rs create mode 100644 tests/ui/auto-traits/has-arguments.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cf52e6726a17c..08208cc60475b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2389,12 +2389,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ) }); - let obligation = Obligation::new( - self.tcx(), - cause.clone(), - param_env, - ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]), - ); + let tcx = self.tcx(); + let trait_ref = if tcx.generics_of(trait_def_id).params.len() == 1 { + ty::TraitRef::new(tcx, trait_def_id, [normalized_ty]) + } else { + // If this is an ill-formed auto/built-in trait, then synthesize + // new error args for the missing generics. + let err_args = ty::GenericArgs::extend_with_error( + tcx, + trait_def_id, + &[normalized_ty.into()], + ); + ty::TraitRef::new(tcx, trait_def_id, err_args) + }; + + let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); obligations.push(obligation); obligations }) diff --git a/tests/ui/auto-traits/has-arguments.rs b/tests/ui/auto-traits/has-arguments.rs new file mode 100644 index 0000000000000..f579eb6772d44 --- /dev/null +++ b/tests/ui/auto-traits/has-arguments.rs @@ -0,0 +1,10 @@ +#![feature(auto_traits)] + +auto trait Trait1<'outer> {} +//~^ ERROR auto traits cannot have generic parameters + +fn f<'a>(x: impl Trait1<'a>) {} + +fn main() { + f(""); +} diff --git a/tests/ui/auto-traits/has-arguments.stderr b/tests/ui/auto-traits/has-arguments.stderr new file mode 100644 index 0000000000000..3bba74badbce9 --- /dev/null +++ b/tests/ui/auto-traits/has-arguments.stderr @@ -0,0 +1,11 @@ +error[E0567]: auto traits cannot have generic parameters + --> $DIR/has-arguments.rs:3:18 + | +LL | auto trait Trait1<'outer> {} + | ------^^^^^^^^ help: remove the parameters + | | + | auto trait cannot have generic parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0567`. From 102384523a32f54b813fdfdc49758a090cb82766 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 15 Oct 2023 12:48:06 +0000 Subject: [PATCH 2/7] Document how rust atomics work wrt mixed-sized and non-atomic accesses --- library/core/src/sync/atomic.rs | 124 +++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 43 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index de41bd1a1167a..a5be33c7f56cb 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -4,26 +4,12 @@ //! threads, and are the building blocks of other concurrent //! types. //! -//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`. -//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating -//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference -//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not* -//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.) -//! //! This module defines atomic versions of a select number of primitive //! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`], //! [`AtomicI8`], [`AtomicU16`], etc. //! Atomic types present operations that, when used correctly, synchronize //! updates between threads. //! -//! Each method takes an [`Ordering`] which represents the strength of -//! the memory barrier for that operation. These orderings are the -//! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2]. -//! -//! [cpp]: https://en.cppreference.com/w/cpp/atomic -//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order -//! [2]: ../../../nomicon/atomics.html -//! //! Atomic variables are safe to share between threads (they implement [`Sync`]) //! but they do not themselves provide the mechanism for sharing and follow the //! [threading model](../../../std/thread/index.html#the-threading-model) of Rust. @@ -36,6 +22,75 @@ //! the constant initializers like [`AtomicBool::new`]. Atomic statics //! are often used for lazy global initialization. //! +//! ## Memory model for atomic accesses +//! +//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`. +//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating +//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference +//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not* +//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.) +//! +//! [cpp]: https://en.cppreference.com/w/cpp/atomic +//! +//! Each method takes an [`Ordering`] which represents the strength of +//! the memory barrier for that operation. These orderings are the +//! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2]. +//! +//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order +//! [2]: ../../../nomicon/atomics.html +//! +//! Since C++ does not support mixing atomic and non-atomic accesses, or non-synchronized +//! different-sized accesses to the same data, Rust does not support those operations either. +//! Note that both of those restrictions only apply if the accesses are non-synchronized. +//! +//! ```rust,no_run undefined_behavior +//! use std::sync::atomic::{AtomicU16, AtomicU8, Ordering}; +//! use std::mem::transmute; +//! use std::thread; +//! +//! let atomic = AtomicU16::new(0); +//! +//! thread::scope(|s| { +//! // This is UB: mixing atomic and non-atomic accesses +//! s.spawn(|| atomic.store(1, Ordering::Relaxed)); +//! s.spawn(|| unsafe { atomic.as_ptr().write(2) }); +//! }); +//! +//! thread::scope(|s| { +//! // This is UB: even reads are not allowed to be mixed +//! s.spawn(|| atomic.load(Ordering::Relaxed)); +//! s.spawn(|| unsafe { atomic.as_ptr().read() }); +//! }); +//! +//! thread::scope(|s| { +//! // This is fine, `join` synchronizes the code in a way such that atomic +//! // and non-atomic accesses can't happen "at the same time" +//! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); +//! handle.join().unwrap(); +//! s.spawn(|| unsafe { atomic.as_ptr().write(2) }); +//! }); +//! +//! thread::scope(|s| { +//! // This is UB: using different-sized atomic accesses to the same data +//! s.spawn(|| atomic.store(1, Ordering::Relaxed)); +//! s.spawn(|| unsafe { +//! let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic); +//! differently_sized.store(2, Ordering::Relaxed); +//! }); +//! }); +//! +//! thread::scope(|s| { +//! // This is fine, `join` synchronizes the code in a way such that +//! // differently-sized accesses can't happen "at the same time" +//! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); +//! handle.join().unwrap(); +//! s.spawn(|| unsafe { +//! let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic); +//! differently_sized.store(2, Ordering::Relaxed); +//! }); +//! }); +//! ``` +//! //! # Portability //! //! All atomic types in this module are guaranteed to be [lock-free] if they're @@ -349,16 +404,12 @@ impl AtomicBool { /// * `ptr` must be aligned to `align_of::()` (note that on some platforms this can /// be bigger than `align_of::()`). /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. - /// * Non-atomic accesses to the value behind `ptr` must have a happens-before relationship - /// with atomic accesses via the returned value (or vice-versa). - /// * In other words, time periods where the value is accessed atomically may not overlap - /// with periods where the value is accessed non-atomically. - /// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the - /// duration of lifetime `'a`. Most use cases should be able to follow this guideline. - /// * This requirement is also trivially satisfied if all accesses (atomic or not) are done - /// from the same thread. + /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not + /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, + /// without synchronization. /// /// [valid]: crate::ptr#safety + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")] pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool { @@ -1151,18 +1202,12 @@ impl AtomicPtr { /// * `ptr` must be aligned to `align_of::>()` (note that on some platforms this /// can be bigger than `align_of::<*mut T>()`). /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. - /// * Non-atomic accesses to the value behind `ptr` must have a happens-before relationship - /// with atomic accesses via the returned value (or vice-versa). - /// * In other words, time periods where the value is accessed atomically may not overlap - /// with periods where the value is accessed non-atomically. - /// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the - /// duration of lifetime `'a`. Most use cases should be able to follow this guideline. - /// * This requirement is also trivially satisfied if all accesses (atomic or not) are done - /// from the same thread. - /// * This method should not be used to create overlapping or mixed-size atomic accesses, as - /// these are not supported by the memory model. + /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not + /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, + /// without synchronization. /// /// [valid]: crate::ptr#safety + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")] pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr { @@ -2133,19 +2178,12 @@ macro_rules! atomic_int { `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this \ can be bigger than `align_of::<", stringify!($int_type), ">()`).")] /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. - /// * Non-atomic accesses to the value behind `ptr` must have a happens-before - /// relationship with atomic accesses via the returned value (or vice-versa). - /// * In other words, time periods where the value is accessed atomically may not - /// overlap with periods where the value is accessed non-atomically. - /// * This requirement is trivially satisfied if `ptr` is never used non-atomically - /// for the duration of lifetime `'a`. Most use cases should be able to follow - /// this guideline. - /// * This requirement is also trivially satisfied if all accesses (atomic or not) are - /// done from the same thread. - /// * This method should not be used to create overlapping or mixed-size atomic - /// accesses, as these are not supported by the memory model. + /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not + /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, + /// without synchronization. /// /// [valid]: crate::ptr#safety + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")] pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type { From 769ad29c3ec2c1925a85652254b0368c1fd3f0c5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 8 Nov 2023 11:21:44 +0200 Subject: [PATCH 3/7] triagebot.toml: use inclusive language --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 69bbbdb03bf43..b51a91c7452dc 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -579,7 +579,7 @@ Otherwise, you can ignore this comment. message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x` so tidy will suggest installing the new version." [mentions."src/tools/tidy/src/deps.rs"] -message = "Third-party dependency whitelist may have been modified! You must ensure that any new dependencies have compatible licenses before merging." +message = "Third-party dependency allowlist may have been modified! You must ensure that any new dependencies have compatible licenses before merging." cc = ["@davidtwco", "@wesleywiser"] [mentions."src/bootstrap/src/core/config"] From 03435e6fdd42a6b810e9a0fcbafd89f8935b72fc Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 8 Nov 2023 12:19:32 +0200 Subject: [PATCH 4/7] accept review suggestion Co-authored-by: joboet --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index b51a91c7452dc..4c8c1c59beba4 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -579,7 +579,7 @@ Otherwise, you can ignore this comment. message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x` so tidy will suggest installing the new version." [mentions."src/tools/tidy/src/deps.rs"] -message = "Third-party dependency allowlist may have been modified! You must ensure that any new dependencies have compatible licenses before merging." +message = "The list of allowed third-party dependencies may have been modified! You must ensure that any new dependencies have compatible licenses before merging." cc = ["@davidtwco", "@wesleywiser"] [mentions."src/bootstrap/src/core/config"] From de0458af970adfd768b18bac7cb5a377f837378c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 8 Nov 2023 23:45:31 +0300 Subject: [PATCH 5/7] speed up `x clean` Since `x clean` runs with bootstrap, we can speed up this process by avoiding the cleaning of bootstrap artifacts, as they are not necessarily needed to be cleaned. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/clean.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index 679770ce0ec78..1f0ca2ac5c882 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -139,7 +139,6 @@ fn clean_specific_stage(build: &Build, stage: u32) { fn clean_default(build: &Build) { rm_rf(&build.out.join("tmp")); rm_rf(&build.out.join("dist")); - rm_rf(&build.out.join("bootstrap")); rm_rf(&build.out.join("rustfmt.stamp")); for host in &build.hosts { From 622be2d138e2849e0b9ea9afb2a83f31ba030be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 8 Nov 2023 22:17:27 +0100 Subject: [PATCH 6/7] Restore rustc shim error message --- src/bootstrap/src/bin/rustc.rs | 3 +++ src/bootstrap/src/utils/bin_helpers.rs | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 3041fd37ac80a..e3c010eb49c55 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -32,6 +32,9 @@ fn main() { let args = env::args_os().skip(1).collect::>(); let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); + // We don't use the stage in this shim, but let's parse it to make sure that we're invoked + // by bootstrap, or that we provide a helpful error message if not. + bin_helpers::parse_rustc_stage(); let verbose = bin_helpers::parse_rustc_verbose(); // Detect whether or not we're a build script depending on whether --target diff --git a/src/bootstrap/src/utils/bin_helpers.rs b/src/bootstrap/src/utils/bin_helpers.rs index b9177c490ac28..ab41a6b960025 100644 --- a/src/bootstrap/src/utils/bin_helpers.rs +++ b/src/bootstrap/src/utils/bin_helpers.rs @@ -18,7 +18,6 @@ pub(crate) fn parse_rustc_verbose() -> usize { /// Parses the value of the "RUSTC_STAGE" environment variable and returns it as a `String`. /// /// If "RUSTC_STAGE" was not set, the program will be terminated with 101. -#[allow(unused)] pub(crate) fn parse_rustc_stage() -> String { std::env::var("RUSTC_STAGE").unwrap_or_else(|_| { // Don't panic here; it's reasonable to try and run these shims directly. Give a helpful error instead. From 341c85648c612532d757afb3cafa63ebaa3693db Mon Sep 17 00:00:00 2001 From: John Millikin Date: Wed, 8 Nov 2023 09:12:01 +0900 Subject: [PATCH 7/7] Move `BorrowedBuf` and `BorrowedCursor` from `std:io` to `core::io` Assigned new feature name `core_io_borrowed_buf` to distinguish from the `Read::read_buf` functionality in `std::io`. --- compiler/rustc_span/src/lib.rs | 1 + .../src/io/borrowed_buf.rs} | 19 +------------------ library/core/src/io/mod.rs | 6 ++++++ library/core/src/lib.rs | 2 ++ .../tests/io/borrowed_buf.rs} | 4 ++-- library/core/tests/io/mod.rs | 1 + library/core/tests/lib.rs | 2 ++ library/std/src/io/impls.rs | 14 ++++++++++++++ library/std/src/io/mod.rs | 3 +-- library/std/src/lib.rs | 1 + 10 files changed, 31 insertions(+), 22 deletions(-) rename library/{std/src/io/readbuf.rs => core/src/io/borrowed_buf.rs} (96%) create mode 100644 library/core/src/io/mod.rs rename library/{std/src/io/readbuf/tests.rs => core/tests/io/borrowed_buf.rs} (98%) create mode 100644 library/core/tests/io/mod.rs diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index fc13bdff36f5d..489c8d1892657 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -24,6 +24,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] #![feature(cfg_match)] +#![feature(core_io_borrowed_buf)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(min_specialization)] diff --git a/library/std/src/io/readbuf.rs b/library/core/src/io/borrowed_buf.rs similarity index 96% rename from library/std/src/io/readbuf.rs rename to library/core/src/io/borrowed_buf.rs index 95044de2a09e1..fe25cac280fe3 100644 --- a/library/std/src/io/readbuf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -1,10 +1,6 @@ -#![unstable(feature = "read_buf", issue = "78485")] - -#[cfg(test)] -mod tests; +#![unstable(feature = "core_io_borrowed_buf", issue = "117693")] use crate::fmt::{self, Debug, Formatter}; -use crate::io::{Result, Write}; use crate::mem::{self, MaybeUninit}; use crate::{cmp, ptr}; @@ -303,16 +299,3 @@ impl<'a> BorrowedCursor<'a> { self.buf.filled += buf.len(); } } - -impl<'a> Write for BorrowedCursor<'a> { - fn write(&mut self, buf: &[u8]) -> Result { - let amt = cmp::min(buf.len(), self.capacity()); - self.append(&buf[..amt]); - Ok(amt) - } - - #[inline] - fn flush(&mut self) -> Result<()> { - Ok(()) - } -} diff --git a/library/core/src/io/mod.rs b/library/core/src/io/mod.rs new file mode 100644 index 0000000000000..2f20180cdc9a2 --- /dev/null +++ b/library/core/src/io/mod.rs @@ -0,0 +1,6 @@ +//! Traits, helpers, and type definitions for core I/O functionality. + +mod borrowed_buf; + +#[unstable(feature = "core_io_borrowed_buf", issue = "117693")] +pub use self::borrowed_buf::{BorrowedBuf, BorrowedCursor}; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index de643fb333efe..5a6d242a7298e 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -369,6 +369,8 @@ pub mod async_iter; pub mod cell; pub mod char; pub mod ffi; +#[unstable(feature = "core_io_borrowed_buf", issue = "117693")] +pub mod io; pub mod iter; pub mod net; pub mod option; diff --git a/library/std/src/io/readbuf/tests.rs b/library/core/tests/io/borrowed_buf.rs similarity index 98% rename from library/std/src/io/readbuf/tests.rs rename to library/core/tests/io/borrowed_buf.rs index 89a2f6b2271bd..69511e49acdbc 100644 --- a/library/std/src/io/readbuf/tests.rs +++ b/library/core/tests/io/borrowed_buf.rs @@ -1,5 +1,5 @@ -use super::BorrowedBuf; -use crate::mem::MaybeUninit; +use core::io::BorrowedBuf; +use core::mem::MaybeUninit; /// Test that BorrowedBuf has the correct numbers when created with new #[test] diff --git a/library/core/tests/io/mod.rs b/library/core/tests/io/mod.rs new file mode 100644 index 0000000000000..a24893a525a9d --- /dev/null +++ b/library/core/tests/io/mod.rs @@ -0,0 +1 @@ +mod borrowed_buf; diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index df7b34ce73b42..168b47dc99cc6 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -23,6 +23,7 @@ #![feature(const_likely)] #![feature(const_location_fields)] #![feature(core_intrinsics)] +#![feature(core_io_borrowed_buf)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] @@ -135,6 +136,7 @@ mod fmt; mod future; mod hash; mod intrinsics; +mod io; mod iter; mod lazy; #[cfg(test)] diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index f438325560f54..256b043a60971 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -528,3 +528,17 @@ impl Write for VecDeque { Ok(()) } } + +#[unstable(feature = "read_buf", issue = "78485")] +impl<'a> io::Write for core::io::BorrowedCursor<'a> { + fn write(&mut self, buf: &[u8]) -> io::Result { + let amt = cmp::min(buf.len(), self.capacity()); + self.append(&buf[..amt]); + Ok(amt) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index aa9a2482d2d92..7d70a0bac24fd 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -330,7 +330,7 @@ pub use self::{ }; #[unstable(feature = "read_buf", issue = "78485")] -pub use self::readbuf::{BorrowedBuf, BorrowedCursor}; +pub use core::io::{BorrowedBuf, BorrowedCursor}; pub(crate) use error::const_io_error; mod buffered; @@ -339,7 +339,6 @@ mod cursor; mod error; mod impls; pub mod prelude; -mod readbuf; mod stdio; mod util; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f57c8d4e7e282..425890122577f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -310,6 +310,7 @@ // tidy-alphabetical-start #![feature(char_internals)] #![feature(core_intrinsics)] +#![feature(core_io_borrowed_buf)] #![feature(duration_constants)] #![feature(error_generic_member_access)] #![feature(error_in_core)]