Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #117736

Merged
merged 13 commits into from
Nov 9, 2023
Merged
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
1 change: 1 addition & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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<usize> {
let amt = cmp::min(buf.len(), self.capacity());
self.append(&buf[..amt]);
Ok(amt)
}

#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
6 changes: 6 additions & 0 deletions library/core/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -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};
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
124 changes: 81 additions & 43 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -383,16 +438,12 @@ impl AtomicBool {
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can
/// be bigger than `align_of::<bool>()`).
/// * `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 {
Expand Down Expand Up @@ -1185,18 +1236,12 @@ impl<T> AtomicPtr<T> {
/// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (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<T> {
Expand Down Expand Up @@ -2167,19 +2212,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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod borrowed_buf;
2 changes: 2 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -135,6 +136,7 @@ mod fmt;
mod future;
mod hash;
mod intrinsics;
mod io;
mod iter;
mod lazy;
#[cfg(test)]
Expand Down
14 changes: 14 additions & 0 deletions library/std/src/io/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,3 +528,17 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
Ok(())
}
}

#[unstable(feature = "read_buf", issue = "78485")]
impl<'a> io::Write for core::io::BorrowedCursor<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.capacity());
self.append(&buf[..amt]);
Ok(amt)
}

#[inline]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
3 changes: 1 addition & 2 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -339,7 +339,6 @@ mod cursor;
mod error;
mod impls;
pub mod prelude;
mod readbuf;
mod stdio;
mod util;

Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/src/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ fn main() {
let args = env::args_os().skip(1).collect::<Vec<_>>();
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
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/src/core/build_steps/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/src/utils/bin_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/auto-traits/has-arguments.rs
Original file line number Diff line number Diff line change
@@ -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("");
}
11 changes: 11 additions & 0 deletions tests/ui/auto-traits/has-arguments.stderr
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 1 addition & 1 deletion triagebot.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "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"]
Expand Down
Loading