Rollup merge of #143303 - Kivooeo:tf28, r=tgross35

`tests/ui`: A New Order [28/28] FINAL PART

> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.

Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.

r? ``@tgross35``
This commit is contained in:
Matthias Krüger 2025-07-11 07:35:19 +02:00 committed by GitHub
commit 66799d0b83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 262 additions and 197 deletions

View file

@ -0,0 +1,13 @@
//! Checks that `Weak` pointers can be created with an empty enum type parameter.
//! And generic `Weak` handles zero-variant enums without error.
//!
//! Regression test for <https://github.com/rust-lang/rust/issues/48493>
//@ run-pass
enum Void {}
fn main() {
let _ = std::rc::Weak::<Void>::new();
let _ = std::sync::Weak::<Void>::new();
}

View file

@ -0,0 +1,15 @@
//! Test that argument names starting with `_` are usable.
//@ run-pass
fn good(_a: &isize) {}
fn called<F>(_f: F)
where
F: FnOnce(&isize),
{
}
pub fn main() {
called(good);
}

View file

@ -0,0 +1,19 @@
//! Checks borrow after move error when using `self` consuming method with struct update syntax.
struct Mine {
test: String,
other_val: isize,
}
impl Mine {
fn make_string_bar(mut self) -> Mine {
self.test = "Bar".to_string();
self
}
}
fn main() {
let start = Mine { test: "Foo".to_string(), other_val: 0 };
let end = Mine { other_val: 1, ..start.make_string_bar() };
println!("{}", start.test); //~ ERROR borrow of moved value: `start`
}

View file

@ -1,17 +1,17 @@
error[E0382]: borrow of moved value: `start` error[E0382]: borrow of moved value: `start`
--> $DIR/walk-struct-literal-with.rs:16:20 --> $DIR/ownership-struct-update-moved-error.rs:18:20
| |
LL | let start = Mine{test:"Foo".to_string(), other_val:0}; LL | let start = Mine { test: "Foo".to_string(), other_val: 0 };
| ----- move occurs because `start` has type `Mine`, which does not implement the `Copy` trait | ----- move occurs because `start` has type `Mine`, which does not implement the `Copy` trait
LL | let end = Mine{other_val:1, ..start.make_string_bar()}; LL | let end = Mine { other_val: 1, ..start.make_string_bar() };
| ----------------- `start` moved due to this method call | ----------------- `start` moved due to this method call
LL | println!("{}", start.test); LL | println!("{}", start.test);
| ^^^^^^^^^^ value borrowed here after move | ^^^^^^^^^^ value borrowed here after move
| |
note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start` note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start`
--> $DIR/walk-struct-literal-with.rs:7:28 --> $DIR/ownership-struct-update-moved-error.rs:9:28
| |
LL | fn make_string_bar(mut self) -> Mine{ LL | fn make_string_bar(mut self) -> Mine {
| ^^^^ | ^^^^
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -1,3 +1,5 @@
//! Sanity check for no capture closures
//@ run-pass //@ run-pass
pub fn main() { pub fn main() {

View file

@ -0,0 +1,12 @@
//! Regression test for a crash caused by an "unsused move"
//! (specifically, a variable bound to a `Box` used as a statement)
//! leading to incorrect memory zero-filling after drop.
//!
//! Regression test for <https://github.com/rust-lang/rust/issues/3878>.
//@ run-pass
pub fn main() {
let y: Box<_> = Box::new(1);
drop(y);
}

View file

@ -1,26 +1,27 @@
//! Check for correct initialization of `HashSet` with enums. This is a regression test for a
//! codegen bug that caused the `HashSet` to appear as if it contained one of each enum variant.
//!
//! Regression test for <https://github.com/rust-lang/rust/issues/42918>
//@ run-pass //@ run-pass
//
#![allow(dead_code)]
//@ compile-flags: -O //@ compile-flags: -O
#![allow(dead_code)]
use std::collections::HashSet; use std::collections::HashSet;
#[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] #[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)]
enum MyEnum { enum MyEnum {
E0, E0,
E1, E1,
E2, E2,
E3, E3,
E4, E4,
E5, E5,
E6, E6,
E7, E7,
} }
fn main() { fn main() {
use MyEnum::*; use MyEnum::*;
let s: HashSet<_> = [E4, E1].iter().cloned().collect(); let s: HashSet<_> = [E4, E1].iter().cloned().collect();

View file

@ -1,3 +1,6 @@
//! Tests that errors from both the writer (`Write::write`) and formatter (`Display::fmt`)
//! are correctly propagated: writer errors return `Err`, formatter errors cause panics.
//@ run-pass //@ run-pass
//@ needs-unwind //@ needs-unwind
@ -24,7 +27,9 @@ impl Write for ErrorWriter {
Err(Error::new(WRITER_ERROR, "not connected")) Err(Error::new(WRITER_ERROR, "not connected"))
} }
fn flush(&mut self) -> io::Result<()> { Ok(()) } fn flush(&mut self) -> io::Result<()> {
Ok(())
}
} }
fn main() { fn main() {
@ -37,7 +42,8 @@ fn main() {
let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap();
assert!( assert!(
err.contains("formatting trait implementation returned an error"), err.contains("formatting trait implementation returned an error"),
"unexpected panic: {}", err "unexpected panic: {}",
err
); );
// Writer error when there's some string before the first `{}` // Writer error when there's some string before the first `{}`
@ -50,6 +56,7 @@ fn main() {
let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap();
assert!( assert!(
err.contains("formatting trait implementation returned an error"), err.contains("formatting trait implementation returned an error"),
"unexpected panic: {}", err "unexpected panic: {}",
err
); );
} }

View file

@ -0,0 +1,12 @@
//! Checks that compiler prevernt attempting to define an unrecognized or unknown lang item
#![allow(unused)]
#![feature(lang_items)]
#[lang = "foo"]
fn bar() -> ! {
//~^^ ERROR definition of an unknown lang item: `foo`
loop {}
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0522]: definition of an unknown lang item: `foo` error[E0522]: definition of an unknown lang item: `foo`
--> $DIR/unknown-language-item.rs:4:1 --> $DIR/lang-item-unknown-definition-error.rs:6:1
| |
LL | #[lang = "foo"] LL | #[lang = "foo"]
| ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo`

View file

@ -0,0 +1,20 @@
//! Checks that functions from different modules are accessible via their fully-qualified paths.
//@ run-pass
mod foo {
pub fn x() -> isize {
return 1;
}
}
mod bar {
pub fn y() -> isize {
return 1;
}
}
pub fn main() {
foo::x();
bar::y();
}

View file

@ -1,3 +1,5 @@
//! Checks complex `use` syntax and availability of types across nested modules.
//@ run-pass //@ run-pass
mod a { mod a {

View file

@ -0,0 +1,13 @@
//! Make sure the module level constants are still there and accessible even after
//! the corresponding associated constants have been added, and later stabilized.
//@ run-pass
#![allow(deprecated, deprecated_in_future)]
use std::{f32, u16};
fn main() {
let _ = u16::MAX;
let _ = f32::EPSILON;
let _ = std::f64::MANTISSA_DIGITS;
}

View file

@ -1,18 +1,20 @@
//! Checks module re-exports, aliasing with `pub use`,
//! and calling private methods via `Self` in an impl block.
//@ run-pass //@ run-pass
#![allow(unused_variables)] #![allow(unused_variables)]
pub struct A; pub struct A;
mod test { mod test {
pub use super :: A; pub use self::A as B;
pub use super::A;
pub use self :: A as B;
} }
impl A { impl A {
fn f() {} fn f() {}
fn g() { fn g() {
Self :: f() Self::f()
} }
} }

View file

@ -1,3 +1,5 @@
//! This test ensures that the unary negation operator (`-`) cannot be applied to unsigned ints
fn main() { fn main() {
let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` let x = -1 as usize; //~ ERROR: cannot apply unary operator `-`
let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-`

View file

@ -1,5 +1,5 @@
error[E0600]: cannot apply unary operator `-` to type `usize` error[E0600]: cannot apply unary operator `-` to type `usize`
--> $DIR/unsigned-literal-negation.rs:2:13 --> $DIR/unary-negation-unsigned-integer-error.rs:4:13
| |
LL | let x = -1 as usize; LL | let x = -1 as usize;
| ^^ cannot apply unary operator `-` | ^^ cannot apply unary operator `-`
@ -12,7 +12,7 @@ LL + let x = usize::MAX;
| |
error[E0600]: cannot apply unary operator `-` to type `usize` error[E0600]: cannot apply unary operator `-` to type `usize`
--> $DIR/unsigned-literal-negation.rs:3:13 --> $DIR/unary-negation-unsigned-integer-error.rs:5:13
| |
LL | let x = (-1) as usize; LL | let x = (-1) as usize;
| ^^^^ cannot apply unary operator `-` | ^^^^ cannot apply unary operator `-`
@ -25,7 +25,7 @@ LL + let x = usize::MAX;
| |
error[E0600]: cannot apply unary operator `-` to type `u32` error[E0600]: cannot apply unary operator `-` to type `u32`
--> $DIR/unsigned-literal-negation.rs:4:18 --> $DIR/unary-negation-unsigned-integer-error.rs:6:18
| |
LL | let x: u32 = -1; LL | let x: u32 = -1;
| ^^ cannot apply unary operator `-` | ^^ cannot apply unary operator `-`

View file

@ -1,3 +1,7 @@
//! This test checks that Rust's unwinding mechanism correctly executes `Drop`
//! implementations during stack unwinding, even when unwind tables (`uwtable`)
//! are explicitly disabled via `-C force-unwind-tables=n`.
//@ run-pass //@ run-pass
//@ needs-unwind //@ needs-unwind
//@ ignore-windows target requires uwtable //@ ignore-windows target requires uwtable
@ -26,9 +30,12 @@ fn increase(count: &mut u8) {
fn main() { fn main() {
let mut count = 0; let mut count = 0;
assert!(panic::catch_unwind(AssertUnwindSafe( assert!(
#[inline(never)] panic::catch_unwind(AssertUnwindSafe(
|| increase(&mut count) #[inline(never)]
)).is_err()); || increase(&mut count)
))
.is_err()
);
assert_eq!(count, 1); assert_eq!(count, 1);
} }

View file

@ -1,3 +1,9 @@
//! Tests that repeatedly spawning a failing command does not create zombie processes.
//! Spawns a deliberately invalid command multiple times, verifies each spawn fails,
//! then uses `ps` (on Unix) to detect any leftover zombie (defunct) child processes.
//! Checks Rust's process spawning cleans up resources properly.
//! Skipped on platforms without `ps` utility.
//@ run-pass //@ run-pass
//@ needs-subprocess //@ needs-subprocess
//@ ignore-vxworks no 'ps' //@ ignore-vxworks no 'ps'
@ -36,35 +42,42 @@ fn find_zombies() {
// the PPID column contains a "-" for the respective process. // the PPID column contains a "-" for the respective process.
// Filter out any lines that have a "-" as the PPID as the PPID is // Filter out any lines that have a "-" as the PPID as the PPID is
// expected to be an integer. // expected to be an integer.
let filtered_ps: Vec<_> = ps_output let filtered_ps: Vec<_> =
.lines() ps_output.lines().filter(|line| line.split_whitespace().nth(1) != Some("-")).collect();
.filter(|line| line.split_whitespace().nth(1) != Some("-"))
.collect();
for (line_no, line) in filtered_ps.into_iter().enumerate() { for (line_no, line) in filtered_ps.into_iter().enumerate() {
if 0 < line_no && 0 < line.len() && if 0 < line_no
my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1) && 0 < line.len()
.expect("1st column should be PPID") && my_pid
.parse().ok() == line
.expect("PPID string into integer") && .split(' ')
line.contains("defunct") { .filter(|w| 0 < w.len())
.nth(1)
.expect("1st column should be PPID")
.parse()
.ok()
.expect("PPID string into integer")
&& line.contains("defunct")
{
panic!("Zombie child {}", line); panic!("Zombie child {}", line);
} }
} }
} }
#[cfg(windows)] #[cfg(windows)]
fn find_zombies() { } fn find_zombies() {}
fn main() { fn main() {
let too_long = format!("/NoSuchCommand{:0300}", 0u8); let too_long = format!("/NoSuchCommand{:0300}", 0u8);
let _failures = (0..100).map(|_| { let _failures = (0..100)
let mut cmd = Command::new(&too_long); .map(|_| {
let failed = cmd.spawn(); let mut cmd = Command::new(&too_long);
assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); let failed = cmd.spawn();
failed assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd);
}).collect::<Vec<_>>(); failed
})
.collect::<Vec<_>>();
find_zombies(); find_zombies();
// then _failures goes out of scope // then _failures goes out of scope

View file

@ -0,0 +1,26 @@
//! On Windows the GetExitCodeProcess API is used to get the exit code of a
//! process, but it's easy to mistake a process exiting with the code 259 as
//! "still running" because this is the value of the STILL_ACTIVE constant. Make
//! sure we handle this case in the standard library and correctly report the
//! status.
//!
//! Note that this is disabled on unix as processes exiting with 259 will have
//! their exit status truncated to 3 (only the lower 8 bits are used).
//@ run-pass
#[cfg(windows)]
fn main() {
use std::env;
use std::process::{self, Command};
if env::args().len() == 1 {
let status = Command::new(env::current_exe().unwrap()).arg("foo").status().unwrap();
assert_eq!(status.code(), Some(259));
} else {
process::exit(259);
}
}
#[cfg(not(windows))]
fn main() {}

View file

@ -0,0 +1,19 @@
//@ run-pass
#![allow(unused_must_use)]
#![allow(unreachable_code)]
fn _id(x: bool) -> bool {
x
}
fn _call_id() {
let _c = panic!();
_id(_c);
}
fn _call_id_3() {
_id(return) && _id(return);
}
pub fn main() {}

View file

@ -26,9 +26,13 @@ fn call_id_3() {
fn ret_guard() { fn ret_guard() {
match 2 { match 2 {
x if (return) => { x; } x if (return) => {
x if let true = return => { x; } x;
_ => {} }
x if let true = return => {
x;
}
_ => {}
} }
} }

View file

@ -1,5 +1,7 @@
//! Regression test for https://github.com/rust-lang/rust/issues/137646. //! This test checks the correct parameter handling during virtual method calls
//! The parameter value at all calls to `check` should be `(1, 1, 1)`. //! through a `dyn Trait` object.
//!
//! Regression test for: <https://github.com/rust-lang/rust/issues/137646>
//@ run-pass //@ run-pass

View file

@ -0,0 +1,14 @@
//! Checks the basic usage of unit type
//@ run-pass
fn f(u: ()) {
u
}
pub fn main() {
let u1: () = ();
let mut _u2: () = f(u1);
_u2 = ();
()
}

View file

@ -1,3 +1,5 @@
//! Sanity test that primitives cannot have const generics.
fn foo() { fn foo() {
let x: usize<foo>; //~ ERROR const arguments are not allowed on builtin type `usize` let x: usize<foo>; //~ ERROR const arguments are not allowed on builtin type `usize`
} }

View file

@ -1,5 +1,5 @@
error[E0109]: const arguments are not allowed on builtin type `usize` error[E0109]: const arguments are not allowed on builtin type `usize`
--> $DIR/usize-generic-argument-parent.rs:2:18 --> $DIR/usize-no-generic-arguments.rs:4:18
| |
LL | let x: usize<foo>; LL | let x: usize<foo>;
| ----- ^^^ const argument not allowed | ----- ^^^ const argument not allowed

View file

@ -1,16 +0,0 @@
//@ run-pass
#![allow(unused_assignments)]
#![allow(unknown_lints)]
#![allow(unused_variables)]
#![allow(dead_assignment)]
fn f(u: ()) { return u; }
pub fn main() {
let u1: () = ();
let mut u2: () = f(u1);
u2 = ();
return ();
}

View file

@ -1,10 +0,0 @@
#![allow(unused)]
#![feature(lang_items)]
#[lang = "foo"]
fn bar() -> ! {
//~^^ ERROR definition of an unknown lang item: `foo`
loop {}
}
fn main() {}

View file

@ -1,13 +0,0 @@
//@ run-pass
fn good(_a: &isize) {
}
// unnamed argument &isize is now parse x: &isize
fn called<F>(_f: F) where F: FnOnce(&isize) {
}
pub fn main() {
called(good);
}

View file

@ -1,19 +0,0 @@
//@ run-pass
#![allow(unused_must_use)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
#![allow(dead_code)]
fn id(x: bool) -> bool { x }
fn call_id() {
let c = panic!();
id(c);
}
fn call_id_3() { id(return) && id(return); }
pub fn main() {
}

View file

@ -1,6 +1,9 @@
//@ build-pass //! This test checks that ZSTs can be safely initialized from
// Test the uninit() construct returning various empty types. //! `MaybeUninit::uninit().assume_init()` and `std::mem::uninitialized()`
//! (which is deprecated). This is safe because ZSTs inherently
//! require no actual memory initialization, as they occupy no memory.
//@ build-pass
use std::mem::MaybeUninit; use std::mem::MaybeUninit;

View file

@ -1,12 +0,0 @@
//@ run-pass
// Issue #3878
// Issue Name: Unused move causes a crash
// Abstract: zero-fill to block after drop
#![allow(path_statements)]
pub fn main() {
let y: Box<_> = Box::new(1);
y;
}

View file

@ -1,11 +0,0 @@
//@ run-pass
mod foo {
pub fn x() -> isize { return 1; }
}
mod bar {
pub fn y() -> isize { return 1; }
}
pub fn main() { foo::x(); bar::y(); }

View file

@ -1,12 +0,0 @@
//@ run-pass
// Make sure the module level constants are still there and accessible even after
// the corresponding associated constants have been added, and later stabilized.
#![allow(deprecated, deprecated_in_future)]
use std::{u16, f32};
fn main() {
let _ = u16::MAX;
let _ = f32::EPSILON;
let _ = std::f64::MANTISSA_DIGITS;
}

View file

@ -1,17 +0,0 @@
struct Mine{
test: String,
other_val: isize
}
impl Mine{
fn make_string_bar(mut self) -> Mine{
self.test = "Bar".to_string();
self
}
}
fn main(){
let start = Mine{test:"Foo".to_string(), other_val:0};
let end = Mine{other_val:1, ..start.make_string_bar()};
println!("{}", start.test); //~ ERROR borrow of moved value: `start`
}

View file

@ -1,7 +0,0 @@
//@ run-pass
fn main() {
enum Void {}
let _ = std::rc::Weak::<Void>::new();
let _ = std::sync::Weak::<Void>::new();
}

View file

@ -1,28 +0,0 @@
//@ run-pass
// On Windows the GetExitCodeProcess API is used to get the exit code of a
// process, but it's easy to mistake a process exiting with the code 259 as
// "still running" because this is the value of the STILL_ACTIVE constant. Make
// sure we handle this case in the standard library and correctly report the
// status.
//
// Note that this is disabled on unix as processes exiting with 259 will have
// their exit status truncated to 3 (only the lower 8 bits are used).
#[cfg(windows)]
fn main() {
use std::process::{self, Command};
use std::env;
if env::args().len() == 1 {
let status = Command::new(env::current_exe().unwrap())
.arg("foo")
.status()
.unwrap();
assert_eq!(status.code(), Some(259));
} else {
process::exit(259);
}
}
#[cfg(not(windows))]
fn main() {}