Auto merge of #136533 - jhpratt:rollup-s0ign8n, r=jhpratt

Rollup of 5 pull requests

Successful merges:

 - #134777 (Enable more tests on Windows)
 - #135621 (Move some std tests to integration tests)
 - #135844 ( Add new tool for dumping feature status based on tidy )
 - #136167 (Implement unstable `new_range` feature)
 - #136334 (Extract `core::ffi` primitives to a separate (internal) module)

Failed merges:

 - #136201 (Removed dependency on the field-offset crate, alternate approach)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-02-04 12:13:02 +00:00
commit 7b31983d55
142 changed files with 1244 additions and 936 deletions

View File

@ -186,6 +186,9 @@ name = "anyhow"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
dependencies = [
"backtrace",
]
[[package]]
name = "ar_archive_writer"
@ -1195,6 +1198,17 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "features-status-dump"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"serde",
"serde_json",
"tidy",
]
[[package]]
name = "field-offset"
version = "0.3.6"
@ -5418,6 +5432,7 @@ dependencies = [
"regex",
"rustc-hash 2.1.0",
"semver",
"serde",
"similar",
"termcolor",
"walkdir",

View File

@ -47,6 +47,7 @@ members = [
"src/tools/coverage-dump",
"src/tools/rustc-perf-wrapper",
"src/tools/wasm-component-ld",
"src/tools/features-status-dump",
]
exclude = [

View File

@ -284,9 +284,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Index(el, er, brackets_span) => {
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
}
ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
self.lower_expr_range_closed(e.span, e1, e2)
}
ExprKind::Range(e1, e2, lims) => {
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims)
}
@ -1512,15 +1509,39 @@ impl<'hir> LoweringContext<'_, 'hir> {
let lang_item = match (e1, e2, lims) {
(None, None, HalfOpen) => hir::LangItem::RangeFull,
(Some(..), None, HalfOpen) => hir::LangItem::RangeFrom,
(Some(..), None, HalfOpen) => {
if self.tcx.features().new_range() {
hir::LangItem::RangeFromCopy
} else {
hir::LangItem::RangeFrom
}
}
(None, Some(..), HalfOpen) => hir::LangItem::RangeTo,
(Some(..), Some(..), HalfOpen) => hir::LangItem::Range,
(Some(..), Some(..), HalfOpen) => {
if self.tcx.features().new_range() {
hir::LangItem::RangeCopy
} else {
hir::LangItem::Range
}
}
(None, Some(..), Closed) => hir::LangItem::RangeToInclusive,
(Some(..), Some(..), Closed) => unreachable!(),
(Some(e1), Some(e2), Closed) => {
if self.tcx.features().new_range() {
hir::LangItem::RangeInclusiveCopy
} else {
return self.lower_expr_range_closed(span, e1, e2);
}
}
(start, None, Closed) => {
self.dcx().emit_err(InclusiveRangeWithNoEnd { span });
match start {
Some(..) => hir::LangItem::RangeFrom,
Some(..) => {
if self.tcx.features().new_range() {
hir::LangItem::RangeFromCopy
} else {
hir::LangItem::RangeFrom
}
}
None => hir::LangItem::RangeFull,
}
}

View File

@ -570,6 +570,8 @@ declare_features! (
(unstable, never_type, "1.13.0", Some(35121)),
/// Allows diverging expressions to fall back to `!` rather than `()`.
(unstable, never_type_fallback, "1.41.0", Some(65992)),
/// Switch `..` syntax to use the new (`Copy + IntoIterator`) range types.
(unstable, new_range, "CURRENT_RUSTC_VERSION", Some(123741)),
/// Allows `#![no_core]`.
(unstable, no_core, "1.3.0", Some(29639)),
/// Allows the use of `no_sanitize` attribute.

View File

@ -2313,6 +2313,18 @@ impl Expr<'_> {
[val2],
StructTailExpr::None,
),
)
| (
ExprKind::Struct(
QPath::LangItem(LangItem::RangeFromCopy, _),
[val1],
StructTailExpr::None,
),
ExprKind::Struct(
QPath::LangItem(LangItem::RangeFromCopy, _),
[val2],
StructTailExpr::None,
),
) => val1.expr.equivalent_for_indexing(val2.expr),
(
ExprKind::Struct(
@ -2325,6 +2337,30 @@ impl Expr<'_> {
[val2, val4],
StructTailExpr::None,
),
)
| (
ExprKind::Struct(
QPath::LangItem(LangItem::RangeCopy, _),
[val1, val3],
StructTailExpr::None,
),
ExprKind::Struct(
QPath::LangItem(LangItem::RangeCopy, _),
[val2, val4],
StructTailExpr::None,
),
)
| (
ExprKind::Struct(
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
[val1, val3],
StructTailExpr::None,
),
ExprKind::Struct(
QPath::LangItem(LangItem::RangeInclusiveCopy, _),
[val2, val4],
StructTailExpr::None,
),
) => {
val1.expr.equivalent_for_indexing(val2.expr)
&& val3.expr.equivalent_for_indexing(val4.expr)
@ -2354,7 +2390,10 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
| LangItem::RangeTo
| LangItem::RangeFrom
| LangItem::RangeFull
| LangItem::RangeToInclusive,
| LangItem::RangeToInclusive
| LangItem::RangeCopy
| LangItem::RangeFromCopy
| LangItem::RangeInclusiveCopy,
..
)
),

View File

@ -416,6 +416,11 @@ language_item_table! {
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None;
RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None;
// `new_range` types that are `Copy + IntoIterator`
RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None;
RangeCopy, sym::RangeCopy, range_copy_struct, Target::Struct, GenericRequirement::None;
RangeInclusiveCopy, sym::RangeInclusiveCopy, range_inclusive_copy_struct, Target::Struct, GenericRequirement::None;
String, sym::String, string, Target::Struct, GenericRequirement::None;
CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None;
}

View File

@ -2395,6 +2395,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let lang_item = match parent_expr.kind {
ExprKind::Struct(qpath, _, _) => match *qpath {
QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
QPath::LangItem(LangItem::RangeCopy, ..) => Some(LangItem::RangeCopy),
QPath::LangItem(LangItem::RangeInclusiveCopy, ..) => {
Some(LangItem::RangeInclusiveCopy)
}
QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
QPath::LangItem(LangItem::RangeToInclusive, ..) => {
Some(LangItem::RangeToInclusive)

View File

@ -294,9 +294,12 @@ symbols! {
ProceduralMasqueradeDummyType,
Range,
RangeBounds,
RangeCopy,
RangeFrom,
RangeFromCopy,
RangeFull,
RangeInclusive,
RangeInclusiveCopy,
RangeTo,
RangeToInclusive,
Rc,
@ -1364,6 +1367,7 @@ symbols! {
new_lower_hex,
new_octal,
new_pointer,
new_range,
new_unchecked,
new_upper_exp,
new_upper_hex,

View File

@ -37,175 +37,14 @@ pub use self::va_list::{VaList, VaListImpl};
)]
pub mod va_list;
macro_rules! type_alias {
{
$Docfile:tt, $Alias:ident = $Real:ty;
$( $Cfg:tt )*
} => {
#[doc = include_str!($Docfile)]
$( $Cfg )*
#[stable(feature = "core_ffi_c", since = "1.64.0")]
pub type $Alias = $Real;
}
}
type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
type_alias! { "c_schar.md", c_schar = i8; }
type_alias! { "c_uchar.md", c_uchar = u8; }
type_alias! { "c_short.md", c_short = i16; }
type_alias! { "c_ushort.md", c_ushort = u16; }
type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
type_alias! { "c_longlong.md", c_longlong = i64; }
type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
type_alias! { "c_float.md", c_float = f32; }
type_alias! { "c_double.md", c_double = f64; }
/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
///
/// This type is currently always [`usize`], however in the future there may be
/// platforms where this is not the case.
mod primitives;
#[stable(feature = "core_ffi_c", since = "1.64.0")]
pub use self::primitives::{
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
c_ulong, c_ulonglong, c_ushort,
};
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_size_t = usize;
/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
///
/// This type is currently always [`isize`], however in the future there may be
/// platforms where this is not the case.
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_ptrdiff_t = isize;
/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
///
/// This type is currently always [`isize`], however in the future there may be
/// platforms where this is not the case.
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_ssize_t = isize;
mod c_char_definition {
cfg_if! {
// These are the targets on which c_char is unsigned. Usually the
// signedness is the same for all target_os values on a given architecture
// but there are some exceptions (see isSignedCharDefault() in clang).
//
// aarch64:
// Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
// 64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
// https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#arm-c-and-c-language-mappings
// arm:
// Section 8 "Arm C and C++ Language Mappings" in Procedure Call Standard for the Arm®
// Architecture says C/C++ char is unsigned byte.
// https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs32/aapcs32.rst#arm-c-and-c-language-mappings
// csky:
// Section 2.1.2 "Primary Data Type" in C-SKY V2 CPU Applications Binary Interface
// Standards Manual says ANSI C char is unsigned byte.
// https://github.com/c-sky/csky-doc/blob/9f7121f7d40970ba5cc0f15716da033db2bb9d07/C-SKY_V2_CPU_Applications_Binary_Interface_Standards_Manual.pdf
// Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945).
// hexagon:
// Section 3.1 "Basic data type" in Qualcomm Hexagon™ Application
// Binary Interface User Guide says "By default, the `char` data type is unsigned."
// https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf
// msp430:
// Section 2.1 "Basic Types" in MSP430 Embedded Application Binary
// Interface says "The char type is unsigned by default".
// https://www.ti.com/lit/an/slaa534a/slaa534a.pdf
// powerpc/powerpc64:
// - PPC32 SysV: "Table 3-1 Scalar Types" in System V Application Binary Interface PowerPC
// Processor Supplement says ANSI C char is unsigned byte
// https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf
// - PPC64 ELFv1: Section 3.1.4 "Fundamental Types" in 64-bit PowerPC ELF Application
// Binary Interface Supplement 1.9 says ANSI C is unsigned byte
// https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUND-TYPE
// - PPC64 ELFv2: Section 2.1.2.2 "Fundamental Types" in 64-Bit ELF V2 ABI Specification
// says char is unsigned byte
// https://openpowerfoundation.org/specifications/64bitelfabi/
// - AIX: XL C for AIX Language Reference says "By default, char behaves like an unsigned char."
// https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=specifiers-character-types
// riscv32/riscv64:
// C/C++ type representations section in RISC-V Calling Conventions
// page in RISC-V ELF psABI Document says "char is unsigned."
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#cc-type-representations
// s390x:
// - ELF: "Table 1.1.: Scalar types" in ELF Application Binary Interface s390x Supplement
// Version 1.6.1 categorize ISO C char in unsigned integer
// https://github.com/IBM/s390x-abi/releases/tag/v1.6.1
// - z/OS: XL C/C++ Language Reference says: "By default, char behaves like an unsigned char."
// https://www.ibm.com/docs/en/zos/3.1.0?topic=specifiers-character-types
// xtensa:
// Section 2.17.1 "Data Types and Alignment" of Xtensa LX Microprocessor Overview handbook
// says "`char` type is unsigned by default".
// https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf
//
// On the following operating systems, c_char is signed by default, regardless of architecture.
// Darwin (macOS, iOS, etc.):
// Apple targets' c_char is signed by default even on arm
// https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-data-types-and-data-alignment-properly
// Windows:
// Windows MSVC C++ Language Reference says "Microsoft-specific: Variables of type char
// are promoted to int as if from type signed char by default, unless the /J compilation
// option is used."
// https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
// L4Re:
// The kernel builds with -funsigned-char on all targets (but useserspace follows the
// architecture defaults). As we only have a target for userspace apps so there are no
// special cases for L4Re below.
// https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
if #[cfg(all(
not(windows),
not(target_vendor = "apple"),
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "csky",
target_arch = "hexagon",
target_arch = "msp430",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "xtensa",
)
))] {
pub(super) type c_char = u8;
} else {
// On every other target, c_char is signed.
pub(super) type c_char = i8;
}
}
}
mod c_int_definition {
cfg_if! {
if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
pub(super) type c_int = i16;
pub(super) type c_uint = u16;
} else {
pub(super) type c_int = i32;
pub(super) type c_uint = u32;
}
}
}
mod c_long_definition {
cfg_if! {
if #[cfg(all(target_pointer_width = "64", not(windows)))] {
pub(super) type c_long = i64;
pub(super) type c_ulong = u64;
} else {
// The minimal size of `long` in the C standard is 32 bits
pub(super) type c_long = i32;
pub(super) type c_ulong = u32;
}
}
}
pub use self::primitives::{c_ptrdiff_t, c_size_t, c_ssize_t};
// N.B., for LLVM to recognize the void pointer type and by extension
// functions like malloc(), we need to have it represented as i8* in

View File

@ -0,0 +1,174 @@
//! Defines primitive types that match C's type definitions for FFI compatibility.
//!
//! This module is intentionally standalone to facilitate parsing when retrieving
//! core C types.
macro_rules! type_alias {
{
$Docfile:tt, $Alias:ident = $Real:ty;
$( $Cfg:tt )*
} => {
#[doc = include_str!($Docfile)]
$( $Cfg )*
#[stable(feature = "core_ffi_c", since = "1.64.0")]
pub type $Alias = $Real;
}
}
type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
type_alias! { "c_schar.md", c_schar = i8; }
type_alias! { "c_uchar.md", c_uchar = u8; }
type_alias! { "c_short.md", c_short = i16; }
type_alias! { "c_ushort.md", c_ushort = u16; }
type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
type_alias! { "c_longlong.md", c_longlong = i64; }
type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
type_alias! { "c_float.md", c_float = f32; }
type_alias! { "c_double.md", c_double = f64; }
mod c_char_definition {
cfg_if! {
// These are the targets on which c_char is unsigned. Usually the
// signedness is the same for all target_os values on a given architecture
// but there are some exceptions (see isSignedCharDefault() in clang).
//
// aarch64:
// Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
// 64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
// https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#arm-c-and-c-language-mappings
// arm:
// Section 8 "Arm C and C++ Language Mappings" in Procedure Call Standard for the Arm®
// Architecture says C/C++ char is unsigned byte.
// https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs32/aapcs32.rst#arm-c-and-c-language-mappings
// csky:
// Section 2.1.2 "Primary Data Type" in C-SKY V2 CPU Applications Binary Interface
// Standards Manual says ANSI C char is unsigned byte.
// https://github.com/c-sky/csky-doc/blob/9f7121f7d40970ba5cc0f15716da033db2bb9d07/C-SKY_V2_CPU_Applications_Binary_Interface_Standards_Manual.pdf
// Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945).
// hexagon:
// Section 3.1 "Basic data type" in Qualcomm Hexagon™ Application
// Binary Interface User Guide says "By default, the `char` data type is unsigned."
// https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf
// msp430:
// Section 2.1 "Basic Types" in MSP430 Embedded Application Binary
// Interface says "The char type is unsigned by default".
// https://www.ti.com/lit/an/slaa534a/slaa534a.pdf
// powerpc/powerpc64:
// - PPC32 SysV: "Table 3-1 Scalar Types" in System V Application Binary Interface PowerPC
// Processor Supplement says ANSI C char is unsigned byte
// https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf
// - PPC64 ELFv1: Section 3.1.4 "Fundamental Types" in 64-bit PowerPC ELF Application
// Binary Interface Supplement 1.9 says ANSI C is unsigned byte
// https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUND-TYPE
// - PPC64 ELFv2: Section 2.1.2.2 "Fundamental Types" in 64-Bit ELF V2 ABI Specification
// says char is unsigned byte
// https://openpowerfoundation.org/specifications/64bitelfabi/
// - AIX: XL C for AIX Language Reference says "By default, char behaves like an unsigned char."
// https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=specifiers-character-types
// riscv32/riscv64:
// C/C++ type representations section in RISC-V Calling Conventions
// page in RISC-V ELF psABI Document says "char is unsigned."
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#cc-type-representations
// s390x:
// - ELF: "Table 1.1.: Scalar types" in ELF Application Binary Interface s390x Supplement
// Version 1.6.1 categorize ISO C char in unsigned integer
// https://github.com/IBM/s390x-abi/releases/tag/v1.6.1
// - z/OS: XL C/C++ Language Reference says: "By default, char behaves like an unsigned char."
// https://www.ibm.com/docs/en/zos/3.1.0?topic=specifiers-character-types
// xtensa:
// Section 2.17.1 "Data Types and Alignment" of Xtensa LX Microprocessor Overview handbook
// says "`char` type is unsigned by default".
// https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf
//
// On the following operating systems, c_char is signed by default, regardless of architecture.
// Darwin (macOS, iOS, etc.):
// Apple targets' c_char is signed by default even on arm
// https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-data-types-and-data-alignment-properly
// Windows:
// Windows MSVC C++ Language Reference says "Microsoft-specific: Variables of type char
// are promoted to int as if from type signed char by default, unless the /J compilation
// option is used."
// https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
// L4Re:
// The kernel builds with -funsigned-char on all targets (but useserspace follows the
// architecture defaults). As we only have a target for userspace apps so there are no
// special cases for L4Re below.
// https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
if #[cfg(all(
not(windows),
not(target_vendor = "apple"),
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "csky",
target_arch = "hexagon",
target_arch = "msp430",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "xtensa",
)
))] {
pub(super) type c_char = u8;
} else {
// On every other target, c_char is signed.
pub(super) type c_char = i8;
}
}
}
mod c_long_definition {
cfg_if! {
if #[cfg(all(target_pointer_width = "64", not(windows)))] {
pub(super) type c_long = i64;
pub(super) type c_ulong = u64;
} else {
// The minimal size of `long` in the C standard is 32 bits
pub(super) type c_long = i32;
pub(super) type c_ulong = u32;
}
}
}
/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
///
/// This type is currently always [`usize`], however in the future there may be
/// platforms where this is not the case.
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_size_t = usize;
/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
///
/// This type is currently always [`isize`], however in the future there may be
/// platforms where this is not the case.
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_ptrdiff_t = isize;
/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
///
/// This type is currently always [`isize`], however in the future there may be
/// platforms where this is not the case.
#[unstable(feature = "c_size_t", issue = "88345")]
pub type c_ssize_t = isize;
mod c_int_definition {
cfg_if! {
if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
pub(super) type c_int = i16;
pub(super) type c_uint = u16;
} else {
pub(super) type c_int = i32;
pub(super) type c_uint = u32;
}
}
}

View File

@ -48,6 +48,7 @@ pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, Rang
/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 });
/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
/// ```
#[cfg_attr(not(bootstrap), lang = "RangeCopy")]
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
#[unstable(feature = "new_range_api", issue = "125687")]
pub struct Range<Idx> {
@ -205,6 +206,7 @@ impl<T> From<legacy::Range<T>> for Range<T> {
/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 });
/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
/// ```
#[cfg_attr(not(bootstrap), lang = "RangeInclusiveCopy")]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[unstable(feature = "new_range_api", issue = "125687")]
pub struct RangeInclusive<Idx> {
@ -388,6 +390,7 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 });
/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
/// ```
#[cfg_attr(not(bootstrap), lang = "RangeFromCopy")]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[unstable(feature = "new_range_api", issue = "125687")]
pub struct RangeFrom<Idx> {

View File

@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust.git"
description = "The Rust Standard Library"
edition = "2021"
autobenches = false
[lib]
crate-type = ["dylib", "rlib"]
@ -130,6 +131,18 @@ name = "pipe-subprocess"
path = "tests/pipe_subprocess.rs"
harness = false
[[test]]
name = "sync"
path = "tests/sync/lib.rs"
[[test]]
name = "floats"
path = "tests/floats/lib.rs"
[[test]]
name = "thread_local"
path = "tests/thread_local/lib.rs"
[[bench]]
name = "stdbenches"
path = "benches/lib.rs"

View File

@ -5,3 +5,5 @@
extern crate test;
mod hash;
mod path;
mod time;

114
library/std/benches/path.rs Normal file
View File

@ -0,0 +1,114 @@
use core::hint::black_box;
use std::collections::{BTreeSet, HashSet};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::*;
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
paths.sort();
b.iter(|| {
black_box(paths.as_mut_slice()).sort_unstable();
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(black_box(paths[500].as_path()))
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
let probe = PathBuf::from(prefix).join("other");
b.iter(|| set.remove(black_box(probe.as_path())));
}
#[bench]
fn bench_hash_path_short(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path = Path::new("explorer.exe");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[bench]
fn bench_hash_path_long(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path =
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}

View File

@ -0,0 +1,47 @@
use std::time::Instant;
#[cfg(not(target_arch = "wasm32"))]
use test::{Bencher, black_box};
macro_rules! bench_instant_threaded {
($bench_name:ident, $thread_count:expr) => {
#[bench]
#[cfg(not(target_arch = "wasm32"))]
fn $bench_name(b: &mut Bencher) -> std::thread::Result<()> {
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
let running = Arc::new(AtomicBool::new(true));
let threads: Vec<_> = (0..$thread_count)
.map(|_| {
let flag = Arc::clone(&running);
std::thread::spawn(move || {
while flag.load(Ordering::Relaxed) {
black_box(Instant::now());
}
})
})
.collect();
b.iter(|| {
let a = Instant::now();
let b = Instant::now();
assert!(b >= a);
});
running.store(false, Ordering::Relaxed);
for t in threads {
t.join()?;
}
Ok(())
}
};
}
bench_instant_threaded!(instant_contention_01_threads, 0);
bench_instant_threaded!(instant_contention_02_threads, 1);
bench_instant_threaded!(instant_contention_04_threads, 3);
bench_instant_threaded!(instant_contention_08_threads, 7);
bench_instant_threaded!(instant_contention_16_threads, 15);

View File

@ -10,9 +10,6 @@
#![stable(feature = "env", since = "1.0.0")]
#[cfg(test)]
mod tests;
use crate::error::Error;
use crate::ffi::{OsStr, OsString};
use crate::path::{Path, PathBuf};

View File

@ -1,120 +0,0 @@
use super::*;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
let path = path.unwrap();
// Hard to test this function
assert!(path.is_absolute());
}
#[test]
fn test() {
assert!((!Path::new("test-path").is_absolute()));
#[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}
#[test]
#[cfg(windows)]
fn split_paths_windows() {
use crate::path::PathBuf;
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse(r#""""#, &mut [""]));
assert!(check_parse(";;", &mut ["", "", ""]));
assert!(check_parse(r"c:\", &mut [r"c:\"]));
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
}
#[test]
#[cfg(unix)]
fn split_paths_unix() {
use crate::path::PathBuf;
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse("::", &mut ["", "", ""]));
assert!(check_parse("/", &mut ["/"]));
assert!(check_parse("/:", &mut ["/", ""]));
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
}
#[test]
#[cfg(unix)]
fn join_paths_unix() {
use crate::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
}
#[test]
#[cfg(windows)]
fn join_paths_windows() {
use crate::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
}
#[test]
fn args_debug() {
assert_eq!(
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
format!("{:?}", args())
);
}
#[test]
fn args_os_debug() {
assert_eq!(
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
format!("{:?}", args_os())
);
}
#[test]
fn vars_debug() {
assert_eq!(
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
format!("{:?}", vars())
);
}
#[test]
fn vars_os_debug() {
assert_eq!(
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
format!("{:?}", vars_os())
);
}

View File

@ -1,9 +1,6 @@
#![doc = include_str!("../../core/src/error.md")]
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::error::Error;
#[unstable(feature = "error_generic_member_access", issue = "99301")]

View File

@ -4,9 +4,6 @@
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;
#[unstable(feature = "f128", issue = "116909")]
pub use core::f128::consts;

View File

@ -4,9 +4,6 @@
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;
#[unstable(feature = "f16", issue = "116909")]
pub use core::f16::consts;

View File

@ -12,9 +12,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)]
pub use core::f32::{

View File

@ -12,9 +12,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)]
pub use core::f64::{

View File

@ -530,6 +530,8 @@ pub use core::option;
pub use core::pin;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::ptr;
#[unstable(feature = "new_range_api", issue = "125687")]
pub use core::range;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::result;
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -372,18 +372,3 @@ macro_rules! dbg {
($($crate::dbg!($val)),+,)
};
}
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
#[cfg(test)]
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
($a:expr, $b:expr, $lim:expr) => {{
let (a, b) = (&$a, &$b);
let diff = (*a - *b).abs();
assert!(
diff < $lim,
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
lim = $lim
);
}};
}

View File

@ -6,9 +6,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(test)]
mod tests;
#[stable(feature = "int_error_matching", since = "1.55.0")]
pub use core::num::IntErrorKind;
#[stable(feature = "generic_nonzero", since = "1.79.0")]
@ -29,28 +26,3 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
#[stable(feature = "nonzero", since = "1.28.0")]
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
#[cfg(test)]
use crate::fmt;
#[cfg(test)]
use crate::ops::{Add, Div, Mul, Rem, Sub};
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T)
where
T: PartialEq
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ Rem<Output = T>
+ fmt::Debug
+ Copy,
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}

View File

@ -529,6 +529,3 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
Err(new) => BacktraceStyle::from_u8(new),
}
}
#[cfg(test)]
mod tests;

View File

@ -67,9 +67,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(test)]
mod tests;
use core::clone::CloneToUninit;
use crate::borrow::{Borrow, Cow};

View File

@ -1,6 +1,3 @@
#[cfg(test)]
mod tests;
use crate::fmt;
// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
use crate::sync::{Condvar, Mutex};

View File

@ -350,6 +350,3 @@ unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
#[stable(feature = "lazy_cell", since = "1.80.0")]
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}
#[cfg(test)]
mod tests;

View File

@ -137,12 +137,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod sync_tests;
// MPSC channels are built as a wrapper around MPMC channels, which
// were ported from the `crossbeam-channel` crate. MPMC channels are
// not exposed publicly, but if you are curious about the implementation,
@ -737,9 +731,10 @@ impl<T> SyncSender<T> {
// Attempts to send for a value on this receiver, returning an error if the
// corresponding channel has hung up, or if it waits more than `timeout`.
//
// This method is currently private and only used for tests.
#[allow(unused)]
fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
// This method is currently only used for tests.
#[unstable(issue = "none", feature = "std_internals")]
#[doc(hidden)]
pub fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
self.inner.send_timeout(t, timeout)
}
}

View File

@ -681,6 +681,3 @@ unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
}
}
}
#[cfg(test)]
mod tests;

View File

@ -1,6 +1,3 @@
#[cfg(test)]
mod tests;
use crate::fmt;
use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
use crate::sys::sync as sys;

View File

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::marker::PhantomData;

View File

@ -3,9 +3,6 @@
//! This primitive is meant to be used to run one-time initialization. An
//! example use case would be for initializing an FFI library.
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::fmt;
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sys::sync as sys;

View File

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::marker::PhantomData;

View File

@ -1,6 +1,3 @@
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
use cfg_if::cfg_if;
use crate::cell::UnsafeCell;
@ -324,7 +321,10 @@ impl<T: ?Sized> ReentrantLock<T> {
/// Otherwise, an RAII guard is returned.
///
/// This function does not block.
pub(crate) fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
// FIXME maybe make it a public part of the API?
#[unstable(issue = "none", feature = "std_internals")]
#[doc(hidden)]
pub fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
let this_thread = current_id();
// Safety: We only touch lock_count when we own the inner mutex.
// Additionally, we only call `self.owner.set()` while holding

View File

@ -2,12 +2,6 @@
#![unstable(feature = "thread_local_internals", issue = "none")]
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
mod tests;
#[cfg(test)]
mod dynamic_tests;
use crate::cell::{Cell, RefCell};
use crate::error::Error;
use crate::fmt;

View File

@ -31,9 +31,6 @@
#![stable(feature = "time", since = "1.3.0")]
#[cfg(test)]
mod tests;
#[stable(feature = "time", since = "1.3.0")]
pub use core::time::Duration;
#[stable(feature = "duration_checked_float", since = "1.66.0")]

View File

@ -1,163 +1,123 @@
use std::env::*;
use std::ffi::{OsStr, OsString};
use rand::distributions::{Alphanumeric, DistString};
use std::path::Path;
mod common;
use std::thread;
use common::test_rng;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
let path = path.unwrap();
#[track_caller]
fn make_rand_name() -> OsString {
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
// Hard to test this function
assert!(path.is_absolute());
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
fn test() {
assert!((!Path::new("test-path").is_absolute()));
#[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = "x".repeat(10000);
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
}
#[test]
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
#[allow(deprecated)]
fn env_home_dir() {
#[cfg(windows)]
fn split_paths_windows() {
use std::path::PathBuf;
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
match var {
Ok(var) => Some(OsString::from(var)),
Err(VarError::NotUnicode(var)) => Some(var),
_ => None,
}
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
cfg_if::cfg_if! {
if #[cfg(unix)] {
let oldhome = var_to_os_string(var("HOME"));
assert!(check_parse("", &mut [""]));
assert!(check_parse(r#""""#, &mut [""]));
assert!(check_parse(";;", &mut ["", "", ""]));
assert!(check_parse(r"c:\", &mut [r"c:\"]));
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
}
set_var("HOME", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
#[test]
#[cfg(unix)]
fn split_paths_unix() {
use std::path::PathBuf;
remove_var("HOME");
if cfg!(target_os = "android") {
assert!(home_dir().is_none());
} else {
// When HOME is not set, some platforms return `None`,
// but others return `Some` with a default.
// Just check that it is not "/home/MountainView".
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
} else if #[cfg(windows)] {
let oldhome = var_to_os_string(var("HOME"));
let olduserprofile = var_to_os_string(var("USERPROFILE"));
remove_var("HOME");
remove_var("USERPROFILE");
assert!(home_dir().is_some());
set_var("HOME", "/home/PaloAlto");
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
set_var("USERPROFILE", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
set_var("USERPROFILE", "");
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
remove_var("USERPROFILE");
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
}
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed).collect::<Vec<_>>()
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
assert!(check_parse("::", &mut ["", "", ""]));
assert!(check_parse("/", &mut ["/"]));
assert!(check_parse("/:", &mut ["/", ""]));
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
}
#[test] // miri shouldn't detect any data race in this fn
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
fn test_env_get_set_multithreaded() {
let getter = thread::spawn(|| {
for _ in 0..100 {
let _ = var_os("foo");
}
});
#[test]
#[cfg(unix)]
fn join_paths_unix() {
use std::ffi::OsStr;
let setter = thread::spawn(|| {
for _ in 0..100 {
set_var("foo", "bar");
}
});
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
let _ = getter.join();
let _ = setter.join();
assert!(test_eq(&[], ""));
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
}
#[test]
#[cfg(windows)]
fn join_paths_windows() {
use std::ffi::OsStr;
fn test_eq(input: &[&str], output: &str) -> bool {
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
}
assert!(test_eq(&[], ""));
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
}
#[test]
fn args_debug() {
assert_eq!(
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
format!("{:?}", args())
);
}
#[test]
fn args_os_debug() {
assert_eq!(
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
format!("{:?}", args_os())
);
}
#[test]
fn vars_debug() {
assert_eq!(
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
format!("{:?}", vars())
);
}
#[test]
fn vars_os_debug() {
assert_eq!(
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
format!("{:?}", vars_os())
);
}

View File

@ -0,0 +1,166 @@
// These tests are in a separate integration test as they modify the environment,
// and would otherwise cause some other tests to fail.
use std::env::*;
use std::ffi::{OsStr, OsString};
use rand::distributions::{Alphanumeric, DistString};
mod common;
use std::thread;
use common::test_rng;
#[track_caller]
fn make_rand_name() -> OsString {
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = "x".repeat(10000);
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
}
#[test]
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
#[allow(deprecated)]
fn env_home_dir() {
use std::path::PathBuf;
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
match var {
Ok(var) => Some(OsString::from(var)),
Err(VarError::NotUnicode(var)) => Some(var),
_ => None,
}
}
cfg_if::cfg_if! {
if #[cfg(unix)] {
let oldhome = var_to_os_string(var("HOME"));
set_var("HOME", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
if cfg!(target_os = "android") {
assert!(home_dir().is_none());
} else {
// When HOME is not set, some platforms return `None`,
// but others return `Some` with a default.
// Just check that it is not "/home/MountainView".
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
}
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
} else if #[cfg(windows)] {
let oldhome = var_to_os_string(var("HOME"));
let olduserprofile = var_to_os_string(var("USERPROFILE"));
remove_var("HOME");
remove_var("USERPROFILE");
assert!(home_dir().is_some());
set_var("HOME", "/home/PaloAlto");
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
set_var("USERPROFILE", "/home/MountainView");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
remove_var("HOME");
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
set_var("USERPROFILE", "");
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
remove_var("USERPROFILE");
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
}
}
}
#[test] // miri shouldn't detect any data race in this fn
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
fn test_env_get_set_multithreaded() {
let getter = thread::spawn(|| {
for _ in 0..100 {
let _ = var_os("foo");
}
});
let setter = thread::spawn(|| {
for _ in 0..100 {
set_var("foo", "bar");
}
});
let _ = getter.join();
let _ = setter.join();
}

View File

@ -1,7 +1,8 @@
use core::error::Request;
#![feature(error_generic_member_access, error_reporter)]
use super::Error;
use crate::fmt;
use std::backtrace::Backtrace;
use std::error::{Error, Report, Request};
use std::fmt;
#[derive(Debug, PartialEq)]
struct A;
@ -38,9 +39,6 @@ fn downcasting() {
}
}
use crate::backtrace::Backtrace;
use crate::error::Report;
#[derive(Debug)]
struct SuperError {
source: SuperErrorSideKick,

View File

@ -1,11 +1,11 @@
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
#![cfg(reliable_f128)]
use crate::f128::consts;
use crate::num::FpCategory as Fp;
use std::f128::consts;
use std::num::FpCategory as Fp;
#[cfg(reliable_f128_math)]
use crate::ops::Rem;
use crate::ops::{Add, Div, Mul, Sub};
use std::ops::Rem;
use std::ops::{Add, Div, Mul, Sub};
// Note these tolerances make sense around zero, but not for more extreme exponents.
@ -762,8 +762,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f128 = consts::PI;
let frac_pi_2: f128 = consts::FRAC_PI_2;
let frac_pi_3: f128 = consts::FRAC_PI_3;

View File

@ -1,8 +1,8 @@
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
#![cfg(reliable_f16)]
use crate::f16::consts;
use crate::num::{FpCategory as Fp, *};
use std::f16::consts;
use std::num::FpCategory as Fp;
/// Tolerance for results on the order of 10.0e-2
#[allow(unused)]
@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
#[test]
fn test_num_f16() {
test_num(10f16, 2f16);
crate::test_num(10f16, 2f16);
}
#[test]
@ -734,7 +734,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
// FIXME(f16_f128): add math tests when available
use super::consts;
let pi: f16 = consts::PI;
let frac_pi_2: f16 = consts::FRAC_PI_2;

View File

@ -1,5 +1,5 @@
use crate::f32::consts;
use crate::num::{FpCategory as Fp, *};
use std::f32::consts;
use std::num::FpCategory as Fp;
/// Smallest number
const TINY_BITS: u32 = 0x1;
@ -35,7 +35,7 @@ macro_rules! assert_f32_biteq {
#[test]
fn test_num_f32() {
test_num(10f32, 2f32);
crate::test_num(10f32, 2f32);
}
#[test]
@ -700,8 +700,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f32 = consts::PI;
let frac_pi_2: f32 = consts::FRAC_PI_2;
let frac_pi_3: f32 = consts::FRAC_PI_3;

View File

@ -1,5 +1,5 @@
use crate::f64::consts;
use crate::num::{FpCategory as Fp, *};
use std::f64::consts;
use std::num::FpCategory as Fp;
/// Smallest number
const TINY_BITS: u64 = 0x1;
@ -35,7 +35,7 @@ macro_rules! assert_f64_biteq {
#[test]
fn test_num_f64() {
test_num(10f64, 2f64);
crate::test_num(10f64, 2f64);
}
#[test]
@ -680,7 +680,6 @@ fn test_ln_gamma() {
#[test]
fn test_real_consts() {
use super::consts;
let pi: f64 = consts::PI;
let frac_pi_2: f64 = consts::FRAC_PI_2;
let frac_pi_3: f64 = consts::FRAC_PI_3;

View File

@ -0,0 +1,42 @@
#![feature(f16, f128, float_gamma, float_minimum_maximum)]
use std::fmt;
use std::ops::{Add, Div, Mul, Rem, Sub};
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
($a:expr, $b:expr, $lim:expr) => {{
let (a, b) = (&$a, &$b);
let diff = (*a - *b).abs();
assert!(
diff < $lim,
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
lim = $lim
);
}};
}
/// Helper function for testing numeric operations
pub fn test_num<T>(ten: T, two: T)
where
T: PartialEq
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ Rem<Output = T>
+ fmt::Debug
+ Copy,
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}
mod f128;
mod f16;
mod f32;
mod f64;

View File

@ -1,4 +1,4 @@
use crate::ops::Mul;
use std::ops::Mul;
#[test]
fn test_saturating_add_uint() {
@ -190,8 +190,8 @@ fn test_uint_to_str_overflow() {
assert_eq!(u64_val.to_string(), "0");
}
fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
crate::str::FromStr::from_str(t).ok()
fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
std::str::FromStr::from_str(t).ok()
}
#[test]

View File

@ -1,9 +1,9 @@
#![allow(dead_code)]
use crate::cell::RefCell;
use crate::panic::{AssertUnwindSafe, UnwindSafe};
use crate::rc::Rc;
use crate::sync::{Arc, Mutex, RwLock};
use std::cell::RefCell;
use std::panic::{AssertUnwindSafe, UnwindSafe};
use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
struct Foo {
a: i32,

View File

@ -1,10 +1,19 @@
use core::hint::black_box;
#![feature(
clone_to_uninit,
path_add_extension,
path_file_prefix,
maybe_uninit_slice,
os_string_pathbuf_leak
)]
use super::*;
use crate::collections::{BTreeSet, HashSet};
use crate::hash::DefaultHasher;
use crate::mem::MaybeUninit;
use crate::ptr;
use std::clone::CloneToUninit;
use std::ffi::OsStr;
use std::hash::{DefaultHasher, Hash, Hasher};
use std::mem::MaybeUninit;
use std::path::*;
use std::ptr;
use std::rc::Rc;
use std::sync::Arc;
#[allow(unknown_lints, unused_macro_rules)]
macro_rules! t (
@ -110,7 +119,7 @@ macro_rules! t (
#[test]
fn into() {
use crate::borrow::Cow;
use std::borrow::Cow;
let static_path = Path::new("/home/foo");
let static_cow_path: Cow<'static, Path> = static_path.into();
@ -1525,7 +1534,7 @@ pub fn test_with_added_extension() {
#[test]
fn test_eq_receivers() {
use crate::borrow::Cow;
use std::borrow::Cow;
let borrowed: &Path = Path::new("foo/bar");
let mut owned: PathBuf = PathBuf::new();
@ -1550,7 +1559,7 @@ fn test_eq_receivers() {
#[test]
pub fn test_compare() {
use crate::hash::{DefaultHasher, Hash, Hasher};
use std::hash::{DefaultHasher, Hash, Hasher};
fn hash<T: Hash>(t: T) -> u64 {
let mut s = DefaultHasher::new();
@ -1867,12 +1876,12 @@ fn test_ord() {
#[test]
#[cfg(any(unix, target_os = "wasi"))]
fn test_unix_absolute() {
use crate::path::absolute;
use std::path::absolute;
assert!(absolute("").is_err());
let relative = "a/b";
let mut expected = crate::env::current_dir().unwrap();
let mut expected = std::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
@ -1888,7 +1897,7 @@ fn test_unix_absolute() {
);
// Test leading `.` and `..` components
let curdir = crate::env::current_dir().unwrap();
let curdir = std::env::current_dir().unwrap();
assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
}
@ -1896,12 +1905,12 @@ fn test_unix_absolute() {
#[test]
#[cfg(windows)]
fn test_windows_absolute() {
use crate::path::absolute;
use std::path::absolute;
// An empty path is an error.
assert!(absolute("").is_err());
let relative = r"a\b";
let mut expected = crate::env::current_dir().unwrap();
let mut expected = std::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
@ -1953,116 +1962,6 @@ fn test_extension_path_sep_alternate() {
assert_eq!(path, Path::new("path/to/file.d\\test"));
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
let mut paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
paths.sort();
b.iter(|| {
black_box(paths.as_mut_slice()).sort_unstable();
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
let prefix = "my/home";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = BTreeSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(paths[500].as_path());
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
b.iter(|| {
set.remove(paths[500].as_path());
set.insert(black_box(paths[500].as_path()))
});
}
#[bench]
#[cfg_attr(miri, ignore)] // Miri isn't fast...
fn bench_path_hashset_miss(b: &mut test::Bencher) {
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
let paths: Vec<_> =
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
let mut set = HashSet::new();
paths.iter().for_each(|p| {
set.insert(p.as_path());
});
let probe = PathBuf::from(prefix).join("other");
b.iter(|| set.remove(black_box(probe.as_path())));
}
#[bench]
fn bench_hash_path_short(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path = Path::new("explorer.exe");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[bench]
fn bench_hash_path_long(b: &mut test::Bencher) {
let mut hasher = DefaultHasher::new();
let path =
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
b.iter(|| black_box(path).hash(&mut hasher));
black_box(hasher.finish());
}
#[test]
fn clone_to_uninit() {
let a = Path::new("hello.txt");

View File

@ -1,6 +1,6 @@
use crate::sync::mpsc::{TryRecvError, channel};
use crate::sync::{Arc, Barrier};
use crate::thread;
use std::sync::mpsc::{TryRecvError, channel};
use std::sync::{Arc, Barrier};
use std::thread;
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads

View File

@ -1,8 +1,8 @@
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread;
use crate::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::time::Duration;
#[test]
fn smoke() {

View File

@ -1,8 +1,8 @@
use crate::cell::LazyCell;
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
use crate::sync::{LazyLock, Mutex, OnceLock};
use crate::{panic, thread};
use std::cell::LazyCell;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::{LazyLock, Mutex, OnceLock};
use std::{panic, thread};
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
thread::spawn(f).join().unwrap()
@ -149,7 +149,7 @@ fn is_sync_send() {
#[should_panic = "has previously been poisoned"]
fn lazy_force_mut_panic() {
let mut lazy = LazyLock::<String>::new(|| panic!());
crate::panic::catch_unwind(crate::panic::AssertUnwindSafe(|| {
panic::catch_unwind(panic::AssertUnwindSafe(|| {
let _ = LazyLock::force_mut(&mut lazy);
}))
.unwrap_err();

View File

@ -0,0 +1,31 @@
#![feature(lazy_get)]
#![feature(mapped_lock_guards)]
#![feature(mpmc_channel)]
#![feature(once_cell_try)]
#![feature(lock_value_accessors)]
#![feature(reentrant_lock)]
#![feature(rwlock_downgrade)]
#![feature(std_internals)]
#![allow(internal_features)]
mod barrier;
mod condvar;
mod lazy_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpmc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc_sync;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mutex;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod once;
mod once_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod reentrant_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod rwlock;
#[path = "../common/mod.rs"]
mod common;

View File

@ -1,5 +1,6 @@
use super::*;
use crate::{env, thread};
use std::sync::mpmc::*;
use std::time::{Duration, Instant};
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View File

@ -1,5 +1,6 @@
use super::*;
use crate::{env, thread};
use std::sync::mpsc::*;
use std::time::{Duration, Instant};
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View File

@ -1,7 +1,8 @@
use super::*;
use crate::rc::Rc;
use crate::sync::mpmc::SendTimeoutError;
use crate::{env, thread};
use std::rc::Rc;
use std::sync::mpmc::SendTimeoutError;
use std::sync::mpsc::*;
use std::time::Duration;
use std::{env, thread};
pub fn stress_factor() -> usize {
match env::var("RUST_TEST_STRESS") {

View File

@ -1,10 +1,10 @@
use crate::fmt::Debug;
use crate::ops::FnMut;
use crate::panic::{self, AssertUnwindSafe};
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
use crate::{hint, mem, thread};
use std::fmt::Debug;
use std::ops::FnMut;
use std::panic::{self, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
use std::{hint, mem, thread};
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);

View File

@ -1,9 +1,9 @@
use super::Once;
use crate::sync::atomic::AtomicBool;
use crate::sync::atomic::Ordering::Relaxed;
use crate::sync::mpsc::channel;
use crate::time::Duration;
use crate::{panic, thread};
use std::sync::Once;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::{panic, thread};
#[test]
fn smoke_once() {

View File

@ -1,8 +1,8 @@
use crate::sync::OnceLock;
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
use crate::sync::mpsc::channel;
use crate::{panic, thread};
use std::sync::OnceLock;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::mpsc::channel;
use std::{panic, thread};
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
thread::spawn(f).join().unwrap()
@ -33,15 +33,6 @@ fn sync_once_cell_get_mut() {
assert_eq!(c.get_mut(), Some(&mut 92));
}
#[test]
fn sync_once_cell_get_unchecked() {
let c = OnceLock::new();
c.set(92).unwrap();
unsafe {
assert_eq!(c.get_unchecked(), &92);
}
}
#[test]
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
fn sync_once_cell_drop() {
@ -88,7 +79,6 @@ fn get_or_try_init() {
let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
assert!(res.is_err());
assert!(!cell.is_initialized());
assert!(cell.get().is_none());
assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
@ -174,7 +164,7 @@ fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
break;
}
#[cfg(target_env = "sgx")]
crate::thread::yield_now();
std::thread::yield_now();
}
});
}

View File

@ -1,7 +1,6 @@
use super::ReentrantLock;
use crate::cell::RefCell;
use crate::sync::Arc;
use crate::thread;
use std::cell::RefCell;
use std::sync::{Arc, ReentrantLock};
use std::thread;
#[test]
fn smoke() {

View File

@ -1,15 +1,15 @@
use rand::Rng;
use crate::fmt::Debug;
use crate::ops::FnMut;
use crate::panic::{self, AssertUnwindSafe};
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::mpsc::channel;
use crate::sync::{
use std::fmt::Debug;
use std::ops::FnMut;
use std::panic::{self, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
use std::sync::{
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
TryLockError,
};
use crate::{hint, mem, thread};
use std::{hint, mem, thread};
use rand::Rng;
#[derive(Eq, PartialEq, Debug)]
struct NonCopy(i32);
@ -57,7 +57,7 @@ fn frob() {
let tx = tx.clone();
let r = r.clone();
thread::spawn(move || {
let mut rng = crate::test_helpers::test_rng();
let mut rng = crate::common::test_rng();
for _ in 0..M {
if rng.gen_bool(1.0 / (N as f64)) {
drop(r.write().unwrap());
@ -704,7 +704,7 @@ fn test_downgrade_atomic() {
// Wait for a good amount of time so that evil threads go to sleep.
// Note: this is not strictly necessary...
let eternity = crate::time::Duration::from_millis(42);
let eternity = std::time::Duration::from_millis(42);
thread::sleep(eternity);
// Once everyone is asleep, set the value to `NEW_VALUE`.

View File

@ -1,6 +1,6 @@
use crate::cell::RefCell;
use crate::collections::HashMap;
use crate::thread_local;
use std::cell::RefCell;
use std::collections::HashMap;
use std::thread_local;
#[test]
fn smoke() {

View File

@ -0,0 +1,4 @@
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod tests;
mod dynamic_tests;

View File

@ -1,8 +1,8 @@
use crate::cell::{Cell, UnsafeCell};
use crate::sync::atomic::{AtomicU8, Ordering};
use crate::sync::{Arc, Condvar, Mutex};
use crate::thread::{self, Builder, LocalKey};
use crate::thread_local;
use std::cell::{Cell, UnsafeCell};
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::{Arc, Condvar, Mutex};
use std::thread::{self, Builder, LocalKey};
use std::thread_local;
#[derive(Clone, Default)]
struct Signal(Arc<(Mutex<bool>, Condvar)>);

View File

@ -1,9 +1,7 @@
use core::fmt::Debug;
#![feature(duration_constants)]
#[cfg(not(target_arch = "wasm32"))]
use test::{Bencher, black_box};
use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::fmt::Debug;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
macro_rules! assert_almost_eq {
($a:expr, $b:expr) => {{
@ -29,10 +27,10 @@ fn instant_monotonic() {
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
fn instant_monotonic_concurrent() -> std::thread::Result<()> {
let threads: Vec<_> = (0..8)
.map(|_| {
crate::thread::spawn(|| {
std::thread::spawn(|| {
let mut old = Instant::now();
let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
for _ in 0..count {
@ -229,46 +227,3 @@ fn big_math() {
check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub);
check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub);
}
macro_rules! bench_instant_threaded {
($bench_name:ident, $thread_count:expr) => {
#[bench]
#[cfg(not(target_arch = "wasm32"))]
fn $bench_name(b: &mut Bencher) -> crate::thread::Result<()> {
use crate::sync::Arc;
use crate::sync::atomic::{AtomicBool, Ordering};
let running = Arc::new(AtomicBool::new(true));
let threads: Vec<_> = (0..$thread_count)
.map(|_| {
let flag = Arc::clone(&running);
crate::thread::spawn(move || {
while flag.load(Ordering::Relaxed) {
black_box(Instant::now());
}
})
})
.collect();
b.iter(|| {
let a = Instant::now();
let b = Instant::now();
assert!(b >= a);
});
running.store(false, Ordering::Relaxed);
for t in threads {
t.join()?;
}
Ok(())
}
};
}
bench_instant_threaded!(instant_contention_01_threads, 0);
bench_instant_threaded!(instant_contention_02_threads, 1);
bench_instant_threaded!(instant_contention_04_threads, 3);
bench_instant_threaded!(instant_contention_08_threads, 7);
bench_instant_threaded!(instant_contention_16_threads, 15);

View File

@ -455,6 +455,7 @@ tool_check_step!(Rls { path: "src/tools/rls" });
tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump" });
tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });

View File

@ -311,3 +311,34 @@ impl Step for UnicodeTableGenerator {
cmd.run(builder);
}
}
#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
pub struct FeaturesStatusDump;
impl Step for FeaturesStatusDump {
type Output = ();
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/tools/features-status-dump")
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(FeaturesStatusDump);
}
fn run(self, builder: &Builder<'_>) {
let mut cmd = builder.tool_cmd(Tool::FeaturesStatusDump);
cmd.arg("--library-path");
cmd.arg(builder.src.join("library"));
cmd.arg("--compiler-path");
cmd.arg(builder.src.join("compiler"));
cmd.arg("--output-path");
cmd.arg(builder.out.join("features-status-dump.json"));
cmd.run(builder);
}
}

View File

@ -365,6 +365,7 @@ bootstrap_tool!(
RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
);
/// These are the submodules that are required for rustbook to work due to

View File

@ -938,6 +938,7 @@ impl<'a> Builder<'a> {
check::Bootstrap,
check::RunMakeSupport,
check::Compiletest,
check::FeaturesStatusDump,
),
Kind::Test => describe!(
crate::core::build_steps::toolstate::ToolStateCheck,
@ -1089,6 +1090,7 @@ impl<'a> Builder<'a> {
run::GenerateWindowsSys,
run::GenerateCompletions,
run::UnicodeTableGenerator,
run::FeaturesStatusDump,
),
Kind::Setup => {
describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)

View File

@ -0,0 +1,9 @@
# `new_range`
The tracking issue for this feature is: [#123741]
[#123741]: https://github.com/rust-lang/rust/issues/123741
---
Switch the syntaxes `a..`, `a..b`, and `a..=b` to resolve the new range types.

View File

@ -0,0 +1,12 @@
[package]
name = "features-status-dump"
version = "0.1.0"
license = "MIT OR Apache-2.0"
edition = "2021"
[dependencies]
anyhow = { version = "1", features = ["backtrace"] }
clap = { version = "4", features = ["derive"] }
serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"
tidy = { path = "../tidy", features = ["build-metrics"] }

View File

@ -0,0 +1,53 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::BufWriter;
use std::path::PathBuf;
use anyhow::{Context, Result};
use clap::Parser;
use tidy::features::{Feature, collect_lang_features, collect_lib_features};
#[derive(Debug, Parser)]
struct Cli {
/// Path to `library/` directory.
#[arg(long)]
library_path: PathBuf,
/// Path to `compiler/` directory.
#[arg(long)]
compiler_path: PathBuf,
/// Path to `output/` directory.
#[arg(long)]
output_path: PathBuf,
}
#[derive(Debug, serde::Serialize)]
struct FeaturesStatus {
lang_features_status: HashMap<String, Feature>,
lib_features_status: HashMap<String, Feature>,
}
fn main() -> Result<()> {
let Cli { compiler_path, library_path, output_path } = Cli::parse();
let lang_features_status = collect_lang_features(&compiler_path, &mut false);
let lib_features_status = collect_lib_features(&library_path)
.into_iter()
.filter(|&(ref name, _)| !lang_features_status.contains_key(name))
.collect();
let features_status = FeaturesStatus { lang_features_status, lib_features_status };
let output_dir = output_path.parent().with_context(|| {
format!("failed to get parent dir of output path `{}`", output_path.display())
})?;
std::fs::create_dir_all(output_dir).with_context(|| {
format!("failed to create output directory at `{}`", output_dir.display())
})?;
let output_file = File::create(&output_path).with_context(|| {
format!("failed to create file at given output path `{}`", output_path.display())
})?;
let writer = BufWriter::new(output_file);
serde_json::to_writer_pretty(writer, &features_status)
.context("failed to write json output")?;
Ok(())
}

View File

@ -12,11 +12,15 @@ miropt-test-tools = { path = "../miropt-test-tools" }
walkdir = "2"
ignore = "0.4.18"
semver = "1.0"
serde = { version = "1.0.125", features = ["derive"], optional = true }
termcolor = "1.1.3"
rustc-hash = "2.0.0"
fluent-syntax = "0.11.1"
similar = "2.5.0"
[features]
build-metrics = ["dep:serde"]
[[bin]]
name = "rust-tidy"
path = "src/main.rs"

View File

@ -27,6 +27,7 @@ const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start";
const FEATURE_GROUP_END_PREFIX: &str = "// feature-group-end";
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
pub enum Status {
Accepted,
Removed,
@ -45,6 +46,7 @@ impl fmt::Display for Status {
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
pub struct Feature {
pub level: Status,
pub since: Option<Version>,

View File

@ -8,6 +8,7 @@ mod tests;
pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
pub enum Version {
Explicit { parts: [u32; 3] },
CurrentPlaceholder,

View File

@ -48,8 +48,9 @@ const EXCEPTION_PATHS: &[&str] = &[
// we must use `#[cfg(windows)]` to conditionally compile the
// correct `VaList` structure for windows.
"library/core/src/ffi/va_list.rs",
// We placed a linkage against Windows libraries here
// core::ffi contains platform-specific type and linkage configuration
"library/core/src/ffi/mod.rs",
"library/core/src/ffi/primitives.rs",
"library/std/src/sys", // Platform-specific code for std lives here.
"library/std/src/os", // Platform-specific public interfaces
// Temporary `std` exceptions

View File

@ -1,6 +1,6 @@
// Verify that debuginfo column numbers are 1-based byte offsets.
//
//@ ignore-windows
//@ ignore-msvc
//@ compile-flags: -C debuginfo=2
#[rustfmt::skip]

View File

@ -1,5 +1,5 @@
//@ compile-flags: -C no-prepopulate-passes -C panic=abort -C force-unwind-tables=n
//@ ignore-windows
//@ ignore-windows: unwind tables are required for panics on Windows
#![crate_type = "lib"]

View File

@ -1,6 +1,6 @@
//@ compile-flags: -O
//@ aux-build:thread_local_aux.rs
//@ ignore-windows FIXME(#84933)
//@ ignore-windows FIXME(#134939)
//@ ignore-wasm globals are used instead of thread locals
//@ ignore-emscripten globals are used instead of thread locals
//@ ignore-android does not use #[thread_local]

View File

@ -2,6 +2,10 @@
//@compile-flags: -Clink-dead-code=true --crate-type lib
//@ only-x86_64
//@ ignore-windows
// The set of targets this crashes on is really fiddly, because it is deep in our ABI logic. It
// crashes on x86_64-unknown-linux-gnu, and i686-pc-windows-msvc, but not on
// x86_64-pc-windows-msvc. If you are trying to fix this crash, don't pay too much attention to the
// directives.
#![feature(rust_cold_cc)]
pub extern "rust-cold" fn foo(_: [usize; 3]) {}

View File

@ -19,16 +19,16 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
scope 2 {
debug x => _9;
}
scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
scope 5 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
}
}
scope 3 (inlined RangeInclusive::<u32>::new) {
scope 3 (inlined std::ops::RangeInclusive::<u32>::new) {
}
scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) {
scope 4 (inlined <std::ops::RangeInclusive<u32> as IntoIterator>::into_iter) {
}
bb0: {
_4 = RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
_4 = std::ops::RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
StorageLive(_5);
_5 = copy _4;
goto -> bb1;
@ -37,7 +37,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
bb1: {
StorageLive(_7);
_6 = &mut _5;
_7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable];
_7 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable];
}
bb2: {

View File

@ -19,16 +19,16 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
scope 2 {
debug x => _9;
}
scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
scope 5 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
}
}
scope 3 (inlined RangeInclusive::<u32>::new) {
scope 3 (inlined std::ops::RangeInclusive::<u32>::new) {
}
scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) {
scope 4 (inlined <std::ops::RangeInclusive<u32> as IntoIterator>::into_iter) {
}
bb0: {
_4 = RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
_4 = std::ops::RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
StorageLive(_5);
_5 = copy _4;
goto -> bb1;
@ -37,7 +37,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
bb1: {
StorageLive(_7);
_6 = &mut _5;
_7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8];
_7 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8];
}
bb2: {

View File

@ -1,13 +1,13 @@
// MIR for `range_inclusive_iter_next` after PreCodegen
fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
fn range_inclusive_iter_next(_1: &mut std::ops::RangeInclusive<u32>) -> Option<u32> {
debug it => _1;
let mut _0: std::option::Option<u32>;
scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
scope 1 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
}
bb0: {
_0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind unreachable];
_0 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind unreachable];
}
bb1: {

View File

@ -1,13 +1,13 @@
// MIR for `range_inclusive_iter_next` after PreCodegen
fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
fn range_inclusive_iter_next(_1: &mut std::ops::RangeInclusive<u32>) -> Option<u32> {
debug it => _1;
let mut _0: std::option::Option<u32>;
scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
scope 1 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
}
bb0: {
_0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue];
_0 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue];
}
bb1: {

View File

@ -1,4 +1,4 @@
//@ ignore-windows
//@ ignore-windows different error message
//@ revisions: edition2015 edition2024
//@[edition2015]edition:2015
//@[edition2015]check-fail

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]
#![feature(assert_matches)]

View File

@ -5,7 +5,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]
#![feature(assert_matches)]

View File

@ -5,7 +5,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -8,7 +8,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]
#![feature(assert_matches)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

View File

@ -4,7 +4,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
#![feature(rustc_private)]
#![feature(assert_matches)]

View File

@ -5,7 +5,6 @@
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]

Some files were not shown because too many files have changed in this diff Show More