diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2769a2c2749d..5364c1e9f466c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: - name: Checkout the source code uses: actions/checkout@v4 - name: Calculate the CI job matrix + env: + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT id: jobs job: @@ -75,14 +77,6 @@ jobs: matrix: # Check the `calculate_matrix` job to see how is the matrix defined. include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} - # GitHub Actions fails the workflow if an empty list of jobs is provided to - # the workflow, so we need to skip this job if nothing was produced by - # the Python script. - # - # Unfortunately checking whether a list is empty is not possible in a nice - # way due to GitHub Actions expressions limits. - # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 - if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null steps: - if: contains(matrix.os, 'windows') uses: msys2/setup-msys2@v2.22.0 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", ] 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 fe50499db767b..60b386acf9106 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. @@ -581,6 +579,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 13b6054586cd5..f9f766f832af7 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1101,6 +1101,32 @@ fn get_nullable_type<'tcx>( }) } +/// 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. +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(); + let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none()) + || (ty_def.is_enum() && ty_def.variants().is_empty()); + + !non_exhaustive && empty + } + 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`, @@ -1117,6 +1143,22 @@ 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]) => { + if !tcx.features().result_ffi_guarantees { + return None; + } + + 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, @@ -1202,7 +1244,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.. @@ -1329,27 +1370,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`. - if repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode) - .is_none() + // Special-case types like `Option` and `Result` + 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), }; } 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/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9c556f1152a5b..d41059e8c24a4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1511,6 +1511,7 @@ symbols! { require, residual, result, + result_ffi_guarantees, resume, return_position_impl_trait_in_trait, return_type_notation, 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/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 18a9503cfd2f5..d8597369b9bfd 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1133,6 +1133,12 @@ impl (T,) {} /// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on /// half-precision values][wikipedia] for more information. /// +/// 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 @@ -1232,6 +1238,12 @@ 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, +/// 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 diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs index 3f3615ea3e0a4..ff88ef4e0e1d0 100644 --- a/library/std/src/sys/personality/dwarf/eh.rs +++ b/library/std/src/sys/personality/dwarf/eh.rs @@ -54,7 +54,14 @@ pub enum EHAction { Terminate, } -pub const USING_SJLJ_EXCEPTIONS: bool = cfg!(all(target_os = "ios", target_arch = "arm")); +/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS. +/// +/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM +/// devices. +/// +/// +pub const USING_SJLJ_EXCEPTIONS: bool = + cfg!(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm")); pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result { if lsda.is_null() { diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index b0f744dd96605..0dc53550ca943 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -92,11 +92,12 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c cfg_if::cfg_if! { - if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "visionos"), not(target_os = "netbsd")))] { + if #[cfg(all(not(all(target_vendor = "apple", not(target_os = "watchos"))), target_arch = "arm", not(target_os = "netbsd")))] { // ARM EHABI personality routine. // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf // - // iOS uses the default routine instead since it uses SjLj unwinding. + // Apple 32-bit ARM (but not watchOS) uses the default routine instead + // since it uses SjLj unwinding. #[lang = "eh_personality"] unsafe extern "C" fn rust_eh_personality( state: uw::_Unwind_State, diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index e34e73a351637..e5e28f32e4dbf 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -33,10 +33,10 @@ pub const unwinder_private_data_size: usize = 2; #[cfg(all(target_arch = "x86_64", target_os = "windows"))] pub const unwinder_private_data_size: usize = 6; -#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))] +#[cfg(all(target_arch = "arm", not(all(target_vendor = "apple", not(target_os = "watchos")))))] pub const unwinder_private_data_size: usize = 20; -#[cfg(all(target_arch = "arm", any(target_os = "ios", target_os = "watchos")))] +#[cfg(all(target_arch = "arm", all(target_vendor = "apple", not(target_os = "watchos"))))] pub const unwinder_private_data_size: usize = 5; #[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))] @@ -123,7 +123,7 @@ extern "C" { } cfg_if::cfg_if! { -if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos", target_os = "netbsd", not(target_arch = "arm")))] { +if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os = "netbsd", not(target_arch = "arm")))] { // Not ARM EHABI #[repr(C)] #[derive(Copy, Clone, PartialEq)] @@ -258,8 +258,15 @@ if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", targe } // cfg_if! cfg_if::cfg_if! { -if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { - // Not 32-bit iOS +if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] { + // 32-bit ARM Apple (except for watchOS) uses SjLj and does not provide + // _Unwind_Backtrace() + extern "C-unwind" { + pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; + } + + pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; +} else { #[cfg_attr( all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), link(name = "unwind", kind = "static", modifiers = "-bundle") @@ -276,13 +283,6 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { trace_argument: *mut c_void) -> _Unwind_Reason_Code; } -} else { - // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace() - extern "C-unwind" { - pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; - } - - pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; } } // cfg_if! diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index 68565f489c939..4f9bc39a628ce 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -8,10 +8,11 @@ and filters them based on the event that happened on CI. """ import dataclasses -import enum import json import logging import os +import re +import typing from pathlib import Path from typing import List, Dict, Any, Optional @@ -44,10 +45,22 @@ def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]: return jobs -class WorkflowRunType(enum.Enum): - PR = enum.auto() - Try = enum.auto() - Auto = enum.auto() +@dataclasses.dataclass +class PRRunType: + pass + + +@dataclasses.dataclass +class TryRunType: + custom_jobs: List[str] + + +@dataclasses.dataclass +class AutoRunType: + pass + + +WorkflowRunType = typing.Union[PRRunType, TryRunType, AutoRunType] @dataclasses.dataclass @@ -55,11 +68,28 @@ class GitHubCtx: event_name: str ref: str repository: str + commit_message: Optional[str] + + +def get_custom_jobs(ctx: GitHubCtx) -> List[str]: + """ + Tries to parse names of specific CI jobs that should be executed in the form of + try-job: + from the commit message of the passed GitHub context. + """ + if ctx.commit_message is None: + return [] + + regex = re.compile(r"^try-job: (.*)", re.MULTILINE) + jobs = [] + for match in regex.finditer(ctx.commit_message): + jobs.append(match.group(1)) + return jobs def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: if ctx.event_name == "pull_request": - return WorkflowRunType.PR + return PRRunType() elif ctx.event_name == "push": old_bors_try_build = ( ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and @@ -72,20 +102,41 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: try_build = old_bors_try_build or new_bors_try_build if try_build: - return WorkflowRunType.Try + jobs = get_custom_jobs(ctx) + return TryRunType(custom_jobs=jobs) if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust": - return WorkflowRunType.Auto + return AutoRunType() return None def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[Job]: - if run_type == WorkflowRunType.PR: + if isinstance(run_type, PRRunType): return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"]) - elif run_type == WorkflowRunType.Try: - return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"]) - elif run_type == WorkflowRunType.Auto: + elif isinstance(run_type, TryRunType): + jobs = job_data["try"] + custom_jobs = run_type.custom_jobs + if custom_jobs: + if len(custom_jobs) > 10: + raise Exception( + f"It is only possible to schedule up to 10 custom jobs, " + f"received {len(custom_jobs)} jobs" + ) + + jobs = [] + unknown_jobs = [] + for custom_job in custom_jobs: + job = [j for j in job_data["auto"] if j["image"] == custom_job] + if not job: + unknown_jobs.append(custom_job) + continue + jobs.append(job[0]) + if unknown_jobs: + raise Exception(f"Custom job(s) `{unknown_jobs}` not found in auto jobs") + + return add_base_env(name_jobs(jobs, "try"), job_data["envs"]["try"]) + elif isinstance(run_type, AutoRunType): return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"]) return [] @@ -99,19 +150,25 @@ def skip_jobs(jobs: List[Dict[str, Any]], channel: str) -> List[Job]: def get_github_ctx() -> GitHubCtx: + event_name = os.environ["GITHUB_EVENT_NAME"] + + commit_message = None + if event_name == "push": + commit_message = os.environ["COMMIT_MESSAGE"] return GitHubCtx( - event_name=os.environ["GITHUB_EVENT_NAME"], + event_name=event_name, ref=os.environ["GITHUB_REF"], - repository=os.environ["GITHUB_REPOSITORY"] + repository=os.environ["GITHUB_REPOSITORY"], + commit_message=commit_message ) def format_run_type(run_type: WorkflowRunType) -> str: - if run_type == WorkflowRunType.PR: + if isinstance(run_type, PRRunType): return "pr" - elif run_type == WorkflowRunType.Auto: + elif isinstance(run_type, AutoRunType): return "auto" - elif run_type == WorkflowRunType.Try: + elif isinstance(run_type, TryRunType): return "try" else: raise AssertionError() @@ -135,6 +192,10 @@ def format_run_type(run_type: WorkflowRunType) -> str: if run_type is not None: jobs = calculate_jobs(run_type, data) jobs = skip_jobs(jobs, channel) + + if not jobs: + raise Exception("Scheduled job list is empty, this is an error") + run_type = format_run_type(run_type) logging.info(f"Output:\n{yaml.dump(dict(jobs=jobs, run_type=run_type), indent=4)}") 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/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/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/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!(), | ^^^^^^^ diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 0af334a654b40..3bc4163ab5246 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 . @@ -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 @@ -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 @@ -95,7 +101,7 @@ jobs: # over time). - name: Add cache for cargo id: cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | # Taken from . @@ -111,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 diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 293b937a5e52b..6960c1661c5e8 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,12 +547,12 @@ version = "0.1.0" dependencies = [ "aes", "chrono", + "chrono-tz", "colored", "ctrlc", "directories", "getrandom", "jemalloc-sys", - "lazy_static", "libc", "libffi", "libloading", @@ -690,6 +650,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 +668,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 +938,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 +1107,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 +1129,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 ac8b4b37e9200..976bd080867eb 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/README.md b/src/tools/miri/README.md index ef01ca25fb0b4..f92cc088e0f0c 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 @@ -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, 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); } diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index b774ca8fa7252..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. @@ -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()); diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index c1ffb80783ef6..d3dee0de617fe 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 @@ -71,10 +62,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 @@ -117,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 } @@ -135,23 +125,11 @@ 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 MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests - # Extra tier 2 - MIRI_TEST_TARGET=aarch64-apple-darwin run_tests - MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests - # 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 - 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 ;; aarch64-apple-darwin) # Host (tier 2) @@ -160,13 +138,25 @@ case $HOST_TARGET in 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 + 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) + 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 ;; 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 + # 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.) + 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 66707dee5e75e..6d07455c0deb6 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, flags } => Self::run(dep, 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()), @@ -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}") @@ -257,12 +259,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(()) } @@ -353,43 +369,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"); @@ -481,7 +460,12 @@ impl Command { Ok(()) } - fn run(dep: 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 @@ -508,26 +492,49 @@ 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()); - // 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; - 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()?; + let quiet_flag = if verbose { None } else { Some("--quiet") }; + // 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()?) + }; + // 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 { - cmd!( - e.sh, - "cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {flags...}" - ).quiet().run()?; + 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 712180be2825a..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 { @@ -38,6 +38,8 @@ pub enum Command { /// (Also respects MIRIFLAGS environment variable.) Run { dep: bool, + verbose: bool, + many_seeds: Option>, /// Flags that are passed through to `miri`. flags: Vec, }, @@ -54,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. @@ -90,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] : +./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`. @@ -110,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. @@ -132,10 +125,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,18 +155,39 @@ 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; + 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, 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") => { @@ -187,17 +201,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`"); } 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(()) + }) + } } diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index a45ecda15c4c0..ca6f4d50917e9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6acb9e75ebc936df737381a9d0b7a7bccd6f0b2f +d568423a7a4ddb4b49323d96078a22f94df55fbd 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) } 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()); diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 9fa786332e3cd..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![ @@ -320,7 +328,9 @@ 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")), + ], UndefinedBehavior(AlignmentCheckFailed { .. }) if ecx.machine.check_alignment == AlignmentCheck::Symbolic => @@ -344,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/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 94% rename from src/tools/miri/src/shims/intrinsics/mod.rs rename to src/tools/miri/src/intrinsics/mod.rs index 974943432aa59..effd7f6d5435f 100644 --- a/src/tools/miri/src/shims/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); } @@ -193,12 +194,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 +239,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 +367,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 +377,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 +387,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 +397,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/intrinsics/simd.rs similarity index 99% rename from src/tools/miri/src/shims/intrinsics/simd.rs rename to src/tools/miri/src/intrinsics/simd.rs index c7de587443a42..3be98d7f5f864 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -100,14 +100,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(), diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 3b1d7687d0267..1680b98eca33f 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,14 +96,14 @@ pub use rustc_const_eval::interpret::*; #[doc(no_inline)] pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _}; -pub use crate::shims::EmulateItemResult; +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 _; pub use crate::shims::tls::TlsData; +pub use crate::shims::EmulateItemResult; pub use crate::alloc_addresses::{EvalContextExt as _, ProvenanceMode}; pub use crate::borrow_tracker::stacked_borrows::{ diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index fc0160fdf2117..695d1138756ca 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_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::Windows(vars) => vars.get(name), + } + } +} diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 442338a6117d8..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], @@ -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" @@ -44,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); @@ -58,12 +74,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 8a38c6c11a831..c51a27b7458a8 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -93,7 +93,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, ))?; @@ -104,6 +104,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, @@ -396,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 }); } @@ -702,7 +705,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(), @@ -733,7 +736,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(), @@ -759,7 +762,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(), @@ -790,7 +793,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(), @@ -820,7 +823,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]); @@ -831,7 +834,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]); @@ -865,36 +868,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") => { @@ -918,6 +891,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") => @@ -926,6 +900,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 _ => diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 975efe29b4bd7..11048459206bf 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/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index dfdf58470d63a..8d1f07f916c9b 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_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, + }; + // 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/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); } _ => { diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 128f0dcafa942..9082d13da8404 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -70,6 +70,41 @@ impl<'tcx> UnixEnvVars<'tcx> { pub(crate) fn environ(&self) -> Pointer> { self.environ.ptr() } + + fn get_ptr<'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, + )?; + 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>( @@ -116,19 +151,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_ptr(this, name)?; + Ok(var_ptr.unwrap_or_else(Pointer::null)) } fn setenv( diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index a5fe38b902de8..e536b78d1c0bc 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,9 +14,10 @@ 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; + /// Reads as much as possible into the given buffer, and returns the number of bytes read. fn read<'tcx>( &mut self, _communicate_allowed: bool, @@ -24,8 +27,9 @@ pub trait FileDescriptor: 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>( - &self, + &mut self, _communicate_allowed: bool, _bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -33,6 +37,8 @@ pub trait FileDescriptor: 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, @@ -44,13 +50,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 +61,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 +73,7 @@ impl dyn FileDescriptor { } } -impl FileDescriptor for io::Stdin { +impl FileDescription for io::Stdin { fn name(&self) -> &'static str { "stdin" } @@ -88,28 +91,24 @@ 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" } 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 @@ -120,22 +119,18 @@ 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" } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -145,10 +140,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,13 +149,13 @@ 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" } fn write<'tcx>( - &self, + &mut self, _communicate_allowed: bool, bytes: &[u8], _tcx: TyCtxt<'tcx>, @@ -172,16 +163,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 +197,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 +240,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(&self, fd: i32) -> Option> { + let fd = self.fds.get(&fd)?; + Some(RefMut::map(fd.0.borrow_mut(), |fd| fd.as_mut())) } - pub fn get_mut(&mut self, fd: i32) -> Option<&mut dyn FileDescriptor> { - Some(&mut **self.fds.get_mut(&fd)?) + pub fn dup(&self, fd: i32) -> Option { + let fd = self.fds.get(&fd)?; + Some(fd.clone()) } - pub fn remove(&mut self, fd: i32) -> Option> { + pub fn remove(&mut self, fd: i32) -> Option { self.fds.remove(&fd) } @@ -296,17 +304,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 +329,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 +370,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) + } } } @@ -418,14 +420,16 @@ 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 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 bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?.to_owned(); + 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/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 7f6a3ba088792..90e0406f099ba 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -14,7 +14,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, @@ -723,25 +723,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/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 1e0e7d1632005..0d5d5cb3d9ad3 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -46,21 +46,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 @@ -89,7 +74,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/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index ebf9f43c19ef6..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>( @@ -39,13 +41,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>( @@ -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 0f28b69ac4a8e..a865f2efff957 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; @@ -9,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 @@ -20,24 +21,19 @@ 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 { +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.clone() })) - } - 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 @@ -53,12 +49,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 +62,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 +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: Cell::new(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/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index dd4ec8cfaa721..9b3302359ae12 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -11,7 +11,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> {} @@ -28,7 +28,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)?; @@ -40,6 +40,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" => { @@ -112,9 +118,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() { @@ -135,26 +138,14 @@ 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)?; } 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(EmulateItemResult::AlreadyJumped); } } @@ -194,6 +185,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. 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)?; diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index e50a8934e09d0..9c096760415e3 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, @@ -719,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") @@ -739,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/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index e91623ac87160..b3bc5d4d85235 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_env_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> {} diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 08aee04254bb8..dba5b7a906f91 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -14,7 +14,7 @@ use crate::shims::windows::*; use crate::*; 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, @@ -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] = diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 6e3468c018923..783be802bb73b 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -70,6 +70,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); diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 2ab2ae859051d..e519fa5508d28 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -738,14 +738,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(()) @@ -1126,6 +1132,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>, 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") 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..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,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: 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 7547ec417194c..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..4b12729bbff9c 100644 --- a/src/tools/miri/tests/fail-dep/tokio/sleep.stderr +++ b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr @@ -9,7 +9,7 @@ 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 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..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,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: 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 bd2a6c628f9e5..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,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: 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 cbbf1b3836199..e0d6e9ebf1de7 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,7 @@ 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 = 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..21759f9601904 100644 --- a/src/tools/miri/tests/fail/extern_static.stderr +++ b/src/tools/miri/tests/fail/extern_static.stderr @@ -4,7 +4,7 @@ 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 = 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..aa524c064694e 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,7 @@ 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 = 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..3c013a5d15d05 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,7 @@ 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 = 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 b37e05c62f95e..699dda52096f3 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,7 @@ 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 = note: BACKTRACE: = note: inside `main` at $DIR/intrinsic_fallback_checks_ub.rs:LL:CC 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/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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..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 @@ -4,7 +4,7 @@ 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 = 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..df54c98bb0e11 100644 --- a/src/tools/miri/tests/fail/unsized-local.stderr +++ b/src/tools/miri/tests/fail/unsized-local.stderr @@ -4,7 +4,7 @@ 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 = 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..f392e9564c751 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: 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 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() { 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() { 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/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 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 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 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/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 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 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([], []) diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index 3b767b3e62f13..addb36418d4b4 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -10,5 +10,10 @@ allow-unauthenticated = [ # Gives us the commands 'ready', 'author', 'blocked' [shortcut] +# Enables assigning users to issues and PRs. +[assign] +warn_non_default_branch = true +contributing_url = "https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md" + [no-merges] exclude_titles = ["Rustup"] 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(); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index d4d6c1460ceec..f96386a143d23 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/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 e13f20455a864..2d87915d50781 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 995779a6a9ca8..cadd9b542e9cb 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, stmt_expr_attributes)] #![omit_gdb_pretty_printer_section] diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs index 0293ec0ec3975..fbfe33763d87f 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)] 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/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); +} 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/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/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/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index c60290f8553a7..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; @@ -55,38 +56,123 @@ 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>); + //~^ 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>); + //~^ 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>); + //~^ 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>); + //~^ 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 + 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 103fda8d40253..bba5b09b69cc9 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -1,13 +1,13 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:60:13 + --> $DIR/lint-ctypes-enum.rs:69: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 note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:9:1 + --> $DIR/lint-ctypes-enum.rs:10:1 | LL | enum U { | ^^^^^^ @@ -18,75 +18,233 @@ 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:70: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 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:62:13 + --> $DIR/lint-ctypes-enum.rs:71: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 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:74:23 + --> $DIR/lint-ctypes-enum.rs:83: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:90: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:95: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:97: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:107: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:114: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:119: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:121: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, U>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:125: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:127: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:129: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:132: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:134: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:145: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:152: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:157: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:159: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:163: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:165: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:167: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:170: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:172:30 + | +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: `extern` block uses type `Result<(), ()>`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:174:27 | -LL | fn no_result(x: Result<(), num::NonZero>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe +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 8 previous errors +error: aborting due to 26 previous errors 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 => {}, | ^^^^^ 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]