diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 148193b5a97..d0ce209be44 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,6 +1,6 @@ -#![cfg_attr(all(doc, not(bootstrap)), allow(internal_features))] -#![cfg_attr(all(doc, not(bootstrap)), feature(rustdoc_internals))] -#![cfg_attr(all(doc, not(bootstrap)), doc(rust_logo))] +#![cfg_attr(doc, allow(internal_features))] +#![cfg_attr(doc, feature(rustdoc_internals))] +#![cfg_attr(doc, doc(rust_logo))] #![feature(rustc_private)] // Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 3c42eb21d07..a81056ed3ad 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -8,7 +8,6 @@ #![feature(rustdoc_internals)] #![doc(rust_logo)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![cfg_attr(bootstrap, feature(c_str_literals))] #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(hash_raw_entry)] diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs index cafa91c8b8b..f17a0bf26d7 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -81,150 +81,6 @@ /// E::A, /// } /// ``` -#[cfg(bootstrap)] -#[macro_export] -macro_rules! impl_tag { - ( - impl Tag for $Self:ty; - $( - $($path:ident)::* $( { $( $fields:tt )* })?, - )* - ) => { - // Safety: - // `bits_for_tags` is called on the same `${index()}`-es as - // `into_usize` returns, thus `BITS` constant is correct. - unsafe impl $crate::tagged_ptr::Tag for $Self { - const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[ - $( - ${index()}, - $( ${ignore(path)} )* - )* - ]); - - #[inline] - fn into_usize(self) -> usize { - // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc) - // (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>) - #[forbid(unreachable_patterns)] - match self { - // `match` is doing heavy lifting here, by requiring exhaustiveness - $( - $($path)::* $( { $( $fields )* } )? => ${index()}, - )* - } - } - - #[inline] - unsafe fn from_usize(tag: usize) -> Self { - match tag { - $( - ${index()} => $($path)::* $( { $( $fields )* } )?, - )* - - // Safety: - // `into_usize` only returns `${index()}` of the same - // repetition as we are filtering above, thus if this is - // reached, the safety contract of this function was - // already breached. - _ => unsafe { - debug_assert!( - false, - "invalid tag: {tag}\ - (this is a bug in the caller of `from_usize`)" - ); - std::hint::unreachable_unchecked() - }, - } - } - - } - }; -} - -/// Implements [`Tag`] for a given type. -/// -/// You can use `impl_tag` on structs and enums. -/// You need to specify the type and all its possible values, -/// which can only be paths with optional fields. -/// -/// [`Tag`]: crate::tagged_ptr::Tag -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// #![feature(macro_metavar_expr)] -/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag}; -/// -/// #[derive(Copy, Clone, PartialEq, Debug)] -/// enum SomeTag { -/// A, -/// B, -/// X { v: bool }, -/// Y(bool, bool), -/// } -/// -/// impl_tag! { -/// // The type for which the `Tag` will be implemented -/// impl Tag for SomeTag; -/// // You need to specify all possible tag values: -/// SomeTag::A, // 0 -/// SomeTag::B, // 1 -/// // For variants with fields, you need to specify the fields: -/// SomeTag::X { v: true }, // 2 -/// SomeTag::X { v: false }, // 3 -/// // For tuple variants use named syntax: -/// SomeTag::Y { 0: true, 1: true }, // 4 -/// SomeTag::Y { 0: false, 1: true }, // 5 -/// SomeTag::Y { 0: true, 1: false }, // 6 -/// SomeTag::Y { 0: false, 1: false }, // 7 -/// } -/// -/// // Tag values are assigned in order: -/// assert_eq!(SomeTag::A.into_usize(), 0); -/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3); -/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5); -/// -/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B); -/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true }); -/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false)); -/// ``` -/// -/// Structs are supported: -/// -/// ``` -/// #![feature(macro_metavar_expr)] -/// # use rustc_data_structures::impl_tag; -/// #[derive(Copy, Clone)] -/// struct Flags { a: bool, b: bool } -/// -/// impl_tag! { -/// impl Tag for Flags; -/// Flags { a: true, b: true }, -/// Flags { a: false, b: true }, -/// Flags { a: true, b: false }, -/// Flags { a: false, b: false }, -/// } -/// ``` -/// -/// Not specifying all values results in a compile error: -/// -/// ```compile_fail,E0004 -/// #![feature(macro_metavar_expr)] -/// # use rustc_data_structures::impl_tag; -/// #[derive(Copy, Clone)] -/// enum E { -/// A, -/// B, -/// } -/// -/// impl_tag! { -/// impl Tag for E; -/// E::A, -/// } -/// ``` -#[cfg(not(bootstrap))] #[macro_export] macro_rules! impl_tag { ( diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 89caf8aa231..da727ddb208 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -41,132 +41,6 @@ use std::path::PathBuf; use std::rc::Rc; use std::{iter, mem}; -#[cfg(bootstrap)] -macro_rules! ast_fragments { - ( - $($Kind:ident($AstTy:ty) { - $kind_name:expr; - $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? - $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)? - fn $make_ast:ident; - })* - ) => { - /// A fragment of AST that can be produced by a single macro expansion. - /// Can also serve as an input and intermediate result for macro expansion operations. - pub enum AstFragment { - OptExpr(Option<P<ast::Expr>>), - MethodReceiverExpr(P<ast::Expr>), - $($Kind($AstTy),)* - } - - /// "Discriminant" of an AST fragment. - #[derive(Copy, Clone, PartialEq, Eq)] - pub enum AstFragmentKind { - OptExpr, - MethodReceiverExpr, - $($Kind,)* - } - - impl AstFragmentKind { - pub fn name(self) -> &'static str { - match self { - AstFragmentKind::OptExpr => "expression", - AstFragmentKind::MethodReceiverExpr => "expression", - $(AstFragmentKind::$Kind => $kind_name,)* - } - } - - fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> { - match self { - AstFragmentKind::OptExpr => - result.make_expr().map(Some).map(AstFragment::OptExpr), - AstFragmentKind::MethodReceiverExpr => - result.make_expr().map(AstFragment::MethodReceiverExpr), - $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)* - } - } - } - - impl AstFragment { - pub fn add_placeholders(&mut self, placeholders: &[NodeId]) { - if placeholders.is_empty() { - return; - } - match self { - $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| { - ${ignore(flat_map_ast_elt)} - placeholder(AstFragmentKind::$Kind, *id, None).$make_ast() - })),)?)* - _ => panic!("unexpected AST fragment kind") - } - } - - pub fn make_opt_expr(self) -> Option<P<ast::Expr>> { - match self { - AstFragment::OptExpr(expr) => expr, - _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), - } - } - - pub fn make_method_receiver_expr(self) -> P<ast::Expr> { - match self { - AstFragment::MethodReceiverExpr(expr) => expr, - _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), - } - } - - $(pub fn $make_ast(self) -> $AstTy { - match self { - AstFragment::$Kind(ast) => ast, - _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), - } - })* - - fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy { - T::fragment_to_output(self) - } - - pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) { - match self { - AstFragment::OptExpr(opt_expr) => { - visit_clobber(opt_expr, |opt_expr| { - if let Some(expr) = opt_expr { - vis.filter_map_expr(expr) - } else { - None - } - }); - } - AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr), - $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)* - $($(AstFragment::$Kind(ast) => - ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)* - } - } - - pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { - match self { - AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr), - AstFragment::OptExpr(None) => {} - AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr), - $($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)* - $($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] { - visitor.$visit_ast_elt(ast_elt, $($args)*); - })?)* - } - } - } - - impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> { - $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>) - -> Option<$AstTy> { - Some(self.make(AstFragmentKind::$Kind).$make_ast()) - })* - } - } -} - -#[cfg(not(bootstrap))] macro_rules! ast_fragments { ( $($Kind:ident($AstTy:ty) { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a4ab5527e3f..0fc24e88b3b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -39,7 +39,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e048268fad1..3475e582a8f 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -49,7 +49,6 @@ #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(control_flow_enum)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![feature(trusted_step)] #![feature(try_blocks)] #![feature(try_reserve_kind)] diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs index 8a45bd36f7a..a8197332fd0 100644 --- a/library/core/src/async_iter/async_iter.rs +++ b/library/core/src/async_iter/async_iter.rs @@ -13,7 +13,7 @@ use crate::task::{Context, Poll}; #[unstable(feature = "async_iterator", issue = "79024")] #[must_use = "async iterators do nothing unless polled"] #[doc(alias = "Stream")] -#[cfg_attr(not(bootstrap), lang = "async_iterator")] +#[lang = "async_iterator"] pub trait AsyncIterator { /// The type of items yielded by the async iterator. type Item; @@ -116,7 +116,7 @@ impl<T> Poll<Option<T>> { /// A helper function for internal desugaring -- produces `Ready(Some(t))`, /// which corresponds to the async iterator yielding a value. #[unstable(feature = "async_gen_internals", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "AsyncGenReady")] + #[lang = "AsyncGenReady"] pub fn async_gen_ready(t: T) -> Self { Poll::Ready(Some(t)) } @@ -124,13 +124,13 @@ impl<T> Poll<Option<T>> { /// A helper constant for internal desugaring -- produces `Pending`, /// which corresponds to the async iterator pending on an `.await`. #[unstable(feature = "async_gen_internals", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "AsyncGenPending")] + #[lang = "AsyncGenPending"] // FIXME(gen_blocks): This probably could be deduplicated. pub const PENDING: Self = Poll::Pending; /// A helper constant for internal desugaring -- produces `Ready(None)`, /// which corresponds to the async iterator finishing its iteration. #[unstable(feature = "async_gen_internals", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "AsyncGenFinished")] + #[lang = "AsyncGenFinished"] pub const FINISHED: Self = Poll::Ready(None); } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index d7c41ac5c06..bffd3b2af97 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -224,13 +224,13 @@ use self::Ordering::*; append_const_msg )] #[rustc_diagnostic_item = "PartialEq"] -#[cfg_attr(not(bootstrap), const_trait)] +#[const_trait] pub trait PartialEq<Rhs: ?Sized = Self> { /// This method tests for `self` and `other` values to be equal, and is used /// by `==`. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialeq_eq")] + #[rustc_diagnostic_item = "cmp_partialeq_eq"] fn eq(&self, other: &Rhs) -> bool; /// This method tests for `!=`. The default implementation is almost always @@ -238,7 +238,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialeq_ne")] + #[rustc_diagnostic_item = "cmp_partialeq_ne"] fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } @@ -1416,18 +1416,8 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( - #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(bootstrap)] - impl PartialEq for $t { - #[inline] - fn eq(&self, other: &$t) -> bool { (*self) == (*other) } - #[inline] - fn ne(&self, other: &$t) -> bool { (*self) != (*other) } - } - #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - #[cfg(not(bootstrap))] impl const PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 68c8a335b40..0fd27974dce 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -257,7 +257,6 @@ extern "platform-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. - #[cfg(not(bootstrap))] pub fn simd_masked_load<V, U, T>(mask: V, ptr: U, val: T) -> T; /// Write to a vector of pointers. @@ -277,7 +276,6 @@ extern "platform-intrinsic" { /// type). /// /// `mask` must only contain `0` or `!0` values. - #[cfg(not(bootstrap))] pub fn simd_masked_store<V, U, T>(mask: V, ptr: U, val: T); /// Add two simd vectors elementwise, with saturation. diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a444c30c756..12ff64de879 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1772,7 +1772,7 @@ impl<T> *const [T] { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> PartialEq for *const T { #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*const T) -> bool { *self == *other } @@ -1785,7 +1785,7 @@ impl<T: ?Sized> Eq for *const T {} #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Ord for *const T { #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*const T) -> Ordering { if self < other { Less @@ -1805,25 +1805,25 @@ impl<T: ?Sized> PartialOrd for *const T { } #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn lt(&self, other: &*const T) -> bool { *self < *other } #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn le(&self, other: &*const T) -> bool { *self <= *other } #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn gt(&self, other: &*const T) -> bool { *self > *other } #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn ge(&self, other: &*const T) -> bool { *self >= *other } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 390e0737197..a9078854125 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1900,7 +1900,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz #[inline(always)] #[must_use = "pointer comparison produces a value"] #[rustc_diagnostic_item = "ptr_eq"] -#[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] // it's actually clear here +#[allow(ambiguous_wide_pointer_comparisons)] // it's actually clear here pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { a == b } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 9e7b8ec64ac..4f5fca4367d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2199,7 +2199,7 @@ impl<T> *mut [T] { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> PartialEq for *mut T { #[inline(always)] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*mut T) -> bool { *self == *other } @@ -2211,7 +2211,7 @@ impl<T: ?Sized> Eq for *mut T {} #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Ord for *mut T { #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*mut T) -> Ordering { if self < other { Less @@ -2231,25 +2231,25 @@ impl<T: ?Sized> PartialOrd for *mut T { } #[inline(always)] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn lt(&self, other: &*mut T) -> bool { *self < *other } #[inline(always)] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn le(&self, other: &*mut T) -> bool { *self <= *other } #[inline(always)] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn gt(&self, other: &*mut T) -> bool { *self > *other } #[inline(always)] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn ge(&self, other: &*mut T) -> bool { *self >= *other } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 77961506e13..427a9f3f494 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1791,7 +1791,7 @@ impl<T: ?Sized> Eq for NonNull<T> {} #[stable(feature = "nonnull", since = "1.25.0")] impl<T: ?Sized> PartialEq for NonNull<T> { #[inline] - #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] + #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &Self) -> bool { self.as_ptr() == other.as_ptr() } diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 3689312e6ae..e1b77e34f21 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -8,146 +8,6 @@ use crate::marker::{StructuralEq, StructuralPartialEq}; // // Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C) // will implement everything for (A, B, C), (A, B) and (A,). -#[cfg(bootstrap)] -macro_rules! tuple_impls { - // Stopping criteria (1-ary tuple) - ($T:ident) => { - tuple_impls!(@impl $T); - }; - // Running criteria (n-ary tuple, with n >= 2) - ($T:ident $( $U:ident )+) => { - tuple_impls!($( $U )+); - tuple_impls!(@impl $T $( $U )+); - }; - // "Private" internal implementation - (@impl $( $T:ident )+) => { - maybe_tuple_doc! { - $($T)+ @ - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: PartialEq),+> PartialEq for ($($T,)+) - where - last_type!($($T,)+): ?Sized - { - #[inline] - fn eq(&self, other: &($($T,)+)) -> bool { - $( ${ignore(T)} self.${index()} == other.${index()} )&&+ - } - #[inline] - fn ne(&self, other: &($($T,)+)) -> bool { - $( ${ignore(T)} self.${index()} != other.${index()} )||+ - } - } - } - - maybe_tuple_doc! { - $($T)+ @ - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: Eq),+> Eq for ($($T,)+) - where - last_type!($($T,)+): ?Sized - {} - } - - maybe_tuple_doc! { - $($T)+ @ - #[unstable(feature = "structural_match", issue = "31434")] - impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+) {} - } - - maybe_tuple_doc! { - $($T)+ @ - #[unstable(feature = "structural_match", issue = "31434")] - impl<$($T),+> StructuralPartialEq for ($($T,)+) {} - } - - maybe_tuple_doc! { - $($T)+ @ - #[unstable(feature = "structural_match", issue = "31434")] - impl<$($T),+> StructuralEq for ($($T,)+) {} - } - - maybe_tuple_doc! { - $($T)+ @ - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) - where - last_type!($($T,)+): ?Sized - { - #[inline] - fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { - lexical_partial_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - #[inline] - fn lt(&self, other: &($($T,)+)) -> bool { - lexical_ord!(lt, Less, $( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - #[inline] - fn le(&self, other: &($($T,)+)) -> bool { - lexical_ord!(le, Less, $( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - #[inline] - fn ge(&self, other: &($($T,)+)) -> bool { - lexical_ord!(ge, Greater, $( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - #[inline] - fn gt(&self, other: &($($T,)+)) -> bool { - lexical_ord!(gt, Greater, $( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - } - } - - maybe_tuple_doc! { - $($T)+ @ - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: Ord),+> Ord for ($($T,)+) - where - last_type!($($T,)+): ?Sized - { - #[inline] - fn cmp(&self, other: &($($T,)+)) -> Ordering { - lexical_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+) - } - } - } - - maybe_tuple_doc! { - $($T)+ @ - #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: Default),+> Default for ($($T,)+) { - #[inline] - fn default() -> ($($T,)+) { - ($($T::default(),)+) - } - } - } - - #[stable(feature = "array_tuple_conv", since = "1.71.0")] - impl<T> From<[T; ${count(T)}]> for ($(${ignore(T)} T,)+) { - #[inline] - #[allow(non_snake_case)] - fn from(array: [T; ${count(T)}]) -> Self { - let [$($T,)+] = array; - ($($T,)+) - } - } - - #[stable(feature = "array_tuple_conv", since = "1.71.0")] - impl<T> From<($(${ignore(T)} T,)+)> for [T; ${count(T)}] { - #[inline] - #[allow(non_snake_case)] - fn from(tuple: ($(${ignore(T)} T,)+)) -> Self { - let ($($T,)+) = tuple; - [$($T,)+] - } - } - } -} - -// Recursive macro for implementing n-ary tuple functions and operations -// -// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C) -// will implement everything for (A, B, C), (A, B) and (A,). -#[cfg(not(bootstrap))] macro_rules! tuple_impls { // Stopping criteria (1-ary tuple) ($T:ident) => { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index c531117bed5..fabdd4ee25d 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -111,7 +111,6 @@ #![feature(slice_flatten)] #![feature(error_generic_member_access)] #![feature(error_in_core)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![feature(utf8_chunks)] #![feature(is_ascii_octdigit)] #![feature(get_many_mut)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 76081833e05..70b9aab9161 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -308,7 +308,6 @@ // // Library features (core): // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(c_str_literals))] #![feature(char_internals)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 1eb40ab826c..4e9febf0205 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -11,7 +11,6 @@ #![feature(round_ties_even)] #![feature(let_chains)] #![feature(lint_reasons)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] // Configure clippy and other lints #![allow( clippy::collapsible_else_if,