Skip to content

Commit

Permalink
restrict libs test to not(bootstrap)
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed May 4, 2021
1 parent 3fbed98 commit 1ed03a2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 39 deletions.
41 changes: 15 additions & 26 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,36 +391,25 @@ mod array_defaults {

#[cfg(not(bootstrap))]
mod array_defaults {
// We use auto traits to get overlapping impls without relying on nightly features.
//
// As the auto impl for `SendToDefault` is only considered if the manual impl does not apply,
// we have to use the generic impl for `T: Default` as the impl for the `N = 0` case would
// influence type inference in undesirable ways.
//
// While we are now able to implement `Default` exactly for the array types we want,
// we're still not able to actually write the body of the `Default` function without
// some further hacks.
//
// The idea here is that `array_default_hack` is resolved to itself only if `N = 0`
// and is otherwise replaced with `T::default()`.
//
// This would cause issues if `T` doesn't actually implement default but as this function
// is private and only used in the default impl itself this can not happen.

struct ZeroToSend<T, const N: usize>(*mut (), T);
unsafe impl<T> Send for ZeroToSend<T, 0> {}

/// This struct implements `Send` either because of the manual impl for `N` is `0` or
/// because all its fields implement `Send`, which is the case if `T` implements `Default`.
#[marker]
#[unstable(
feature = "array_default_impl",
issue = "none",
reason = "internal implementation detail for `[T; N]: Default`"
)]
#[allow(missing_debug_implementations)]
pub struct SendToDefault<T, const N: usize>(ZeroToSend<T, N>);
#[unstable(feature = "array_default_impl", issue = "none")]
unsafe impl<T: Default, const N: usize> Send for SendToDefault<T, N> {}
pub trait ArrayDefault {}
#[unstable(
feature = "array_default_impl",
issue = "none",
reason = "internal implementation detail for `[T; N]: Default`"
)]
impl<T: Default, const N: usize> ArrayDefault for [T; N] {}
#[unstable(
feature = "array_default_impl",
issue = "none",
reason = "internal implementation detail for `[T; N]: Default`"
)]
impl<T> ArrayDefault for [T; 0] {}

// This function must not get called for `N != 0` if `T` does not implement `Default`.
#[lang = "array_default_hack"]
Expand All @@ -431,7 +420,7 @@ mod array_defaults {
#[stable(since = "1.4.0", feature = "array_default")]
impl<T, const N: usize> Default for [T; N]
where
SendToDefault<T, N>: Send,
[T; N]: ArrayDefault,
{
fn default() -> [T; N] {
// SAFETY: The only case where `T` does not implement `Default` is
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
#![feature(min_specialization)]
#![feature(marker_trait_attr)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stmt_expr_attributes)]
Expand Down
27 changes: 15 additions & 12 deletions library/core/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,18 +357,21 @@ fn cell_allows_array_cycle() {
b3.a[1].set(Some(&b2));
}

fn generic_default<T: Default, const N: usize>() -> [T; N] {
Default::default()
}
#[cfg(not(bootstrap))]
mod array_defaults {
fn generic_default<T: Default, const N: usize>() -> [T; N] {
Default::default()
}

#[test]
fn use_generic_default() {
assert_eq!(generic_default::<String, 2>(), [String::new(), String::new()]);
assert_eq!(generic_default::<u8, 33>(), [0; 33]);
}
#[test]
fn use_generic_default() {
assert_eq!(generic_default::<String, 2>(), [String::new(), String::new()]);
assert_eq!(generic_default::<u8, 33>(), [0; 33]);
}

#[test]
fn use_zero_default() {
struct NotDefault;
assert!(matches!(<[NotDefault; 0] as Default>::default(), []));
#[test]
fn use_zero_default() {
struct NotDefault;
assert!(matches!(<[NotDefault; 0] as Default>::default(), []));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotDefault: Default` is not satisfied
LL | let _: [NotDefault; 1] = Default::default();
| ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `NotDefault`
|
= note: required because of the requirements on the impl of `Send` for `array::array_defaults::SendToDefault<NotDefault, 1_usize>`
= note: required because of the requirements on the impl of `array::array_defaults::ArrayDefault` for `[NotDefault; 1]`
= note: required because of the requirements on the impl of `Default` for `[NotDefault; 1]`
= note: required by `std::default::Default::default`

Expand Down

0 comments on commit 1ed03a2

Please sign in to comment.