Skip to content
Draft
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_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#![allow(internal_features)]
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
#![cfg_attr(not(bootstrap), feature(forget_trait))]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
Expand Down
37 changes: 37 additions & 0 deletions compiler/rustc_data_structures/src/marker.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::alloc::Allocator;
#[cfg(not(bootstrap))]
use std::marker::Forget;
use std::marker::PointeeSized;

#[diagnostic::on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \
Expand All @@ -25,6 +27,7 @@ macro_rules! impls_dyn_send_neg {
}

// Consistent with `std`
#[cfg(bootstrap)]
impls_dyn_send_neg!(
[std::env::Args]
[std::env::ArgsOs]
Expand All @@ -40,6 +43,22 @@ impls_dyn_send_neg!(
[std::io::StderrLock<'_>]
);

#[cfg(not(bootstrap))]
impls_dyn_send_neg!(
[std::env::Args]
[std::env::ArgsOs]
[*const T where T: ?Sized + ?Forget + PointeeSized]
[*mut T where T: ?Sized + ?Forget + PointeeSized]
[std::ptr::NonNull<T> where T: ?Sized + ?Forget + PointeeSized]
[std::rc::Rc<T, A> where T: ?Sized + ?Forget, A: Allocator]
[std::rc::Weak<T, A> where T: ?Sized + ?Forget, A: Allocator]
[std::sync::MutexGuard<'_, T> where T: ?Sized + ?Forget]
[std::sync::RwLockReadGuard<'_, T> where T: ?Sized + ?Forget]
[std::sync::RwLockWriteGuard<'_, T> where T: ?Sized + ?Forget]
[std::io::StdoutLock<'_>]
[std::io::StderrLock<'_>]
);

#[cfg(any(
unix,
target_os = "hermit",
Expand Down Expand Up @@ -98,6 +117,7 @@ macro_rules! impls_dyn_sync_neg {
}

// Consistent with `std`
#[cfg(bootstrap)]
impls_dyn_sync_neg!(
[std::env::Args]
[std::env::ArgsOs]
Expand All @@ -114,6 +134,23 @@ impls_dyn_sync_neg!(
[std::sync::mpsc::Sender<T> where T]
);

#[cfg(not(bootstrap))]
impls_dyn_sync_neg!(
[std::env::Args]
[std::env::ArgsOs]
[*const T where T: ?Sized + ?Forget + PointeeSized]
[*mut T where T: ?Sized + ?Forget + PointeeSized]
[std::cell::Cell<T> where T: ?Sized + ?Forget ]
[std::cell::RefCell<T> where T: ?Sized + ?Forget ]
[std::cell::UnsafeCell<T> where T: ?Sized + ?Forget ]
[std::ptr::NonNull<T> where T: ?Sized + ?Forget + PointeeSized]
[std::rc::Rc<T, A> where T: ?Sized + ?Forget , A: Allocator]
[std::rc::Weak<T, A> where T: ?Sized + ?Forget , A: Allocator]
[std::cell::OnceCell<T> where T]
[std::sync::mpsc::Receiver<T> where T]
[std::sync::mpsc::Sender<T> where T]
);

#[cfg(any(
unix,
target_os = "hermit",
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::fmuladdf32
| sym::fmuladdf64
| sym::fmuladdf128
| sym::forget
| sym::frem_algebraic
| sym::fsub_algebraic
| sym::is_val_statically_known
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}

/// Adds `experimental_default_bounds` bounds to the supertrait bounds.
/// Sets `experimental_default_bounds` to true on trait super bounds.
pub(crate) fn add_default_super_traits(
&self,
trait_def_id: LocalDefId,
Expand All @@ -243,8 +243,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
) {
assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias);

// Supertraits for auto trait are unsound according to the unstable book:
// https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits
if self.tcx().trait_is_auto(trait_def_id.to_def_id()) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2311,7 +2311,7 @@ options! {
"Use WebAssembly error handling for wasm32-unknown-emscripten"),
enforce_type_length_limit: bool = (false, parse_bool, [TRACKED],
"enforce the type length limit when monomorphizing instances in codegen"),
experimental_default_bounds: bool = (false, parse_bool, [TRACKED],
experimental_default_bounds: bool = (true, parse_bool, [TRACKED],
"enable default bounds for experimental group of auto traits"),
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
"export symbols from executables, as if they were dynamic libraries"),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ symbols! {
Fn,
FnMut,
FnOnce,
Forget,
Formatter,
Forward,
From,
Expand Down
31 changes: 28 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
} else {
let has_non_region_infer = stack.obligation.predicate.has_non_region_infer();
if let Some(candidate) = self.winnow_candidates(has_non_region_infer, candidates) {
let is_default_auto_trait = self
.tcx()
.as_lang_item(stack.obligation.predicate.def_id())
.is_some_and(|lang_item| matches!(lang_item, LangItem::DefaultTrait1));
if let Some(candidate) =
self.winnow_candidates(has_non_region_infer, is_default_auto_trait, candidates)
{
self.filter_reservation_impls(candidate)
} else {
Ok(None)
Expand Down Expand Up @@ -1821,15 +1827,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn winnow_candidates(
&mut self,
has_non_region_infer: bool,
is_default_auto_trait: bool,
mut candidates: Vec<EvaluatedCandidate<'tcx>>,
) -> Option<SelectionCandidate<'tcx>> {
if candidates.len() == 1 {
return Some(candidates.pop().unwrap().candidate);
}

// We prefer `Sized` candidates over everything.
let mut sized_candidates =
candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate));
let mut sized_candidates = candidates.iter().filter(|c| {
matches!(c.candidate, SizedCandidate)
|| (is_default_auto_trait
&& matches!(c.candidate, AutoImplCandidate | ImplCandidate(..)))
});
if let Some(sized_candidate) = sized_candidates.next() {
// There should only ever be a single sized candidate
// as they would otherwise overlap.
Expand Down Expand Up @@ -1874,6 +1884,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
break;
}

if is_default_auto_trait {
// Need to prefer alias-bound over env candidates.
let alias_bound = candidates
.iter()
.filter_map(
|c| if let ProjectionCandidate(i) = c.candidate { Some(i) } else { None },
)
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
match alias_bound {
Some(Some(index)) => return Some(ProjectionCandidate(index)),
Some(None) => {}
None => return None,
}
}

// The next highest priority is for non-global where-bounds. However, while we don't
// prefer global where-clauses here, we do bail with ambiguity when encountering both
// a global and a non-global where-clause.
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ use core::error::{self, Error};
use core::fmt;
use core::future::Future;
use core::hash::{Hash, Hasher};
use core::marker::{Tuple, Unsize};
use core::marker::{Forget, Tuple, Unsize};
use core::mem::{self, SizedTypeProperties};
use core::ops::{
AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut,
Expand Down Expand Up @@ -229,7 +229,7 @@ pub use thin::ThinBox;
// The declaration of the `Box` struct must be kept in sync with the
// compiler or ICEs will happen.
pub struct Box<
T: ?Sized,
T: ?Sized + ?Forget,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
>(Unique<T>, A);

Expand Down Expand Up @@ -1672,7 +1672,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
unsafe impl<#[may_dangle] T: ?Sized + ?Forget, A: Allocator> Drop for Box<T, A> {
#[inline]
fn drop(&mut self) {
// the T in the Box is dropped by the compiler before the destructor is run
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
#![feature(local_waker)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(forget_trait)]
#![feature(panic_internals)]
#![feature(pattern)]
#![feature(pin_coerce_unsized_trait)]
Expand Down
1 change: 1 addition & 0 deletions library/alloctests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(int_format_into)]
#![feature(linked_list_cursors)]
#![feature(map_try_insert)]
#![feature(forget_trait)]
#![feature(pattern)]
#![feature(trusted_len)]
#![feature(try_reserve_kind)]
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use crate::error::Error;
use crate::intrinsics::{unchecked_add, unchecked_mul, unchecked_sub};
use crate::marker::Forget;
use crate::mem::SizedTypeProperties;
use crate::ptr::{Alignment, NonNull};
use crate::{assert_unsafe_precondition, fmt, mem};
Expand All @@ -16,7 +17,7 @@ use crate::{assert_unsafe_precondition, fmt, mem};
//
// * https://github.com/rust-lang/rust/pull/72189
// * https://github.com/rust-lang/rust/pull/79827
const fn size_align<T>() -> (usize, usize) {
const fn size_align<T: ?Forget>() -> (usize, usize) {
(size_of::<T>(), align_of::<T>())
}

Expand Down Expand Up @@ -167,7 +168,7 @@ impl Layout {
#[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]
#[must_use]
#[inline]
pub const fn new<T>() -> Self {
pub const fn new<T: ?Forget>() -> Self {
let (size, align) = size_align::<T>();
// SAFETY: if the type is instantiated, rustc already ensures that its
// layout is valid. Use the unchecked constructor to avoid inserting a
Expand Down Expand Up @@ -217,7 +218,7 @@ impl Layout {
/// [extern type]: ../../unstable-book/language-features/extern-types.html
#[unstable(feature = "layout_for_ptr", issue = "69835")]
#[must_use]
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
pub const unsafe fn for_value_raw<T: ?Sized + ?Forget>(t: *const T) -> Self {
// SAFETY: we pass along the prerequisites of these functions to the caller
let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) };
// SAFETY: see rationale in `new` for why this is using the unsafe variant
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@

#![stable(feature = "rust1", since = "1.0.0")]

use crate::marker::Forget;
use crate::{fmt, hash, intrinsics};

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -854,7 +855,7 @@ impl fmt::Debug for TypeId {
#[must_use]
#[stable(feature = "type_name", since = "1.38.0")]
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
pub const fn type_name<T: ?Sized>() -> &'static str {
pub const fn type_name<T: ?Sized + ?Forget>() -> &'static str {
const { intrinsics::type_name::<T>() }
}

Expand Down
4 changes: 3 additions & 1 deletion library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::fmt;
use crate::hash::{self, Hash};
use crate::intrinsics::transmute_unchecked;
use crate::iter::{UncheckedIterator, repeat_n};
use crate::marker::Forget;
use crate::mem::{self, MaybeUninit};
use crate::ops::{
ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
Expand Down Expand Up @@ -146,6 +147,7 @@ pub fn try_from_fn<R, const N: usize, F>(cb: F) -> ChangeOutputType<R, [R::Outpu
where
F: FnMut(usize) -> R,
R: Try,
R::Output: Forget,
R::Residual: Residual<[R::Output; N]>,
{
let mut array = [const { MaybeUninit::uninit() }; N];
Expand Down Expand Up @@ -582,7 +584,7 @@ impl<T, const N: usize> [T; N] {
#[unstable(feature = "array_try_map", issue = "79711")]
pub fn try_map<R>(self, f: impl FnMut(T) -> R) -> ChangeOutputType<R, [R::Output; N]>
where
R: Try<Residual: Residual<[R::Output; N]>>,
R: Try<Output: Forget, Residual: Residual<[R::Output; N]>>,
{
drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
}
Expand Down
21 changes: 12 additions & 9 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@

use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::{PhantomData, Unsize};
use crate::marker::{Forget, PhantomData, Unsize};
use crate::mem::{self, ManuallyDrop};
use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
use crate::panic::const_panic;
Expand Down Expand Up @@ -310,7 +310,7 @@ pub use once::OnceCell;
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)]
#[rustc_pub_transparent]
pub struct Cell<T: ?Sized> {
pub struct Cell<T: ?Sized + ?Forget> {
value: UnsafeCell<T>,
}

Expand All @@ -323,7 +323,7 @@ unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
// having an explicit negative impl is nice for documentation purposes
// and results in nicer error messages.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Sync for Cell<T> {}
impl<T: ?Sized + ?Forget> !Sync for Cell<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Copy> Clone for Cell<T> {
Expand Down Expand Up @@ -670,7 +670,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
// `self: Cell<&Self>` won't work
// `self: CellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
impl<T: DispatchFromDyn<U> + ?Forget, U: ?Forget> DispatchFromDyn<Cell<U>> for Cell<T> {}

impl<T> Cell<[T]> {
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
Expand Down Expand Up @@ -2273,12 +2273,12 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)]
#[rustc_pub_transparent]
pub struct UnsafeCell<T: ?Sized> {
pub struct UnsafeCell<T: ?Sized + ?Forget> {
value: T,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
impl<T: ?Sized + ?Forget> !Sync for UnsafeCell<T> {}

impl<T> UnsafeCell<T> {
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
Expand Down Expand Up @@ -2543,7 +2543,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
// `self: UnsafeCell<&Self>` won't work
// `self: UnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
impl<T: DispatchFromDyn<U> + ?Forget, U: ?Forget> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}

/// [`UnsafeCell`], but [`Sync`].
///
Expand All @@ -2561,7 +2561,7 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T>
#[repr(transparent)]
#[rustc_diagnostic_item = "SyncUnsafeCell"]
#[rustc_pub_transparent]
pub struct SyncUnsafeCell<T: ?Sized> {
pub struct SyncUnsafeCell<T: ?Sized + ?Forget> {
value: UnsafeCell<T>,
}

Expand Down Expand Up @@ -2651,7 +2651,10 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
// `self: SyncUnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
impl<T: DispatchFromDyn<U> + ?Forget, U: ?Forget> DispatchFromDyn<SyncUnsafeCell<U>>
for SyncUnsafeCell<T>
{
}

#[allow(unused)]
fn assert_coerce_unsized(
Expand Down
Loading