| author | bors <bors@rust-lang.org> 2026-04-23 08:38:23 UTC |
| committer | bors <bors@rust-lang.org> 2026-04-23 08:38:23 UTC |
| log | 827651f2200cefab42dac4c2ae7f80a7149340de |
| tree | 884d31109632a54d85417e7794cce43d769392e5 |
| parent | 92c7010294007f9bb819f0ddd9d9e9b5ccd5714a |
| parent | 0fa807c149db79d3865d1733a18453a39d3ca04f |
Rollup of 10 pull requests
Successful merges:
- rust-lang/rust#146544 (mir-opt: Remove the workaround in UnreachableEnumBranching)
- rust-lang/rust#154819 (Fix ICE for inherent associated type mismatches)
- rust-lang/rust#155265 (Improved assumptions relating to isqrt)
- rust-lang/rust#152576 (c-variadic: use `emit_ptr_va_arg` for mips)
- rust-lang/rust#154481 (Mark a function only used in nightly as nightly only)
- rust-lang/rust#155614 (c-variadic: rename `VaList::arg` to `VaList::next_arg`)
- rust-lang/rust#155630 (Make `//@ skip-filecheck` a normal compiletest directive)
- rust-lang/rust#155641 (Remove non-working code for "running" mir-opt tests)
- rust-lang/rust#155652 (Expand `Path::is_empty` docs)
- rust-lang/rust#155656 (rustc_llvm: update opt-level handling for LLVM 23)194 files changed, 755 insertions(+), 490 deletions(-)
compiler/rustc_abi/src/callconv.rs+1| ... | ... | @@ -35,6 +35,7 @@ impl HomogeneousAggregate { |
| 35 | 35 | /// Try to combine two `HomogeneousAggregate`s, e.g. from two fields in |
| 36 | 36 | /// the same `struct`. Only succeeds if only one of them has any data, |
| 37 | 37 | /// or both units are identical. |
| 38 | #[cfg(feature = "nightly")] | |
| 38 | 39 | fn merge(self, other: HomogeneousAggregate) -> Result<HomogeneousAggregate, Heterogeneous> { |
| 39 | 40 | match (self, other) { |
| 40 | 41 | (x, HomogeneousAggregate::NoData) | (HomogeneousAggregate::NoData, x) => Ok(x), |
compiler/rustc_codegen_llvm/src/va_arg.rs+19-4| ... | ... | @@ -1171,14 +1171,29 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( |
| 1171 | 1171 | AllowHigherAlign::Yes, |
| 1172 | 1172 | ForceRightAdjust::No, |
| 1173 | 1173 | ), |
| 1174 | Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => emit_ptr_va_arg( | |
| 1175 | bx, | |
| 1176 | addr, | |
| 1177 | target_ty, | |
| 1178 | PassMode::Direct, | |
| 1179 | match &target.llvm_abiname { | |
| 1180 | LlvmAbi::N32 | LlvmAbi::N64 => SlotSize::Bytes8, | |
| 1181 | LlvmAbi::O32 => SlotSize::Bytes4, | |
| 1182 | other => bug!("unexpected LLVM ABI {other}"), | |
| 1183 | }, | |
| 1184 | AllowHigherAlign::Yes, | |
| 1185 | // In big-endian mode the actual value is stored in the right side of the slot, meaning | |
| 1186 | // that when the value is smaller than a slot, we need to adjust the pointer we read | |
| 1187 | // to somewhere in the middle of the slot. | |
| 1188 | match bx.tcx().sess.target.endian { | |
| 1189 | Endian::Big => ForceRightAdjust::Yes, | |
| 1190 | Endian::Little => ForceRightAdjust::No, | |
| 1191 | }, | |
| 1192 | ), | |
| 1174 | 1193 | |
| 1175 | 1194 | Arch::Bpf => bug!("bpf does not support c-variadic functions"), |
| 1176 | 1195 | Arch::SpirV => bug!("spirv does not support c-variadic functions"), |
| 1177 | 1196 | |
| 1178 | Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { | |
| 1179 | // FIXME: port MipsTargetLowering::lowerVAARG. | |
| 1180 | bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) | |
| 1181 | } | |
| 1182 | 1197 | Arch::Sparc | Arch::Avr | Arch::M68k | Arch::Msp430 => { |
| 1183 | 1198 | // Clang uses the LLVM implementation for these architectures. |
| 1184 | 1199 | bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) |
compiler/rustc_index/src/bit_set.rs-2| ... | ... | @@ -1,6 +1,4 @@ |
| 1 | 1 | use std::marker::PhantomData; |
| 2 | #[cfg(not(feature = "nightly"))] | |
| 3 | use std::mem; | |
| 4 | 2 | use std::ops::{Bound, Range, RangeBounds}; |
| 5 | 3 | use std::rc::Rc; |
| 6 | 4 | use std::{fmt, iter, slice}; |
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp+7| ... | ... | @@ -165,10 +165,17 @@ static OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) { |
| 165 | 165 | return OptimizationLevel::O2; |
| 166 | 166 | case LLVMRustPassBuilderOptLevel::O3: |
| 167 | 167 | return OptimizationLevel::O3; |
| 168 | #if LLVM_VERSION_GE(23, 0) | |
| 169 | case LLVMRustPassBuilderOptLevel::Os: | |
| 170 | return OptimizationLevel::O2; | |
| 171 | case LLVMRustPassBuilderOptLevel::Oz: | |
| 172 | return OptimizationLevel::O2; | |
| 173 | #else | |
| 168 | 174 | case LLVMRustPassBuilderOptLevel::Os: |
| 169 | 175 | return OptimizationLevel::Os; |
| 170 | 176 | case LLVMRustPassBuilderOptLevel::Oz: |
| 171 | 177 | return OptimizationLevel::Oz; |
| 178 | #endif | |
| 172 | 179 | default: |
| 173 | 180 | report_fatal_error("Bad PassBuilderOptLevel."); |
| 174 | 181 | } |
compiler/rustc_mir_transform/src/unreachable_enum_branching.rs+6-46| ... | ... | @@ -4,8 +4,7 @@ use rustc_abi::Variants; |
| 4 | 4 | use rustc_data_structures::fx::FxHashSet; |
| 5 | 5 | use rustc_middle::bug; |
| 6 | 6 | use rustc_middle::mir::{ |
| 7 | BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind, | |
| 8 | TerminatorKind, | |
| 7 | BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, TerminatorKind, | |
| 9 | 8 | }; |
| 10 | 9 | use rustc_middle::ty::layout::TyAndLayout; |
| 11 | 10 | use rustc_middle::ty::{Ty, TyCtxt}; |
| ... | ... | @@ -125,43 +124,10 @@ impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching { |
| 125 | 124 | unreachable_targets.push(index); |
| 126 | 125 | } |
| 127 | 126 | } |
| 128 | let otherwise_is_empty_unreachable = | |
| 129 | body.basic_blocks[targets.otherwise()].is_empty_unreachable(); | |
| 130 | fn check_successors(basic_blocks: &BasicBlocks<'_>, bb: BasicBlock) -> bool { | |
| 131 | // After resolving https://github.com/llvm/llvm-project/issues/78578, | |
| 132 | // We can remove this check. | |
| 133 | // The main issue here is that `early-tailduplication` causes compile time overhead | |
| 134 | // and potential performance problems. | |
| 135 | // Simply put, when encounter a switch (indirect branch) statement, | |
| 136 | // `early-tailduplication` tries to duplicate the switch branch statement with BB | |
| 137 | // into (each) predecessors. This makes CFG very complex. | |
| 138 | // We can understand it as it transforms the following code | |
| 139 | // ```rust | |
| 140 | // match a { ... many cases }; | |
| 141 | // match b { ... many cases }; | |
| 142 | // ``` | |
| 143 | // into | |
| 144 | // ```rust | |
| 145 | // match a { ... many match b { goto BB cases } } | |
| 146 | // ... BB cases | |
| 147 | // ``` | |
| 148 | // Abandon this transformation when it is possible (the best effort) | |
| 149 | // to encounter the problem. | |
| 150 | let mut successors = basic_blocks[bb].terminator().successors(); | |
| 151 | let Some(first_successor) = successors.next() else { return true }; | |
| 152 | if successors.next().is_some() { | |
| 153 | return true; | |
| 154 | } | |
| 155 | if let TerminatorKind::SwitchInt { .. } = | |
| 156 | &basic_blocks[first_successor].terminator().kind | |
| 157 | { | |
| 158 | return false; | |
| 159 | }; | |
| 160 | true | |
| 161 | } | |
| 127 | ||
| 162 | 128 | // If and only if there is a variant that does not have a branch set, change the |
| 163 | 129 | // current of otherwise as the variant branch and set otherwise to unreachable. It |
| 164 | // transforms following code | |
| 130 | // transforms the following code | |
| 165 | 131 | // ```rust |
| 166 | 132 | // match c { |
| 167 | 133 | // Ordering::Less => 1, |
| ... | ... | @@ -177,15 +143,8 @@ impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching { |
| 177 | 143 | // Ordering::Greater => 3, |
| 178 | 144 | // } |
| 179 | 145 | // ``` |
| 180 | let otherwise_is_last_variant = !otherwise_is_empty_unreachable | |
| 181 | && allowed_variants.len() == 1 | |
| 182 | // Despite the LLVM issue, we hope that small enum can still be transformed. | |
| 183 | // This is valuable for both `a <= b` and `if let Some/Ok(v)`. | |
| 184 | && (targets.all_targets().len() <= 3 | |
| 185 | || check_successors(&body.basic_blocks, targets.otherwise())); | |
| 186 | let replace_otherwise_to_unreachable = otherwise_is_last_variant | |
| 187 | || (!otherwise_is_empty_unreachable && allowed_variants.is_empty()); | |
| 188 | ||
| 146 | let replace_otherwise_to_unreachable = allowed_variants.len() <= 1 | |
| 147 | && !body.basic_blocks[targets.otherwise()].is_empty_unreachable(); | |
| 189 | 148 | if unreachable_targets.is_empty() && !replace_otherwise_to_unreachable { |
| 190 | 149 | continue; |
| 191 | 150 | } |
| ... | ... | @@ -193,6 +152,7 @@ impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching { |
| 193 | 152 | let unreachable_block = patch.unreachable_no_cleanup_block(); |
| 194 | 153 | let mut targets = targets.clone(); |
| 195 | 154 | if replace_otherwise_to_unreachable { |
| 155 | let otherwise_is_last_variant = allowed_variants.len() == 1; | |
| 196 | 156 | if otherwise_is_last_variant { |
| 197 | 157 | // We have checked that `allowed_variants` has only one element. |
| 198 | 158 | #[allow(rustc::potential_query_instability)] |
compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs+4| ... | ... | @@ -606,6 +606,10 @@ impl<T> Trait<T> for X { |
| 606 | 606 | ty: Ty<'tcx>, |
| 607 | 607 | ) -> bool { |
| 608 | 608 | let tcx = self.tcx; |
| 609 | // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. | |
| 610 | if !matches!(proj_ty.kind, ty::AliasTyKind::Projection { .. }) { | |
| 611 | return false; | |
| 612 | } | |
| 609 | 613 | let Some(body_owner_def_id) = body_owner_def_id else { |
| 610 | 614 | return false; |
| 611 | 615 | }; |
library/core/src/ffi/va_list.rs+4-4| ... | ... | @@ -204,7 +204,7 @@ crate::cfg_select! { |
| 204 | 204 | /// unsafe fn vmy_func(count: u32, mut ap: VaList<'_>) -> i32 { |
| 205 | 205 | /// let mut sum = 0; |
| 206 | 206 | /// for _ in 0..count { |
| 207 | /// sum += unsafe { ap.arg::<i32>() }; | |
| 207 | /// sum += unsafe { ap.next_arg::<i32>() }; | |
| 208 | 208 | /// } |
| 209 | 209 | /// sum |
| 210 | 210 | /// } |
| ... | ... | @@ -213,7 +213,7 @@ crate::cfg_select! { |
| 213 | 213 | /// assert_eq!(unsafe { my_func(3, 42i32, -7i32, 20i32) }, 55); |
| 214 | 214 | /// ``` |
| 215 | 215 | /// |
| 216 | /// The [`VaList::arg`] method reads the next argument from the variable argument list, | |
| 216 | /// The [`VaList::next_arg`] method reads the next argument from the variable argument list, | |
| 217 | 217 | /// and is equivalent to C `va_arg`. |
| 218 | 218 | /// |
| 219 | 219 | /// Cloning a `VaList` performs the equivalent of C `va_copy`, producing an independent cursor |
| ... | ... | @@ -284,7 +284,7 @@ mod sealed { |
| 284 | 284 | impl<T> Sealed for *const T {} |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | /// Types that are valid to read using [`VaList::arg`]. | |
| 287 | /// Types that are valid to read using [`VaList::next_arg`]. | |
| 288 | 288 | /// |
| 289 | 289 | /// This trait is implemented for primitive types that have a variable argument application-binary |
| 290 | 290 | /// interface (ABI) on the current platform. It is always implemented for: |
| ... | ... | @@ -391,7 +391,7 @@ impl<'f> VaList<'f> { |
| 391 | 391 | /// are no more variable arguments, is unsound. |
| 392 | 392 | #[inline] // Avoid codegen when not used to help backends that don't support VaList. |
| 393 | 393 | #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] |
| 394 | pub const unsafe fn arg<T: VaArgSafe>(&mut self) -> T { | |
| 394 | pub const unsafe fn next_arg<T: VaArgSafe>(&mut self) -> T { | |
| 395 | 395 | // SAFETY: the caller must uphold the safety contract for `va_arg`. |
| 396 | 396 | unsafe { va_arg(self) } |
| 397 | 397 | } |
library/core/src/num/imp/int_sqrt.rs-30| ... | ... | @@ -41,36 +41,6 @@ pub(in crate::num) const fn u8(n: u8) -> u8 { |
| 41 | 41 | U8_ISQRT_WITH_REMAINDER[n as usize].0 |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | /// Generates an `i*` function that returns the [integer square root]( | |
| 45 | /// https://en.wikipedia.org/wiki/Integer_square_root) of any **nonnegative** | |
| 46 | /// input of a specific signed integer type. | |
| 47 | macro_rules! signed_fn { | |
| 48 | ($SignedT:ident, $UnsignedT:ident) => { | |
| 49 | /// Returns the [integer square root]( | |
| 50 | /// https://en.wikipedia.org/wiki/Integer_square_root) of any | |
| 51 | /// **nonnegative** | |
| 52 | #[doc = concat!("[`", stringify!($SignedT), "`](prim@", stringify!($SignedT), ")")] | |
| 53 | /// input. | |
| 54 | /// | |
| 55 | /// # Safety | |
| 56 | /// | |
| 57 | /// This results in undefined behavior when the input is negative. | |
| 58 | #[must_use = "this returns the result of the operation, \ | |
| 59 | without modifying the original"] | |
| 60 | #[inline] | |
| 61 | pub(in crate::num) const unsafe fn $SignedT(n: $SignedT) -> $SignedT { | |
| 62 | debug_assert!(n >= 0, "Negative input inside `isqrt`."); | |
| 63 | $UnsignedT(n as $UnsignedT) as $SignedT | |
| 64 | } | |
| 65 | }; | |
| 66 | } | |
| 67 | ||
| 68 | signed_fn!(i8, u8); | |
| 69 | signed_fn!(i16, u16); | |
| 70 | signed_fn!(i32, u32); | |
| 71 | signed_fn!(i64, u64); | |
| 72 | signed_fn!(i128, u128); | |
| 73 | ||
| 74 | 44 | /// Generates a `u*` function that returns the [integer square root]( |
| 75 | 45 | /// https://en.wikipedia.org/wiki/Integer_square_root) of any input of |
| 76 | 46 | /// a specific unsigned integer type. |
library/core/src/num/int_macros.rs+4-11| ... | ... | @@ -1933,10 +1933,9 @@ macro_rules! int_impl { |
| 1933 | 1933 | if self < 0 { |
| 1934 | 1934 | None |
| 1935 | 1935 | } else { |
| 1936 | // SAFETY: Input is nonnegative in this `else` branch. | |
| 1937 | let result = unsafe { | |
| 1938 | imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT | |
| 1939 | }; | |
| 1936 | // The upper bound of `$UnsignedT::MAX.isqrt()` told to the compiler | |
| 1937 | // in the unsigned function also tells it that `result >= 0` | |
| 1938 | let result = self.cast_unsigned().isqrt().cast_signed(); | |
| 1940 | 1939 | |
| 1941 | 1940 | // Inform the optimizer what the range of outputs is. If |
| 1942 | 1941 | // testing `core` crashes with no panic message and a |
| ... | ... | @@ -1950,15 +1949,9 @@ macro_rules! int_impl { |
| 1950 | 1949 | // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by |
| 1951 | 1950 | // `[sqrt(0), sqrt(<$ActualT>::MAX)]`. |
| 1952 | 1951 | unsafe { |
| 1953 | // SAFETY: `<$ActualT>::MAX` is nonnegative. | |
| 1954 | const MAX_RESULT: $SelfT = unsafe { | |
| 1955 | imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT | |
| 1956 | }; | |
| 1957 | ||
| 1958 | crate::hint::assert_unchecked(result >= 0); | |
| 1952 | const MAX_RESULT: $SelfT = <$SelfT>::MAX.cast_unsigned().isqrt().cast_signed(); | |
| 1959 | 1953 | crate::hint::assert_unchecked(result <= MAX_RESULT); |
| 1960 | 1954 | } |
| 1961 | ||
| 1962 | 1955 | Some(result) |
| 1963 | 1956 | } |
| 1964 | 1957 | } |
library/core/src/num/uint_macros.rs+22-3| ... | ... | @@ -3682,7 +3682,7 @@ macro_rules! uint_impl { |
| 3682 | 3682 | without modifying the original"] |
| 3683 | 3683 | #[inline] |
| 3684 | 3684 | pub const fn isqrt(self) -> Self { |
| 3685 | let result = imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT; | |
| 3685 | let result = imp::int_sqrt::$ActualT(self as $ActualT) as Self; | |
| 3686 | 3686 | |
| 3687 | 3687 | // Inform the optimizer what the range of outputs is. If testing |
| 3688 | 3688 | // `core` crashes with no panic message and a `num::int_sqrt::u*` |
| ... | ... | @@ -3693,10 +3693,29 @@ macro_rules! uint_impl { |
| 3693 | 3693 | // function, which means that increasing the input will never |
| 3694 | 3694 | // cause the output to decrease. Thus, since the input for unsigned |
| 3695 | 3695 | // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be |
| 3696 | // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`. | |
| 3696 | // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]` and bounding the | |
| 3697 | // input by `[1, <$ActualT>::MAX]` bounds sqrt(n) by | |
| 3698 | // `[sqrt(1), sqrt(<$ActualT>::MAX)]`. | |
| 3697 | 3699 | unsafe { |
| 3698 | 3700 | const MAX_RESULT: $SelfT = imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT; |
| 3699 | crate::hint::assert_unchecked(result <= MAX_RESULT); | |
| 3701 | crate::hint::assert_unchecked(result <= MAX_RESULT) | |
| 3702 | } | |
| 3703 | ||
| 3704 | if self >= 1 { | |
| 3705 | // SAFETY: The above statements about monotonicity also apply here. | |
| 3706 | // Since the input in this branch is bounded by `[1, <$ActualT>::MAX]`, | |
| 3707 | // sqrt(n) is bounded by `[sqrt(1), sqrt(<$ActualT>::MAX)]`, and | |
| 3708 | // `sqrt(1) == 1`. | |
| 3709 | unsafe { crate::hint::assert_unchecked(result >= 1) } | |
| 3710 | } | |
| 3711 | ||
| 3712 | // SAFETY: the isqrt implementation returns the square root and rounds down, | |
| 3713 | // meaning `result * result <= self`. This implies `result <= self`. | |
| 3714 | // The compiler needs both to optimize for both. | |
| 3715 | // `result * result <= self` implies the multiplication will not overflow. | |
| 3716 | unsafe { | |
| 3717 | crate::hint::assert_unchecked(result.unchecked_mul(result) <= self); | |
| 3718 | crate::hint::assert_unchecked(result <= self); | |
| 3700 | 3719 | } |
| 3701 | 3720 | |
| 3702 | 3721 | result |
library/std/src/path.rs+4| ... | ... | @@ -2828,6 +2828,10 @@ impl Path { |
| 2828 | 2828 | |
| 2829 | 2829 | /// Checks whether the `Path` is empty. |
| 2830 | 2830 | /// |
| 2831 | /// Passing an empty path to most OS filesystem APIs will always result in an error. | |
| 2832 | /// | |
| 2833 | /// [Pushing][PathBuf::push] an empty path to an existing path will append a directory separator unless it already ends with a separator or the existing path is itself empty. | |
| 2834 | /// | |
| 2831 | 2835 | /// # Examples |
| 2832 | 2836 | /// |
| 2833 | 2837 | /// ``` |
src/doc/rustc-dev-guide/src/tests/directives.md+2| ... | ... | @@ -326,6 +326,8 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests). |
| 326 | 326 | The following directives affect how certain command-line tools are invoked, in |
| 327 | 327 | test suites that use those tools: |
| 328 | 328 | |
| 329 | - `skip-filecheck` avoids running LLVM's `FileCheck` tool in tests that would normally run it to check output. | |
| 330 | - Used by codegen tests, assembly tests, and mir-opt tests. | |
| 329 | 331 | - `filecheck-flags` adds extra flags when running LLVM's `FileCheck` tool. |
| 330 | 332 | - Used by [codegen tests](compiletest.md#codegen-tests), |
| 331 | 333 | [assembly tests](compiletest.md#assembly-tests), and |
src/doc/unstable-book/src/language-features/c-variadic.md+1-1| ... | ... | @@ -17,7 +17,7 @@ defined in Rust. They may be called both from within Rust and via FFI. |
| 17 | 17 | pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize { |
| 18 | 18 | let mut sum = 0; |
| 19 | 19 | for _ in 0..n { |
| 20 | sum += args.arg::<usize>(); | |
| 20 | sum += args.next_arg::<usize>(); | |
| 21 | 21 | } |
| 22 | 22 | sum |
| 23 | 23 | } |
src/tools/compiletest/src/directives.rs+4-1| ... | ... | @@ -195,6 +195,9 @@ pub(crate) struct TestProps { |
| 195 | 195 | /// Extra flags to pass to `llvm-cov` when producing coverage reports. |
| 196 | 196 | /// Only used by the "coverage-run" test mode. |
| 197 | 197 | pub(crate) llvm_cov_flags: Vec<String>, |
| 198 | /// Don't run LLVM's `filecheck` tool to check compiler output, | |
| 199 | /// in tests that would normally run it. | |
| 200 | pub(crate) skip_filecheck: bool, | |
| 198 | 201 | /// Extra flags to pass to LLVM's `filecheck` tool, in tests that use it. |
| 199 | 202 | pub(crate) filecheck_flags: Vec<String>, |
| 200 | 203 | /// Don't automatically insert any `--check-cfg` args |
| ... | ... | @@ -308,6 +311,7 @@ impl TestProps { |
| 308 | 311 | mir_unit_test: None, |
| 309 | 312 | remap_src_base: false, |
| 310 | 313 | llvm_cov_flags: vec![], |
| 314 | skip_filecheck: false, | |
| 311 | 315 | filecheck_flags: vec![], |
| 312 | 316 | no_auto_check_cfg: false, |
| 313 | 317 | add_minicore: false, |
| ... | ... | @@ -438,7 +442,6 @@ impl TestProps { |
| 438 | 442 | let check_no_run = |s| match (config.mode, s) { |
| 439 | 443 | (TestMode::Ui, _) => (), |
| 440 | 444 | (TestMode::Crashes, _) => (), |
| 441 | (TestMode::Codegen, "build-pass") => (), | |
| 442 | 445 | (mode, _) => panic!("`{s}` directive is not supported in `{mode}` tests"), |
| 443 | 446 | }; |
| 444 | 447 | let pass_mode = if config.parse_name_directive(ln, "check-pass") { |
src/tools/compiletest/src/directives/directive_names.rs+1| ... | ... | @@ -286,6 +286,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ |
| 286 | 286 | "rustc-env", |
| 287 | 287 | "rustfix-only-machine-applicable", |
| 288 | 288 | "should-fail", |
| 289 | "skip-filecheck", | |
| 289 | 290 | "stderr-per-bitwidth", |
| 290 | 291 | "test-mir-pass", |
| 291 | 292 | "unique-doc-out-dir", |
src/tools/compiletest/src/directives/handlers.rs+13-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | use std::collections::HashMap; |
| 2 | 2 | use std::sync::{Arc, LazyLock}; |
| 3 | 3 | |
| 4 | use crate::common::Config; | |
| 4 | use crate::common::{Config, TestMode}; | |
| 5 | 5 | use crate::directives::{ |
| 6 | 6 | DirectiveLine, NormalizeKind, NormalizeRule, TestProps, parse_and_update_aux, |
| 7 | 7 | parse_edition_range, split_flags, |
| ... | ... | @@ -312,6 +312,18 @@ fn make_directive_handlers_map() -> HashMap<&'static str, Handler> { |
| 312 | 312 | props.llvm_cov_flags.extend(split_flags(&flags)); |
| 313 | 313 | } |
| 314 | 314 | }), |
| 315 | handler("skip-filecheck", |config, ln, props| { | |
| 316 | let directive_name = ln.name; | |
| 317 | // FIXME(Zalathar): Someday we should add unified support for declaring | |
| 318 | // and checking which modes are supported by each directive. | |
| 319 | if !matches!(config.mode, TestMode::Assembly | TestMode::Codegen | TestMode::MirOpt) { | |
| 320 | panic!( | |
| 321 | "directive `//@ {directive_name}` is not supported by this test suite (mode: {mode:?})", | |
| 322 | mode = config.mode | |
| 323 | ); | |
| 324 | } | |
| 325 | config.set_name_directive(ln, directive_name, &mut props.skip_filecheck); | |
| 326 | }), | |
| 315 | 327 | handler(FILECHECK_FLAGS, |config, ln, props| { |
| 316 | 328 | if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) { |
| 317 | 329 | props.filecheck_flags.extend(split_flags(&flags)); |
src/tools/compiletest/src/runtest.rs+5-20| ... | ... | @@ -295,14 +295,9 @@ impl<'test> TestCx<'test> { |
| 295 | 295 | |
| 296 | 296 | fn should_run(&self, pm: Option<PassMode>) -> WillExecute { |
| 297 | 297 | let test_should_run = match self.config.mode { |
| 298 | TestMode::Ui | |
| 299 | if pm == Some(PassMode::Run) | |
| 300 | || matches!(self.props.fail_mode, Some(FailMode::Run(_))) => | |
| 301 | { | |
| 302 | true | |
| 298 | TestMode::Ui => { | |
| 299 | pm == Some(PassMode::Run) || matches!(self.props.fail_mode, Some(FailMode::Run(_))) | |
| 303 | 300 | } |
| 304 | TestMode::MirOpt if pm == Some(PassMode::Run) => true, | |
| 305 | TestMode::Ui | TestMode::MirOpt => false, | |
| 306 | 301 | mode => panic!("unimplemented for mode {:?}", mode), |
| 307 | 302 | }; |
| 308 | 303 | if test_should_run { self.run_if_enabled() } else { WillExecute::No } |
| ... | ... | @@ -314,7 +309,7 @@ impl<'test> TestCx<'test> { |
| 314 | 309 | |
| 315 | 310 | fn should_run_successfully(&self, pm: Option<PassMode>) -> bool { |
| 316 | 311 | match self.config.mode { |
| 317 | TestMode::Ui | TestMode::MirOpt => pm == Some(PassMode::Run), | |
| 312 | TestMode::Ui => pm == Some(PassMode::Run), | |
| 318 | 313 | mode => panic!("unimplemented for mode {:?}", mode), |
| 319 | 314 | } |
| 320 | 315 | } |
| ... | ... | @@ -935,23 +930,13 @@ impl<'test> TestCx<'test> { |
| 935 | 930 | } |
| 936 | 931 | |
| 937 | 932 | fn compile_test(&self, will_execute: WillExecute, emit: Emit) -> ProcRes { |
| 938 | self.compile_test_general(will_execute, emit, self.props.local_pass_mode(), Vec::new()) | |
| 939 | } | |
| 940 | ||
| 941 | fn compile_test_with_passes( | |
| 942 | &self, | |
| 943 | will_execute: WillExecute, | |
| 944 | emit: Emit, | |
| 945 | passes: Vec<String>, | |
| 946 | ) -> ProcRes { | |
| 947 | self.compile_test_general(will_execute, emit, self.props.local_pass_mode(), passes) | |
| 933 | self.compile_test_general(will_execute, emit, Vec::new()) | |
| 948 | 934 | } |
| 949 | 935 | |
| 950 | 936 | fn compile_test_general( |
| 951 | 937 | &self, |
| 952 | 938 | will_execute: WillExecute, |
| 953 | 939 | emit: Emit, |
| 954 | local_pm: Option<PassMode>, | |
| 955 | 940 | passes: Vec<String>, |
| 956 | 941 | ) -> ProcRes { |
| 957 | 942 | let compiler_kind = self.compiler_kind_for_non_aux(); |
| ... | ... | @@ -975,7 +960,7 @@ impl<'test> TestCx<'test> { |
| 975 | 960 | // Note that we use the local pass mode here as we don't want |
| 976 | 961 | // to set unused to allow if we've overridden the pass mode |
| 977 | 962 | // via command line flags. |
| 978 | && local_pm != Some(PassMode::Run) | |
| 963 | && self.props.local_pass_mode() != Some(PassMode::Run) | |
| 979 | 964 | { |
| 980 | 965 | AllowUnused::Yes |
| 981 | 966 | } else { |
src/tools/compiletest/src/runtest/assembly.rs+5-3| ... | ... | @@ -13,9 +13,11 @@ impl TestCx<'_> { |
| 13 | 13 | self.fatal_proc_rec("compilation failed!", &proc_res); |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | let proc_res = self.verify_with_filecheck(&output_path); | |
| 17 | if !proc_res.status.success() { | |
| 18 | self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); | |
| 16 | if !self.props.skip_filecheck { | |
| 17 | let proc_res = self.verify_with_filecheck(&output_path); | |
| 18 | if !proc_res.status.success() { | |
| 19 | self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); | |
| 20 | } | |
| 19 | 21 | } |
| 20 | 22 | } |
| 21 | 23 |
src/tools/compiletest/src/runtest/codegen.rs+6-7| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | use super::{PassMode, TestCx}; | |
| 1 | use super::TestCx; | |
| 2 | 2 | |
| 3 | 3 | impl TestCx<'_> { |
| 4 | 4 | pub(super) fn run_codegen_test(&self) { |
| ... | ... | @@ -11,12 +11,11 @@ impl TestCx<'_> { |
| 11 | 11 | self.fatal_proc_rec("compilation failed!", &proc_res); |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | if let Some(PassMode::Build) = self.pass_mode() { | |
| 15 | return; | |
| 16 | } | |
| 17 | let proc_res = self.verify_with_filecheck(&output_path); | |
| 18 | if !proc_res.status.success() { | |
| 19 | self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); | |
| 14 | if !self.props.skip_filecheck { | |
| 15 | let proc_res = self.verify_with_filecheck(&output_path); | |
| 16 | if !proc_res.status.success() { | |
| 17 | self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); | |
| 18 | } | |
| 20 | 19 | } |
| 21 | 20 | } |
| 22 | 21 | } |
src/tools/compiletest/src/runtest/mir_opt.rs+3-14| ... | ... | @@ -10,9 +10,6 @@ use crate::runtest::compute_diff::write_diff; |
| 10 | 10 | |
| 11 | 11 | impl TestCx<'_> { |
| 12 | 12 | pub(super) fn run_mir_opt_test(&self) { |
| 13 | let pm = self.pass_mode(); | |
| 14 | let should_run = self.should_run(pm); | |
| 15 | ||
| 16 | 13 | let mut test_info = files_for_miropt_test( |
| 17 | 14 | &self.testpaths.file.as_std_path(), |
| 18 | 15 | self.config.get_pointer_width(), |
| ... | ... | @@ -21,26 +18,18 @@ impl TestCx<'_> { |
| 21 | 18 | |
| 22 | 19 | let passes = std::mem::take(&mut test_info.passes); |
| 23 | 20 | |
| 24 | let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes); | |
| 21 | let proc_res = self.compile_test_general(WillExecute::No, Emit::Mir, passes); | |
| 25 | 22 | if !proc_res.status.success() { |
| 26 | 23 | self.fatal_proc_rec("compilation failed!", &proc_res); |
| 27 | 24 | } |
| 28 | 25 | self.check_mir_dump(test_info); |
| 29 | ||
| 30 | if let WillExecute::Yes = should_run { | |
| 31 | let proc_res = self.exec_compiled_test(); | |
| 32 | ||
| 33 | if !proc_res.status.success() { | |
| 34 | self.fatal_proc_rec("test run failed!", &proc_res); | |
| 35 | } | |
| 36 | } | |
| 37 | 26 | } |
| 38 | 27 | |
| 39 | 28 | fn check_mir_dump(&self, test_info: MiroptTest) { |
| 40 | 29 | let test_dir = self.testpaths.file.parent().unwrap(); |
| 41 | 30 | let test_crate = self.testpaths.file.file_stem().unwrap().replace('-', "_"); |
| 42 | 31 | |
| 43 | let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info; | |
| 32 | let MiroptTest { suffix, files, passes: _ } = test_info; | |
| 44 | 33 | |
| 45 | 34 | if self.config.bless { |
| 46 | 35 | for e in glob(&format!("{}/{}.*{}.mir", test_dir, test_crate, suffix)).unwrap() { |
| ... | ... | @@ -89,7 +78,7 @@ impl TestCx<'_> { |
| 89 | 78 | } |
| 90 | 79 | } |
| 91 | 80 | |
| 92 | if run_filecheck { | |
| 81 | if !self.props.skip_filecheck { | |
| 93 | 82 | let output_path = self.output_base_name().with_extension("mir"); |
| 94 | 83 | let proc_res = self.verify_with_filecheck(&output_path); |
| 95 | 84 | if !proc_res.status.success() { |
src/tools/compiletest/src/runtest/ui.rs+6-4| ... | ... | @@ -15,10 +15,12 @@ impl TestCx<'_> { |
| 15 | 15 | pub(super) fn run_ui_test(&self) { |
| 16 | 16 | if let Some(FailMode::Build) = self.props.fail_mode { |
| 17 | 17 | // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck). |
| 18 | let pm = Some(PassMode::Check); | |
| 19 | let proc_res = | |
| 20 | self.compile_test_general(WillExecute::No, Emit::Metadata, pm, Vec::new()); | |
| 21 | self.check_if_test_should_compile(self.props.fail_mode, pm, &proc_res); | |
| 18 | let proc_res = self.compile_test(WillExecute::No, Emit::Metadata); | |
| 19 | self.check_if_test_should_compile( | |
| 20 | self.props.fail_mode, | |
| 21 | Some(PassMode::Check), | |
| 22 | &proc_res, | |
| 23 | ); | |
| 22 | 24 | } |
| 23 | 25 | |
| 24 | 26 | let pm = self.pass_mode(); |
src/tools/miri/tests/fail/c-variadic.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | |
| 5 | 5 | fn read_too_many() { |
| 6 | 6 | unsafe extern "C" fn variadic(mut ap: ...) { |
| 7 | ap.arg::<i32>(); | |
| 7 | ap.next_arg::<i32>(); | |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | unsafe { variadic() }; |
src/tools/miri/tests/fail/c-variadic.stderr+1-1| ... | ... | @@ -7,7 +7,7 @@ LL | unsafe { va_arg(self) } |
| 7 | 7 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior |
| 8 | 8 | = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information |
| 9 | 9 | = note: stack backtrace: |
| 10 | 0: std::ffi::VaList::<'_>::arg | |
| 10 | 0: std::ffi::VaList::<'_>::next_arg | |
| 11 | 11 | at RUSTLIB/core/src/ffi/va_list.rs:LL:CC |
| 12 | 12 | 1: read_too_many::variadic |
| 13 | 13 | at tests/fail/c-variadic.rs:LL:CC |
src/tools/miri/tests/pass/c-variadic-ignored-argument.rs+2-2| ... | ... | @@ -13,8 +13,8 @@ |
| 13 | 13 | |
| 14 | 14 | fn main() { |
| 15 | 15 | unsafe extern "C" fn variadic(mut ap: ...) { |
| 16 | ap.arg::<i32>(); | |
| 17 | ap.arg::<i32>(); | |
| 16 | ap.next_arg::<i32>(); | |
| 17 | ap.next_arg::<i32>(); | |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | unsafe { variadic(0i32, (), 1i32) } |
src/tools/miri/tests/pass/c-variadic.rs+11-11| ... | ... | @@ -11,7 +11,7 @@ fn ignores_arguments() { |
| 11 | 11 | |
| 12 | 12 | fn echo() { |
| 13 | 13 | unsafe extern "C" fn variadic(mut ap: ...) -> i32 { |
| 14 | ap.arg() | |
| 14 | ap.next_arg() | |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | assert_eq!(unsafe { variadic(1) }, 1); |
| ... | ... | @@ -20,7 +20,7 @@ fn echo() { |
| 20 | 20 | |
| 21 | 21 | fn forward_by_val() { |
| 22 | 22 | unsafe fn helper(mut ap: VaList) -> i32 { |
| 23 | ap.arg() | |
| 23 | ap.next_arg() | |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | unsafe extern "C" fn variadic(ap: ...) -> i32 { |
| ... | ... | @@ -33,7 +33,7 @@ fn forward_by_val() { |
| 33 | 33 | |
| 34 | 34 | fn forward_by_ref() { |
| 35 | 35 | unsafe fn helper(ap: &mut VaList) -> i32 { |
| 36 | ap.arg() | |
| 36 | ap.next_arg() | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | unsafe extern "C" fn variadic(mut ap: ...) -> i32 { |
| ... | ... | @@ -47,7 +47,7 @@ fn forward_by_ref() { |
| 47 | 47 | #[allow(improper_ctypes_definitions)] |
| 48 | 48 | fn nested() { |
| 49 | 49 | unsafe fn helper(mut ap1: VaList, mut ap2: VaList) -> (i32, i32) { |
| 50 | (ap1.arg(), ap2.arg()) | |
| 50 | (ap1.next_arg(), ap2.next_arg()) | |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | unsafe extern "C" fn variadic2(ap1: VaList, ap2: ...) -> (i32, i32) { |
| ... | ... | @@ -83,13 +83,13 @@ fn various_types() { |
| 83 | 83 | } |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); | |
| 87 | continue_if!(ap.arg::<c_long>() == 12); | |
| 88 | continue_if!(ap.arg::<c_int>() == 'a' as c_int); | |
| 89 | continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor()); | |
| 90 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); | |
| 91 | continue_if!(ap.arg::<c_int>() == 42); | |
| 92 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); | |
| 86 | continue_if!(ap.next_arg::<c_double>().floor() == 3.14f64.floor()); | |
| 87 | continue_if!(ap.next_arg::<c_long>() == 12); | |
| 88 | continue_if!(ap.next_arg::<c_int>() == 'a' as c_int); | |
| 89 | continue_if!(ap.next_arg::<c_double>().floor() == 6.18f64.floor()); | |
| 90 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "Hello")); | |
| 91 | continue_if!(ap.next_arg::<c_int>() == 42); | |
| 92 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "World")); | |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | unsafe { |
src/tools/miropt-test-tools/src/lib.rs+6-8| ... | ... | @@ -8,7 +8,6 @@ pub struct MiroptTestFile { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | pub struct MiroptTest { |
| 11 | pub run_filecheck: bool, | |
| 12 | 11 | pub suffix: String, |
| 13 | 12 | pub files: Vec<MiroptTestFile>, |
| 14 | 13 | /// Vec of passes under test to be dumped |
| ... | ... | @@ -57,13 +56,15 @@ pub fn files_for_miropt_test( |
| 57 | 56 | let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_"); |
| 58 | 57 | |
| 59 | 58 | let suffix = output_file_suffix(testfile, bit_width, panic_strategy); |
| 60 | let mut run_filecheck = true; | |
| 61 | 59 | let mut passes = Vec::new(); |
| 62 | 60 | |
| 63 | 61 | for l in test_file_contents.lines() { |
| 62 | // FIXME(Zalathar): Remove this `skip-filecheck` migration error in 2027, | |
| 63 | // or perhaps earlier if it seems no longer useful. | |
| 64 | 64 | if l.starts_with("// skip-filecheck") { |
| 65 | run_filecheck = false; | |
| 66 | continue; | |
| 65 | panic!( | |
| 66 | "error: `// skip-filecheck` is no longer supported, use `//@ skip-filecheck` instead." | |
| 67 | ); | |
| 67 | 68 | } |
| 68 | 69 | if l.starts_with("// EMIT_MIR ") { |
| 69 | 70 | let test_name = l.trim_start_matches("// EMIT_MIR ").trim(); |
| ... | ... | @@ -128,10 +129,7 @@ pub fn files_for_miropt_test( |
| 128 | 129 | |
| 129 | 130 | out.push(MiroptTestFile { expected_file, from_file, to_file }); |
| 130 | 131 | } |
| 131 | if !run_filecheck && l.trim_start().starts_with("// CHECK") { | |
| 132 | panic!("error: test contains filecheck directive but is marked `skip-filecheck`"); | |
| 133 | } | |
| 134 | 132 | } |
| 135 | 133 | |
| 136 | MiroptTest { run_filecheck, suffix, files: out, passes } | |
| 134 | MiroptTest { suffix, files: out, passes } | |
| 137 | 135 | } |
tests/assembly-llvm/c-variadic-arm.rs+2-2| ... | ... | @@ -18,8 +18,8 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { |
| 18 | 18 | // CHECK: vadd.f64 |
| 19 | 19 | // CHECK: vldr |
| 20 | 20 | // CHECK: vadd.f64 |
| 21 | let b = args.arg::<f64>(); | |
| 22 | let c = args.arg::<f64>(); | |
| 21 | let b = args.next_arg::<f64>(); | |
| 22 | let c = args.next_arg::<f64>(); | |
| 23 | 23 | a + b + c |
| 24 | 24 | |
| 25 | 25 | // CHECK: add sp, sp |
tests/assembly-llvm/c-variadic-mips.rs created+137| ... | ... | @@ -0,0 +1,137 @@ |
| 1 | //@ add-minicore | |
| 2 | //@ assembly-output: emit-asm | |
| 3 | // | |
| 4 | //@ revisions: MIPS MIPS64 MIPS64EL | |
| 5 | //@ [MIPS] compile-flags: -Copt-level=3 --target mips-unknown-linux-gnu | |
| 6 | //@ [MIPS] needs-llvm-components: mips | |
| 7 | //@ [MIPS64] compile-flags: -Copt-level=3 --target mipsisa64r6-unknown-linux-gnuabi64 | |
| 8 | //@ [MIPS64] needs-llvm-components: mips | |
| 9 | //@ [MIPS64EL] compile-flags: -Copt-level=3 --target mips64el-unknown-linux-gnuabi64 | |
| 10 | //@ [MIPS64EL] needs-llvm-components: mips | |
| 11 | #![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)] | |
| 12 | #![no_core] | |
| 13 | #![crate_type = "lib"] | |
| 14 | ||
| 15 | // Check that the assembly that rustc generates matches what clang emits. | |
| 16 | ||
| 17 | extern crate minicore; | |
| 18 | use minicore::*; | |
| 19 | ||
| 20 | #[lang = "va_arg_safe"] | |
| 21 | pub unsafe trait VaArgSafe {} | |
| 22 | ||
| 23 | unsafe impl VaArgSafe for i32 {} | |
| 24 | unsafe impl VaArgSafe for i64 {} | |
| 25 | unsafe impl VaArgSafe for f64 {} | |
| 26 | unsafe impl<T> VaArgSafe for *const T {} | |
| 27 | ||
| 28 | #[repr(transparent)] | |
| 29 | struct VaListInner { | |
| 30 | ptr: *const c_void, | |
| 31 | } | |
| 32 | ||
| 33 | #[repr(transparent)] | |
| 34 | #[lang = "va_list"] | |
| 35 | pub struct VaList<'a> { | |
| 36 | inner: VaListInner, | |
| 37 | _marker: PhantomData<&'a mut ()>, | |
| 38 | } | |
| 39 | ||
| 40 | #[rustc_intrinsic] | |
| 41 | #[rustc_nounwind] | |
| 42 | pub const unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T; | |
| 43 | ||
| 44 | #[unsafe(no_mangle)] | |
| 45 | unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { | |
| 46 | // CHECK-LABEL: read_f64 | |
| 47 | // | |
| 48 | // MIPS: lw $1, 0($4) | |
| 49 | // MIPS-NEXT: addiu $2, $zero, -8 | |
| 50 | // MIPS-NEXT: addiu $1, $1, 7 | |
| 51 | // MIPS-NEXT: and $1, $1, $2 | |
| 52 | // MIPS-NEXT: addiu $2, $1, 8 | |
| 53 | // MIPS-NEXT: sw $2, 0($4) | |
| 54 | // MIPS-NEXT: ldc1 $f0, 0($1) | |
| 55 | // MIPS-NEXT: jr $ra | |
| 56 | // MIPS-NEXT: nop | |
| 57 | // | |
| 58 | // MIPS64: ld $1, 0($4) | |
| 59 | // MIPS64-NEXT: daddiu $2, $1, 8 | |
| 60 | // MIPS64-NEXT: sd $2, 0($4) | |
| 61 | // MIPS64-NEXT: ldc1 $f0, 0($1) | |
| 62 | // MIPS64-NEXT: jrc $ra | |
| 63 | // | |
| 64 | // MIPS64EL: ld $1, 0($4) | |
| 65 | // MIPS64EL-NEXT: daddiu $2, $1, 8 | |
| 66 | // MIPS64EL-NEXT: sd $2, 0($4) | |
| 67 | // MIPS64EL-NEXT: ldc1 $f0, 0($1) | |
| 68 | // MIPS64EL-NEXT: jr $ra | |
| 69 | // MIPS64EL-NEXT: nop | |
| 70 | va_arg(ap) | |
| 71 | } | |
| 72 | ||
| 73 | #[unsafe(no_mangle)] | |
| 74 | unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { | |
| 75 | // CHECK-LABEL: read_i32 | |
| 76 | // | |
| 77 | // MIPS: lw $1, 0($4) | |
| 78 | // MIPS-NEXT: addiu $2, $1, 4 | |
| 79 | // MIPS-NEXT: sw $2, 0($4) | |
| 80 | // MIPS-NEXT: lw $2, 0($1) | |
| 81 | // MIPS-NEXT: jr $ra | |
| 82 | // MIPS-NEXT: nop | |
| 83 | // | |
| 84 | // MIPS64: ld $1, 0($4) | |
| 85 | // MIPS64-NEXT: daddiu $2, $1, 8 | |
| 86 | // MIPS64-NEXT: sd $2, 0($4) | |
| 87 | // MIPS64-NEXT: lw $2, 4($1) | |
| 88 | // MIPS64-NEXT: jrc $ra | |
| 89 | // | |
| 90 | // MIPS64EL: ld $1, 0($4) | |
| 91 | // MIPS64EL-NEXT: daddiu $2, $1, 8 | |
| 92 | // MIPS64EL-NEXT: sd $2, 0($4) | |
| 93 | // MIPS64EL-NEXT: lw $2, 0($1) | |
| 94 | // MIPS64EL-NEXT: jr $ra | |
| 95 | // MIPS64EL-NEXT: nop | |
| 96 | va_arg(ap) | |
| 97 | } | |
| 98 | ||
| 99 | #[unsafe(no_mangle)] | |
| 100 | unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { | |
| 101 | // CHECK-LABEL: read_i64 | |
| 102 | // | |
| 103 | // MIPS: lw $1, 0($4) | |
| 104 | // MIPS-NEXT: addiu $2, $zero, -8 | |
| 105 | // MIPS-NEXT: addiu $1, $1, 7 | |
| 106 | // MIPS-NEXT: and $2, $1, $2 | |
| 107 | // MIPS-NEXT: addiu $3, $2, 8 | |
| 108 | // MIPS-NEXT: sw $3, 0($4) | |
| 109 | // MIPS-NEXT: addiu $3, $zero, 4 | |
| 110 | // MIPS-NEXT: lw $2, 0($2) | |
| 111 | // MIPS-NEXT: ins $1, $3, 0, 3 | |
| 112 | // MIPS-NEXT: lw $3, 0($1) | |
| 113 | // MIPS-NEXT: jr $ra | |
| 114 | // MIPS-NEXT: nop | |
| 115 | // | |
| 116 | // MIPS64: ld $1, 0($4) | |
| 117 | // MIPS64-NEXT: daddiu $2, $1, 8 | |
| 118 | // MIPS64-NEXT: sd $2, 0($4) | |
| 119 | // MIPS64-NEXT: ld $2, 0($1) | |
| 120 | // MIPS64-NEXT: jrc $ra | |
| 121 | // | |
| 122 | // MIPS64EL: ld $1, 0($4) | |
| 123 | // MIPS64EL-NEXT: daddiu $2, $1, 8 | |
| 124 | // MIPS64EL-NEXT: sd $2, 0($4) | |
| 125 | // MIPS64EL-NEXT: ld $2, 0($1) | |
| 126 | // MIPS64EL-NEXT: jr $ra | |
| 127 | // MIPS64EL-NEXT: nop | |
| 128 | va_arg(ap) | |
| 129 | } | |
| 130 | ||
| 131 | #[unsafe(no_mangle)] | |
| 132 | unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { | |
| 133 | // MIPS: read_ptr = read_i32 | |
| 134 | // MIPS64: read_ptr = read_i64 | |
| 135 | // MIPS64EL: read_ptr = read_i64 | |
| 136 | va_arg(ap) | |
| 137 | } |
tests/codegen-llvm/c-variadic-lifetime.rs+2-2| ... | ... | @@ -11,8 +11,8 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { |
| 11 | 11 | // CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args) |
| 12 | 12 | // CHECK: call void @llvm.va_start.p0(ptr nonnull %args) |
| 13 | 13 | |
| 14 | let b = args.arg::<f64>(); | |
| 15 | let c = args.arg::<f64>(); | |
| 14 | let b = args.next_arg::<f64>(); | |
| 15 | let c = args.next_arg::<f64>(); | |
| 16 | 16 | |
| 17 | 17 | a + b + c |
| 18 | 18 |
tests/codegen-llvm/cffi/c-variadic-inline.rs+4-4| ... | ... | @@ -8,22 +8,22 @@ |
| 8 | 8 | |
| 9 | 9 | #[inline(always)] |
| 10 | 10 | unsafe extern "C" fn inline_always(mut ap: ...) -> u32 { |
| 11 | ap.arg::<u32>() | |
| 11 | ap.next_arg::<u32>() | |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | #[inline] |
| 15 | 15 | unsafe extern "C" fn inline(mut ap: ...) -> u32 { |
| 16 | ap.arg::<u32>() | |
| 16 | ap.next_arg::<u32>() | |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | #[inline(never)] |
| 20 | 20 | unsafe extern "C" fn inline_never(mut ap: ...) -> u32 { |
| 21 | ap.arg::<u32>() | |
| 21 | ap.next_arg::<u32>() | |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | #[cold] |
| 25 | 25 | unsafe extern "C" fn cold(mut ap: ...) -> u32 { |
| 26 | ap.arg::<u32>() | |
| 26 | ap.next_arg::<u32>() | |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | #[unsafe(no_mangle)] |
tests/codegen-llvm/cffi/c-variadic.rs+1-1| ... | ... | @@ -28,7 +28,7 @@ pub unsafe extern "C" fn c_variadic(n: i32, mut ap: ...) -> i32 { |
| 28 | 28 | // CHECK: call void @llvm.va_start |
| 29 | 29 | let mut sum = 0; |
| 30 | 30 | for _ in 0..n { |
| 31 | sum += ap.arg::<i32>(); | |
| 31 | sum += ap.next_arg::<i32>(); | |
| 32 | 32 | } |
| 33 | 33 | sum |
| 34 | 34 | // CHECK: call void @llvm.va_end |
tests/codegen-llvm/scalable-vectors/tuple-intrinsics.rs+2-1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | //@ build-pass | |
| 1 | // FIXME: The FileCheck directives in this test are unchecked and probably broken. | |
| 2 | //@ skip-filecheck | |
| 2 | 3 | //@ only-aarch64 |
| 3 | 4 | #![crate_type = "lib"] |
| 4 | 5 | #![allow(incomplete_features, internal_features)] |
tests/codegen-llvm/simd/simd-wide-sum.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@ edition: 2021 |
| 4 | 4 | //@ only-x86_64 |
| 5 | 5 | //@ [mir-opt3]compile-flags: -Zmir-opt-level=3 |
| 6 | //@ [mir-opt3]build-pass | |
| 6 | //@ [mir-opt3] skip-filecheck | |
| 7 | 7 | |
| 8 | 8 | // mir-opt3 is a regression test for https://github.com/rust-lang/rust/issues/98016 |
| 9 | 9 |
tests/mir-opt/README.md+1-1| ... | ... | @@ -57,7 +57,7 @@ The LLVM FileCheck tool is used to verify the contents of output MIR against `CH |
| 57 | 57 | present in the test file. This works on the runtime MIR, generated by `--emit=mir`, and not |
| 58 | 58 | on the output of a individual passes. |
| 59 | 59 | |
| 60 | Use `// skip-filecheck` to prevent FileCheck from running. | |
| 60 | Use `//@ skip-filecheck` to prevent FileCheck from running. | |
| 61 | 61 | |
| 62 | 62 | To check MIR for function `foo`, start with a `// CHECK-LABEL fn foo(` directive. |
| 63 | 63 |
tests/mir-opt/address_of.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir |
| 3 | 3 | |
| 4 | 4 | fn address_of_reborrow() { |
tests/mir-opt/async_closure_fake_read_for_by_move.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ edition:2021 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | |
| 4 | 4 | enum Foo { |
| 5 | 5 | Bar, |
tests/mir-opt/async_closure_shims.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ edition:2021 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | |
| 4 | 4 | #![allow(unused)] |
| 5 | 5 |
tests/mir-opt/async_drop_live_dead.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ edition:2024 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 | |
| 5 | 5 | #![feature(async_drop)] |
tests/mir-opt/async_drop_mir_pin.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@edition: 2024 |
| 2 | 2 | //@ test-mir-pass: MentionedItems |
| 3 | // skip-filecheck | |
| 3 | //@ skip-filecheck | |
| 4 | 4 | #![feature(async_drop)] |
| 5 | 5 | #![allow(incomplete_features)] |
| 6 | 6 | use std::future::AsyncDrop; |
tests/mir-opt/box_conditional_drop_allocator.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: ElaborateDrops |
| 3 | 3 | //@ needs-unwind |
| 4 | 4 | #![feature(allocator_api)] |
tests/mir-opt/build_correct_coerce.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | |
| 3 | 3 | // Validate that we record the target for the `as` coercion as `for<'a> fn(&'a (), &'a ())`, |
| 4 | 4 | // and not `for<'a, 'b>(&'a (), &'b ())`. We previously did the latter due to a bug in |
tests/mir-opt/building/async_await.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // This test makes sure that the coroutine MIR pass eliminates all calls to |
| 3 | 3 | // `get_context`, and that the MIR argument type for an async fn and all locals |
| 4 | 4 | // related to `yield` are `&mut Context`, and its return type is `Poll`. |
tests/mir-opt/building/coroutine.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ edition:2024 |
| 3 | 3 | //@ compile-flags: -Zmir-opt-level=0 -C panic=abort |
| 4 | 4 |
tests/mir-opt/building/custom/aggregate_exprs.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/arbitrary_let.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/arrays.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/as_cast.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/assume.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/composite_return.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/consts.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/enums.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/operators.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: --crate-type=lib |
| 3 | 3 | #![feature(custom_mir, core_intrinsics)] |
| 4 | 4 | use std::intrinsics::mir::*; |
tests/mir-opt/building/custom/projections.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/references.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/simple_assign.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/custom/terminators.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(custom_mir, core_intrinsics)] |
| 3 | 3 | |
| 4 | 4 | extern crate core; |
tests/mir-opt/building/enum_cast.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // EMIT_MIR enum_cast.foo.built.after.mir |
| 4 | 4 | // EMIT_MIR enum_cast.bar.built.after.mir |
| 5 | 5 | // EMIT_MIR enum_cast.boo.built.after.mir |
tests/mir-opt/building/eq_never_type.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | #![feature(never_type)] |
| 4 | 4 | #![allow(unreachable_code)] |
| 5 | 5 |
tests/mir-opt/building/issue_101867.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // EMIT_MIR issue_101867.main.built.after.mir |
| 4 | 4 | fn main() { |
| 5 | 5 | let x: Option<u8> = Some(1); |
tests/mir-opt/building/issue_110508.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // EMIT_MIR issue_110508.{impl#0}-BAR.built.after.mir |
| 4 | 4 | // EMIT_MIR issue_110508.{impl#0}-SELF_BAR.built.after.mir |
| 5 | 5 |
tests/mir-opt/building/issue_49232.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // We must mark a variable whose initialization fails due to an |
| 4 | 4 | // abort statement as StorageDead. |
| 5 | 5 |
tests/mir-opt/building/logical_or_in_conditional.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=0 -Z validate-mir |
| 3 | 3 | //@ edition: 2024 |
| 4 | 4 | struct Droppy(u8); |
tests/mir-opt/building/loop_match_diverges.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![allow(incomplete_features)] |
| 3 | 3 | #![feature(loop_match)] |
| 4 | 4 | #![crate_type = "lib"] |
tests/mir-opt/building/match/deref-patterns/string.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=0 -C panic=abort |
| 3 | 3 | |
| 4 | 4 | #![feature(deref_patterns)] |
tests/mir-opt/building/match/exponential_or.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that simple or-patterns don't get expanded to exponentially large CFGs |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR exponential_or.match_tuple.SimplifyCfg-initial.after.mir |
tests/mir-opt/building/match/match_false_edges.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | fn guard() -> bool { |
| 3 | 3 | false |
| 4 | 4 | } |
tests/mir-opt/building/match/simple_match.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that we don't generate unnecessarily large MIR for very simple matches |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR simple_match.match_bool.built.after.mir |
tests/mir-opt/building/receiver_ptr_mutability.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // EMIT_MIR receiver_ptr_mutability.main.built.after.mir |
| 4 | 4 | |
| 5 | 5 | #![feature(arbitrary_self_types_pointers)] |
tests/mir-opt/building/shifts.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=0 -C debug-assertions=yes |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR shifts.shift_signed.built.after.mir |
tests/mir-opt/building/storage_live_dead_in_statics.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | // Check that when we compile the static `XXX` into MIR, we do not |
| 4 | 4 | // generate `StorageStart` or `StorageEnd` statements. |
| 5 | 5 |
tests/mir-opt/building/uniform_array_move_out.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | |
| 4 | 4 | // Can't emit `built.after` here as that contains user type annotations which contain DefId that |
| 5 | 5 | // change all the time. |
tests/mir-opt/building/user_type_annotations.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ compile-flags: -Zmir-opt-level=0 |
| 2 | 2 | //@ edition: 2024 |
| 3 | // skip-filecheck | |
| 3 | //@ skip-filecheck | |
| 4 | 4 | |
| 5 | 5 | // This test demonstrates how many user type annotations are recorded in MIR |
| 6 | 6 | // for various binding constructs. In particular, this makes it possible to see |
tests/mir-opt/byte_slice.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=0 |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR byte_slice.main.SimplifyCfg-pre-optimizations.after.mir |
tests/mir-opt/const_allocation.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | //@ ignore-endian-big |
| 4 | 4 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
tests/mir-opt/const_allocation2.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | //@ ignore-endian-big |
| 4 | 4 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
tests/mir-opt/const_allocation3.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | //@ ignore-endian-big |
| 4 | 4 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
tests/mir-opt/const_goto_const_eval_fail.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(min_const_generics)] |
| 3 | 3 | #![crate_type = "lib"] |
| 4 | 4 |
tests/mir-opt/const_promotion_extern_static.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ ignore-endian-big |
| 3 | 3 | extern "C" { |
| 4 | 4 | static X: i32; |
tests/mir-opt/const_prop/invalid_constant.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | //@ compile-flags: -Zmir-enable-passes=+RemoveZsts -Zdump-mir-exclude-alloc-bytes |
| 4 | 4 | // Verify that we can pretty print invalid constants. |
tests/mir-opt/const_prop/large_array_index.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
tests/mir-opt/const_prop/offset_of.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 |
tests/mir-opt/coroutine_drop_cleanup.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/coroutine_storage_dead_unwind.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | |
| 4 | 4 | // Test that we generate StorageDead on unwind paths for coroutines. |
tests/mir-opt/coroutine_tiny.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //! Tests that coroutines that cannot return or unwind don't have unnecessary |
| 3 | 3 | //! panic branches. |
| 4 | 4 |
tests/mir-opt/coverage/branch_match_arms.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | #![feature(coverage_attribute)] |
| 2 | 2 | //@ test-mir-pass: InstrumentCoverage |
| 3 | 3 | //@ compile-flags: -Cinstrument-coverage -Zno-profiler-runtime -Zcoverage-options=branch |
| 4 | // skip-filecheck | |
| 4 | //@ skip-filecheck | |
| 5 | 5 | |
| 6 | 6 | enum Enum { |
| 7 | 7 | A(u32), |
tests/mir-opt/dataflow.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test graphviz dataflow output |
| 3 | 3 | //@ compile-flags: -Z dump-mir=main -Z dump-mir-dataflow |
| 4 | 4 |
tests/mir-opt/derefer_complex_case.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Derefer |
| 3 | 3 | // EMIT_MIR derefer_complex_case.main.Derefer.diff |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/derefer_inline_test.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Derefer |
| 3 | 3 | // EMIT_MIR derefer_inline_test.main.Derefer.diff |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/derefer_terminator_test.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Derefer |
| 3 | 3 | // EMIT_MIR derefer_terminator_test.main.Derefer.diff |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/derefer_test.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Derefer |
| 3 | 3 | // EMIT_MIR derefer_test.main.Derefer.diff |
| 4 | 4 | fn main() { |
tests/mir-opt/derefer_test_multiple.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Derefer |
| 3 | 3 | // EMIT_MIR derefer_test_multiple.main.Derefer.diff |
| 4 | 4 | fn main() { |
tests/mir-opt/dest-prop/nrvo_borrowed.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | //@ test-mir-pass: DestinationPropagation |
| 4 | 4 |
tests/mir-opt/dont_inline_type_id.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Inline |
| 3 | 3 | //@ compile-flags: --crate-type=lib -C panic=abort |
| 4 | 4 |
tests/mir-opt/elaborate_box_deref_in_debuginfo.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: ElaborateBoxDerefs |
| 3 | 3 | |
| 4 | 4 | #![feature(custom_mir, core_intrinsics)] |
tests/mir-opt/enum_opt.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: EnumSizeOpt |
| 3 | 3 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
| 4 | 4 | //@ compile-flags: -Zunsound-mir-opts |
tests/mir-opt/fn_ptr_shim.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=0 |
| 3 | 3 | |
| 4 | 4 | // Tests that the `<fn() as Fn>` shim does not create a `Call` terminator with a `Self` callee |
tests/mir-opt/funky_arms.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
| 4 | 4 |
tests/mir-opt/global_asm.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ needs-asm-support |
| 3 | 3 | |
| 4 | 4 | // `global_asm!` gets a fake body, make sure it is handled correctly |
tests/mir-opt/graphviz.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test graphviz output |
| 3 | 3 | //@ compile-flags: -Z dump-mir-graphviz |
| 4 | 4 |
tests/mir-opt/gvn_on_unsafe_binder.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR gvn_on_unsafe_binder.test.GVN.diff |
tests/mir-opt/gvn_ptr_eq_with_constant.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: GVN |
| 3 | 3 | //@ only-64bit |
| 4 | 4 | //@ compile-flags: -Z mir-enable-passes=+Inline |
tests/mir-opt/gvn_uninhabited.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ test-mir-pass: GVN |
| 2 | 2 | //@ compile-flags: -O |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | // skip-filecheck | |
| 4 | //@ skip-filecheck | |
| 5 | 5 | |
| 6 | 6 | #![feature(never_type)] |
| 7 | 7 |
tests/mir-opt/impossible_predicates.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR impossible_predicates.impossible_predicate.ImpossiblePredicates.diff |
| 3 | 3 | |
| 4 | 4 | pub fn impossible_predicate(x: &mut i32) -> (&mut i32, &mut i32) |
tests/mir-opt/inline/inline_async.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Checks that inliner doesn't introduce cycles when optimizing coroutines. |
| 3 | 3 | // The outcome of optimization is not verfied, just the absence of the cycle. |
| 4 | 4 | // Regression test for #76181. |
tests/mir-opt/inline/inline_compatibility.rs+1-1| ... | ... | @@ -70,7 +70,7 @@ unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 { |
| 70 | 70 | let mut s = 0; |
| 71 | 71 | let mut i = 0; |
| 72 | 72 | while i != n { |
| 73 | s += vs.arg::<u32>(); | |
| 73 | s += vs.next_arg::<u32>(); | |
| 74 | 74 | i += 1; |
| 75 | 75 | } |
| 76 | 76 | s |
tests/mir-opt/inline/inline_cycle.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -C debuginfo=full |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 | // Check that inliner handles various forms of recursion and doesn't fall into |
tests/mir-opt/inline/inline_cycle_generic.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // Check that inliner handles various forms of recursion and doesn't fall into |
| 4 | 4 | // an infinite inlining cycle. The particular outcome of inlining is not |
tests/mir-opt/inline/polymorphic_recursion.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Make sure that the MIR inliner does not loop indefinitely on polymorphic recursion. |
| 3 | 3 | //@ compile-flags: --crate-type lib |
| 4 | 4 |
tests/mir-opt/inline/recursion_limit_prevents_cycle_discovery.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ aux-build: wrapper.rs |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=2 -Zinline-mir |
| 3 | // skip-filecheck | |
| 3 | //@ skip-filecheck | |
| 4 | 4 | |
| 5 | 5 | // This is a regression test for https://github.com/rust-lang/rust/issues/146998 |
| 6 | 6 |
tests/mir-opt/inline/type_overflow.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // This is a regression test for one of the problems in #128887; it checks that the |
| 2 | 2 | // strategy in #129714 avoids trait solver overflows in this specific case. |
| 3 | 3 | |
| 4 | // skip-filecheck | |
| 4 | //@ skip-filecheck | |
| 5 | 5 | //@ compile-flags: -Zinline-mir |
| 6 | 6 | |
| 7 | 7 | pub trait Foo { |
tests/mir-opt/inline/unit_test.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // Check that `-Zmir-enable-passes=+Inline` does not ICE because of stolen MIR. |
| 2 | 2 | //@ test-mir-pass: Inline |
| 3 | // skip-filecheck | |
| 3 | //@ skip-filecheck | |
| 4 | 4 | #![crate_type = "lib"] |
| 5 | 5 | |
| 6 | 6 | // Randomize `def_path_hash` by defining them under a module with different names |
tests/mir-opt/inline_coroutine_body.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | //@ test-mir-pass: Inline |
| 4 | 4 | //@ edition: 2021 |
| 5 | 5 | //@ compile-flags: -Zinline-mir-hint-threshold=10000 -Zinline-mir-threshold=10000 --crate-type=lib |
tests/mir-opt/inline_default_trait_body.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | //@ test-mir-pass: Inline |
| 4 | 4 | //@ edition: 2021 |
| 5 | 5 | //@ compile-flags: -Zinline-mir --crate-type=lib |
tests/mir-opt/inline_double_cycle.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | //@ test-mir-pass: Inline |
| 4 | 4 | //@ edition: 2021 |
| 5 | 5 | //@ compile-flags: -Zinline-mir --crate-type=lib |
tests/mir-opt/inline_generically_if_sized.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: Inline |
| 3 | 3 | //@ compile-flags: --crate-type=lib -C panic=abort |
| 4 | 4 |
tests/mir-opt/issue_101973.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | //@ compile-flags: -O -C debug-assertions=on |
| 4 | 4 | // This needs inlining followed by GVN to reproduce, so we cannot use "test-mir-pass". |
tests/mir-opt/issue_104451_unwindable_intrinsics.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Check that `UnwindAction::Unreachable` is not generated for unwindable intrinsics. |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 | #![feature(core_intrinsics)] |
tests/mir-opt/issue_120925_unsafefncast.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // Verify that we do not ICE when attempting to interpret casts between fn types. |
| 2 | // skip-filecheck | |
| 2 | //@ skip-filecheck | |
| 3 | 3 | |
| 4 | 4 | static FOO: fn() = || assert_ne!(42, 43); |
| 5 | 5 | static BAR: fn(i32, i32) = |a, b| assert_ne!(a, b); |
tests/mir-opt/issue_38669.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // check that we don't StorageDead booleans before they are used |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR issue_38669.main.SimplifyCfg-initial.after.mir |
tests/mir-opt/issue_41110.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | |
| 4 | 4 | // check that we don't emit multiple drop flags when they are not needed. |
tests/mir-opt/issue_41697.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Regression test for #41697. Using dump-mir was triggering |
| 3 | 3 | // artificial cycles: during type-checking, we had to get the MIR for |
| 4 | 4 | // the constant expressions in `[u8; 2]`, which in turn would trigger |
tests/mir-opt/issue_41888.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // check that we clear the "ADT master drop flag" even when there are |
| 4 | 4 | // no fields to be dropped. |
tests/mir-opt/issue_62289.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // check that we don't forget to drop the Box if we early return before |
| 3 | 3 | // initializing it |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/issue_72181.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=1 |
| 3 | 3 | // Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags. |
| 4 | 4 |
tests/mir-opt/issue_72181_1.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=1 |
| 3 | 3 | // Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags. |
| 4 | 4 |
tests/mir-opt/issue_76432.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // Check that we do not insert StorageDead at each target if StorageDead was never seen |
| 4 | 4 |
tests/mir-opt/issue_78192.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=1 -Zinline-mir |
| 3 | 3 | pub fn f<T>(a: &T) -> *const T { |
| 4 | 4 | let b: &*const T = &(a as *const T); |
tests/mir-opt/issue_91633.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=0 |
| 3 | 3 | // EMIT_MIR issue_91633.hey.built.after.mir |
| 4 | 4 | fn hey<T>(it: &[T]) |
tests/mir-opt/issue_99325.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
| 3 | 3 | |
| 4 | 4 | #![feature(adt_const_params, unsized_const_params)] |
tests/mir-opt/loop_test.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z identify_regions |
| 3 | 3 | |
| 4 | 4 | // Tests to make sure we correctly generate falseUnwind edges in loops |
tests/mir-opt/match_arm_scopes.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // Test that StorageDead and Drops are generated properly for bindings in |
| 4 | 4 | // matches: |
tests/mir-opt/matches_u8.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: MatchBranchSimplification |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff |
tests/mir-opt/multiple_return_terminators.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Z mir-opt-level=4 |
| 3 | 3 | // EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff |
| 4 | 4 |
tests/mir-opt/nll/named_lifetimes_basic.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Basic test for named lifetime translation. Check that we |
| 3 | 3 | // instantiate the types that appear in function arguments with |
| 4 | 4 | // suitable variables and that we setup the outlives relationship |
tests/mir-opt/nll/region_subtyping_basic.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Basic test for liveness constraints: the region (`R1`) that appears |
| 3 | 3 | // in the type of `p` includes the points after `&v[0]` up to (but not |
| 4 | 4 | // including) the call to `use_x`. The `else` branch is not included. |
tests/mir-opt/no_drop_for_inactive_variant.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | |
| 4 | 4 | // Ensure that there are no drop terminators in `unwrap<T>` (except the one along the cleanup |
tests/mir-opt/no_spurious_drop_after_call.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | |
| 4 | 4 | // Test that after the call to `std::mem::drop` we do not generate a |
tests/mir-opt/or_pattern.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | |
| 3 | 3 | // EMIT_MIR or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir |
| 4 | 4 | fn shortcut_second_or() { |
tests/mir-opt/packed_struct_drop_aligned.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-pre-optimizations.after.mir |
tests/mir-opt/pre-codegen/chained_comparison.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2 |
| 3 | 3 | |
| 4 | 4 | #![crate_type = "lib"] |
tests/mir-opt/pre-codegen/duplicate_switch_targets.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 |
| 3 | 3 | |
| 4 | 4 | #![crate_type = "lib"] |
tests/mir-opt/pre-codegen/intrinsics.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 |
| 3 | 3 | |
| 4 | 4 | // Checks that we do not have any branches in the MIR for the two tested functions. |
tests/mir-opt/pre-codegen/loops.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -Zmir-opt-level=2 -g |
| 3 | 3 | //@ ignore-std-debug-assertions (debug assertions result in different inlines) |
| 4 | 4 | //@ needs-unwind |
tests/mir-opt/pre-codegen/mem_replace.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir |
| 3 | 3 | //@ ignore-std-debug-assertions |
| 4 | 4 | // Reason: precondition checks on ptr::read/write are under cfg(debug_assertions) |
tests/mir-opt/pre-codegen/optimizes_into_variable.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | //@ compile-flags: -C overflow-checks=on -Zdump-mir-exclude-alloc-bytes |
| 4 | 4 |
tests/mir-opt/pre-codegen/ptr_offset.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir |
| 3 | 3 | //@ ignore-std-debug-assertions (precondition checks are under cfg(debug_assertions)) |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/pre-codegen/range_iter.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 |
tests/mir-opt/pre-codegen/slice_filter.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2 |
| 3 | 3 | |
| 4 | 4 | #![crate_type = "lib"] |
tests/mir-opt/pre-codegen/slice_iter.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 |
| 3 | 3 | //@ only-64bit (constants for `None::<&T>` show in the output) |
| 4 | 4 | //@ ignore-std-debug-assertions (precondition checks on ptr::add are under cfg(debug_assertions)) |
tests/mir-opt/pre-codegen/spans.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that the comments we emit in MIR opts are accurate. |
| 3 | 3 | // |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/pre-codegen/try_identity.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 |
| 3 | 3 | |
| 4 | 4 | // Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings |
tests/mir-opt/pre-codegen/vec_deref.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2 |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 |
tests/mir-opt/remove_fake_borrows.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that the fake borrows for matches are removed after borrow checking. |
| 3 | 3 | |
| 4 | 4 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
tests/mir-opt/remove_never_const.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // This was originally a regression test for #66975 - ensure that we do not generate never typed |
| 3 | 3 | // consts in codegen. We also have tests for this that catches the error, see |
| 4 | 4 | // tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs. |
tests/mir-opt/retag.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: AddRetag |
| 3 | 3 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 4 | 4 | // ignore-tidy-linelength |
tests/mir-opt/return_an_array.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // this tests move up progration, which is not yet implemented |
| 3 | 3 | |
| 4 | 4 | fn foo() -> [u8; 1024] { |
tests/mir-opt/separate_const_switch.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | #![feature(try_trait_v2)] |
| 3 | 3 | |
| 4 | 4 | //@ compile-flags: -Zunsound-mir-opts |
tests/mir-opt/simplify_cfg.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that the goto chain starting from bb0 is collapsed. |
| 3 | 3 | //@ compile-flags: -Cpanic=abort |
| 4 | 4 | //@ no-prefer-dynamic |
tests/mir-opt/simplify_locals.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: SimplifyLocals-before-const-prop |
| 3 | 3 | |
| 4 | 4 | #![feature(thread_local)] |
tests/mir-opt/simplify_locals_removes_unused_consts.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | //@ test-mir-pass: SimplifyLocals-before-const-prop |
| 4 | 4 | //@ compile-flags: -C overflow-checks=no |
tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ test-mir-pass: SimplifyLocals-before-const-prop |
| 3 | 3 | |
| 4 | 4 | fn map(x: Option<Box<()>>) -> Option<Box<()>> { |
tests/mir-opt/slice_drop_shim.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | //@ compile-flags: -Zmir-opt-level=0 -Clink-dead-code |
| 3 | 3 | // mir-opt tests are always built as rlibs so that they seamlessly cross-compile, |
| 4 | 4 | // so this test only produces MIR for the drop_in_place we're looking for |
tests/mir-opt/ssa_unreachable_116212.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Regression test for issue #116212. |
| 3 | 3 | |
| 4 | 4 | #![feature(never_type)] |
tests/mir-opt/storage_ranges.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR storage_ranges.main.nll.0.mir |
| 3 | 3 | |
| 4 | 4 | fn main() { |
tests/mir-opt/switch_to_self.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that MatchBranchSimplification doesn't ICE on a SwitchInt where |
| 3 | 3 | // one of the targets is the block that the SwitchInt terminates. |
| 4 | 4 | #![crate_type = "lib"] |
tests/mir-opt/tail_call_drops.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | #![allow(incomplete_features)] |
| 4 | 4 | #![feature(explicit_tail_calls)] |
tests/mir-opt/tail_expr_drop_order_unwind.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR_FOR_EACH_PANIC_STRATEGY |
| 3 | 3 | // EMIT_MIR tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.mir |
| 4 | 4 |
tests/mir-opt/tls_access.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // EMIT_MIR tls_access.main.PreCodegen.after.mir |
| 3 | 3 | //@ compile-flags: -Zmir-opt-level=0 |
| 4 | 4 |
tests/mir-opt/uninhabited_enum.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // |
| 3 | 3 | // check that we mark blocks with `!` locals as unreachable. |
| 4 | 4 | // (and currently don't do the same for other uninhabited types) |
tests/mir-opt/uninhabited_fallthrough_elimination.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | enum Empty {} |
| 3 | 3 | |
| 4 | 4 | enum S { |
tests/mir-opt/uninhabited_not_read.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | |
| 3 | 3 | //@ edition: 2021 |
| 4 | 4 | // In ed 2021 and below, we fallback `!` to `()`. |
tests/mir-opt/unusual_item_types.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | // skip-filecheck | |
| 1 | //@ skip-filecheck | |
| 2 | 2 | // Test that we don't ICE when trying to dump MIR for unusual item types and |
| 3 | 3 | // that we don't create filenames containing `<` and `>` |
| 4 | 4 | //@ compile-flags: -Zmir-opt-level=0 |
tests/pretty/fn-variadic.rs+1-1| ... | ... | @@ -9,7 +9,7 @@ extern "C" { |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | 11 | pub unsafe extern "C" fn bar(_: i32, mut ap: ...) -> usize { |
| 12 | ap.arg::<usize>() | |
| 12 | ap.next_arg::<usize>() | |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn main() {} |
tests/pretty/hir-fn-variadic.pp+2-1| ... | ... | @@ -11,7 +11,8 @@ extern "C" { |
| 11 | 11 | unsafe fn foo(x: i32, va1: ...); |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { va2.arg::<usize>() } | |
| 14 | unsafe extern "C" fn bar(_: i32, mut va2: ...) | |
| 15 | -> usize { va2.next_arg::<usize>() } | |
| 15 | 16 | |
| 16 | 17 | fn main() { |
| 17 | 18 | fn g1(_: extern "C" fn(_: u8, va: ...)) { } |
tests/pretty/hir-fn-variadic.rs+13-5| ... | ... | @@ -9,7 +9,7 @@ extern "C" { |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | 11 | pub unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { |
| 12 | va2.arg::<usize>() | |
| 12 | va2.next_arg::<usize>() | |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn main() { |
| ... | ... | @@ -21,9 +21,17 @@ fn main() { |
| 21 | 21 | fn g5(_: extern "C" fn(va: ...)) {} |
| 22 | 22 | fn g6(_: extern "C" fn(_: ...)) {} |
| 23 | 23 | |
| 24 | _ = { unsafe extern "C" fn f1(_: u8, va: ...) {} }; | |
| 25 | _ = { unsafe extern "C" fn f2(_: u8, _: ...) {} }; | |
| 24 | _ = { | |
| 25 | unsafe extern "C" fn f1(_: u8, va: ...) {} | |
| 26 | }; | |
| 27 | _ = { | |
| 28 | unsafe extern "C" fn f2(_: u8, _: ...) {} | |
| 29 | }; | |
| 26 | 30 | |
| 27 | _ = { unsafe extern "C" fn f5(va: ...) {} }; | |
| 28 | _ = { unsafe extern "C" fn f6(_: ...) {} }; | |
| 31 | _ = { | |
| 32 | unsafe extern "C" fn f5(va: ...) {} | |
| 33 | }; | |
| 34 | _ = { | |
| 35 | unsafe extern "C" fn f6(_: ...) {} | |
| 36 | }; | |
| 29 | 37 | } |
tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs+77-77| ... | ... | @@ -17,59 +17,59 @@ unsafe fn compare_c_str(ptr: *const c_char, val: &CStr) -> bool { |
| 17 | 17 | |
| 18 | 18 | #[unsafe(no_mangle)] |
| 19 | 19 | pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize { |
| 20 | continue_if!(ap.arg::<c_longlong>() == 1); | |
| 21 | continue_if!(ap.arg::<c_int>() == 2); | |
| 22 | continue_if!(ap.arg::<c_longlong>() == 3); | |
| 20 | continue_if!(ap.next_arg::<c_longlong>() == 1); | |
| 21 | continue_if!(ap.next_arg::<c_int>() == 2); | |
| 22 | continue_if!(ap.next_arg::<c_longlong>() == 3); | |
| 23 | 23 | 0 |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | #[unsafe(no_mangle)] |
| 27 | 27 | pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize { |
| 28 | continue_if!(ap.arg::<c_int>() == -1); | |
| 29 | continue_if!(ap.arg::<c_int>() == 'A' as c_int); | |
| 30 | continue_if!(ap.arg::<c_int>() == '4' as c_int); | |
| 31 | continue_if!(ap.arg::<c_int>() == ';' as c_int); | |
| 32 | continue_if!(ap.arg::<c_int>() == 0x32); | |
| 33 | continue_if!(ap.arg::<i32>() == 0x10000001); | |
| 34 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Valid!")); | |
| 28 | continue_if!(ap.next_arg::<c_int>() == -1); | |
| 29 | continue_if!(ap.next_arg::<c_int>() == 'A' as c_int); | |
| 30 | continue_if!(ap.next_arg::<c_int>() == '4' as c_int); | |
| 31 | continue_if!(ap.next_arg::<c_int>() == ';' as c_int); | |
| 32 | continue_if!(ap.next_arg::<c_int>() == 0x32); | |
| 33 | continue_if!(ap.next_arg::<i32>() == 0x10000001); | |
| 34 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), c"Valid!")); | |
| 35 | 35 | 0 |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | #[unsafe(no_mangle)] |
| 39 | 39 | pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize { |
| 40 | continue_if!(ap.arg::<c_double>() == 3.14); | |
| 41 | continue_if!(ap.arg::<c_long>() == 12); | |
| 42 | continue_if!(ap.arg::<c_int>() == 'a' as c_int); | |
| 43 | continue_if!(ap.arg::<c_double>() == 6.28); | |
| 44 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Hello")); | |
| 45 | continue_if!(ap.arg::<c_int>() == 42); | |
| 46 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"World")); | |
| 40 | continue_if!(ap.next_arg::<c_double>() == 3.14); | |
| 41 | continue_if!(ap.next_arg::<c_long>() == 12); | |
| 42 | continue_if!(ap.next_arg::<c_int>() == 'a' as c_int); | |
| 43 | continue_if!(ap.next_arg::<c_double>() == 6.28); | |
| 44 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), c"Hello")); | |
| 45 | continue_if!(ap.next_arg::<c_int>() == 42); | |
| 46 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), c"World")); | |
| 47 | 47 | 0 |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | #[unsafe(no_mangle)] |
| 51 | 51 | pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { |
| 52 | continue_if!(ap.arg::<c_double>() == 6.28); | |
| 53 | continue_if!(ap.arg::<c_int>() == 16); | |
| 54 | continue_if!(ap.arg::<c_int>() == 'A' as c_int); | |
| 55 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Skip Me!")); | |
| 52 | continue_if!(ap.next_arg::<c_double>() == 6.28); | |
| 53 | continue_if!(ap.next_arg::<c_int>() == 16); | |
| 54 | continue_if!(ap.next_arg::<c_int>() == 'A' as c_int); | |
| 55 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), c"Skip Me!")); | |
| 56 | 56 | let mut ap = ap.clone(); |
| 57 | if compare_c_str(ap.arg::<*const c_char>(), c"Correct") { 0 } else { 0xff } | |
| 57 | if compare_c_str(ap.next_arg::<*const c_char>(), c"Correct") { 0 } else { 0xff } | |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | #[unsafe(no_mangle)] |
| 61 | 61 | pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize { |
| 62 | continue_if!(ap.arg::<c_int>() == 42); | |
| 63 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Hello, World!")); | |
| 62 | continue_if!(ap.next_arg::<c_int>() == 42); | |
| 63 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), c"Hello, World!")); | |
| 64 | 64 | 0 |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | #[unsafe(no_mangle)] |
| 68 | 68 | pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { |
| 69 | continue_if!(ap.arg::<c_double>() == 3.14); | |
| 70 | continue_if!(ap.arg::<c_long>() == 12); | |
| 71 | continue_if!(ap.arg::<c_int>() == 'A' as c_int); | |
| 72 | continue_if!(ap.arg::<c_longlong>() == 1); | |
| 69 | continue_if!(ap.next_arg::<c_double>() == 3.14); | |
| 70 | continue_if!(ap.next_arg::<c_long>() == 12); | |
| 71 | continue_if!(ap.next_arg::<c_int>() == 'A' as c_int); | |
| 72 | continue_if!(ap.next_arg::<c_longlong>() == 1); | |
| 73 | 73 | 0 |
| 74 | 74 | } |
| 75 | 75 | |
| ... | ... | @@ -80,65 +80,65 @@ pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize { |
| 80 | 80 | |
| 81 | 81 | #[unsafe(no_mangle)] |
| 82 | 82 | pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize { |
| 83 | continue_if!(ap.arg::<c_int>() == 1); | |
| 84 | continue_if!(ap.arg::<c_int>() == 2); | |
| 85 | continue_if!(ap.arg::<c_int>() == 3); | |
| 86 | continue_if!(ap.arg::<c_int>() == 4); | |
| 87 | continue_if!(ap.arg::<c_int>() == 5); | |
| 88 | continue_if!(ap.arg::<c_int>() == 6); | |
| 89 | continue_if!(ap.arg::<c_int>() == 7); | |
| 90 | continue_if!(ap.arg::<c_int>() == 8); | |
| 91 | continue_if!(ap.arg::<c_int>() == 9); | |
| 92 | continue_if!(ap.arg::<c_int>() == 10); | |
| 83 | continue_if!(ap.next_arg::<c_int>() == 1); | |
| 84 | continue_if!(ap.next_arg::<c_int>() == 2); | |
| 85 | continue_if!(ap.next_arg::<c_int>() == 3); | |
| 86 | continue_if!(ap.next_arg::<c_int>() == 4); | |
| 87 | continue_if!(ap.next_arg::<c_int>() == 5); | |
| 88 | continue_if!(ap.next_arg::<c_int>() == 6); | |
| 89 | continue_if!(ap.next_arg::<c_int>() == 7); | |
| 90 | continue_if!(ap.next_arg::<c_int>() == 8); | |
| 91 | continue_if!(ap.next_arg::<c_int>() == 9); | |
| 92 | continue_if!(ap.next_arg::<c_int>() == 10); | |
| 93 | 93 | 0 |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | #[unsafe(no_mangle)] |
| 97 | 97 | pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize { |
| 98 | continue_if!(ap.arg::<c_double>() == 1.0); | |
| 99 | continue_if!(ap.arg::<c_double>() == 2.0); | |
| 100 | continue_if!(ap.arg::<c_double>() == 3.0); | |
| 101 | continue_if!(ap.arg::<c_double>() == 4.0); | |
| 102 | continue_if!(ap.arg::<c_double>() == 5.0); | |
| 103 | continue_if!(ap.arg::<c_double>() == 6.0); | |
| 104 | continue_if!(ap.arg::<c_double>() == 7.0); | |
| 105 | continue_if!(ap.arg::<c_double>() == 8.0); | |
| 106 | continue_if!(ap.arg::<c_double>() == 9.0); | |
| 107 | continue_if!(ap.arg::<c_double>() == 10.0); | |
| 108 | continue_if!(ap.arg::<c_double>() == 11.0); | |
| 109 | continue_if!(ap.arg::<c_double>() == 12.0); | |
| 110 | continue_if!(ap.arg::<c_double>() == 13.0); | |
| 98 | continue_if!(ap.next_arg::<c_double>() == 1.0); | |
| 99 | continue_if!(ap.next_arg::<c_double>() == 2.0); | |
| 100 | continue_if!(ap.next_arg::<c_double>() == 3.0); | |
| 101 | continue_if!(ap.next_arg::<c_double>() == 4.0); | |
| 102 | continue_if!(ap.next_arg::<c_double>() == 5.0); | |
| 103 | continue_if!(ap.next_arg::<c_double>() == 6.0); | |
| 104 | continue_if!(ap.next_arg::<c_double>() == 7.0); | |
| 105 | continue_if!(ap.next_arg::<c_double>() == 8.0); | |
| 106 | continue_if!(ap.next_arg::<c_double>() == 9.0); | |
| 107 | continue_if!(ap.next_arg::<c_double>() == 10.0); | |
| 108 | continue_if!(ap.next_arg::<c_double>() == 11.0); | |
| 109 | continue_if!(ap.next_arg::<c_double>() == 12.0); | |
| 110 | continue_if!(ap.next_arg::<c_double>() == 13.0); | |
| 111 | 111 | 0 |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | #[unsafe(no_mangle)] |
| 115 | 115 | pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize { |
| 116 | continue_if!(ap.arg::<c_double>() == 1.0); | |
| 117 | continue_if!(ap.arg::<c_int>() == 1); | |
| 118 | continue_if!(ap.arg::<c_double>() == 2.0); | |
| 119 | continue_if!(ap.arg::<c_int>() == 2); | |
| 120 | continue_if!(ap.arg::<c_double>() == 3.0); | |
| 121 | continue_if!(ap.arg::<c_int>() == 3); | |
| 122 | continue_if!(ap.arg::<c_double>() == 4.0); | |
| 123 | continue_if!(ap.arg::<c_int>() == 4); | |
| 124 | continue_if!(ap.arg::<c_int>() == 5); | |
| 125 | continue_if!(ap.arg::<c_double>() == 5.0); | |
| 126 | continue_if!(ap.arg::<c_int>() == 6); | |
| 127 | continue_if!(ap.arg::<c_double>() == 6.0); | |
| 128 | continue_if!(ap.arg::<c_int>() == 7); | |
| 129 | continue_if!(ap.arg::<c_double>() == 7.0); | |
| 130 | continue_if!(ap.arg::<c_int>() == 8); | |
| 131 | continue_if!(ap.arg::<c_double>() == 8.0); | |
| 132 | continue_if!(ap.arg::<c_int>() == 9); | |
| 133 | continue_if!(ap.arg::<c_double>() == 9.0); | |
| 134 | continue_if!(ap.arg::<c_int>() == 10); | |
| 135 | continue_if!(ap.arg::<c_double>() == 10.0); | |
| 136 | continue_if!(ap.arg::<c_int>() == 11); | |
| 137 | continue_if!(ap.arg::<c_double>() == 11.0); | |
| 138 | continue_if!(ap.arg::<c_int>() == 12); | |
| 139 | continue_if!(ap.arg::<c_double>() == 12.0); | |
| 140 | continue_if!(ap.arg::<c_int>() == 13); | |
| 141 | continue_if!(ap.arg::<c_double>() == 13.0); | |
| 116 | continue_if!(ap.next_arg::<c_double>() == 1.0); | |
| 117 | continue_if!(ap.next_arg::<c_int>() == 1); | |
| 118 | continue_if!(ap.next_arg::<c_double>() == 2.0); | |
| 119 | continue_if!(ap.next_arg::<c_int>() == 2); | |
| 120 | continue_if!(ap.next_arg::<c_double>() == 3.0); | |
| 121 | continue_if!(ap.next_arg::<c_int>() == 3); | |
| 122 | continue_if!(ap.next_arg::<c_double>() == 4.0); | |
| 123 | continue_if!(ap.next_arg::<c_int>() == 4); | |
| 124 | continue_if!(ap.next_arg::<c_int>() == 5); | |
| 125 | continue_if!(ap.next_arg::<c_double>() == 5.0); | |
| 126 | continue_if!(ap.next_arg::<c_int>() == 6); | |
| 127 | continue_if!(ap.next_arg::<c_double>() == 6.0); | |
| 128 | continue_if!(ap.next_arg::<c_int>() == 7); | |
| 129 | continue_if!(ap.next_arg::<c_double>() == 7.0); | |
| 130 | continue_if!(ap.next_arg::<c_int>() == 8); | |
| 131 | continue_if!(ap.next_arg::<c_double>() == 8.0); | |
| 132 | continue_if!(ap.next_arg::<c_int>() == 9); | |
| 133 | continue_if!(ap.next_arg::<c_double>() == 9.0); | |
| 134 | continue_if!(ap.next_arg::<c_int>() == 10); | |
| 135 | continue_if!(ap.next_arg::<c_double>() == 10.0); | |
| 136 | continue_if!(ap.next_arg::<c_int>() == 11); | |
| 137 | continue_if!(ap.next_arg::<c_double>() == 11.0); | |
| 138 | continue_if!(ap.next_arg::<c_int>() == 12); | |
| 139 | continue_if!(ap.next_arg::<c_double>() == 12.0); | |
| 140 | continue_if!(ap.next_arg::<c_int>() == 13); | |
| 141 | continue_if!(ap.next_arg::<c_double>() == 13.0); | |
| 142 | 142 | 0 |
| 143 | 143 | } |
| 144 | 144 |
tests/ui/abi/variadic-ffi.rs+6-6| ... | ... | @@ -28,20 +28,20 @@ pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { |
| 28 | 28 | |
| 29 | 29 | // Advance one pair in the copy before checking |
| 30 | 30 | let mut ap2 = ap.clone(); |
| 31 | let _ = ap2.arg::<u64>(); | |
| 32 | let _ = ap2.arg::<f64>(); | |
| 31 | let _ = ap2.next_arg::<u64>(); | |
| 32 | let _ = ap2.next_arg::<f64>(); | |
| 33 | 33 | assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); |
| 34 | 34 | |
| 35 | 35 | // Advance one pair in the original |
| 36 | let _ = ap.arg::<u64>(); | |
| 37 | let _ = ap.arg::<f64>(); | |
| 36 | let _ = ap.next_arg::<u64>(); | |
| 37 | let _ = ap.next_arg::<f64>(); | |
| 38 | 38 | |
| 39 | 39 | let ap2 = ap.clone(); |
| 40 | 40 | assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); |
| 41 | 41 | |
| 42 | 42 | let mut ap2 = ap.clone(); |
| 43 | let _ = ap2.arg::<u64>(); | |
| 44 | let _ = ap2.arg::<f64>(); | |
| 43 | let _ = ap2.next_arg::<u64>(); | |
| 44 | let _ = ap2.next_arg::<f64>(); | |
| 45 | 45 | assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 70); |
| 46 | 46 | } |
| 47 | 47 |
tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/155204> | |
| 2 | //@compile-flags: -Znext-solver=globally | |
| 3 | #![feature(inherent_associated_types)] | |
| 4 | pub struct Windows<T> {} | |
| 5 | //~^ ERROR type parameter `T` is never used | |
| 6 | ||
| 7 | impl<T> Windows<fn(&())> { | |
| 8 | //~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates | |
| 9 | type AssocType = impl Send; | |
| 10 | //~^ ERROR `impl Trait` in associated types is unstable | |
| 11 | //~| ERROR unconstrained opaque type | |
| 12 | fn ret(&self) -> Self::AssocType { | |
| 13 | //~^ ERROR type annotations needed | |
| 14 | () | |
| 15 | //~^ ERROR mismatched types | |
| 16 | } | |
| 17 | } | |
| 18 | //~^ ERROR `main` function not found |
tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.stderr created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | error[E0658]: `impl Trait` in associated types is unstable | |
| 2 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:9:22 | |
| 3 | | | |
| 4 | LL | type AssocType = impl Send; | |
| 5 | | ^^^^^^^^^ | |
| 6 | | | |
| 7 | = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information | |
| 8 | = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable | |
| 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 10 | ||
| 11 | error[E0601]: `main` function not found in crate `next_solver_opaque_inherent_fn_ptr_issue_155204` | |
| 12 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:17:2 | |
| 13 | | | |
| 14 | LL | } | |
| 15 | | ^ consider adding a `main` function to `$DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs` | |
| 16 | ||
| 17 | error[E0392]: type parameter `T` is never used | |
| 18 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:4:20 | |
| 19 | | | |
| 20 | LL | pub struct Windows<T> {} | |
| 21 | | ^ unused type parameter | |
| 22 | | | |
| 23 | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` | |
| 24 | = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead | |
| 25 | ||
| 26 | error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates | |
| 27 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:7:6 | |
| 28 | | | |
| 29 | LL | impl<T> Windows<fn(&())> { | |
| 30 | | ^ unconstrained type parameter | |
| 31 | ||
| 32 | error[E0282]: type annotations needed | |
| 33 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:12:22 | |
| 34 | | | |
| 35 | LL | fn ret(&self) -> Self::AssocType { | |
| 36 | | ^^^^^^^^^^^^^^^ cannot infer type | |
| 37 | ||
| 38 | error: unconstrained opaque type | |
| 39 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:9:22 | |
| 40 | | | |
| 41 | LL | type AssocType = impl Send; | |
| 42 | | ^^^^^^^^^ | |
| 43 | | | |
| 44 | = note: `AssocType` must be used in combination with a concrete type within the same impl | |
| 45 | ||
| 46 | error[E0308]: mismatched types | |
| 47 | --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:14:9 | |
| 48 | | | |
| 49 | LL | fn ret(&self) -> Self::AssocType { | |
| 50 | | --------------- expected `Windows<for<'a> fn(&'a ())>::AssocType` because of return type | |
| 51 | LL | | |
| 52 | LL | () | |
| 53 | | ^^ types differ | |
| 54 | | | |
| 55 | = note: expected associated type `Windows<for<'a> fn(&'a ())>::AssocType` | |
| 56 | found unit type `()` | |
| 57 | = help: consider constraining the associated type `Windows<for<'a> fn(&'a ())>::AssocType` to `()` or calling a method that returns `Windows<for<'a> fn(&'a ())>::AssocType` | |
| 58 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html | |
| 59 | ||
| 60 | error: aborting due to 7 previous errors | |
| 61 | ||
| 62 | Some errors have detailed explanations: E0207, E0282, E0308, E0392, E0601, E0658. | |
| 63 | For more information about an error, try `rustc --explain E0207`. |
tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/154333> | |
| 2 | //@compile-flags: -Znext-solver=globally | |
| 3 | #![feature(inherent_associated_types)] | |
| 4 | ||
| 5 | struct Foo; | |
| 6 | impl<const X: y> Foo { | |
| 7 | //~^ ERROR the const parameter `X` is not constrained by the impl trait, self type, or predicates | |
| 8 | //~| ERROR cannot find type `y` in this scope | |
| 9 | type ImplTrait = impl Clone; | |
| 10 | //~^ ERROR `impl Trait` in associated types is unstable | |
| 11 | //~| ERROR unconstrained opaque type | |
| 12 | fn f() -> Self::ImplTrait { | |
| 13 | () | |
| 14 | //~^ ERROR mismatched types | |
| 15 | } | |
| 16 | } | |
| 17 | //~^ ERROR `main` function not found |
tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.stderr created+56| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | error[E0425]: cannot find type `y` in this scope | |
| 2 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:6:15 | |
| 3 | | | |
| 4 | LL | impl<const X: y> Foo { | |
| 5 | | ^ not found in this scope | |
| 6 | ||
| 7 | error[E0658]: `impl Trait` in associated types is unstable | |
| 8 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:9:22 | |
| 9 | | | |
| 10 | LL | type ImplTrait = impl Clone; | |
| 11 | | ^^^^^^^^^^ | |
| 12 | | | |
| 13 | = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information | |
| 14 | = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable | |
| 15 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 16 | ||
| 17 | error[E0601]: `main` function not found in crate `next_solver_opaque_inherent_no_ice` | |
| 18 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:16:2 | |
| 19 | | | |
| 20 | LL | } | |
| 21 | | ^ consider adding a `main` function to `$DIR/next-solver-opaque-inherent-no-ice.rs` | |
| 22 | ||
| 23 | error[E0207]: the const parameter `X` is not constrained by the impl trait, self type, or predicates | |
| 24 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:6:6 | |
| 25 | | | |
| 26 | LL | impl<const X: y> Foo { | |
| 27 | | ^^^^^^^^^^ unconstrained const parameter | |
| 28 | | | |
| 29 | = note: expressions using a const parameter must map each value to a distinct output value | |
| 30 | = note: proving the result of expressions other than the parameter are unique is not supported | |
| 31 | ||
| 32 | error: unconstrained opaque type | |
| 33 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:9:22 | |
| 34 | | | |
| 35 | LL | type ImplTrait = impl Clone; | |
| 36 | | ^^^^^^^^^^ | |
| 37 | | | |
| 38 | = note: `ImplTrait` must be used in combination with a concrete type within the same impl | |
| 39 | ||
| 40 | error[E0308]: mismatched types | |
| 41 | --> $DIR/next-solver-opaque-inherent-no-ice.rs:13:9 | |
| 42 | | | |
| 43 | LL | fn f() -> Self::ImplTrait { | |
| 44 | | --------------- expected `Foo::ImplTrait` because of return type | |
| 45 | LL | () | |
| 46 | | ^^ types differ | |
| 47 | | | |
| 48 | = note: expected associated type `Foo::ImplTrait` | |
| 49 | found unit type `()` | |
| 50 | = help: consider constraining the associated type `Foo::ImplTrait` to `()` or calling a method that returns `Foo::ImplTrait` | |
| 51 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html | |
| 52 | ||
| 53 | error: aborting due to 6 previous errors | |
| 54 | ||
| 55 | Some errors have detailed explanations: E0207, E0308, E0425, E0601, E0658. | |
| 56 | For more information about an error, try `rustc --explain E0207`. |
tests/ui/c-variadic/copy.rs+5-5| ... | ... | @@ -13,12 +13,12 @@ fn main() { |
| 13 | 13 | unsafe extern "C" fn variadic(mut ap1: ...) { |
| 14 | 14 | let mut ap2 = ap1.clone(); |
| 15 | 15 | |
| 16 | assert_eq!(ap1.arg::<i32>(), 1); | |
| 17 | assert_eq!(ap2.arg::<i32>(), 1); | |
| 16 | assert_eq!(ap1.next_arg::<i32>(), 1); | |
| 17 | assert_eq!(ap2.next_arg::<i32>(), 1); | |
| 18 | 18 | |
| 19 | assert_eq!(ap2.arg::<i32>(), 2); | |
| 20 | assert_eq!(ap1.arg::<i32>(), 2); | |
| 19 | assert_eq!(ap2.next_arg::<i32>(), 2); | |
| 20 | assert_eq!(ap1.next_arg::<i32>(), 2); | |
| 21 | 21 | |
| 22 | 22 | drop(ap1); |
| 23 | assert_eq!(ap2.arg::<i32>(), 3); | |
| 23 | assert_eq!(ap2.next_arg::<i32>(), 3); | |
| 24 | 24 | } |
tests/ui/c-variadic/inherent-method.rs+5-5| ... | ... | @@ -7,23 +7,23 @@ struct S(i32); |
| 7 | 7 | |
| 8 | 8 | impl S { |
| 9 | 9 | unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { |
| 10 | unsafe { ap.arg() } | |
| 10 | unsafe { ap.next_arg() } | |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | unsafe extern "C" fn method_owned(self, mut ap: ...) -> i32 { |
| 14 | self.0 + unsafe { ap.arg::<i32>() } | |
| 14 | self.0 + unsafe { ap.next_arg::<i32>() } | |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | unsafe extern "C" fn method_ref(&self, mut ap: ...) -> i32 { |
| 18 | self.0 + unsafe { ap.arg::<i32>() } | |
| 18 | self.0 + unsafe { ap.next_arg::<i32>() } | |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | unsafe extern "C" fn method_mut(&mut self, mut ap: ...) -> i32 { |
| 22 | self.0 + unsafe { ap.arg::<i32>() } | |
| 22 | self.0 + unsafe { ap.next_arg::<i32>() } | |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | 25 | unsafe extern "C" fn fat_pointer(self: Box<Self>, mut ap: ...) -> i32 { |
| 26 | self.0 + unsafe { ap.arg::<i32>() } | |
| 26 | self.0 + unsafe { ap.next_arg::<i32>() } | |
| 27 | 27 | } |
| 28 | 28 | } |
| 29 | 29 |
tests/ui/c-variadic/not-dyn-compatible.rs+1-1| ... | ... | @@ -12,7 +12,7 @@ trait Trait { |
| 12 | 12 | fn get(&self) -> u64; |
| 13 | 13 | |
| 14 | 14 | unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { |
| 15 | self.get() + unsafe { ap.arg::<u64>() } | |
| 15 | self.get() + unsafe { ap.next_arg::<u64>() } | |
| 16 | 16 | } |
| 17 | 17 | } |
| 18 | 18 |
tests/ui/c-variadic/roundtrip.rs+3-3| ... | ... | @@ -10,11 +10,11 @@ use std::ffi::*; |
| 10 | 10 | |
| 11 | 11 | #[allow(improper_ctypes_definitions)] |
| 12 | 12 | const unsafe extern "C" fn variadic<T: VaArgSafe>(mut ap: ...) -> (T, T) { |
| 13 | let x = ap.arg::<T>(); | |
| 13 | let x = ap.next_arg::<T>(); | |
| 14 | 14 | // Intersperse a small type to test alignment logic. A `u32` (i.e. `c_uint`) is the smallest |
| 15 | 15 | // type that implements `VaArgSafe`: smaller types would automatically be promoted. |
| 16 | assert!(ap.arg::<u32>() == 0xAAAA_AAAA); | |
| 17 | let y = ap.arg::<T>(); | |
| 16 | assert!(ap.next_arg::<u32>() == 0xAAAA_AAAA); | |
| 17 | let y = ap.next_arg::<T>(); | |
| 18 | 18 | |
| 19 | 19 | (x, y) |
| 20 | 20 | } |
tests/ui/c-variadic/same-program-multiple-abis-arm.rs+2-2| ... | ... | @@ -25,8 +25,8 @@ fn main() { |
| 25 | 25 | // |
| 26 | 26 | // #[unsafe(no_mangle)] |
| 27 | 27 | // unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { |
| 28 | // let b = args.arg::<f64>(); | |
| 29 | // let c = args.arg::<f64>(); | |
| 28 | // let b = args.next_arg::<f64>(); | |
| 29 | // let c = args.next_arg::<f64>(); | |
| 30 | 30 | // |
| 31 | 31 | // a + b + c |
| 32 | 32 | // } |
tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs+2-2| ... | ... | @@ -24,8 +24,8 @@ fn main() { |
| 24 | 24 | // |
| 25 | 25 | // #[unsafe(no_mangle)] |
| 26 | 26 | // unsafe extern "C" fn variadic(a: u32, mut args: ...) -> u32 { |
| 27 | // let b = args.arg::<u32>(); | |
| 28 | // let c = args.arg::<u32>(); | |
| 27 | // let b = args.next_arg::<u32>(); | |
| 28 | // let c = args.next_arg::<u32>(); | |
| 29 | 29 | // |
| 30 | 30 | // a + b + c |
| 31 | 31 | // } |
tests/ui/c-variadic/trait-method.rs+7-7| ... | ... | @@ -7,11 +7,11 @@ struct Struct(i32); |
| 7 | 7 | |
| 8 | 8 | impl Struct { |
| 9 | 9 | unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { |
| 10 | unsafe { ap.arg() } | |
| 10 | unsafe { ap.next_arg() } | |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { |
| 14 | self.0 + unsafe { ap.arg::<i32>() } | |
| 14 | self.0 + unsafe { ap.next_arg::<i32>() } | |
| 15 | 15 | } |
| 16 | 16 | } |
| 17 | 17 | |
| ... | ... | @@ -19,23 +19,23 @@ trait Trait: Sized { |
| 19 | 19 | fn get(&self) -> i32; |
| 20 | 20 | |
| 21 | 21 | unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { |
| 22 | unsafe { ap.arg() } | |
| 22 | unsafe { ap.next_arg() } | |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | 25 | unsafe extern "C" fn trait_method_owned(self, mut ap: ...) -> i32 { |
| 26 | self.get() + unsafe { ap.arg::<i32>() } | |
| 26 | self.get() + unsafe { ap.next_arg::<i32>() } | |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | unsafe extern "C" fn trait_method_ref(&self, mut ap: ...) -> i32 { |
| 30 | self.get() + unsafe { ap.arg::<i32>() } | |
| 30 | self.get() + unsafe { ap.next_arg::<i32>() } | |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | unsafe extern "C" fn trait_method_mut(&mut self, mut ap: ...) -> i32 { |
| 34 | self.get() + unsafe { ap.arg::<i32>() } | |
| 34 | self.get() + unsafe { ap.next_arg::<i32>() } | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | unsafe extern "C" fn trait_fat_pointer(self: Box<Self>, mut ap: ...) -> i32 { |
| 38 | self.get() + unsafe { ap.arg::<i32>() } | |
| 38 | self.get() + unsafe { ap.next_arg::<i32>() } | |
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 |
tests/ui/c-variadic/valid.rs+3-3| ... | ... | @@ -4,16 +4,16 @@ |
| 4 | 4 | |
| 5 | 5 | // In rust (and C23 and above) `...` can be the only argument. |
| 6 | 6 | unsafe extern "C" fn only_dot_dot_dot(mut ap: ...) -> i32 { |
| 7 | unsafe { ap.arg() } | |
| 7 | unsafe { ap.next_arg() } | |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | unsafe extern "C-unwind" fn abi_c_unwind(mut ap: ...) -> i32 { |
| 11 | unsafe { ap.arg() } | |
| 11 | unsafe { ap.next_arg() } | |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | #[allow(improper_ctypes_definitions)] |
| 15 | 15 | unsafe extern "C" fn mix_int_float(mut ap: ...) -> (i64, f64, *const i32, f64) { |
| 16 | (ap.arg(), ap.arg(), ap.arg(), ap.arg()) | |
| 16 | (ap.next_arg(), ap.next_arg(), ap.next_arg(), ap.next_arg()) | |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | fn main() { |
tests/ui/consts/const-eval/c-variadic-fail.rs+8-8| ... | ... | @@ -13,7 +13,7 @@ const unsafe extern "C" fn read_n<const N: usize>(mut ap: ...) { |
| 13 | 13 | let mut i = N; |
| 14 | 14 | while i > 0 { |
| 15 | 15 | i -= 1; |
| 16 | let _ = ap.arg::<i32>(); | |
| 16 | let _ = ap.next_arg::<i32>(); | |
| 17 | 17 | } |
| 18 | 18 | } |
| 19 | 19 | |
| ... | ... | @@ -34,7 +34,7 @@ unsafe fn read_too_many() { |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | const unsafe extern "C" fn read_as<T: core::ffi::VaArgSafe>(mut ap: ...) -> T { |
| 37 | ap.arg::<T>() | |
| 37 | ap.next_arg::<T>() | |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | unsafe fn read_cast() { |
| ... | ... | @@ -72,7 +72,7 @@ fn use_after_free() { |
| 72 | 72 | unsafe { |
| 73 | 73 | let ap = helper(1, 2, 3); |
| 74 | 74 | let mut ap = std::mem::transmute::<_, VaList>(ap); |
| 75 | ap.arg::<i32>(); | |
| 75 | ap.next_arg::<i32>(); | |
| 76 | 76 | //~^ ERROR memory access failed: ALLOC0 has been freed, so this pointer is dangling [E0080] |
| 77 | 77 | } |
| 78 | 78 | }; |
| ... | ... | @@ -82,12 +82,12 @@ fn manual_copy_drop() { |
| 82 | 82 | const unsafe extern "C" fn helper(ap: ...) { |
| 83 | 83 | // A copy created using Clone is valid, and can be used to read arguments. |
| 84 | 84 | let mut copy = ap.clone(); |
| 85 | assert!(copy.arg::<i32>() == 1i32); | |
| 85 | assert!(copy.next_arg::<i32>() == 1i32); | |
| 86 | 86 | |
| 87 | 87 | let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; |
| 88 | 88 | |
| 89 | 89 | // Using the copy is actually fine. |
| 90 | let _ = copy.arg::<i32>(); | |
| 90 | let _ = copy.next_arg::<i32>(); | |
| 91 | 91 | drop(copy); |
| 92 | 92 | |
| 93 | 93 | // But then using the original is UB. |
| ... | ... | @@ -103,7 +103,7 @@ fn manual_copy_forget() { |
| 103 | 103 | let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; |
| 104 | 104 | |
| 105 | 105 | // Using the copy is actually fine. |
| 106 | let _ = copy.arg::<i32>(); | |
| 106 | let _ = copy.next_arg::<i32>(); | |
| 107 | 107 | std::mem::forget(copy); |
| 108 | 108 | |
| 109 | 109 | // The read (via `copy`) deallocated the original allocation. |
| ... | ... | @@ -119,8 +119,8 @@ fn manual_copy_read() { |
| 119 | 119 | let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; |
| 120 | 120 | |
| 121 | 121 | // Reading from `ap` after reading from `copy` is UB. |
| 122 | let _ = copy.arg::<i32>(); | |
| 123 | let _ = ap.arg::<i32>(); | |
| 122 | let _ = copy.next_arg::<i32>(); | |
| 123 | let _ = ap.next_arg::<i32>(); | |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | const { unsafe { helper(1, 2, 3) } }; |
tests/ui/consts/const-eval/c-variadic-fail.stderr+27-27| ... | ... | @@ -7,9 +7,9 @@ LL | const { read_n::<1>() } |
| 7 | 7 | note: inside `read_n::<1>` |
| 8 | 8 | --> $DIR/c-variadic-fail.rs:16:17 |
| 9 | 9 | | |
| 10 | LL | let _ = ap.arg::<i32>(); | |
| 11 | | ^^^^^^^^^^^^^^^ | |
| 12 | note: inside `VaList::<'_>::arg::<i32>` | |
| 10 | LL | let _ = ap.next_arg::<i32>(); | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 13 | 13 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 14 | 14 | |
| 15 | 15 | note: erroneous constant encountered |
| ... | ... | @@ -35,9 +35,9 @@ LL | const { read_n::<2>(1) } |
| 35 | 35 | note: inside `read_n::<2>` |
| 36 | 36 | --> $DIR/c-variadic-fail.rs:16:17 |
| 37 | 37 | | |
| 38 | LL | let _ = ap.arg::<i32>(); | |
| 39 | | ^^^^^^^^^^^^^^^ | |
| 40 | note: inside `VaList::<'_>::arg::<i32>` | |
| 38 | LL | let _ = ap.next_arg::<i32>(); | |
| 39 | | ^^^^^^^^^^^^^^^^^^^^ | |
| 40 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 41 | 41 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 42 | 42 | |
| 43 | 43 | note: erroneous constant encountered |
| ... | ... | @@ -63,9 +63,9 @@ LL | const { read_as::<u32>(1i32) }; |
| 63 | 63 | note: inside `read_as::<u32>` |
| 64 | 64 | --> $DIR/c-variadic-fail.rs:37:5 |
| 65 | 65 | | |
| 66 | LL | ap.arg::<T>() | |
| 67 | | ^^^^^^^^^^^^^ | |
| 68 | note: inside `VaList::<'_>::arg::<u32>` | |
| 66 | LL | ap.next_arg::<T>() | |
| 67 | | ^^^^^^^^^^^^^^^^^^ | |
| 68 | note: inside `VaList::<'_>::next_arg::<u32>` | |
| 69 | 69 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 70 | 70 | |
| 71 | 71 | note: erroneous constant encountered |
| ... | ... | @@ -91,9 +91,9 @@ LL | const { read_as::<i32>(1u32) }; |
| 91 | 91 | note: inside `read_as::<i32>` |
| 92 | 92 | --> $DIR/c-variadic-fail.rs:37:5 |
| 93 | 93 | | |
| 94 | LL | ap.arg::<T>() | |
| 95 | | ^^^^^^^^^^^^^ | |
| 96 | note: inside `VaList::<'_>::arg::<i32>` | |
| 94 | LL | ap.next_arg::<T>() | |
| 95 | | ^^^^^^^^^^^^^^^^^^ | |
| 96 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 97 | 97 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 98 | 98 | |
| 99 | 99 | note: erroneous constant encountered |
| ... | ... | @@ -119,9 +119,9 @@ LL | const { read_as::<i32>(1u64) }; |
| 119 | 119 | note: inside `read_as::<i32>` |
| 120 | 120 | --> $DIR/c-variadic-fail.rs:37:5 |
| 121 | 121 | | |
| 122 | LL | ap.arg::<T>() | |
| 123 | | ^^^^^^^^^^^^^ | |
| 124 | note: inside `VaList::<'_>::arg::<i32>` | |
| 122 | LL | ap.next_arg::<T>() | |
| 123 | | ^^^^^^^^^^^^^^^^^^ | |
| 124 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 125 | 125 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 126 | 126 | |
| 127 | 127 | note: erroneous constant encountered |
| ... | ... | @@ -147,9 +147,9 @@ LL | const { read_as::<f64>(1i32) }; |
| 147 | 147 | note: inside `read_as::<f64>` |
| 148 | 148 | --> $DIR/c-variadic-fail.rs:37:5 |
| 149 | 149 | | |
| 150 | LL | ap.arg::<T>() | |
| 151 | | ^^^^^^^^^^^^^ | |
| 152 | note: inside `VaList::<'_>::arg::<f64>` | |
| 150 | LL | ap.next_arg::<T>() | |
| 151 | | ^^^^^^^^^^^^^^^^^^ | |
| 152 | note: inside `VaList::<'_>::next_arg::<f64>` | |
| 153 | 153 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 154 | 154 | |
| 155 | 155 | note: erroneous constant encountered |
| ... | ... | @@ -175,9 +175,9 @@ LL | const { read_as::<*const u8>(1i32) }; |
| 175 | 175 | note: inside `read_as::<*const u8>` |
| 176 | 176 | --> $DIR/c-variadic-fail.rs:37:5 |
| 177 | 177 | | |
| 178 | LL | ap.arg::<T>() | |
| 179 | | ^^^^^^^^^^^^^ | |
| 180 | note: inside `VaList::<'_>::arg::<*const u8>` | |
| 178 | LL | ap.next_arg::<T>() | |
| 179 | | ^^^^^^^^^^^^^^^^^^ | |
| 180 | note: inside `VaList::<'_>::next_arg::<*const u8>` | |
| 181 | 181 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 182 | 182 | |
| 183 | 183 | note: erroneous constant encountered |
| ... | ... | @@ -197,10 +197,10 @@ LL | const { read_as::<*const u8>(1i32) }; |
| 197 | 197 | error[E0080]: memory access failed: ALLOC0 has been freed, so this pointer is dangling |
| 198 | 198 | --> $DIR/c-variadic-fail.rs:75:13 |
| 199 | 199 | | |
| 200 | LL | ap.arg::<i32>(); | |
| 201 | | ^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call | |
| 200 | LL | ap.next_arg::<i32>(); | |
| 201 | | ^^^^^^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call | |
| 202 | 202 | | |
| 203 | note: inside `VaList::<'_>::arg::<i32>` | |
| 203 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 204 | 204 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 205 | 205 | |
| 206 | 206 | note: erroneous constant encountered |
| ... | ... | @@ -300,9 +300,9 @@ LL | const { unsafe { helper(1, 2, 3) } }; |
| 300 | 300 | note: inside `manual_copy_read::helper` |
| 301 | 301 | --> $DIR/c-variadic-fail.rs:123:17 |
| 302 | 302 | | |
| 303 | LL | let _ = ap.arg::<i32>(); | |
| 304 | | ^^^^^^^^^^^^^^^ | |
| 305 | note: inside `VaList::<'_>::arg::<i32>` | |
| 303 | LL | let _ = ap.next_arg::<i32>(); | |
| 304 | | ^^^^^^^^^^^^^^^^^^^^ | |
| 305 | note: inside `VaList::<'_>::next_arg::<i32>` | |
| 306 | 306 | --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL |
| 307 | 307 | |
| 308 | 308 | note: erroneous constant encountered |
tests/ui/consts/const-eval/c-variadic.rs+11-11| ... | ... | @@ -21,7 +21,7 @@ fn ignores_arguments() { |
| 21 | 21 | |
| 22 | 22 | fn echo() { |
| 23 | 23 | const unsafe extern "C" fn variadic(mut ap: ...) -> i32 { |
| 24 | ap.arg() | |
| 24 | ap.next_arg() | |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | assert_eq!(unsafe { variadic(1) }, 1); |
| ... | ... | @@ -35,7 +35,7 @@ fn echo() { |
| 35 | 35 | |
| 36 | 36 | fn forward_by_val() { |
| 37 | 37 | const unsafe fn helper(mut ap: VaList) -> i32 { |
| 38 | ap.arg() | |
| 38 | ap.next_arg() | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | const unsafe extern "C" fn variadic(ap: ...) -> i32 { |
| ... | ... | @@ -53,7 +53,7 @@ fn forward_by_val() { |
| 53 | 53 | |
| 54 | 54 | fn forward_by_ref() { |
| 55 | 55 | const unsafe fn helper(ap: &mut VaList) -> i32 { |
| 56 | ap.arg() | |
| 56 | ap.next_arg() | |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | const unsafe extern "C" fn variadic(mut ap: ...) -> i32 { |
| ... | ... | @@ -72,7 +72,7 @@ fn forward_by_ref() { |
| 72 | 72 | #[allow(improper_ctypes_definitions)] |
| 73 | 73 | fn nested() { |
| 74 | 74 | const unsafe fn helper(mut ap1: VaList, mut ap2: VaList) -> (i32, i32) { |
| 75 | (ap1.arg(), ap2.arg()) | |
| 75 | (ap1.next_arg(), ap2.next_arg()) | |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | const unsafe extern "C" fn variadic2(ap1: VaList, ap2: ...) -> (i32, i32) { |
| ... | ... | @@ -112,13 +112,13 @@ fn various_types() { |
| 112 | 112 | } |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); | |
| 116 | continue_if!(ap.arg::<c_long>() == 12); | |
| 117 | continue_if!(ap.arg::<c_int>() == 'a' as c_int); | |
| 118 | continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor()); | |
| 119 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); | |
| 120 | continue_if!(ap.arg::<c_int>() == 42); | |
| 121 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); | |
| 115 | continue_if!(ap.next_arg::<c_double>().floor() == 3.14f64.floor()); | |
| 116 | continue_if!(ap.next_arg::<c_long>() == 12); | |
| 117 | continue_if!(ap.next_arg::<c_int>() == 'a' as c_int); | |
| 118 | continue_if!(ap.next_arg::<c_double>().floor() == 6.18f64.floor()); | |
| 119 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "Hello")); | |
| 120 | continue_if!(ap.next_arg::<c_int>() == 42); | |
| 121 | continue_if!(compare_c_str(ap.next_arg::<*const c_char>(), "World")); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | unsafe { |
tests/ui/explicit-tail-calls/c-variadic.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | #![allow(unused)] |
| 4 | 4 | |
| 5 | 5 | unsafe extern "C" fn foo(mut ap: ...) -> u32 { |
| 6 | ap.arg::<u32>() | |
| 6 | ap.next_arg::<u32>() | |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | extern "C" fn bar() -> u32 { |
tests/ui/sanitizer/kcfi-c-variadic.rs+1-1| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | |
| 9 | 9 | trait Trait { |
| 10 | 10 | unsafe extern "C" fn foo(x: i32, y: i32, mut ap: ...) -> i32 { |
| 11 | x + y + ap.arg::<i32>() + ap.arg::<i32>() | |
| 11 | x + y + ap.next_arg::<i32>() + ap.next_arg::<i32>() | |
| 12 | 12 | } |
| 13 | 13 | } |
| 14 | 14 |