From 3fd8c6432df4396c7f593e570a27b8d7c1a78b5b Mon Sep 17 00:00:00 2001 From: ultrabear Date: Sat, 13 Apr 2024 04:15:10 -0700 Subject: [PATCH 01/72] doc note that f16 and f128 hardware support is limited --- library/core/src/primitive_docs.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index e8e23f2a7ecc5..6b142c1a0cdf4 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1082,6 +1082,9 @@ impl (T,) {} /// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// half-precision values][wikipedia] for more information. /// +/// Note that not all major platforms have hardware support for f16, in which case a +/// software implementation will be used. This may be slower than expected. +/// /// *[See also the `std::f16::consts` module](crate::f16::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format @@ -1181,6 +1184,9 @@ mod prim_f64 {} /// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// quad-precision values][wikipedia] for more information. /// +/// Note that not all major platforms have hardware support for f128, in which case a +/// software implementation will be used. This may be slower than expected. +/// /// *[See also the `std::f128::consts` module](crate::f128::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format From fc37633580af9da06ab5e01e595a51f1e7c54cc7 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Sat, 9 Mar 2024 11:56:17 -0800 Subject: [PATCH 02/72] Support Result across FFI when niche optimization can be used Allow allow enums like `Result` to be used across FFI if the T/E can be niche optimized and the non-niche-optimized type is FFI safe. --- compiler/rustc_lint/src/types.rs | 48 +++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index e982842f5363f..001bf27afb9cc 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1099,6 +1099,32 @@ fn get_nullable_type<'tcx>( }) } +/// A type is niche_optimization_candiate iff: +/// - Is a zero-sized type with alignment 1 (a “1-ZST”). +/// - Has no fields. +/// - Does not have the #[non_exhaustive] attribute. +fn is_niche_optimization_candidate<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, +) -> bool { + if !tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| layout.is_1zst()) { + return false; + } + + match ty.kind() { + ty::Adt(ty_def, _) => { + let non_exhaustive = ty_def.is_variant_list_non_exhaustive() + || ty_def.variants().iter().any(|variant| variant.is_field_list_non_exhaustive()); + let contains_no_fields = ty_def.all_fields().next().is_none(); + + !non_exhaustive && contains_no_fields + } + ty::Tuple(tys) => tys.is_empty(), + _ => false, + } +} + /// Check if this enum can be safely exported based on the "nullable pointer optimization". If it /// can, return the type that `ty` can be safely converted to, otherwise return `None`. /// Currently restricted to function pointers, boxes, references, `core::num::NonZero`, @@ -1115,6 +1141,26 @@ pub(crate) fn repr_nullable_ptr<'tcx>( let field_ty = match &ty_def.variants().raw[..] { [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { ([], [field]) | ([field], []) => field.ty(tcx, args), + ([field1], [field2]) => { + // TODO: We pass all the checks here although individual enum variants has + // checks for FFI safety even when niche optimized which needs to be + // suppressed. for types like `Result, E>`, PhantomData has + // it's own lint for FFI which needs to be suppressed: `composed only of + // `PhantomData``. This is true for other custom types as well `struct + // Example;` which emits `this struct has unspecified layout` and suggests to + // add `#[repr(C)]` and when that is done, linter emits `this struct has no + // fields`, all under the `improper_ctypes_definitions` lint group + let ty1 = field1.ty(tcx, args); + let ty2 = field2.ty(tcx, args); + + if is_niche_optimization_candidate(tcx, param_env, ty1) { + ty2 + } else if is_niche_optimization_candidate(tcx, param_env, ty2) { + ty1 + } else { + return None; + } + } _ => return None, }, _ => return None, @@ -1331,7 +1377,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // discriminant. if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none() { - // Special-case types like `Option`. + // Special-case types like `Option` and `Result` if repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode) .is_none() { From b3e6d52e49345db9e59c955b79ca3ea7cf4f7afc Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Sat, 9 Mar 2024 12:35:17 -0800 Subject: [PATCH 03/72] We don't need to check for non-exhaustive fields Fields are disallowed so checking the top attribute is enough. --- compiler/rustc_lint/src/types.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 001bf27afb9cc..ae118ffbf4c38 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1114,8 +1114,7 @@ fn is_niche_optimization_candidate<'tcx>( match ty.kind() { ty::Adt(ty_def, _) => { - let non_exhaustive = ty_def.is_variant_list_non_exhaustive() - || ty_def.variants().iter().any(|variant| variant.is_field_list_non_exhaustive()); + let non_exhaustive = ty_def.is_variant_list_non_exhaustive(); let contains_no_fields = ty_def.all_fields().next().is_none(); !non_exhaustive && contains_no_fields From 08b85a1c5381cfc9c62347996b4b5c0316522b60 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Sat, 9 Mar 2024 14:30:01 -0800 Subject: [PATCH 04/72] Don't lint niche optimized variants in enums --- compiler/rustc_lint/src/types.rs | 33 +++++++++++++------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index ae118ffbf4c38..1fd358836a2cf 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1141,14 +1141,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>( [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { ([], [field]) | ([field], []) => field.ty(tcx, args), ([field1], [field2]) => { - // TODO: We pass all the checks here although individual enum variants has - // checks for FFI safety even when niche optimized which needs to be - // suppressed. for types like `Result, E>`, PhantomData has - // it's own lint for FFI which needs to be suppressed: `composed only of - // `PhantomData``. This is true for other custom types as well `struct - // Example;` which emits `this struct has unspecified layout` and suggests to - // add `#[repr(C)]` and when that is done, linter emits `this struct has no - // fields`, all under the `improper_ctypes_definitions` lint group let ty1 = field1.ty(tcx, args); let ty2 = field2.ty(tcx, args); @@ -1245,7 +1237,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { args: GenericArgsRef<'tcx>, ) -> FfiResult<'tcx> { use FfiResult::*; - let transparent_with_all_zst_fields = if def.repr().transparent() { if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { // Transparent newtypes have at most one non-ZST field which needs to be checked.. @@ -1372,27 +1363,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiSafe; } + if def.is_variant_list_non_exhaustive() && !def.did().is_local() { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_non_exhaustive, + help: None, + }; + } + // Check for a repr() attribute to specify the size of the // discriminant. if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none() { // Special-case types like `Option` and `Result` - if repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode) - .is_none() + if let Some(ty) = + repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode) { - return FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_enum_repr_reason, - help: Some(fluent::lint_improper_ctypes_enum_repr_help), - }; + return self.check_type_for_ffi(cache, ty); } - } - if def.is_variant_list_non_exhaustive() && !def.did().is_local() { return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_non_exhaustive, - help: None, + reason: fluent::lint_improper_ctypes_enum_repr_reason, + help: Some(fluent::lint_improper_ctypes_enum_repr_help), }; } From 223d5eb64f492a41801396e34e714a657d020ac6 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Sat, 9 Mar 2024 14:34:08 -0800 Subject: [PATCH 05/72] Add tests Tests both `T` and `E` for niche variant optimization lints --- tests/ui/lint/lint-ctypes-enum.rs | 144 +++++++++++++++----- tests/ui/lint/lint-ctypes-enum.stderr | 183 ++++++++++++++++++++++---- 2 files changed, 270 insertions(+), 57 deletions(-) diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index c60290f8553a7..8d60a8dd3171f 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -55,38 +55,120 @@ union TransparentUnion { struct Rust(T); +struct NoField; + +#[repr(transparent)] +struct Field(()); + +#[non_exhaustive] +enum NonExhaustive {} + extern "C" { - fn zf(x: Z); - fn uf(x: U); //~ ERROR `extern` block uses type `U` - fn bf(x: B); //~ ERROR `extern` block uses type `B` - fn tf(x: T); //~ ERROR `extern` block uses type `T` - fn repr_c(x: ReprC); - fn repr_u8(x: U8); - fn repr_isize(x: Isize); - fn option_ref(x: Option<&'static u8>); - fn option_fn(x: Option); - fn nonnull(x: Option>); - fn unique(x: Option>); - fn nonzero_u8(x: Option>); - fn nonzero_u16(x: Option>); - fn nonzero_u32(x: Option>); - fn nonzero_u64(x: Option>); - fn nonzero_u128(x: Option>); - //~^ ERROR `extern` block uses type `u128` - fn nonzero_usize(x: Option>); - fn nonzero_i8(x: Option>); - fn nonzero_i16(x: Option>); - fn nonzero_i32(x: Option>); - fn nonzero_i64(x: Option>); - fn nonzero_i128(x: Option>); - //~^ ERROR `extern` block uses type `i128` - fn nonzero_isize(x: Option>); - fn transparent_struct(x: Option>>); - fn transparent_enum(x: Option>>); - fn transparent_union(x: Option>>); - //~^ ERROR `extern` block uses type - fn repr_rust(x: Option>>); //~ ERROR `extern` block uses type - fn no_result(x: Result<(), num::NonZero>); //~ ERROR `extern` block uses type + fn zf(x: Z); + fn uf(x: U); //~ ERROR `extern` block uses type `U` + fn bf(x: B); //~ ERROR `extern` block uses type `B` + fn tf(x: T); //~ ERROR `extern` block uses type `T` + fn repr_c(x: ReprC); + fn repr_u8(x: U8); + fn repr_isize(x: Isize); + fn option_ref(x: Option<&'static u8>); + fn option_fn(x: Option); + fn option_nonnull(x: Option>); + fn option_unique(x: Option>); + fn option_nonzero_u8(x: Option>); + fn option_nonzero_u16(x: Option>); + fn option_nonzero_u32(x: Option>); + fn option_nonzero_u64(x: Option>); + fn option_nonzero_u128(x: Option>); + //~^ ERROR `extern` block uses type `u128` + fn option_nonzero_usize(x: Option>); + fn option_nonzero_i8(x: Option>); + fn option_nonzero_i16(x: Option>); + fn option_nonzero_i32(x: Option>); + fn option_nonzero_i64(x: Option>); + fn option_nonzero_i128(x: Option>); + //~^ ERROR `extern` block uses type `i128` + fn option_nonzero_isize(x: Option>); + fn option_transparent_struct(x: Option>>); + fn option_transparent_enum(x: Option>>); + fn option_transparent_union(x: Option>>); + //~^ ERROR `extern` block uses type + fn option_repr_rust(x: Option>>); //~ ERROR `extern` block uses type + + fn result_ref_t(x: Result<&'static u8, ()>); + fn result_fn_t(x: Result); + fn result_nonnull_t(x: Result, ()>); + fn result_unique_t(x: Result, ()>); + fn result_nonzero_u8_t(x: Result, ()>); + fn result_nonzero_u16_t(x: Result, ()>); + fn result_nonzero_u32_t(x: Result, ()>); + fn result_nonzero_u64_t(x: Result, ()>); + fn result_nonzero_u128_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `u128` + fn result_nonzero_usize_t(x: Result, ()>); + fn result_nonzero_i8_t(x: Result, ()>); + fn result_nonzero_i16_t(x: Result, ()>); + fn result_nonzero_i32_t(x: Result, ()>); + fn result_nonzero_i64_t(x: Result, ()>); + fn result_nonzero_i128_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `i128` + fn result_nonzero_isize_t(x: Result, ()>); + fn result_transparent_struct_t(x: Result>, ()>); + fn result_transparent_enum_t(x: Result>, ()>); + fn result_transparent_union_t(x: Result>, ()>); + //~^ ERROR `extern` block uses type + fn result_repr_rust_t(x: Result>, ()>); + //~^ ERROR `extern` block uses type + fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); + fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); + fn result_1zst_exhaustive_single_variant_t(x: Result, U>); + fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); + //~^ ERROR `extern` block uses type + fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); + //~^ ERROR `extern` block uses type + fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); + fn result_1zst_exhaustive_single_field_t(x: Result, Field>); + //~^ ERROR `extern` block uses type + fn result_cascading_t(x: Result>, ()>); + //~^ ERROR `extern` block uses type + + fn result_ref_e(x: Result<(), &'static u8>); + fn result_fn_e(x: Result<(), extern "C" fn()>); + fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); + fn result_unique_e(x: Result<(), std::ptr::Unique>); + fn result_nonzero_u8_e(x: Result<(), num::NonZero>); + fn result_nonzero_u16_e(x: Result<(), num::NonZero>); + fn result_nonzero_u32_e(x: Result<(), num::NonZero>); + fn result_nonzero_u64_e(x: Result<(), num::NonZero>); + fn result_nonzero_u128_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `u128` + fn result_nonzero_usize_e(x: Result<(), num::NonZero>); + fn result_nonzero_i8_e(x: Result<(), num::NonZero>); + fn result_nonzero_i16_e(x: Result<(), num::NonZero>); + fn result_nonzero_i32_e(x: Result<(), num::NonZero>); + fn result_nonzero_i64_e(x: Result<(), num::NonZero>); + fn result_nonzero_i128_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `i128` + fn result_nonzero_isize_e(x: Result<(), num::NonZero>); + fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); + fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); + fn result_transparent_union_e(x: Result<(), TransparentUnion>>); + //~^ ERROR `extern` block uses type + fn result_repr_rust_e(x: Result<(), Rust>>); + //~^ ERROR `extern` block uses type + fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); + fn result_1zst_exhaustive_no_variant_e(x: Result>); + fn result_1zst_exhaustive_single_variant_e(x: Result>); + fn result_1zst_exhaustive_multiple_variant_e(x: Result>); + //~^ ERROR `extern` block uses type + fn result_1zst_non_exhaustive_no_variant_e(x: Result>); + //~^ ERROR `extern` block uses type + fn result_1zst_exhaustive_no_field_e(x: Result>); + fn result_1zst_exhaustive_single_field_e(x: Result>); + //~^ ERROR `extern` block uses type + fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); + //~^ ERROR `extern` block uses type + } pub fn main() {} diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index 103fda8d40253..c982f040fb6fb 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -1,8 +1,8 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:60:13 + --> $DIR/lint-ctypes-enum.rs:68:14 | -LL | fn uf(x: U); - | ^ not FFI-safe +LL | fn uf(x: U); + | ^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint @@ -18,10 +18,10 @@ LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:61:13 + --> $DIR/lint-ctypes-enum.rs:69:14 | -LL | fn bf(x: B); - | ^ not FFI-safe +LL | fn bf(x: B); + | ^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint @@ -32,10 +32,10 @@ LL | enum B { | ^^^^^^ error: `extern` block uses type `T`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:62:13 + --> $DIR/lint-ctypes-enum.rs:70:14 | -LL | fn tf(x: T); - | ^ not FFI-safe +LL | fn tf(x: T); + | ^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint @@ -46,47 +46,178 @@ LL | enum T { | ^^^^^^ error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:74:23 + --> $DIR/lint-ctypes-enum.rs:82:31 | -LL | fn nonzero_u128(x: Option>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn option_nonzero_u128(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:81:23 + --> $DIR/lint-ctypes-enum.rs:89:31 | -LL | fn nonzero_i128(x: Option>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn option_nonzero_i128(x: Option>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:86:28 + --> $DIR/lint-ctypes-enum.rs:94:36 | -LL | fn transparent_union(x: Option>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn option_transparent_union(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:88:20 + --> $DIR/lint-ctypes-enum.rs:96:28 | -LL | fn repr_rust(x: Option>>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn option_repr_rust(x: Option>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:89:20 +error: `extern` block uses type `u128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:106:33 + | +LL | fn result_nonzero_u128_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI + +error: `extern` block uses type `i128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:113:33 + | +LL | fn result_nonzero_i128_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI + +error: `extern` block uses type `Result>, ()>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:118:38 + | +LL | fn result_transparent_union_t(x: Result>, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>, ()>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:120:30 + | +LL | fn result_repr_rust_t(x: Result>, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, B>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:125:53 + | +LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:127:51 + | +LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, Field>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:130:49 + | +LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>, ()>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:132:30 + | +LL | fn result_cascading_t(x: Result>, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `u128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:143:33 + | +LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI + +error: `extern` block uses type `i128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:150:33 + | +LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI + +error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:155:38 + | +LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), Rust>>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:157:30 + | +LL | fn result_repr_rust_e(x: Result<(), Rust>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:162:53 + | +LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:164:51 + | +LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:167:49 + | +LL | fn result_1zst_exhaustive_single_field_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), Result<(), NonZero>>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:169:30 | -LL | fn no_result(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: aborting due to 8 previous errors +error: aborting due to 23 previous errors From 014ddac9c98d827237c1179050e5f96312884254 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Sat, 9 Mar 2024 15:13:29 -0800 Subject: [PATCH 06/72] Disallow single-variant enums Couldn't find documentation supporting that single-variant `#[repr(Rust)]` enums with RHS assigned work as expected with this change. ```rust enum Variants { A = 17, } // Would this be zero sized optimized guaranteed? ``` --- compiler/rustc_lint/src/types.rs | 10 +++--- tests/ui/lint/lint-ctypes-enum.rs | 2 ++ tests/ui/lint/lint-ctypes-enum.stderr | 44 +++++++++++++++++++-------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 1fd358836a2cf..d491de7609beb 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1102,22 +1102,24 @@ fn get_nullable_type<'tcx>( /// A type is niche_optimization_candiate iff: /// - Is a zero-sized type with alignment 1 (a “1-ZST”). /// - Has no fields. -/// - Does not have the #[non_exhaustive] attribute. +/// - Does not have the `#[non_exhaustive]` attribute. fn is_niche_optimization_candidate<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> bool { - if !tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| layout.is_1zst()) { + if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) { return false; } match ty.kind() { ty::Adt(ty_def, _) => { let non_exhaustive = ty_def.is_variant_list_non_exhaustive(); - let contains_no_fields = ty_def.all_fields().next().is_none(); + // Should single-variant enums be allowed? + let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none()) + || (ty_def.is_enum() && ty_def.variants().is_empty()); - !non_exhaustive && contains_no_fields + !non_exhaustive && empty } ty::Tuple(tys) => tys.is_empty(), _ => false, diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index 8d60a8dd3171f..b69ee82f8aeb1 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -122,6 +122,7 @@ extern "C" { fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); fn result_1zst_exhaustive_single_variant_t(x: Result, U>); + //~^ ERROR `extern` block uses type fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); //~^ ERROR `extern` block uses type fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); @@ -159,6 +160,7 @@ extern "C" { fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); fn result_1zst_exhaustive_no_variant_e(x: Result>); fn result_1zst_exhaustive_single_variant_e(x: Result>); + //~^ ERROR `extern` block uses type fn result_1zst_exhaustive_multiple_variant_e(x: Result>); //~^ ERROR `extern` block uses type fn result_1zst_non_exhaustive_no_variant_e(x: Result>); diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index c982f040fb6fb..ab1eb67c07510 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -113,8 +113,17 @@ LL | fn result_repr_rust_t(x: Result>, ()>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint +error: `extern` block uses type `Result, U>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:124:51 + | +LL | fn result_1zst_exhaustive_single_variant_t(x: Result, U>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + error: `extern` block uses type `Result, B>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:125:53 + --> $DIR/lint-ctypes-enum.rs:126:53 | LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -123,7 +132,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result = note: enum has no representation hint error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:127:51 + --> $DIR/lint-ctypes-enum.rs:128:51 | LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -132,7 +141,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, Field>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:130:49 + --> $DIR/lint-ctypes-enum.rs:131:49 | LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -141,7 +150,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result, Fi = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:132:30 + --> $DIR/lint-ctypes-enum.rs:133:30 | LL | fn result_cascading_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -150,7 +159,7 @@ LL | fn result_cascading_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:143:33 + --> $DIR/lint-ctypes-enum.rs:144:33 | LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -158,7 +167,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:150:33 + --> $DIR/lint-ctypes-enum.rs:151:33 | LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -166,7 +175,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:155:38 + --> $DIR/lint-ctypes-enum.rs:156:38 | LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -175,7 +184,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:157:30 + --> $DIR/lint-ctypes-enum.rs:158:30 | LL | fn result_repr_rust_e(x: Result<(), Rust>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -183,8 +192,17 @@ LL | fn result_repr_rust_e(x: Result<(), Rust>>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:162:51 + | +LL | fn result_1zst_exhaustive_single_variant_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + error: `extern` block uses type `Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:162:53 + --> $DIR/lint-ctypes-enum.rs:164:53 | LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -193,7 +211,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:164:51 + --> $DIR/lint-ctypes-enum.rs:166:51 | LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -202,7 +220,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:167:49 + --> $DIR/lint-ctypes-enum.rs:169:49 | LL | fn result_1zst_exhaustive_single_field_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -211,7 +229,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:169:30 + --> $DIR/lint-ctypes-enum.rs:171:30 | LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -219,5 +237,5 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: aborting due to 23 previous errors +error: aborting due to 25 previous errors From b3f6511755228ee3ff2e59c69f575454f6eb3108 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Mon, 18 Mar 2024 19:45:40 -0700 Subject: [PATCH 07/72] Add a test against Result<(), ()> --- tests/ui/lint/lint-ctypes-enum.rs | 3 ++- tests/ui/lint/lint-ctypes-enum.stderr | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index b69ee82f8aeb1..19af1de95760b 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -170,7 +170,8 @@ extern "C" { //~^ ERROR `extern` block uses type fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); //~^ ERROR `extern` block uses type - + fn result_unit_t_e(x: Result<(), ()>); + //~^ ERROR `extern` block uses type } pub fn main() {} diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index ab1eb67c07510..8d7b28bfb7ddf 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -237,5 +237,14 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: aborting due to 25 previous errors +error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:174:27 + | +LL | fn result_unit_t_e(x: Result<(), ()>); + | ^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: aborting due to 26 previous errors From 764f64f0d7e8a51adb05f29bee11909b4f446579 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Mon, 18 Mar 2024 19:47:43 -0700 Subject: [PATCH 08/72] Reword `is_niche_optimization_candidate` doc --- compiler/rustc_lint/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d491de7609beb..5db5f4ab9eedc 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1099,7 +1099,7 @@ fn get_nullable_type<'tcx>( }) } -/// A type is niche_optimization_candiate iff: +/// A type is niche-optimization candidate iff: /// - Is a zero-sized type with alignment 1 (a “1-ZST”). /// - Has no fields. /// - Does not have the `#[non_exhaustive]` attribute. From 437ca26de5d2fe25a37f88956b6225344084fd1d Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Mon, 18 Mar 2024 19:48:40 -0700 Subject: [PATCH 09/72] Remove comment out of RFC's scope --- compiler/rustc_lint/src/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 5db5f4ab9eedc..09fdceb156cf6 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1115,7 +1115,6 @@ fn is_niche_optimization_candidate<'tcx>( match ty.kind() { ty::Adt(ty_def, _) => { let non_exhaustive = ty_def.is_variant_list_non_exhaustive(); - // Should single-variant enums be allowed? let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none()) || (ty_def.is_enum() && ty_def.variants().is_empty()); From ed532cc186a651a3e4b848ffbef8c080018f1732 Mon Sep 17 00:00:00 2001 From: Arvind Mukund Date: Mon, 18 Mar 2024 20:31:48 -0700 Subject: [PATCH 10/72] Put the RFC behind a feature gate `result_ffi_guarantees` --- compiler/rustc_feature/src/unstable.rs | 3 + compiler/rustc_lint/src/types.rs | 4 + compiler/rustc_span/src/symbol.rs | 1 + .../result-ffi-guarantees.md | 14 + .../feature-gate-result_ffi_guarantees.rs | 99 +++++ .../feature-gate-result_ffi_guarantees.stderr | 349 ++++++++++++++++++ tests/ui/lint/lint-ctypes-enum.rs | 1 + tests/ui/lint/lint-ctypes-enum.stderr | 56 +-- 8 files changed, 499 insertions(+), 28 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/result-ffi-guarantees.md create mode 100644 tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs create mode 100644 tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 9641d336c3f3c..eec0d0eb5298a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -585,6 +585,9 @@ declare_features! ( (incomplete, repr128, "1.16.0", Some(56071)), /// Allows `repr(simd)` and importing the various simd intrinsics. (unstable, repr_simd, "1.4.0", Some(27731)), + /// Allows enums like Result to be used across FFI, if T's niche value can + /// be used to describe E or vise-versa. + (unstable, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)), /// Allows bounding the return type of AFIT/RPITIT. (incomplete, return_type_notation, "1.70.0", Some(109417)), /// Allows `extern "rust-cold"`. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 09fdceb156cf6..b3fd03d3f78bf 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1142,6 +1142,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>( [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { ([], [field]) | ([field], []) => field.ty(tcx, args), ([field1], [field2]) => { + if !tcx.features().result_ffi_guarantees { + return None; + } + let ty1 = field1.ty(tcx, args); let ty2 = field2.ty(tcx, args); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8abf42e2c1392..ff9b2a413c952 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1509,6 +1509,7 @@ symbols! { require, residual, result, + result_ffi_guarantees, resume, return_position_impl_trait_in_trait, return_type_notation, diff --git a/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md b/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md new file mode 100644 index 0000000000000..dc9c196524ed4 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/result-ffi-guarantees.md @@ -0,0 +1,14 @@ +# `result_ffi_guarantees` + +The tracking issue for this feature is: [#110503] + +[#110503]: https://github.com/rust-lang/rust/issues/110503 + +------------------------ + +This feature adds the possibility of using `Result` in FFI if T's niche +value can be used to describe E or vise-versa. + +See [RFC 3391] for more information. + +[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs new file mode 100644 index 0000000000000..dda317aecc3c3 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.rs @@ -0,0 +1,99 @@ +#![allow(dead_code)] +#![deny(improper_ctypes)] +#![feature(ptr_internals)] + +use std::num; + +enum Z {} + +#[repr(transparent)] +struct TransparentStruct(T, std::marker::PhantomData); + +#[repr(transparent)] +enum TransparentEnum { + Variant(T, std::marker::PhantomData), +} + +struct NoField; + +extern "C" { + fn result_ref_t(x: Result<&'static u8, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_fn_t(x: Result); + //~^ ERROR `extern` block uses type `Result + fn result_nonnull_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_unique_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u8_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u16_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u32_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u64_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_usize_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i8_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i16_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i32_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i64_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_isize_t(x: Result, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_transparent_struct_t(x: Result>, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_transparent_enum_t(x: Result>, ()>); + //~^ ERROR `extern` block uses type `Result + fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); + //~^ ERROR `extern` block uses type `Result + fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); + //~^ ERROR `extern` block uses type `Result + fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); + //~^ ERROR `extern` block uses type `Result + + fn result_ref_e(x: Result<(), &'static u8>); + //~^ ERROR `extern` block uses type `Result + fn result_fn_e(x: Result<(), extern "C" fn()>); + //~^ ERROR `extern` block uses type `Result + fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); + //~^ ERROR `extern` block uses type `Result + fn result_unique_e(x: Result<(), std::ptr::Unique>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u8_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u16_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u32_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_u64_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_usize_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i8_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i16_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i32_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_i64_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_nonzero_isize_e(x: Result<(), num::NonZero>); + //~^ ERROR `extern` block uses type `Result + fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); + //~^ ERROR `extern` block uses type `Result + fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); + //~^ ERROR `extern` block uses type `Result + fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); + //~^ ERROR `extern` block uses type `Result + fn result_1zst_exhaustive_no_variant_e(x: Result>); + //~^ ERROR `extern` block uses type `Result + fn result_1zst_exhaustive_no_field_e(x: Result>); + //~^ ERROR `extern` block uses type `Result +} + +pub fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr new file mode 100644 index 0000000000000..94416eb99c878 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-result_ffi_guarantees.stderr @@ -0,0 +1,349 @@ +error: `extern` block uses type `Result<&u8, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:20:24 + | +LL | fn result_ref_t(x: Result<&'static u8, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint +note: the lint level is defined here + --> $DIR/feature-gate-result_ffi_guarantees.rs:2:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ + +error: `extern` block uses type `Result`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:22:23 + | +LL | fn result_fn_t(x: Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:24:28 + | +LL | fn result_nonnull_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:26:27 + | +LL | fn result_unique_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:28:31 + | +LL | fn result_nonzero_u8_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:30:32 + | +LL | fn result_nonzero_u16_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:32:32 + | +LL | fn result_nonzero_u32_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:34:32 + | +LL | fn result_nonzero_u64_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:36:34 + | +LL | fn result_nonzero_usize_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:38:31 + | +LL | fn result_nonzero_i8_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:40:32 + | +LL | fn result_nonzero_i16_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:42:32 + | +LL | fn result_nonzero_i32_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:44:32 + | +LL | fn result_nonzero_i64_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:46:34 + | +LL | fn result_nonzero_isize_t(x: Result, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:48:39 + | +LL | fn result_transparent_struct_t(x: Result>, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>, ()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:50:37 + | +LL | fn result_transparent_enum_t(x: Result>, ()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, PhantomData<()>>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:52:28 + | +LL | fn result_phantom_t(x: Result, std::marker::PhantomData<()>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, Z>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:54:47 + | +LL | fn result_1zst_exhaustive_no_variant_t(x: Result, Z>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, NoField>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:56:45 + | +LL | fn result_1zst_exhaustive_no_field_t(x: Result, NoField>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), &u8>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:59:24 + | +LL | fn result_ref_e(x: Result<(), &'static u8>); + | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), extern "C" fn()>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:61:23 + | +LL | fn result_fn_e(x: Result<(), extern "C" fn()>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonNull>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:63:28 + | +LL | fn result_nonnull_e(x: Result<(), std::ptr::NonNull>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), Unique>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:65:27 + | +LL | fn result_unique_e(x: Result<(), std::ptr::Unique>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:67:31 + | +LL | fn result_nonzero_u8_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:69:32 + | +LL | fn result_nonzero_u16_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:71:32 + | +LL | fn result_nonzero_u32_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:73:32 + | +LL | fn result_nonzero_u64_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:75:34 + | +LL | fn result_nonzero_usize_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:77:31 + | +LL | fn result_nonzero_i8_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:79:32 + | +LL | fn result_nonzero_i16_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:81:32 + | +LL | fn result_nonzero_i32_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:83:32 + | +LL | fn result_nonzero_i64_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), NonZero>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:85:34 + | +LL | fn result_nonzero_isize_e(x: Result<(), num::NonZero>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), TransparentStruct>>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:87:39 + | +LL | fn result_transparent_struct_e(x: Result<(), TransparentStruct>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result<(), TransparentEnum>>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:89:37 + | +LL | fn result_transparent_enum_e(x: Result<(), TransparentEnum>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result, PhantomData<()>>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:91:28 + | +LL | fn result_phantom_e(x: Result, std::marker::PhantomData<()>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:93:47 + | +LL | fn result_1zst_exhaustive_no_variant_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: `extern` block uses type `Result>`, which is not FFI-safe + --> $DIR/feature-gate-result_ffi_guarantees.rs:95:45 + | +LL | fn result_1zst_exhaustive_no_field_e(x: Result>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint + +error: aborting due to 38 previous errors + diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index 19af1de95760b..cb8e9e8067513 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -2,6 +2,7 @@ #![deny(improper_ctypes)] #![feature(ptr_internals)] #![feature(transparent_unions)] +#![feature(result_ffi_guarantees)] use std::num; diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index 8d7b28bfb7ddf..bba5b09b69cc9 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:68:14 + --> $DIR/lint-ctypes-enum.rs:69:14 | LL | fn uf(x: U); | ^ not FFI-safe @@ -7,7 +7,7 @@ LL | fn uf(x: U); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:9:1 + --> $DIR/lint-ctypes-enum.rs:10:1 | LL | enum U { | ^^^^^^ @@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:69:14 + --> $DIR/lint-ctypes-enum.rs:70:14 | LL | fn bf(x: B); | ^ not FFI-safe @@ -26,13 +26,13 @@ LL | fn bf(x: B); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:12:1 + --> $DIR/lint-ctypes-enum.rs:13:1 | LL | enum B { | ^^^^^^ error: `extern` block uses type `T`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:70:14 + --> $DIR/lint-ctypes-enum.rs:71:14 | LL | fn tf(x: T); | ^ not FFI-safe @@ -40,13 +40,13 @@ LL | fn tf(x: T); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:16:1 + --> $DIR/lint-ctypes-enum.rs:17:1 | LL | enum T { | ^^^^^^ error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:82:31 + --> $DIR/lint-ctypes-enum.rs:83:31 | LL | fn option_nonzero_u128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -54,7 +54,7 @@ LL | fn option_nonzero_u128(x: Option>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:89:31 + --> $DIR/lint-ctypes-enum.rs:90:31 | LL | fn option_nonzero_i128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -62,7 +62,7 @@ LL | fn option_nonzero_i128(x: Option>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:94:36 + --> $DIR/lint-ctypes-enum.rs:95:36 | LL | fn option_transparent_union(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -71,7 +71,7 @@ LL | fn option_transparent_union(x: Option = note: enum has no representation hint error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:96:28 + --> $DIR/lint-ctypes-enum.rs:97:28 | LL | fn option_repr_rust(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -80,7 +80,7 @@ LL | fn option_repr_rust(x: Option>>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:106:33 + --> $DIR/lint-ctypes-enum.rs:107:33 | LL | fn result_nonzero_u128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -88,7 +88,7 @@ LL | fn result_nonzero_u128_t(x: Result, ()>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:113:33 + --> $DIR/lint-ctypes-enum.rs:114:33 | LL | fn result_nonzero_i128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -96,7 +96,7 @@ LL | fn result_nonzero_i128_t(x: Result, ()>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:118:38 + --> $DIR/lint-ctypes-enum.rs:119:38 | LL | fn result_transparent_union_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -105,7 +105,7 @@ LL | fn result_transparent_union_t(x: Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:120:30 + --> $DIR/lint-ctypes-enum.rs:121:30 | LL | fn result_repr_rust_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -114,7 +114,7 @@ LL | fn result_repr_rust_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `Result, U>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:124:51 + --> $DIR/lint-ctypes-enum.rs:125:51 | LL | fn result_1zst_exhaustive_single_variant_t(x: Result, U>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -123,7 +123,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, B>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:126:53 + --> $DIR/lint-ctypes-enum.rs:127:53 | LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -132,7 +132,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result = note: enum has no representation hint error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:128:51 + --> $DIR/lint-ctypes-enum.rs:129:51 | LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -141,7 +141,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, Field>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:131:49 + --> $DIR/lint-ctypes-enum.rs:132:49 | LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -150,7 +150,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result, Fi = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:133:30 + --> $DIR/lint-ctypes-enum.rs:134:30 | LL | fn result_cascading_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -159,7 +159,7 @@ LL | fn result_cascading_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:144:33 + --> $DIR/lint-ctypes-enum.rs:145:33 | LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -167,7 +167,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:151:33 + --> $DIR/lint-ctypes-enum.rs:152:33 | LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -175,7 +175,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:156:38 + --> $DIR/lint-ctypes-enum.rs:157:38 | LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -184,7 +184,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:158:30 + --> $DIR/lint-ctypes-enum.rs:159:30 | LL | fn result_repr_rust_e(x: Result<(), Rust>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -193,7 +193,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust>>); = note: enum has no representation hint error: `extern` block uses type `Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:162:51 + --> $DIR/lint-ctypes-enum.rs:163:51 | LL | fn result_1zst_exhaustive_single_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -202,7 +202,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:164:53 + --> $DIR/lint-ctypes-enum.rs:165:53 | LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -211,7 +211,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:166:51 + --> $DIR/lint-ctypes-enum.rs:167:51 | LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -220,7 +220,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:169:49 + --> $DIR/lint-ctypes-enum.rs:170:49 | LL | fn result_1zst_exhaustive_single_field_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -229,7 +229,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:171:30 + --> $DIR/lint-ctypes-enum.rs:172:30 | LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe From 2681edf93436a31ed0cfe127d8877c236627ffa3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Apr 2024 08:57:55 +0200 Subject: [PATCH 11/72] josh rustc-pull: check that no new root commits get created --- src/tools/miri/miri-script/src/commands.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 66707dee5e75e..575bf4a15dfd0 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -257,12 +257,26 @@ impl Command { }) .context("FAILED to fetch new commits, something went wrong (committing the rust-version file has been undone)")?; + // This should not add any new root commits. So count those before and after merging. + let num_roots = || -> Result { + Ok(cmd!(sh, "git rev-list HEAD --max-parents=0 --count") + .read() + .context("failed to determine the number of root commits")? + .parse::()?) + }; + let num_roots_before = num_roots()?; + // Merge the fetched commit. const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc"; cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}") .run() .context("FAILED to merge new commits, something went wrong")?; + // Check that the number of roots did not increase. + if num_roots()? != num_roots_before { + bail!("Josh created a new root commit. This is probably not the history you want."); + } + drop(josh); Ok(()) } From 39f7a46d63cf71bfd71926e797eb6f5b20d6b05f Mon Sep 17 00:00:00 2001 From: Hamir Mahal Date: Sat, 27 Apr 2024 00:15:39 -0700 Subject: [PATCH 12/72] fix: usage of `deprecated` version of `Node.js` --- src/tools/miri/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 0af334a654b40..3f714fc93201a 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: # over time). - name: Add cache for cargo id: cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | # Taken from . @@ -95,7 +95,7 @@ jobs: # over time). - name: Add cache for cargo id: cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | # Taken from . From ee47a8e6b610626034f89b4e04132857f5bb2127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Sat, 27 Apr 2024 16:23:44 +0200 Subject: [PATCH 13/72] Add doc comment to `pack_generic` --- src/tools/miri/src/shims/x86/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index cf4d6a04bec87..e04519d9c0ee5 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1127,6 +1127,13 @@ fn pmulhrsw<'tcx>( Ok(()) } +/// Packs two N-bit integer vectors to a single N/2-bit integers. +/// +/// The conversion from N-bit to N/2-bit should be provided by `f`. +/// +/// Each 128-bit chunk is treated independently (i.e., the value for +/// the is i-th 128-bit chunk of `dest` is calculated with the i-th +/// 128-bit chunks of `left` and `right`). fn pack_generic<'tcx>( this: &mut crate::MiriInterpCx<'_, 'tcx>, left: &OpTy<'tcx, Provenance>, From b3b1b498b9f98c229d90c33c1ae87d6eb4758291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Sat, 27 Apr 2024 16:41:27 +0200 Subject: [PATCH 14/72] Clarify behavior of AVX2 gather when dest and offsets have different numbers of elements --- src/tools/miri/src/shims/x86/avx2.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index bbf53f9f1e5d0..ba361ec65584e 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -71,6 +71,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: let (dest, dest_len) = this.mplace_to_simd(dest)?; // There are cases like dest: i32x4, offsets: i64x2 + // If dest has more elements than offset, extra dest elements are filled with zero. + // If offsets has more elements than dest, extra offsets are ignored. let actual_len = dest_len.min(offsets_len); assert_eq!(dest_len, mask_len); From b26153555f623b5c436695b76fa536f449fd3424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Sat, 27 Apr 2024 17:43:39 +0200 Subject: [PATCH 15/72] Do not implement x86 SIMD abs with host integers --- src/tools/miri/src/shims/x86/mod.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index e04519d9c0ee5..9a36286a75531 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -739,14 +739,20 @@ fn int_abs<'tcx>( assert_eq!(op_len, dest_len); + let zero = ImmTy::from_int(0, op.layout.field(this, 0)); + for i in 0..dest_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?; + let op = this.read_immediate(&this.project_index(&op, i)?)?; let dest = this.project_index(&dest, i)?; - // Converting to a host "i128" works since the input is always signed. - let res = op.to_int(dest.layout.size)?.unsigned_abs(); + let lt_zero = this.wrapping_binary_op(mir::BinOp::Lt, &op, &zero)?; + let res = if lt_zero.to_scalar().to_bool()? { + this.wrapping_unary_op(mir::UnOp::Neg, &op)? + } else { + op + }; - this.write_scalar(Scalar::from_uint(res, dest.layout.size), &dest)?; + this.write_immediate(*res, &dest)?; } Ok(()) From b5482aad01e1bc48a5eacd1e1244470bfb2ba09f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Apr 2024 09:38:54 +0200 Subject: [PATCH 16/72] file descriptors: make write take &mut self --- src/tools/miri/src/shims/unix/fd.rs | 16 ++++++++-------- src/tools/miri/src/shims/unix/fs.rs | 4 ++-- src/tools/miri/src/shims/unix/linux/eventfd.rs | 14 +++++--------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index a5fe38b902de8..18a41f6c667ca 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -25,7 +25,7 @@ pub trait FileDescriptor: std::fmt::Debug + Any { } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, _bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -103,13 +103,13 @@ impl FileDescriptor for io::Stdout { } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result> { // We allow writing to stderr even with isolation enabled. - let result = Write::write(&mut { self }, bytes); + let result = Write::write(self, bytes); // Stdout is buffered, flush to make sure it appears on the // screen. This is the write() syscall of the interpreted // program, we want it to correspond to a write() syscall on @@ -135,7 +135,7 @@ impl FileDescriptor for io::Stderr { } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -164,7 +164,7 @@ impl FileDescriptor for NullOutput { } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -418,10 +418,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); - if let Some(file_descriptor) = this.machine.fds.get(fd) { - let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?; + let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?.to_owned(); + if let Some(file_descriptor) = this.machine.fds.get_mut(fd) { let result = file_descriptor - .write(communicate, bytes, *this.tcx)? + .write(communicate, &bytes, *this.tcx)? .map(|c| i64::try_from(c).unwrap()); this.try_unwrap_io_result(result) } else { diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index ebf9f43c19ef6..0bf0e3d52c3c1 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -39,13 +39,13 @@ impl FileDescriptor for FileHandle { } fn write<'tcx>( - &self, + &mut self, communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); - Ok((&mut &self.file).write(bytes)) + Ok(self.file.write(bytes)) } fn seek<'tcx>( diff --git a/src/tools/miri/src/shims/unix/linux/eventfd.rs b/src/tools/miri/src/shims/unix/linux/eventfd.rs index 0f28b69ac4a8e..452527017feb3 100644 --- a/src/tools/miri/src/shims/unix/linux/eventfd.rs +++ b/src/tools/miri/src/shims/unix/linux/eventfd.rs @@ -1,6 +1,5 @@ //! Linux `eventfd` implementation. //! Currently just a stub. -use std::cell::Cell; use std::io; use rustc_middle::ty::TyCtxt; @@ -20,7 +19,7 @@ use crate::*; struct Event { /// The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the /// kernel. This counter is initialized with the value specified in the argument initval. - val: Cell, + val: u64, } impl FileDescriptor for Event { @@ -30,7 +29,7 @@ impl FileDescriptor for Event { fn dup(&mut self) -> io::Result> { // FIXME: this is wrong, the new and old FD should refer to the same event object! - Ok(Box::new(Event { val: self.val.clone() })) + Ok(Box::new(Event { val: self.val })) } fn close<'tcx>( @@ -53,12 +52,11 @@ impl FileDescriptor for Event { /// supplied buffer is less than 8 bytes, or if an attempt is /// made to write the value 0xffffffffffffffff. fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], tcx: TyCtxt<'tcx>, ) -> InterpResult<'tcx, io::Result> { - let v1 = self.val.get(); let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size // Convert from target endianness to host endianness. let num = match tcx.sess.target.endian { @@ -67,9 +65,7 @@ impl FileDescriptor for Event { }; // FIXME handle blocking when addition results in exceeding the max u64 value // or fail with EAGAIN if the file descriptor is nonblocking. - let v2 = v1.checked_add(num).unwrap(); - self.val.set(v2); - assert_eq!(8, bytes.len()); + self.val = self.val.checked_add(num).unwrap(); Ok(Ok(8)) } } @@ -119,7 +115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("eventfd: EFD_SEMAPHORE is unsupported"); } - let fd = this.machine.fds.insert_fd(Box::new(Event { val: Cell::new(val.into()) })); + let fd = this.machine.fds.insert_fd(Box::new(Event { val: val.into() })); Ok(Scalar::from_i32(fd)) } } From 622f697f5dbb1489eb568638fd3f07a477a51958 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 27 Apr 2024 14:55:39 -0400 Subject: [PATCH 17/72] Use the interpreted program's TZ variable in localtime_r --- src/tools/miri/Cargo.lock | 201 +++++++++--------------- src/tools/miri/Cargo.toml | 3 +- src/tools/miri/src/shims/env.rs | 15 +- src/tools/miri/src/shims/time.rs | 26 ++- src/tools/miri/src/shims/unix/env.rs | 21 +++ src/tools/miri/src/shims/windows/env.rs | 9 +- 6 files changed, 137 insertions(+), 138 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 293b937a5e52b..3a282e89312a2 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -37,21 +37,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "annotate-snippets" version = "0.9.2" @@ -121,12 +106,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - [[package]] name = "camino" version = "1.1.6" @@ -177,10 +156,29 @@ version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ - "android-tzdata", - "iana-time-zone", "num-traits", - "windows-targets 0.52.3", +] + +[[package]] +name = "chrono-tz" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", ] [[package]] @@ -249,12 +247,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - [[package]] name = "cpufeatures" version = "0.2.12" @@ -379,29 +371,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "indenter" version = "0.3.3" @@ -455,15 +424,6 @@ dependencies = [ "libc", ] -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -587,6 +547,7 @@ version = "0.1.0" dependencies = [ "aes", "chrono", + "chrono-tz", "colored", "ctrlc", "directories", @@ -690,6 +651,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + [[package]] name = "perf-event-open-sys" version = "3.0.0" @@ -699,6 +669,44 @@ dependencies = [ "libc", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -931,6 +939,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "smallvec" version = "1.13.1" @@ -1094,60 +1108,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - [[package]] name = "winapi" version = "0.3.9" @@ -1170,15 +1130,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.3", -] - [[package]] name = "windows-sys" version = "0.48.0" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index b00dae784d22c..de7a6de9e3e46 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -24,7 +24,8 @@ smallvec = "1.7" aes = { version = "0.8.3", features = ["hazmat"] } measureme = "11" ctrlc = "3.2.5" -chrono = { version = "0.4.38", default-features = false, features = ["clock"] } +chrono = { version = "0.4.38", default-features = false } +chrono-tz = "0.9" directories = "5" # Copied from `compiler/rustc/Cargo.toml`. diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index fc0160fdf2117..395a1ca62c612 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -1,4 +1,4 @@ -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use rustc_data_structures::fx::FxHashMap; @@ -99,4 +99,15 @@ impl<'tcx> EnvVars<'tcx> { } impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {} +pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { + /// Try to get an environment variable from the interpreted program's environment. This is + /// useful for implementing shims which are documented to read from the environment. + fn get_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option> { + let this = self.eval_context_ref(); + match &this.machine.env_vars { + EnvVars::Uninit => return Ok(None), + EnvVars::Unix(vars) => vars.get(this, name), + EnvVars::Windows(vars) => vars.get(name), + } + } +} diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index dfdf58470d63a..05dbdef1ba188 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -1,8 +1,10 @@ -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fmt::Write; +use std::str::FromStr; use std::time::{Duration, SystemTime}; -use chrono::{DateTime, Datelike, Local, Timelike, Utc}; +use chrono::{DateTime, Datelike, Offset, Timelike, Utc}; +use chrono_tz::Tz; use crate::concurrency::thread::MachineCallback; use crate::*; @@ -136,8 +138,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .unwrap(); let dt_utc: DateTime = DateTime::from_timestamp(sec_since_epoch, 0).expect("Invalid timestamp"); + + // Figure out what time zone is in use + let tz = this.get_var(OsStr::new("TZ"))?.unwrap_or_else(|| OsString::from("UTC")); + let tz = match tz.into_string() { + Ok(tz) => Tz::from_str(&tz).unwrap_or(Tz::UTC), + _ => Tz::UTC, + }; + // Convert that to local time, then return the broken-down time value. - let dt: DateTime = DateTime::from(dt_utc); + let dt: DateTime = dt_utc.with_timezone(&tz); // This value is always set to -1, because there is no way to know if dst is in effect with // chrono crate yet. @@ -146,17 +156,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08. // This may not be consistent with libc::localtime_r's result. - let offset_in_second = Local::now().offset().local_minus_utc(); - let tm_gmtoff = offset_in_second; + let offset_in_seconds = dt.offset().fix().local_minus_utc(); + let tm_gmtoff = offset_in_seconds; let mut tm_zone = String::new(); - if offset_in_second < 0 { + if offset_in_seconds < 0 { tm_zone.push('-'); } else { tm_zone.push('+'); } - let offset_hour = offset_in_second.abs() / 3600; + let offset_hour = offset_in_seconds.abs() / 3600; write!(tm_zone, "{:02}", offset_hour).unwrap(); - let offset_min = (offset_in_second.abs() % 3600) / 60; + let offset_min = (offset_in_seconds.abs() % 3600) / 60; if offset_min != 0 { write!(tm_zone, "{:02}", offset_min).unwrap(); } diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 128f0dcafa942..f61a81b07cbbb 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -70,6 +70,27 @@ impl<'tcx> UnixEnvVars<'tcx> { pub(crate) fn environ(&self) -> Pointer> { self.environ.ptr() } + + /// Implementation detail for [`InterpCx::get_var`]. This basically does `getenv`, complete + /// with the reads of the environment, but returns an [`OsString`] instead of a pointer. + pub(crate) fn get<'mir>( + &self, + ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + name: &OsStr, + ) -> InterpResult<'tcx, Option> { + // We don't care about the value as we have the `map` to keep track of everything, + // but we do want to do this read so it shows up as a data race. + let _vars_ptr = ecx.read_pointer(&self.environ)?; + let Some(var_ptr) = self.map.get(name) else { + return Ok(None); + }; + // The offset is used to strip the "{name}=" part of the string. + let var_ptr = var_ptr.offset( + Size::from_bytes(u64::try_from(name.len()).unwrap().checked_add(1).unwrap()), + ecx, + )?; + ecx.read_os_str_from_c_str(var_ptr).map(|s| Some(s.to_owned())) + } } fn alloc_env_var<'mir, 'tcx>( diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index e91623ac87160..a8b0a77b23b74 100644 --- a/src/tools/miri/src/shims/windows/env.rs +++ b/src/tools/miri/src/shims/windows/env.rs @@ -1,5 +1,5 @@ use std::env; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::io::ErrorKind; use rustc_data_structures::fx::FxHashMap; @@ -9,7 +9,7 @@ use helpers::windows_check_buffer_size; #[derive(Default)] pub struct WindowsEnvVars { - /// Stores the environment varialbles. + /// Stores the environment variables. map: FxHashMap, } @@ -26,6 +26,11 @@ impl WindowsEnvVars { ) -> InterpResult<'tcx, Self> { Ok(Self { map: env_vars }) } + + /// Implementation detail for [`InterpCx::get_var`]. + pub(crate) fn get<'tcx>(&self, name: &OsStr) -> InterpResult<'tcx, Option> { + Ok(self.map.get(name).cloned()) + } } impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} From 9bed19edc42fe7db30df8258d13598bfe7b1971b Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 28 Apr 2024 17:45:08 -0400 Subject: [PATCH 18/72] Refactor UnixEnvVars::get so that it can be reused by getenv --- src/tools/miri/src/shims/env.rs | 12 ++++++++++-- src/tools/miri/src/shims/time.rs | 2 +- src/tools/miri/src/shims/unix/env.rs | 21 +++++---------------- src/tools/miri/src/shims/windows/env.rs | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 395a1ca62c612..b95abb484c875 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -102,11 +102,19 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Try to get an environment variable from the interpreted program's environment. This is /// useful for implementing shims which are documented to read from the environment. - fn get_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option> { + fn get_env_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option> { let this = self.eval_context_ref(); match &this.machine.env_vars { EnvVars::Uninit => return Ok(None), - EnvVars::Unix(vars) => vars.get(this, name), + EnvVars::Unix(vars) => { + let var_ptr = vars.get(this, name)?; + if let Some(ptr) = var_ptr { + let var = this.read_os_str_from_c_str(ptr)?; + Ok(Some(var.to_owned())) + } else { + Ok(None) + } + } EnvVars::Windows(vars) => vars.get(name), } } diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 05dbdef1ba188..8d1f07f916c9b 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -140,7 +140,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { DateTime::from_timestamp(sec_since_epoch, 0).expect("Invalid timestamp"); // Figure out what time zone is in use - let tz = this.get_var(OsStr::new("TZ"))?.unwrap_or_else(|| OsString::from("UTC")); + let tz = this.get_env_var(OsStr::new("TZ"))?.unwrap_or_else(|| OsString::from("UTC")); let tz = match tz.into_string() { Ok(tz) => Tz::from_str(&tz).unwrap_or(Tz::UTC), _ => Tz::UTC, diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index f61a81b07cbbb..910e53260bfbc 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -71,13 +71,13 @@ impl<'tcx> UnixEnvVars<'tcx> { self.environ.ptr() } - /// Implementation detail for [`InterpCx::get_var`]. This basically does `getenv`, complete + /// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete /// with the reads of the environment, but returns an [`OsString`] instead of a pointer. pub(crate) fn get<'mir>( &self, ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, name: &OsStr, - ) -> InterpResult<'tcx, Option> { + ) -> InterpResult<'tcx, Option>>> { // We don't care about the value as we have the `map` to keep track of everything, // but we do want to do this read so it shows up as a data race. let _vars_ptr = ecx.read_pointer(&self.environ)?; @@ -89,7 +89,7 @@ impl<'tcx> UnixEnvVars<'tcx> { Size::from_bytes(u64::try_from(name.len()).unwrap().checked_add(1).unwrap()), ecx, )?; - ecx.read_os_str_from_c_str(var_ptr).map(|s| Some(s.to_owned())) + Ok(Some(var_ptr)) } } @@ -137,19 +137,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let name_ptr = this.read_pointer(name_op)?; let name = this.read_os_str_from_c_str(name_ptr)?; - // We don't care about the value as we have the `map` to keep track of everything, - // but we do want to do this read so it shows up as a data race. - let _vars_ptr = this.read_pointer(&this.machine.env_vars.unix().environ)?; - Ok(match this.machine.env_vars.unix().map.get(name) { - Some(var_ptr) => { - // The offset is used to strip the "{name}=" part of the string. - var_ptr.offset( - Size::from_bytes(u64::try_from(name.len()).unwrap().checked_add(1).unwrap()), - this, - )? - } - None => Pointer::null(), - }) + let var_ptr = this.machine.env_vars.unix().get(this, name)?; + Ok(var_ptr.unwrap_or_else(Pointer::null)) } fn setenv( diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index a8b0a77b23b74..b3bc5d4d85235 100644 --- a/src/tools/miri/src/shims/windows/env.rs +++ b/src/tools/miri/src/shims/windows/env.rs @@ -27,7 +27,7 @@ impl WindowsEnvVars { Ok(Self { map: env_vars }) } - /// Implementation detail for [`InterpCx::get_var`]. + /// Implementation detail for [`InterpCx::get_env_var`]. pub(crate) fn get<'tcx>(&self, name: &OsStr) -> InterpResult<'tcx, Option> { Ok(self.map.get(name).cloned()) } From 7afef08b6d01c4baabe4523f4b91ea2d1748f0e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 29 Apr 2024 17:33:35 +0200 Subject: [PATCH 19/72] don't leak UnixEnvVars impl details into get_env_var --- src/tools/miri/src/shims/env.rs | 10 +--------- src/tools/miri/src/shims/unix/env.rs | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index b95abb484c875..695d1138756ca 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -106,15 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_ref(); match &this.machine.env_vars { EnvVars::Uninit => return Ok(None), - EnvVars::Unix(vars) => { - let var_ptr = vars.get(this, name)?; - if let Some(ptr) = var_ptr { - let var = this.read_os_str_from_c_str(ptr)?; - Ok(Some(var.to_owned())) - } else { - Ok(None) - } - } + EnvVars::Unix(vars) => vars.get(this, name), EnvVars::Windows(vars) => vars.get(name), } } diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 910e53260bfbc..9082d13da8404 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -71,9 +71,7 @@ impl<'tcx> UnixEnvVars<'tcx> { self.environ.ptr() } - /// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete - /// with the reads of the environment, but returns an [`OsString`] instead of a pointer. - pub(crate) fn get<'mir>( + fn get_ptr<'mir>( &self, ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, name: &OsStr, @@ -91,6 +89,22 @@ impl<'tcx> UnixEnvVars<'tcx> { )?; Ok(Some(var_ptr)) } + + /// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete + /// with the reads of the environment, but returns an [`OsString`] instead of a pointer. + pub(crate) fn get<'mir>( + &self, + ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + name: &OsStr, + ) -> InterpResult<'tcx, Option> { + let var_ptr = self.get_ptr(ecx, name)?; + if let Some(ptr) = var_ptr { + let var = ecx.read_os_str_from_c_str(ptr)?; + Ok(Some(var.to_owned())) + } else { + Ok(None) + } + } } fn alloc_env_var<'mir, 'tcx>( @@ -137,7 +151,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let name_ptr = this.read_pointer(name_op)?; let name = this.read_os_str_from_c_str(name_ptr)?; - let var_ptr = this.machine.env_vars.unix().get(this, name)?; + let var_ptr = this.machine.env_vars.unix().get_ptr(this, name)?; Ok(var_ptr.unwrap_or_else(Pointer::null)) } From 1cf951e5c6efd4fa55031b72f17c196e74b0f349 Mon Sep 17 00:00:00 2001 From: Paul Gey Date: Wed, 1 May 2024 21:27:49 +0200 Subject: [PATCH 20/72] =?UTF-8?q?Don=E2=80=99t=20print=20`Preparing=20a=20?= =?UTF-8?q?sysroot`=20when=20`-q`/`--quiet`=20is=20passed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tools/miri/cargo-miri/src/phases.rs | 3 ++- src/tools/miri/cargo-miri/src/setup.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index b774ca8fa7252..6a3b6f68a7ed3 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -87,6 +87,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { ), }; let verbose = num_arg_flag("-v"); + let quiet = has_arg_flag("-q") || has_arg_flag("--quiet"); // Determine the involved architectures. let rustc_version = VersionMeta::for_command(miri_for_host()).unwrap_or_else(|err| { @@ -110,7 +111,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { } // We always setup. - let miri_sysroot = setup(&subcommand, target, &rustc_version, verbose); + let miri_sysroot = setup(&subcommand, target, &rustc_version, verbose, quiet); // Invoke actual cargo for the job, but with different flags. // We re-use `cargo test` and `cargo run`, which makes target and binary handling very easy but diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs index 401e9158faec5..9a58e6fa018da 100644 --- a/src/tools/miri/cargo-miri/src/setup.rs +++ b/src/tools/miri/cargo-miri/src/setup.rs @@ -19,6 +19,7 @@ pub fn setup( target: &str, rustc_version: &VersionMeta, verbose: usize, + quiet: bool, ) -> PathBuf { let only_setup = matches!(subcommand, MiriCommand::Setup); let ask_user = !only_setup; @@ -119,6 +120,9 @@ pub fn setup( for _ in 0..verbose { command.arg("-v"); } + if quiet { + command.arg("--quiet"); + } } else { // Suppress output. command.stdout(process::Stdio::null()); @@ -134,7 +138,7 @@ pub fn setup( let rustflags = &["-Cdebug-assertions=off", "-Coverflow-checks=on"]; // Do the build. - if print_sysroot { + if print_sysroot || quiet { // Be silent. } else { let mut msg = String::new(); @@ -169,7 +173,7 @@ pub fn setup( ) } }); - if print_sysroot { + if print_sysroot || quiet { // Be silent. } else if only_setup { eprintln!("A sysroot for Miri is now available in `{}`.", sysroot_dir.display()); From 4b4262691da5fe93e3226842efbdd06f89e1abb3 Mon Sep 17 00:00:00 2001 From: Paul Gey Date: Wed, 1 May 2024 21:34:50 +0200 Subject: [PATCH 21/72] fix usage example for `--print-sysroot` --- src/tools/miri/cargo-miri/src/phases.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 6a3b6f68a7ed3..e2fc2a0c2779b 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -28,7 +28,7 @@ Examples: cargo miri run cargo miri test -- test-suite-filter - cargo miri setup --print sysroot + cargo miri setup --print-sysroot This will print the path to the generated sysroot (and nothing else) on stdout. stderr will still contain progress information about how the build is doing. From a2b3211b199375f358ec087e8a264063417e2d22 Mon Sep 17 00:00:00 2001 From: Paul Gey Date: Wed, 1 May 2024 21:50:45 +0200 Subject: [PATCH 22/72] no longer strip `Preparing a sysroot` message from test output --- src/tools/miri/test-cargo-miri/run-test.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py index cac11dff77557..2639d29b73de6 100755 --- a/src/tools/miri/test-cargo-miri/run-test.py +++ b/src/tools/miri/test-cargo-miri/run-test.py @@ -34,10 +34,6 @@ def normalize_stdout(str): str = re.sub("finished in \\d+\\.\\d\\ds", "finished in $TIME", str) # the time keeps changing, obviously return str -def normalize_stderr(str): - str = re.sub("Preparing a sysroot for Miri \\(target: [a-z0-9_-]+\\)\\.\\.\\. done\n", "", str) # remove leading cargo-miri setup output - return str - def check_output(actual, path, name): if os.environ.get("RUSTC_BLESS", "0") != "0": # Write the output only if bless is set @@ -69,7 +65,7 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env=None): ) (stdout, stderr) = p.communicate(input=stdin) stdout = normalize_stdout(stdout.decode("UTF-8")) - stderr = normalize_stderr(stderr.decode("UTF-8")) + stderr = stderr.decode("UTF-8") stdout_matches = check_output(stdout, stdout_ref, "stdout") stderr_matches = check_output(stderr, stderr_ref, "stderr") From aa986f080080e293d059255baee26638728eaee7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2024 11:09:01 +0200 Subject: [PATCH 23/72] Tree Borrows: first apply transition, then check protector with new 'initialized' --- src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 2470624181e74..ff4589657aff2 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -106,6 +106,8 @@ impl LocationState { let old_perm = self.permission; let transition = Permission::perform_access(access_kind, rel_pos, old_perm, protected) .ok_or(TransitionError::ChildAccessForbidden(old_perm))?; + self.initialized |= !rel_pos.is_foreign(); + self.permission = transition.applied(old_perm).unwrap(); // Why do only initialized locations cause protector errors? // Consider two mutable references `x`, `y` into disjoint parts of // the same allocation. A priori, these may actually both be used to @@ -123,8 +125,6 @@ impl LocationState { if protected && self.initialized && transition.produces_disabled() { return Err(TransitionError::ProtectedDisabled(old_perm)); } - self.permission = transition.applied(old_perm).unwrap(); - self.initialized |= !rel_pos.is_foreign(); Ok(transition) } From 36caaa9f4f10547903a8bd15f435d02bc48c1ce6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2024 19:13:28 +0200 Subject: [PATCH 24/72] update host-float comments --- src/tools/miri/src/shims/foreign_items.rs | 12 ++++++------ src/tools/miri/src/shims/intrinsics/mod.rs | 16 ++++++++-------- src/tools/miri/src/shims/intrinsics/simd.rs | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 636361148a469..4b96ff18b74cb 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -730,7 +730,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { => { let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let f = this.read_scalar(f)?.to_f32()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); let res = match link_name.as_str() { "cbrtf" => f_host.cbrt(), @@ -761,7 +761,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let f2 = this.read_scalar(f2)?.to_f32()?; // underscore case for windows, here and below // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019) - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let res = match link_name.as_str() { "_hypotf" | "hypotf" => f1.to_host().hypot(f2.to_host()).to_soft(), "atan2f" => f1.to_host().atan2(f2.to_host()).to_soft(), @@ -787,7 +787,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { => { let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let f = this.read_scalar(f)?.to_f64()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); let res = match link_name.as_str() { "cbrt" => f_host.cbrt(), @@ -818,7 +818,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let f2 = this.read_scalar(f2)?.to_f64()?; // underscore case for windows, here and below // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019) - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let res = match link_name.as_str() { "_hypot" | "hypot" => f1.to_host().hypot(f2.to_host()).to_soft(), "atan2" => f1.to_host().atan2(f2.to_host()).to_soft(), @@ -848,7 +848,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; let res = this.adjust_nan(res.to_soft(), &[x]); @@ -859,7 +859,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; let res = this.adjust_nan(res.to_soft(), &[x]); diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index d16d5d99e9c01..a7ba4fd7f9e54 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -193,12 +193,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); let res = match intrinsic_name { "sinf32" => f_host.sin(), "cosf32" => f_host.cos(), - "sqrtf32" => f_host.sqrt(), + "sqrtf32" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats "expf32" => f_host.exp(), "exp2f32" => f_host.exp2(), "logf32" => f_host.ln(), @@ -238,12 +238,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); let res = match intrinsic_name { "sinf64" => f_host.sin(), "cosf64" => f_host.cos(), - "sqrtf64" => f_host.sqrt(), + "sqrtf64" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats "expf64" => f_host.exp(), "exp2f64" => f_host.exp2(), "logf64" => f_host.ln(), @@ -366,7 +366,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [f1, f2] = check_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, this operation does not have guaranteed precision). let res = f1.to_host().powf(f2.to_host()).to_soft(); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; @@ -376,7 +376,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [f1, f2] = check_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, this operation does not have guaranteed precision). let res = f1.to_host().powf(f2.to_host()).to_soft(); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; @@ -386,7 +386,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [f, i] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let i = this.read_scalar(i)?.to_i32()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, this operation does not have guaranteed precision). let res = f.to_host().powi(i).to_soft(); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; @@ -396,7 +396,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [f, i] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let i = this.read_scalar(i)?.to_i32()?; - // FIXME: Using host floats. + // Using host floats (but it's fine, this operation does not have guaranteed precision). let res = f.to_host().powi(i).to_soft(); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index 9a0671430d438..e6d6f72404e11 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -99,14 +99,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ty::Float(float_ty) = op.layout.ty.kind() else { span_bug!(this.cur_span(), "{} operand is not a float", intrinsic_name) }; - // FIXME using host floats + // Using host floats (but it's fine, these operations do not have guaranteed precision). match float_ty { FloatTy::F16 => unimplemented!("f16_f128"), FloatTy::F32 => { let f = op.to_scalar().to_f32()?; let f_host = f.to_host(); let res = match host_op { - "fsqrt" => f_host.sqrt(), + "fsqrt" => f_host.sqrt(), // FIXME Using host floats, this should use full-precision soft-floats "fsin" => f_host.sin(), "fcos" => f_host.cos(), "fexp" => f_host.exp(), From 56bb51761ab90fa3ccc6261d59b71d2fdc404b54 Mon Sep 17 00:00:00 2001 From: tiif Date: Fri, 3 May 2024 07:05:29 +0800 Subject: [PATCH 25/72] Add assign --- src/tools/miri/triagebot.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index 3b767b3e62f13..22dc0c49aa815 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -10,5 +10,14 @@ allow-unauthenticated = [ # Gives us the commands 'ready', 'author', 'blocked' [shortcut] +# Gives us 'claim', 'release-assignment', 'assign @user' +[assign] +# If set, posts a warning message if the PR is opened against a non-default +# branch (usually main or master). +warn_non_default_branch = true +# If set, the welcome message to new contributors will include this link to +# a contributing guide. +contributing_url = "https://rustc-dev-guide.rust-lang.org/contributing.html" + [no-merges] exclude_titles = ["Rustup"] From 6967d1c0fcea4ade223bf3ae443a87d504005cbf Mon Sep 17 00:00:00 2001 From: Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Date: Sat, 27 Apr 2024 20:35:32 -0400 Subject: [PATCH 26/72] Stabilize exclusive_range --- compiler/rustc_ast_passes/src/feature_gate.rs | 15 +- .../src/error_codes/E0579.md | 1 - compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_lint_defs/src/builtin.rs | 1 - .../rustc_pattern_analysis/src/usefulness.rs | 1 - library/alloc/src/lib.rs | 2 +- .../exclusive-range-pattern.md | 26 ---- .../half-open-range-patterns-in-slices.md | 3 +- .../mir-opt/building/match/sort_candidates.rs | 1 - tests/ui/binding/match-range.rs | 1 - .../const_refers_to_static_cross_crate.rs | 2 +- .../feature-gate-exclusive-range-pattern.rs | 6 - ...eature-gate-exclusive-range-pattern.stderr | 14 -- ...xclusive_range_pattern_syntax_collision.rs | 1 - ...sive_range_pattern_syntax_collision.stderr | 2 +- ...clusive_range_pattern_syntax_collision2.rs | 1 - ...ive_range_pattern_syntax_collision2.stderr | 4 +- ...clusive_range_pattern_syntax_collision3.rs | 2 - ...ive_range_pattern_syntax_collision3.stderr | 6 +- ...gate-half-open-range-patterns-in-slices.rs | 2 - ...-half-open-range-patterns-in-slices.stderr | 4 +- .../half-open-range-pats-bad-types.rs | 2 - .../half-open-range-pats-bad-types.stderr | 6 +- .../half-open-range-pats-exhaustive-fail.rs | 1 - ...alf-open-range-pats-exhaustive-fail.stderr | 136 ++++++++--------- .../half-open-range-pats-exhaustive-pass.rs | 2 - .../half-open-range-pats-semantics.rs | 1 - .../half-open-range-pats-syntactic-pass.rs | 2 - .../half-open-range-pats-thir-lower-empty.rs | 2 - ...lf-open-range-pats-thir-lower-empty.stderr | 26 ++-- .../half-open-range-patterns/pat-tuple-4.rs | 2 - .../half-open-range-patterns/pat-tuple-5.rs | 2 - .../pat-tuple-5.stderr | 2 +- .../range_pat_interactions0.rs | 1 - .../range_pat_interactions1.rs | 9 +- .../range_pat_interactions1.stderr | 83 +---------- .../range_pat_interactions2.rs | 4 - .../range_pat_interactions2.stderr | 48 +----- .../range_pat_interactions3.rs | 4 - .../range_pat_interactions3.stderr | 48 +----- .../slice_pattern_syntax_problem0.rs | 1 - .../slice_pattern_syntax_problem0.stderr | 2 +- .../slice_pattern_syntax_problem1.rs | 2 - .../slice_pattern_syntax_problem1.stderr | 24 +-- .../ui/inline-const/const-match-pat-range.rs | 2 +- tests/ui/match/match-range-fail-2.rs | 2 - tests/ui/match/match-range-fail-2.stderr | 6 +- tests/ui/match/validate-range-endpoints.rs | 1 - .../ui/match/validate-range-endpoints.stderr | 22 +-- tests/ui/mir/mir_match_test.rs | 1 - .../issue-63115-range-pat-interpolated.rs | 2 - tests/ui/parser/recover/recover-range-pats.rs | 1 - .../parser/recover/recover-range-pats.stderr | 140 +++++++++--------- ...-pattern-meant-to-be-slice-rest-pattern.rs | 1 - ...tern-meant-to-be-slice-rest-pattern.stderr | 19 +-- tests/ui/pattern/usefulness/floats.rs | 1 - tests/ui/pattern/usefulness/floats.stderr | 18 +-- tests/ui/pattern/usefulness/guards.rs | 1 - tests/ui/pattern/usefulness/guards.stderr | 2 +- .../integer-ranges/exhaustiveness.rs | 1 - .../integer-ranges/exhaustiveness.stderr | 24 +-- .../integer-ranges/gap_between_ranges.rs | 1 - .../integer-ranges/gap_between_ranges.stderr | 36 ++--- .../overlapping_range_endpoints.rs | 1 - .../overlapping_range_endpoints.stderr | 22 +-- .../pointer-sized-int.deny.stderr | 24 +-- .../integer-ranges/pointer-sized-int.rs | 1 - .../usefulness/integer-ranges/reachability.rs | 1 - .../integer-ranges/reachability.stderr | 52 +++---- ...range-pattern-out-of-bounds-issue-68972.rs | 1 - ...e-pattern-out-of-bounds-issue-68972.stderr | 4 +- .../issue-6804-nan-match.rs | 1 - .../issue-6804-nan-match.stderr | 22 +-- 74 files changed, 300 insertions(+), 619 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/exclusive-range-pattern.md delete mode 100644 tests/ui/feature-gates/feature-gate-exclusive-range-pattern.rs delete mode 100644 tests/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index e0000e354ca5f..6622caaaab412 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId}; -use rustc_ast::{token, PatKind, RangeEnd}; +use rustc_ast::{token, PatKind}; use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; use rustc_session::Session; @@ -418,15 +418,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { PatKind::Box(..) => { gate!(&self, box_patterns, pattern.span, "box pattern syntax is experimental"); } - PatKind::Range(_, Some(_), Spanned { node: RangeEnd::Excluded, .. }) => { - gate!( - &self, - exclusive_range_pattern, - pattern.span, - "exclusive range pattern syntax is experimental", - "use an inclusive range pattern, like N..=M" - ); - } _ => {} } visit::walk_pat(self, pattern) @@ -619,10 +610,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { // be too. gate_all_legacy_dont_use!(return_type_notation, "return type notation is experimental"); gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental"); - gate_all_legacy_dont_use!( - exclusive_range_pattern, - "exclusive range pattern syntax is experimental" - ); gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable"); diff --git a/compiler/rustc_error_codes/src/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md index e7e6fb682566e..decf810b8c618 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0579.md +++ b/compiler/rustc_error_codes/src/error_codes/E0579.md @@ -3,7 +3,6 @@ A lower range wasn't less than the upper range. Erroneous code example: ```compile_fail,E0579 -#![feature(exclusive_range_pattern)] fn main() { match 5u32 { diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 943cc63285787..bb6a54fae7072 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -162,6 +162,8 @@ declare_features! ( (accepted, drop_types_in_const, "1.22.0", Some(33156)), /// Allows using `dyn Trait` as a syntax for trait objects. (accepted, dyn_trait, "1.27.0", Some(44662)), + /// Allows `X..Y` patterns. + (accepted, exclusive_range_pattern, "CURRENT_RUSTC_VERSION", Some(37854)), /// Allows integer match exhaustiveness checking (RFC 2591). (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907)), /// Allows explicit generic arguments specification with `impl Trait` present. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e7d7a9f380b19..cbeeacfec37c8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -454,8 +454,6 @@ declare_features! ( (incomplete, dyn_star, "1.65.0", Some(102425)), /// Uses generic effect parameters for ~const bounds (unstable, effects, "1.72.0", Some(102090)), - /// Allows `X..Y` patterns. - (unstable, exclusive_range_pattern, "1.11.0", Some(37854)), /// Allows exhaustive pattern matching on types that contain uninhabited types. (unstable, exhaustive_patterns, "1.13.0", Some(51085)), /// Allows explicit tail calls via `become` expression. diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c7996c27c2f09..eea3ca44c48b2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -844,7 +844,6 @@ declare_lint! { /// ### Example /// /// ```rust - /// # #![feature(exclusive_range_pattern)] /// let x = 123u32; /// match x { /// 0..100 => { println!("small"); } diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 74af9154f8581..6e96a93473f7d 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -42,7 +42,6 @@ //! This is enough to compute usefulness: a pattern in a `match` expression is redundant iff it is //! not useful w.r.t. the patterns above it: //! ```compile_fail,E0004 -//! # #![feature(exclusive_range_pattern)] //! # fn foo() { //! match Some(0u32) { //! Some(0..100) => {}, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index b93936869b3fd..91b83cfe011f2 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -165,6 +165,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(exclusive_range_pattern))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] @@ -179,7 +180,6 @@ #![feature(const_try)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] -#![feature(exclusive_range_pattern)] #![feature(fundamental)] #![feature(hashmap_internals)] #![feature(lang_items)] diff --git a/src/doc/unstable-book/src/language-features/exclusive-range-pattern.md b/src/doc/unstable-book/src/language-features/exclusive-range-pattern.md deleted file mode 100644 index d26512703f494..0000000000000 --- a/src/doc/unstable-book/src/language-features/exclusive-range-pattern.md +++ /dev/null @@ -1,26 +0,0 @@ -# `exclusive_range_pattern` - -The tracking issue for this feature is: [#37854]. - - -[#67264]: https://github.com/rust-lang/rust/issues/67264 -[#37854]: https://github.com/rust-lang/rust/issues/37854 ------ - -The `exclusive_range_pattern` feature allows non-inclusive range -patterns (`0..10`) to be used in appropriate pattern matching -contexts. It also can be combined with `#![feature(half_open_range_patterns]` -to be able to use RangeTo patterns (`..10`). - -It also enabled RangeFrom patterns but that has since been -stabilized. - -```rust -#![feature(exclusive_range_pattern)] - let x = 5; - match x { - 0..10 => println!("single digit"), - 10 => println!("ten isn't part of the above range"), - _ => println!("nor is everything else.") - } -``` diff --git a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md index 56a1a97df1629..93e9bc32ff064 100644 --- a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md +++ b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md @@ -1,7 +1,7 @@ # `half_open_range_patterns_in_slices` The tracking issue for this feature is: [#67264] -It is part of the `exclusive_range_pattern` feature, +It is a future part of the `exclusive_range_pattern` feature, tracked at [#37854]. [#67264]: https://github.com/rust-lang/rust/issues/67264 @@ -12,7 +12,6 @@ This feature allow using top-level half-open range patterns in slices. ```rust #![feature(half_open_range_patterns_in_slices)] -#![feature(exclusive_range_pattern)] fn main() { let xs = [13, 1, 5, 2, 3, 1, 21, 8]; diff --git a/tests/mir-opt/building/match/sort_candidates.rs b/tests/mir-opt/building/match/sort_candidates.rs index a2583ff828484..f207f0b323483 100644 --- a/tests/mir-opt/building/match/sort_candidates.rs +++ b/tests/mir-opt/building/match/sort_candidates.rs @@ -1,5 +1,4 @@ // Check specific cases of sorting candidates in match lowering. -#![feature(exclusive_range_pattern)] // EMIT_MIR sort_candidates.constant_eq.SimplifyCfg-initial.after.mir fn constant_eq(s: &str, b: bool) -> u32 { diff --git a/tests/ui/binding/match-range.rs b/tests/ui/binding/match-range.rs index a024e5e585ae7..097ccb34f87c3 100644 --- a/tests/ui/binding/match-range.rs +++ b/tests/ui/binding/match-range.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(exclusive_range_pattern)] pub fn main() { match 5_usize { diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index 5e7845e4e82f6..fa3ca6928e35b 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -2,7 +2,7 @@ //@ aux-build:static_cross_crate.rs //@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -#![feature(exclusive_range_pattern, half_open_range_patterns_in_slices)] +#![feature(half_open_range_patterns_in_slices)] #![allow(static_mut_refs)] extern crate static_cross_crate; diff --git a/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.rs b/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.rs deleted file mode 100644 index ded08b93fe81c..0000000000000 --- a/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub fn main() { - match 22 { - 0 .. 3 => {} //~ ERROR exclusive range pattern syntax is experimental - _ => {} - } -} diff --git a/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr b/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr deleted file mode 100644 index 5e3d34aa9f3ed..0000000000000 --- a/tests/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/feature-gate-exclusive-range-pattern.rs:3:9 - | -LL | 0 .. 3 => {} - | ^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs index b2e9ffb57727e..dd4fe7c78b76d 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs @@ -1,5 +1,4 @@ #![feature(half_open_range_patterns_in_slices)] -#![feature(exclusive_range_pattern)] fn main() { match [5..4, 99..105, 43..44] { diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr index 357d3a4a124d9..5ee31a0a23b22 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13 + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs index 20f4d8f882a75..1b06181464f69 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs @@ -1,5 +1,4 @@ #![feature(half_open_range_patterns_in_slices)] -#![feature(exclusive_range_pattern)] fn main() { match [5..4, 99..105, 43..44] { diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr index 6f56ecd4c1c9c..9ad6d5363adcb 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr @@ -1,11 +1,11 @@ error[E0527]: pattern requires 2 elements but array has 3 - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:9 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9 | LL | [_, 99..] => {}, | ^^^^^^^^^ expected 3 elements error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs index 14ca07d0a5388..a3aca8dfac7fc 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - fn main() { match [5..4, 99..105, 43..44] { [..9, 99..100, _] => {}, diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr index b9b272c4c7cb6..4a4a4c00b2e67 100644 --- a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr +++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:3:12 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -10,7 +10,7 @@ LL | [..9, 99..100, _] => {}, found type `{integer}` error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:3:15 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` @@ -23,7 +23,7 @@ LL | [..9, 99..100, _] => {}, found type `{integer}` error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:3:19 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs index 99de7845d7b65..a7b0ca6fe4a54 100644 --- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs +++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - fn main() { let xs = [13, 1, 5, 2, 3, 1, 21, 8]; let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr index b011044f4ddc4..af11bc82d0c2e 100644 --- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr +++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr @@ -1,5 +1,5 @@ error[E0658]: `X..` patterns in slices are experimental - --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:5:10 + --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:3:10 | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; | ^^^^^^^ @@ -9,7 +9,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0005]: refutable pattern in local binding - --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:5:9 + --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:3:9 | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs index 17ea2b13f690f..b133e32452fb0 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - fn main() { let "a".. = "a"; //~ ERROR only `char` and numeric types are allowed in range patterns let .."a" = "a"; //~ ERROR only `char` and numeric types are allowed in range patterns diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr index f7c59a1961933..c14c38eca6e24 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr @@ -1,17 +1,17 @@ error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/half-open-range-pats-bad-types.rs:4:9 + --> $DIR/half-open-range-pats-bad-types.rs:2:9 | LL | let "a".. = "a"; | ^^^ this is of type `&'static str` but it should be `char` or numeric error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/half-open-range-pats-bad-types.rs:5:11 + --> $DIR/half-open-range-pats-bad-types.rs:3:11 | LL | let .."a" = "a"; | ^^^ this is of type `&'static str` but it should be `char` or numeric error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/half-open-range-pats-bad-types.rs:6:12 + --> $DIR/half-open-range-pats-bad-types.rs:4:12 | LL | let ..="a" = "a"; | ^^^ this is of type `&'static str` but it should be `char` or numeric diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs index 9d067229b6de8..2059c9707d224 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs @@ -1,6 +1,5 @@ // Test various non-exhaustive matches for `X..`, `..=X` and `..X` ranges. -#![feature(exclusive_range_pattern)] #![allow(non_contiguous_range_endpoints)] fn main() {} diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr index bb4c2a4c52353..78970f8c6497d 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:15:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:14:8 | LL | m!(0f32, f32::NEG_INFINITY..); | ^^^^ pattern `_` not covered @@ -11,7 +11,7 @@ LL | match $s { $($t)+ => {}, _ => todo!() } | ++++++++++++++ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:15:8 | LL | m!(0f32, ..f32::INFINITY); | ^^^^ pattern `_` not covered @@ -23,7 +23,7 @@ LL | match $s { $($t)+ => {}, _ => todo!() } | ++++++++++++++ error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:25:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:24:8 | LL | m!('a', ..core::char::MAX); | ^^^ pattern `'\u{10ffff}'` not covered @@ -35,7 +35,7 @@ LL | match $s { $($t)+ => {}, '\u{10ffff}' => todo!() } | +++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:25:8 | LL | m!('a', ..ALMOST_MAX); | ^^^ pattern `'\u{10fffe}'..='\u{10ffff}'` not covered @@ -47,7 +47,7 @@ LL | match $s { $($t)+ => {}, '\u{10fffe}'..='\u{10ffff}' => todo!() } | ++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `'\0'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8 | LL | m!('a', ALMOST_MIN..); | ^^^ pattern `'\0'` not covered @@ -59,7 +59,7 @@ LL | match $s { $($t)+ => {}, '\0' => todo!() } | +++++++++++++++++ error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8 | LL | m!('a', ..=ALMOST_MAX); | ^^^ pattern `'\u{10ffff}'` not covered @@ -71,7 +71,7 @@ LL | match $s { $($t)+ => {}, '\u{10ffff}' => todo!() } | +++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `'b'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8 | LL | m!('a', ..=VAL | VAL_2..); | ^^^ pattern `'b'` not covered @@ -83,7 +83,7 @@ LL | match $s { $($t)+ => {}, 'b' => todo!() } | ++++++++++++++++ error[E0004]: non-exhaustive patterns: `'b'` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:30:8 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8 | LL | m!('a', ..VAL_1 | VAL_2..); | ^^^ pattern `'b'` not covered @@ -95,7 +95,7 @@ LL | match $s { $($t)+ => {}, 'b' => todo!() } | ++++++++++++++++ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:40:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:39:12 | LL | m!(0, ..u8::MAX); | ^ pattern `u8::MAX` not covered @@ -107,7 +107,7 @@ LL | match $s { $($t)+ => {}, u8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `254_u8..=u8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:40:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `254_u8..=u8::MAX` not covered @@ -119,7 +119,7 @@ LL | match $s { $($t)+ => {}, 254_u8..=u8::MAX => todo!() } | +++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u8` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `0_u8` not covered @@ -131,7 +131,7 @@ LL | match $s { $($t)+ => {}, 0_u8 => todo!() } | +++++++++++++++++ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `u8::MAX` not covered @@ -143,7 +143,7 @@ LL | match $s { $($t)+ => {}, u8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u8` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_u8` not covered @@ -155,7 +155,7 @@ LL | match $s { $($t)+ => {}, 43_u8 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u8` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:45:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_u8` not covered @@ -167,7 +167,7 @@ LL | match $s { $($t)+ => {}, 43_u8 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:53:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:52:12 | LL | m!(0, ..u16::MAX); | ^ pattern `u16::MAX` not covered @@ -179,7 +179,7 @@ LL | match $s { $($t)+ => {}, u16::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `65534_u16..=u16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:53:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `65534_u16..=u16::MAX` not covered @@ -191,7 +191,7 @@ LL | match $s { $($t)+ => {}, 65534_u16..=u16::MAX => todo!() } | +++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u16` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `0_u16` not covered @@ -203,7 +203,7 @@ LL | match $s { $($t)+ => {}, 0_u16 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `u16::MAX` not covered @@ -215,7 +215,7 @@ LL | match $s { $($t)+ => {}, u16::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u16` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_u16` not covered @@ -227,7 +227,7 @@ LL | match $s { $($t)+ => {}, 43_u16 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u16` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:58:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_u16` not covered @@ -239,7 +239,7 @@ LL | match $s { $($t)+ => {}, 43_u16 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:66:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:65:12 | LL | m!(0, ..u32::MAX); | ^ pattern `u32::MAX` not covered @@ -251,7 +251,7 @@ LL | match $s { $($t)+ => {}, u32::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `4294967294_u32..=u32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:66:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `4294967294_u32..=u32::MAX` not covered @@ -263,7 +263,7 @@ LL | match $s { $($t)+ => {}, 4294967294_u32..=u32::MAX => todo!() } | ++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u32` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `0_u32` not covered @@ -275,7 +275,7 @@ LL | match $s { $($t)+ => {}, 0_u32 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `u32::MAX` not covered @@ -287,7 +287,7 @@ LL | match $s { $($t)+ => {}, u32::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u32` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_u32` not covered @@ -299,7 +299,7 @@ LL | match $s { $($t)+ => {}, 43_u32 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u32` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:71:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_u32` not covered @@ -311,7 +311,7 @@ LL | match $s { $($t)+ => {}, 43_u32 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:79:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:78:12 | LL | m!(0, ..u64::MAX); | ^ pattern `u64::MAX` not covered @@ -323,7 +323,7 @@ LL | match $s { $($t)+ => {}, u64::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `18446744073709551614_u64..=u64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:79:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `18446744073709551614_u64..=u64::MAX` not covered @@ -335,7 +335,7 @@ LL | match $s { $($t)+ => {}, 18446744073709551614_u64..=u64::MAX => tod | ++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u64` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `0_u64` not covered @@ -347,7 +347,7 @@ LL | match $s { $($t)+ => {}, 0_u64 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `u64::MAX` not covered @@ -359,7 +359,7 @@ LL | match $s { $($t)+ => {}, u64::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u64` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_u64` not covered @@ -371,7 +371,7 @@ LL | match $s { $($t)+ => {}, 43_u64 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u64` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:84:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_u64` not covered @@ -383,7 +383,7 @@ LL | match $s { $($t)+ => {}, 43_u64 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u128::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:92:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:91:12 | LL | m!(0, ..u128::MAX); | ^ pattern `u128::MAX` not covered @@ -395,7 +395,7 @@ LL | match $s { $($t)+ => {}, u128::MAX => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:92:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `340282366920938463463374607431768211454_u128..` not covered @@ -407,7 +407,7 @@ LL | match $s { $($t)+ => {}, 340282366920938463463374607431768211454_u1 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u128` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `0_u128` not covered @@ -419,7 +419,7 @@ LL | match $s { $($t)+ => {}, 0_u128 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u128::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `u128::MAX` not covered @@ -431,7 +431,7 @@ LL | match $s { $($t)+ => {}, u128::MAX => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u128` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_u128` not covered @@ -443,7 +443,7 @@ LL | match $s { $($t)+ => {}, 43_u128 => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_u128` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:97:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_u128` not covered @@ -455,7 +455,7 @@ LL | match $s { $($t)+ => {}, 43_u128 => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:108:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:107:12 | LL | m!(0, ..i8::MAX); | ^ pattern `i8::MAX` not covered @@ -467,7 +467,7 @@ LL | match $s { $($t)+ => {}, i8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `126_i8..=i8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:108:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `126_i8..=i8::MAX` not covered @@ -479,7 +479,7 @@ LL | match $s { $($t)+ => {}, 126_i8..=i8::MAX => todo!() } | +++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MIN` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `i8::MIN` not covered @@ -491,7 +491,7 @@ LL | match $s { $($t)+ => {}, i8::MIN => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `i8::MAX` not covered @@ -503,7 +503,7 @@ LL | match $s { $($t)+ => {}, i8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i8` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_i8` not covered @@ -515,7 +515,7 @@ LL | match $s { $($t)+ => {}, 43_i8 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i8` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:113:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_i8` not covered @@ -527,7 +527,7 @@ LL | match $s { $($t)+ => {}, 43_i8 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:121:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:120:12 | LL | m!(0, ..i16::MAX); | ^ pattern `i16::MAX` not covered @@ -539,7 +539,7 @@ LL | match $s { $($t)+ => {}, i16::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `32766_i16..=i16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:121:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `32766_i16..=i16::MAX` not covered @@ -551,7 +551,7 @@ LL | match $s { $($t)+ => {}, 32766_i16..=i16::MAX => todo!() } | +++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i16::MIN` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `i16::MIN` not covered @@ -563,7 +563,7 @@ LL | match $s { $($t)+ => {}, i16::MIN => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i16::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `i16::MAX` not covered @@ -575,7 +575,7 @@ LL | match $s { $($t)+ => {}, i16::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i16` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_i16` not covered @@ -587,7 +587,7 @@ LL | match $s { $($t)+ => {}, 43_i16 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i16` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:126:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_i16` not covered @@ -599,7 +599,7 @@ LL | match $s { $($t)+ => {}, 43_i16 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:134:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:133:12 | LL | m!(0, ..i32::MAX); | ^ pattern `i32::MAX` not covered @@ -611,7 +611,7 @@ LL | match $s { $($t)+ => {}, i32::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `2147483646_i32..=i32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:134:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `2147483646_i32..=i32::MAX` not covered @@ -623,7 +623,7 @@ LL | match $s { $($t)+ => {}, 2147483646_i32..=i32::MAX => todo!() } | ++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i32::MIN` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `i32::MIN` not covered @@ -635,7 +635,7 @@ LL | match $s { $($t)+ => {}, i32::MIN => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i32::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `i32::MAX` not covered @@ -647,7 +647,7 @@ LL | match $s { $($t)+ => {}, i32::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i32` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_i32` not covered @@ -659,7 +659,7 @@ LL | match $s { $($t)+ => {}, 43_i32 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i32` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:139:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_i32` not covered @@ -671,7 +671,7 @@ LL | match $s { $($t)+ => {}, 43_i32 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:147:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:146:12 | LL | m!(0, ..i64::MAX); | ^ pattern `i64::MAX` not covered @@ -683,7 +683,7 @@ LL | match $s { $($t)+ => {}, i64::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `9223372036854775806_i64..=i64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:147:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `9223372036854775806_i64..=i64::MAX` not covered @@ -695,7 +695,7 @@ LL | match $s { $($t)+ => {}, 9223372036854775806_i64..=i64::MAX => todo | +++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i64::MIN` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `i64::MIN` not covered @@ -707,7 +707,7 @@ LL | match $s { $($t)+ => {}, i64::MIN => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i64::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `i64::MAX` not covered @@ -719,7 +719,7 @@ LL | match $s { $($t)+ => {}, i64::MAX => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i64` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_i64` not covered @@ -731,7 +731,7 @@ LL | match $s { $($t)+ => {}, 43_i64 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i64` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:152:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_i64` not covered @@ -743,7 +743,7 @@ LL | match $s { $($t)+ => {}, 43_i64 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i128::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:160:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:159:12 | LL | m!(0, ..i128::MAX); | ^ pattern `i128::MAX` not covered @@ -755,7 +755,7 @@ LL | match $s { $($t)+ => {}, i128::MAX => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:160:12 | LL | m!(0, ..ALMOST_MAX); | ^ pattern `170141183460469231731687303715884105726_i128..` not covered @@ -767,7 +767,7 @@ LL | match $s { $($t)+ => {}, 170141183460469231731687303715884105726_i1 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i128::MIN` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12 | LL | m!(0, ALMOST_MIN..); | ^ pattern `i128::MIN` not covered @@ -779,7 +779,7 @@ LL | match $s { $($t)+ => {}, i128::MIN => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i128::MAX` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12 | LL | m!(0, ..=ALMOST_MAX); | ^ pattern `i128::MAX` not covered @@ -791,7 +791,7 @@ LL | match $s { $($t)+ => {}, i128::MAX => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i128` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12 | LL | m!(0, ..=VAL | VAL_2..); | ^ pattern `43_i128` not covered @@ -803,7 +803,7 @@ LL | match $s { $($t)+ => {}, 43_i128 => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `43_i128` not covered - --> $DIR/half-open-range-pats-exhaustive-fail.rs:165:12 + --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12 | LL | m!(0, ..VAL_1 | VAL_2..); | ^ pattern `43_i128` not covered diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs index fe2db67013ecc..0d92ff90cc539 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs @@ -2,8 +2,6 @@ // Test various exhaustive matches for `X..`, `..=X` and `..X` ranges. -#![feature(exclusive_range_pattern)] - fn main() {} macro_rules! m { diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs index 03ff706fe6aef..3487bac528249 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -3,7 +3,6 @@ // Test half-open range patterns against their expression equivalents // via `.contains(...)` and make sure the dynamic semantics match. -#![feature(exclusive_range_pattern)] #![allow(unreachable_patterns)] macro_rules! yes { diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs index 98e8b2b04620a..4e3fffbef2de5 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs @@ -2,8 +2,6 @@ // Test the parsing of half-open ranges. -#![feature(exclusive_range_pattern)] - fn main() {} #[cfg(FALSE)] diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs index 158da6509662f..9ca8dd25ed76f 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - macro_rules! m { ($s:expr, $($t:tt)+) => { match $s { $($t)+ => {} } diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr index 169e776fc20fd..668b5c858f06c 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr @@ -1,77 +1,77 @@ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:10:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:8:11 | LL | m!(0, ..u8::MIN); | ^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:12:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:10:11 | LL | m!(0, ..u16::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:12:11 | LL | m!(0, ..u32::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:16:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11 | LL | m!(0, ..u64::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:18:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:16:11 | LL | m!(0, ..u128::MIN); | ^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:21:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:19:11 | LL | m!(0, ..i8::MIN); | ^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:21:11 | LL | m!(0, ..i16::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:25:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11 | LL | m!(0, ..i32::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:25:11 | LL | m!(0, ..i64::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:29:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11 | LL | m!(0, ..i128::MIN); | ^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:32:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:30:14 | LL | m!(0f32, ..f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:34:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:32:14 | LL | m!(0f64, ..f64::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:37:13 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:35:13 | LL | m!('a', ..'\u{0}'); | ^^^^^^^^^ diff --git a/tests/ui/half-open-range-patterns/pat-tuple-4.rs b/tests/ui/half-open-range-patterns/pat-tuple-4.rs index 95aae25ada894..325293aa486ec 100644 --- a/tests/ui/half-open-range-patterns/pat-tuple-4.rs +++ b/tests/ui/half-open-range-patterns/pat-tuple-4.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(exclusive_range_pattern)] - fn main() { const PAT: u8 = 1; diff --git a/tests/ui/half-open-range-patterns/pat-tuple-5.rs b/tests/ui/half-open-range-patterns/pat-tuple-5.rs index 995ef03c83ed7..4ed43954e0294 100644 --- a/tests/ui/half-open-range-patterns/pat-tuple-5.rs +++ b/tests/ui/half-open-range-patterns/pat-tuple-5.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - fn main() { const PAT: u8 = 1; diff --git a/tests/ui/half-open-range-patterns/pat-tuple-5.stderr b/tests/ui/half-open-range-patterns/pat-tuple-5.stderr index a7dd413979237..e6d33947d46ef 100644 --- a/tests/ui/half-open-range-patterns/pat-tuple-5.stderr +++ b/tests/ui/half-open-range-patterns/pat-tuple-5.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pat-tuple-5.rs:7:10 + --> $DIR/pat-tuple-5.rs:5:10 | LL | match (0, 1) { | ------ this expression has type `({integer}, {integer})` diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs index 53b6b89ed1662..f943ea0271da2 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs +++ b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(non_contiguous_range_endpoints)] -#![feature(exclusive_range_pattern)] #![feature(inline_const_pat)] fn main() { diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs index 0c050c550c4ce..4d7c9f10261f2 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs +++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs @@ -9,26 +9,19 @@ fn main() { for x in -9 + 1..=(9 - 2) { if let n @ 2..3|4 = x { //~^ error: variable `n` is not bound in all patterns - //~| exclusive range pattern syntax is experimental errors_only.push(x); } else if let 2..3 | 4 = x { - //~^ exclusive range pattern syntax is experimental if_lettable.push(x); } match x as i32 { 0..5+1 => errors_only.push(x), //~^ error: expected a pattern range bound, found an expression - //~| error: exclusive range pattern syntax is experimental 1 | -3..0 => first_or.push(x), - //~^ error: exclusive range pattern syntax is experimental y @ (0..5 | 6) => or_two.push(y), - //~^ error: exclusive range pattern syntax is experimental y @ 0..const { 5 + 1 } => assert_eq!(y, 5), - //~^ error: exclusive range pattern syntax is experimental - //~| error: inline-const in pattern position is experimental + //~^ error: inline-const in pattern position is experimental [E0658] y @ -5.. => range_from.push(y), y @ ..-7 => assert_eq!(y, -8), - //~^ error: exclusive range pattern syntax is experimental y => bottom.push(y), } } diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr index cc481f7a79e13..c14021e009bd1 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr @@ -1,5 +1,5 @@ error: expected a pattern range bound, found an expression - --> $DIR/range_pat_interactions1.rs:19:16 + --> $DIR/range_pat_interactions1.rs:17:16 | LL | 0..5+1 => errors_only.push(x), | ^^^ arbitrary expressions are not allowed in patterns @@ -13,7 +13,7 @@ LL | if let n @ 2..3|4 = x { | variable not in all patterns error[E0658]: inline-const in pattern position is experimental - --> $DIR/range_pat_interactions1.rs:26:20 + --> $DIR/range_pat_interactions1.rs:21:20 | LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), | ^^^^^ @@ -22,84 +22,7 @@ LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:10:20 - | -LL | if let n @ 2..3|4 = x { - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:14:23 - | -LL | } else if let 2..3 | 4 = x { - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:19:13 - | -LL | 0..5+1 => errors_only.push(x), - | ^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:22:17 - | -LL | 1 | -3..0 => first_or.push(x), - | ^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:24:18 - | -LL | y @ (0..5 | 6) => or_two.push(y), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:26:17 - | -LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions1.rs:30:17 - | -LL | y @ ..-7 => assert_eq!(y, -8), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error: aborting due to 10 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0408, E0658. For more information about an error, try `rustc --explain E0408`. diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs index 068104c4b1b8c..0dbdb8fe7b6ef 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs +++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs @@ -11,15 +11,11 @@ fn main() { //~^ error: expected a pattern range bound, found an expression //~| error: range pattern bounds cannot have parentheses 1 | -3..0 => first_or.push(x), - //~^ error: exclusive range pattern syntax is experimental y @ (0..5 | 6) => or_two.push(y), - //~^ error: exclusive range pattern syntax is experimental y @ 0..const { 5 + 1 } => assert_eq!(y, 5), //~^ error: inline-const in pattern position is experimental - //~| error: exclusive range pattern syntax is experimental y @ -5.. => range_from.push(y), y @ ..-7 => assert_eq!(y, -8), - //~^ error: exclusive range pattern syntax is experimental y => bottom.push(y), } } diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr index 8f21a6149fb89..136296fa5b0f0 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr @@ -17,7 +17,7 @@ LL + 0..=5+1 => errors_only.push(x), | error[E0658]: inline-const in pattern position is experimental - --> $DIR/range_pat_interactions2.rs:17:20 + --> $DIR/range_pat_interactions2.rs:15:20 | LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), | ^^^^^ @@ -26,50 +26,6 @@ LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions2.rs:13:17 - | -LL | 1 | -3..0 => first_or.push(x), - | ^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions2.rs:15:18 - | -LL | y @ (0..5 | 6) => or_two.push(y), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions2.rs:17:17 - | -LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions2.rs:21:17 - | -LL | y @ ..-7 => assert_eq!(y, -8), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error: aborting due to 7 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.rs b/tests/ui/half-open-range-patterns/range_pat_interactions3.rs index 446ed45f9c6f0..2f2778095cf49 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions3.rs +++ b/tests/ui/half-open-range-patterns/range_pat_interactions3.rs @@ -8,15 +8,11 @@ fn main() { match x as i32 { 8.. => bottom.push(x), 1 | -3..0 => first_or.push(x), - //~^ exclusive range pattern syntax is experimental y @ (0..5 | 6) => or_two.push(y), - //~^ exclusive range pattern syntax is experimental y @ 0..const { 5 + 1 } => assert_eq!(y, 5), //~^ inline-const in pattern position is experimental - //~| exclusive range pattern syntax is experimental y @ -5.. => range_from.push(y), y @ ..-7 => assert_eq!(y, -8), - //~^ exclusive range pattern syntax is experimental y => bottom.push(y), } } diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr index 51cc22e7d5602..dc7dc0efa7a28 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr @@ -1,5 +1,5 @@ error[E0658]: inline-const in pattern position is experimental - --> $DIR/range_pat_interactions3.rs:14:20 + --> $DIR/range_pat_interactions3.rs:12:20 | LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), | ^^^^^ @@ -8,50 +8,6 @@ LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions3.rs:10:17 - | -LL | 1 | -3..0 => first_or.push(x), - | ^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions3.rs:12:18 - | -LL | y @ (0..5 | 6) => or_two.push(y), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions3.rs:14:17 - | -LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range_pat_interactions3.rs:18:17 - | -LL | y @ ..-7 => assert_eq!(y, -8), - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error: aborting due to 5 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs index d54cbfbf4bbf9..aa2690f377768 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs @@ -1,5 +1,4 @@ #![feature(half_open_range_patterns_in_slices)] -#![feature(exclusive_range_pattern)] fn main() { let xs = [13, 1, 5, 2, 3, 1, 21, 8]; diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr index eca5c3301801f..5bcbe21a6a930 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr @@ -1,5 +1,5 @@ error[E0527]: pattern requires 2 elements but array has 8 - --> $DIR/slice_pattern_syntax_problem0.rs:11:9 + --> $DIR/slice_pattern_syntax_problem0.rs:10:9 | LL | let [first_three @ ..3, rest @ 2..] = xs; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 8 elements diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs index cd38154437266..60b056fbcb694 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs @@ -3,7 +3,5 @@ fn main() { let xs = [13, 1, 5, 2, 3, 1, 21, 8]; let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; //~^ `X..` patterns in slices are experimental - //~| exclusive range pattern syntax is experimental - //~| exclusive range pattern syntax is experimental //~| ERROR: refutable pattern } diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr index fc549eb65c0ed..4951591990462 100644 --- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr +++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr @@ -8,28 +8,6 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; = help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/slice_pattern_syntax_problem1.rs:4:23 - | -LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; - | ^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/slice_pattern_syntax_problem1.rs:4:32 - | -LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs; - | ^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - error[E0005]: refutable pattern in local binding --> $DIR/slice_pattern_syntax_problem1.rs:4:9 | @@ -44,7 +22,7 @@ help: you might want to use `let else` to handle the variant that isn't matched LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() }; | ++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0005, E0658. For more information about an error, try `rustc --explain E0005`. diff --git a/tests/ui/inline-const/const-match-pat-range.rs b/tests/ui/inline-const/const-match-pat-range.rs index 7f51815cb7792..7202c0c04521e 100644 --- a/tests/ui/inline-const/const-match-pat-range.rs +++ b/tests/ui/inline-const/const-match-pat-range.rs @@ -1,6 +1,6 @@ //@ build-pass -#![feature(inline_const_pat, exclusive_range_pattern)] +#![feature(inline_const_pat)] fn main() { const N: u32 = 10; diff --git a/tests/ui/match/match-range-fail-2.rs b/tests/ui/match/match-range-fail-2.rs index 4489cf1ab1f2b..524e84323e7cd 100644 --- a/tests/ui/match/match-range-fail-2.rs +++ b/tests/ui/match/match-range-fail-2.rs @@ -1,5 +1,3 @@ -#![feature(exclusive_range_pattern)] - fn main() { match 5 { 6 ..= 1 => { } diff --git a/tests/ui/match/match-range-fail-2.stderr b/tests/ui/match/match-range-fail-2.stderr index 089fa851f97c2..8bad2e6e1470f 100644 --- a/tests/ui/match/match-range-fail-2.stderr +++ b/tests/ui/match/match-range-fail-2.stderr @@ -1,17 +1,17 @@ error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/match-range-fail-2.rs:5:9 + --> $DIR/match-range-fail-2.rs:3:9 | LL | 6 ..= 1 => { } | ^^^^^^^ lower bound larger than upper bound error[E0579]: lower range bound must be less than upper - --> $DIR/match-range-fail-2.rs:11:9 + --> $DIR/match-range-fail-2.rs:9:9 | LL | 0 .. 0 => { } | ^^^^^^ error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/match-range-fail-2.rs:17:9 + --> $DIR/match-range-fail-2.rs:15:9 | LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound diff --git a/tests/ui/match/validate-range-endpoints.rs b/tests/ui/match/validate-range-endpoints.rs index 31d5bc3b65d50..46d4239886d3c 100644 --- a/tests/ui/match/validate-range-endpoints.rs +++ b/tests/ui/match/validate-range-endpoints.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![feature(inline_const_pat)] #![allow(overlapping_range_endpoints)] diff --git a/tests/ui/match/validate-range-endpoints.stderr b/tests/ui/match/validate-range-endpoints.stderr index b3b4066cd9158..2d0538804a378 100644 --- a/tests/ui/match/validate-range-endpoints.stderr +++ b/tests/ui/match/validate-range-endpoints.stderr @@ -1,59 +1,59 @@ error: literal out of range for `u8` - --> $DIR/validate-range-endpoints.rs:8:12 + --> $DIR/validate-range-endpoints.rs:7:12 | LL | 1..257 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` error: literal out of range for `u8` - --> $DIR/validate-range-endpoints.rs:10:13 + --> $DIR/validate-range-endpoints.rs:9:13 | LL | 1..=256 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/validate-range-endpoints.rs:19:9 + --> $DIR/validate-range-endpoints.rs:18:9 | LL | 1..=TOO_BIG => {} | ^^^^^^^^^^^ lower bound larger than upper bound error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/validate-range-endpoints.rs:21:9 + --> $DIR/validate-range-endpoints.rs:20:9 | LL | 1..=const { 256 } => {} | ^^^^^^^^^^^^^^^^^ lower bound larger than upper bound error: literal out of range for `u64` - --> $DIR/validate-range-endpoints.rs:27:32 + --> $DIR/validate-range-endpoints.rs:26:32 | LL | 10000000000000000000..=99999999999999999999 => {} | ^^^^^^^^^^^^^^^^^^^^ this value does not fit into the type `u64` whose range is `0..=18446744073709551615` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:33:12 + --> $DIR/validate-range-endpoints.rs:32:12 | LL | 0..129 => {} | ^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:35:13 + --> $DIR/validate-range-endpoints.rs:34:13 | LL | 0..=128 => {} | ^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:37:9 + --> $DIR/validate-range-endpoints.rs:36:9 | LL | -129..0 => {} | ^^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:39:9 + --> $DIR/validate-range-endpoints.rs:38:9 | LL | -10000..=-20 => {} | ^^^^^^ this value does not fit into the type `i8` whose range is `-128..=127` error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered - --> $DIR/validate-range-endpoints.rs:50:11 + --> $DIR/validate-range-endpoints.rs:49:11 | LL | match 0i8 { | ^^^ patterns `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered @@ -66,7 +66,7 @@ LL + i8::MIN..=-17_i8 | 1_i8..=i8::MAX => todo!() | error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` not covered - --> $DIR/validate-range-endpoints.rs:54:11 + --> $DIR/validate-range-endpoints.rs:53:11 | LL | match 0i8 { | ^^^ pattern `i8::MIN..=-17_i8` not covered diff --git a/tests/ui/mir/mir_match_test.rs b/tests/ui/mir/mir_match_test.rs index 0da8522f2181a..ad54a91646ab0 100644 --- a/tests/ui/mir/mir_match_test.rs +++ b/tests/ui/mir/mir_match_test.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![allow(overlapping_range_endpoints)] #![allow(non_contiguous_range_endpoints)] diff --git a/tests/ui/parser/issues/issue-63115-range-pat-interpolated.rs b/tests/ui/parser/issues/issue-63115-range-pat-interpolated.rs index d1a5f32b95464..9a6bd4442e563 100644 --- a/tests/ui/parser/issues/issue-63115-range-pat-interpolated.rs +++ b/tests/ui/parser/issues/issue-63115-range-pat-interpolated.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(exclusive_range_pattern)] - #![allow(ellipsis_inclusive_range_patterns)] fn main() { diff --git a/tests/ui/parser/recover/recover-range-pats.rs b/tests/ui/parser/recover/recover-range-pats.rs index 3dc525cd6e104..42cd69fd9594d 100644 --- a/tests/ui/parser/recover/recover-range-pats.rs +++ b/tests/ui/parser/recover/recover-range-pats.rs @@ -3,7 +3,6 @@ // 1. Things parse as they should. // 2. Or at least we have parser recovery if they don't. -#![feature(exclusive_range_pattern)] #![deny(ellipsis_inclusive_range_patterns)] fn main() {} diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr index 2c0baf7e5f80b..e0ea8ec24dcf2 100644 --- a/tests/ui/parser/recover/recover-range-pats.stderr +++ b/tests/ui/parser/recover/recover-range-pats.stderr @@ -1,47 +1,47 @@ error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:21:12 + --> $DIR/recover-range-pats.rs:20:12 | LL | if let .0..Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:23:16 + --> $DIR/recover-range-pats.rs:22:16 | LL | if let X.. .0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:34:12 + --> $DIR/recover-range-pats.rs:33:12 | LL | if let .0..=Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:36:16 + --> $DIR/recover-range-pats.rs:35:16 | LL | if let X..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:59:12 + --> $DIR/recover-range-pats.rs:58:12 | LL | if let .0...Y = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:63:17 + --> $DIR/recover-range-pats.rs:62:17 | LL | if let X... .0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:74:12 + --> $DIR/recover-range-pats.rs:73:12 | LL | if let .0.. = 0 {} | ^^ help: must have an integer part: `0.0` error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:80:13 + --> $DIR/recover-range-pats.rs:79:13 | LL | if let 0..= = 0 {} | ^^^ help: use `..` instead @@ -49,7 +49,7 @@ LL | if let 0..= = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:81:13 + --> $DIR/recover-range-pats.rs:80:13 | LL | if let X..= = 0 {} | ^^^ help: use `..` instead @@ -57,7 +57,7 @@ LL | if let X..= = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:82:16 + --> $DIR/recover-range-pats.rs:81:16 | LL | if let true..= = 0 {} | ^^^ help: use `..` instead @@ -65,13 +65,13 @@ LL | if let true..= = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:84:12 + --> $DIR/recover-range-pats.rs:83:12 | LL | if let .0..= = 0 {} | ^^ help: must have an integer part: `0.0` error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:84:14 + --> $DIR/recover-range-pats.rs:83:14 | LL | if let .0..= = 0 {} | ^^^ help: use `..` instead @@ -79,7 +79,7 @@ LL | if let .0..= = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:90:13 + --> $DIR/recover-range-pats.rs:89:13 | LL | if let 0... = 0 {} | ^^^ help: use `..` instead @@ -87,7 +87,7 @@ LL | if let 0... = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:91:13 + --> $DIR/recover-range-pats.rs:90:13 | LL | if let X... = 0 {} | ^^^ help: use `..` instead @@ -95,7 +95,7 @@ LL | if let X... = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:92:16 + --> $DIR/recover-range-pats.rs:91:16 | LL | if let true... = 0 {} | ^^^ help: use `..` instead @@ -103,13 +103,13 @@ LL | if let true... = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:94:12 + --> $DIR/recover-range-pats.rs:93:12 | LL | if let .0... = 0 {} | ^^ help: must have an integer part: `0.0` error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:94:14 + --> $DIR/recover-range-pats.rs:93:14 | LL | if let .0... = 0 {} | ^^^ help: use `..` instead @@ -117,49 +117,49 @@ LL | if let .0... = 0 {} = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:104:15 + --> $DIR/recover-range-pats.rs:103:15 | LL | if let .. .0 = 0 {} | ^^ help: must have an integer part: `0.0` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:114:15 + --> $DIR/recover-range-pats.rs:113:15 | LL | if let ..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` error: range-to patterns with `...` are not allowed - --> $DIR/recover-range-pats.rs:120:12 + --> $DIR/recover-range-pats.rs:119:12 | LL | if let ...3 = 0 {} | ^^^ help: use `..=` instead error: range-to patterns with `...` are not allowed - --> $DIR/recover-range-pats.rs:122:12 + --> $DIR/recover-range-pats.rs:121:12 | LL | if let ...Y = 0 {} | ^^^ help: use `..=` instead error: range-to patterns with `...` are not allowed - --> $DIR/recover-range-pats.rs:124:12 + --> $DIR/recover-range-pats.rs:123:12 | LL | if let ...true = 0 {} | ^^^ help: use `..=` instead error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:127:15 + --> $DIR/recover-range-pats.rs:126:15 | LL | if let ....3 = 0 {} | ^^ help: must have an integer part: `0.3` error: range-to patterns with `...` are not allowed - --> $DIR/recover-range-pats.rs:127:12 + --> $DIR/recover-range-pats.rs:126:12 | LL | if let ....3 = 0 {} | ^^^ help: use `..=` instead error: range-to patterns with `...` are not allowed - --> $DIR/recover-range-pats.rs:153:17 + --> $DIR/recover-range-pats.rs:152:17 | LL | let ...$e; | ^^^ help: use `..=` instead @@ -170,7 +170,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:160:19 + --> $DIR/recover-range-pats.rs:159:19 | LL | let $e...; | ^^^ help: use `..` instead @@ -182,7 +182,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0586]: inclusive range with no end - --> $DIR/recover-range-pats.rs:162:19 + --> $DIR/recover-range-pats.rs:161:19 | LL | let $e..=; | ^^^ help: use `..` instead @@ -194,7 +194,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:41:13 + --> $DIR/recover-range-pats.rs:40:13 | LL | if let 0...3 = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -202,13 +202,13 @@ LL | if let 0...3 = 0 {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see note: the lint level is defined here - --> $DIR/recover-range-pats.rs:7:9 + --> $DIR/recover-range-pats.rs:6:9 | LL | #![deny(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:44:13 + --> $DIR/recover-range-pats.rs:43:13 | LL | if let 0...Y = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -217,7 +217,7 @@ LL | if let 0...Y = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:47:13 + --> $DIR/recover-range-pats.rs:46:13 | LL | if let X...3 = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -226,7 +226,7 @@ LL | if let X...3 = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:50:13 + --> $DIR/recover-range-pats.rs:49:13 | LL | if let X...Y = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -235,7 +235,7 @@ LL | if let X...Y = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:53:16 + --> $DIR/recover-range-pats.rs:52:16 | LL | if let true...Y = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -244,7 +244,7 @@ LL | if let true...Y = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:56:13 + --> $DIR/recover-range-pats.rs:55:13 | LL | if let X...true = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -253,7 +253,7 @@ LL | if let X...true = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:59:14 + --> $DIR/recover-range-pats.rs:58:14 | LL | if let .0...Y = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -262,7 +262,7 @@ LL | if let .0...Y = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:63:13 + --> $DIR/recover-range-pats.rs:62:13 | LL | if let X... .0 = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -271,7 +271,7 @@ LL | if let X... .0 = 0 {} = note: for more information, see error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:138:20 + --> $DIR/recover-range-pats.rs:137:20 | LL | let $e1...$e2; | ^^^ help: use `..=` for an inclusive range @@ -284,7 +284,7 @@ LL | mac2!(0, 1); = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:19:12 + --> $DIR/recover-range-pats.rs:18:12 | LL | if let true..Y = 0 {} | ^^^^ - this is of type `u8` @@ -292,7 +292,7 @@ LL | if let true..Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:20:15 + --> $DIR/recover-range-pats.rs:19:15 | LL | if let X..true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -300,7 +300,7 @@ LL | if let X..true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:21:12 + --> $DIR/recover-range-pats.rs:20:12 | LL | if let .0..Y = 0 {} | ^^ - - this expression has type `{integer}` @@ -309,7 +309,7 @@ LL | if let .0..Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:23:16 + --> $DIR/recover-range-pats.rs:22:16 | LL | if let X.. .0 = 0 {} | - ^^ - this expression has type `u8` @@ -321,7 +321,7 @@ LL | if let X.. .0 = 0 {} found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:32:12 + --> $DIR/recover-range-pats.rs:31:12 | LL | if let true..=Y = 0 {} | ^^^^ - this is of type `u8` @@ -329,7 +329,7 @@ LL | if let true..=Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:33:16 + --> $DIR/recover-range-pats.rs:32:16 | LL | if let X..=true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -337,7 +337,7 @@ LL | if let X..=true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:34:12 + --> $DIR/recover-range-pats.rs:33:12 | LL | if let .0..=Y = 0 {} | ^^ - - this expression has type `{integer}` @@ -346,7 +346,7 @@ LL | if let .0..=Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:36:16 + --> $DIR/recover-range-pats.rs:35:16 | LL | if let X..=.0 = 0 {} | - ^^ - this expression has type `u8` @@ -358,7 +358,7 @@ LL | if let X..=.0 = 0 {} found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:53:12 + --> $DIR/recover-range-pats.rs:52:12 | LL | if let true...Y = 0 {} | ^^^^ - this is of type `u8` @@ -366,7 +366,7 @@ LL | if let true...Y = 0 {} | this is of type `bool` but it should be `char` or numeric error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:56:16 + --> $DIR/recover-range-pats.rs:55:16 | LL | if let X...true = 0 {} | - ^^^^ this is of type `bool` but it should be `char` or numeric @@ -374,7 +374,7 @@ LL | if let X...true = 0 {} | this is of type `u8` error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:59:12 + --> $DIR/recover-range-pats.rs:58:12 | LL | if let .0...Y = 0 {} | ^^ - - this expression has type `{integer}` @@ -383,7 +383,7 @@ LL | if let .0...Y = 0 {} | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:63:17 + --> $DIR/recover-range-pats.rs:62:17 | LL | if let X... .0 = 0 {} | - ^^ - this expression has type `u8` @@ -395,13 +395,13 @@ LL | if let X... .0 = 0 {} found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:72:12 + --> $DIR/recover-range-pats.rs:71:12 | LL | if let true.. = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:74:12 + --> $DIR/recover-range-pats.rs:73:12 | LL | if let .0.. = 0 {} | ^^ - this expression has type `{integer}` @@ -409,13 +409,13 @@ LL | if let .0.. = 0 {} | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:82:12 + --> $DIR/recover-range-pats.rs:81:12 | LL | if let true..= = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:84:12 + --> $DIR/recover-range-pats.rs:83:12 | LL | if let .0..= = 0 {} | ^^ - this expression has type `{integer}` @@ -423,13 +423,13 @@ LL | if let .0..= = 0 {} | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:92:12 + --> $DIR/recover-range-pats.rs:91:12 | LL | if let true... = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:94:12 + --> $DIR/recover-range-pats.rs:93:12 | LL | if let .0... = 0 {} | ^^ - this expression has type `{integer}` @@ -437,13 +437,13 @@ LL | if let .0... = 0 {} | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:102:14 + --> $DIR/recover-range-pats.rs:101:14 | LL | if let ..true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:104:15 + --> $DIR/recover-range-pats.rs:103:15 | LL | if let .. .0 = 0 {} | ^^ - this expression has type `{integer}` @@ -451,13 +451,13 @@ LL | if let .. .0 = 0 {} | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:112:15 + --> $DIR/recover-range-pats.rs:111:15 | LL | if let ..=true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:114:15 + --> $DIR/recover-range-pats.rs:113:15 | LL | if let ..=.0 = 0 {} | ^^ - this expression has type `{integer}` @@ -465,13 +465,13 @@ LL | if let ..=.0 = 0 {} | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:124:15 + --> $DIR/recover-range-pats.rs:123:15 | LL | if let ...true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:127:15 + --> $DIR/recover-range-pats.rs:126:15 | LL | if let ....3 = 0 {} | ^^ - this expression has type `{integer}` @@ -479,7 +479,7 @@ LL | if let ....3 = 0 {} | expected integer, found floating-point number error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:136:17 + --> $DIR/recover-range-pats.rs:135:17 | LL | let $e1..$e2; | ^^^^^^^^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered @@ -493,7 +493,7 @@ LL | mac2!(0, 1); = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:138:17 + --> $DIR/recover-range-pats.rs:137:17 | LL | let $e1...$e2; | ^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `2_i32..=i32::MAX` not covered @@ -507,7 +507,7 @@ LL | mac2!(0, 1); = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:142:17 + --> $DIR/recover-range-pats.rs:141:17 | LL | let $e1..=$e2; | ^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `2_i32..=i32::MAX` not covered @@ -521,7 +521,7 @@ LL | mac2!(0, 1); = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:151:17 + --> $DIR/recover-range-pats.rs:150:17 | LL | let ..$e; | ^^^^ pattern `0_i32..=i32::MAX` not covered @@ -535,7 +535,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:153:17 + --> $DIR/recover-range-pats.rs:152:17 | LL | let ...$e; | ^^^^^ pattern `1_i32..=i32::MAX` not covered @@ -549,7 +549,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:156:17 + --> $DIR/recover-range-pats.rs:155:17 | LL | let ..=$e; | ^^^^^ pattern `1_i32..=i32::MAX` not covered @@ -563,7 +563,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:158:17 + --> $DIR/recover-range-pats.rs:157:17 | LL | let $e..; | ^^^^ pattern `i32::MIN..=-1_i32` not covered @@ -577,7 +577,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:160:17 + --> $DIR/recover-range-pats.rs:159:17 | LL | let $e...; | ^^^^^ pattern `i32::MIN..=-1_i32` not covered @@ -591,7 +591,7 @@ LL | mac!(0); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0005]: refutable pattern in local binding - --> $DIR/recover-range-pats.rs:162:17 + --> $DIR/recover-range-pats.rs:161:17 | LL | let $e..=; | ^^^^^ pattern `i32::MIN..=-1_i32` not covered diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs index 1eba7aeb4d64a..fe7655c2c4e1c 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs @@ -11,7 +11,6 @@ fn main() { [_, ..tail] => println!("{tail}"), //~^ ERROR cannot find value `tail` in this scope //~| ERROR cannot find value `tail` in this scope - //~| ERROR exclusive range pattern syntax is experimental } match &[7, 8, 9][..] { [] => {} diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 3a19517c85bd2..37c02eb6ada9c 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -1,5 +1,5 @@ error: range-to patterns with `...` are not allowed - --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:13 + --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:13 | LL | [_, ...tail] => println!("{tail}"), | ^^^ help: use `..=` instead @@ -39,7 +39,7 @@ LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope error[E0425]: cannot find value `tail` in this scope - --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:16 + --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:16 | LL | [_, ...tail] => println!("{tail}"), | ^^^^ not found in this scope @@ -50,7 +50,7 @@ LL | [_, tail @ ..] => println!("{tail}"), | ~~~~~~~~~ error[E0425]: cannot find value `tail` in this scope - --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:36 + --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 | LL | [_, ...tail] => println!("{tail}"), | ^^^^ not found in this scope @@ -65,18 +65,7 @@ LL | [1, rest..] => println!("{rest}"), = help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:13 - | -LL | [_, ..tail] => println!("{tail}"), - | ^^^^^^ - | - = note: see issue #37854 for more information - = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: use an inclusive range pattern, like N..=M - -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0425, E0658. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/pattern/usefulness/floats.rs b/tests/ui/pattern/usefulness/floats.rs index 63ce26adab2a4..b3d49ba8e15e5 100644 --- a/tests/ui/pattern/usefulness/floats.rs +++ b/tests/ui/pattern/usefulness/floats.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![deny(unreachable_patterns)] fn main() { diff --git a/tests/ui/pattern/usefulness/floats.stderr b/tests/ui/pattern/usefulness/floats.stderr index d99f05f52842d..04f2fe3cd94f4 100644 --- a/tests/ui/pattern/usefulness/floats.stderr +++ b/tests/ui/pattern/usefulness/floats.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/floats.rs:10:11 + --> $DIR/floats.rs:9:11 | LL | match 0.0 { | ^^^ pattern `_` not covered @@ -12,49 +12,49 @@ LL + _ => todo!() | error: unreachable pattern - --> $DIR/floats.rs:18:9 + --> $DIR/floats.rs:17:9 | LL | 0.01f64 => {} | ^^^^^^^ | note: the lint level is defined here - --> $DIR/floats.rs:2:9 + --> $DIR/floats.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:19:9 + --> $DIR/floats.rs:18:9 | LL | 0.02f64 => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:20:9 + --> $DIR/floats.rs:19:9 | LL | 6.5f64 => {} | ^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:22:9 + --> $DIR/floats.rs:21:9 | LL | 1.0f64..=4.0f64 => {} | ^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:34:9 + --> $DIR/floats.rs:33:9 | LL | 0.01f32 => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:35:9 + --> $DIR/floats.rs:34:9 | LL | 0.02f32 => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/floats.rs:36:9 + --> $DIR/floats.rs:35:9 | LL | 6.5f32 => {} | ^^^^^^ diff --git a/tests/ui/pattern/usefulness/guards.rs b/tests/ui/pattern/usefulness/guards.rs index b15440cf608bd..94ee8ee14adf1 100644 --- a/tests/ui/pattern/usefulness/guards.rs +++ b/tests/ui/pattern/usefulness/guards.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![deny(unreachable_patterns)] enum Q { R(Option) } diff --git a/tests/ui/pattern/usefulness/guards.stderr b/tests/ui/pattern/usefulness/guards.stderr index ad9046fe24828..82ed2a93c55f5 100644 --- a/tests/ui/pattern/usefulness/guards.stderr +++ b/tests/ui/pattern/usefulness/guards.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered - --> $DIR/guards.rs:12:11 + --> $DIR/guards.rs:11:11 | LL | match 0u8 { | ^^^ pattern `128_u8..=u8::MAX` not covered diff --git a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs index 07156d9a08a34..026175e3abf72 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![allow(overlapping_range_endpoints)] #![allow(non_contiguous_range_endpoints)] #![deny(unreachable_patterns)] diff --git a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr index 68976c1b0576f..cc250b79274c6 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/exhaustiveness.rs:48:8 + --> $DIR/exhaustiveness.rs:47:8 | LL | m!(0u8, 0..255); | ^^^ pattern `u8::MAX` not covered @@ -11,7 +11,7 @@ LL | match $s { $($t)+ => {}, u8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/exhaustiveness.rs:49:8 + --> $DIR/exhaustiveness.rs:48:8 | LL | m!(0u8, 0..=254); | ^^^ pattern `u8::MAX` not covered @@ -23,7 +23,7 @@ LL | match $s { $($t)+ => {}, u8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u8` not covered - --> $DIR/exhaustiveness.rs:50:8 + --> $DIR/exhaustiveness.rs:49:8 | LL | m!(0u8, 1..=255); | ^^^ pattern `0_u8` not covered @@ -35,7 +35,7 @@ LL | match $s { $($t)+ => {}, 0_u8 => todo!() } | +++++++++++++++++ error[E0004]: non-exhaustive patterns: `42_u8` not covered - --> $DIR/exhaustiveness.rs:51:8 + --> $DIR/exhaustiveness.rs:50:8 | LL | m!(0u8, 0..42 | 43..=255); | ^^^ pattern `42_u8` not covered @@ -47,7 +47,7 @@ LL | match $s { $($t)+ => {}, 42_u8 => todo!() } | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/exhaustiveness.rs:52:8 + --> $DIR/exhaustiveness.rs:51:8 | LL | m!(0i8, -128..127); | ^^^ pattern `i8::MAX` not covered @@ -59,7 +59,7 @@ LL | match $s { $($t)+ => {}, i8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/exhaustiveness.rs:53:8 + --> $DIR/exhaustiveness.rs:52:8 | LL | m!(0i8, -128..=126); | ^^^ pattern `i8::MAX` not covered @@ -71,7 +71,7 @@ LL | match $s { $($t)+ => {}, i8::MAX => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i8::MIN` not covered - --> $DIR/exhaustiveness.rs:54:8 + --> $DIR/exhaustiveness.rs:53:8 | LL | m!(0i8, -127..=127); | ^^^ pattern `i8::MIN` not covered @@ -83,7 +83,7 @@ LL | match $s { $($t)+ => {}, i8::MIN => todo!() } | ++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_i8` not covered - --> $DIR/exhaustiveness.rs:55:11 + --> $DIR/exhaustiveness.rs:54:11 | LL | match 0i8 { | ^^^ pattern `0_i8` not covered @@ -96,7 +96,7 @@ LL + 0_i8 => todo!() | error[E0004]: non-exhaustive patterns: `u128::MAX` not covered - --> $DIR/exhaustiveness.rs:60:8 + --> $DIR/exhaustiveness.rs:59:8 | LL | m!(0u128, 0..=ALMOST_MAX); | ^^^^^ pattern `u128::MAX` not covered @@ -108,7 +108,7 @@ LL | match $s { $($t)+ => {}, u128::MAX => todo!() } | ++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `5_u128..` not covered - --> $DIR/exhaustiveness.rs:61:8 + --> $DIR/exhaustiveness.rs:60:8 | LL | m!(0u128, 0..=4); | ^^^^^ pattern `5_u128..` not covered @@ -120,7 +120,7 @@ LL | match $s { $($t)+ => {}, 5_u128.. => todo!() } | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u128` not covered - --> $DIR/exhaustiveness.rs:62:8 + --> $DIR/exhaustiveness.rs:61:8 | LL | m!(0u128, 1..=u128::MAX); | ^^^^^ pattern `0_u128` not covered @@ -132,7 +132,7 @@ LL | match $s { $($t)+ => {}, 0_u128 => todo!() } | +++++++++++++++++++ error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered - --> $DIR/exhaustiveness.rs:70:11 + --> $DIR/exhaustiveness.rs:69:11 | LL | match (0u8, true) { | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered diff --git a/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.rs b/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.rs index 78849d7e14325..2e2519d1b6d8f 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![deny(non_contiguous_range_endpoints)] macro_rules! m { diff --git a/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.stderr b/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.stderr index e5c2d788ba4ef..8a029073f0574 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/gap_between_ranges.stderr @@ -1,5 +1,5 @@ error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:16:9 + --> $DIR/gap_between_ranges.rs:15:9 | LL | 20..30 => {} | ^^^^^^ @@ -10,13 +10,13 @@ LL | 31..=40 => {} | ------- this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them | note: the lint level is defined here - --> $DIR/gap_between_ranges.rs:2:9 + --> $DIR/gap_between_ranges.rs:1:9 | LL | #![deny(non_contiguous_range_endpoints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:21:9 + --> $DIR/gap_between_ranges.rs:20:9 | LL | 20..30 => {} | ^^^^^^ @@ -27,7 +27,7 @@ LL | 31 => {} | -- this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:26:13 + --> $DIR/gap_between_ranges.rs:25:13 | LL | m!(0u8, 20..30, 31..=40); | ^^^^^^ ------- this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them @@ -36,7 +36,7 @@ LL | m!(0u8, 20..30, 31..=40); | help: use an inclusive range instead: `20_u8..=30_u8` error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:27:22 + --> $DIR/gap_between_ranges.rs:26:22 | LL | m!(0u8, 31..=40, 20..30); | ------- ^^^^^^ @@ -46,7 +46,7 @@ LL | m!(0u8, 31..=40, 20..30); | this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them warning: multiple patterns overlap on their endpoints - --> $DIR/gap_between_ranges.rs:28:21 + --> $DIR/gap_between_ranges.rs:27:21 | LL | m!(0u8, 20..30, 29..=40); | ------ ^^^^^^^ ... with this range @@ -57,7 +57,7 @@ LL | m!(0u8, 20..30, 29..=40); = note: `#[warn(overlapping_range_endpoints)]` on by default error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:30:13 + --> $DIR/gap_between_ranges.rs:29:13 | LL | m!(0u8, 20..30, 31..=40); | ^^^^^^ ------- this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them @@ -66,7 +66,7 @@ LL | m!(0u8, 20..30, 31..=40); | help: use an inclusive range instead: `20_u8..=30_u8` error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:32:13 + --> $DIR/gap_between_ranges.rs:31:13 | LL | m!(0u8, 20..30, 31..=32); | ^^^^^^ ------- this could appear to continue range `20_u8..30_u8`, but `30_u8` isn't matched by either of them @@ -75,7 +75,7 @@ LL | m!(0u8, 20..30, 31..=32); | help: use an inclusive range instead: `20_u8..=30_u8` error: exclusive range missing `u8::MAX` - --> $DIR/gap_between_ranges.rs:42:9 + --> $DIR/gap_between_ranges.rs:41:9 | LL | 0..255 => {} | ^^^^^^ @@ -84,7 +84,7 @@ LL | 0..255 => {} | help: use an inclusive range instead: `0_u8..=u8::MAX` error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:71:9 + --> $DIR/gap_between_ranges.rs:70:9 | LL | 0..10 => {} | ^^^^^ @@ -97,7 +97,7 @@ LL | 11..30 => {} | ------ this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:77:9 + --> $DIR/gap_between_ranges.rs:76:9 | LL | 0..10 => {} | ^^^^^ @@ -108,7 +108,7 @@ LL | 11..20 => {} | ------ this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:78:9 + --> $DIR/gap_between_ranges.rs:77:9 | LL | 11..20 => {} | ^^^^^^ @@ -119,7 +119,7 @@ LL | 21..30 => {} | ------ this could appear to continue range `11_u8..20_u8`, but `20_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:83:9 + --> $DIR/gap_between_ranges.rs:82:9 | LL | 00..20 => {} | ^^^^^^ @@ -133,7 +133,7 @@ LL | 21..40 => {} | ------ this could appear to continue range `0_u8..20_u8`, but `20_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:84:9 + --> $DIR/gap_between_ranges.rs:83:9 | LL | 10..20 => {} | ^^^^^^ @@ -146,7 +146,7 @@ LL | 21..40 => {} | ------ this could appear to continue range `10_u8..20_u8`, but `20_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:92:10 + --> $DIR/gap_between_ranges.rs:91:10 | LL | (0..10, true) => {} | ^^^^^ @@ -157,7 +157,7 @@ LL | (11..20, true) => {} | ------ this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:97:16 + --> $DIR/gap_between_ranges.rs:96:16 | LL | (true, 0..10) => {} | ^^^^^ @@ -168,7 +168,7 @@ LL | (true, 11..20) => {} | ------ this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:103:10 + --> $DIR/gap_between_ranges.rs:102:10 | LL | (0..10, true) => {} | ^^^^^ @@ -179,7 +179,7 @@ LL | (11..20, false) => {} | ------ this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them error: multiple ranges are one apart - --> $DIR/gap_between_ranges.rs:113:14 + --> $DIR/gap_between_ranges.rs:112:14 | LL | Some(0..10) => {} | ^^^^^ diff --git a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs index 7e56880a87f70..a5b7a90161635 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![deny(overlapping_range_endpoints)] macro_rules! m { diff --git a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index aa37bd9bc9c9c..6634532d5edd9 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -1,5 +1,5 @@ error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:15:22 + --> $DIR/overlapping_range_endpoints.rs:14:22 | LL | m!(0u8, 20..=30, 30..=40); | ------- ^^^^^^^ ... with this range @@ -8,13 +8,13 @@ LL | m!(0u8, 20..=30, 30..=40); | = note: you likely meant to write mutually exclusive ranges note: the lint level is defined here - --> $DIR/overlapping_range_endpoints.rs:2:9 + --> $DIR/overlapping_range_endpoints.rs:1:9 | LL | #![deny(overlapping_range_endpoints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:16:22 + --> $DIR/overlapping_range_endpoints.rs:15:22 | LL | m!(0u8, 30..=40, 20..=30); | ------- ^^^^^^^ ... with this range @@ -24,7 +24,7 @@ LL | m!(0u8, 30..=40, 20..=30); = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:19:21 + --> $DIR/overlapping_range_endpoints.rs:18:21 | LL | m!(0u8, 20..30, 29..=40); | ------ ^^^^^^^ ... with this range @@ -34,7 +34,7 @@ LL | m!(0u8, 20..30, 29..=40); = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:23:22 + --> $DIR/overlapping_range_endpoints.rs:22:22 | LL | m!(0u8, 20..=30, 30..=31); | ------- ^^^^^^^ ... with this range @@ -44,7 +44,7 @@ LL | m!(0u8, 20..=30, 30..=31); = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:27:22 + --> $DIR/overlapping_range_endpoints.rs:26:22 | LL | m!(0u8, 20..=30, 19..=20); | ------- ^^^^^^^ ... with this range @@ -54,7 +54,7 @@ LL | m!(0u8, 20..=30, 19..=20); = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:39:9 + --> $DIR/overlapping_range_endpoints.rs:38:9 | LL | 0..=10 => {} | ------ this range overlaps on `10_u8`... @@ -65,7 +65,7 @@ LL | 10..=20 => {} = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:39:9 + --> $DIR/overlapping_range_endpoints.rs:38:9 | LL | 20..=30 => {} | ------- this range overlaps on `20_u8`... @@ -75,7 +75,7 @@ LL | 10..=20 => {} = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:46:10 + --> $DIR/overlapping_range_endpoints.rs:45:10 | LL | (0..=10, true) => {} | ------ this range overlaps on `10_u8`... @@ -85,7 +85,7 @@ LL | (10..20, true) => {} = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:52:16 + --> $DIR/overlapping_range_endpoints.rs:51:16 | LL | (true, 0..=10) => {} | ------ this range overlaps on `10_u8`... @@ -95,7 +95,7 @@ LL | (true, 10..20) => {} = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:58:14 + --> $DIR/overlapping_range_endpoints.rs:57:14 | LL | Some(0..=10) => {} | ------ this range overlaps on `10_u8`... diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr index 416523213c098..914c6ed60c839 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:13:11 + --> $DIR/pointer-sized-int.rs:12:11 | LL | match 0usize { | ^^^^^^ pattern `usize::MAX..` not covered @@ -13,7 +13,7 @@ LL + usize::MAX.. => todo!() | error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:18:11 + --> $DIR/pointer-sized-int.rs:17:11 | LL | match 0isize { | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered @@ -27,7 +27,7 @@ LL + ..isize::MIN | isize::MAX.. => todo!() | error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:23:8 + --> $DIR/pointer-sized-int.rs:22:8 | LL | m!(0usize, 0..=usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered @@ -40,7 +40,7 @@ LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } | +++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:25:8 + --> $DIR/pointer-sized-int.rs:24:8 | LL | m!(0usize, 0..5 | 5..=usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered @@ -53,7 +53,7 @@ LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } | +++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `usize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:27:8 + --> $DIR/pointer-sized-int.rs:26:8 | LL | m!(0usize, 0..usize::MAX | usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered @@ -66,7 +66,7 @@ LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } | +++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `(usize::MAX.., _)` not covered - --> $DIR/pointer-sized-int.rs:29:8 + --> $DIR/pointer-sized-int.rs:28:8 | LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); | ^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered @@ -79,7 +79,7 @@ LL | match $s { $($t)+ => {}, (usize::MAX.., _) => todo!() } | ++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:38:8 + --> $DIR/pointer-sized-int.rs:37:8 | LL | m!(0isize, isize::MIN..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered @@ -92,7 +92,7 @@ LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } | ++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:40:8 + --> $DIR/pointer-sized-int.rs:39:8 | LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered @@ -105,7 +105,7 @@ LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } | ++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:42:8 + --> $DIR/pointer-sized-int.rs:41:8 | LL | m!(0isize, isize::MIN..=-1 | 0 | 1..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered @@ -118,7 +118,7 @@ LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } | ++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered - --> $DIR/pointer-sized-int.rs:44:8 + --> $DIR/pointer-sized-int.rs:43:8 | LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered @@ -131,7 +131,7 @@ LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } | ++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered - --> $DIR/pointer-sized-int.rs:47:9 + --> $DIR/pointer-sized-int.rs:46:9 | LL | (0isize, true), | ^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered @@ -144,7 +144,7 @@ LL | match $s { $($t)+ => {}, (..isize::MIN, _) | (isize::MAX.., _) => t | ++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: type `usize` is non-empty - --> $DIR/pointer-sized-int.rs:58:11 + --> $DIR/pointer-sized-int.rs:57:11 | LL | match 7usize {} | ^^^^^^ diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs index 40f086dcc71c8..0d6056e228f25 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs @@ -1,5 +1,4 @@ //@ revisions: deny -#![feature(exclusive_range_pattern)] #![allow(overlapping_range_endpoints)] macro_rules! m { diff --git a/tests/ui/pattern/usefulness/integer-ranges/reachability.rs b/tests/ui/pattern/usefulness/integer-ranges/reachability.rs index 13b84e2c44bc1..a72588b623c1f 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/reachability.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/reachability.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![allow(overlapping_range_endpoints)] #![allow(non_contiguous_range_endpoints)] #![deny(unreachable_patterns)] diff --git a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr index 0f52dfd83b9cb..c5b028d2038c3 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -1,137 +1,137 @@ error: unreachable pattern - --> $DIR/reachability.rs:19:17 + --> $DIR/reachability.rs:18:17 | LL | m!(0u8, 42, 42); | ^^ | note: the lint level is defined here - --> $DIR/reachability.rs:4:9 + --> $DIR/reachability.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:23:22 + --> $DIR/reachability.rs:22:22 | LL | m!(0u8, 20..=30, 20); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:24:22 + --> $DIR/reachability.rs:23:22 | LL | m!(0u8, 20..=30, 21); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:25:22 + --> $DIR/reachability.rs:24:22 | LL | m!(0u8, 20..=30, 25); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:26:22 + --> $DIR/reachability.rs:25:22 | LL | m!(0u8, 20..=30, 29); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:27:22 + --> $DIR/reachability.rs:26:22 | LL | m!(0u8, 20..=30, 30); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:30:21 + --> $DIR/reachability.rs:29:21 | LL | m!(0u8, 20..30, 20); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:31:21 + --> $DIR/reachability.rs:30:21 | LL | m!(0u8, 20..30, 21); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:32:21 + --> $DIR/reachability.rs:31:21 | LL | m!(0u8, 20..30, 25); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:33:21 + --> $DIR/reachability.rs:32:21 | LL | m!(0u8, 20..30, 29); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:37:22 + --> $DIR/reachability.rs:36:22 | LL | m!(0u8, 20..=30, 20..=30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:38:22 + --> $DIR/reachability.rs:37:22 | LL | m!(0u8, 20.. 30, 20.. 30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:39:22 + --> $DIR/reachability.rs:38:22 | LL | m!(0u8, 20..=30, 20.. 30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:41:22 + --> $DIR/reachability.rs:40:22 | LL | m!(0u8, 20..=30, 21..=30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:42:22 + --> $DIR/reachability.rs:41:22 | LL | m!(0u8, 20..=30, 20..=29); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:44:24 + --> $DIR/reachability.rs:43:24 | LL | m!('a', 'A'..='z', 'a'..='z'); | ^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:51:9 + --> $DIR/reachability.rs:50:9 | LL | 5..=8 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:57:9 + --> $DIR/reachability.rs:56:9 | LL | 5..15 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:64:9 + --> $DIR/reachability.rs:63:9 | LL | 5..25 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:72:9 + --> $DIR/reachability.rs:71:9 | LL | 5..25 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:78:9 + --> $DIR/reachability.rs:77:9 | LL | 5..15 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:85:9 + --> $DIR/reachability.rs:84:9 | LL | _ => {}, | - matches any value @@ -139,19 +139,19 @@ LL | '\u{D7FF}'..='\u{E000}' => {}, | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/reachability.rs:90:9 + --> $DIR/reachability.rs:89:9 | LL | '\u{D7FF}'..='\u{E000}' => {}, | ^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:106:9 + --> $DIR/reachability.rs:105:9 | LL | &FOO => {} | ^^^^ error: unreachable pattern - --> $DIR/reachability.rs:107:9 + --> $DIR/reachability.rs:106:9 | LL | BAR => {} | ^^^ diff --git a/tests/ui/range/range-pattern-out-of-bounds-issue-68972.rs b/tests/ui/range/range-pattern-out-of-bounds-issue-68972.rs index 206f05d0d3caf..50203d3cf4f22 100644 --- a/tests/ui/range/range-pattern-out-of-bounds-issue-68972.rs +++ b/tests/ui/range/range-pattern-out-of-bounds-issue-68972.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![allow(unreachable_patterns)] fn main() { match 0u8 { diff --git a/tests/ui/range/range-pattern-out-of-bounds-issue-68972.stderr b/tests/ui/range/range-pattern-out-of-bounds-issue-68972.stderr index 21f1fdba886c5..38ce1a8a2402f 100644 --- a/tests/ui/range/range-pattern-out-of-bounds-issue-68972.stderr +++ b/tests/ui/range/range-pattern-out-of-bounds-issue-68972.stderr @@ -1,11 +1,11 @@ error: literal out of range for `u8` - --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:5:14 + --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:4:14 | LL | 251..257 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` error: literal out of range for `u8` - --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:7:15 + --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:6:15 | LL | 251..=256 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs index d43db576b3848..6d6a336e6885b 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs @@ -1,5 +1,4 @@ // Matching against NaN should result in an error -#![feature(exclusive_range_pattern)] #![allow(unused)] const NAN: f64 = f64::NAN; diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr index 167ada783c24c..baca1d75048ee 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr @@ -1,5 +1,5 @@ error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:15:9 + --> $DIR/issue-6804-nan-match.rs:14:9 | LL | NAN => {}, | ^^^ @@ -8,7 +8,7 @@ LL | NAN => {}, = help: try using the `is_nan` method instead error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:20:10 + --> $DIR/issue-6804-nan-match.rs:19:10 | LL | [NAN, _] => {}, | ^^^ @@ -17,7 +17,7 @@ LL | [NAN, _] => {}, = help: try using the `is_nan` method instead error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:25:9 + --> $DIR/issue-6804-nan-match.rs:24:9 | LL | C => {}, | ^ @@ -26,7 +26,7 @@ LL | C => {}, = help: try using the `is_nan` method instead error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:31:9 + --> $DIR/issue-6804-nan-match.rs:30:9 | LL | NAN..=1.0 => {}, | ^^^ @@ -35,13 +35,13 @@ LL | NAN..=1.0 => {}, = help: try using the `is_nan` method instead error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:31:9 + --> $DIR/issue-6804-nan-match.rs:30:9 | LL | NAN..=1.0 => {}, | ^^^^^^^^^ lower bound larger than upper bound error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:33:16 + --> $DIR/issue-6804-nan-match.rs:32:16 | LL | -1.0..=NAN => {}, | ^^^ @@ -50,13 +50,13 @@ LL | -1.0..=NAN => {}, = help: try using the `is_nan` method instead error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:33:9 + --> $DIR/issue-6804-nan-match.rs:32:9 | LL | -1.0..=NAN => {}, | ^^^^^^^^^^ lower bound larger than upper bound error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:35:9 + --> $DIR/issue-6804-nan-match.rs:34:9 | LL | NAN.. => {}, | ^^^ @@ -65,13 +65,13 @@ LL | NAN.. => {}, = help: try using the `is_nan` method instead error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:35:9 + --> $DIR/issue-6804-nan-match.rs:34:9 | LL | NAN.. => {}, | ^^^^^ lower bound larger than upper bound error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:37:11 + --> $DIR/issue-6804-nan-match.rs:36:11 | LL | ..NAN => {}, | ^^^ @@ -80,7 +80,7 @@ LL | ..NAN => {}, = help: try using the `is_nan` method instead error[E0579]: lower range bound must be less than upper - --> $DIR/issue-6804-nan-match.rs:37:9 + --> $DIR/issue-6804-nan-match.rs:36:9 | LL | ..NAN => {}, | ^^^^^ From 57f00ceada25dd17da6b19cf51c735696a9fab6f Mon Sep 17 00:00:00 2001 From: Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Date: Sun, 28 Apr 2024 00:39:32 -0400 Subject: [PATCH 27/72] Update clippy tests for stable exclusive_range --- .../tests/ui/almost_complete_range.fixed | 1 - .../clippy/tests/ui/almost_complete_range.rs | 1 - .../tests/ui/almost_complete_range.stderr | 54 +++++++++---------- .../tests/ui/manual_range_patterns.fixed | 1 - .../clippy/tests/ui/manual_range_patterns.rs | 1 - .../tests/ui/manual_range_patterns.stderr | 38 ++++++------- .../clippy/tests/ui/match_overlapping_arm.rs | 1 - .../tests/ui/match_overlapping_arm.stderr | 32 +++++------ .../clippy/tests/ui/match_wild_err_arm.rs | 1 - .../clippy/tests/ui/match_wild_err_arm.stderr | 8 +-- 10 files changed, 66 insertions(+), 72 deletions(-) diff --git a/src/tools/clippy/tests/ui/almost_complete_range.fixed b/src/tools/clippy/tests/ui/almost_complete_range.fixed index 21caeb153e77d..6c2b2f117437d 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.fixed +++ b/src/tools/clippy/tests/ui/almost_complete_range.fixed @@ -1,7 +1,6 @@ //@edition:2018 //@aux-build:proc_macros.rs -#![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] #![warn(clippy::almost_complete_range)] #![allow(ellipsis_inclusive_range_patterns)] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.rs b/src/tools/clippy/tests/ui/almost_complete_range.rs index 556110a5c8aae..813668a530966 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.rs +++ b/src/tools/clippy/tests/ui/almost_complete_range.rs @@ -1,7 +1,6 @@ //@edition:2018 //@aux-build:proc_macros.rs -#![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] #![warn(clippy::almost_complete_range)] #![allow(ellipsis_inclusive_range_patterns)] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.stderr b/src/tools/clippy/tests/ui/almost_complete_range.stderr index 0195e59226d51..bfc2beb07d857 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.stderr +++ b/src/tools/clippy/tests/ui/almost_complete_range.stderr @@ -1,5 +1,5 @@ error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:18:17 + --> tests/ui/almost_complete_range.rs:17:17 | LL | let _ = ('a') ..'z'; | ^^^^^^--^^^ @@ -10,7 +10,7 @@ LL | let _ = ('a') ..'z'; = help: to override `-D warnings` add `#[allow(clippy::almost_complete_range)]` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:19:17 + --> tests/ui/almost_complete_range.rs:18:17 | LL | let _ = 'A' .. ('Z'); | ^^^^--^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = 'A' .. ('Z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:20:17 + --> tests/ui/almost_complete_range.rs:19:17 | LL | let _ = ((('0'))) .. ('9'); | ^^^^^^^^^^--^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = ((('0'))) .. ('9'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:27:13 + --> tests/ui/almost_complete_range.rs:26:13 | LL | let _ = (b'a')..(b'z'); | ^^^^^^--^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = (b'a')..(b'z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:28:13 + --> tests/ui/almost_complete_range.rs:27:13 | LL | let _ = b'A'..b'Z'; | ^^^^--^^^^ @@ -42,7 +42,7 @@ LL | let _ = b'A'..b'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:29:13 + --> tests/ui/almost_complete_range.rs:28:13 | LL | let _ = b'0'..b'9'; | ^^^^--^^^^ @@ -50,7 +50,7 @@ LL | let _ = b'0'..b'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:35:13 + --> tests/ui/almost_complete_range.rs:34:13 | LL | let _ = inline!('a')..'z'; | ^^^^^^^^^^^^--^^^ @@ -58,7 +58,7 @@ LL | let _ = inline!('a')..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:36:13 + --> tests/ui/almost_complete_range.rs:35:13 | LL | let _ = inline!('A')..'Z'; | ^^^^^^^^^^^^--^^^ @@ -66,7 +66,7 @@ LL | let _ = inline!('A')..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:37:13 + --> tests/ui/almost_complete_range.rs:36:13 | LL | let _ = inline!('0')..'9'; | ^^^^^^^^^^^^--^^^ @@ -74,7 +74,7 @@ LL | let _ = inline!('0')..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:40:9 + --> tests/ui/almost_complete_range.rs:39:9 | LL | b'a'..b'z' if true => 1, | ^^^^--^^^^ @@ -82,7 +82,7 @@ LL | b'a'..b'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:41:9 + --> tests/ui/almost_complete_range.rs:40:9 | LL | b'A'..b'Z' if true => 2, | ^^^^--^^^^ @@ -90,7 +90,7 @@ LL | b'A'..b'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:42:9 + --> tests/ui/almost_complete_range.rs:41:9 | LL | b'0'..b'9' if true => 3, | ^^^^--^^^^ @@ -98,7 +98,7 @@ LL | b'0'..b'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:50:9 + --> tests/ui/almost_complete_range.rs:49:9 | LL | 'a'..'z' if true => 1, | ^^^--^^^ @@ -106,7 +106,7 @@ LL | 'a'..'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:51:9 + --> tests/ui/almost_complete_range.rs:50:9 | LL | 'A'..'Z' if true => 2, | ^^^--^^^ @@ -114,7 +114,7 @@ LL | 'A'..'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:52:9 + --> tests/ui/almost_complete_range.rs:51:9 | LL | '0'..'9' if true => 3, | ^^^--^^^ @@ -122,7 +122,7 @@ LL | '0'..'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:65:17 + --> tests/ui/almost_complete_range.rs:64:17 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -132,7 +132,7 @@ LL | let _ = 'a'..'z'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:66:17 + --> tests/ui/almost_complete_range.rs:65:17 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -142,7 +142,7 @@ LL | let _ = 'A'..'Z'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:67:17 + --> tests/ui/almost_complete_range.rs:66:17 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -152,7 +152,7 @@ LL | let _ = '0'..'9'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:74:9 + --> tests/ui/almost_complete_range.rs:73:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -160,7 +160,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:75:9 + --> tests/ui/almost_complete_range.rs:74:9 | LL | 'A'..'Z' => 2, | ^^^--^^^ @@ -168,7 +168,7 @@ LL | 'A'..'Z' => 2, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:76:9 + --> tests/ui/almost_complete_range.rs:75:9 | LL | '0'..'9' => 3, | ^^^--^^^ @@ -176,7 +176,7 @@ LL | '0'..'9' => 3, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:83:13 + --> tests/ui/almost_complete_range.rs:82:13 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -184,7 +184,7 @@ LL | let _ = 'a'..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:84:13 + --> tests/ui/almost_complete_range.rs:83:13 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -192,7 +192,7 @@ LL | let _ = 'A'..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:85:13 + --> tests/ui/almost_complete_range.rs:84:13 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -200,7 +200,7 @@ LL | let _ = '0'..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:87:9 + --> tests/ui/almost_complete_range.rs:86:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -208,7 +208,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:88:9 + --> tests/ui/almost_complete_range.rs:87:9 | LL | 'A'..'Z' => 1, | ^^^--^^^ @@ -216,7 +216,7 @@ LL | 'A'..'Z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:89:9 + --> tests/ui/almost_complete_range.rs:88:9 | LL | '0'..'9' => 3, | ^^^--^^^ diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.fixed b/src/tools/clippy/tests/ui/manual_range_patterns.fixed index e9f6fbcc3fc8c..f1b99637afdba 100644 --- a/src/tools/clippy/tests/ui/manual_range_patterns.fixed +++ b/src/tools/clippy/tests/ui/manual_range_patterns.fixed @@ -1,7 +1,6 @@ #![allow(unused)] #![allow(non_contiguous_range_endpoints)] #![warn(clippy::manual_range_patterns)] -#![feature(exclusive_range_pattern)] fn main() { let f = 6; diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.rs b/src/tools/clippy/tests/ui/manual_range_patterns.rs index d525aaa24ad1b..869ffbe80b973 100644 --- a/src/tools/clippy/tests/ui/manual_range_patterns.rs +++ b/src/tools/clippy/tests/ui/manual_range_patterns.rs @@ -1,7 +1,6 @@ #![allow(unused)] #![allow(non_contiguous_range_endpoints)] #![warn(clippy::manual_range_patterns)] -#![feature(exclusive_range_pattern)] fn main() { let f = 6; diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.stderr b/src/tools/clippy/tests/ui/manual_range_patterns.stderr index af9256aeea390..7c19fdd475f19 100644 --- a/src/tools/clippy/tests/ui/manual_range_patterns.stderr +++ b/src/tools/clippy/tests/ui/manual_range_patterns.stderr @@ -1,5 +1,5 @@ error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:9:25 + --> tests/ui/manual_range_patterns.rs:8:25 | LL | let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` @@ -8,109 +8,109 @@ LL | let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); = help: to override `-D warnings` add `#[allow(clippy::manual_range_patterns)]` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:10:25 + --> tests/ui/manual_range_patterns.rs:9:25 | LL | let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:17:25 + --> tests/ui/manual_range_patterns.rs:16:25 | LL | let _ = matches!(f, 1 | (2..=4)); | ^^^^^^^^^^^ help: try: `1..=4` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:18:25 + --> tests/ui/manual_range_patterns.rs:17:25 | LL | let _ = matches!(f, 1 | (2..4)); | ^^^^^^^^^^ help: try: `1..4` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:19:25 + --> tests/ui/manual_range_patterns.rs:18:25 | LL | let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=48324729` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:20:25 + --> tests/ui/manual_range_patterns.rs:19:25 | LL | let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=48324730` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:21:25 + --> tests/ui/manual_range_patterns.rs:20:25 | LL | let _ = matches!(f, 0..=1 | 0..=2 | 0..=3); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=3` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:24:9 + --> tests/ui/manual_range_patterns.rs:23:9 | LL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:27:25 + --> tests/ui/manual_range_patterns.rs:26:25 | LL | let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:29:25 + --> tests/ui/manual_range_patterns.rs:28:25 | LL | let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1_000_001..=1_000_001` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:32:17 + --> tests/ui/manual_range_patterns.rs:31:17 | LL | matches!(f, 0x00 | 0x01 | 0x02 | 0x03); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x03` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:33:17 + --> tests/ui/manual_range_patterns.rs:32:17 | LL | matches!(f, 0x00..=0x05 | 0x06 | 0x07); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x07` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:34:17 + --> tests/ui/manual_range_patterns.rs:33:17 | LL | matches!(f, -0x09 | -0x08 | -0x07..=0x00); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-0x09..=0x00` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:36:17 + --> tests/ui/manual_range_patterns.rs:35:17 | LL | matches!(f, 0..5 | 5); | ^^^^^^^^ help: try: `0..=5` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:37:17 + --> tests/ui/manual_range_patterns.rs:36:17 | LL | matches!(f, 0 | 1..5); | ^^^^^^^^ help: try: `0..5` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:39:17 + --> tests/ui/manual_range_patterns.rs:38:17 | LL | matches!(f, 0..=5 | 6..10); | ^^^^^^^^^^^^^ help: try: `0..10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:40:17 + --> tests/ui/manual_range_patterns.rs:39:17 | LL | matches!(f, 0..5 | 5..=10); | ^^^^^^^^^^^^^ help: try: `0..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:41:17 + --> tests/ui/manual_range_patterns.rs:40:17 | LL | matches!(f, 5..=10 | 0..5); | ^^^^^^^^^^^^^ help: try: `0..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:45:26 + --> tests/ui/manual_range_patterns.rs:44:26 | LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.rs b/src/tools/clippy/tests/ui/match_overlapping_arm.rs index c2c2f28392d77..4457ae73da2f0 100644 --- a/src/tools/clippy/tests/ui/match_overlapping_arm.rs +++ b/src/tools/clippy/tests/ui/match_overlapping_arm.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![warn(clippy::match_overlapping_arm)] #![allow(clippy::redundant_pattern_matching)] #![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_if)] diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr index 1a6c5746c3dd2..65092ffbb5558 100644 --- a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr +++ b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr @@ -1,11 +1,11 @@ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:12:9 + --> tests/ui/match_overlapping_arm.rs:11:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:14:9 + --> tests/ui/match_overlapping_arm.rs:13:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ @@ -13,85 +13,85 @@ LL | 0..=11 => println!("0..=11"), = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]` error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:19:9 + --> tests/ui/match_overlapping_arm.rs:18:9 | LL | 0..=5 => println!("0..=5"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:22:9 + --> tests/ui/match_overlapping_arm.rs:21:9 | LL | FOO..=11 => println!("FOO..=11"), | ^^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:57:9 + --> tests/ui/match_overlapping_arm.rs:56:9 | LL | 0..11 => println!("0..11"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:59:9 + --> tests/ui/match_overlapping_arm.rs:58:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:83:9 + --> tests/ui/match_overlapping_arm.rs:82:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:82:9 + --> tests/ui/match_overlapping_arm.rs:81:9 | LL | 5..14 => println!("5..14"), | ^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:89:9 + --> tests/ui/match_overlapping_arm.rs:88:9 | LL | 0..7 => println!("0..7"), | ^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:91:9 + --> tests/ui/match_overlapping_arm.rs:90:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:102:9 + --> tests/ui/match_overlapping_arm.rs:101:9 | LL | ..=23 => println!("..=23"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:104:9 + --> tests/ui/match_overlapping_arm.rs:103:9 | LL | ..26 => println!("..26"), | ^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:112:9 + --> tests/ui/match_overlapping_arm.rs:111:9 | LL | 21..=30 => (), | ^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:114:9 + --> tests/ui/match_overlapping_arm.rs:113:9 | LL | 21..=40 => (), | ^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:127:9 + --> tests/ui/match_overlapping_arm.rs:126:9 | LL | 0..=0x0000_0000_0000_00ff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:129:9 + --> tests/ui/match_overlapping_arm.rs:128:9 | LL | 0..=0x0000_0000_0000_ffff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.rs b/src/tools/clippy/tests/ui/match_wild_err_arm.rs index 7bdd75d7f4639..8e670ce5bda2c 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.rs +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.rs @@ -1,4 +1,3 @@ -#![feature(exclusive_range_pattern)] #![allow(clippy::match_same_arms, dead_code)] #![warn(clippy::match_wild_err_arm)] diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.stderr index 3145665a341e8..f98065d9a591f 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.stderr +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.stderr @@ -1,5 +1,5 @@ error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:24:9 + --> tests/ui/match_wild_err_arm.rs:23:9 | LL | Err(_) => panic!("err"), | ^^^^^^ @@ -9,7 +9,7 @@ LL | Err(_) => panic!("err"), = help: to override `-D warnings` add `#[allow(clippy::match_wild_err_arm)]` error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:32:9 + --> tests/ui/match_wild_err_arm.rs:31:9 | LL | Err(_) => panic!(), | ^^^^^^ @@ -17,7 +17,7 @@ LL | Err(_) => panic!(), = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:40:9 + --> tests/ui/match_wild_err_arm.rs:39:9 | LL | Err(_) => { | ^^^^^^ @@ -25,7 +25,7 @@ LL | Err(_) => { = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors - --> tests/ui/match_wild_err_arm.rs:50:9 + --> tests/ui/match_wild_err_arm.rs:49:9 | LL | Err(_e) => panic!(), | ^^^^^^^ From aeef18043eba235bb4bc74f169ee92ffaa3024db Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 3 May 2024 04:56:14 +0000 Subject: [PATCH 28/72] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index a45ecda15c4c0..dcd7b0698a6b3 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6acb9e75ebc936df737381a9d0b7a7bccd6f0b2f +79734f1db8dbe322192dea32c0f6b80ab14c4c1d From b348e418611dd38b9022e0dc95d125daf64c2492 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 08:00:24 +0200 Subject: [PATCH 29/72] update comments and URL --- src/tools/miri/triagebot.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index 22dc0c49aa815..addb36418d4b4 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -10,14 +10,10 @@ allow-unauthenticated = [ # Gives us the commands 'ready', 'author', 'blocked' [shortcut] -# Gives us 'claim', 'release-assignment', 'assign @user' +# Enables assigning users to issues and PRs. [assign] -# If set, posts a warning message if the PR is opened against a non-default -# branch (usually main or master). warn_non_default_branch = true -# If set, the welcome message to new contributors will include this link to -# a contributing guide. -contributing_url = "https://rustc-dev-guide.rust-lang.org/contributing.html" +contributing_url = "https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md" [no-merges] exclude_titles = ["Rustup"] From 4af1ba020405ce815cdc134335726edcd0d92cac Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 08:10:16 +0200 Subject: [PATCH 30/72] update lockfile --- src/tools/miri/Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 3a282e89312a2..6960c1661c5e8 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -553,7 +553,6 @@ dependencies = [ "directories", "getrandom", "jemalloc-sys", - "lazy_static", "libc", "libffi", "libloading", From 03589bfe98dd2baa44557f4e432218db0479cd6d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 19:36:33 +0200 Subject: [PATCH 31/72] run clippy on a Windows host --- src/tools/miri/.github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 3f714fc93201a..3d7ec210dac58 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -78,6 +78,12 @@ jobs: rustc -Vv cargo -V + # The `style` job only runs on Linux; this makes sure the Windows-host-specific + # code is also covered by clippy. + - name: Check clippy + if: ${{ matrix.os == 'windows-latest' }} + run: ./miri clippy -- -D warnings + - name: Test Miri run: ./ci/ci.sh From 0de07d80ff30cb05feae4fa56df05e1700fd3ca7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 19:52:08 +0200 Subject: [PATCH 32/72] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index dcd7b0698a6b3..b2e6353778f5a 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -79734f1db8dbe322192dea32c0f6b80ab14c4c1d +d6d3b342e85272f5e75c0d7a1dd3a1d8becb40ac From eaf30cee7e4720a2dfeafe86f010c5191b75822a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 20:31:27 +0200 Subject: [PATCH 33/72] ./miri run: support -v flag to print what it is doing --- src/tools/miri/miri-script/src/commands.rs | 21 ++++++++------ src/tools/miri/miri-script/src/main.rs | 32 ++++++++++++---------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 575bf4a15dfd0..b460c7eba5601 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -162,7 +162,7 @@ impl Command { Command::Build { flags } => Self::build(flags), Command::Check { flags } => Self::check(flags), Command::Test { bless, flags } => Self::test(bless, flags), - Command::Run { dep, flags } => Self::run(dep, flags), + Command::Run { dep, verbose, flags } => Self::run(dep, verbose, flags), Command::Fmt { flags } => Self::fmt(flags), Command::Clippy { flags } => Self::clippy(flags), Command::Cargo { flags } => Self::cargo(flags), @@ -495,7 +495,7 @@ impl Command { Ok(()) } - fn run(dep: bool, mut flags: Vec) -> Result<()> { + fn run(dep: bool, verbose: bool, mut flags: Vec) -> Result<()> { let mut e = MiriEnv::new()?; // Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so // that we set the MIRI_SYSROOT up the right way. We must make sure that @@ -522,7 +522,7 @@ impl Command { } // Prepare a sysroot, and add it to the flags. - let miri_sysroot = e.build_miri_sysroot(/* quiet */ true)?; + let miri_sysroot = e.build_miri_sysroot(/* quiet */ !verbose)?; flags.push("--sysroot".into()); flags.push(miri_sysroot.into()); @@ -532,17 +532,20 @@ impl Command { let miri_flags = flagsplit(&miri_flags); let toolchain = &e.toolchain; let extra_flags = &e.cargo_extra_flags; - if dep { + let quiet_flag = if verbose { None } else { Some("--quiet") }; + let mut cmd = if dep { cmd!( e.sh, - "cargo +{toolchain} --quiet test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {flags...}" - ).quiet().run()?; + "cargo +{toolchain} {quiet_flag...} test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {flags...}" + ) } else { cmd!( e.sh, - "cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {flags...}" - ).quiet().run()?; - } + "cargo +{toolchain} {quiet_flag...} run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {flags...}" + ) + }; + cmd.set_quiet(!verbose); + cmd.run()?; Ok(()) } diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index 712180be2825a..4904744cb9f6b 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs @@ -38,6 +38,7 @@ pub enum Command { /// (Also respects MIRIFLAGS environment variable.) Run { dep: bool, + verbose: bool, /// Flags that are passed through to `miri`. flags: Vec, }, @@ -90,7 +91,7 @@ Just check miri. are passed to `cargo check`. Build miri, set up a sysroot and then run the test suite. are passed to the final `cargo test` invocation. -./miri run [--dep] : +./miri run [--dep] [-v|--verbose] : Build miri, set up a sysroot and then run the driver with the given . (Also respects MIRIFLAGS environment variable.) @@ -132,10 +133,10 @@ Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest rustc commit. The fetched commit is stored in the `rust-version` file, so the next `./miri toolchain` will install the rustc that just got pulled. -./miri rustc-push : +./miri rustc-push []: Push Miri changes back to the rustc repo. This will pull a copy of the rustc history into the Miri repo, unless you set the RUSTC_GIT env var to an existing -clone of the rustc repo. +clone of the rustc repo. The branch defaults to `miri-sync`. ENVIRONMENT VARIABLES @@ -162,12 +163,18 @@ fn main() -> Result<()> { Command::Test { bless, flags: args.collect() } } Some("run") => { - let dep = args.peek().is_some_and(|a| a.to_str() == Some("--dep")); - if dep { - // Consume the flag. + let mut dep = false; + let mut verbose = false; + while let Some(arg) = args.peek().and_then(|a| a.to_str()) { + match arg { + "--dep" => dep = true, + "-v" | "--verbose" => verbose = true, + _ => break, // not for us + } + // Consume the flag, look at the next one. args.next().unwrap(); } - Command::Run { dep, flags: args.collect() } + Command::Run { dep, verbose, flags: args.collect() } } Some("fmt") => Command::Fmt { flags: args.collect() }, Some("clippy") => Command::Clippy { flags: args.collect() }, @@ -187,17 +194,12 @@ fn main() -> Result<()> { let github_user = args .next() .ok_or_else(|| { - anyhow!("Missing first argument for `./miri rustc-push GITHUB_USER BRANCH`") - })? - .to_string_lossy() - .into_owned(); - let branch = args - .next() - .ok_or_else(|| { - anyhow!("Missing second argument for `./miri rustc-push GITHUB_USER BRANCH`") + anyhow!("Missing first argument for `./miri rustc-push GITHUB_USER [BRANCH]`") })? .to_string_lossy() .into_owned(); + let branch = + args.next().unwrap_or_else(|| "miri-sync".into()).to_string_lossy().into_owned(); if args.next().is_some() { bail!("Too many arguments for `./miri rustc-push GITHUB_USER BRANCH`"); } From aa71f9b03361155602115716a109e46c31342046 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 21:45:03 +0200 Subject: [PATCH 34/72] CI: no need to surround if: condition in expansion braces --- src/tools/miri/.github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 3d7ec210dac58..3bc4163ab5246 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -61,7 +61,7 @@ jobs: restore-keys: cargo-${{ runner.os }}-reset20240425 - name: Install tools - if: ${{ steps.cache.outputs.cache-hit != 'true' }} + if: steps.cache.outputs.cache-hit != 'true' run: cargo install -f rustup-toolchain-install-master hyperfine - name: Install miri toolchain @@ -81,7 +81,7 @@ jobs: # The `style` job only runs on Linux; this makes sure the Windows-host-specific # code is also covered by clippy. - name: Check clippy - if: ${{ matrix.os == 'windows-latest' }} + if: matrix.os == 'windows-latest' run: ./miri clippy -- -D warnings - name: Test Miri @@ -117,7 +117,7 @@ jobs: restore-keys: cargo-${{ runner.os }}-reset20240331 - name: Install rustup-toolchain-install-master - if: ${{ steps.cache.outputs.cache-hit != 'true' }} + if: steps.cache.outputs.cache-hit != 'true' run: cargo install -f rustup-toolchain-install-master - name: Install "master" toolchain From 6ce00aa99234c4771abb84ef9a1b46fc818a0d5f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 00:03:23 +0200 Subject: [PATCH 35/72] make many-seeds a mode of ./miri run rather than a separate command --- src/tools/miri/ci/ci.sh | 13 ++- src/tools/miri/miri-script/Cargo.lock | 8 +- src/tools/miri/miri-script/Cargo.toml | 2 +- src/tools/miri/miri-script/src/commands.rs | 96 ++++++++++------------ src/tools/miri/miri-script/src/main.rs | 49 ++++++----- src/tools/miri/miri-script/src/util.rs | 53 ++++++++++++ 6 files changed, 134 insertions(+), 87 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index c1ffb80783ef6..0db267650dbf6 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -71,10 +71,9 @@ function run_tests { time MIRIFLAGS="${MIRIFLAGS-} -O -Zmir-opt-level=4 -Cdebug-assertions=yes" MIRI_SKIP_UI_CHECKS=1 ./miri test -- tests/{pass,panic} fi if [ -n "${MANY_SEEDS-}" ]; then - # Also run some many-seeds tests. 64 seeds means this takes around a minute per test. - # (Need to invoke via explicit `bash -c` for Windows.) + # Also run some many-seeds tests. time for FILE in tests/many-seeds/*.rs; do - MIRI_SEEDS=$MANY_SEEDS ./miri many-seeds "$BASH" -c "./miri run '$FILE'" + ./miri run "--many-seeds=0..$MANY_SEEDS" "$FILE" done fi if [ -n "${TEST_BENCH-}" ]; then @@ -135,7 +134,7 @@ case $HOST_TARGET in GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests # Extra tier 1 # With reduced many-seed count to avoid spending too much time on that. - # (All OSes are run with 64 seeds at least once though via the macOS runner.) + # (All OSes and ABIs are run with 64 seeds at least once though via the macOS runner.) MANY_SEEDS=16 MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests MANY_SEEDS=16 MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-apple-darwin run_tests @@ -164,9 +163,9 @@ case $HOST_TARGET in ;; i686-pc-windows-msvc) # Host - # Only smoke-test `many-seeds`; 64 runs of just the scoped-thread-leak test take 15min here! - # See . - GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=1 TEST_BENCH=1 run_tests + # With reduced many-seeds count as this is the slowest runner already. + # (The macOS runner checks windows-msvc with full many-seeds count.) + GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=16 TEST_BENCH=1 run_tests # Extra tier 1 # We really want to ensure a Linux target works on a Windows host, # and a 64bit target works on a 32bit host. diff --git a/src/tools/miri/miri-script/Cargo.lock b/src/tools/miri/miri-script/Cargo.lock index a6f7467f0a2f7..5e792abac175d 100644 --- a/src/tools/miri/miri-script/Cargo.lock +++ b/src/tools/miri/miri-script/Cargo.lock @@ -466,15 +466,15 @@ checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" [[package]] name = "xshell" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad" +checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437" dependencies = [ "xshell-macros", ] [[package]] name = "xshell-macros" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" +checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" diff --git a/src/tools/miri/miri-script/Cargo.toml b/src/tools/miri/miri-script/Cargo.toml index 79d0b13600d4f..631d3a82102b5 100644 --- a/src/tools/miri/miri-script/Cargo.toml +++ b/src/tools/miri/miri-script/Cargo.toml @@ -19,7 +19,7 @@ itertools = "0.11" path_macro = "1.0" shell-words = "1.1" anyhow = "1.0" -xshell = "0.2" +xshell = "0.2.6" rustc_version = "0.4" dunce = "1.0.4" directories = "5" diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index b460c7eba5601..7e34ad050b319 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -2,6 +2,7 @@ use std::env; use std::ffi::OsString; use std::io::Write; use std::ops::Not; +use std::ops::Range; use std::path::PathBuf; use std::process; use std::thread; @@ -150,7 +151,6 @@ impl Command { | Command::Fmt { .. } | Command::Clippy { .. } | Command::Cargo { .. } => Self::auto_actions()?, - | Command::ManySeeds { .. } | Command::Toolchain { .. } | Command::Bench { .. } | Command::RustcPull { .. } @@ -162,11 +162,11 @@ impl Command { Command::Build { flags } => Self::build(flags), Command::Check { flags } => Self::check(flags), Command::Test { bless, flags } => Self::test(bless, flags), - Command::Run { dep, verbose, flags } => Self::run(dep, verbose, flags), + Command::Run { dep, verbose, many_seeds, flags } => + Self::run(dep, verbose, many_seeds, flags), Command::Fmt { flags } => Self::fmt(flags), Command::Clippy { flags } => Self::clippy(flags), Command::Cargo { flags } => Self::cargo(flags), - Command::ManySeeds { command } => Self::many_seeds(command), Command::Bench { benches } => Self::bench(benches), Command::Toolchain { flags } => Self::toolchain(flags), Command::RustcPull { commit } => Self::rustc_pull(commit.clone()), @@ -367,43 +367,6 @@ impl Command { Ok(()) } - fn many_seeds(command: Vec) -> Result<()> { - let seed_start: u64 = env::var("MIRI_SEED_START") - .unwrap_or_else(|_| "0".into()) - .parse() - .context("failed to parse MIRI_SEED_START")?; - let seed_end: u64 = match (env::var("MIRI_SEEDS"), env::var("MIRI_SEED_END")) { - (Ok(_), Ok(_)) => bail!("Only one of MIRI_SEEDS and MIRI_SEED_END may be set"), - (Ok(seeds), Err(_)) => - seed_start + seeds.parse::().context("failed to parse MIRI_SEEDS")?, - (Err(_), Ok(seed_end)) => seed_end.parse().context("failed to parse MIRI_SEED_END")?, - (Err(_), Err(_)) => seed_start + 256, - }; - if seed_end <= seed_start { - bail!("the end of the seed range must be larger than the start."); - } - - let Some((command_name, trailing_args)) = command.split_first() else { - bail!("expected many-seeds command to be non-empty"); - }; - let sh = Shell::new()?; - sh.set_var("MIRI_AUTO_OPS", "no"); // just in case we get recursively invoked - for seed in seed_start..seed_end { - println!("Trying seed: {seed}"); - let mut miriflags = env::var_os("MIRIFLAGS").unwrap_or_default(); - miriflags.push(format!(" -Zlayout-seed={seed} -Zmiri-seed={seed}")); - let status = cmd!(sh, "{command_name} {trailing_args...}") - .env("MIRIFLAGS", miriflags) - .quiet() - .run(); - if let Err(err) = status { - println!("Failing seed: {seed}"); - return Err(err.into()); - } - } - Ok(()) - } - fn bench(benches: Vec) -> Result<()> { // The hyperfine to use let hyperfine = env::var("HYPERFINE"); @@ -495,7 +458,12 @@ impl Command { Ok(()) } - fn run(dep: bool, verbose: bool, mut flags: Vec) -> Result<()> { + fn run( + dep: bool, + verbose: bool, + many_seeds: Option>, + mut flags: Vec, + ) -> Result<()> { let mut e = MiriEnv::new()?; // Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so // that we set the MIRI_SYSROOT up the right way. We must make sure that @@ -526,26 +494,46 @@ impl Command { flags.push("--sysroot".into()); flags.push(miri_sysroot.into()); - // Then run the actual command. Also add MIRIFLAGS. + // Compute everything needed to run the actual command. Also add MIRIFLAGS. let miri_manifest = path!(e.miri_dir / "Cargo.toml"); let miri_flags = e.sh.var("MIRIFLAGS").unwrap_or_default(); let miri_flags = flagsplit(&miri_flags); let toolchain = &e.toolchain; let extra_flags = &e.cargo_extra_flags; let quiet_flag = if verbose { None } else { Some("--quiet") }; - let mut cmd = if dep { - cmd!( - e.sh, - "cargo +{toolchain} {quiet_flag...} test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {flags...}" - ) - } else { - cmd!( - e.sh, - "cargo +{toolchain} {quiet_flag...} run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {flags...}" - ) + // This closure runs the command with the given `seed_flag` added between the MIRIFLAGS and + // the `flags` given on the command-line. + let run_miri = |sh: &Shell, seed_flag: Option| -> Result<()> { + // The basic command that executes the Miri driver. + let mut cmd = if dep { + cmd!( + sh, + "cargo +{toolchain} {quiet_flag...} test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode" + ) + } else { + cmd!( + sh, + "cargo +{toolchain} {quiet_flag...} run {extra_flags...} --manifest-path {miri_manifest} --" + ) + }; + cmd.set_quiet(!verbose); + // Add Miri flags + let cmd = cmd.args(&miri_flags).args(seed_flag).args(&flags); + // And run the thing. + Ok(cmd.run()?) }; - cmd.set_quiet(!verbose); - cmd.run()?; + // Run the closure once or many times. + if let Some(seed_range) = many_seeds { + e.run_many_times(seed_range, |sh, seed| { + eprintln!("Trying seed: {seed}"); + run_miri(sh, Some(format!("-Zmiri-seed={seed}"))).map_err(|err| { + eprintln!("FAILING SEED: {seed}"); + err + }) + })?; + } else { + run_miri(&e.sh, None)?; + } Ok(()) } diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index 4904744cb9f6b..f0ebbc846906e 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs @@ -3,10 +3,10 @@ mod commands; mod util; -use std::env; use std::ffi::OsString; +use std::{env, ops::Range}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, bail, Context, Result}; #[derive(Clone, Debug)] pub enum Command { @@ -39,6 +39,7 @@ pub enum Command { Run { dep: bool, verbose: bool, + many_seeds: Option>, /// Flags that are passed through to `miri`. flags: Vec, }, @@ -55,10 +56,6 @@ pub enum Command { /// Runs just `cargo ` with the Miri-specific environment variables. /// Mainly meant to be invoked by rust-analyzer. Cargo { flags: Vec }, - /// Runs over and over again with different seeds for Miri. The MIRIFLAGS - /// variable is set to its original value appended with ` -Zmiri-seed=$SEED` for - /// many different seeds. - ManySeeds { command: Vec }, /// Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed. Bench { /// List of benchmarks to run. By default all benchmarks are run. @@ -91,9 +88,11 @@ Just check miri. are passed to `cargo check`. Build miri, set up a sysroot and then run the test suite. are passed to the final `cargo test` invocation. -./miri run [--dep] [-v|--verbose] : +./miri run [--dep] [-v|--verbose] [--many-seeds|--many-seeds=..to|--many-seeds=from..to] : Build miri, set up a sysroot and then run the driver with the given . (Also respects MIRIFLAGS environment variable.) +If `--many-seeds` is present, Miri is run many times in parallel with different seeds. +The range defaults to `0..256`. ./miri fmt : Format all sources and tests. are passed to `rustfmt`. @@ -111,13 +110,6 @@ install`. Sets up the rpath such that the installed binary should work in any working directory. Note that the binaries are placed in the `miri` toolchain sysroot, to prevent conflicts with other toolchains. -./miri many-seeds : -Runs over and over again with different seeds for Miri. The MIRIFLAGS -variable is set to its original value appended with ` -Zmiri-seed=$SEED` for -many different seeds. MIRI_SEED_START controls the first seed to try (default: 0). -MIRI_SEEDS controls how many seeds are being tried (default: 256); -alternatively, MIRI_SEED_END controls the end of the (exclusive) seed range to try. - ./miri bench : Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed. can explicitly list the benchmarks to run; by default, all of them are run. @@ -165,22 +157,37 @@ fn main() -> Result<()> { Some("run") => { let mut dep = false; let mut verbose = false; - while let Some(arg) = args.peek().and_then(|a| a.to_str()) { - match arg { - "--dep" => dep = true, - "-v" | "--verbose" => verbose = true, - _ => break, // not for us + let mut many_seeds = None; + while let Some(arg) = args.peek().and_then(|s| s.to_str()) { + if arg == "--dep" { + dep = true; + } else if arg == "-v" || arg == "--verbose" { + verbose = true; + } else if arg == "--many-seeds" { + many_seeds = Some(0..256); + } else if let Some(val) = arg.strip_prefix("--many-seeds=") { + let (from, to) = val.split_once("..").ok_or_else(|| { + anyhow!("invalid format for `--many-seeds`: expected `from..to`") + })?; + let from: u32 = if from.is_empty() { + 0 + } else { + from.parse().context("invalid `from` in `--many-seeds=from..to")? + }; + let to: u32 = to.parse().context("invalid `to` in `--many-seeds=from..to")?; + many_seeds = Some(from..to); + } else { + break; // not for us } // Consume the flag, look at the next one. args.next().unwrap(); } - Command::Run { dep, verbose, flags: args.collect() } + Command::Run { dep, verbose, many_seeds, flags: args.collect() } } Some("fmt") => Command::Fmt { flags: args.collect() }, Some("clippy") => Command::Clippy { flags: args.collect() }, Some("cargo") => Command::Cargo { flags: args.collect() }, Some("install") => Command::Install { flags: args.collect() }, - Some("many-seeds") => Command::ManySeeds { command: args.collect() }, Some("bench") => Command::Bench { benches: args.collect() }, Some("toolchain") => Command::Toolchain { flags: args.collect() }, Some("rustc-pull") => { diff --git a/src/tools/miri/miri-script/src/util.rs b/src/tools/miri/miri-script/src/util.rs index 361a4ca0cf769..23b5e936edd81 100644 --- a/src/tools/miri/miri-script/src/util.rs +++ b/src/tools/miri/miri-script/src/util.rs @@ -1,5 +1,8 @@ use std::ffi::{OsStr, OsString}; +use std::ops::Range; use std::path::{Path, PathBuf}; +use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; +use std::thread; use anyhow::{anyhow, Context, Result}; use dunce::canonicalize; @@ -189,4 +192,54 @@ impl MiriEnv { Ok(()) } + + /// Run the given closure many times in parallel with access to the shell, once for each value in the `range`. + pub fn run_many_times( + &self, + range: Range, + run: impl Fn(&Shell, u32) -> Result<()> + Sync, + ) -> Result<()> { + // `next` is atomic so threads can concurrently fetch their next value to run. + let next = AtomicU32::new(range.start); + let end = range.end; // exclusive! + let failed = AtomicBool::new(false); + thread::scope(|s| { + let mut handles = Vec::new(); + // Spawn one worker per core. + for _ in 0..thread::available_parallelism()?.get() { + // Create a copy of the shell for this thread. + let local_shell = self.sh.clone(); + let handle = s.spawn(|| -> Result<()> { + let local_shell = local_shell; // move the copy into this thread. + // Each worker thread keeps asking for numbers until we're all done. + loop { + let cur = next.fetch_add(1, Ordering::Relaxed); + if cur >= end { + // We hit the upper limit and are done. + break; + } + // Run the command with this seed. + run(&local_shell, cur).map_err(|err| { + // If we failed, tell everyone about this. + failed.store(true, Ordering::Relaxed); + err + })?; + // Check if some other command failed (in which case we'll stop as well). + if failed.load(Ordering::Relaxed) { + return Ok(()); + } + } + Ok(()) + }); + handles.push(handle); + } + // Wait for all workers to be done. + for handle in handles { + handle.join().unwrap()?; + } + // If all workers succeeded, we can't have failed. + assert!(!failed.load(Ordering::Relaxed)); + Ok(()) + }) + } } From f7a3aa9811aaadbd59b6d399b10f323de7f9647d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 09:02:51 +0200 Subject: [PATCH 36/72] remove a hack that is no longer needed --- src/tools/miri/ci/ci.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 0db267650dbf6..c8c24ba5da61a 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -13,15 +13,6 @@ function endgroup { begingroup "Building Miri" -# Special Windows hacks -if [ "$HOST_TARGET" = i686-pc-windows-msvc ]; then - # The $BASH variable is `/bin/bash` here, but that path does not actually work. There are some - # hacks in place somewhere to try to paper over this, but the hacks dont work either (see - # ). So we hard-code the correct location for Github - # CI instead. - BASH="C:/Program Files/Git/usr/bin/bash" -fi - # Global configuration export RUSTFLAGS="-D warnings" export CARGO_INCREMENTAL=0 From 65593420587fb16324f2620d63b58e0968fb27af Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 10:45:54 +0200 Subject: [PATCH 37/72] tls dtors: treat all unixes uniformly --- src/tools/miri/src/shims/tls.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index d25bae1cdc03f..0dec12f0b65f1 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -242,21 +242,21 @@ impl<'tcx> TlsDtorsState<'tcx> { match &mut self.0 { Init => { match this.tcx.sess.target.os.as_ref() { - "linux" | "freebsd" | "android" => { - // Run the pthread dtors. - break 'new_state PthreadDtors(Default::default()); - } "macos" => { // The macOS thread wide destructor runs "before any TLS slots get // freed", so do that first. this.schedule_macos_tls_dtor()?; - // When the stack is empty again, go on with the pthread dtors. + // When that destructor is done, go on with the pthread dtors. + break 'new_state PthreadDtors(Default::default()); + } + _ if this.target_os_is_unix() => { + // All other Unixes directly jump to running the pthread dtors. break 'new_state PthreadDtors(Default::default()); } "windows" => { // Determine which destructors to run. let dtors = this.lookup_windows_tls_dtors()?; - // And move to the final state. + // And move to the next state, that runs them. break 'new_state WindowsDtors(dtors); } _ => { From 07a517a6bac8e022ee1070d6b751ee18a6b32929 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 10:52:25 +0200 Subject: [PATCH 38/72] macos: use getentropy from libc --- src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs b/src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs index 4b863f6851618..06109397c2bc6 100644 --- a/src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs +++ b/src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs @@ -1,12 +1,5 @@ //@ignore-target-windows: no libc -// on macOS this is not in the `libc` crate. -#[cfg(target_os = "macos")] -extern "C" { - fn getentropy(bytes: *mut libc::c_void, count: libc::size_t) -> libc::c_int; -} - -#[cfg(not(target_os = "macos"))] use libc::getentropy; fn main() { From 459c6ce944ccef19f5da60d8ee1fbdccf685e2b3 Mon Sep 17 00:00:00 2001 From: Luv-Ray Date: Sat, 4 May 2024 17:24:18 +0800 Subject: [PATCH 39/72] Make file descriptors into refcount references take ownership of self and return `io::Result<()>` in `FileDescription::close` Co-authored-by: Ralf Jung --- src/tools/miri/src/shims/unix/fd.rs | 172 +++++++++--------- src/tools/miri/src/shims/unix/fs.rs | 120 ++++++------ src/tools/miri/src/shims/unix/linux/epoll.rs | 69 ++++--- .../miri/src/shims/unix/linux/eventfd.rs | 15 +- src/tools/miri/src/shims/unix/mod.rs | 2 +- src/tools/miri/src/shims/unix/socket.rs | 16 +- 6 files changed, 193 insertions(+), 201 deletions(-) diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 18a41f6c667ca..566988cba1f82 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -2,8 +2,10 @@ //! standard file descriptors (stdin/stdout/stderr). use std::any::Any; +use std::cell::{Ref, RefCell, RefMut}; use std::collections::BTreeMap; use std::io::{self, ErrorKind, IsTerminal, Read, SeekFrom, Write}; +use std::rc::Rc; use rustc_middle::ty::TyCtxt; use rustc_target::abi::Size; @@ -12,7 +14,7 @@ use crate::shims::unix::*; use crate::*; /// Represents an open file descriptor. -pub trait FileDescriptor: std::fmt::Debug + Any { +pub trait FileDescription: std::fmt::Debug + Any { fn name(&self) -> &'static str; fn read<'tcx>( @@ -44,13 +46,10 @@ pub trait FileDescriptor: std::fmt::Debug + Any { fn close<'tcx>( self: Box, _communicate_allowed: bool, - ) -> InterpResult<'tcx, io::Result> { + ) -> InterpResult<'tcx, io::Result<()>> { throw_unsup_format!("cannot close {}", self.name()); } - /// Return a new file descriptor *that refers to the same underlying object*. - fn dup(&mut self) -> io::Result>; - fn is_tty(&self, _communicate_allowed: bool) -> bool { // Most FDs are not tty's and the consequence of a wrong `false` are minor, // so we use a default impl here. @@ -58,7 +57,7 @@ pub trait FileDescriptor: std::fmt::Debug + Any { } } -impl dyn FileDescriptor { +impl dyn FileDescription { #[inline(always)] pub fn downcast_ref(&self) -> Option<&T> { (self as &dyn Any).downcast_ref() @@ -70,7 +69,7 @@ impl dyn FileDescriptor { } } -impl FileDescriptor for io::Stdin { +impl FileDescription for io::Stdin { fn name(&self) -> &'static str { "stdin" } @@ -88,16 +87,12 @@ impl FileDescriptor for io::Stdin { Ok(Read::read(self, bytes)) } - fn dup(&mut self) -> io::Result> { - Ok(Box::new(io::stdin())) - } - fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.is_terminal() } } -impl FileDescriptor for io::Stdout { +impl FileDescription for io::Stdout { fn name(&self) -> &'static str { "stdout" } @@ -120,16 +115,12 @@ impl FileDescriptor for io::Stdout { Ok(result) } - fn dup(&mut self) -> io::Result> { - Ok(Box::new(io::stdout())) - } - fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.is_terminal() } } -impl FileDescriptor for io::Stderr { +impl FileDescription for io::Stderr { fn name(&self) -> &'static str { "stderr" } @@ -145,10 +136,6 @@ impl FileDescriptor for io::Stderr { Ok(Write::write(&mut { self }, bytes)) } - fn dup(&mut self) -> io::Result> { - Ok(Box::new(io::stderr())) - } - fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.is_terminal() } @@ -158,7 +145,7 @@ impl FileDescriptor for io::Stderr { #[derive(Debug)] pub struct NullOutput; -impl FileDescriptor for NullOutput { +impl FileDescription for NullOutput { fn name(&self) -> &'static str { "stderr and stdout" } @@ -172,16 +159,30 @@ impl FileDescriptor for NullOutput { // We just don't write anything, but report to the user that we did. Ok(Ok(bytes.len())) } +} + +#[derive(Clone, Debug)] +pub struct FileDescriptor(Rc>>); + +impl FileDescriptor { + pub fn new(fd: T) -> Self { + FileDescriptor(Rc::new(RefCell::new(Box::new(fd)))) + } - fn dup(&mut self) -> io::Result> { - Ok(Box::new(NullOutput)) + pub fn close<'ctx>(self, communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> { + // Destroy this `Rc` using `into_inner` so we can call `close` instead of + // implicitly running the destructor of the file description. + match Rc::into_inner(self.0) { + Some(fd) => RefCell::into_inner(fd).close(communicate_allowed), + None => Ok(Ok(())), + } } } /// The file descriptor table #[derive(Debug)] pub struct FdTable { - pub fds: BTreeMap>, + pub fds: BTreeMap, } impl VisitProvenance for FdTable { @@ -192,28 +193,24 @@ impl VisitProvenance for FdTable { impl FdTable { pub(crate) fn new(mute_stdout_stderr: bool) -> FdTable { - let mut fds: BTreeMap<_, Box> = BTreeMap::new(); - fds.insert(0i32, Box::new(io::stdin())); + let mut fds: BTreeMap<_, FileDescriptor> = BTreeMap::new(); + fds.insert(0i32, FileDescriptor::new(io::stdin())); if mute_stdout_stderr { - fds.insert(1i32, Box::new(NullOutput)); - fds.insert(2i32, Box::new(NullOutput)); + fds.insert(1i32, FileDescriptor::new(NullOutput)); + fds.insert(2i32, FileDescriptor::new(NullOutput)); } else { - fds.insert(1i32, Box::new(io::stdout())); - fds.insert(2i32, Box::new(io::stderr())); + fds.insert(1i32, FileDescriptor::new(io::stdout())); + fds.insert(2i32, FileDescriptor::new(io::stderr())); } FdTable { fds } } - pub fn insert_fd(&mut self, file_handle: Box) -> i32 { + pub fn insert_fd(&mut self, file_handle: FileDescriptor) -> i32 { self.insert_fd_with_min_fd(file_handle, 0) } /// Insert a new FD that is at least `min_fd`. - pub fn insert_fd_with_min_fd( - &mut self, - file_handle: Box, - min_fd: i32, - ) -> i32 { + pub fn insert_fd_with_min_fd(&mut self, file_handle: FileDescriptor, min_fd: i32) -> i32 { // Find the lowest unused FD, starting from min_fd. If the first such unused FD is in // between used FDs, the find_map combinator will return it. If the first such unused FD // is after all other used FDs, the find_map combinator will return None, and we will use @@ -239,15 +236,22 @@ impl FdTable { new_fd } - pub fn get(&self, fd: i32) -> Option<&dyn FileDescriptor> { - Some(&**self.fds.get(&fd)?) + pub fn get(&self, fd: i32) -> Option> { + let fd = self.fds.get(&fd)?; + Some(Ref::map(fd.0.borrow(), |fd| fd.as_ref())) } - pub fn get_mut(&mut self, fd: i32) -> Option<&mut dyn FileDescriptor> { - Some(&mut **self.fds.get_mut(&fd)?) + pub fn get_mut(&self, fd: i32) -> Option> { + let fd = self.fds.get(&fd)?; + Some(RefMut::map(fd.0.borrow_mut(), |fd| fd.as_mut())) } - pub fn remove(&mut self, fd: i32) -> Option> { + pub fn dup(&self, fd: i32) -> Option { + let fd = self.fds.get(&fd)?; + Some(fd.clone()) + } + + pub fn remove(&mut self, fd: i32) -> Option { self.fds.remove(&fd) } @@ -296,17 +300,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } let start = this.read_scalar(&args[2])?.to_i32()?; - match this.machine.fds.get_mut(fd) { - Some(file_descriptor) => { - let dup_result = file_descriptor.dup(); - match dup_result { - Ok(dup_fd) => Ok(this.machine.fds.insert_fd_with_min_fd(dup_fd, start)), - Err(e) => { - this.set_last_error_from_io_error(e.kind())?; - Ok(-1) - } - } - } + match this.machine.fds.dup(fd) { + Some(dup_fd) => Ok(this.machine.fds.insert_fd_with_min_fd(dup_fd, start)), None => this.fd_not_found(), } } else if this.tcx.sess.target.os == "macos" && cmd == this.eval_libc_i32("F_FULLFSYNC") { @@ -330,6 +325,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(Scalar::from_i32(if let Some(file_descriptor) = this.machine.fds.remove(fd) { let result = file_descriptor.close(this.machine.communicate())?; + // return `0` if close is successful + let result = result.map(|()| 0i32); this.try_unwrap_io_result(result)? } else { this.fd_not_found()? @@ -369,32 +366,33 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); - if let Some(file_descriptor) = this.machine.fds.get_mut(fd) { - trace!("read: FD mapped to {:?}", file_descriptor); - // We want to read at most `count` bytes. We are sure that `count` is not negative - // because it was a target's `usize`. Also we are sure that its smaller than - // `usize::MAX` because it is bounded by the host's `isize`. - let mut bytes = vec![0; usize::try_from(count).unwrap()]; - // `File::read` never returns a value larger than `count`, - // so this cannot fail. - let result = file_descriptor - .read(communicate, &mut bytes, *this.tcx)? - .map(|c| i64::try_from(c).unwrap()); - - match result { - Ok(read_bytes) => { - // If reading to `bytes` did not fail, we write those bytes to the buffer. - this.write_bytes_ptr(buf, bytes)?; - Ok(read_bytes) - } - Err(e) => { - this.set_last_error_from_io_error(e.kind())?; - Ok(-1) - } - } - } else { + let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else { trace!("read: FD not found"); - this.fd_not_found() + return this.fd_not_found(); + }; + + trace!("read: FD mapped to {:?}", file_descriptor); + // We want to read at most `count` bytes. We are sure that `count` is not negative + // because it was a target's `usize`. Also we are sure that its smaller than + // `usize::MAX` because it is bounded by the host's `isize`. + let mut bytes = vec![0; usize::try_from(count).unwrap()]; + // `File::read` never returns a value larger than `count`, + // so this cannot fail. + let result = file_descriptor + .read(communicate, &mut bytes, *this.tcx)? + .map(|c| i64::try_from(c).unwrap()); + drop(file_descriptor); + + match result { + Ok(read_bytes) => { + // If reading to `bytes` did not fail, we write those bytes to the buffer. + this.write_bytes_ptr(buf, bytes)?; + Ok(read_bytes) + } + Err(e) => { + this.set_last_error_from_io_error(e.kind())?; + Ok(-1) + } } } @@ -419,13 +417,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let communicate = this.machine.communicate(); let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?.to_owned(); - if let Some(file_descriptor) = this.machine.fds.get_mut(fd) { - let result = file_descriptor - .write(communicate, &bytes, *this.tcx)? - .map(|c| i64::try_from(c).unwrap()); - this.try_unwrap_io_result(result) - } else { - this.fd_not_found() - } + let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else { + return this.fd_not_found(); + }; + + let result = file_descriptor + .write(communicate, &bytes, *this.tcx)? + .map(|c| i64::try_from(c).unwrap()); + drop(file_descriptor); + + this.try_unwrap_io_result(result) } } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 0bf0e3d52c3c1..058747916c0ac 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -17,15 +17,17 @@ use crate::shims::unix::*; use crate::*; use shims::time::system_time_to_duration; +use self::fd::FileDescriptor; + #[derive(Debug)] struct FileHandle { file: File, writable: bool, } -impl FileDescriptor for FileHandle { +impl FileDescription for FileHandle { fn name(&self) -> &'static str { - "FILE" + "file" } fn read<'tcx>( @@ -60,16 +62,14 @@ impl FileDescriptor for FileHandle { fn close<'tcx>( self: Box, communicate_allowed: bool, - ) -> InterpResult<'tcx, io::Result> { + ) -> InterpResult<'tcx, io::Result<()>> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); // We sync the file if it was opened in a mode different than read-only. if self.writable { // `File::sync_all` does the checks that are done when closing a file. We do this to // to handle possible errors correctly. - let result = self.file.sync_all().map(|_| 0i32); - // Now we actually close the file. - drop(self); - // And return the result. + let result = self.file.sync_all(); + // Now we actually close the file and return the result. Ok(result) } else { // We drop the file, this closes it but ignores any errors @@ -78,16 +78,10 @@ impl FileDescriptor for FileHandle { // `/dev/urandom` which are read-only. Check // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439 // for a deeper discussion. - drop(self); - Ok(Ok(0)) + Ok(Ok(())) } } - fn dup(&mut self) -> io::Result> { - let duplicated = self.file.try_clone()?; - Ok(Box::new(FileHandle { file: duplicated, writable: self.writable })) - } - fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.file.is_terminal() } @@ -399,7 +393,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let fd = options.open(path).map(|file| { let fh = &mut this.machine.fds; - fh.insert_fd(Box::new(FileHandle { file, writable })) + fh.insert_fd(FileDescriptor::new(FileHandle { file, writable })) }); this.try_unwrap_io_result(fd) @@ -428,14 +422,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; let communicate = this.machine.communicate(); - Ok(Scalar::from_i64(if let Some(file_descriptor) = this.machine.fds.get_mut(fd) { - let result = file_descriptor - .seek(communicate, seek_from)? - .map(|offset| i64::try_from(offset).unwrap()); - this.try_unwrap_io_result(result)? - } else { - this.fd_not_found()? - })) + + let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else { + return Ok(Scalar::from_i64(this.fd_not_found()?)); + }; + let result = file_descriptor + .seek(communicate, seek_from)? + .map(|offset| i64::try_from(offset).unwrap()); + drop(file_descriptor); + + let result = this.try_unwrap_io_result(result)?; + Ok(Scalar::from_i64(result)) } fn unlink(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { @@ -1131,32 +1128,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(Scalar::from_i32(this.fd_not_found()?)); } - Ok(Scalar::from_i32(if let Some(file_descriptor) = this.machine.fds.get_mut(fd) { - // FIXME: Support ftruncate64 for all FDs - let FileHandle { file, writable } = - file_descriptor.downcast_ref::().ok_or_else(|| { - err_unsup_format!( - "`ftruncate64` is only supported on file-backed file descriptors" - ) - })?; - if *writable { - if let Ok(length) = length.try_into() { - let result = file.set_len(length); - this.try_unwrap_io_result(result.map(|_| 0i32))? - } else { - let einval = this.eval_libc("EINVAL"); - this.set_last_error(einval)?; - -1 - } + let Some(file_descriptor) = this.machine.fds.get(fd) else { + return Ok(Scalar::from_i32(this.fd_not_found()?)); + }; + + // FIXME: Support ftruncate64 for all FDs + let FileHandle { file, writable } = + file_descriptor.downcast_ref::().ok_or_else(|| { + err_unsup_format!("`ftruncate64` is only supported on file-backed file descriptors") + })?; + + if *writable { + if let Ok(length) = length.try_into() { + let result = file.set_len(length); + drop(file_descriptor); + let result = this.try_unwrap_io_result(result.map(|_| 0i32))?; + Ok(Scalar::from_i32(result)) } else { - // The file is not writable + drop(file_descriptor); let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - -1 + Ok(Scalar::from_i32(-1)) } } else { - this.fd_not_found()? - })) + drop(file_descriptor); + // The file is not writable + let einval = this.eval_libc("EINVAL"); + this.set_last_error(einval)?; + Ok(Scalar::from_i32(-1)) + } } fn fsync(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { @@ -1190,6 +1190,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { err_unsup_format!("`fsync` is only supported on file-backed file descriptors") })?; let io_result = maybe_sync_file(file, *writable, File::sync_all); + drop(file_descriptor); this.try_unwrap_io_result(io_result) } @@ -1214,6 +1215,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { err_unsup_format!("`fdatasync` is only supported on file-backed file descriptors") })?; let io_result = maybe_sync_file(file, *writable, File::sync_data); + drop(file_descriptor); this.try_unwrap_io_result(io_result) } @@ -1263,6 +1265,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) })?; let io_result = maybe_sync_file(file, *writable, File::sync_data); + drop(file_descriptor); Ok(Scalar::from_i32(this.try_unwrap_io_result(io_result)?)) } @@ -1498,7 +1501,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { match file { Ok(f) => { let fh = &mut this.machine.fds; - let fd = fh.insert_fd(Box::new(FileHandle { file: f, writable: true })); + let fd = + fh.insert_fd(FileDescriptor::new(FileHandle { file: f, writable: true })); return Ok(fd); } Err(e) => @@ -1563,21 +1567,21 @@ impl FileMetadata { ecx: &mut MiriInterpCx<'_, 'tcx>, fd: i32, ) -> InterpResult<'tcx, Option> { - let option = ecx.machine.fds.get(fd); - let file = match option { - Some(file_descriptor) => - &file_descriptor - .downcast_ref::() - .ok_or_else(|| { - err_unsup_format!( - "obtaining metadata is only supported on file-backed file descriptors" - ) - })? - .file, - None => return ecx.fd_not_found().map(|_: i32| None), + let Some(file_descriptor) = ecx.machine.fds.get(fd) else { + return ecx.fd_not_found().map(|_: i32| None); }; - let metadata = file.metadata(); + let file = &file_descriptor + .downcast_ref::() + .ok_or_else(|| { + err_unsup_format!( + "obtaining metadata is only supported on file-backed file descriptors" + ) + })? + .file; + + let metadata = file.metadata(); + drop(file_descriptor); FileMetadata::from_meta(ecx, metadata) } diff --git a/src/tools/miri/src/shims/unix/linux/epoll.rs b/src/tools/miri/src/shims/unix/linux/epoll.rs index 5161d91ca3639..48a0ba0197608 100644 --- a/src/tools/miri/src/shims/unix/linux/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux/epoll.rs @@ -5,6 +5,8 @@ use rustc_data_structures::fx::FxHashMap; use crate::shims::unix::*; use crate::*; +use self::shims::unix::fd::FileDescriptor; + /// An `Epoll` file descriptor connects file handles and epoll events #[derive(Clone, Debug, Default)] struct Epoll { @@ -29,22 +31,16 @@ struct EpollEvent { data: Scalar, } -impl FileDescriptor for Epoll { +impl FileDescription for Epoll { fn name(&self) -> &'static str { "epoll" } - fn dup(&mut self) -> io::Result> { - // FIXME: this is probably wrong -- check if the `dup`ed descriptor truly uses an - // independent event set. - Ok(Box::new(self.clone())) - } - fn close<'tcx>( self: Box, _communicate_allowed: bool, - ) -> InterpResult<'tcx, io::Result> { - Ok(Ok(0)) + ) -> InterpResult<'tcx, io::Result<()>> { + Ok(Ok(())) } } @@ -70,7 +66,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("epoll_create1 flags {flags} are not implemented"); } - let fd = this.machine.fds.insert_fd(Box::new(Epoll::default())); + let fd = this.machine.fds.insert_fd(FileDescriptor::new(Epoll::default())); Ok(Scalar::from_i32(fd)) } @@ -114,27 +110,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let data = this.read_scalar(&data)?; let event = EpollEvent { events, data }; - if let Some(epfd) = this.machine.fds.get_mut(epfd) { - let epfd = epfd - .downcast_mut::() - .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?; + let Some(mut epfd) = this.machine.fds.get_mut(epfd) else { + return Ok(Scalar::from_i32(this.fd_not_found()?)); + }; + let epfd = epfd + .downcast_mut::() + .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?; - epfd.file_descriptors.insert(fd, event); - Ok(Scalar::from_i32(0)) - } else { - Ok(Scalar::from_i32(this.fd_not_found()?)) - } + epfd.file_descriptors.insert(fd, event); + Ok(Scalar::from_i32(0)) } else if op == epoll_ctl_del { - if let Some(epfd) = this.machine.fds.get_mut(epfd) { - let epfd = epfd - .downcast_mut::() - .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?; - - epfd.file_descriptors.remove(&fd); - Ok(Scalar::from_i32(0)) - } else { - Ok(Scalar::from_i32(this.fd_not_found()?)) - } + let Some(mut epfd) = this.machine.fds.get_mut(epfd) else { + return Ok(Scalar::from_i32(this.fd_not_found()?)); + }; + let epfd = epfd + .downcast_mut::() + .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?; + + epfd.file_descriptors.remove(&fd); + Ok(Scalar::from_i32(0)) } else { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; @@ -185,15 +179,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let _maxevents = this.read_scalar(maxevents)?.to_i32()?; let _timeout = this.read_scalar(timeout)?.to_i32()?; - if let Some(epfd) = this.machine.fds.get_mut(epfd) { - let _epfd = epfd - .downcast_mut::() - .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?; + let Some(mut epfd) = this.machine.fds.get_mut(epfd) else { + return Ok(Scalar::from_i32(this.fd_not_found()?)); + }; + let _epfd = epfd + .downcast_mut::() + .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?; - // FIXME return number of events ready when scheme for marking events ready exists - throw_unsup_format!("returning ready events from epoll_wait is not yet implemented"); - } else { - Ok(Scalar::from_i32(this.fd_not_found()?)) - } + // FIXME return number of events ready when scheme for marking events ready exists + throw_unsup_format!("returning ready events from epoll_wait is not yet implemented"); } } diff --git a/src/tools/miri/src/shims/unix/linux/eventfd.rs b/src/tools/miri/src/shims/unix/linux/eventfd.rs index 452527017feb3..a865f2efff957 100644 --- a/src/tools/miri/src/shims/unix/linux/eventfd.rs +++ b/src/tools/miri/src/shims/unix/linux/eventfd.rs @@ -8,6 +8,8 @@ use rustc_target::abi::Endian; use crate::shims::unix::*; use crate::*; +use self::shims::unix::fd::FileDescriptor; + /// A kind of file descriptor created by `eventfd`. /// The `Event` type isn't currently written to by `eventfd`. /// The interface is meant to keep track of objects associated @@ -22,21 +24,16 @@ struct Event { val: u64, } -impl FileDescriptor for Event { +impl FileDescription for Event { fn name(&self) -> &'static str { "event" } - fn dup(&mut self) -> io::Result> { - // FIXME: this is wrong, the new and old FD should refer to the same event object! - Ok(Box::new(Event { val: self.val })) - } - fn close<'tcx>( self: Box, _communicate_allowed: bool, - ) -> InterpResult<'tcx, io::Result> { - Ok(Ok(0)) + ) -> InterpResult<'tcx, io::Result<()>> { + Ok(Ok(())) } /// A write call adds the 8-byte integer value supplied in @@ -115,7 +112,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("eventfd: EFD_SEMAPHORE is unsupported"); } - let fd = this.machine.fds.insert_fd(Box::new(Event { val: val.into() })); + let fd = this.machine.fds.insert_fd(FileDescriptor::new(Event { val: val.into() })); Ok(Scalar::from_i32(fd)) } } diff --git a/src/tools/miri/src/shims/unix/mod.rs b/src/tools/miri/src/shims/unix/mod.rs index 144593aa2fc08..bede2fbd3897a 100644 --- a/src/tools/miri/src/shims/unix/mod.rs +++ b/src/tools/miri/src/shims/unix/mod.rs @@ -13,7 +13,7 @@ mod linux; mod macos; pub use env::UnixEnvVars; -pub use fd::{FdTable, FileDescriptor}; +pub use fd::{FdTable, FileDescription}; pub use fs::DirTable; // All the Unix-specific extension traits pub use env::EvalContextExt as _; diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index 84ddd746fb584..11fd83f57e67e 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -3,26 +3,24 @@ use std::io; use crate::shims::unix::*; use crate::*; +use self::fd::FileDescriptor; + /// Pair of connected sockets. /// /// We currently don't allow sending any data through this pair, so this can be just a dummy. #[derive(Debug)] struct SocketPair; -impl FileDescriptor for SocketPair { +impl FileDescription for SocketPair { fn name(&self) -> &'static str { "socketpair" } - fn dup(&mut self) -> io::Result> { - Ok(Box::new(SocketPair)) - } - fn close<'tcx>( self: Box, _communicate_allowed: bool, - ) -> InterpResult<'tcx, io::Result> { - Ok(Ok(0)) + ) -> InterpResult<'tcx, io::Result<()>> { + Ok(Ok(())) } } @@ -52,9 +50,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // FIXME: fail on unsupported inputs let fds = &mut this.machine.fds; - let sv0 = fds.insert_fd(Box::new(SocketPair)); + let sv0 = fds.insert_fd(FileDescriptor::new(SocketPair)); let sv0 = Scalar::try_from_int(sv0, sv.layout.size).unwrap(); - let sv1 = fds.insert_fd(Box::new(SocketPair)); + let sv1 = fds.insert_fd(FileDescriptor::new(SocketPair)); let sv1 = Scalar::try_from_int(sv1, sv.layout.size).unwrap(); this.write_scalar(sv0, &sv)?; From d130eaac1f1aba8adc7a59bb389b21e7766f4be5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 10:58:52 +0200 Subject: [PATCH 40/72] speed up Windows runner: don't run GC_STRESS test --- src/tools/miri/ci/ci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index c8c24ba5da61a..6945b39032365 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -154,9 +154,9 @@ case $HOST_TARGET in ;; i686-pc-windows-msvc) # Host - # With reduced many-seeds count as this is the slowest runner already. + # Without GC_STRESS and with reduced many-seeds count as this is the slowest runner. # (The macOS runner checks windows-msvc with full many-seeds count.) - GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=16 TEST_BENCH=1 run_tests + MIR_OPT=1 MANY_SEEDS=16 TEST_BENCH=1 run_tests # Extra tier 1 # We really want to ensure a Linux target works on a Windows host, # and a 64bit target works on a 32bit host. From 502ed4965f854e97f44600b59bfc151a58f88070 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 11:46:10 +0200 Subject: [PATCH 41/72] show time taken in run_tests_minimal --- src/tools/miri/ci/ci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 6945b39032365..3962138635b2b 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -107,10 +107,10 @@ function run_tests_minimal { exit 1 fi - ./miri test -- "$@" + time ./miri test -- "$@" # Ensure that a small smoke test of cargo-miri works. - cargo miri run --manifest-path test-cargo-miri/no-std-smoke/Cargo.toml --target ${MIRI_TEST_TARGET-$HOST_TARGET} + time cargo miri run --manifest-path test-cargo-miri/no-std-smoke/Cargo.toml --target ${MIRI_TEST_TARGET-$HOST_TARGET} endgroup } From be874a468be821ea103bd380181abcb4ef6df6d0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 11:55:17 +0200 Subject: [PATCH 42/72] move available-parallelism tests into shims/ folder --- .../tests/pass/{ => shims}/available-parallelism-miri-num-cpus.rs | 0 src/tools/miri/tests/pass/{ => shims}/available-parallelism.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/tools/miri/tests/pass/{ => shims}/available-parallelism-miri-num-cpus.rs (100%) rename src/tools/miri/tests/pass/{ => shims}/available-parallelism.rs (100%) diff --git a/src/tools/miri/tests/pass/available-parallelism-miri-num-cpus.rs b/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs similarity index 100% rename from src/tools/miri/tests/pass/available-parallelism-miri-num-cpus.rs rename to src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs diff --git a/src/tools/miri/tests/pass/available-parallelism.rs b/src/tools/miri/tests/pass/shims/available-parallelism.rs similarity index 100% rename from src/tools/miri/tests/pass/available-parallelism.rs rename to src/tools/miri/tests/pass/shims/available-parallelism.rs From 57ff16bb5f93ef697f18f5222314ea3b8a385185 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 12:29:36 +0200 Subject: [PATCH 43/72] rename integer test --- src/tools/miri/tests/pass/{ints.rs => integers.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/tools/miri/tests/pass/{ints.rs => integers.rs} (100%) diff --git a/src/tools/miri/tests/pass/ints.rs b/src/tools/miri/tests/pass/integers.rs similarity index 100% rename from src/tools/miri/tests/pass/ints.rs rename to src/tools/miri/tests/pass/integers.rs From 3046dbe7deaebf2804fc822dd1828b3c794edc6f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 12:34:16 +0200 Subject: [PATCH 44/72] move intrinsics implementations and tests into dedicated folder and make them separate from 'shims' --- src/tools/miri/src/{shims => }/intrinsics/atomic.rs | 0 src/tools/miri/src/{shims => }/intrinsics/mod.rs | 0 src/tools/miri/src/{shims => }/intrinsics/simd.rs | 0 src/tools/miri/src/lib.rs | 3 ++- src/tools/miri/src/shims/mod.rs | 1 - .../fail/{shims => intrinsics}/intrinsic_target_feature.rs | 0 .../fail/{shims => intrinsics}/intrinsic_target_feature.stderr | 0 .../pass/{intrinsics-integer.rs => intrinsics/integer.rs} | 0 src/tools/miri/tests/pass/{ => intrinsics}/intrinsics.rs | 0 .../miri/tests/pass/{ => intrinsics}/portable-simd-ptrs.rs | 0 src/tools/miri/tests/pass/{ => intrinsics}/portable-simd.rs | 0 src/tools/miri/tests/pass/{ => intrinsics}/volatile.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-aes-vaes.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx2.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx512.rs | 0 .../pass/{ => shims/x86}/intrinsics-x86-pause-without-sse2.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse2.rs | 0 .../tests/pass/{ => shims/x86}/intrinsics-x86-sse3-ssse3.rs | 0 .../miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse41.rs | 0 src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86.rs | 0 22 files changed, 2 insertions(+), 2 deletions(-) rename src/tools/miri/src/{shims => }/intrinsics/atomic.rs (100%) rename src/tools/miri/src/{shims => }/intrinsics/mod.rs (100%) rename src/tools/miri/src/{shims => }/intrinsics/simd.rs (100%) rename src/tools/miri/tests/fail/{shims => intrinsics}/intrinsic_target_feature.rs (100%) rename src/tools/miri/tests/fail/{shims => intrinsics}/intrinsic_target_feature.stderr (100%) rename src/tools/miri/tests/pass/{intrinsics-integer.rs => intrinsics/integer.rs} (100%) rename src/tools/miri/tests/pass/{ => intrinsics}/intrinsics.rs (100%) rename src/tools/miri/tests/pass/{ => intrinsics}/portable-simd-ptrs.rs (100%) rename src/tools/miri/tests/pass/{ => intrinsics}/portable-simd.rs (100%) rename src/tools/miri/tests/pass/{ => intrinsics}/volatile.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-aes-vaes.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx2.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-avx512.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-pause-without-sse2.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse2.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse3-ssse3.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86-sse41.rs (100%) rename src/tools/miri/tests/pass/{ => shims/x86}/intrinsics-x86.rs (100%) diff --git a/src/tools/miri/src/shims/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs similarity index 100% rename from src/tools/miri/src/shims/intrinsics/atomic.rs rename to src/tools/miri/src/intrinsics/atomic.rs diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs similarity index 100% rename from src/tools/miri/src/shims/intrinsics/mod.rs rename to src/tools/miri/src/intrinsics/mod.rs diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs similarity index 100% rename from src/tools/miri/src/shims/intrinsics/simd.rs rename to src/tools/miri/src/intrinsics/simd.rs diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f47c84842b17f..f01c2da25d9e2 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -79,6 +79,7 @@ mod concurrency; mod diagnostics; mod eval; mod helpers; +mod intrinsics; mod machine; mod mono_hash_map; mod operator; @@ -95,9 +96,9 @@ pub use rustc_const_eval::interpret::*; #[doc(no_inline)] pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _}; +pub use crate::intrinsics::EvalContextExt as _; pub use crate::shims::env::{EnvVars, EvalContextExt as _}; pub use crate::shims::foreign_items::{DynSym, EvalContextExt as _}; -pub use crate::shims::intrinsics::EvalContextExt as _; pub use crate::shims::os_str::EvalContextExt as _; pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _}; pub use crate::shims::time::EvalContextExt as _; diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 85c9a202f7daf..ab5a8c5877ec2 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -5,7 +5,6 @@ mod backtrace; #[cfg(target_os = "linux")] pub mod ffi_support; pub mod foreign_items; -pub mod intrinsics; pub mod unix; pub mod windows; mod x86; diff --git a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs b/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs rename to src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.rs diff --git a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr b/src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr rename to src/tools/miri/tests/fail/intrinsics/intrinsic_target_feature.stderr diff --git a/src/tools/miri/tests/pass/intrinsics-integer.rs b/src/tools/miri/tests/pass/intrinsics/integer.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-integer.rs rename to src/tools/miri/tests/pass/intrinsics/integer.rs diff --git a/src/tools/miri/tests/pass/intrinsics.rs b/src/tools/miri/tests/pass/intrinsics/intrinsics.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics.rs rename to src/tools/miri/tests/pass/intrinsics/intrinsics.rs diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd-ptrs.rs similarity index 100% rename from src/tools/miri/tests/pass/portable-simd-ptrs.rs rename to src/tools/miri/tests/pass/intrinsics/portable-simd-ptrs.rs diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs similarity index 100% rename from src/tools/miri/tests/pass/portable-simd.rs rename to src/tools/miri/tests/pass/intrinsics/portable-simd.rs diff --git a/src/tools/miri/tests/pass/volatile.rs b/src/tools/miri/tests/pass/intrinsics/volatile.rs similarity index 100% rename from src/tools/miri/tests/pass/volatile.rs rename to src/tools/miri/tests/pass/intrinsics/volatile.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-avx.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx2.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-avx2.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx2.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-avx512.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-pause-without-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-pause-without-sse2.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-sse.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-sse2.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse3-ssse3.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse3-ssse3.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse41.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86-sse41.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse41.rs diff --git a/src/tools/miri/tests/pass/intrinsics-x86.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86.rs similarity index 100% rename from src/tools/miri/tests/pass/intrinsics-x86.rs rename to src/tools/miri/tests/pass/shims/x86/intrinsics-x86.rs From a4355bbbb14120b33ff7b397bc38524833ea8792 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 12:39:37 +0200 Subject: [PATCH 45/72] fix grouping of target-specific LLVM shims --- src/tools/miri/src/shims/foreign_items.rs | 60 +++++++++++------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4b96ff18b74cb..6a12180b836b7 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -893,36 +893,6 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty); } } - // FIXME: Move these to an `arm` submodule. - "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { - let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let arg = this.read_scalar(arg)?.to_i32()?; - match arg { - // SY ("full system scope") - 15 => { - this.yield_active_thread(); - } - _ => { - throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg); - } - } - } - "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { - let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let arg = this.read_scalar(arg)?.to_i32()?; - // Note that different arguments might have different target feature requirements. - match arg { - // YIELD - 1 => { - this.expect_target_feature_for_intrinsic(link_name, "v6")?; - this.yield_active_thread(); - } - _ => { - throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg); - } - } - } - // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { @@ -946,6 +916,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } + // Target-specific shims name if name.starts_with("llvm.x86.") && (this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64") => @@ -954,6 +925,35 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this, link_name, abi, args, dest, ); } + // FIXME: Move these to an `arm` submodule. + "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { + let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let arg = this.read_scalar(arg)?.to_i32()?; + match arg { + // SY ("full system scope") + 15 => { + this.yield_active_thread(); + } + _ => { + throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg); + } + } + } + "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { + let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let arg = this.read_scalar(arg)?.to_i32()?; + // Note that different arguments might have different target feature requirements. + match arg { + // YIELD + 1 => { + this.expect_target_feature_for_intrinsic(link_name, "v6")?; + this.yield_active_thread(); + } + _ => { + throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg); + } + } + } // Platform-specific shims _ => From 52bf84f3cfbece7da285e1ef622b8567c6f58f1a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 10:56:53 +0200 Subject: [PATCH 46/72] move some minimal targets over to the macOS runner, to even out CI times --- src/tools/miri/ci/ci.sh | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 3962138635b2b..67835960bd7ce 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -130,9 +130,16 @@ case $HOST_TARGET in MANY_SEEDS=16 MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-apple-darwin run_tests MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests + ;; + aarch64-apple-darwin) + # Host (tier 2) + GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests + # Extra tier 1 + MANY_SEEDS=64 MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests + MANY_SEEDS=64 MIRI_TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests # Extra tier 2 - MIRI_TEST_TARGET=aarch64-apple-darwin run_tests MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests + MIRI_TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice # Partially supported targets (tier 2) MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus @@ -143,15 +150,6 @@ case $HOST_TARGET in # Custom target JSON file MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std ;; - aarch64-apple-darwin) - # Host (tier 2) - GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests - # Extra tier 1 - MANY_SEEDS=64 MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests - MANY_SEEDS=64 MIRI_TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests - # Extra tier 2 - MIRI_TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture - ;; i686-pc-windows-msvc) # Host # Without GC_STRESS and with reduced many-seeds count as this is the slowest runner. From e1c3d67d2113a5f4c76859761afd259a1038e8dc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 13:33:12 +0200 Subject: [PATCH 47/72] Revert "moving out sched_getaffinity interception from linux'shim, FreeBSD supporting it too." This reverts commit c1a3f8576ea12b0bed68ad3dedf4069ca3d9816f. --- .../miri/src/shims/unix/foreign_items.rs | 19 ------------------- .../src/shims/unix/linux/foreign_items.rs | 13 +++++++++++++ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index bd299aaa1253a..b07f596c741c8 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -724,25 +724,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } - "sched_getaffinity" => { - // FreeBSD supports it as well since 13.1 (as a wrapper of cpuset_getaffinity) - if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd") { - throw_unsup_format!( - "`sched_getaffinity` is not supported on {}", - this.tcx.sess.target.os - ); - } - let [pid, cpusetsize, mask] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_scalar(pid)?.to_i32()?; - this.read_target_usize(cpusetsize)?; - this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?; - // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`. - let einval = this.eval_libc("EINVAL"); - this.set_last_error(einval)?; - this.write_scalar(Scalar::from_i32(-1), dest)?; - } - // Platform-specific shims _ => { let target_os = &*this.tcx.sess.target.os; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 497e8bee70ec9..0d4c7ce112ceb 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -195,6 +195,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(Scalar::from_i32(SIGRTMAX), dest)?; } + "sched_getaffinity" => { + // This shim isn't useful, aside from the fact that it makes `num_cpus` + // fall back to `sysconf` where it will successfully determine the number of CPUs. + let [pid, cpusetsize, mask] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.read_scalar(pid)?.to_i32()?; + this.read_target_usize(cpusetsize)?; + this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?; + // FIXME: we just return an error. + let einval = this.eval_libc("EINVAL"); + this.set_last_error(einval)?; + this.write_scalar(Scalar::from_i32(-1), dest)?; + } // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. From 8b4b259da2aa1a666806d39a63066bd07039e4e8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 13:45:54 +0200 Subject: [PATCH 48/72] update 'unsupported' message --- src/tools/miri/README.md | 2 +- src/tools/miri/src/diagnostics.rs | 5 ++++- .../miri/tests/extern-so/fail/function_not_in_so.stderr | 3 ++- src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr | 3 ++- .../miri/tests/fail-dep/shims/fs/read_from_stdout.stderr | 3 ++- src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr | 3 ++- src/tools/miri/tests/fail-dep/tokio/sleep.stderr | 3 ++- .../tests/fail-dep/unsupported_incomplete_function.stderr | 3 ++- src/tools/miri/tests/fail/alloc/no_global_allocator.stderr | 3 ++- src/tools/miri/tests/fail/extern-type-field-offset.stderr | 3 ++- src/tools/miri/tests/fail/extern_static.stderr | 3 ++- src/tools/miri/tests/fail/extern_static_in_const.stderr | 3 ++- src/tools/miri/tests/fail/extern_static_wrong_size.stderr | 3 ++- ...sue-miri-3288-ice-symbolic-alignment-extern-static.stderr | 3 ++- .../tests/fail/shims/backtrace/bad-backtrace-flags.stderr | 3 ++- .../fail/shims/backtrace/bad-backtrace-resolve-flags.stderr | 3 ++- .../shims/backtrace/bad-backtrace-resolve-names-flags.stderr | 3 ++- .../fail/shims/backtrace/bad-backtrace-size-flags.stderr | 3 ++- .../promise_alignment.call_unaligned_ptr.stderr | 3 ++- .../fail/unaligned_pointers/promise_alignment_zero.stderr | 3 ++- src/tools/miri/tests/fail/unsized-local.stderr | 3 ++- .../miri/tests/fail/unsupported_foreign_function.stderr | 3 ++- 22 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index ef01ca25fb0b4..5b088abcbe626 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -141,7 +141,7 @@ interpreter will explicitly tell you when it finds something unsupported: error: unsupported operation: can't call foreign function: bind ... = help: this is likely not a bug in the program; it indicates that the program \ - performed an operation that the interpreter does not support + performed an operation that Miri does not support ``` ### Cross-interpretation: running for different targets diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 9fa786332e3cd..5fac922f56833 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -320,7 +320,10 @@ pub fn report_error<'tcx, 'mir>( #[rustfmt::skip] let helps = match e.kind() { Unsupported(_) => - vec![(None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support"))], + vec![ + (None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support")), + (None, format!("if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there")), + ], UndefinedBehavior(AlignmentCheckFailed { .. }) if ecx.machine.check_alignment == AlignmentCheck::Symbolic => diff --git a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr index c031cb0146ad6..26761c48721df 100644 --- a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr +++ b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr @@ -4,7 +4,8 @@ error: unsupported operation: can't call foreign function `foo` on $OS LL | foo(); | ^^^^^ can't call foreign function `foo` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/function_not_in_so.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr index 7547ec417194c..e50480157657b 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr @@ -4,7 +4,8 @@ error: unsupported operation: cannot close stdout LL | libc::close(1); | ^^^^^^^^^^^^^^ cannot close stdout | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/close_stdout.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr index 355e16d5c3498..fb0fb8acc3f11 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr @@ -4,7 +4,8 @@ error: unsupported operation: cannot read from stdout LL | libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot read from stdout | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/read_from_stdout.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr index e2ebe234b0bb0..8426c5cb84732 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr @@ -4,7 +4,8 @@ error: unsupported operation: cannot write to stdin LL | libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot write to stdin | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/write_to_stdin.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/tokio/sleep.stderr b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr index 59179478c3025..f7d829f77d2bd 100644 --- a/src/tools/miri/tests/fail-dep/tokio/sleep.stderr +++ b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr @@ -9,7 +9,8 @@ LL | | timeout, LL | | )) | |__________^ returning ready events from epoll_wait is not yet implemented | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr index fabe3bbf1216a..23327ff7dbd57 100644 --- a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr +++ b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr @@ -4,7 +4,8 @@ error: unsupported operation: can't call foreign function `signal` on $OS LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC diff --git a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr index bd2a6c628f9e5..70f60a3f591f6 100644 --- a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr +++ b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr @@ -4,7 +4,8 @@ error: unsupported operation: can't call foreign function `__rust_alloc` on $OS LL | __rust_alloc(1, 1); | ^^^^^^^^^^^^^^^^^^ can't call foreign function `__rust_alloc` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `start` at $DIR/no_global_allocator.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr index cbbf1b3836199..14609ec699cea 100644 --- a/src/tools/miri/tests/fail/extern-type-field-offset.stderr +++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr @@ -4,7 +4,8 @@ error: unsupported operation: `extern type` does not have a known offset LL | let _field = &x.a; | ^^^^ `extern type` does not have a known offset | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static.stderr b/src/tools/miri/tests/fail/extern_static.stderr index 34bb273f04be0..1d12fd76bedb7 100644 --- a/src/tools/miri/tests/fail/extern_static.stderr +++ b/src/tools/miri/tests/fail/extern_static.stderr @@ -4,7 +4,8 @@ error: unsupported operation: extern static `FOO` is not supported by Miri LL | let _val = unsafe { std::ptr::addr_of!(FOO) }; | ^^^ extern static `FOO` is not supported by Miri | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static_in_const.stderr b/src/tools/miri/tests/fail/extern_static_in_const.stderr index 45d1632cce2ee..455d6af18e417 100644 --- a/src/tools/miri/tests/fail/extern_static_in_const.stderr +++ b/src/tools/miri/tests/fail/extern_static_in_const.stderr @@ -4,7 +4,8 @@ error: unsupported operation: extern static `E` is not supported by Miri LL | let _val = X; | ^ extern static `E` is not supported by Miri | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static_in_const.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr index 27699d780c228..91afb936facb9 100644 --- a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr +++ b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr @@ -4,7 +4,8 @@ error: unsupported operation: extern static `environ` has been declared as `exte LL | let _val = unsafe { environ }; | ^^^^^^^ extern static `environ` has been declared as `extern_static_wrong_size::environ` with a size of 1 bytes and alignment of 1 bytes, but Miri emulates it via an extern static shim with a size of N bytes and alignment of N bytes | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static_wrong_size.rs:LL:CC diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr index e5dbe749884cc..0d10b03fc4f4d 100644 --- a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr +++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr @@ -4,7 +4,8 @@ error: unsupported operation: extern static `_dispatch_queue_attr_concurrent` is LL | let _val = *DISPATCH_QUEUE_CONCURRENT; | ^^^^^^^^^^^^^^^^^^^^^^^^^ extern static `_dispatch_queue_attr_concurrent` is not supported by Miri | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr index 2523e5063e1b5..ced44ee776840 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr @@ -4,7 +4,8 @@ error: unsupported operation: unknown `miri_get_backtrace` flags 2 LL | miri_get_backtrace(2, std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_get_backtrace` flags 2 | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr index 36446ae283bf7..6e282ff4908aa 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr @@ -4,7 +4,8 @@ error: unsupported operation: unknown `miri_resolve_frame` flags 2 LL | miri_resolve_frame(buf[0], 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame` flags 2 | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-resolve-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr index ff60ab09172fd..ddf8d221cc41f 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr @@ -4,7 +4,8 @@ error: unsupported operation: unknown `miri_resolve_frame_names` flags 2 LL | ... miri_resolve_frame_names(buf[0], 2, std::ptr::null_mut(), std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame_names` flags 2 | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr index 6d4c370050f49..b3186fc5b0769 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr @@ -4,7 +4,8 @@ error: unsupported operation: unknown `miri_backtrace_size` flags 2 LL | miri_backtrace_size(2); | ^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_backtrace_size` flags 2 | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-size-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr index e23ac5ac2fc5d..9ad715f7ba4ae 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr @@ -4,7 +4,8 @@ error: unsupported operation: `miri_promise_symbolic_alignment`: pointer is not LL | unsafe { utils::miri_promise_symbolic_alignment(align8.add(1).cast(), 8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: pointer is not actually aligned | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/promise_alignment.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr index b3327e04933d5..62b6e85231107 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr @@ -4,7 +4,8 @@ error: unsupported operation: `miri_promise_symbolic_alignment`: alignment must LL | unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), 0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0 | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/promise_alignment_zero.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unsized-local.stderr b/src/tools/miri/tests/fail/unsized-local.stderr index 0ffda9e6d6317..d938f36bd5ec7 100644 --- a/src/tools/miri/tests/fail/unsized-local.stderr +++ b/src/tools/miri/tests/fail/unsized-local.stderr @@ -4,7 +4,8 @@ error: unsupported operation: unsized locals are not supported LL | let x = *(Box::new(A) as Box); | ^ unsized locals are not supported | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/unsized-local.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr index 5a2f415bb84b0..7492fdd77bbac 100644 --- a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr @@ -4,7 +4,8 @@ error: unsupported operation: can't call foreign function `foo` on $OS LL | foo(); | ^^^^^ can't call foreign function `foo` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/unsupported_foreign_function.rs:LL:CC From 6df585ade577933bdd89c376f4edc0b01b8d37e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 11:48:16 +0200 Subject: [PATCH 49/72] freebsd: test std threadname and fs APIs also reorder foreign_items to fix the grouping, and reorder the tests_minimal invocations to be more consistent --- src/tools/miri/ci/ci.sh | 12 ++++--- .../src/shims/unix/freebsd/foreign_items.rs | 32 +++++++++---------- .../{thread_name.rs => threadname.rs} | 0 3 files changed, 23 insertions(+), 21 deletions(-) rename src/tools/miri/tests/pass/concurrency/{thread_name.rs => threadname.rs} (100%) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 67835960bd7ce..d3dee0de617fe 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -141,11 +141,13 @@ case $HOST_TARGET in MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests MIRI_TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice # Partially supported targets (tier 2) - MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus - MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus - MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic - MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm - MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm + VERY_BASIC="integer vec string btreemap" # common things we test on all of them (if they have std), requires no target-specific shims + BASIC="$VERY_BASIC hello hashmap alloc align" # ensures we have the shims for stdout and basic data structures + MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus + MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus + MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic + MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm + MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std # Custom target JSON file MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index ffb583123d41b..3db9b9c1db580 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -47,21 +47,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.read_scalar(len)?, )?; } - "getrandom" => { - let [ptr, len, flags] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let ptr = this.read_pointer(ptr)?; - let len = this.read_target_usize(len)?; - let _flags = this.read_scalar(flags)?.to_i32()?; - // flags on freebsd does not really matter - // in practice, GRND_RANDOM does not particularly draw from /dev/random - // since it is the same as to /dev/urandom. - // GRND_INSECURE is only an alias of GRND_NONBLOCK, which - // does not affect the RNG. - // https://man.freebsd.org/cgi/man.cgi?query=getrandom&sektion=2&n=1 - this.gen_random(ptr, len)?; - this.write_scalar(Scalar::from_target_usize(len, this), dest)?; - } // File related shims // For those, we both intercept `func` and `call@FBSD_1.0` symbols cases @@ -90,7 +75,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(result, dest)?; } - // errno + // Miscellaneous + "getrandom" => { + let [ptr, len, flags] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let len = this.read_target_usize(len)?; + let _flags = this.read_scalar(flags)?.to_i32()?; + // flags on freebsd does not really matter + // in practice, GRND_RANDOM does not particularly draw from /dev/random + // since it is the same as to /dev/urandom. + // GRND_INSECURE is only an alias of GRND_NONBLOCK, which + // does not affect the RNG. + // https://man.freebsd.org/cgi/man.cgi?query=getrandom&sektion=2&n=1 + this.gen_random(ptr, len)?; + this.write_scalar(Scalar::from_target_usize(len, this), dest)?; + } "__error" => { let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; diff --git a/src/tools/miri/tests/pass/concurrency/thread_name.rs b/src/tools/miri/tests/pass/concurrency/threadname.rs similarity index 100% rename from src/tools/miri/tests/pass/concurrency/thread_name.rs rename to src/tools/miri/tests/pass/concurrency/threadname.rs From 38598e68c5d6c204d392af8b17ae4fc64ba6eccf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 11:49:24 +0200 Subject: [PATCH 50/72] document unofficially supported OSes --- src/tools/miri/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index ef01ca25fb0b4..616426bd838eb 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -224,8 +224,11 @@ degree documented below): - `s390x-unknown-linux-gnu` is supported as our "big-endian target of choice". - For every other target with OS `linux`, `macos`, or `windows`, Miri should generally work, but we make no promises and we don't run tests for such targets. -- For targets on other operating systems, even basic operations such as printing to the standard - output might not work, and Miri might fail before even reaching the `main` function. +- We have unofficial support (not maintained by the Miri team itself) for some further operating systems. + - `freebsd`: **maintainer wanted**. Supports `std::env` and parts of `std::{thread, fs}`, but not `std::sync`. + - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. + - `wasm`: **maintainer wanted**. Support very incomplete, not even standard output works, but an empty `main` function works. +- For targets on other operating systems, Miri might fail before even reaching the `main` function. However, even for targets that we do support, the degree of support for accessing platform APIs (such as the file system) differs between targets: generally, Linux targets have the best support, From 05e7850d7ad28b163f858361c33d9951258a6bc1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 13:00:59 +0200 Subject: [PATCH 51/72] make some tests not need output (so they work on wasm) --- src/tools/miri/tests/pass/align_offset_symbolic.rs | 5 ++++- src/tools/miri/tests/pass/align_offset_symbolic.stdout | 1 - src/tools/miri/tests/pass/vecdeque.rs | 4 ++-- src/tools/miri/tests/pass/vecdeque.stack.stdout | 2 -- src/tools/miri/tests/pass/vecdeque.tree.stdout | 2 -- src/tools/miri/tests/pass/vecdeque.tree_uniq.stdout | 2 -- 6 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 src/tools/miri/tests/pass/align_offset_symbolic.stdout delete mode 100644 src/tools/miri/tests/pass/vecdeque.stack.stdout delete mode 100644 src/tools/miri/tests/pass/vecdeque.tree.stdout delete mode 100644 src/tools/miri/tests/pass/vecdeque.tree_uniq.stdout diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs index c32fa2c8f9bda..dec3d779a789a 100644 --- a/src/tools/miri/tests/pass/align_offset_symbolic.rs +++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs @@ -62,7 +62,10 @@ fn test_from_utf8() { const N: usize = 10; let vec = vec![0x4141414141414141u64; N]; let content = unsafe { std::slice::from_raw_parts(vec.as_ptr() as *const u8, 8 * N) }; - println!("{:?}", std::str::from_utf8(content).unwrap()); + assert_eq!( + std::str::from_utf8(content).unwrap(), + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + ); } fn test_u64_array() { diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.stdout b/src/tools/miri/tests/pass/align_offset_symbolic.stdout deleted file mode 100644 index 66d4399481596..0000000000000 --- a/src/tools/miri/tests/pass/align_offset_symbolic.stdout +++ /dev/null @@ -1 +0,0 @@ -"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" diff --git a/src/tools/miri/tests/pass/vecdeque.rs b/src/tools/miri/tests/pass/vecdeque.rs index ccecf3d30a414..77c4ca5a04e6a 100644 --- a/src/tools/miri/tests/pass/vecdeque.rs +++ b/src/tools/miri/tests/pass/vecdeque.rs @@ -31,8 +31,8 @@ fn main() { } // Regression test for Debug impl's - println!("{:?} {:?}", dst, dst.iter()); - println!("{:?}", VecDeque::::new().iter()); + format!("{:?} {:?}", dst, dst.iter()); + format!("{:?}", VecDeque::::new().iter()); for a in dst { assert_eq!(*a, 2); diff --git a/src/tools/miri/tests/pass/vecdeque.stack.stdout b/src/tools/miri/tests/pass/vecdeque.stack.stdout deleted file mode 100644 index 63de960ee2bdf..0000000000000 --- a/src/tools/miri/tests/pass/vecdeque.stack.stdout +++ /dev/null @@ -1,2 +0,0 @@ -[2, 2] Iter([2, 2], []) -Iter([], []) diff --git a/src/tools/miri/tests/pass/vecdeque.tree.stdout b/src/tools/miri/tests/pass/vecdeque.tree.stdout deleted file mode 100644 index 63de960ee2bdf..0000000000000 --- a/src/tools/miri/tests/pass/vecdeque.tree.stdout +++ /dev/null @@ -1,2 +0,0 @@ -[2, 2] Iter([2, 2], []) -Iter([], []) diff --git a/src/tools/miri/tests/pass/vecdeque.tree_uniq.stdout b/src/tools/miri/tests/pass/vecdeque.tree_uniq.stdout deleted file mode 100644 index 63de960ee2bdf..0000000000000 --- a/src/tools/miri/tests/pass/vecdeque.tree_uniq.stdout +++ /dev/null @@ -1,2 +0,0 @@ -[2, 2] Iter([2, 2], []) -Iter([], []) From 823e31d9fa5ef4aa6076e1f15083fef336bc44fc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 14:26:11 +0200 Subject: [PATCH 52/72] add helper function to declare an extern static for a weak symbol --- src/tools/miri/src/shims/extern_static.rs | 22 ++++++++++++++----- src/tools/miri/src/shims/foreign_items.rs | 9 ++++++++ .../miri/src/shims/unix/foreign_items.rs | 2 +- .../src/shims/unix/linux/foreign_items.rs | 2 -- .../miri/src/shims/windows/foreign_items.rs | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 442338a6117d8..5cec51e960484 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -29,6 +29,21 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { Ok(()) } + /// Extern statics that are initialized with function pointers to the symbols of the same name. + fn weak_symbol_extern_statics( + this: &mut MiriInterpCx<'mir, 'tcx>, + names: &[&str], + ) -> InterpResult<'tcx> { + for name in names { + assert!(this.is_dyn_sym(name), "{name} is not a dynamic symbol"); + let layout = this.machine.layouts.const_raw_ptr; + let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name))); + let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout); + Self::alloc_extern_static(this, name, val)?; + } + Ok(()) + } + /// Sets up the "extern statics" for this machine. pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> { // "__rust_no_alloc_shim_is_unstable" @@ -58,12 +73,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } "android" => { Self::null_ptr_extern_statics(this, &["bsd_signal"])?; - // "signal" -- just needs a non-zero pointer value (function does not even get called), - // but we arrange for this to call the `signal` function anyway. - let layout = this.machine.layouts.const_raw_ptr; - let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal"))); - let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout); - Self::alloc_extern_static(this, "signal", val)?; + Self::weak_symbol_extern_statics(this, &["signal"])?; } "windows" => { // "_tls_used" diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 6a12180b836b7..4f8bb801100c1 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -151,6 +151,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(None) } + fn is_dyn_sym(&self, name: &str) -> bool { + let this = self.eval_context_ref(); + match this.tcx.sess.target.os.as_ref() { + os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os), + "windows" => shims::windows::foreign_items::is_dyn_sym(name), + _ => false, + } + } + /// Emulates a call to a `DynSym`. fn emulate_dyn_sym( &mut self, diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index bd299aaa1253a..bebf8b4b8a542 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -15,7 +15,7 @@ use shims::unix::freebsd::foreign_items as freebsd; use shims::unix::linux::foreign_items as linux; use shims::unix::macos::foreign_items as macos; -fn is_dyn_sym(name: &str, target_os: &str) -> bool { +pub fn is_dyn_sym(name: &str, target_os: &str) -> bool { match name { // Used for tests. "isatty" => true, diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 497e8bee70ec9..58ffd5fc1e037 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -113,9 +113,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // have the right type. let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; - let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?; - let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; if args.is_empty() { diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index e8ae80261c662..7b156ee311a0a 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -15,7 +15,7 @@ use crate::*; use shims::foreign_items::EmulateForeignItemResult; use shims::windows::handle::{Handle, PseudoHandle}; -fn is_dyn_sym(name: &str) -> bool { +pub fn is_dyn_sym(name: &str) -> bool { // std does dynamic detection for these symbols matches!( name, From 19aa8a021d82d16af95913627055f064ed976b3b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 14:41:12 +0200 Subject: [PATCH 53/72] make statx a regular function (so we don't need to support the syscall) --- src/tools/miri/src/shims/extern_static.rs | 7 +++--- src/tools/miri/src/shims/unix/fd.rs | 4 +++ .../src/shims/unix/linux/foreign_items.rs | 25 ++++++------------- .../miri/tests/pass/alloc-access-tracking.rs | 5 ++-- .../tests/pass/alloc-access-tracking.stderr | 8 +++--- 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 5cec51e960484..c3c7ef7c1fd8e 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -16,8 +16,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { /// Zero-initialized pointer-sized extern statics are pretty common. /// Most of them are for weak symbols, which we all set to null (indicating that the - /// symbol is not supported, and triggering fallback code which ends up calling a - /// syscall that we do support). + /// symbol is not supported, and triggering fallback code which ends up calling + /// some other shim that we do support). fn null_ptr_extern_statics( this: &mut MiriInterpCx<'mir, 'tcx>, names: &[&str], @@ -59,8 +59,9 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { "linux" => { Self::null_ptr_extern_statics( this, - &["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"], + &["__cxa_thread_atexit_impl", "__clock_gettime64"], )?; + Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?; // "environ" let environ = this.machine.env_vars.unix().environ(); Self::add_extern_static(this, "environ", environ); diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 566988cba1f82..e536b78d1c0bc 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -17,6 +17,7 @@ use crate::*; pub trait FileDescription: std::fmt::Debug + Any { fn name(&self) -> &'static str; + /// Reads as much as possible into the given buffer, and returns the number of bytes read. fn read<'tcx>( &mut self, _communicate_allowed: bool, @@ -26,6 +27,7 @@ pub trait FileDescription: std::fmt::Debug + Any { throw_unsup_format!("cannot read from {}", self.name()); } + /// Writes as much as possible from the given buffer, and returns the number of bytes written. fn write<'tcx>( &mut self, _communicate_allowed: bool, @@ -35,6 +37,8 @@ pub trait FileDescription: std::fmt::Debug + Any { throw_unsup_format!("cannot write to {}", self.name()); } + /// Seeks to the given offset (which can be relative to the beginning, end, or current position). + /// Returns the new position from the start of the stream. fn seek<'tcx>( &mut self, _communicate_allowed: bool, diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 58ffd5fc1e037..71cdc3be81470 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -12,7 +12,7 @@ use shims::unix::linux::mem::EvalContextExt as _; use shims::unix::linux::sync::futex; pub fn is_dyn_sym(name: &str) -> bool { - matches!(name, "getrandom") + matches!(name, "getrandom" | "statx") } impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} @@ -29,7 +29,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. match link_name.as_str() { - // File related shims (but also see "syscall" below for statx) + // File related shims "readdir64" => { let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let result = this.linux_readdir64(dirp)?; @@ -41,6 +41,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let result = this.sync_file_range(fd, offset, nbytes, flags)?; this.write_scalar(result, dest)?; } + "statx" => { + let [dirfd, pathname, flags, mask, statxbuf] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; + this.write_scalar(Scalar::from_i32(result), dest)?; + } // epoll, eventfd "epoll_create1" => { @@ -113,7 +119,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // have the right type. let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; - let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?; let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; if args.is_empty() { @@ -134,20 +139,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } getrandom(this, &args[1], &args[2], &args[3], dest)?; } - // `statx` is used by `libstd` to retrieve metadata information on `linux` - // instead of using `stat`,`lstat` or `fstat` as on `macos`. - id if id == sys_statx => { - // The first argument is the syscall id, so skip over it. - if args.len() < 6 { - throw_ub_format!( - "incorrect number of arguments for `statx` syscall: got {}, expected at least 6", - args.len() - ); - } - let result = - this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?; - this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?; - } // `futex` is used by some synchronization primitives. id if id == sys_futex => { futex(this, &args[1..], dest)?; diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index 29c1ee2f7b765..a226783155b42 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,7 +1,8 @@ #![feature(start)] #![no_std] -//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort -//@only-target-linux: alloc IDs differ between OSes for some reason +//@compile-flags: -Zmiri-track-alloc-id=20 -Zmiri-track-alloc-accesses -Cpanic=abort +//@normalize-stderr-test: "id 20" -> "id $$ALLOC" +//@only-target-linux: alloc IDs differ between OSes (due to extern static allocations) extern "Rust" { fn miri_alloc(size: usize, align: usize) -> *mut u8; diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index bef13701ea2c4..0af6cde833f7f 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -2,7 +2,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | let ptr = miri_alloc(123, 1); - | ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id 18 + | ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC @@ -11,7 +11,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | *ptr = 42; // Crucially, only a write is printed here, no read! - | ^^^^^^^^^ write access to allocation with id 18 + | ^^^^^^^^^ write access to allocation with id $ALLOC | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC @@ -20,7 +20,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | assert_eq!(*ptr, 42); - | ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id 18 + | ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id $ALLOC | = note: BACKTRACE: = note: inside `start` at RUSTLIB/core/src/macros/mod.rs:LL:CC @@ -30,7 +30,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | miri_dealloc(ptr, 123, 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id 18 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id $ALLOC | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC From 98bb8acb5b437b7cc3a174d23660587469e4c8d1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 17:52:50 +0200 Subject: [PATCH 54/72] sync: better error in invalid synchronization primitive ID --- src/tools/miri/src/concurrency/sync.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index d3cef8bf5f32b..9467695599966 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -305,6 +305,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let next_index = this.machine.threads.sync.mutexes.next_index(); if let Some(old) = existing(this, next_index)? { + if this.machine.threads.sync.mutexes.get(old).is_none() { + throw_ub_format!("mutex has invalid ID"); + } Ok(old) } else { let new_index = this.machine.threads.sync.mutexes.push(Default::default()); @@ -399,6 +402,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let next_index = this.machine.threads.sync.rwlocks.next_index(); if let Some(old) = existing(this, next_index)? { + if this.machine.threads.sync.rwlocks.get(old).is_none() { + throw_ub_format!("rwlock has invalid ID"); + } Ok(old) } else { let new_index = this.machine.threads.sync.rwlocks.push(Default::default()); @@ -563,6 +569,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let next_index = this.machine.threads.sync.condvars.next_index(); if let Some(old) = existing(this, next_index)? { + if this.machine.threads.sync.condvars.get(old).is_none() { + throw_ub_format!("condvar has invalid ID"); + } Ok(old) } else { let new_index = this.machine.threads.sync.condvars.push(Default::default()); From 86d7dff0b81748b45e43e0e4073ee9ec97c1e08f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 18:08:41 +0200 Subject: [PATCH 55/72] factor some pthread offset into constants --- src/tools/miri/src/shims/unix/sync.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index e50a8934e09d0..544f3259eeaf7 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -65,7 +65,8 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>( // (need to avoid this because it is set by static initializer macros) // bytes 4-7: mutex id as u32 or 0 if id is not assigned yet. // bytes 12-15 or 16-19 (depending on platform): mutex kind, as an i32 -// (the kind has to be at its offset for compatibility with static initializer macros) +// (the kind has to be at this particular offset for compatibility with Linux's static initializer +// macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.) fn mutex_get_id<'mir, 'tcx: 'mir>( ecx: &mut MiriInterpCx<'mir, 'tcx>, @@ -123,11 +124,13 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>( // (need to avoid this because it is set by static initializer macros) // bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet. +const RWLOCK_ID_OFFSET: u64 = 4; + fn rwlock_get_id<'mir, 'tcx: 'mir>( ecx: &mut MiriInterpCx<'mir, 'tcx>, rwlock_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, RwLockId> { - ecx.rwlock_get_or_create_id(rwlock_op, ecx.libc_ty_layout("pthread_rwlock_t"), 4) + ecx.rwlock_get_or_create_id(rwlock_op, ecx.libc_ty_layout("pthread_rwlock_t"), RWLOCK_ID_OFFSET) } // pthread_condattr_t @@ -136,13 +139,15 @@ fn rwlock_get_id<'mir, 'tcx: 'mir>( // store an i32 in the first four bytes equal to the corresponding libc clock id constant // (e.g. CLOCK_REALTIME). +const CONDATTR_CLOCK_OFFSET: u64 = 0; + fn condattr_get_clock_id<'mir, 'tcx: 'mir>( ecx: &MiriInterpCx<'mir, 'tcx>, attr_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( attr_op, - 0, + CONDATTR_CLOCK_OFFSET, ecx.libc_ty_layout("pthread_condattr_t"), ecx.machine.layouts.i32, )? @@ -156,7 +161,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>( ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( attr_op, - 0, + CONDATTR_CLOCK_OFFSET, Scalar::from_i32(clock_id), ecx.libc_ty_layout("pthread_condattr_t"), ecx.machine.layouts.i32, @@ -172,11 +177,14 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>( // bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet. // bytes 8-11: the clock id constant as i32 +const CONDVAR_ID_OFFSET: u64 = 4; +const CONDVAR_CLOCK_OFFSET: u64 = 8; + fn cond_get_id<'mir, 'tcx: 'mir>( ecx: &mut MiriInterpCx<'mir, 'tcx>, cond_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, CondvarId> { - ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), 4) + ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), CONDVAR_ID_OFFSET) } fn cond_reset_id<'mir, 'tcx: 'mir>( @@ -185,7 +193,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>( ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( cond_op, - 4, + CONDVAR_ID_OFFSET, Scalar::from_i32(0), ecx.libc_ty_layout("pthread_cond_t"), ecx.machine.layouts.u32, @@ -198,7 +206,7 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>( ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( cond_op, - 8, + CONDVAR_CLOCK_OFFSET, ecx.libc_ty_layout("pthread_cond_t"), ecx.machine.layouts.i32, )? @@ -212,7 +220,7 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>( ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( cond_op, - 8, + CONDVAR_CLOCK_OFFSET, Scalar::from_i32(clock_id), ecx.libc_ty_layout("pthread_cond_t"), ecx.machine.layouts.i32, From 9503c41eccd35239c1a35d4e1e38b620f3e6262b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 18:18:10 +0200 Subject: [PATCH 56/72] also test pthread_condattr_getclock --- src/tools/miri/src/shims/unix/sync.rs | 16 ++++++++++++ .../tests/pass-dep/shims/libc-rsfs.stdout | 1 - .../miri/tests/pass-dep/shims/pthread-sync.rs | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 544f3259eeaf7..9c096760415e3 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -727,6 +727,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); + // Does not exist on macOS! + if !matches!(&*this.tcx.sess.target.os, "linux") { + throw_unsup_format!( + "`pthread_condattr_init` is not supported on {}", + this.tcx.sess.target.os + ); + } + let clock_id = this.read_scalar(clock_id_op)?.to_i32()?; if clock_id == this.eval_libc_i32("CLOCK_REALTIME") || clock_id == this.eval_libc_i32("CLOCK_MONOTONIC") @@ -747,6 +755,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); + // Does not exist on macOS! + if !matches!(&*this.tcx.sess.target.os, "linux") { + throw_unsup_format!( + "`pthread_condattr_init` is not supported on {}", + this.tcx.sess.target.os + ); + } + let clock_id = condattr_get_clock_id(this, attr_op)?; this.write_scalar(Scalar::from_i32(clock_id), &this.deref_pointer(clk_id_op)?)?; diff --git a/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout b/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout deleted file mode 100644 index b6fa69e3d5d2e..0000000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout +++ /dev/null @@ -1 +0,0 @@ -hello dup fd diff --git a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs b/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs index c9d10cb83d4d2..12d3f2b6f142f 100644 --- a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs +++ b/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs @@ -19,6 +19,7 @@ fn main() { check_rwlock_write(); check_rwlock_read_no_deadlock(); check_cond(); + check_condattr(); } fn test_mutex_libc_init_recursive() { @@ -261,6 +262,31 @@ fn check_cond() { } } +fn check_condattr() { + unsafe { + // Just smoke-testing that these functions can be called. + let mut attr: MaybeUninit = MaybeUninit::uninit(); + assert_eq!(libc::pthread_condattr_init(attr.as_mut_ptr()), 0); + + #[cfg(not(target_os = "macos"))] // setclock-getclock do not exist on macOS + { + let clock_id = libc::CLOCK_MONOTONIC; + assert_eq!(libc::pthread_condattr_setclock(attr.as_mut_ptr(), clock_id), 0); + let mut check_clock_id = MaybeUninit::::uninit(); + assert_eq!( + libc::pthread_condattr_getclock(attr.as_mut_ptr(), check_clock_id.as_mut_ptr()), + 0 + ); + assert_eq!(check_clock_id.assume_init(), clock_id); + } + + let mut cond: MaybeUninit = MaybeUninit::uninit(); + assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()), 0); + assert_eq!(libc::pthread_condattr_destroy(attr.as_mut_ptr()), 0); + assert_eq!(libc::pthread_cond_destroy(cond.as_mut_ptr()), 0); + } +} + // std::sync::RwLock does not even used pthread_rwlock any more. // Do some smoke testing of the API surface. fn test_rwlock_libc_static_initializer() { From adb74ae486938f14ef5a337b0550804abaa6aa0d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 18:37:23 +0200 Subject: [PATCH 57/72] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index b2e6353778f5a..038c2549b66de 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -d6d3b342e85272f5e75c0d7a1dd3a1d8becb40ac +d7ea27808deb5e10a0f7384e339e4e6165e33398 From c6e273cccde6fac190920077f20d133acdaa158b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 18:39:45 +0200 Subject: [PATCH 58/72] bless and fmt --- src/tools/miri/src/intrinsics/mod.rs | 15 +++++++++++---- .../fail/intrinsic_fallback_checks_ub.stderr | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 8b078921fdf3b..05fcaa69e7884 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -10,8 +10,8 @@ use rustc_middle::{ mir, ty::{self, FloatTy}, }; -use rustc_target::abi::Size; use rustc_span::{sym, Symbol}; +use rustc_target::abi::Size; use crate::*; use atomic::EvalContextExt as _; @@ -70,13 +70,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("unimplemented intrinsic: `{intrinsic_name}`") } let intrinsic_fallback_checks_ub = Symbol::intern("intrinsic_fallback_checks_ub"); - if this.tcx.get_attrs_by_path(instance.def_id(), &[sym::miri, intrinsic_fallback_checks_ub]).next().is_none() { - throw_unsup_format!("miri can only use intrinsic fallback bodies that check UB. After verifying that `{intrinsic_name}` does so, add the `#[miri::intrinsic_fallback_checks_ub]` attribute to it; also ping @rust-lang/miri when you do that"); + if this + .tcx + .get_attrs_by_path(instance.def_id(), &[sym::miri, intrinsic_fallback_checks_ub]) + .next() + .is_none() + { + throw_unsup_format!( + "miri can only use intrinsic fallback bodies that check UB. After verifying that `{intrinsic_name}` does so, add the `#[miri::intrinsic_fallback_checks_ub]` attribute to it; also ping @rust-lang/miri when you do that" + ); } return Ok(Some(ty::Instance { def: ty::InstanceDef::Item(instance.def_id()), args: instance.args, - })) + })); } trace!("{:?}", this.dump_place(&dest.clone().into())); diff --git a/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr b/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr index b37e05c62f95e..5dd6520fe42d4 100644 --- a/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr +++ b/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr @@ -4,7 +4,8 @@ error: unsupported operation: miri can only use intrinsic fallback bodies that c LL | ptr_guaranteed_cmp::<()>(std::ptr::null(), std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ miri can only use intrinsic fallback bodies that check UB. After verifying that `ptr_guaranteed_cmp` does so, add the `#[miri::intrinsic_fallback_checks_ub]` attribute to it; also ping @rust-lang/miri when you do that | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/intrinsic_fallback_checks_ub.rs:LL:CC From a040df7e4e250e4b1bc064725c6ccd61861a73b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 19:09:40 +0200 Subject: [PATCH 59/72] remove some dead code --- src/tools/miri/bench-cargo-miri/mse/src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/miri/bench-cargo-miri/mse/src/main.rs b/src/tools/miri/bench-cargo-miri/mse/src/main.rs index c09dc2484d380..e16ccd2c0d735 100644 --- a/src/tools/miri/bench-cargo-miri/mse/src/main.rs +++ b/src/tools/miri/bench-cargo-miri/mse/src/main.rs @@ -4,9 +4,6 @@ static EXPECTED: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static PCM: &[i16] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -2, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0, -2, 0, -2, 0, -2, 0, -2, -2, -2, -3, -3, -3, -3, -4, -2, -5, -2, -5, -2, -4, 0, -4, 0, -4, 0, -4, 1, -4, 1, -4, 2, -4, 2, -4, 2, -4, 2, -4, 2, -3, 1, -4, 0, -4, 0, -5, 0, -5, 0, -5, 0, -4, 2, -4, 3, -4, 4, -3, 5, -2, 5, -3, 6, -3, 6, -3, 5, -3, 5, -2, 4, -2, 3, -5, 0, -6, 0, -3, -2, -4, -4, -9, -5, -9, -4, -4, -2, -4, -2, -4, 0, -2, 1, 1, 1, 4, 2, 8, 2, 12, 1, 13, 0, 12, 0, 11, 0, 8, -2, 7, 0, 7, -3, 11, -8, 15, -9, 17, -6, 17, -5, 13, -3, 7, 0, 3, 0, -2, 0, -4, 0, -4, -2, -6, 0, -14, -2, -17, -4, -8, 0, -7, 5, -17, 7, -18, 10, -7, 18, -2, 25, -3, 27, 0, 31, 4, 34, 4, 34, 8, 36, 8, 37, 2, 36, 4, 34, 8, 28, 3, 15, 0, 11, 0, 12, -5, 8, -4, 10, 0, 23, -4, 31, -8, 30, -2, 30, 0, 26, -6, 22, -6, 20, -12, 15, -19, 10, -10, 13, -14, 6, -43, -13, -43, -16, -9, -12, -10, -29, -42, -40, -37, -28, -5, -21, 1, -24, -8, -20, 4, -18, 26, -24, 44, -26, 66, -30, 86, -37, 88, -41, 72, -46, 50, -31, 28, 23, 14, 64, 16, 51, 26, 32, 34, 39, 42, 48, 35, 58, 0, 72, -36, 69, -59, 58, -98, 54, -124, 36, -103, 12, -110, 5, -173, -19, -146, -59, -4, -42, 51, 1, -23, -6, -30, -6, 45, 46, 47, 70, 6, 55, 19, 60, 38, 62, 42, 47, 61, 46, 40, 42, -19, 22, -34, 6, -35, -50, -61, -141, -37, -171, 17, -163, 26, -180, 46, -154, 80, -63, 48, -4, 18, 20, 50, 47, 58, 53, 44, 61, 57, 85, 37, 80, 0, 86, -8, 106, -95, 49, -213, -8, -131, 47, 49, 63, 40, -39, -69, -74, -37, -20, 63, -12, 58, -14, -12, 25, -31, 41, 11, 45, 76, 47, 167, 5, 261, -37, 277, -83, 183, -172, 35, -122, -79, 138, -70, 266, 69, 124, 228, 0, 391, -29, 594, -84, 702, -78, 627, -8, 551, -13, 509, 13, 372, 120, 352, 125, 622, 127, 691, 223, 362, 126, 386, -33, 915, 198, 958, 457, 456, 298, 500, 233, 1027, 469, 1096, 426, 918, 160, 1067, 141, 1220, 189, 1245, 164, 1375, 297, 1378, 503, 1299, 702, 1550, 929, 1799, 855, 1752, 547, 1830, 602, 1928, 832, 1736, 796, 1735, 933, 1961, 1385, 1935, 1562, 2105, 1485, 2716, 1449, 2948, 1305, 2768, 1205, 2716, 1346, 2531, 1450, 2470, 1653, 3117, 2111, 3370, 2176, 2696, 1947, 2925, 2305, 3846, 2658, 2425, 2184, -877, 1981, -2261, 2623, -1645, 2908, -1876, 2732, -2704, 2953, -2484, 3116, -2120, 2954, -2442, 3216, -2466, 3499, -2192, 3234, -2392, 3361, -2497, 3869, -2078, 3772, -1858, 3915, -2066, 4438, -2285, 2934, -2294, -280, -2066, -1762, -1992, -1412, -2298, -1535, -2399, -1789, -2223, -1419, -2244, -1334, -2092, -1476, -1777, -1396, -2014, -1571, -2199, -1574, -1843, -1167, -1910, -1446, -2007, -1818]; fn main() { - #[cfg(increase_thread_usage)] - let thread = std::thread::spawn(|| 4); - for _ in 0..2 { mse(PCM.len(), PCM, EXPECTED); } From 43e66003f3aaab70da9a8f3356188fda0a2b1a10 Mon Sep 17 00:00:00 2001 From: Vladimir Makayev Date: Mon, 22 Apr 2024 18:55:29 -0700 Subject: [PATCH 60/72] Implement lldb formattter for "clang encoded" enums (LLDB 18.1+) Summary: I landed a fix last year to enable `DW_TAG_variant_part` encoding in LLDBs (https://reviews.llvm.org/D149213). This PR is a corresponding fix in synthetic formatters to decode that information. This is in no way perfect implementation but at least it improves the status quo. But most types of enums will be visible and debuggable in some way. I've also updated most of the existing tests that touch enums and re-enabled test cases based on LLDB for enums. Test Plan: ran tests `./x test tests/debuginfo/`. Also tested manually in LLDB CLI and LLDB VSCode Other Thoughs A better approach would probably be adopting [formatters from codelldb](https://github.com/vadimcn/codelldb/blob/master/formatters/rust.py). There is some neat hack that hooks up summary provider via synthetic provider which can ultimately fix more display issues for Rust types and enums too. But getting it to work well might take more time that I have right now. --- src/etc/lldb_lookup.py | 3 +- src/etc/lldb_providers.py | 52 ++++++++++++++++++ src/etc/rust_types.py | 7 ++- tests/debuginfo/borrowed-enum.rs | 5 +- tests/debuginfo/coroutine-objects.rs | 16 ++---- tests/debuginfo/enum-thinlto.rs | 4 +- tests/debuginfo/issue-57822.rs | 4 +- tests/debuginfo/msvc-pretty-enums.rs | 81 +++++++++++++++++++++++++++- tests/debuginfo/struct-style-enum.rs | 7 ++- tests/debuginfo/tuple-style-enum.rs | 6 ++- tests/debuginfo/unique-enum.rs | 5 +- 11 files changed, 166 insertions(+), 24 deletions(-) diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index a93b42e1cc449..db3afb00369da 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -86,7 +86,8 @@ def synthetic_lookup(valobj, dict): return synthetic_lookup(valobj.GetChildAtIndex(discriminant), dict) if rust_type == RustType.SINGLETON_ENUM: return synthetic_lookup(valobj.GetChildAtIndex(0), dict) - + if rust_type == RustType.ENUM: + return ClangEncodedEnumProvider(valobj, dict) if rust_type == RustType.STD_VEC: return StdVecSyntheticProvider(valobj, dict) if rust_type == RustType.STD_VEC_DEQUE: diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 1c43977a501a0..a87fd6078b866 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -247,6 +247,58 @@ def has_children(self): # type: () -> bool return True +class ClangEncodedEnumProvider: + """Pretty-printer for 'clang-encoded' enums support implemented in LLDB""" + DISCRIMINANT_MEMBER_NAME = "$discr$" + VALUE_MEMBER_NAME = "value" + + def __init__(self, valobj, dict): + self.valobj = valobj + self.update() + + def has_children(self): + return True + + def num_children(self): + if self.is_default: + return 1 + return 2 + + def get_child_index(self, name): + if name == ClangEncodedEnumProvider.VALUE_MEMBER_NAME: + return 0 + if name == ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME: + return 1 + return -1 + + def get_child_at_index(self, index): + if index == 0: + return self.variant.GetChildMemberWithName(ClangEncodedEnumProvider.VALUE_MEMBER_NAME) + if index == 1: + return self.variant.GetChildMemberWithName( + ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME) + + + def update(self): + all_variants = self.valobj.GetChildAtIndex(0) + index = self._getCurrentVariantIndex(all_variants) + self.variant = all_variants.GetChildAtIndex(index) + self.is_default = self.variant.GetIndexOfChildWithName( + ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME) == -1 + + def _getCurrentVariantIndex(self, all_variants): + default_index = 0 + for i in range(all_variants.GetNumChildren()): + variant = all_variants.GetChildAtIndex(i) + discr = variant.GetChildMemberWithName( + ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME) + if discr.IsValid(): + discr_unsigned_value = discr.GetValueAsUnsigned() + if variant.GetName() == f"$variant${discr_unsigned_value}": + return i + else: + default_index = i + return default_index class TupleSyntheticProvider: """Pretty-printer for tuples and tuple enum variants""" diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py index c0415a3cdcfe4..190fbc13a173f 100644 --- a/src/etc/rust_types.py +++ b/src/etc/rust_types.py @@ -60,6 +60,7 @@ class RustType(object): ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$" ENUM_DISR_FIELD_NAME = "<>" +ENUM_LLDB_ENCODED_VARIANTS = "$variants$" STD_TYPE_TO_REGEX = { RustType.STD_STRING: STD_STRING_REGEX, @@ -96,7 +97,11 @@ def classify_struct(name, fields): if regex.match(name): return ty - if fields[0].name == ENUM_DISR_FIELD_NAME: + # <> is emitted by GDB while LLDB(18.1+) emits "$variants$" + if ( + fields[0].name == ENUM_DISR_FIELD_NAME + or fields[0].name == ENUM_LLDB_ENCODED_VARIANTS + ): return RustType.ENUM if is_tuple_fields(fields): diff --git a/tests/debuginfo/borrowed-enum.rs b/tests/debuginfo/borrowed-enum.rs index 39883ffd0b6ab..fc2ab62a21c49 100644 --- a/tests/debuginfo/borrowed-enum.rs +++ b/tests/debuginfo/borrowed-enum.rs @@ -1,6 +1,6 @@ // Require a gdb or lldb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 -//@ needs-rust-lldb +//@ min-lldb-version: 1800 //@ compile-flags:-g @@ -23,10 +23,13 @@ // lldb-command:run // lldb-command:v *the_a_ref +// lldbg-check:(borrowed_enum::ABC) *the_a_ref = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 } // lldbr-check:(borrowed_enum::ABC::TheA) *the_a_ref = TheA { TheA: 0, TheB: 8970181431921507452 } // lldb-command:v *the_b_ref +// lldbg-check:(borrowed_enum::ABC) *the_b_ref = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 } // lldbr-check:(borrowed_enum::ABC::TheB) *the_b_ref = { = 0 = 286331153 = 286331153 } // lldb-command:v *univariant_ref +// lldbg-check:(borrowed_enum::Univariant) *univariant_ref = { value = { 0 = 4820353753753434 } } // lldbr-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { = 4820353753753434 } } #![allow(unused_variables)] diff --git a/tests/debuginfo/coroutine-objects.rs b/tests/debuginfo/coroutine-objects.rs index 9e1bd5d62e7a1..eca31a6e5de61 100644 --- a/tests/debuginfo/coroutine-objects.rs +++ b/tests/debuginfo/coroutine-objects.rs @@ -1,8 +1,9 @@ // Require a gdb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 +//@ min-lldb-version: 1800 -// LLDB without native Rust support cannot read DW_TAG_variant_part, -// so it prints nothing for coroutines. But those tests are kept to +// LLDB (18.1+) now supports DW_TAG_variant_part, but there is some bug in either compiler or LLDB +// with memory layout of discriminant for this particular enum // ensure that LLDB won't crash at least (like #57822). //@ compile-flags:-g @@ -26,16 +27,7 @@ // lldb-command:run // lldb-command:v b -// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b = -// lldb-command:continue -// lldb-command:v b -// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b = -// lldb-command:continue -// lldb-command:v b -// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b = -// lldb-command:continue -// lldb-command:v b -// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b = +// lldb-check:(coroutine_objects::main::{coroutine_env#0}) b = { value = { _ref__a = 0x[...] } $discr$ = ',' } // === CDB TESTS =================================================================================== diff --git a/tests/debuginfo/enum-thinlto.rs b/tests/debuginfo/enum-thinlto.rs index f3f177589318c..42a0d1e28f8e5 100644 --- a/tests/debuginfo/enum-thinlto.rs +++ b/tests/debuginfo/enum-thinlto.rs @@ -1,6 +1,6 @@ // Require a gdb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 - +//@ min-lldb-version: 1800 //@ compile-flags:-g -Z thinlto // === GDB TESTS =================================================================================== @@ -15,7 +15,7 @@ // lldb-command:run // lldb-command:v *abc -// lldbg-check:(enum_thinlto::ABC) *abc = +// lldbg-check:(enum_thinlto::ABC) *abc = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 } // lldbr-check:(enum_thinlto::ABC) *abc = (x = 0, y = 8970181431921507452) #![allow(unused_variables)] diff --git a/tests/debuginfo/issue-57822.rs b/tests/debuginfo/issue-57822.rs index 93e1a2558f693..66912fc471a94 100644 --- a/tests/debuginfo/issue-57822.rs +++ b/tests/debuginfo/issue-57822.rs @@ -3,7 +3,7 @@ // Require a gdb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 - +//@ min-lldb-version: 1800 //@ compile-flags:-g // === GDB TESTS =================================================================================== @@ -24,7 +24,7 @@ // lldbg-check:(issue_57822::main::{closure_env#1}) g = { f = { x = 1 } } // lldb-command:v b -// lldbg-check:(issue_57822::main::{coroutine_env#3}) b = +// lldbg-check:(issue_57822::main::{coroutine_env#3}) b = { value = { a = { value = { y = 2 } $discr$ = '\x02' } } $discr$ = '\x02' } #![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait)] #![omit_gdb_pretty_printer_section] diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs index cfac14a22c418..c267da0e1b759 100644 --- a/tests/debuginfo/msvc-pretty-enums.rs +++ b/tests/debuginfo/msvc-pretty-enums.rs @@ -1,5 +1,84 @@ -//@ only-cdb +//@ min-lldb-version: 1800 +//@ ignore-gdb //@ compile-flags:-g + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:v a +// lldbg-check:(core::option::Option) a = { value = { 0 = Low } } + +// lldb-command:v b +// lldbg-check:(core::option::Option) b = { value = $discr$ = '\x01' } + +// lldb-command:v c +// lldbg-check:(msvc_pretty_enums::NicheLayoutEnum) c = { value = $discr$ = '\x11' } + +// lldb-command:v d +// lldbg-check:(msvc_pretty_enums::NicheLayoutEnum) d = { value = { my_data = High } } + +// lldb-command:v e +// lldbg-check:(msvc_pretty_enums::NicheLayoutEnum) e = { value = $discr$ = '\x13' } + +// lldb-command:v h +// lldbg-check:(core::option::Option) h = { value = { 0 = 12 } $discr$ = 1 } + +// lldb-command:v i +// lldbg-check:(core::option::Option) i = { value = $discr$ = 0 } + +// lldb-command:v j +// lldbg-check:(msvc_pretty_enums::CStyleEnum) j = High + +// lldb-command:v k +// lldbg-check:(core::option::Option) k = { value = { 0 = "IAMA optional string!" { vec = size=21 { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 'o' [6] = 'p' [7] = 't' [8] = 'i' [9] = 'o' [10] = 'n' [11] = 'a' [12] = 'l' [13] = ' ' [14] = 's' [15] = 't' [16] = 'r' [17] = 'i' [18] = 'n' [19] = 'g' [20] = '!' } } } } + +// lldb-command:v l +// lldbg-check:(core::result::Result) l = { value = { 0 = {} } } + +// lldb-command:v niche128_some +// lldbg-check:(core::option::Option>) niche128_some = { value = $discr$ = 123456 } + +// lldb-command:v niche128_none +// lldbg-check:(core::option::Option>) niche128_none = { value = $discr$ = 0 } + +// lldb-command:v wrapping_niche128_untagged +// lldbg-check:(msvc_pretty_enums::Wrapping128Niche) wrapping_niche128_untagged = { value = { 0 = { 0 = 340282366920938463463374607431768211454 } } } + +// lldb-command:v wrapping_niche128_none1 +// lldbg-check:(msvc_pretty_enums::Wrapping128Niche) wrapping_niche128_none1 = { value = { 0 = { 0 = 2 } } } + +// lldb-command:v direct_tag_128_a +// lldbg-check:(msvc_pretty_enums::DirectTag128) direct_tag_128_a = { value = { 0 = 42 } $discr$ = 0 } + +// lldb-command:v direct_tag_128_b +// lldbg-check:(msvc_pretty_enums::DirectTag128) direct_tag_128_b = { value = { 0 = 137 } $discr$ = 1 } + +// &u32 is incorrectly formatted and LLDB thinks it's a char* so skipping niche_w_fields_1_some + +// lldb-command:v niche_w_fields_1_none +// lldbg-check:(msvc_pretty_enums::NicheLayoutWithFields1) niche_w_fields_1_none = { value = { 0 = 99 } $discr$ = 1 } + +// lldb-command:v niche_w_fields_2_some +// lldbg-check:(msvc_pretty_enums::NicheLayoutWithFields2) niche_w_fields_2_some = { value = { 0 = 800 { __0 = { 0 = 800 } } 1 = 900 } $discr$ = 0 } + +// lldb-command:v niche_w_fields_3_some +// lldbg-check:(msvc_pretty_enums::NicheLayoutWithFields3) niche_w_fields_3_some = { value = { 0 = '\x89' 1 = true } } + +// lldb-command:v niche_w_fields_3_niche3 +// lldbg-check:(msvc_pretty_enums::NicheLayoutWithFields3) niche_w_fields_3_niche3 = { value = { 0 = '"' } $discr$ = '\x04' } + +// lldb-command:v arbitrary_discr1 +// lldbg-check:(msvc_pretty_enums::ArbitraryDiscr) arbitrary_discr1 = { value = { 0 = 1234 } $discr$ = 1000 } + +// lldb-command:v arbitrary_discr2 +// lldbg-check:(msvc_pretty_enums::ArbitraryDiscr) arbitrary_discr2 = { value = { 0 = 5678 } $discr$ = 5000000 } + +// === CDB TESTS ================================================================================== +// cdb-command: g +// +// cdb-command: dx a +// cdb-check:a : Some [Type: enum2$ >] +// cdb-check: [+0x000] __0 : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum] // // cdb-command: g // diff --git a/tests/debuginfo/struct-style-enum.rs b/tests/debuginfo/struct-style-enum.rs index 517b76c14120b..42368017cae69 100644 --- a/tests/debuginfo/struct-style-enum.rs +++ b/tests/debuginfo/struct-style-enum.rs @@ -1,7 +1,6 @@ // Require a gdb or lldb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 -//@ needs-rust-lldb - +//@ min-lldb-version: 1800 //@ compile-flags:-g // === GDB TESTS =================================================================================== @@ -27,15 +26,19 @@ // lldb-command:run // lldb-command:v case1 +// lldbg-check:(struct_style_enum::Regular) case1 = { value = { a = 0 b = 31868 c = 31868 d = 31868 e = 31868 } $discr$ = 0 } // lldbr-check:(struct_style_enum::Regular::Case1) case1 = { a = 0 b = 31868 c = 31868 d = 31868 e = 31868 } // lldb-command:v case2 +// lldbg-check:(struct_style_enum::Regular) case2 = { value = { a = 0 b = 286331153 c = 286331153 } $discr$ = 1 } // lldbr-check:(struct_style_enum::Regular::Case2) case2 = Case2 { Case1: 0, Case2: 286331153, Case3: 286331153 } // lldb-command:v case3 +// lldbg-check:(struct_style_enum::Regular) case3 = { value = { a = 0 b = 6438275382588823897 } $discr$ = 2 } // lldbr-check:(struct_style_enum::Regular::Case3) case3 = Case3 { Case1: 0, Case2: 6438275382588823897 } // lldb-command:v univariant +// lldbg-check:(struct_style_enum::Univariant) univariant = { value = { a = -1 } } // lldbr-check:(struct_style_enum::Univariant) univariant = Univariant { TheOnlyCase: TheOnlyCase { a: -1 } } #![allow(unused_variables)] diff --git a/tests/debuginfo/tuple-style-enum.rs b/tests/debuginfo/tuple-style-enum.rs index 883aa658eb2c7..3de4ecb128494 100644 --- a/tests/debuginfo/tuple-style-enum.rs +++ b/tests/debuginfo/tuple-style-enum.rs @@ -1,6 +1,6 @@ // Require a gdb or lldb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 -//@ needs-rust-lldb +//@ min-lldb-version: 1800 //@ compile-flags:-g @@ -27,15 +27,19 @@ // lldb-command:run // lldb-command:v case1 +// lldbg-check:(tuple_style_enum::Regular) case1 = { value = { 0 = 0 1 = 31868 2 = 31868 3 = 31868 4 = 31868 } $discr$ = 0 } // lldbr-check:(tuple_style_enum::Regular::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 } // lldb-command:v case2 +// lldbg-check:(tuple_style_enum::Regular) case2 = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 } // lldbr-check:(tuple_style_enum::Regular::Case2) case2 = Case2 { Case1: 0, Case2: 286331153, Case3: 286331153 } // lldb-command:v case3 +// lldbg-check:(tuple_style_enum::Regular) case3 = { value = { 0 = 0 1 = 6438275382588823897 } $discr$ = 2 } // lldbr-check:(tuple_style_enum::Regular::Case3) case3 = Case3 { Case1: 0, Case2: 6438275382588823897 } // lldb-command:v univariant +// lldbg-check:(tuple_style_enum::Univariant) univariant = { value = { 0 = -1 } } // lldbr-check:(tuple_style_enum::Univariant) univariant = { TheOnlyCase = { = -1 } } #![allow(unused_variables)] diff --git a/tests/debuginfo/unique-enum.rs b/tests/debuginfo/unique-enum.rs index b3879468e0a98..514c7c50812c6 100644 --- a/tests/debuginfo/unique-enum.rs +++ b/tests/debuginfo/unique-enum.rs @@ -1,6 +1,6 @@ // Require a gdb or lldb that can read DW_TAG_variant_part. //@ min-gdb-version: 8.2 -//@ needs-rust-lldb +//@ min-lldb-version: 1800 //@ compile-flags:-g @@ -23,12 +23,15 @@ // lldb-command:run // lldb-command:v *the_a +// lldbg-check:(unique_enum::ABC) *the_a = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 } // lldbr-check:(unique_enum::ABC::TheA) *the_a = TheA { TheA: 0, TheB: 8970181431921507452 } // lldb-command:v *the_b +// lldbg-check:(unique_enum::ABC) *the_b = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 } // lldbr-check:(unique_enum::ABC::TheB) *the_b = { = 0 = 286331153 = 286331153 } // lldb-command:v *univariant +// lldbg-check:(unique_enum::Univariant) *univariant = { value = { 0 = 123234 } } // lldbr-check:(unique_enum::Univariant) *univariant = { TheOnlyCase = { = 123234 } } #![allow(unused_variables)] From cdf3f3c2024f8634b93ad80ea6f9915c12276d51 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 18:56:02 +0200 Subject: [PATCH 61/72] only show the 'basic API common for this target' message when this is a missing foreign function --- src/tools/miri/src/diagnostics.rs | 13 ++++++++++--- src/tools/miri/src/helpers.rs | 10 ++++------ src/tools/miri/src/shims/foreign_items.rs | 4 ++-- .../miri/src/shims/unix/linux/foreign_items.rs | 4 +++- .../tests/extern-so/fail/function_not_in_so.stderr | 4 ++-- .../tests/fail-dep/shims/fs/close_stdout.stderr | 1 - .../tests/fail-dep/shims/fs/read_from_stdout.stderr | 1 - .../tests/fail-dep/shims/fs/write_to_stdin.stderr | 1 - src/tools/miri/tests/fail-dep/tokio/sleep.stderr | 1 - .../fail-dep/unsupported_incomplete_function.stderr | 4 ++-- .../tests/fail/alloc/no_global_allocator.stderr | 4 ++-- .../miri/tests/fail/extern-type-field-offset.stderr | 1 - src/tools/miri/tests/fail/extern_static.stderr | 1 - .../miri/tests/fail/extern_static_in_const.stderr | 1 - .../miri/tests/fail/extern_static_wrong_size.stderr | 1 - .../abi_mismatch_array_vs_struct.stderr | 2 +- .../abi_mismatch_int_vs_float.stderr | 2 +- .../abi_mismatch_raw_pointer.stderr | 2 +- .../function_pointers/abi_mismatch_repr_C.stderr | 2 +- .../abi_mismatch_return_type.stderr | 2 +- .../function_pointers/abi_mismatch_simple.stderr | 2 +- .../function_pointers/abi_mismatch_vector.stderr | 2 +- .../tests/fail/intrinsic_fallback_checks_ub.stderr | 1 - ...3288-ice-symbolic-alignment-extern-static.stderr | 1 - .../fail/shims/backtrace/bad-backtrace-flags.stderr | 1 - .../backtrace/bad-backtrace-resolve-flags.stderr | 1 - .../bad-backtrace-resolve-names-flags.stderr | 1 - .../shims/backtrace/bad-backtrace-size-flags.stderr | 1 - .../promise_alignment.call_unaligned_ptr.stderr | 1 - .../promise_alignment_zero.stderr | 1 - src/tools/miri/tests/fail/unsized-local.stderr | 1 - .../tests/fail/unsupported_foreign_function.stderr | 4 ++-- 32 files changed, 34 insertions(+), 44 deletions(-) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 5fac922f56833..cb5ed27b6cf18 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -48,6 +48,7 @@ pub enum TerminationInfo { extra: Option<&'static str>, retag_explain: bool, }, + UnsupportedForeignItem(String), } pub struct RacingOp { @@ -85,6 +86,7 @@ impl fmt::Display for TerminationInfo { op2.action, op2.thread_info ), + UnsupportedForeignItem(msg) => write!(f, "{msg}"), } } } @@ -214,7 +216,7 @@ pub fn report_error<'tcx, 'mir>( let title = match info { Exit { code, leak_check } => return Some((*code, *leak_check)), Abort(_) => Some("abnormal termination"), - UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance => + UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance | UnsupportedForeignItem(_) => Some("unsupported operation"), StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } => Some("Undefined Behavior"), @@ -228,6 +230,12 @@ pub fn report_error<'tcx, 'mir>( (None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")), (None, format!("or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning")), ], + UnsupportedForeignItem(_) => { + vec![ + (None, format!("if this is a basic API commonly used on this target, please report an issue with Miri")), + (None, format!("however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases")), + ] + } StackedBorrowsUb { help, history, .. } => { msg.extend(help.clone()); let mut helps = vec![ @@ -322,7 +330,6 @@ pub fn report_error<'tcx, 'mir>( Unsupported(_) => vec![ (None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support")), - (None, format!("if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there")), ], UndefinedBehavior(AlignmentCheckFailed { .. }) if ecx.machine.check_alignment == AlignmentCheck::Symbolic @@ -347,7 +354,7 @@ pub fn report_error<'tcx, 'mir>( } AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => { helps.push((None, format!("this means these two types are not *guaranteed* to be ABI-compatible across all targets"))); - helps.push((None, format!("if you think this code should be accepted anyway, please report an issue"))); + helps.push((None, format!("if you think this code should be accepted anyway, please report an issue with Miri"))); } _ => {}, } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 92bdaf301704b..f81e997efd886 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1067,20 +1067,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { crate_name == "std" || crate_name == "std_miri_test" } - /// Handler that should be called when unsupported functionality is encountered. + /// Handler that should be called when an unsupported foreign item is encountered. /// This function will either panic within the context of the emulated application /// or return an error in the Miri process context - /// - /// Return value of `Ok(bool)` indicates whether execution should continue. - fn handle_unsupported>(&mut self, error_msg: S) -> InterpResult<'tcx, ()> { + fn handle_unsupported_foreign_item(&mut self, error_msg: String) -> InterpResult<'tcx, ()> { let this = self.eval_context_mut(); if this.machine.panic_on_unsupported { // message is slightly different here to make automated analysis easier - let error_msg = format!("unsupported Miri functionality: {}", error_msg.as_ref()); + let error_msg = format!("unsupported Miri functionality: {error_msg}"); this.start_panic(error_msg.as_ref(), mir::UnwindAction::Continue)?; Ok(()) } else { - throw_unsup_format!("{}", error_msg.as_ref()); + throw_machine_stop!(TerminationInfo::UnsupportedForeignItem(error_msg)); } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4f8bb801100c1..7c97d597ae463 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -119,7 +119,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if let Some(body) = this.lookup_exported_symbol(link_name)? { return Ok(Some(body)); } - this.handle_unsupported(format!( + this.handle_unsupported_foreign_item(format!( "can't call (diverging) foreign function: {link_name}" ))?; return Ok(None); @@ -140,7 +140,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(Some(body)); } - this.handle_unsupported(format!( + this.handle_unsupported_foreign_item(format!( "can't call foreign function `{link_name}` on OS `{os}`", os = this.tcx.sess.target.os, ))?; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index a72ca510b4b2f..9d1deb3201cb0 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -144,7 +144,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { futex(this, &args[1..], dest)?; } id => { - this.handle_unsupported(format!("can't execute syscall with ID {id}"))?; + this.handle_unsupported_foreign_item(format!( + "can't execute syscall with ID {id}" + ))?; return Ok(EmulateForeignItemResult::AlreadyJumped); } } diff --git a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr index 26761c48721df..e905d7d039143 100644 --- a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr +++ b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr @@ -4,8 +4,8 @@ error: unsupported operation: can't call foreign function `foo` on $OS LL | foo(); | ^^^^^ can't call foreign function `foo` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there + = help: if this is a basic API commonly used on this target, please report an issue with Miri + = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases = note: BACKTRACE: = note: inside `main` at $DIR/function_not_in_so.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr index e50480157657b..e1b1b053bbc65 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr @@ -5,7 +5,6 @@ LL | libc::close(1); | ^^^^^^^^^^^^^^ cannot close stdout | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/close_stdout.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr index fb0fb8acc3f11..baa6eb5ad6a09 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr @@ -5,7 +5,6 @@ LL | libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot read from stdout | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/read_from_stdout.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr index 8426c5cb84732..37323faf560df 100644 --- a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr +++ b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr @@ -5,7 +5,6 @@ LL | libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot write to stdin | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/write_to_stdin.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/tokio/sleep.stderr b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr index f7d829f77d2bd..4b12729bbff9c 100644 --- a/src/tools/miri/tests/fail-dep/tokio/sleep.stderr +++ b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr @@ -10,7 +10,6 @@ LL | | )) | |__________^ returning ready events from epoll_wait is not yet implemented | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr index 23327ff7dbd57..f62622e29bf13 100644 --- a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr +++ b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr @@ -4,8 +4,8 @@ error: unsupported operation: can't call foreign function `signal` on $OS LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there + = help: if this is a basic API commonly used on this target, please report an issue with Miri + = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases = note: BACKTRACE: = note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC diff --git a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr index 70f60a3f591f6..82bcb48cbe6ac 100644 --- a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr +++ b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr @@ -4,8 +4,8 @@ error: unsupported operation: can't call foreign function `__rust_alloc` on $OS LL | __rust_alloc(1, 1); | ^^^^^^^^^^^^^^^^^^ can't call foreign function `__rust_alloc` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there + = help: if this is a basic API commonly used on this target, please report an issue with Miri + = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases = note: BACKTRACE: = note: inside `start` at $DIR/no_global_allocator.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr index 14609ec699cea..e0d6e9ebf1de7 100644 --- a/src/tools/miri/tests/fail/extern-type-field-offset.stderr +++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr @@ -5,7 +5,6 @@ LL | let _field = &x.a; | ^^^^ `extern type` does not have a known offset | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static.stderr b/src/tools/miri/tests/fail/extern_static.stderr index 1d12fd76bedb7..21759f9601904 100644 --- a/src/tools/miri/tests/fail/extern_static.stderr +++ b/src/tools/miri/tests/fail/extern_static.stderr @@ -5,7 +5,6 @@ LL | let _val = unsafe { std::ptr::addr_of!(FOO) }; | ^^^ extern static `FOO` is not supported by Miri | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static_in_const.stderr b/src/tools/miri/tests/fail/extern_static_in_const.stderr index 455d6af18e417..aa524c064694e 100644 --- a/src/tools/miri/tests/fail/extern_static_in_const.stderr +++ b/src/tools/miri/tests/fail/extern_static_in_const.stderr @@ -5,7 +5,6 @@ LL | let _val = X; | ^ extern static `E` is not supported by Miri | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static_in_const.rs:LL:CC diff --git a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr index 91afb936facb9..3c013a5d15d05 100644 --- a/src/tools/miri/tests/fail/extern_static_wrong_size.stderr +++ b/src/tools/miri/tests/fail/extern_static_wrong_size.stderr @@ -5,7 +5,6 @@ LL | let _val = unsafe { environ }; | ^^^^^^^ extern static `environ` has been declared as `extern_static_wrong_size::environ` with a size of 1 bytes and alignment of 1 bytes, but Miri emulates it via an extern static shim with a size of N bytes and alignment of N bytes | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/extern_static_wrong_size.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr index 595235088f6f2..2b2a898ce73bb 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr @@ -7,7 +7,7 @@ LL | g(Default::default()) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_array_vs_struct.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr index a8b1cf40c043c..752e17116d12f 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr @@ -7,7 +7,7 @@ LL | g(42) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_int_vs_float.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr index 60dd3814bf577..907a8e50c411d 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr @@ -7,7 +7,7 @@ LL | g(&42 as *const i32) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_raw_pointer.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr index 6d42bea9da998..eaacc32bf6880 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_repr_C.stderr @@ -7,7 +7,7 @@ LL | fnptr(S1(NonZeroI32::new(1).unwrap())); = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_repr_C.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr index 198896b0dd765..3793590f84237 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr @@ -7,7 +7,7 @@ LL | g() = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_return_type.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr index daf216a142c9c..0c533c14173da 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr @@ -7,7 +7,7 @@ LL | g(42) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_simple.rs:LL:CC diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr index 50f4474cc0e1c..ef4b60b83b1ff 100644 --- a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr +++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr @@ -7,7 +7,7 @@ LL | g(Default::default()) = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/abi_mismatch_vector.rs:LL:CC diff --git a/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr b/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr index 5dd6520fe42d4..699dda52096f3 100644 --- a/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr +++ b/src/tools/miri/tests/fail/intrinsic_fallback_checks_ub.stderr @@ -5,7 +5,6 @@ LL | ptr_guaranteed_cmp::<()>(std::ptr::null(), std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ miri can only use intrinsic fallback bodies that check UB. After verifying that `ptr_guaranteed_cmp` does so, add the `#[miri::intrinsic_fallback_checks_ub]` attribute to it; also ping @rust-lang/miri when you do that | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/intrinsic_fallback_checks_ub.rs:LL:CC diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr index 0d10b03fc4f4d..4064d7fe4e953 100644 --- a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr +++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr @@ -5,7 +5,6 @@ LL | let _val = *DISPATCH_QUEUE_CONCURRENT; | ^^^^^^^^^^^^^^^^^^^^^^^^^ extern static `_dispatch_queue_attr_concurrent` is not supported by Miri | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr index ced44ee776840..504485e3b3a41 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-flags.stderr @@ -5,7 +5,6 @@ LL | miri_get_backtrace(2, std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_get_backtrace` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr index 6e282ff4908aa..c1f0ce3d1a8c1 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-flags.stderr @@ -5,7 +5,6 @@ LL | miri_resolve_frame(buf[0], 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-resolve-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr index ddf8d221cc41f..fc270593e6369 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-resolve-names-flags.stderr @@ -5,7 +5,6 @@ LL | ... miri_resolve_frame_names(buf[0], 2, std::ptr::null_mut(), std::ptr::n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame_names` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr index b3186fc5b0769..2d70733334d85 100644 --- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr +++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-size-flags.stderr @@ -5,7 +5,6 @@ LL | miri_backtrace_size(2); | ^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_backtrace_size` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/bad-backtrace-size-flags.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr index 9ad715f7ba4ae..6d62db4d3d556 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr @@ -5,7 +5,6 @@ LL | unsafe { utils::miri_promise_symbolic_alignment(align8.add(1).cast( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: pointer is not actually aligned | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/promise_alignment.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr index 62b6e85231107..3f7ced0b407df 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment_zero.stderr @@ -5,7 +5,6 @@ LL | unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/promise_alignment_zero.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unsized-local.stderr b/src/tools/miri/tests/fail/unsized-local.stderr index d938f36bd5ec7..df54c98bb0e11 100644 --- a/src/tools/miri/tests/fail/unsized-local.stderr +++ b/src/tools/miri/tests/fail/unsized-local.stderr @@ -5,7 +5,6 @@ LL | let x = *(Box::new(A) as Box); | ^ unsized locals are not supported | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there = note: BACKTRACE: = note: inside `main` at $DIR/unsized-local.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr index 7492fdd77bbac..f392e9564c751 100644 --- a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr @@ -4,8 +4,8 @@ error: unsupported operation: can't call foreign function `foo` on $OS LL | foo(); | ^^^^^ can't call foreign function `foo` on $OS | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = help: if this is a basic API commonly used on this target, please report an issue; but note that Miri does not aim to support every FFI function out there + = help: if this is a basic API commonly used on this target, please report an issue with Miri + = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases = note: BACKTRACE: = note: inside `main` at $DIR/unsupported_foreign_function.rs:LL:CC From 94f922ab58375c0929c9550ed4f6bc86185bf31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 4 May 2024 21:58:57 +0200 Subject: [PATCH 62/72] Meta: Enable the triagebot transfer command --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 499ba6e470cda..2b149331def49 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1057,3 +1057,7 @@ project-exploit-mitigations = [ # Enable tracking of PR review assignment # Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html [pr-tracking] + +# Enable issue transfers within the org +# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html +[transfer] From 89e828889a8c572294f069e1773b4b308030f0c8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 22:28:57 +0200 Subject: [PATCH 63/72] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 038c2549b66de..ca6f4d50917e9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -d7ea27808deb5e10a0f7384e339e4e6165e33398 +d568423a7a4ddb4b49323d96078a22f94df55fbd From ef5a574af48d9300c2e44674f2187c6d7d6d951a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 22:44:56 +0200 Subject: [PATCH 64/72] rustc_pull: explain order of operations --- src/tools/miri/miri-script/src/commands.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 7e34ad050b319..6d07455c0deb6 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -239,6 +239,8 @@ impl Command { // the merge has confused the heck out of josh in the past. // We pass `--no-verify` to avoid running git hooks like `./miri fmt` that could in turn // trigger auto-actions. + // We do this before the merge so that if there are merge conflicts, we have + // the right rust-version file while resolving them. sh.write_file("rust-version", format!("{commit}\n"))?; const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc"; cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}") From 85e061af8f5fdee70627515998721be38c9d8e3c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 22:48:02 +0200 Subject: [PATCH 65/72] fix/extend some comments --- src/tools/miri/src/intrinsics/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 82b6c3d106d92..effd7f6d5435f 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -91,6 +91,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } match intrinsic_name { + // Basic control flow "abort" => { throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() @@ -98,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } "catch_unwind" => { this.handle_catch_unwind(args, dest, ret)?; - // THis pushed a stack frame, don't jump to `ret`. + // This pushed a stack frame, don't jump to `ret`. return Ok(EmulateItemResult::AlreadyJumped); } From 745e3f224cb779f46c814eceb246839e01eaea57 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 22:50:46 +0200 Subject: [PATCH 66/72] make ExitProcess Windows-only --- src/tools/miri/src/shims/foreign_items.rs | 10 ++-------- src/tools/miri/src/shims/windows/foreign_items.rs | 6 ++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 954405de863c1..c51a27b7458a8 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -405,14 +405,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Aborting the process. - "exit" | "ExitProcess" => { - let exp_abi = if link_name.as_str() == "exit" { - Abi::C { unwind: false } - } else { - Abi::System { unwind: false } - }; - let [code] = this.check_shim(abi, exp_abi, link_name, args)?; - // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway + "exit" => { + let [code] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 92676e1b99b17..dba5b7a906f91 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -506,6 +506,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Miscellaneous + "ExitProcess" => { + let [code] = + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let code = this.read_scalar(code)?.to_u32()?; + throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); + } "SystemFunction036" => { // This is really 'RtlGenRandom'. let [ptr, len] = From 7ba814442a6fbad12c658fff3371a5c6689f04e0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 May 2024 23:19:12 +0200 Subject: [PATCH 67/72] Implement `edition` method on `Rustdoc` type as well --- src/tools/run-make-support/src/rustdoc.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index c2c4f2e68e2f8..6733925b74d03 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -93,6 +93,13 @@ impl Rustdoc { } } + /// Specify the edition year. + pub fn edition(&mut self, edition: &str) -> &mut Self { + self.cmd.arg("--edition"); + self.cmd.arg(edition); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); From a64ba04f94fb3cd2d40a3e64a5de81af7d2f7e98 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 May 2024 16:18:36 +0200 Subject: [PATCH 68/72] Migrate `run-make/doctests-runtool` to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/doctests-runtool/Makefile | 20 ---------- tests/run-make/doctests-runtool/rmake.rs | 39 +++++++++++++++++++ 3 files changed, 39 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/doctests-runtool/Makefile create mode 100644 tests/run-make/doctests-runtool/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a56ea8df6ccb5..2af1cb71f5dfb 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -44,7 +44,6 @@ run-make/dep-graph/Makefile run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile -run-make/doctests-runtool/Makefile run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile run-make/duplicate-output-flavors/Makefile diff --git a/tests/run-make/doctests-runtool/Makefile b/tests/run-make/doctests-runtool/Makefile deleted file mode 100644 index 7d5df1e307fb8..0000000000000 --- a/tests/run-make/doctests-runtool/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Tests behavior of rustdoc --runtool - -MY_SRC_DIR := ${CURDIR} - -all: with_test_run_directory - -# Behavior with --runtool with relative paths and --test-run-directory. -with_test_run_directory: - mkdir -p $(TMPDIR)/rundir - mkdir -p $(TMPDIR)/runtool - $(RUSTC) --crate-type rlib t.rs - $(RUSTC) runtool.rs -o $(TMPDIR)/runtool/runtool - ( cd $(TMPDIR); \ - $(RUSTDOC) -Zunstable-options --test --test-run-directory rundir \ - --runtool runtool/runtool --extern t=libt.rlib $(MY_SRC_DIR)/t.rs \ - ) - rm -rf $(TMPDIR)/rundir $(TMPDIR)/runtool diff --git a/tests/run-make/doctests-runtool/rmake.rs b/tests/run-make/doctests-runtool/rmake.rs new file mode 100644 index 0000000000000..164514095289e --- /dev/null +++ b/tests/run-make/doctests-runtool/rmake.rs @@ -0,0 +1,39 @@ +// Tests behavior of rustdoc `--runtool`. + +use run_make_support::{rustc, rustdoc, tmp_dir}; +use std::env::current_dir; +use std::fs::{create_dir, remove_dir_all}; +use std::path::PathBuf; + +fn mkdir(name: &str) -> PathBuf { + let dir = tmp_dir().join(name); + create_dir(&dir).expect("failed to create doctests folder"); + dir +} + +// Behavior with --runtool with relative paths and --test-run-directory. +fn main() { + let run_dir_name = "rundir"; + let run_dir = mkdir(run_dir_name); + let run_tool = mkdir("runtool"); + let run_tool_binary = run_tool.join("runtool"); + + rustc().input("t.rs").crate_type("rlib").run(); + rustc().input("runtool.rs").arg("-o").arg(&run_tool_binary).run(); + + rustdoc() + .input(current_dir().unwrap().join("t.rs")) + .arg("-Zunstable-options") + .arg("--test") + .arg("--test-run-directory") + .arg(run_dir_name) + .arg("--runtool") + .arg(&run_tool_binary) + .arg("--extern") + .arg("t=libt.rlib") + .current_dir(tmp_dir()) + .run(); + + remove_dir_all(run_dir); + remove_dir_all(run_tool); +} From b5051c557429308de7afbacec4b6204225bc339d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 May 2024 23:19:21 +0200 Subject: [PATCH 69/72] update lockfile --- Cargo.lock | 88 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c034cbae9912b..e363608a436e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -512,6 +512,28 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "chrono-tz" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf 0.11.2", +] + +[[package]] +name = "chrono-tz-build" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" +dependencies = [ + "parse-zoneinfo", + "phf 0.11.2", + "phf_codegen 0.11.2", +] + [[package]] name = "cipher" version = "0.4.4" @@ -2318,8 +2340,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf", - "phf_codegen", + "phf 0.10.1", + "phf_codegen 0.10.0", "string_cache", "string_cache_codegen", "tendril", @@ -2480,6 +2502,7 @@ version = "0.1.0" dependencies = [ "aes", "chrono", + "chrono-tz", "colored", "ctrlc", "directories", @@ -2835,6 +2858,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +dependencies = [ + "regex", +] + [[package]] name = "pathdiff" version = "0.2.1" @@ -2907,7 +2939,16 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", ] [[package]] @@ -2916,8 +2957,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -2926,7 +2977,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", + "rand", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", "rand", ] @@ -2939,6 +3000,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -5285,7 +5355,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -5296,8 +5366,8 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro2", "quote", ] From e30ad6ff2c5c83823438a9a3d872a8c5da82807e Mon Sep 17 00:00:00 2001 From: Alex H Date: Sun, 14 Apr 2024 11:55:00 -0700 Subject: [PATCH 70/72] Tgross feedback tweaks Co-authored-by: Trevor Gross Update library/core/src/primitive_docs.rs Co-authored-by: Trevor Gross Update library/core/src/primitive_docs.rs --- library/core/src/primitive_docs.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 6b142c1a0cdf4..b1bc3ba111238 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1082,9 +1082,8 @@ impl (T,) {} /// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// half-precision values][wikipedia] for more information. /// -/// Note that not all major platforms have hardware support for f16, in which case a -/// software implementation will be used. This may be slower than expected. -/// +/// Note that most major platforms will provide `f16` math support by converting to and from +/// an `f32`, which is usually fairly performant but will not be as fast as using `f32` directly. /// *[See also the `std::f16::consts` module](crate::f16::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format @@ -1184,8 +1183,8 @@ mod prim_f64 {} /// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// quad-precision values][wikipedia] for more information. /// -/// Note that not all major platforms have hardware support for f128, in which case a -/// software implementation will be used. This may be slower than expected. +/// Note that most major platforms do not have hardware support for `f128`, in which case a +/// software implementation will be used. This can be significantly slower than using `f64`. /// /// *[See also the `std::f128::consts` module](crate::f128::consts).* /// From 3ef25288a4a68e4bdc03115cee9b259f33fa5b2d Mon Sep 17 00:00:00 2001 From: Alex H Date: Sun, 14 Apr 2024 23:17:44 -0700 Subject: [PATCH 71/72] Make f16 and f128 docs clearer on platform support Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> Update library/core/src/primitive_docs.rs Rewrite f16 and f128 hw support comments to match PR feedback I wrote RISC-V allcaps in all cases, and wrote amd64 lowercase in all cases, im not sure if either is the more correct way for either platform, thats just how I normally write them, if theres a precedent elsewhere it should probably be changed to match though. Update library/core/src/primitive_docs.rs Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> Update library/core/src/primitive_docs.rs Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> Update library/core/src/primitive_docs.rs --- library/core/src/primitive_docs.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index b1bc3ba111238..7fa119b5006ec 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1082,8 +1082,12 @@ impl (T,) {} /// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// half-precision values][wikipedia] for more information. /// -/// Note that most major platforms will provide `f16` math support by converting to and from -/// an `f32`, which is usually fairly performant but will not be as fast as using `f32` directly. +/// Note that most common platforms will not support `f16` in hardware without enabling extra target +/// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors. +/// Hardware support on x86-64 requires the avx512fp16 feature, while RISC-V requires Zhf. +/// Usually the fallback implementation will be to use `f32` hardware if it exists, and convert +/// between `f16` and `f32` when performing math. +/// /// *[See also the `std::f16::consts` module](crate::f16::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format @@ -1183,12 +1187,15 @@ mod prim_f64 {} /// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// quad-precision values][wikipedia] for more information. /// -/// Note that most major platforms do not have hardware support for `f128`, in which case a -/// software implementation will be used. This can be significantly slower than using `f64`. +/// Note that no platforms have hardware support for `f128` without enabling target specific features +/// (and [only some consumer level hardware has support][wikipedia-support], for example RISC-V has support, but +/// neither amd64 nor aarch64 has support), in which case a software implementation will be used. This can be +/// significantly slower than using `f64`. /// /// *[See also the `std::f128::consts` module](crate::f128::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format +/// [wikipedia-support]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Hardware_support #[unstable(feature = "f128", issue = "116909")] mod prim_f128 {} From 5aa2f9a208162389a743c45cebb72a994effca1c Mon Sep 17 00:00:00 2001 From: Alex H Date: Sat, 4 May 2024 12:54:34 -0700 Subject: [PATCH 72/72] Make f128 docs mention lack of any normal platform support Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> Update library/core/src/primitive_docs.rs Remove orphaned doc link and clean up grammar a bit Update library/core/src/primitive_docs.rs --- library/core/src/primitive_docs.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 7fa119b5006ec..cc369f1733fe1 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1187,15 +1187,15 @@ mod prim_f64 {} /// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// quad-precision values][wikipedia] for more information. /// -/// Note that no platforms have hardware support for `f128` without enabling target specific features -/// (and [only some consumer level hardware has support][wikipedia-support], for example RISC-V has support, but -/// neither amd64 nor aarch64 has support), in which case a software implementation will be used. This can be -/// significantly slower than using `f64`. +/// Note that no platforms have hardware support for `f128` without enabling target specific features, +/// as for all instruction set architectures `f128` is considered an optional feature. +/// Only Power ISA ("PowerPC") and RISCV specify it, and only certain microarchitectures +/// actually implement it. For x86-64 and AArch64, ISA support is not even specified, +/// so it will always be a software implementation significantly slower than `f64`. /// /// *[See also the `std::f128::consts` module](crate::f128::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format -/// [wikipedia-support]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Hardware_support #[unstable(feature = "f128", issue = "116909")] mod prim_f128 {}