diff options
43 files changed, 591 insertions, 286 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index d23a7ae72f8..0b2c05482bf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -176,3 +176,27 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser { }) } } + +pub(crate) struct NoCoreParser; + +impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser { + const PATH: &[Symbol] = &[sym::no_core]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore; + const TYPE: AttributeType = AttributeType::CrateLevel; +} + +pub(crate) struct NoStdParser; + +impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser { + const PATH: &[Symbol] = &[sym::no_std]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd; + const TYPE: AttributeType = AttributeType::CrateLevel; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index d2b35090135..b3ab1d3edd6 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -25,8 +25,8 @@ use crate::attributes::codegen_attrs::{ }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ - CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser, - TypeLengthLimitParser, + CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser, + RecursionLimitParser, TypeLengthLimitParser, }; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; @@ -223,8 +223,10 @@ attribute_parsers!( Single<WithoutArgs<MacroEscapeParser>>, Single<WithoutArgs<MarkerParser>>, Single<WithoutArgs<MayDangleParser>>, + Single<WithoutArgs<NoCoreParser>>, Single<WithoutArgs<NoImplicitPreludeParser>>, Single<WithoutArgs<NoMangleParser>>, + Single<WithoutArgs<NoStdParser>>, Single<WithoutArgs<NonExhaustiveParser>>, Single<WithoutArgs<ParenSugarParser>>, Single<WithoutArgs<PassByValueParser>>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index b4c1b61b9b5..ea11a99efbc 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -579,12 +579,18 @@ pub enum AttributeKind { /// Represents `#[naked]` Naked(Span), + /// Represents `#[no_core]` + NoCore(Span), + /// Represents `#[no_implicit_prelude]` NoImplicitPrelude(Span), /// Represents `#[no_mangle]` NoMangle(Span), + /// Represents `#[no_std]` + NoStd(Span), + /// Represents `#[non_exhaustive]` NonExhaustive(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 0e208be3497..55521c15854 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -64,8 +64,10 @@ impl AttributeKind { MoveSizeLimit { .. } => No, MustUse { .. } => Yes, Naked(..) => No, + NoCore(..) => No, NoImplicitPrelude(..) => No, - NoMangle(..) => Yes, // Needed for rustdoc + NoMangle(..) => Yes, // Needed for rustdoc + NoStd(..) => No, NonExhaustive(..) => Yes, // Needed for rustdoc Optimize(..) => No, ParenSugar(..) => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 38a6b4b16c9..2562d2e0b83 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MoveSizeLimit { .. } | AttributeKind::TypeLengthLimit { .. } | AttributeKind::PatternComplexityLimit { .. } + | AttributeKind::NoCore { .. } + | AttributeKind::NoStd { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index c82043f0222..149f5e638b1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::print::{ with_forced_trimmed_paths, }; use rustc_middle::ty::{ - self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, - Upcast, + self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym}; @@ -2316,7 +2316,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cand }) .collect(); - impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref.to_string())); + impl_candidates.sort_by_key(|cand| { + // When suggesting array types, sort them by the length of the array, not lexicographically (#135098) + let len = if let GenericArgKind::Type(ty) = cand.trait_ref.args[0].kind() + && let ty::Array(_, len) = ty.kind() + { + // Deprioritize suggestions for parameterized arrays. + len.try_to_target_usize(self.tcx).unwrap_or(u64::MAX) + } else { + 0 + }; + + (cand.similarity, len, cand.trait_ref.to_string()) + }); let mut impl_candidates: Vec<_> = impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(); impl_candidates.dedup(); diff --git a/library/core/src/any.rs b/library/core/src/any.rs index e7d9763d46e..76ea2d18a82 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -705,7 +705,8 @@ impl dyn Any + Send + Sync { /// std::mem::forget(fake_one_ring); /// } /// ``` -#[derive(Clone, Copy, Eq, PartialOrd, Ord)] +#[derive(Copy, PartialOrd, Ord)] +#[derive_const(Clone, Eq)] #[stable(feature = "rust1", since = "1.0.0")] #[lang = "type_id"] pub struct TypeId { diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs index 1ad2cca64a3..c2c7ccf0daa 100644 --- a/library/core/src/array/equality.rs +++ b/library/core/src/array/equality.rs @@ -1,9 +1,10 @@ use crate::cmp::BytewiseEq; #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<[U; N]> for [T; N] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<[U; N]> for [T; N] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &[U; N]) -> bool { @@ -16,9 +17,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<[U]> for [T; N] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<[U]> for [T; N] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &[U]) -> bool { @@ -37,9 +39,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<[U; N]> for [T] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<[U; N]> for [T] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &[U; N]) -> bool { @@ -58,9 +61,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<&[U]> for [T; N] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<&[U]> for [T; N] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &&[U]) -> bool { @@ -73,9 +77,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<[U; N]> for &[T] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<[U; N]> for &[T] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &[U; N]) -> bool { @@ -88,9 +93,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<&mut [U]> for [T; N] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<&mut [U]> for [T; N] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &&mut [U]) -> bool { @@ -103,9 +109,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, const N: usize> PartialEq<[U; N]> for &mut [T] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T, U, const N: usize> const PartialEq<[U; N]> for &mut [T] where - T: PartialEq<U>, + T: [const] PartialEq<U>, { #[inline] fn eq(&self, other: &[U; N]) -> bool { @@ -122,14 +129,18 @@ where // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Eq, const N: usize> Eq for [T; N] {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Eq, const N: usize> const Eq for [T; N] {} +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] trait SpecArrayEq<Other, const N: usize>: Sized { fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool; fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool; } -impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] PartialEq<Other>, Other, const N: usize> const SpecArrayEq<Other, N> for T { default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool { a[..] == b[..] } @@ -138,7 +149,8 @@ impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T { } } -impl<T: BytewiseEq<U>, U, const N: usize> SpecArrayEq<U, N> for T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] BytewiseEq<U>, U, const N: usize> const SpecArrayEq<U, N> for T { fn spec_eq(a: &[T; N], b: &[U; N]) -> bool { // SAFETY: Arrays are compared element-wise, and don't add any padding // between elements, so when the elements are `BytewiseEq`, we can diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index 49d540314a2..178af2c0e3b 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -54,7 +54,8 @@ use crate::{assert_unsafe_precondition, fmt}; /// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf /// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf /// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Copy, Hash)] +#[derive_const(Clone, Eq, PartialEq, Ord, PartialOrd)] #[unstable(feature = "ascii_char", issue = "110998")] #[repr(u8)] pub enum AsciiChar { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 0812322f3fb..94536f25b41 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,7 +29,7 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; use self::Ordering::*; -use crate::marker::PointeeSized; +use crate::marker::{Destruct, PointeeSized}; use crate::ops::ControlFlow; /// Trait for comparisons using the equality operator. @@ -334,7 +334,9 @@ pub macro PartialEq($item:item) { #[doc(alias = "!=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Eq"] -pub trait Eq: PartialEq<Self> + PointeeSized { +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub trait Eq: [const] PartialEq<Self> + PointeeSized { // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a // type implements `Eq` itself. The current deriving infrastructure means doing this assertion // without using a method on this trait is nearly impossible. @@ -380,8 +382,8 @@ pub struct AssertParamIsEq<T: Eq + PointeeSized> { /// /// assert_eq!(2.cmp(&1), Ordering::Greater); /// ``` -#[derive(Clone, Copy, Eq, PartialOrd, Ord, Debug, Hash)] -#[derive_const(PartialEq)] +#[derive(Copy, Debug, Hash)] +#[derive_const(Clone, Eq, PartialOrd, Ord, PartialEq)] #[stable(feature = "rust1", since = "1.0.0")] // This is a lang item only so that `BinOp::Cmp` in MIR can return it. // It has no special behavior, but does require that the three variants @@ -635,7 +637,11 @@ impl Ordering { #[inline] #[must_use] #[stable(feature = "ordering_chaining", since = "1.17.0")] - pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + pub const fn then_with<F>(self, f: F) -> Ordering + where + F: [const] FnOnce() -> Ordering + [const] Destruct, + { match self { Equal => f(), _ => self, @@ -659,13 +665,15 @@ impl Ordering { /// v.sort_by_key(|&num| (num > 3, Reverse(num))); /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]); /// ``` -#[derive(PartialEq, Eq, Debug, Copy, Default, Hash)] +#[derive(Copy, Debug, Hash)] +#[derive_const(PartialEq, Eq, Default)] #[stable(feature = "reverse_cmp_key", since = "1.19.0")] #[repr(transparent)] pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T); #[stable(feature = "reverse_cmp_key", since = "1.19.0")] -impl<T: PartialOrd> PartialOrd for Reverse<T> { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] PartialOrd> const PartialOrd for Reverse<T> { #[inline] fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> { other.0.partial_cmp(&self.0) @@ -690,7 +698,8 @@ impl<T: PartialOrd> PartialOrd for Reverse<T> { } #[stable(feature = "reverse_cmp_key", since = "1.19.0")] -impl<T: Ord> Ord for Reverse<T> { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Ord> const Ord for Reverse<T> { #[inline] fn cmp(&self, other: &Reverse<T>) -> Ordering { other.0.cmp(&self.0) @@ -957,7 +966,9 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized { /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression @@ -1011,7 +1022,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { #[rustc_diagnostic_item = "cmp_ord_max"] fn max(self, other: Self) -> Self where - Self: Sized, + Self: Sized + [const] Destruct, { if other < self { self } else { other } } @@ -1050,7 +1061,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { #[rustc_diagnostic_item = "cmp_ord_min"] fn min(self, other: Self) -> Self where - Self: Sized, + Self: Sized + [const] Destruct, { if other < self { other } else { self } } @@ -1076,7 +1087,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { #[stable(feature = "clamp", since = "1.50.0")] fn clamp(self, min: Self, max: Self) -> Self where - Self: Sized, + Self: Sized + [const] Destruct, { assert!(min <= max); if self < min { @@ -1341,6 +1352,8 @@ pub macro Ord($item:item) { )] #[rustc_diagnostic_item = "PartialOrd"] #[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized { /// This method returns an ordering between `self` and `other` values if one exists. /// @@ -1481,13 +1494,14 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized { } } -fn default_chaining_impl<T, U>( +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +const fn default_chaining_impl<T, U>( lhs: &T, rhs: &U, - p: impl FnOnce(Ordering) -> bool, + p: impl [const] FnOnce(Ordering) -> bool + [const] Destruct, ) -> ControlFlow<bool> where - T: PartialOrd<U> + PointeeSized, + T: [const] PartialOrd<U> + PointeeSized, U: PointeeSized, { // It's important that this only call `partial_cmp` once, not call `eq` then @@ -1545,7 +1559,8 @@ pub macro PartialOrd($item:item) { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_min"] -pub fn min<T: Ord>(v1: T, v2: T) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn min<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T { v1.min(v2) } @@ -1575,7 +1590,12 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn min_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>( + v1: T, + v2: T, + compare: F, +) -> T { if compare(&v1, &v2).is_le() { v1 } else { v2 } } @@ -1600,7 +1620,13 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn min_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T +where + T: [const] Destruct, + F: [const] FnMut(&T) -> K + [const] Destruct, + K: [const] Ord + [const] Destruct, +{ if f(&v2) < f(&v1) { v2 } else { v1 } } @@ -1640,7 +1666,8 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_max"] -pub fn max<T: Ord>(v1: T, v2: T) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn max<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T { v1.max(v2) } @@ -1670,7 +1697,12 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn max_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>( + v1: T, + v2: T, + compare: F, +) -> T { if compare(&v1, &v2).is_gt() { v1 } else { v2 } } @@ -1695,7 +1727,13 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn max_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T +where + T: [const] Destruct, + F: [const] FnMut(&T) -> K + [const] Destruct, + K: [const] Ord + [const] Destruct, +{ if f(&v2) < f(&v1) { v1 } else { v2 } } @@ -1739,9 +1777,10 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { #[inline] #[must_use] #[unstable(feature = "cmp_minmax", issue = "115939")] -pub fn minmax<T>(v1: T, v2: T) -> [T; 2] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn minmax<T>(v1: T, v2: T) -> [T; 2] where - T: Ord, + T: [const] Ord, { if v2 < v1 { [v2, v1] } else { [v1, v2] } } @@ -1773,9 +1812,10 @@ where #[inline] #[must_use] #[unstable(feature = "cmp_minmax", issue = "115939")] -pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2] where - F: FnOnce(&T, &T) -> Ordering, + F: [const] FnOnce(&T, &T) -> Ordering, { if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] } } @@ -1801,10 +1841,11 @@ where #[inline] #[must_use] #[unstable(feature = "cmp_minmax", issue = "115939")] -pub fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +pub const fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2] where - F: FnMut(&T) -> K, - K: Ord, + F: [const] FnMut(&T) -> K + [const] Destruct, + K: [const] Ord + [const] Destruct, { if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] } } @@ -1830,7 +1871,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialEq for () { #[inline] fn eq(&self, _other: &()) -> bool { true @@ -1848,7 +1890,8 @@ mod impls { macro_rules! eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Eq for $t {} + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Eq for $t {} )*) } @@ -1896,7 +1939,8 @@ mod impls { macro_rules! partial_ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &Self) -> Option<Ordering> { match (*self <= *other, *self >= *other) { @@ -1913,7 +1957,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option<Ordering> { Some(Equal) @@ -1921,7 +1966,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for bool { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option<Ordering> { Some(self.cmp(other)) @@ -1935,7 +1981,8 @@ mod impls { macro_rules! ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(crate::intrinsics::three_way_compare(*self, *other)) @@ -1945,7 +1992,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for $t { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Ord for $t { #[inline] fn cmp(&self, other: &Self) -> Ordering { crate::intrinsics::three_way_compare(*self, *other) @@ -1955,7 +2003,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for () { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Ord for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal @@ -1963,7 +2012,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for bool { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { // Casting to i8's and converting the difference to an Ordering generates @@ -1998,7 +2048,8 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[unstable(feature = "never_type", issue = "35121")] - impl PartialEq for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialEq for ! { #[inline] fn eq(&self, _: &!) -> bool { *self @@ -2006,10 +2057,12 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - impl Eq for ! {} + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Eq for ! {} #[unstable(feature = "never_type", issue = "35121")] - impl PartialOrd for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const PartialOrd for ! { #[inline] fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self @@ -2017,7 +2070,8 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - impl Ord for ! { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl const Ord for ! { #[inline] fn cmp(&self, _: &!) -> Ordering { *self @@ -2042,9 +2096,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized, B: PointeeSized> PartialOrd<&B> for &A + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&B> for &A where - A: PartialOrd<B>, + A: [const] PartialOrd<B>, { #[inline] fn partial_cmp(&self, other: &&B) -> Option<Ordering> { @@ -2084,9 +2139,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized> Ord for &A + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized> const Ord for &A where - A: Ord, + A: [const] Ord, { #[inline] fn cmp(&self, other: &Self) -> Ordering { @@ -2094,7 +2150,8 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized> Eq for &A where A: Eq {} + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized> const Eq for &A where A: [const] Eq {} // &mut pointers @@ -2114,9 +2171,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized, B: PointeeSized> PartialOrd<&mut B> for &mut A + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&mut B> for &mut A where - A: PartialOrd<B>, + A: [const] PartialOrd<B>, { #[inline] fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> { @@ -2156,9 +2214,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized> Ord for &mut A + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized> const Ord for &mut A where - A: Ord, + A: [const] Ord, { #[inline] fn cmp(&self, other: &Self) -> Ordering { @@ -2166,7 +2225,8 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: PointeeSized> Eq for &mut A where A: Eq {} + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<A: PointeeSized> const Eq for &mut A where A: [const] Eq {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index a3cfd85974a..89cda30c030 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -963,17 +963,20 @@ impl const PartialEq for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -impl Eq for Infallible {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Eq for Infallible {} #[stable(feature = "convert_infallible", since = "1.34.0")] -impl PartialOrd for Infallible { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const PartialOrd for Infallible { fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> { match *self {} } } #[stable(feature = "convert_infallible", since = "1.34.0")] -impl Ord for Infallible { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Ord for Infallible { fn cmp(&self, _other: &Self) -> crate::cmp::Ordering { match *self {} } diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 0f38081c355..1b7c28bb95a 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -4,7 +4,7 @@ use super::{IntErrorKind, ParseIntError}; use crate::clone::UseCloned; use crate::cmp::Ordering; use crate::hash::{Hash, Hasher}; -use crate::marker::{Freeze, StructuralPartialEq}; +use crate::marker::{Destruct, Freeze, StructuralPartialEq}; use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign}; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::str::FromStr; @@ -220,12 +220,14 @@ where impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {} #[stable(feature = "nonzero", since = "1.28.0")] -impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T> const Eq for NonZero<T> where T: ZeroablePrimitive + [const] Eq {} #[stable(feature = "nonzero", since = "1.28.0")] -impl<T> PartialOrd for NonZero<T> +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T> const PartialOrd for NonZero<T> where - T: ZeroablePrimitive + PartialOrd, + T: ZeroablePrimitive + [const] PartialOrd, { #[inline] fn partial_cmp(&self, other: &Self) -> Option<Ordering> { @@ -254,9 +256,12 @@ where } #[stable(feature = "nonzero", since = "1.28.0")] -impl<T> Ord for NonZero<T> +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T> const Ord for NonZero<T> where - T: ZeroablePrimitive + Ord, + // FIXME(const_hack): the T: ~const Destruct should be inferred from the Self: ~const Destruct. + // See https://github.com/rust-lang/rust/issues/144207 + T: ZeroablePrimitive + [const] Ord + [const] Destruct, { #[inline] fn cmp(&self, other: &Self) -> Ordering { diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 73b74d53323..b760a7c4e21 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -83,7 +83,8 @@ use crate::{convert, ops}; #[must_use] // ControlFlow should not implement PartialOrd or Ord, per RFC 3058: // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Copy, Debug, Hash)] +#[derive_const(Clone, PartialEq, Eq)] pub enum ControlFlow<B, C = ()> { /// Move on to the next phase of the operation as normal. #[stable(feature = "control_flow_enum_type", since = "1.55.0")] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 198636c67d0..886d581b0a6 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -585,7 +585,8 @@ use crate::{cmp, convert, hint, mem, slice}; /// The `Option` type. See [the module level documentation](self) for more. #[doc(search_unbox)] -#[derive(Copy, Eq, Debug, Hash)] +#[derive(Copy, Debug, Hash)] +#[derive_const(Eq)] #[rustc_diagnostic_item = "Option"] #[lang = "Option"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2363,7 +2364,8 @@ impl<T: [const] PartialEq> const PartialEq for Option<T> { // https://github.com/rust-lang/rust/issues/49892, although still // not optimal. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialOrd> PartialOrd for Option<T> { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] PartialOrd> const PartialOrd for Option<T> { #[inline] fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { match (self, other) { @@ -2376,7 +2378,8 @@ impl<T: PartialOrd> PartialOrd for Option<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Ord> Ord for Option<T> { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Ord> const Ord for Option<T> { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { match (self, other) { diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 8c49123fdaf..a096a8ceafc 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -49,7 +49,8 @@ pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, R /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum()); /// ``` #[lang = "RangeCopy"] -#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Hash)] +#[derive_const(Clone, Default, PartialEq, Eq)] #[unstable(feature = "new_range_api", issue = "125687")] pub struct Range<Idx> { /// The lower bound of the range (inclusive). @@ -424,7 +425,8 @@ impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> { /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum()); /// ``` #[lang = "RangeFromCopy"] -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Copy, Hash)] +#[derive_const(Clone, PartialEq, Eq)] #[unstable(feature = "new_range_api", issue = "125687")] pub struct RangeFrom<Idx> { /// The lower bound of the range (inclusive). diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 7dffab9b316..5c1f64bfe14 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -542,7 +542,8 @@ use crate::{convert, fmt, hint}; /// /// See the [module documentation](self) for details. #[doc(search_unbox)] -#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[derive(Copy, Debug, Hash)] +#[derive_const(PartialEq, PartialOrd, Eq, Ord)] #[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[rustc_diagnostic_item = "Result"] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 0d801306984..103630aba0f 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -23,7 +23,8 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Eq> Eq for [T] {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<T: [const] Eq> const Eq for [T] {} /// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] @@ -34,7 +35,7 @@ impl<T: Ord> Ord for [T] { } #[inline] -fn as_underlying(x: ControlFlow<bool>) -> u8 { +const fn as_underlying(x: ControlFlow<bool>) -> u8 { // SAFETY: This will only compile if `bool` and `ControlFlow<bool>` have the same // size (which isn't guaranteed but this is libcore). Because they have the same // size, it's a niched implementation, which in one byte means there can't be @@ -154,12 +155,16 @@ where } #[doc(hidden)] +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's PartialOrd trait SlicePartialOrd: Sized { fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>; } #[doc(hidden)] +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's PartialOrd chaining methods trait SliceChain: Sized { fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool>; @@ -231,14 +236,17 @@ where } */ -impl<A: AlwaysApplicableOrd> SlicePartialOrd for A { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] AlwaysApplicableOrd> const SlicePartialOrd for A { fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> { Some(SliceOrd::compare(left, right)) } } #[rustc_specialization_trait] -trait AlwaysApplicableOrd: SliceOrd + Ord {} +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +trait AlwaysApplicableOrd: [const] SliceOrd + [const] Ord {} macro_rules! always_applicable_ord { ($([$($p:tt)*] $t:ty,)*) => { @@ -257,6 +265,8 @@ always_applicable_ord! { } #[doc(hidden)] +#[const_trait] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] // intermediate trait for specialization of slice's Ord trait SliceOrd: Sized { fn compare(left: &[Self], right: &[Self]) -> Ordering; @@ -282,17 +292,24 @@ impl<A: Ord> SliceOrd for A { /// * For every `x` and `y` of this type, `Ord(x, y)` must return the same /// value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`. #[rustc_specialization_trait] -unsafe trait UnsignedBytewiseOrd: Ord {} +#[const_trait] +unsafe trait UnsignedBytewiseOrd: [const] Ord {} -unsafe impl UnsignedBytewiseOrd for bool {} -unsafe impl UnsignedBytewiseOrd for u8 {} -unsafe impl UnsignedBytewiseOrd for NonZero<u8> {} -unsafe impl UnsignedBytewiseOrd for Option<NonZero<u8>> {} -unsafe impl UnsignedBytewiseOrd for ascii::Char {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +unsafe impl const UnsignedBytewiseOrd for bool {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +unsafe impl const UnsignedBytewiseOrd for u8 {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +unsafe impl const UnsignedBytewiseOrd for NonZero<u8> {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +unsafe impl const UnsignedBytewiseOrd for Option<NonZero<u8>> {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +unsafe impl const UnsignedBytewiseOrd for ascii::Char {} // `compare_bytes` compares a sequence of unsigned bytes lexicographically, so // use it if the requirements for `UnsignedBytewiseOrd` are fulfilled. -impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] Ord + [const] UnsignedBytewiseOrd> const SliceOrd for A { #[inline] fn compare(left: &[Self], right: &[Self]) -> Ordering { // Since the length of a slice is always less than or equal to @@ -317,7 +334,9 @@ impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A { } // Don't generate our own chaining loops for `memcmp`-able things either. -impl<A: PartialOrd + UnsignedBytewiseOrd> SliceChain for A { + +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl<A: [const] PartialOrd + [const] UnsignedBytewiseOrd> const SliceChain for A { #[inline] fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool> { match SliceOrd::compare(left, right) { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 5adae62b7e6..a7cc943994c 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -32,7 +32,8 @@ impl const PartialEq for str { } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for str {} +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Eq for str {} /// Implements comparison operations on strings. /// diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 2cdee1803a9..3892f831076 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -23,7 +23,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: PartialEq),+> PartialEq for ($($T,)+) { + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<$($T: [const] PartialEq),+> const PartialEq for ($($T,)+) { #[inline] fn eq(&self, other: &($($T,)+)) -> bool { $( ${ignore($T)} self.${index()} == other.${index()} )&&+ @@ -38,7 +39,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: Eq),+> Eq for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<$($T: [const] Eq),+> const Eq for ($($T,)+) {} } @@ -66,7 +68,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<$($T: [const] PartialOrd),+> const PartialOrd for ($($T,)+) { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { @@ -110,7 +113,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T: Ord),+> Ord for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + impl<$($T: [const] Ord),+> const Ord for ($($T,)+) { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs index 72fdf82c1f8..a4af6fd32a1 100644 --- a/library/coretests/tests/alloc.rs +++ b/library/coretests/tests/alloc.rs @@ -56,6 +56,30 @@ fn layout_array_edge_cases() { } #[test] +fn layout_errors() { + let layout = Layout::new::<[u8; 2]>(); + // Should error if the alignment is not a power of two. + assert!(layout.align_to(3).is_err()); + + // The remaining assertions ensure that the methods error on arithmetic overflow as the + // alignment cannot overflow `isize`. + let size = layout.size(); + let size_max = isize::MAX as usize; + let align_max = size_max / size; + + assert!(layout.align_to(size_max + 1).is_err()); + + assert!(layout.repeat(align_max).is_ok()); + assert!(layout.repeat(align_max + 1).is_err()); + + assert!(layout.repeat_packed(align_max).is_ok()); + assert!(layout.repeat_packed(align_max + 1).is_err()); + + let next = Layout::from_size_align(size_max, 1).unwrap(); + assert!(layout.extend(next).is_err()); +} + +#[test] fn layout_debug_shows_log2_of_alignment() { // `Debug` is not stable, but here's what it does right now let layout = Layout::from_size_align(24576, 8192).unwrap(); diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index 852f073bae1..6f94065b2d9 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs @@ -220,6 +220,7 @@ fn test_escape_default() { } assert_eq!(string('\n'), "\\n"); assert_eq!(string('\r'), "\\r"); + assert_eq!(string('\t'), "\\t"); assert_eq!(string('\''), "\\'"); assert_eq!(string('"'), "\\\""); assert_eq!(string(' '), " "); @@ -417,3 +418,45 @@ fn eu_iterator_specializations() { check('\u{12340}'); check('\u{10FFFF}'); } + +#[test] +#[should_panic] +fn test_from_digit_radix_too_high() { + let _ = char::from_digit(0, 37); +} + +#[test] +fn test_from_digit_invalid_radix() { + assert!(char::from_digit(10, 9).is_none()); +} + +#[test] +#[should_panic] +fn test_to_digit_radix_too_low() { + let _ = 'a'.to_digit(1); +} + +#[test] +#[should_panic] +fn test_to_digit_radix_too_high() { + let _ = 'a'.to_digit(37); +} + +#[test] +fn test_as_ascii_invalid() { + assert!('❤'.as_ascii().is_none()); +} + +#[test] +#[should_panic] +fn test_encode_utf8_raw_buffer_too_small() { + let mut buf = [0u8; 1]; + let _ = char::encode_utf8_raw('ß'.into(), &mut buf); +} + +#[test] +#[should_panic] +fn test_encode_utf16_raw_buffer_too_small() { + let mut buf = [0u16; 1]; + let _ = char::encode_utf16_raw('𐐷'.into(), &mut buf); +} diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs index 6c4e2146f91..55e35a4a725 100644 --- a/library/coretests/tests/cmp.rs +++ b/library/coretests/tests/cmp.rs @@ -215,19 +215,18 @@ fn cmp_default() { assert_eq!(Fool(false), Fool(true)); } -/* FIXME(#110395) mod const_cmp { use super::*; struct S(i32); - impl PartialEq for S { + impl const PartialEq for S { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } - impl PartialOrd for S { + impl const PartialOrd for S { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let ret = match (self.0, other.0) { (a, b) if a > b => Ordering::Greater, @@ -247,4 +246,3 @@ mod const_cmp { const _: () = assert!(S(0) < S(1)); const _: () = assert!(S(1) > S(0)); } -*/ diff --git a/library/coretests/tests/hash/mod.rs b/library/coretests/tests/hash/mod.rs index 1f10a4733b0..043a3ee7423 100644 --- a/library/coretests/tests/hash/mod.rs +++ b/library/coretests/tests/hash/mod.rs @@ -53,12 +53,14 @@ fn test_writer_hasher() { assert_eq!(hash(&5_u16), 5); assert_eq!(hash(&5_u32), 5); assert_eq!(hash(&5_u64), 5); + assert_eq!(hash(&5_u128), 5); assert_eq!(hash(&5_usize), 5); assert_eq!(hash(&5_i8), 5); assert_eq!(hash(&5_i16), 5); assert_eq!(hash(&5_i32), 5); assert_eq!(hash(&5_i64), 5); + assert_eq!(hash(&5_i128), 5); assert_eq!(hash(&5_isize), 5); assert_eq!(hash(&false), 0); @@ -85,6 +87,17 @@ fn test_writer_hasher() { let ptr = ptr::without_provenance_mut::<i32>(5_usize); assert_eq!(hash(&ptr), 5); + // Use a newtype to test the `Hash::hash_slice` default implementation. + struct Byte(u8); + + impl Hash for Byte { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u8(self.0) + } + } + + assert_eq!(hash(&[Byte(b'a')]), 97 + 1); + if cfg!(miri) { // Miri cannot hash pointers return; diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1bdaa6965f6..a246c806140 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,8 +13,10 @@ #![feature(bool_to_result)] #![feature(bstr)] #![feature(cfg_target_has_reliable_f16_f128)] +#![feature(char_internals)] #![feature(char_max_len)] #![feature(clone_to_uninit)] +#![feature(const_cmp)] #![feature(const_convert)] #![feature(const_destruct)] #![feature(const_eval_select)] diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 0b75e85772f..1458b0beefa 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1383,14 +1383,17 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS } } - // Build jemalloc on AArch64 with support for page sizes up to 64K - // See: https://github.com/rust-lang/rust/pull/135081 // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the tool build step. - if builder.config.jemalloc(target) - && target.starts_with("aarch64") - && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() - { - cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16"); + if builder.config.jemalloc(target) && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() { + // Build jemalloc on AArch64 with support for page sizes up to 64K + // See: https://github.com/rust-lang/rust/pull/135081 + if target.starts_with("aarch64") { + cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16"); + } + // Build jemalloc on LoongArch with support for page sizes up to 16K + else if target.starts_with("loongarch") { + cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14"); + } } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 6870bf3eddc..dcc4898cae1 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -228,12 +228,18 @@ pub fn prepare_tool_cargo( // own copy cargo.env("LZMA_API_STATIC", "1"); - // Build jemalloc on AArch64 with support for page sizes up to 64K - // See: https://github.com/rust-lang/rust/pull/135081 // Note that `miri` always uses jemalloc. As such, there is no checking of the jemalloc build flag. // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the compile build step. - if target.starts_with("aarch64") && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() { - cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16"); + if env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() { + // Build jemalloc on AArch64 with support for page sizes up to 64K + // See: https://github.com/rust-lang/rust/pull/135081 + if target.starts_with("aarch64") { + cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16"); + } + // Build jemalloc on LoongArch with support for page sizes up to 16K + else if target.starts_with("loongarch") { + cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14"); + } } // CFG_RELEASE is needed by rustfmt (and possibly other tools) which diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 14b64eb4d54..e1077bdf4b1 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2133,17 +2133,11 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { } pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { - cx.tcx - .hir_attrs(hir::CRATE_HIR_ID) - .iter() - .any(|attr| attr.has_name(sym::no_std)) + find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoStd(..)) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { - cx.tcx - .hir_attrs(hir::CRATE_HIR_ID) - .iter() - .any(|attr| attr.has_name(sym::no_core)) + find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoCore(..)) } /// Check if parent of a hir node is a trait implementation block. diff --git a/tests/ui/attributes/malformed-no-std.rs b/tests/ui/attributes/malformed-no-std.rs new file mode 100644 index 00000000000..528ecb549b0 --- /dev/null +++ b/tests/ui/attributes/malformed-no-std.rs @@ -0,0 +1,25 @@ +#![feature(no_core)] +// these all still apply no_std and then later error +#![no_std = "foo"] +//~^ ERROR malformed `no_std` attribute input +#![no_std("bar")] +//~^ ERROR malformed `no_std` attribute input +#![no_std(foo = "bar")] +//~^ ERROR malformed `no_std` attribute input +#![no_core = "foo"] +//~^ ERROR malformed `no_core` attribute input +#![no_core("bar")] +//~^ ERROR malformed `no_core` attribute input +#![no_core(foo = "bar")] +//~^ ERROR malformed `no_core` attribute input + +#[deny(unused_attributes)] +#[no_std] +//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark: +#[no_core] +//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark: +// to fix compilation +extern crate core; +extern crate std; + +fn main() {} diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr new file mode 100644 index 00000000000..322d5f03e41 --- /dev/null +++ b/tests/ui/attributes/malformed-no-std.stderr @@ -0,0 +1,86 @@ +error[E0565]: malformed `no_std` attribute input + --> $DIR/malformed-no-std.rs:3:1 + | +LL | #![no_std = "foo"] + | ^^^^^^^^^^-------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_std]` + +error[E0565]: malformed `no_std` attribute input + --> $DIR/malformed-no-std.rs:5:1 + | +LL | #![no_std("bar")] + | ^^^^^^^^^-------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_std]` + +error[E0565]: malformed `no_std` attribute input + --> $DIR/malformed-no-std.rs:7:1 + | +LL | #![no_std(foo = "bar")] + | ^^^^^^^^^-------------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_std]` + +error[E0565]: malformed `no_core` attribute input + --> $DIR/malformed-no-std.rs:9:1 + | +LL | #![no_core = "foo"] + | ^^^^^^^^^^^-------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_core]` + +error[E0565]: malformed `no_core` attribute input + --> $DIR/malformed-no-std.rs:11:1 + | +LL | #![no_core("bar")] + | ^^^^^^^^^^-------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_core]` + +error[E0565]: malformed `no_core` attribute input + --> $DIR/malformed-no-std.rs:13:1 + | +LL | #![no_core(foo = "bar")] + | ^^^^^^^^^^-------------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#![no_core]` + +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/malformed-no-std.rs:17:1 + | +LL | #[no_std] + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this extern crate + --> $DIR/malformed-no-std.rs:22:1 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/malformed-no-std.rs:16:8 + | +LL | #[deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_core]` + --> $DIR/malformed-no-std.rs:19:1 + | +LL | #[no_core] + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this extern crate + --> $DIR/malformed-no-std.rs:22:1 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index ff44876c5c4..dc0701d3b1d 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -9,8 +9,7 @@ fn main() { assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); assert!(TypeId::of::<()>() != TypeId::of::<u8>()); let _a = TypeId::of::<u8>() < TypeId::of::<u16>(); - //~^ ERROR: cannot call non-const operator in constants - // can't assert `_a` because it is not deterministic - // FIXME(const_trait_impl) make it pass + //~^ ERROR: the trait bound `TypeId: const PartialOrd` is not satisfied + // FIXME(const_trait_impl) make it pass; requires const comparison of pointers (#53020) } } diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr index 05b94caef79..62a1677c0d9 100644 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -1,13 +1,9 @@ -error[E0015]: cannot call non-const operator in constants +error[E0277]: the trait bound `TypeId: const PartialOrd` is not satisfied --> $DIR/const_cmp_type_id.rs:11:18 | LL | let _a = TypeId::of::<u8>() < TypeId::of::<u16>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs index e475c0a1b6f..e4a62e18c7b 100644 --- a/tests/ui/consts/fn_trait_refs.rs +++ b/tests/ui/consts/fn_trait_refs.rs @@ -1,6 +1,5 @@ -//@ known-bug: #110395 +//@ check-pass -#![feature(const_fn_trait_ref_impls)] #![feature(fn_traits)] #![feature(unboxed_closures)] #![feature(const_trait_impl)] diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr deleted file mode 100644 index bbe0714801c..00000000000 --- a/tests/ui/consts/fn_trait_refs.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0635]: unknown feature `const_fn_trait_ref_impls` - --> $DIR/fn_trait_refs.rs:3:12 - | -LL | #![feature(const_fn_trait_ref_impls)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied - --> $DIR/fn_trait_refs.rs:71:17 - | -LL | assert!(test_one == (1, 1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied - --> $DIR/fn_trait_refs.rs:74:17 - | -LL | assert!(test_two == (2, 2)); - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0635. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr index ff4fa36d684..33d7a46339b 100644 --- a/tests/ui/consts/missing-larger-array-impl.stderr +++ b/tests/ui/consts/missing-larger-array-impl.stderr @@ -8,11 +8,11 @@ LL | <[X; 35] as Default>::default(); &[T] &mut [T] [T; 0] - [T; 10] - [T; 11] - [T; 12] - [T; 13] - [T; 14] + [T; 1] + [T; 2] + [T; 3] + [T; 4] + [T; 5] and 27 others error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index c2653dd82a9..546aa4052d3 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -539,26 +539,26 @@ mod macro_escape { #[no_std] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod no_std { + //~^ NOTE This attribute does not have an `!`, which means it is applied to this module mod inner { #![no_std] } -//~^ WARN crate-level attribute should be in the root module +//~^ WARN the `#![no_std]` attribute can only be used at the crate root #[no_std] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this function #[no_std] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this struct #[no_std] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias #[no_std] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block } // At time of authorship, #[proc_macro_derive = "2500"] signals error diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 4a3520972bf..3c835be5cff 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -209,17 +209,6 @@ help: add a `!` LL | #![reexport_test_harness_main = "2900"] | + -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1 - | -LL | #[no_std] - | ^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_std] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:1 | @@ -387,56 +376,6 @@ help: add a `!` LL | #![reexport_test_harness_main = "2900"] impl S { } | + -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17 - | -LL | mod inner { #![no_std] } - | ^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5 - | -LL | #[no_std] fn f() { } - | ^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_std] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5 - | -LL | #[no_std] struct S; - | ^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_std] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5 - | -LL | #[no_std] type T = S; - | ^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_std] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5 - | -LL | #[no_std] impl S { } - | ^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_std] impl S { } - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17 | @@ -1095,6 +1034,76 @@ LL | #[macro_escape] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[macro_escape]` can be applied to modules, extern crates, and crates +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1 + | +LL | #[no_std] + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:1 + | +LL | / mod no_std { +LL | | +LL | | mod inner { #![no_std] } +... | +LL | | } + | |_^ + +warning: the `#![no_std]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17 + | +LL | mod inner { #![no_std] } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5 + | +LL | #[no_std] fn f() { } + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:15 + | +LL | #[no_std] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5 + | +LL | #[no_std] struct S; + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:15 + | +LL | #[no_std] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5 + | +LL | #[no_std] type T = S; + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:15 + | +LL | #[no_std] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5 + | +LL | #[no_std] impl S { } + | ^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:15 + | +LL | #[no_std] impl S { } + | ^^^^^^^^^^ + warning: `#[cold]` attribute cannot be used on modules --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:1 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 076a08ac6f2..3a3b450f3c5 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -29,18 +29,6 @@ LL | #[no_link] | ^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:27:1 - | -LL | #![no_std] - | ^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:26:1 - | -LL | #![no_std] - | ^^^^^^^^^^ - -error: unused attribute --> $DIR/unused-attr-duplicate.rs:31:1 | LL | #![windows_subsystem = "windows"] @@ -305,6 +293,18 @@ LL | #![type_length_limit = "1048576"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute + --> $DIR/unused-attr-duplicate.rs:27:1 + | +LL | #![no_std] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:26:1 + | +LL | #![no_std] + | ^^^^^^^^^^ + +error: unused attribute --> $DIR/unused-attr-duplicate.rs:29:1 | LL | #![no_implicit_prelude] diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index 31f8f1d455a..9e068c311ae 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -5,14 +5,14 @@ LL | let _: &[i8] = data.into(); | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]` | = help: the following other types implement trait `From<T>`: - `[T; 10]` implements `From<(T, T, T, T, T, T, T, T, T, T)>` - `[T; 11]` implements `From<(T, T, T, T, T, T, T, T, T, T, T)>` - `[T; 12]` implements `From<(T, T, T, T, T, T, T, T, T, T, T, T)>` `[T; 1]` implements `From<(T,)>` `[T; 2]` implements `From<(T, T)>` `[T; 3]` implements `From<(T, T, T)>` `[T; 4]` implements `From<(T, T, T, T)>` `[T; 5]` implements `From<(T, T, T, T, T)>` + `[T; 6]` implements `From<(T, T, T, T, T, T)>` + `[T; 7]` implements `From<(T, T, T, T, T, T, T)>` + `[T; 8]` implements `From<(T, T, T, T, T, T, T, T)>` and 6 others = note: required for `&[u8]` to implement `Into<&[i8]>` diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs index da28d9a47c3..c89aaa62d99 100644 --- a/tests/ui/traits/const-traits/const-impl-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-trait.rs @@ -1,7 +1,5 @@ +//@ check-pass //@ compile-flags: -Znext-solver -//@ known-bug: #110395 - -// Broken until `(): const PartialEq` #![allow(incomplete_features)] #![feature(const_trait_impl, const_cmp, const_destruct)] diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr deleted file mode 100644 index cbb68d8c983..00000000000 --- a/tests/ui/traits/const-traits/const-impl-trait.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: the trait bound `(): const PartialEq` is not satisfied - --> $DIR/const-impl-trait.rs:34:17 - | -LL | assert!(cmp(&())); - | --- ^^^ - | | - | required by a bound introduced by this call - | -note: required by a bound in `cmp` - --> $DIR/const-impl-trait.rs:11:23 - | -LL | const fn cmp(a: &impl [const] PartialEq) -> bool { - | ^^^^^^^^^^^^^^^^^ required by this bound in `cmp` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs index 1a3012de06f..78c25ccd6e5 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs @@ -1,5 +1,4 @@ -//@ known-bug: #110395 - +//@ check-pass #![feature(const_trait_impl, const_default, const_cmp, derive_const)] pub struct A; diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr deleted file mode 100644 index 4ea11a0c7ed..00000000000 --- a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `(): [const] PartialEq` is not satisfied - --> $DIR/derive-const-use.rs:16:14 - | -LL | #[derive_const(Default, PartialEq)] - | --------- in this derive macro expansion -LL | pub struct S((), A); - | ^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 924fb98ae18..96d85d1e7c1 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -55,7 +55,7 @@ use self::prelude::*; */ #[doc = "inner doc attribute"] #[allow(dead_code, unused_variables)] -#[no_std] +#[attr = NoStd] mod attributes { /// outer single-line doc comment |
