Auto merge of #94963 - lcnr:inherent-impls-std, r=oli-obk,m-ou-se
allow arbitrary inherent impls for builtin types in core Part of https://github.com/rust-lang/compiler-team/issues/487. Slightly adjusted after some talks with `@m-ou-se` about the requirements of `t-libs-api`. This adds a crate attribute `#![rustc_coherence_is_core]` which allows arbitrary impls for builtin types in core. For other library crates impls for builtin types should be avoided if possible. We do have to allow the existing stable impls however. To prevent us from accidentally adding more of these in the future, there is a second attribute `#[rustc_allow_incoherent_impl]` which has to be added to **all impl items**. This only supports impls for builtin types but can easily be extended to additional types in a future PR. This implementation does not check for overlaps in these impls. Perfectly checking that requires us to check the coherence of these incoherent impls in every crate, as two distinct dependencies may add overlapping methods. It should be easy enough to detect if it goes wrong and the attribute is only intended for use inside of std. The first two commits are mostly unrelated cleanups.
This commit is contained in:
commit
3e7514670d
66 changed files with 701 additions and 849 deletions
|
@ -237,7 +237,7 @@ mod hack {
|
|||
}
|
||||
}
|
||||
|
||||
#[lang = "slice_alloc"]
|
||||
#[cfg_attr(bootstrap, lang = "slice_alloc")]
|
||||
#[cfg(not(test))]
|
||||
impl<T> [T] {
|
||||
/// Sorts the slice.
|
||||
|
@ -267,6 +267,7 @@ impl<T> [T] {
|
|||
/// assert!(v == [-5, -3, 1, 2, 4]);
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn sort(&mut self)
|
||||
|
@ -322,6 +323,7 @@ impl<T> [T] {
|
|||
/// assert!(v == [5, 4, 3, 2, 1]);
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn sort_by<F>(&mut self, mut compare: F)
|
||||
|
@ -363,6 +365,7 @@ impl<T> [T] {
|
|||
/// assert!(v == [1, 2, -3, 4, -5]);
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "slice_sort_by_key", since = "1.7.0")]
|
||||
#[inline]
|
||||
pub fn sort_by_key<K, F>(&mut self, mut f: F)
|
||||
|
@ -409,6 +412,7 @@ impl<T> [T] {
|
|||
///
|
||||
/// [pdqsort]: https://github.com/orlp/pdqsort
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
|
||||
#[inline]
|
||||
pub fn sort_by_cached_key<K, F>(&mut self, f: F)
|
||||
|
@ -467,6 +471,7 @@ impl<T> [T] {
|
|||
/// // Here, `s` and `x` can be modified independently.
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[rustc_conversion_suggestion]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
|
@ -491,6 +496,7 @@ impl<T> [T] {
|
|||
/// // Here, `s` and `x` can be modified independently.
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[inline]
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
|
||||
|
@ -515,6 +521,7 @@ impl<T> [T] {
|
|||
///
|
||||
/// assert_eq!(x, vec![10, 40, 30]);
|
||||
/// ```
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
|
||||
|
@ -542,6 +549,7 @@ impl<T> [T] {
|
|||
/// // this will panic at runtime
|
||||
/// b"0123456789abcdef".repeat(usize::MAX);
|
||||
/// ```
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "repeat_generic_slice", since = "1.40.0")]
|
||||
pub fn repeat(&self, n: usize) -> Vec<T>
|
||||
|
@ -610,6 +618,7 @@ impl<T> [T] {
|
|||
/// assert_eq!(["hello", "world"].concat(), "helloworld");
|
||||
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
|
||||
/// ```
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
|
||||
where
|
||||
|
@ -628,6 +637,7 @@ impl<T> [T] {
|
|||
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
|
||||
/// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
|
||||
/// ```
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
||||
pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
||||
where
|
||||
|
@ -646,6 +656,7 @@ impl<T> [T] {
|
|||
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
|
||||
pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
|
||||
|
@ -656,7 +667,7 @@ impl<T> [T] {
|
|||
}
|
||||
}
|
||||
|
||||
#[lang = "slice_u8_alloc"]
|
||||
#[cfg_attr(bootstrap, lang = "slice_u8_alloc")]
|
||||
#[cfg(not(test))]
|
||||
impl [u8] {
|
||||
/// Returns a vector containing a copy of this slice where each byte
|
||||
|
@ -669,6 +680,7 @@ impl [u8] {
|
|||
///
|
||||
/// [`make_ascii_uppercase`]: slice::make_ascii_uppercase
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[must_use = "this returns the uppercase bytes as a new Vec, \
|
||||
without modifying the original"]
|
||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
|
@ -689,6 +701,7 @@ impl [u8] {
|
|||
///
|
||||
/// [`make_ascii_lowercase`]: slice::make_ascii_lowercase
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
|
||||
#[must_use = "this returns the lowercase bytes as a new Vec, \
|
||||
without modifying the original"]
|
||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue