From e9191ec57ee5bdd0961a22fd9852f361a5c97ea0 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 21:42:20 +0500 Subject: moved tests --- tests/ui/auto-traits/auto-traits-type-parameter | 36 ++++ tests/ui/consts/const-eval-array-len-in-impl.rs | 13 ++ .../ui/consts/const-eval-array-len-in-impl.stderr | 11 ++ .../let-binding-tuple-destructuring.rs | 7 + .../lifetimes/any-lifetime-escape-higher-rank.rs | 31 ++++ tests/ui/limits/type-length-limit-enforcement.rs | 34 ++++ .../ui/limits/type-length-limit-enforcement.stderr | 15 ++ .../macro-fragment-ident-underscore-error.rs | 9 + .../macro-fragment-ident-underscore-error.stderr | 17 ++ .../struct-type-and-function-name-coexistence.rs | 7 + .../integer-literal-method-call-underscore.rs | 11 ++ tests/ui/ptr_ops/ptr-write-bool-representation.rs | 11 ++ tests/ui/ptr_ops/raw-pointer-type-basic.rs | 9 + tests/ui/try-operator-hygiene.rs | 26 --- tests/ui/try-operator.rs | 192 --------------------- .../ui/try-trait/try-operator-expansion-hygiene.rs | 26 +++ .../ui/try-trait/try-operator-various-contexts.rs | 192 +++++++++++++++++++++ tests/ui/tydesc-name.rs | 14 -- tests/ui/type-id-higher-rank-2.rs | 31 ---- .../type-inference-none-in-generic-ref.rs | 7 + .../type-inference-none-in-generic-ref.stderr | 14 ++ .../type-inference-unconstrained-none.rs | 5 + .../type-inference-unconstrained-none.stderr | 14 ++ tests/ui/type-namespace.rs | 7 - tests/ui/type-param-constraints.rs | 36 ---- tests/ui/type-ptr.rs | 9 - tests/ui/type-use-i1-versus-i8.rs | 11 -- tests/ui/type/type-name-basic.rs | 14 ++ tests/ui/type/typeid-consistency-comprehensive.rs | 97 +++++++++++ tests/ui/type_length_limit.rs | 34 ---- tests/ui/type_length_limit.stderr | 15 -- tests/ui/typeid-intrinsic.rs | 97 ----------- tests/ui/typestate-multi-decl.rs | 7 - tests/ui/unconstrained-none.rs | 5 - tests/ui/unconstrained-none.stderr | 14 -- tests/ui/unconstrained-ref.rs | 7 - tests/ui/unconstrained-ref.stderr | 14 -- tests/ui/underscore-ident-matcher.rs | 9 - tests/ui/underscore-ident-matcher.stderr | 17 -- .../basic-underscore-lifetime-elision.rs | 38 ++++ tests/ui/underscore-lifetimes.rs | 38 ---- tests/ui/underscore-method-after-integer.rs | 11 -- tests/ui/unevaluated_fixed_size_array_len.rs | 13 -- tests/ui/unevaluated_fixed_size_array_len.stderr | 11 -- 44 files changed, 618 insertions(+), 618 deletions(-) create mode 100644 tests/ui/auto-traits/auto-traits-type-parameter create mode 100644 tests/ui/consts/const-eval-array-len-in-impl.rs create mode 100644 tests/ui/consts/const-eval-array-len-in-impl.stderr create mode 100644 tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs create mode 100644 tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs create mode 100644 tests/ui/limits/type-length-limit-enforcement.rs create mode 100644 tests/ui/limits/type-length-limit-enforcement.stderr create mode 100644 tests/ui/macros/macro-fragment-ident-underscore-error.rs create mode 100644 tests/ui/macros/macro-fragment-ident-underscore-error.stderr create mode 100644 tests/ui/namespace/struct-type-and-function-name-coexistence.rs create mode 100644 tests/ui/parser/integer-literal-method-call-underscore.rs create mode 100644 tests/ui/ptr_ops/ptr-write-bool-representation.rs create mode 100644 tests/ui/ptr_ops/raw-pointer-type-basic.rs delete mode 100644 tests/ui/try-operator-hygiene.rs delete mode 100644 tests/ui/try-operator.rs create mode 100644 tests/ui/try-trait/try-operator-expansion-hygiene.rs create mode 100644 tests/ui/try-trait/try-operator-various-contexts.rs delete mode 100644 tests/ui/tydesc-name.rs delete mode 100644 tests/ui/type-id-higher-rank-2.rs create mode 100644 tests/ui/type-inference/type-inference-none-in-generic-ref.rs create mode 100644 tests/ui/type-inference/type-inference-none-in-generic-ref.stderr create mode 100644 tests/ui/type-inference/type-inference-unconstrained-none.rs create mode 100644 tests/ui/type-inference/type-inference-unconstrained-none.stderr delete mode 100644 tests/ui/type-namespace.rs delete mode 100644 tests/ui/type-param-constraints.rs delete mode 100644 tests/ui/type-ptr.rs delete mode 100644 tests/ui/type-use-i1-versus-i8.rs create mode 100644 tests/ui/type/type-name-basic.rs create mode 100644 tests/ui/type/typeid-consistency-comprehensive.rs delete mode 100644 tests/ui/type_length_limit.rs delete mode 100644 tests/ui/type_length_limit.stderr delete mode 100644 tests/ui/typeid-intrinsic.rs delete mode 100644 tests/ui/typestate-multi-decl.rs delete mode 100644 tests/ui/unconstrained-none.rs delete mode 100644 tests/ui/unconstrained-none.stderr delete mode 100644 tests/ui/unconstrained-ref.rs delete mode 100644 tests/ui/unconstrained-ref.stderr delete mode 100644 tests/ui/underscore-ident-matcher.rs delete mode 100644 tests/ui/underscore-ident-matcher.stderr create mode 100644 tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs delete mode 100644 tests/ui/underscore-lifetimes.rs delete mode 100644 tests/ui/underscore-method-after-integer.rs delete mode 100644 tests/ui/unevaluated_fixed_size_array_len.rs delete mode 100644 tests/ui/unevaluated_fixed_size_array_len.stderr diff --git a/tests/ui/auto-traits/auto-traits-type-parameter b/tests/ui/auto-traits/auto-traits-type-parameter new file mode 100644 index 00000000000..83d81c0d833 --- /dev/null +++ b/tests/ui/auto-traits/auto-traits-type-parameter @@ -0,0 +1,36 @@ +//@ run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + +fn p_foo(_pinned: T) { } +fn s_foo(_shared: T) { } +fn u_foo(_unique: T) { } + +struct r { + i: isize, +} + +impl Drop for r { + fn drop(&mut self) {} +} + +fn r(i:isize) -> r { + r { + i: i + } +} + +pub fn main() { + p_foo(r(10)); + + p_foo::>(Box::new(r(10))); + p_foo::>(Box::new(10)); + p_foo(10); + + s_foo::>(Box::new(10)); + s_foo(10); + + u_foo::>(Box::new(10)); + u_foo(10); +} diff --git a/tests/ui/consts/const-eval-array-len-in-impl.rs b/tests/ui/consts/const-eval-array-len-in-impl.rs new file mode 100644 index 00000000000..6c545913dd9 --- /dev/null +++ b/tests/ui/consts/const-eval-array-len-in-impl.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/49208 + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() //~ ERROR E0277 +} diff --git a/tests/ui/consts/const-eval-array-len-in-impl.stderr b/tests/ui/consts/const-eval-array-len-in-impl.stderr new file mode 100644 index 00000000000..43cc377006e --- /dev/null +++ b/tests/ui/consts/const-eval-array-len-in-impl.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied + --> $DIR/unevaluated_fixed_size_array_len.rs:12:6 + | +LL | <[(); 0] as Foo>::foo() + | ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` + | + = help: the trait `Foo` is implemented for `[(); 1]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs new file mode 100644 index 00000000000..3d0e79632bb --- /dev/null +++ b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs @@ -0,0 +1,7 @@ +//@ run-pass + +pub fn main() { + let (x, y) = (10, 20); + let z = x + y; + assert_eq!(z, 30); +} diff --git a/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs new file mode 100644 index 00000000000..7b0c7b53940 --- /dev/null +++ b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs @@ -0,0 +1,31 @@ +//@ run-pass +// Test that we can't ignore lifetimes by going through Any. + +use std::any::Any; + +struct Foo<'a>(&'a str); + +fn good(s: &String) -> Foo<'_> { Foo(s) } + +fn bad1(s: String) -> Option<&'static str> { + let a: Box = Box::new(good as fn(&String) -> Foo); + a.downcast_ref:: Foo<'static>>().map(|f| f(&s).0) +} + +trait AsStr<'a, 'b> { + fn get(&'a self) -> &'b str; +} + +impl<'a> AsStr<'a, 'a> for String { + fn get(&'a self) -> &'a str { self } +} + +fn bad2(s: String) -> Option<&'static str> { + let a: Box = Box::new(Box::new(s) as Box AsStr<'a, 'a>>); + a.downcast_ref:: AsStr<'a, 'static>>>().map(|x| x.get()) +} + +fn main() { + assert_eq!(bad1(String::from("foo")), None); + assert_eq!(bad2(String::from("bar")), None); +} diff --git a/tests/ui/limits/type-length-limit-enforcement.rs b/tests/ui/limits/type-length-limit-enforcement.rs new file mode 100644 index 00000000000..87f5ffd76d7 --- /dev/null +++ b/tests/ui/limits/type-length-limit-enforcement.rs @@ -0,0 +1,34 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit +//~^^ ERROR reached the type-length limit + +// Test that the type length limit can be changed. +// The exact type depends on optimizations, so disable them. + +#![allow(dead_code)] +#![type_length_limit="8"] + +macro_rules! link { + ($id:ident, $t:ty) => { + pub type $id = ($t, $t, $t); + } +} + +link! { A1, B1 } +link! { B1, C1 } +link! { C1, D1 } +link! { D1, E1 } +link! { E1, A } +link! { A, B } +link! { B, C } +link! { C, D } +link! { D, E } +link! { E, F } +link! { F, G, Option> } + +pub struct G(std::marker::PhantomData::<(T, K)>); + +fn main() { + drop::>(None); + //~^ ERROR reached the type-length limit +} diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr new file mode 100644 index 00000000000..198d133c08c --- /dev/null +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -0,0 +1,15 @@ +error: reached the type-length limit while instantiating `std::mem::drop::>` + --> $DIR/type_length_limit.rs:32:5 + | +LL | drop::>(None); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' + +error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` + | + = help: consider adding a `#![type_length_limit="10"]` attribute to your crate + +error: aborting due to 2 previous errors + diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.rs b/tests/ui/macros/macro-fragment-ident-underscore-error.rs new file mode 100644 index 00000000000..77ec70d43d5 --- /dev/null +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.rs @@ -0,0 +1,9 @@ +macro_rules! identity { + ($i: ident) => ( + $i + ) +} + +fn main() { + let identity!(_) = 10; //~ ERROR no rules expected reserved identifier `_` +} diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.stderr b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr new file mode 100644 index 00000000000..0c3f980cf6c --- /dev/null +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr @@ -0,0 +1,17 @@ +error: no rules expected reserved identifier `_` + --> $DIR/underscore-ident-matcher.rs:8:19 + | +LL | macro_rules! identity { + | --------------------- when calling this macro +... +LL | let identity!(_) = 10; + | ^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$i:ident` + --> $DIR/underscore-ident-matcher.rs:2:6 + | +LL | ($i: ident) => ( + | ^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs new file mode 100644 index 00000000000..31dc684a214 --- /dev/null +++ b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs @@ -0,0 +1,7 @@ +//@ run-pass + +struct A { a: isize } + +fn a(a: A) -> isize { return a.a; } + +pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } diff --git a/tests/ui/parser/integer-literal-method-call-underscore.rs b/tests/ui/parser/integer-literal-method-call-underscore.rs new file mode 100644 index 00000000000..d9eb21894e8 --- /dev/null +++ b/tests/ui/parser/integer-literal-method-call-underscore.rs @@ -0,0 +1,11 @@ +//@ run-pass + +trait Tr : Sized { + fn _method_on_numbers(self) {} +} + +impl Tr for i32 {} + +fn main() { + 42._method_on_numbers(); +} diff --git a/tests/ui/ptr_ops/ptr-write-bool-representation.rs b/tests/ui/ptr_ops/ptr-write-bool-representation.rs new file mode 100644 index 00000000000..4eb25329223 --- /dev/null +++ b/tests/ui/ptr_ops/ptr-write-bool-representation.rs @@ -0,0 +1,11 @@ +//@ run-pass + +use std::ptr; + +pub fn main() { + unsafe { + let mut x: bool = false; + // this line breaks it + ptr::write(&mut x, false); + } +} diff --git a/tests/ui/ptr_ops/raw-pointer-type-basic.rs b/tests/ui/ptr_ops/raw-pointer-type-basic.rs new file mode 100644 index 00000000000..5c8ed344ab3 --- /dev/null +++ b/tests/ui/ptr_ops/raw-pointer-type-basic.rs @@ -0,0 +1,9 @@ +//@ run-pass + +#![allow(dead_code)] + +fn f(a: *const isize) -> *const isize { return a; } + +fn g(a: *const isize) -> *const isize { let b = f(a); return b; } + +pub fn main() { return; } diff --git a/tests/ui/try-operator-hygiene.rs b/tests/ui/try-operator-hygiene.rs deleted file mode 100644 index 20538e094c6..00000000000 --- a/tests/ui/try-operator-hygiene.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ run-pass - -#![allow(non_upper_case_globals)] -#![allow(dead_code)] -// `expr?` expands to: -// -// match expr { -// Ok(val) => val, -// Err(err) => return Err(From::from(err)), -// } -// -// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and -// `err` bindings that may be in scope. - -use std::num::ParseIntError; - -fn main() { - assert_eq!(parse(), Ok(1)); -} - -fn parse() -> Result { - const val: char = 'a'; - const err: char = 'b'; - - Ok("1".parse::()?) -} diff --git a/tests/ui/try-operator.rs b/tests/ui/try-operator.rs deleted file mode 100644 index b9978204557..00000000000 --- a/tests/ui/try-operator.rs +++ /dev/null @@ -1,192 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -use std::fs::File; -use std::io::{Read, self}; -use std::num::ParseIntError; -use std::str::FromStr; - -fn on_method() -> Result { - Ok("1".parse::()? + "2".parse::()?) -} - -fn in_chain() -> Result { - Ok("3".parse::()?.to_string()) -} - -fn on_call() -> Result { - fn parse(s: &str) -> Result { - s.parse() - } - - Ok(parse("4")?) -} - -fn nested() -> Result { - Ok("5".parse::()?.to_string().parse()?) -} - -fn on_path() -> Result { - let x = "6".parse::(); - - Ok(x?) -} - -fn on_macro() -> Result { - macro_rules! id { - ($e:expr) => { $e } - } - - Ok(id!("7".parse::())?) -} - -fn on_parens() -> Result { - let x = "8".parse::(); - - Ok((x)?) -} - -fn on_block() -> Result { - let x = "9".parse::(); - - Ok({x}?) -} - -fn on_field() -> Result { - struct Pair { a: A, b: B } - - let x = Pair { a: "10".parse::(), b: 0 }; - - Ok(x.a?) -} - -fn on_tuple_field() -> Result { - let x = ("11".parse::(), 0); - - Ok(x.0?) -} - -fn on_try() -> Result { - let x = "12".parse::().map(|i| i.to_string().parse::()); - - Ok(x??) -} - -fn on_binary_op() -> Result { - let x = 13 - "14".parse::()?; - let y = "15".parse::()? - 16; - let z = "17".parse::()? - "18".parse::()?; - - Ok(x + y + z) -} - -fn on_index() -> Result { - let x = [19]; - let y = "0".parse::(); - - Ok(x[y?]) -} - -fn on_args() -> Result { - fn sub(x: i32, y: i32) -> i32 { x - y } - - let x = "20".parse(); - let y = "21".parse(); - - Ok(sub(x?, y?)) -} - -fn on_if() -> Result { - Ok(if true { - "22".parse::() - } else { - "23".parse::() - }?) -} - -fn on_if_let() -> Result { - Ok(if let Ok(..) = "24".parse::() { - "25".parse::() - } else { - "26".parse::() - }?) -} - -fn on_match() -> Result { - Ok(match "27".parse::() { - Err(..) => "28".parse::(), - Ok(..) => "29".parse::(), - }?) -} - -fn tight_binding() -> Result { - fn ok(x: T) -> Result { Ok(x) } - - let x = ok(true); - Ok(!x?) -} - -// just type check -fn merge_error() -> Result { - let mut s = String::new(); - - File::open("foo.txt")?.read_to_string(&mut s)?; - - Ok(s.parse::()? + 1) -} - -fn main() { - assert_eq!(Ok(3), on_method()); - - assert_eq!(Ok("3".to_string()), in_chain()); - - assert_eq!(Ok(4), on_call()); - - assert_eq!(Ok(5), nested()); - - assert_eq!(Ok(6), on_path()); - - assert_eq!(Ok(7), on_macro()); - - assert_eq!(Ok(8), on_parens()); - - assert_eq!(Ok(9), on_block()); - - assert_eq!(Ok(10), on_field()); - - assert_eq!(Ok(11), on_tuple_field()); - - assert_eq!(Ok(12), on_try()); - - assert_eq!(Ok(-3), on_binary_op()); - - assert_eq!(Ok(19), on_index()); - - assert_eq!(Ok(-1), on_args()); - - assert_eq!(Ok(22), on_if()); - - assert_eq!(Ok(25), on_if_let()); - - assert_eq!(Ok(29), on_match()); - - assert_eq!(Ok(false), tight_binding()); -} - -enum Error { - Io(io::Error), - Parse(ParseIntError), -} - -impl From for Error { - fn from(e: io::Error) -> Error { - Error::Io(e) - } -} - -impl From for Error { - fn from(e: ParseIntError) -> Error { - Error::Parse(e) - } -} diff --git a/tests/ui/try-trait/try-operator-expansion-hygiene.rs b/tests/ui/try-trait/try-operator-expansion-hygiene.rs new file mode 100644 index 00000000000..20538e094c6 --- /dev/null +++ b/tests/ui/try-trait/try-operator-expansion-hygiene.rs @@ -0,0 +1,26 @@ +//@ run-pass + +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +// `expr?` expands to: +// +// match expr { +// Ok(val) => val, +// Err(err) => return Err(From::from(err)), +// } +// +// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and +// `err` bindings that may be in scope. + +use std::num::ParseIntError; + +fn main() { + assert_eq!(parse(), Ok(1)); +} + +fn parse() -> Result { + const val: char = 'a'; + const err: char = 'b'; + + Ok("1".parse::()?) +} diff --git a/tests/ui/try-trait/try-operator-various-contexts.rs b/tests/ui/try-trait/try-operator-various-contexts.rs new file mode 100644 index 00000000000..b9978204557 --- /dev/null +++ b/tests/ui/try-trait/try-operator-various-contexts.rs @@ -0,0 +1,192 @@ +//@ run-pass + +#![allow(dead_code)] + +use std::fs::File; +use std::io::{Read, self}; +use std::num::ParseIntError; +use std::str::FromStr; + +fn on_method() -> Result { + Ok("1".parse::()? + "2".parse::()?) +} + +fn in_chain() -> Result { + Ok("3".parse::()?.to_string()) +} + +fn on_call() -> Result { + fn parse(s: &str) -> Result { + s.parse() + } + + Ok(parse("4")?) +} + +fn nested() -> Result { + Ok("5".parse::()?.to_string().parse()?) +} + +fn on_path() -> Result { + let x = "6".parse::(); + + Ok(x?) +} + +fn on_macro() -> Result { + macro_rules! id { + ($e:expr) => { $e } + } + + Ok(id!("7".parse::())?) +} + +fn on_parens() -> Result { + let x = "8".parse::(); + + Ok((x)?) +} + +fn on_block() -> Result { + let x = "9".parse::(); + + Ok({x}?) +} + +fn on_field() -> Result { + struct Pair { a: A, b: B } + + let x = Pair { a: "10".parse::(), b: 0 }; + + Ok(x.a?) +} + +fn on_tuple_field() -> Result { + let x = ("11".parse::(), 0); + + Ok(x.0?) +} + +fn on_try() -> Result { + let x = "12".parse::().map(|i| i.to_string().parse::()); + + Ok(x??) +} + +fn on_binary_op() -> Result { + let x = 13 - "14".parse::()?; + let y = "15".parse::()? - 16; + let z = "17".parse::()? - "18".parse::()?; + + Ok(x + y + z) +} + +fn on_index() -> Result { + let x = [19]; + let y = "0".parse::(); + + Ok(x[y?]) +} + +fn on_args() -> Result { + fn sub(x: i32, y: i32) -> i32 { x - y } + + let x = "20".parse(); + let y = "21".parse(); + + Ok(sub(x?, y?)) +} + +fn on_if() -> Result { + Ok(if true { + "22".parse::() + } else { + "23".parse::() + }?) +} + +fn on_if_let() -> Result { + Ok(if let Ok(..) = "24".parse::() { + "25".parse::() + } else { + "26".parse::() + }?) +} + +fn on_match() -> Result { + Ok(match "27".parse::() { + Err(..) => "28".parse::(), + Ok(..) => "29".parse::(), + }?) +} + +fn tight_binding() -> Result { + fn ok(x: T) -> Result { Ok(x) } + + let x = ok(true); + Ok(!x?) +} + +// just type check +fn merge_error() -> Result { + let mut s = String::new(); + + File::open("foo.txt")?.read_to_string(&mut s)?; + + Ok(s.parse::()? + 1) +} + +fn main() { + assert_eq!(Ok(3), on_method()); + + assert_eq!(Ok("3".to_string()), in_chain()); + + assert_eq!(Ok(4), on_call()); + + assert_eq!(Ok(5), nested()); + + assert_eq!(Ok(6), on_path()); + + assert_eq!(Ok(7), on_macro()); + + assert_eq!(Ok(8), on_parens()); + + assert_eq!(Ok(9), on_block()); + + assert_eq!(Ok(10), on_field()); + + assert_eq!(Ok(11), on_tuple_field()); + + assert_eq!(Ok(12), on_try()); + + assert_eq!(Ok(-3), on_binary_op()); + + assert_eq!(Ok(19), on_index()); + + assert_eq!(Ok(-1), on_args()); + + assert_eq!(Ok(22), on_if()); + + assert_eq!(Ok(25), on_if_let()); + + assert_eq!(Ok(29), on_match()); + + assert_eq!(Ok(false), tight_binding()); +} + +enum Error { + Io(io::Error), + Parse(ParseIntError), +} + +impl From for Error { + fn from(e: io::Error) -> Error { + Error::Io(e) + } +} + +impl From for Error { + fn from(e: ParseIntError) -> Error { + Error::Parse(e) + } +} diff --git a/tests/ui/tydesc-name.rs b/tests/ui/tydesc-name.rs deleted file mode 100644 index 068a42606c2..00000000000 --- a/tests/ui/tydesc-name.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -use std::any::type_name; - -struct Foo { - x: T -} - -pub fn main() { - assert_eq!(type_name::(), "isize"); - assert_eq!(type_name::>(), "tydesc_name::Foo"); -} diff --git a/tests/ui/type-id-higher-rank-2.rs b/tests/ui/type-id-higher-rank-2.rs deleted file mode 100644 index 7b0c7b53940..00000000000 --- a/tests/ui/type-id-higher-rank-2.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ run-pass -// Test that we can't ignore lifetimes by going through Any. - -use std::any::Any; - -struct Foo<'a>(&'a str); - -fn good(s: &String) -> Foo<'_> { Foo(s) } - -fn bad1(s: String) -> Option<&'static str> { - let a: Box = Box::new(good as fn(&String) -> Foo); - a.downcast_ref:: Foo<'static>>().map(|f| f(&s).0) -} - -trait AsStr<'a, 'b> { - fn get(&'a self) -> &'b str; -} - -impl<'a> AsStr<'a, 'a> for String { - fn get(&'a self) -> &'a str { self } -} - -fn bad2(s: String) -> Option<&'static str> { - let a: Box = Box::new(Box::new(s) as Box AsStr<'a, 'a>>); - a.downcast_ref:: AsStr<'a, 'static>>>().map(|x| x.get()) -} - -fn main() { - assert_eq!(bad1(String::from("foo")), None); - assert_eq!(bad2(String::from("bar")), None); -} diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs new file mode 100644 index 00000000000..473ca954b23 --- /dev/null +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs @@ -0,0 +1,7 @@ +struct S<'a, T:'a> { + o: &'a Option +} + +fn main() { + S { o: &None }; //~ ERROR type annotations needed [E0282] +} diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr new file mode 100644 index 00000000000..72fd0202f4e --- /dev/null +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/unconstrained-ref.rs:6:5 + | +LL | S { o: &None }; + | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `S` + | +help: consider specifying the generic argument + | +LL | S:: { o: &None }; + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.rs b/tests/ui/type-inference/type-inference-unconstrained-none.rs new file mode 100644 index 00000000000..e180b3163d4 --- /dev/null +++ b/tests/ui/type-inference/type-inference-unconstrained-none.rs @@ -0,0 +1,5 @@ +// Issue #5062 + +fn main() { + None; //~ ERROR type annotations needed [E0282] +} diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.stderr b/tests/ui/type-inference/type-inference-unconstrained-none.stderr new file mode 100644 index 00000000000..4af6f412e5b --- /dev/null +++ b/tests/ui/type-inference/type-inference-unconstrained-none.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/unconstrained-none.rs:4:5 + | +LL | None; + | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` + | +help: consider specifying the generic argument + | +LL | None::; + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-namespace.rs b/tests/ui/type-namespace.rs deleted file mode 100644 index 31dc684a214..00000000000 --- a/tests/ui/type-namespace.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -struct A { a: isize } - -fn a(a: A) -> isize { return a.a; } - -pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } diff --git a/tests/ui/type-param-constraints.rs b/tests/ui/type-param-constraints.rs deleted file mode 100644 index 83d81c0d833..00000000000 --- a/tests/ui/type-param-constraints.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] - -fn p_foo(_pinned: T) { } -fn s_foo(_shared: T) { } -fn u_foo(_unique: T) { } - -struct r { - i: isize, -} - -impl Drop for r { - fn drop(&mut self) {} -} - -fn r(i:isize) -> r { - r { - i: i - } -} - -pub fn main() { - p_foo(r(10)); - - p_foo::>(Box::new(r(10))); - p_foo::>(Box::new(10)); - p_foo(10); - - s_foo::>(Box::new(10)); - s_foo(10); - - u_foo::>(Box::new(10)); - u_foo(10); -} diff --git a/tests/ui/type-ptr.rs b/tests/ui/type-ptr.rs deleted file mode 100644 index 5c8ed344ab3..00000000000 --- a/tests/ui/type-ptr.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass - -#![allow(dead_code)] - -fn f(a: *const isize) -> *const isize { return a; } - -fn g(a: *const isize) -> *const isize { let b = f(a); return b; } - -pub fn main() { return; } diff --git a/tests/ui/type-use-i1-versus-i8.rs b/tests/ui/type-use-i1-versus-i8.rs deleted file mode 100644 index 4eb25329223..00000000000 --- a/tests/ui/type-use-i1-versus-i8.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass - -use std::ptr; - -pub fn main() { - unsafe { - let mut x: bool = false; - // this line breaks it - ptr::write(&mut x, false); - } -} diff --git a/tests/ui/type/type-name-basic.rs b/tests/ui/type/type-name-basic.rs new file mode 100644 index 00000000000..068a42606c2 --- /dev/null +++ b/tests/ui/type/type-name-basic.rs @@ -0,0 +1,14 @@ +//@ run-pass + +#![allow(dead_code)] + +use std::any::type_name; + +struct Foo { + x: T +} + +pub fn main() { + assert_eq!(type_name::(), "isize"); + assert_eq!(type_name::>(), "tydesc_name::Foo"); +} diff --git a/tests/ui/type/typeid-consistency-comprehensive.rs b/tests/ui/type/typeid-consistency-comprehensive.rs new file mode 100644 index 00000000000..7c4fb3f95a9 --- /dev/null +++ b/tests/ui/type/typeid-consistency-comprehensive.rs @@ -0,0 +1,97 @@ +//@ run-pass + +#![allow(deprecated)] +//@ aux-build:typeid-intrinsic-aux1.rs +//@ aux-build:typeid-intrinsic-aux2.rs + +#![feature(core_intrinsics)] + +extern crate typeid_intrinsic_aux1 as other1; +extern crate typeid_intrinsic_aux2 as other2; + +use std::hash::{SipHasher, Hasher, Hash}; +use std::any::TypeId; + +struct A; +struct Test; + +pub fn main() { + assert_eq!(TypeId::of::(), other1::id_A()); + assert_eq!(TypeId::of::(), other1::id_B()); + assert_eq!(TypeId::of::(), other1::id_C()); + assert_eq!(TypeId::of::(), other1::id_D()); + assert_eq!(TypeId::of::(), other1::id_E()); + assert_eq!(TypeId::of::(), other1::id_F()); + assert_eq!(TypeId::of::(), other1::id_G()); + assert_eq!(TypeId::of::(), other1::id_H()); + assert_eq!(TypeId::of::(), other1::id_I()); + + assert_eq!(TypeId::of::(), other2::id_A()); + assert_eq!(TypeId::of::(), other2::id_B()); + assert_eq!(TypeId::of::(), other2::id_C()); + assert_eq!(TypeId::of::(), other2::id_D()); + assert_eq!(TypeId::of::(), other2::id_E()); + assert_eq!(TypeId::of::(), other2::id_F()); + assert_eq!(TypeId::of::(), other2::id_G()); + assert_eq!(TypeId::of::(), other2::id_H()); + assert_eq!(TypeId::of::(), other2::id_I()); + + assert_eq!(other1::id_F(), other2::id_F()); + assert_eq!(other1::id_G(), other2::id_G()); + assert_eq!(other1::id_H(), other2::id_H()); + assert_eq!(other1::id_I(), other2::id_I()); + + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + + // sanity test of TypeId + let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + + assert!(a != b); + assert!(a != c); + assert!(b != c); + + assert_eq!(a, d); + assert_eq!(b, e); + assert_eq!(c, f); + + // check it has a hash + let (a, b) = (TypeId::of::(), TypeId::of::()); + + let mut s1 = SipHasher::new(); + a.hash(&mut s1); + let mut s2 = SipHasher::new(); + b.hash(&mut s2); + + assert_eq!(s1.finish(), s2.finish()); + + // Check projections + + assert_eq!(TypeId::of::(), other1::id_i32_iterator()); + assert_eq!(TypeId::of::(), other1::id_u32_iterator()); + assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); + assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); + assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); + assert_ne!(TypeId::of::(), TypeId::of::()); + + // Check fn pointer against collisions + assert_ne!( + TypeId::of:: A) -> A>(), + TypeId::of:: A, A) -> A>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32) -> &'a i32>(), + TypeId::of:: fn(&'a i32) -> &'static i32>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), + TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() + ); +} diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs deleted file mode 100644 index 87f5ffd76d7..00000000000 --- a/tests/ui/type_length_limit.rs +++ /dev/null @@ -1,34 +0,0 @@ -//@ build-fail -//@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit -//~^^ ERROR reached the type-length limit - -// Test that the type length limit can be changed. -// The exact type depends on optimizations, so disable them. - -#![allow(dead_code)] -#![type_length_limit="8"] - -macro_rules! link { - ($id:ident, $t:ty) => { - pub type $id = ($t, $t, $t); - } -} - -link! { A1, B1 } -link! { B1, C1 } -link! { C1, D1 } -link! { D1, E1 } -link! { E1, A } -link! { A, B } -link! { B, C } -link! { C, D } -link! { D, E } -link! { E, F } -link! { F, G, Option> } - -pub struct G(std::marker::PhantomData::<(T, K)>); - -fn main() { - drop::>(None); - //~^ ERROR reached the type-length limit -} diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr deleted file mode 100644 index 198d133c08c..00000000000 --- a/tests/ui/type_length_limit.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $DIR/type_length_limit.rs:32:5 - | -LL | drop::>(None); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' - -error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` - | - = help: consider adding a `#![type_length_limit="10"]` attribute to your crate - -error: aborting due to 2 previous errors - diff --git a/tests/ui/typeid-intrinsic.rs b/tests/ui/typeid-intrinsic.rs deleted file mode 100644 index 7c4fb3f95a9..00000000000 --- a/tests/ui/typeid-intrinsic.rs +++ /dev/null @@ -1,97 +0,0 @@ -//@ run-pass - -#![allow(deprecated)] -//@ aux-build:typeid-intrinsic-aux1.rs -//@ aux-build:typeid-intrinsic-aux2.rs - -#![feature(core_intrinsics)] - -extern crate typeid_intrinsic_aux1 as other1; -extern crate typeid_intrinsic_aux2 as other2; - -use std::hash::{SipHasher, Hasher, Hash}; -use std::any::TypeId; - -struct A; -struct Test; - -pub fn main() { - assert_eq!(TypeId::of::(), other1::id_A()); - assert_eq!(TypeId::of::(), other1::id_B()); - assert_eq!(TypeId::of::(), other1::id_C()); - assert_eq!(TypeId::of::(), other1::id_D()); - assert_eq!(TypeId::of::(), other1::id_E()); - assert_eq!(TypeId::of::(), other1::id_F()); - assert_eq!(TypeId::of::(), other1::id_G()); - assert_eq!(TypeId::of::(), other1::id_H()); - assert_eq!(TypeId::of::(), other1::id_I()); - - assert_eq!(TypeId::of::(), other2::id_A()); - assert_eq!(TypeId::of::(), other2::id_B()); - assert_eq!(TypeId::of::(), other2::id_C()); - assert_eq!(TypeId::of::(), other2::id_D()); - assert_eq!(TypeId::of::(), other2::id_E()); - assert_eq!(TypeId::of::(), other2::id_F()); - assert_eq!(TypeId::of::(), other2::id_G()); - assert_eq!(TypeId::of::(), other2::id_H()); - assert_eq!(TypeId::of::(), other2::id_I()); - - assert_eq!(other1::id_F(), other2::id_F()); - assert_eq!(other1::id_G(), other2::id_G()); - assert_eq!(other1::id_H(), other2::id_H()); - assert_eq!(other1::id_I(), other2::id_I()); - - assert_eq!(TypeId::of::(), other2::foo::()); - assert_eq!(TypeId::of::(), other1::foo::()); - assert_eq!(other2::foo::(), other1::foo::()); - assert_eq!(TypeId::of::(), other2::foo::()); - assert_eq!(TypeId::of::(), other1::foo::()); - assert_eq!(other2::foo::(), other1::foo::()); - - // sanity test of TypeId - let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); - let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); - - assert!(a != b); - assert!(a != c); - assert!(b != c); - - assert_eq!(a, d); - assert_eq!(b, e); - assert_eq!(c, f); - - // check it has a hash - let (a, b) = (TypeId::of::(), TypeId::of::()); - - let mut s1 = SipHasher::new(); - a.hash(&mut s1); - let mut s2 = SipHasher::new(); - b.hash(&mut s2); - - assert_eq!(s1.finish(), s2.finish()); - - // Check projections - - assert_eq!(TypeId::of::(), other1::id_i32_iterator()); - assert_eq!(TypeId::of::(), other1::id_u32_iterator()); - assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); - assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); - assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); - assert_ne!(TypeId::of::(), TypeId::of::()); - - // Check fn pointer against collisions - assert_ne!( - TypeId::of:: A) -> A>(), - TypeId::of:: A, A) -> A>() - ); - assert_ne!( - TypeId::of:: fn(&'a i32) -> &'a i32>(), - TypeId::of:: fn(&'a i32) -> &'static i32>() - ); - assert_ne!( - TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), - TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() - ); -} diff --git a/tests/ui/typestate-multi-decl.rs b/tests/ui/typestate-multi-decl.rs deleted file mode 100644 index 3d0e79632bb..00000000000 --- a/tests/ui/typestate-multi-decl.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -pub fn main() { - let (x, y) = (10, 20); - let z = x + y; - assert_eq!(z, 30); -} diff --git a/tests/ui/unconstrained-none.rs b/tests/ui/unconstrained-none.rs deleted file mode 100644 index e180b3163d4..00000000000 --- a/tests/ui/unconstrained-none.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Issue #5062 - -fn main() { - None; //~ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/unconstrained-none.stderr b/tests/ui/unconstrained-none.stderr deleted file mode 100644 index 4af6f412e5b..00000000000 --- a/tests/ui/unconstrained-none.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/unconstrained-none.rs:4:5 - | -LL | None; - | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` - | -help: consider specifying the generic argument - | -LL | None::; - | +++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/unconstrained-ref.rs b/tests/ui/unconstrained-ref.rs deleted file mode 100644 index 473ca954b23..00000000000 --- a/tests/ui/unconstrained-ref.rs +++ /dev/null @@ -1,7 +0,0 @@ -struct S<'a, T:'a> { - o: &'a Option -} - -fn main() { - S { o: &None }; //~ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/unconstrained-ref.stderr b/tests/ui/unconstrained-ref.stderr deleted file mode 100644 index 72fd0202f4e..00000000000 --- a/tests/ui/unconstrained-ref.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:5 - | -LL | S { o: &None }; - | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `S` - | -help: consider specifying the generic argument - | -LL | S:: { o: &None }; - | +++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/underscore-ident-matcher.rs b/tests/ui/underscore-ident-matcher.rs deleted file mode 100644 index 77ec70d43d5..00000000000 --- a/tests/ui/underscore-ident-matcher.rs +++ /dev/null @@ -1,9 +0,0 @@ -macro_rules! identity { - ($i: ident) => ( - $i - ) -} - -fn main() { - let identity!(_) = 10; //~ ERROR no rules expected reserved identifier `_` -} diff --git a/tests/ui/underscore-ident-matcher.stderr b/tests/ui/underscore-ident-matcher.stderr deleted file mode 100644 index 0c3f980cf6c..00000000000 --- a/tests/ui/underscore-ident-matcher.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: no rules expected reserved identifier `_` - --> $DIR/underscore-ident-matcher.rs:8:19 - | -LL | macro_rules! identity { - | --------------------- when calling this macro -... -LL | let identity!(_) = 10; - | ^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$i:ident` - --> $DIR/underscore-ident-matcher.rs:2:6 - | -LL | ($i: ident) => ( - | ^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs new file mode 100644 index 00000000000..a372851f9cf --- /dev/null +++ b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs @@ -0,0 +1,38 @@ +//@ run-pass + +#![allow(dead_code, mismatched_lifetime_syntaxes)] +struct Foo<'a>(&'a u8); + +fn foo(x: &u8) -> Foo<'_> { + Foo(x) +} + +fn foo2(x: &'_ u8) -> Foo<'_> { + Foo(x) +} + +fn foo3(x: &'_ u8) -> Foo { + Foo(x) +} + +fn foo4(_: Foo<'_>) {} + +struct Foo2<'a, 'b> { + a: &'a u8, + b: &'b u8, +} +fn foo5<'b>(foo: Foo2<'_, 'b>) -> &'b u8 { + foo.b +} + +fn main() { + let x = &5; + let _ = foo(x); + let _ = foo2(x); + let _ = foo3(x); + foo4(Foo(x)); + let _ = foo5(Foo2 { + a: x, + b: &6, + }); +} diff --git a/tests/ui/underscore-lifetimes.rs b/tests/ui/underscore-lifetimes.rs deleted file mode 100644 index a372851f9cf..00000000000 --- a/tests/ui/underscore-lifetimes.rs +++ /dev/null @@ -1,38 +0,0 @@ -//@ run-pass - -#![allow(dead_code, mismatched_lifetime_syntaxes)] -struct Foo<'a>(&'a u8); - -fn foo(x: &u8) -> Foo<'_> { - Foo(x) -} - -fn foo2(x: &'_ u8) -> Foo<'_> { - Foo(x) -} - -fn foo3(x: &'_ u8) -> Foo { - Foo(x) -} - -fn foo4(_: Foo<'_>) {} - -struct Foo2<'a, 'b> { - a: &'a u8, - b: &'b u8, -} -fn foo5<'b>(foo: Foo2<'_, 'b>) -> &'b u8 { - foo.b -} - -fn main() { - let x = &5; - let _ = foo(x); - let _ = foo2(x); - let _ = foo3(x); - foo4(Foo(x)); - let _ = foo5(Foo2 { - a: x, - b: &6, - }); -} diff --git a/tests/ui/underscore-method-after-integer.rs b/tests/ui/underscore-method-after-integer.rs deleted file mode 100644 index d9eb21894e8..00000000000 --- a/tests/ui/underscore-method-after-integer.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass - -trait Tr : Sized { - fn _method_on_numbers(self) {} -} - -impl Tr for i32 {} - -fn main() { - 42._method_on_numbers(); -} diff --git a/tests/ui/unevaluated_fixed_size_array_len.rs b/tests/ui/unevaluated_fixed_size_array_len.rs deleted file mode 100644 index 6c545913dd9..00000000000 --- a/tests/ui/unevaluated_fixed_size_array_len.rs +++ /dev/null @@ -1,13 +0,0 @@ -// https://github.com/rust-lang/rust/issues/49208 - -trait Foo { - fn foo(); -} - -impl Foo for [(); 1] { - fn foo() {} -} - -fn main() { - <[(); 0] as Foo>::foo() //~ ERROR E0277 -} diff --git a/tests/ui/unevaluated_fixed_size_array_len.stderr b/tests/ui/unevaluated_fixed_size_array_len.stderr deleted file mode 100644 index 43cc377006e..00000000000 --- a/tests/ui/unevaluated_fixed_size_array_len.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied - --> $DIR/unevaluated_fixed_size_array_len.rs:12:6 - | -LL | <[(); 0] as Foo>::foo() - | ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` - | - = help: the trait `Foo` is implemented for `[(); 1]` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From 1fb5e0149fb85af0e49fa40329cbc352b4cba861 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 23:33:59 +0500 Subject: moved tests --- tests/ui/allocator/weak-uninhabited-type.rs | 7 + .../underscore-prefixed-function-argument.rs | 13 + .../ownership-struct-update-moved-error.rs | 17 ++ .../ownership-struct-update-moved-error.stderr | 20 ++ tests/ui/closures/no-capture-closure-call.rs | 7 + tests/ui/codegen/llvm-args-invalid-flag.rs | 22 ++ tests/ui/codegen/llvm-args-invalid-flag.stderr | 1 + .../box-drop-unused-value-statement-regression.rs | 12 + tests/ui/expr/syntax-edge-cases-lint-clean.rs | 303 +++++++++++++++++++++ tests/ui/hashmap/hashset-enum-variant.rs | 31 +++ tests/ui/io-checks/write-macro-error.rs | 55 ++++ .../lang-item-unknown-definition-error.rs | 10 + .../lang-item-unknown-definition-error.stderr | 9 + tests/ui/modules/module-qualified-paths-basic.rs | 11 + tests/ui/modules/module-use-nested-groups.rs | 32 +++ .../primitive-type-module-deprecated-paths.rs | 12 + .../ui/modules/use-keyword-reexport-type-alias.rs | 23 ++ .../unary-negation-unsigned-integer-error.rs | 5 + .../unary-negation-unsigned-integer-error.stderr | 42 +++ tests/ui/panics/unwind-force-no-unwind-tables.rs | 34 +++ tests/ui/process/process-spawn-failure.rs | 71 +++++ tests/ui/process/windows-exit-code-still-active.rs | 28 ++ .../diverging-expressions-unreachable-code.rs | 19 ++ .../unreachable-code-diverging-expressions.rs | 35 +++ tests/ui/traits/virtual-call-parameter-handling.rs | 45 +++ tests/ui/type/unit-type-basic-usages.rs | 16 ++ tests/ui/type/usize-no-generic-arguments.rs | 5 + tests/ui/type/usize-no-generic-arguments.stderr | 17 ++ tests/ui/uninit-empty-types.rs | 18 -- tests/ui/unit.rs | 16 -- tests/ui/unknown-language-item.rs | 10 - tests/ui/unknown-language-item.stderr | 9 - tests/ui/unknown-llvm-arg.rs | 22 -- tests/ui/unknown-llvm-arg.stderr | 1 - tests/ui/unnamed_argument_mode.rs | 13 - tests/ui/unreachable-code-1.rs | 19 -- tests/ui/unreachable-code.rs | 35 --- tests/ui/unsafe/maybe-uninit-zero-sized-types.rs | 18 ++ tests/ui/unsigned-literal-negation.rs | 5 - tests/ui/unsigned-literal-negation.stderr | 42 --- tests/ui/unused-move-capture.rs | 7 - tests/ui/unused-move.rs | 12 - tests/ui/unwind-no-uwtable.rs | 34 --- tests/ui/use-import-export.rs | 11 - tests/ui/use-keyword-2.rs | 23 -- tests/ui/use-module-level-int-consts.rs | 12 - tests/ui/use-nested-groups.rs | 32 --- tests/ui/usize-generic-argument-parent.rs | 5 - tests/ui/usize-generic-argument-parent.stderr | 17 -- tests/ui/virtual-call-attrs-issue-137646.rs | 45 --- tests/ui/wait-forked-but-failed-child.rs | 71 ----- tests/ui/walk-struct-literal-with.rs | 17 -- tests/ui/walk-struct-literal-with.stderr | 20 -- tests/ui/weak-new-uninhabited-issue-48493.rs | 7 - tests/ui/weird-exit-code.rs | 28 -- tests/ui/weird-exprs.rs | 303 --------------------- tests/ui/write-fmt-errors.rs | 55 ---- tests/ui/wrong-hashset-issue-42918.rs | 31 --- 58 files changed, 920 insertions(+), 920 deletions(-) create mode 100644 tests/ui/allocator/weak-uninhabited-type.rs create mode 100644 tests/ui/binding/underscore-prefixed-function-argument.rs create mode 100644 tests/ui/borrowck/ownership-struct-update-moved-error.rs create mode 100644 tests/ui/borrowck/ownership-struct-update-moved-error.stderr create mode 100644 tests/ui/closures/no-capture-closure-call.rs create mode 100644 tests/ui/codegen/llvm-args-invalid-flag.rs create mode 100644 tests/ui/codegen/llvm-args-invalid-flag.stderr create mode 100644 tests/ui/drop/box-drop-unused-value-statement-regression.rs create mode 100644 tests/ui/expr/syntax-edge-cases-lint-clean.rs create mode 100644 tests/ui/hashmap/hashset-enum-variant.rs create mode 100644 tests/ui/io-checks/write-macro-error.rs create mode 100644 tests/ui/lang-items/lang-item-unknown-definition-error.rs create mode 100644 tests/ui/lang-items/lang-item-unknown-definition-error.stderr create mode 100644 tests/ui/modules/module-qualified-paths-basic.rs create mode 100644 tests/ui/modules/module-use-nested-groups.rs create mode 100644 tests/ui/modules/primitive-type-module-deprecated-paths.rs create mode 100644 tests/ui/modules/use-keyword-reexport-type-alias.rs create mode 100644 tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs create mode 100644 tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr create mode 100644 tests/ui/panics/unwind-force-no-unwind-tables.rs create mode 100644 tests/ui/process/process-spawn-failure.rs create mode 100644 tests/ui/process/windows-exit-code-still-active.rs create mode 100644 tests/ui/reachable/diverging-expressions-unreachable-code.rs create mode 100644 tests/ui/reachable/unreachable-code-diverging-expressions.rs create mode 100644 tests/ui/traits/virtual-call-parameter-handling.rs create mode 100644 tests/ui/type/unit-type-basic-usages.rs create mode 100644 tests/ui/type/usize-no-generic-arguments.rs create mode 100644 tests/ui/type/usize-no-generic-arguments.stderr delete mode 100644 tests/ui/uninit-empty-types.rs delete mode 100644 tests/ui/unit.rs delete mode 100644 tests/ui/unknown-language-item.rs delete mode 100644 tests/ui/unknown-language-item.stderr delete mode 100644 tests/ui/unknown-llvm-arg.rs delete mode 100644 tests/ui/unknown-llvm-arg.stderr delete mode 100644 tests/ui/unnamed_argument_mode.rs delete mode 100644 tests/ui/unreachable-code-1.rs delete mode 100644 tests/ui/unreachable-code.rs create mode 100644 tests/ui/unsafe/maybe-uninit-zero-sized-types.rs delete mode 100644 tests/ui/unsigned-literal-negation.rs delete mode 100644 tests/ui/unsigned-literal-negation.stderr delete mode 100644 tests/ui/unused-move-capture.rs delete mode 100644 tests/ui/unused-move.rs delete mode 100644 tests/ui/unwind-no-uwtable.rs delete mode 100644 tests/ui/use-import-export.rs delete mode 100644 tests/ui/use-keyword-2.rs delete mode 100644 tests/ui/use-module-level-int-consts.rs delete mode 100644 tests/ui/use-nested-groups.rs delete mode 100644 tests/ui/usize-generic-argument-parent.rs delete mode 100644 tests/ui/usize-generic-argument-parent.stderr delete mode 100644 tests/ui/virtual-call-attrs-issue-137646.rs delete mode 100644 tests/ui/wait-forked-but-failed-child.rs delete mode 100644 tests/ui/walk-struct-literal-with.rs delete mode 100644 tests/ui/walk-struct-literal-with.stderr delete mode 100644 tests/ui/weak-new-uninhabited-issue-48493.rs delete mode 100644 tests/ui/weird-exit-code.rs delete mode 100644 tests/ui/weird-exprs.rs delete mode 100644 tests/ui/write-fmt-errors.rs delete mode 100644 tests/ui/wrong-hashset-issue-42918.rs diff --git a/tests/ui/allocator/weak-uninhabited-type.rs b/tests/ui/allocator/weak-uninhabited-type.rs new file mode 100644 index 00000000000..ce7d5786b41 --- /dev/null +++ b/tests/ui/allocator/weak-uninhabited-type.rs @@ -0,0 +1,7 @@ +//@ run-pass + +fn main() { + enum Void {} + let _ = std::rc::Weak::::new(); + let _ = std::sync::Weak::::new(); +} diff --git a/tests/ui/binding/underscore-prefixed-function-argument.rs b/tests/ui/binding/underscore-prefixed-function-argument.rs new file mode 100644 index 00000000000..2014e0d23d8 --- /dev/null +++ b/tests/ui/binding/underscore-prefixed-function-argument.rs @@ -0,0 +1,13 @@ +//@ run-pass + +fn good(_a: &isize) { +} + +// unnamed argument &isize is now parse x: &isize + +fn called(_f: F) where F: FnOnce(&isize) { +} + +pub fn main() { + called(good); +} diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.rs b/tests/ui/borrowck/ownership-struct-update-moved-error.rs new file mode 100644 index 00000000000..ee1a77eb9a4 --- /dev/null +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.rs @@ -0,0 +1,17 @@ +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` +} diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr new file mode 100644 index 00000000000..34b501f8ec8 --- /dev/null +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr @@ -0,0 +1,20 @@ +error[E0382]: borrow of moved value: `start` + --> $DIR/walk-struct-literal-with.rs:16:20 + | +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 +LL | let end = Mine{other_val:1, ..start.make_string_bar()}; + | ----------------- `start` moved due to this method call +LL | println!("{}", start.test); + | ^^^^^^^^^^ value borrowed here after move + | +note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start` + --> $DIR/walk-struct-literal-with.rs:7:28 + | +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) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/closures/no-capture-closure-call.rs b/tests/ui/closures/no-capture-closure-call.rs new file mode 100644 index 00000000000..5f42bcbe280 --- /dev/null +++ b/tests/ui/closures/no-capture-closure-call.rs @@ -0,0 +1,7 @@ +//@ run-pass + +pub fn main() { + let _x: Box<_> = Box::new(1); + let lam_move = || {}; + lam_move(); +} diff --git a/tests/ui/codegen/llvm-args-invalid-flag.rs b/tests/ui/codegen/llvm-args-invalid-flag.rs new file mode 100644 index 00000000000..a8fa55a220a --- /dev/null +++ b/tests/ui/codegen/llvm-args-invalid-flag.rs @@ -0,0 +1,22 @@ +//@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg +//@ normalize-stderr: "--help" -> "-help" +//@ normalize-stderr: "\n(\n|.)*" -> "" + +// I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". + +// Note that the rustc-supplied "program name", given when invoking LLVM, is used by LLVM to +// generate user-facing error messages and a usage (--help) messages. If the program name is +// `rustc`, the usage message in response to `--llvm-args="--help"` starts with: +// ``` +// USAGE: rustc [options] +// ``` +// followed by the list of options not to `rustc` but to `llvm`. +// +// On the other hand, if the program name is set to `rustc -Cllvm-args="..." with`, the usage +// message is more clear: +// ``` +// USAGE: rustc -Cllvm-args="..." with [options] +// ``` +// This test captures the effect of the current program name setting on LLVM command line +// error messages. +fn main() {} diff --git a/tests/ui/codegen/llvm-args-invalid-flag.stderr b/tests/ui/codegen/llvm-args-invalid-flag.stderr new file mode 100644 index 00000000000..e1d3cfea28f --- /dev/null +++ b/tests/ui/codegen/llvm-args-invalid-flag.stderr @@ -0,0 +1 @@ +rustc -Cllvm-args="..." with: Unknown command line argument '-not-a-real-llvm-arg'. Try: 'rustc -Cllvm-args="..." with -help' \ No newline at end of file diff --git a/tests/ui/drop/box-drop-unused-value-statement-regression.rs b/tests/ui/drop/box-drop-unused-value-statement-regression.rs new file mode 100644 index 00000000000..3d5eff2c48d --- /dev/null +++ b/tests/ui/drop/box-drop-unused-value-statement-regression.rs @@ -0,0 +1,12 @@ +//@ 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; +} diff --git a/tests/ui/expr/syntax-edge-cases-lint-clean.rs b/tests/ui/expr/syntax-edge-cases-lint-clean.rs new file mode 100644 index 00000000000..7db92d46067 --- /dev/null +++ b/tests/ui/expr/syntax-edge-cases-lint-clean.rs @@ -0,0 +1,303 @@ +//@ run-pass + +#![feature(coroutines)] + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![allow(redundant_semicolons)] +#![allow(unreachable_code)] +#![allow(unused_braces, unused_must_use, unused_parens)] +#![allow(uncommon_codepoints, confusable_idents)] +#![allow(unused_imports)] +#![allow(unreachable_patterns)] + +#![recursion_limit = "256"] + +extern crate core; +use std::cell::Cell; +use std::mem::swap; +use std::ops::Deref; + +// Just a grab bag of stuff that you wouldn't want to actually write. + +fn strange() -> bool { let _x: bool = return true; } + +fn funny() { + fn f(_x: ()) { } + f(return); +} + +fn what() { + fn the(x: &Cell) { + return while !x.get() { x.set(true); }; + } + let i = &Cell::new(false); + let dont = {||the(i)}; + dont(); + assert!(i.get()); +} + +fn zombiejesus() { + loop { + while (return) { + if (return) { + match (return) { + 1 => { + if (return) { + return + } else { + return + } + } + _ => { return } + }; + } else if (return) { + return; + } + } + if (return) { break; } + } +} + +fn notsure() { + let mut _x: isize; + let mut _y = (_x = 0) == (_x = 0); + let mut _z = (_x = 0) < (_x = 0); + let _a = (_x += 0) == (_x = 0); + let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z); +} + +fn canttouchthis() -> usize { + fn p() -> bool { true } + let _a = (assert!(true) == (assert!(p()))); + let _c = (assert!(p()) == ()); + let _b: bool = (println!("{}", 0) == (return 0)); +} + +fn angrydome() { + loop { if break { } } + let mut i = 0; + loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } } + break; } +} + +fn evil_lincoln() { let _evil: () = println!("lincoln"); } + +fn dots() { + assert_eq!(String::from(".................................................."), + format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. ..)); +} + +fn u8(u8: u8) { + if u8 != 0u8 { + assert_eq!(8u8, { + macro_rules! u8 { + (u8) => { + mod u8 { + pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 { + "u8"; + u8 + } + } + }; + } + + u8!(u8); + let &u8: &u8 = u8::u8(&8u8); + crate::u8(0u8); + u8 + }); + } +} + +fn fishy() { + assert_eq!(String::from("><>"), + String::<>::from::<>("><>").chars::<>().rev::<>().collect::()); +} + +fn union() { + union union<'union> { union: &'union union<'union>, } +} + +fn special_characters() { + let val = !((|(..):(_,_),(|__@_|__)|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})// + ; + assert!(!val); +} + +fn punch_card() -> impl std::fmt::Debug { + ..=..=.. .. .. .. .. .. .. .. .. .. .. .. .. .. + ..=.. ..=.. .. .. .. .. .. .. .. .. .. ..=.. .. + ..=.. ..=.. ..=.. ..=.. .. ..=..=.. ..=..=..=.. + ..=..=.. .. ..=.. ..=.. ..=.. .. .. .. ..=.. .. + ..=.. ..=.. ..=.. ..=.. .. ..=.. .. .. ..=.. .. + ..=.. ..=.. ..=.. ..=.. .. .. ..=.. .. ..=.. .. + ..=.. ..=.. .. ..=..=.. ..=..=.. .. .. ..=..=.. +} + +fn r#match() { + let val: () = match match match match match () { + () => () + } { + () => () + } { + () => () + } { + () => () + } { + () => () + }; + assert_eq!(val, ()); +} + +fn i_yield() { + #[coroutine] + static || { + yield yield yield yield yield yield yield yield yield; + }; +} + +fn match_nested_if() { + let val = match () { + () if if if if true {true} else {false} {true} else {false} {true} else {false} => true, + _ => false, + }; + assert!(val); +} + +fn monkey_barrel() { + let val: () = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=(); + assert_eq!(val, ()); +} + +fn 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎() { + type 𝚕𝚘𝚘𝚙 = i32; + fn 𝚋𝚛𝚎𝚊𝚔() -> 𝚕𝚘𝚘𝚙 { + let 𝚛𝚎𝚝𝚞𝚛𝚗 = 42; + return 𝚛𝚎𝚝𝚞𝚛𝚗; + } + assert_eq!(loop { + break 𝚋𝚛𝚎𝚊𝚔 (); + }, 42); +} + +fn function() { + struct foo; + impl Deref for foo { + type Target = fn() -> Self; + fn deref(&self) -> &Self::Target { + &((|| foo) as _) + } + } + let foo = foo () ()() ()()() ()()()() ()()()()(); +} + +fn bathroom_stall() { + let mut i = 1; + matches!(2, _|_|_|_|_|_ if (i+=1) != (i+=1)); + assert_eq!(i, 13); +} + +fn closure_matching() { + let x = |_| Some(1); + let (|x| x) = match x(..) { + |_| Some(2) => |_| Some(3), + |_| _ => unreachable!(), + }; + assert!(matches!(x(..), |_| Some(4))); +} + +fn semisemisemisemisemi() { + ;;;;;;; ;;;;;;; ;;; ;;; ;; + ;; ;; ;;;; ;;;; ;; + ;;;;;;; ;;;;; ;; ;;;; ;; ;; + ;; ;; ;; ;; ;; ;; + ;;;;;;; ;;;;;;; ;; ;; ;; +} + +fn useful_syntax() { + use {{std::{{collections::{{HashMap}}}}}}; + use ::{{{{core}, {std}}}}; + use {{::{{core as core2}}}}; +} + +fn infcx() { + pub mod cx { + pub mod cx { + pub use super::cx; + pub struct Cx; + } + } + let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx; +} + +fn return_already() -> impl std::fmt::Debug { + loop { + return !!!!!!! + break !!!!!!1111 + } +} + +fn fake_macros() -> impl std::fmt::Debug { + loop { + if! { + match! ( + break! { + return! { + 1337 + } + } + ) + + {} + } + + {} + } +} + +fn fish_fight() { + trait Rope { + fn _____________(_: Self, _: U) where Self: Sized {} + } + + struct T; + + impl Rope for T {} + + fn tug_o_war(_: impl Fn(T, T)) {} + + tug_o_war(::_____________::); +} + +pub fn main() { + strange(); + funny(); + what(); + zombiejesus(); + notsure(); + canttouchthis(); + angrydome(); + evil_lincoln(); + dots(); + u8(8u8); + fishy(); + union(); + special_characters(); + punch_card(); + r#match(); + i_yield(); + match_nested_if(); + monkey_barrel(); + 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎(); + function(); + bathroom_stall(); + closure_matching(); + semisemisemisemisemi(); + useful_syntax(); + infcx(); + return_already(); + fake_macros(); + fish_fight(); +} diff --git a/tests/ui/hashmap/hashset-enum-variant.rs b/tests/ui/hashmap/hashset-enum-variant.rs new file mode 100644 index 00000000000..5795cc527cf --- /dev/null +++ b/tests/ui/hashmap/hashset-enum-variant.rs @@ -0,0 +1,31 @@ +//@ run-pass +// +#![allow(dead_code)] +//@ compile-flags: -O + +use std::collections::HashSet; + +#[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] +enum MyEnum { + E0, + + E1, + + E2, + E3, + E4, + + E5, + E6, + E7, +} + + +fn main() { + use MyEnum::*; + let s: HashSet<_> = [E4, E1].iter().cloned().collect(); + let mut v: Vec<_> = s.into_iter().collect(); + v.sort(); + + assert_eq!([E1, E4], &v[..]); +} diff --git a/tests/ui/io-checks/write-macro-error.rs b/tests/ui/io-checks/write-macro-error.rs new file mode 100644 index 00000000000..b48fa3f11cc --- /dev/null +++ b/tests/ui/io-checks/write-macro-error.rs @@ -0,0 +1,55 @@ +//@ run-pass +//@ needs-unwind + +#![feature(io_error_uncategorized)] + +use std::fmt; +use std::io::{self, Error, Write}; +use std::panic::catch_unwind; + +struct ErrorDisplay; + +impl fmt::Display for ErrorDisplay { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Err(fmt::Error) + } +} + +struct ErrorWriter; + +const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected; + +impl Write for ErrorWriter { + fn write(&mut self, _buf: &[u8]) -> io::Result { + Err(Error::new(WRITER_ERROR, "not connected")) + } + + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} + +fn main() { + // Test that an underlying error is propagated + let res = write!(ErrorWriter, "abc"); + assert!(res.is_err(), "writer error did not propagate"); + + // Test that the error from the formatter is detected. + let res = catch_unwind(|| write!(vec![], "{} {} {}", 1, ErrorDisplay, "bar")); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); + + // Writer error when there's some string before the first `{}` + let res = write!(ErrorWriter, "abc {}", ErrorDisplay); + assert!(res.is_err(), "writer error did not propagate"); + assert_eq!(res.unwrap_err().kind(), WRITER_ERROR); + + // Formatter error when the `{}` comes first + let res = catch_unwind(|| write!(ErrorWriter, "{} abc", ErrorDisplay)); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); +} diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.rs b/tests/ui/lang-items/lang-item-unknown-definition-error.rs new file mode 100644 index 00000000000..ce206d20358 --- /dev/null +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.rs @@ -0,0 +1,10 @@ +#![allow(unused)] +#![feature(lang_items)] + +#[lang = "foo"] +fn bar() -> ! { +//~^^ ERROR definition of an unknown lang item: `foo` + loop {} +} + +fn main() {} diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.stderr b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr new file mode 100644 index 00000000000..832f1342418 --- /dev/null +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr @@ -0,0 +1,9 @@ +error[E0522]: definition of an unknown lang item: `foo` + --> $DIR/unknown-language-item.rs:4:1 + | +LL | #[lang = "foo"] + | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0522`. diff --git a/tests/ui/modules/module-qualified-paths-basic.rs b/tests/ui/modules/module-qualified-paths-basic.rs new file mode 100644 index 00000000000..d948ffc1520 --- /dev/null +++ b/tests/ui/modules/module-qualified-paths-basic.rs @@ -0,0 +1,11 @@ +//@ 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(); } diff --git a/tests/ui/modules/module-use-nested-groups.rs b/tests/ui/modules/module-use-nested-groups.rs new file mode 100644 index 00000000000..c5d66a86935 --- /dev/null +++ b/tests/ui/modules/module-use-nested-groups.rs @@ -0,0 +1,32 @@ +//@ run-pass + +mod a { + pub enum B {} + + pub mod d { + pub enum E {} + pub enum F {} + + pub mod g { + pub enum H {} + pub enum I {} + } + } +} + +// Test every possible part of the syntax +use a::{B, d::{self, *, g::H}}; + +// Test a more common use case +use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; + +fn main() { + let _: B; + let _: E; + let _: F; + let _: H; + let _: d::g::I; + + let _: Arc; + let _: Ordering; +} diff --git a/tests/ui/modules/primitive-type-module-deprecated-paths.rs b/tests/ui/modules/primitive-type-module-deprecated-paths.rs new file mode 100644 index 00000000000..6e8c7053c57 --- /dev/null +++ b/tests/ui/modules/primitive-type-module-deprecated-paths.rs @@ -0,0 +1,12 @@ +//@ 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; +} diff --git a/tests/ui/modules/use-keyword-reexport-type-alias.rs b/tests/ui/modules/use-keyword-reexport-type-alias.rs new file mode 100644 index 00000000000..4f3d1ee500d --- /dev/null +++ b/tests/ui/modules/use-keyword-reexport-type-alias.rs @@ -0,0 +1,23 @@ +//@ run-pass + +#![allow(unused_variables)] +pub struct A; + +mod test { + pub use super :: A; + + pub use self :: A as B; +} + +impl A { + fn f() {} + fn g() { + Self :: f() + } +} + +fn main() { + let a: A = test::A; + let b: A = test::B; + let c: () = A::g(); +} diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs new file mode 100644 index 00000000000..943c7f79742 --- /dev/null +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs @@ -0,0 +1,5 @@ +fn main() { + let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` + let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` + let x: u32 = -1; //~ ERROR: cannot apply unary operator `-` +} diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr new file mode 100644 index 00000000000..0bedbc1accd --- /dev/null +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr @@ -0,0 +1,42 @@ +error[E0600]: cannot apply unary operator `-` to type `usize` + --> $DIR/unsigned-literal-negation.rs:2:13 + | +LL | let x = -1 as usize; + | ^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated +help: you may have meant the maximum value of `usize` + | +LL - let x = -1 as usize; +LL + let x = usize::MAX; + | + +error[E0600]: cannot apply unary operator `-` to type `usize` + --> $DIR/unsigned-literal-negation.rs:3:13 + | +LL | let x = (-1) as usize; + | ^^^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated +help: you may have meant the maximum value of `usize` + | +LL - let x = (-1) as usize; +LL + let x = usize::MAX; + | + +error[E0600]: cannot apply unary operator `-` to type `u32` + --> $DIR/unsigned-literal-negation.rs:4:18 + | +LL | let x: u32 = -1; + | ^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated +help: you may have meant the maximum value of `u32` + | +LL - let x: u32 = -1; +LL + let x: u32 = u32::MAX; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0600`. diff --git a/tests/ui/panics/unwind-force-no-unwind-tables.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs new file mode 100644 index 00000000000..fb8082e3188 --- /dev/null +++ b/tests/ui/panics/unwind-force-no-unwind-tables.rs @@ -0,0 +1,34 @@ +//@ run-pass +//@ needs-unwind +//@ ignore-windows target requires uwtable +//@ compile-flags: -C panic=unwind -C force-unwind-tables=n + +use std::panic::{self, AssertUnwindSafe}; + +struct Increase<'a>(&'a mut u8); + +impl Drop for Increase<'_> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +#[inline(never)] +fn unwind() { + panic!(); +} + +#[inline(never)] +fn increase(count: &mut u8) { + let _increase = Increase(count); + unwind(); +} + +fn main() { + let mut count = 0; + assert!(panic::catch_unwind(AssertUnwindSafe( + #[inline(never)] + || increase(&mut count) + )).is_err()); + assert_eq!(count, 1); +} diff --git a/tests/ui/process/process-spawn-failure.rs b/tests/ui/process/process-spawn-failure.rs new file mode 100644 index 00000000000..4a7f2bee9d9 --- /dev/null +++ b/tests/ui/process/process-spawn-failure.rs @@ -0,0 +1,71 @@ +//@ run-pass +//@ needs-subprocess +//@ ignore-vxworks no 'ps' +//@ ignore-fuchsia no 'ps' +//@ ignore-nto no 'ps' + +#![feature(rustc_private)] + +use std::process::Command; + +// The output from "ps -A -o pid,ppid,args" should look like this: +// PID PPID COMMAND +// 1 0 /sbin/init +// 2 0 [kthreadd] +// ... +// 6076 9064 /bin/zsh +// ... +// 7164 6076 ./spawn-failure +// 7165 7164 [spawn-failure] +// 7166 7164 [spawn-failure] +// ... +// 7197 7164 [spawn-failure] +// 7198 7164 ps -A -o pid,ppid,command +// ... + +#[cfg(unix)] +fn find_zombies() { + extern crate libc; + let my_pid = unsafe { libc::getpid() }; + + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html + let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap(); + let ps_output = String::from_utf8_lossy(&ps_cmd_output.stdout); + // On AIX, the PPID is not always present, such as when a process is blocked + // (marked as ), or if a process is idle. In these situations, + // the PPID column contains a "-" for the respective process. + // Filter out any lines that have a "-" as the PPID as the PPID is + // expected to be an integer. + let filtered_ps: Vec<_> = ps_output + .lines() + .filter(|line| line.split_whitespace().nth(1) != Some("-")) + .collect(); + + for (line_no, line) in filtered_ps.into_iter().enumerate() { + if 0 < line_no && 0 < line.len() && + my_pid == line.split(' ').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); + } + } +} + +#[cfg(windows)] +fn find_zombies() { } + +fn main() { + let too_long = format!("/NoSuchCommand{:0300}", 0u8); + + let _failures = (0..100).map(|_| { + let mut cmd = Command::new(&too_long); + let failed = cmd.spawn(); + assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); + failed + }).collect::>(); + + find_zombies(); + // then _failures goes out of scope +} diff --git a/tests/ui/process/windows-exit-code-still-active.rs b/tests/ui/process/windows-exit-code-still-active.rs new file mode 100644 index 00000000000..e016343f8ba --- /dev/null +++ b/tests/ui/process/windows-exit-code-still-active.rs @@ -0,0 +1,28 @@ +//@ 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() {} diff --git a/tests/ui/reachable/diverging-expressions-unreachable-code.rs b/tests/ui/reachable/diverging-expressions-unreachable-code.rs new file mode 100644 index 00000000000..9c5f7c8f451 --- /dev/null +++ b/tests/ui/reachable/diverging-expressions-unreachable-code.rs @@ -0,0 +1,19 @@ +//@ 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() { +} diff --git a/tests/ui/reachable/unreachable-code-diverging-expressions.rs b/tests/ui/reachable/unreachable-code-diverging-expressions.rs new file mode 100644 index 00000000000..0c46a38d73f --- /dev/null +++ b/tests/ui/reachable/unreachable-code-diverging-expressions.rs @@ -0,0 +1,35 @@ +//@ run-pass + +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(path_statements)] +#![allow(unreachable_code)] +#![allow(unused_variables)] +#![feature(if_let_guard)] + +fn id(x: bool) -> bool { + x +} + +fn call_id() { + let c = panic!(); + id(c); +} + +fn call_id_2() { + id(true) && id(return); +} + +fn call_id_3() { + id(return) && id(return); +} + +fn ret_guard() { + match 2 { + x if (return) => { x; } + x if let true = return => { x; } + _ => {} + } +} + +pub fn main() {} diff --git a/tests/ui/traits/virtual-call-parameter-handling.rs b/tests/ui/traits/virtual-call-parameter-handling.rs new file mode 100644 index 00000000000..e80bd5768a4 --- /dev/null +++ b/tests/ui/traits/virtual-call-parameter-handling.rs @@ -0,0 +1,45 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/137646. +//! The parameter value at all calls to `check` should be `(1, 1, 1)`. + +//@ run-pass + +use std::hint::black_box; + +type T = (i32, i32, i32); + +pub trait Trait { + fn m(&self, _: T, _: T) {} +} + +impl Trait for () { + fn m(&self, mut _v1: T, v2: T) { + _v1 = (0, 0, 0); + check(v2); + } +} + +pub fn run_1(trait_: &dyn Trait) { + let v1 = (1, 1, 1); + let v2 = (1, 1, 1); + trait_.m(v1, v2); +} + +pub fn run_2(trait_: &dyn Trait) { + let v1 = (1, 1, 1); + let v2 = (1, 1, 1); + trait_.m(v1, v2); + check(v1); + check(v2); +} + +#[inline(never)] +fn check(v: T) { + assert_eq!(v, (1, 1, 1)); +} + +fn main() { + black_box(run_1 as fn(&dyn Trait)); + black_box(run_2 as fn(&dyn Trait)); + run_1(&()); + run_2(&()); +} diff --git a/tests/ui/type/unit-type-basic-usages.rs b/tests/ui/type/unit-type-basic-usages.rs new file mode 100644 index 00000000000..04404fc3f5e --- /dev/null +++ b/tests/ui/type/unit-type-basic-usages.rs @@ -0,0 +1,16 @@ +//@ 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 (); +} diff --git a/tests/ui/type/usize-no-generic-arguments.rs b/tests/ui/type/usize-no-generic-arguments.rs new file mode 100644 index 00000000000..4ab80d944a5 --- /dev/null +++ b/tests/ui/type/usize-no-generic-arguments.rs @@ -0,0 +1,5 @@ +fn foo() { + let x: usize; //~ ERROR const arguments are not allowed on builtin type `usize` +} + +fn main() {} diff --git a/tests/ui/type/usize-no-generic-arguments.stderr b/tests/ui/type/usize-no-generic-arguments.stderr new file mode 100644 index 00000000000..9c081a287ed --- /dev/null +++ b/tests/ui/type/usize-no-generic-arguments.stderr @@ -0,0 +1,17 @@ +error[E0109]: const arguments are not allowed on builtin type `usize` + --> $DIR/usize-generic-argument-parent.rs:2:18 + | +LL | let x: usize; + | ----- ^^^ const argument not allowed + | | + | not allowed on builtin type `usize` + | +help: primitive type `usize` doesn't have generic parameters + | +LL - let x: usize; +LL + let x: usize; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/uninit-empty-types.rs b/tests/ui/uninit-empty-types.rs deleted file mode 100644 index 82474d873b7..00000000000 --- a/tests/ui/uninit-empty-types.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ build-pass -// Test the uninit() construct returning various empty types. - - -use std::mem::MaybeUninit; - -struct Foo; - -#[allow(deprecated)] -pub fn main() { - unsafe { - // `Foo` and `[Foo; 2]` are both zero sized and inhabited, so this is safe. - let _x: Foo = MaybeUninit::uninit().assume_init(); - let _x: [Foo; 2] = MaybeUninit::uninit().assume_init(); - let _x: Foo = std::mem::uninitialized(); - let _x: [Foo; 2] = std::mem::uninitialized(); - } -} diff --git a/tests/ui/unit.rs b/tests/ui/unit.rs deleted file mode 100644 index 04404fc3f5e..00000000000 --- a/tests/ui/unit.rs +++ /dev/null @@ -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 (); -} diff --git a/tests/ui/unknown-language-item.rs b/tests/ui/unknown-language-item.rs deleted file mode 100644 index ce206d20358..00000000000 --- a/tests/ui/unknown-language-item.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![allow(unused)] -#![feature(lang_items)] - -#[lang = "foo"] -fn bar() -> ! { -//~^^ ERROR definition of an unknown lang item: `foo` - loop {} -} - -fn main() {} diff --git a/tests/ui/unknown-language-item.stderr b/tests/ui/unknown-language-item.stderr deleted file mode 100644 index 832f1342418..00000000000 --- a/tests/ui/unknown-language-item.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0522]: definition of an unknown lang item: `foo` - --> $DIR/unknown-language-item.rs:4:1 - | -LL | #[lang = "foo"] - | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0522`. diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/unknown-llvm-arg.rs deleted file mode 100644 index a8fa55a220a..00000000000 --- a/tests/ui/unknown-llvm-arg.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg -//@ normalize-stderr: "--help" -> "-help" -//@ normalize-stderr: "\n(\n|.)*" -> "" - -// I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". - -// Note that the rustc-supplied "program name", given when invoking LLVM, is used by LLVM to -// generate user-facing error messages and a usage (--help) messages. If the program name is -// `rustc`, the usage message in response to `--llvm-args="--help"` starts with: -// ``` -// USAGE: rustc [options] -// ``` -// followed by the list of options not to `rustc` but to `llvm`. -// -// On the other hand, if the program name is set to `rustc -Cllvm-args="..." with`, the usage -// message is more clear: -// ``` -// USAGE: rustc -Cllvm-args="..." with [options] -// ``` -// This test captures the effect of the current program name setting on LLVM command line -// error messages. -fn main() {} diff --git a/tests/ui/unknown-llvm-arg.stderr b/tests/ui/unknown-llvm-arg.stderr deleted file mode 100644 index e1d3cfea28f..00000000000 --- a/tests/ui/unknown-llvm-arg.stderr +++ /dev/null @@ -1 +0,0 @@ -rustc -Cllvm-args="..." with: Unknown command line argument '-not-a-real-llvm-arg'. Try: 'rustc -Cllvm-args="..." with -help' \ No newline at end of file diff --git a/tests/ui/unnamed_argument_mode.rs b/tests/ui/unnamed_argument_mode.rs deleted file mode 100644 index 2014e0d23d8..00000000000 --- a/tests/ui/unnamed_argument_mode.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass - -fn good(_a: &isize) { -} - -// unnamed argument &isize is now parse x: &isize - -fn called(_f: F) where F: FnOnce(&isize) { -} - -pub fn main() { - called(good); -} diff --git a/tests/ui/unreachable-code-1.rs b/tests/ui/unreachable-code-1.rs deleted file mode 100644 index 9c5f7c8f451..00000000000 --- a/tests/ui/unreachable-code-1.rs +++ /dev/null @@ -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() { -} diff --git a/tests/ui/unreachable-code.rs b/tests/ui/unreachable-code.rs deleted file mode 100644 index 0c46a38d73f..00000000000 --- a/tests/ui/unreachable-code.rs +++ /dev/null @@ -1,35 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] -#![allow(dead_code)] -#![allow(path_statements)] -#![allow(unreachable_code)] -#![allow(unused_variables)] -#![feature(if_let_guard)] - -fn id(x: bool) -> bool { - x -} - -fn call_id() { - let c = panic!(); - id(c); -} - -fn call_id_2() { - id(true) && id(return); -} - -fn call_id_3() { - id(return) && id(return); -} - -fn ret_guard() { - match 2 { - x if (return) => { x; } - x if let true = return => { x; } - _ => {} - } -} - -pub fn main() {} diff --git a/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs new file mode 100644 index 00000000000..82474d873b7 --- /dev/null +++ b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs @@ -0,0 +1,18 @@ +//@ build-pass +// Test the uninit() construct returning various empty types. + + +use std::mem::MaybeUninit; + +struct Foo; + +#[allow(deprecated)] +pub fn main() { + unsafe { + // `Foo` and `[Foo; 2]` are both zero sized and inhabited, so this is safe. + let _x: Foo = MaybeUninit::uninit().assume_init(); + let _x: [Foo; 2] = MaybeUninit::uninit().assume_init(); + let _x: Foo = std::mem::uninitialized(); + let _x: [Foo; 2] = std::mem::uninitialized(); + } +} diff --git a/tests/ui/unsigned-literal-negation.rs b/tests/ui/unsigned-literal-negation.rs deleted file mode 100644 index 943c7f79742..00000000000 --- a/tests/ui/unsigned-literal-negation.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` - let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` - let x: u32 = -1; //~ ERROR: cannot apply unary operator `-` -} diff --git a/tests/ui/unsigned-literal-negation.stderr b/tests/ui/unsigned-literal-negation.stderr deleted file mode 100644 index 0bedbc1accd..00000000000 --- a/tests/ui/unsigned-literal-negation.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:2:13 - | -LL | let x = -1 as usize; - | ^^ cannot apply unary operator `-` - | - = note: unsigned values cannot be negated -help: you may have meant the maximum value of `usize` - | -LL - let x = -1 as usize; -LL + let x = usize::MAX; - | - -error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:3:13 - | -LL | let x = (-1) as usize; - | ^^^^ cannot apply unary operator `-` - | - = note: unsigned values cannot be negated -help: you may have meant the maximum value of `usize` - | -LL - let x = (-1) as usize; -LL + let x = usize::MAX; - | - -error[E0600]: cannot apply unary operator `-` to type `u32` - --> $DIR/unsigned-literal-negation.rs:4:18 - | -LL | let x: u32 = -1; - | ^^ cannot apply unary operator `-` - | - = note: unsigned values cannot be negated -help: you may have meant the maximum value of `u32` - | -LL - let x: u32 = -1; -LL + let x: u32 = u32::MAX; - | - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0600`. diff --git a/tests/ui/unused-move-capture.rs b/tests/ui/unused-move-capture.rs deleted file mode 100644 index 5f42bcbe280..00000000000 --- a/tests/ui/unused-move-capture.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -pub fn main() { - let _x: Box<_> = Box::new(1); - let lam_move = || {}; - lam_move(); -} diff --git a/tests/ui/unused-move.rs b/tests/ui/unused-move.rs deleted file mode 100644 index 3d5eff2c48d..00000000000 --- a/tests/ui/unused-move.rs +++ /dev/null @@ -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; -} diff --git a/tests/ui/unwind-no-uwtable.rs b/tests/ui/unwind-no-uwtable.rs deleted file mode 100644 index fb8082e3188..00000000000 --- a/tests/ui/unwind-no-uwtable.rs +++ /dev/null @@ -1,34 +0,0 @@ -//@ run-pass -//@ needs-unwind -//@ ignore-windows target requires uwtable -//@ compile-flags: -C panic=unwind -C force-unwind-tables=n - -use std::panic::{self, AssertUnwindSafe}; - -struct Increase<'a>(&'a mut u8); - -impl Drop for Increase<'_> { - fn drop(&mut self) { - *self.0 += 1; - } -} - -#[inline(never)] -fn unwind() { - panic!(); -} - -#[inline(never)] -fn increase(count: &mut u8) { - let _increase = Increase(count); - unwind(); -} - -fn main() { - let mut count = 0; - assert!(panic::catch_unwind(AssertUnwindSafe( - #[inline(never)] - || increase(&mut count) - )).is_err()); - assert_eq!(count, 1); -} diff --git a/tests/ui/use-import-export.rs b/tests/ui/use-import-export.rs deleted file mode 100644 index d948ffc1520..00000000000 --- a/tests/ui/use-import-export.rs +++ /dev/null @@ -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(); } diff --git a/tests/ui/use-keyword-2.rs b/tests/ui/use-keyword-2.rs deleted file mode 100644 index 4f3d1ee500d..00000000000 --- a/tests/ui/use-keyword-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ run-pass - -#![allow(unused_variables)] -pub struct A; - -mod test { - pub use super :: A; - - pub use self :: A as B; -} - -impl A { - fn f() {} - fn g() { - Self :: f() - } -} - -fn main() { - let a: A = test::A; - let b: A = test::B; - let c: () = A::g(); -} diff --git a/tests/ui/use-module-level-int-consts.rs b/tests/ui/use-module-level-int-consts.rs deleted file mode 100644 index 6e8c7053c57..00000000000 --- a/tests/ui/use-module-level-int-consts.rs +++ /dev/null @@ -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; -} diff --git a/tests/ui/use-nested-groups.rs b/tests/ui/use-nested-groups.rs deleted file mode 100644 index c5d66a86935..00000000000 --- a/tests/ui/use-nested-groups.rs +++ /dev/null @@ -1,32 +0,0 @@ -//@ run-pass - -mod a { - pub enum B {} - - pub mod d { - pub enum E {} - pub enum F {} - - pub mod g { - pub enum H {} - pub enum I {} - } - } -} - -// Test every possible part of the syntax -use a::{B, d::{self, *, g::H}}; - -// Test a more common use case -use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; - -fn main() { - let _: B; - let _: E; - let _: F; - let _: H; - let _: d::g::I; - - let _: Arc; - let _: Ordering; -} diff --git a/tests/ui/usize-generic-argument-parent.rs b/tests/ui/usize-generic-argument-parent.rs deleted file mode 100644 index 4ab80d944a5..00000000000 --- a/tests/ui/usize-generic-argument-parent.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn foo() { - let x: usize; //~ ERROR const arguments are not allowed on builtin type `usize` -} - -fn main() {} diff --git a/tests/ui/usize-generic-argument-parent.stderr b/tests/ui/usize-generic-argument-parent.stderr deleted file mode 100644 index 9c081a287ed..00000000000 --- a/tests/ui/usize-generic-argument-parent.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0109]: const arguments are not allowed on builtin type `usize` - --> $DIR/usize-generic-argument-parent.rs:2:18 - | -LL | let x: usize; - | ----- ^^^ const argument not allowed - | | - | not allowed on builtin type `usize` - | -help: primitive type `usize` doesn't have generic parameters - | -LL - let x: usize; -LL + let x: usize; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/virtual-call-attrs-issue-137646.rs b/tests/ui/virtual-call-attrs-issue-137646.rs deleted file mode 100644 index e80bd5768a4..00000000000 --- a/tests/ui/virtual-call-attrs-issue-137646.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Regression test for https://github.com/rust-lang/rust/issues/137646. -//! The parameter value at all calls to `check` should be `(1, 1, 1)`. - -//@ run-pass - -use std::hint::black_box; - -type T = (i32, i32, i32); - -pub trait Trait { - fn m(&self, _: T, _: T) {} -} - -impl Trait for () { - fn m(&self, mut _v1: T, v2: T) { - _v1 = (0, 0, 0); - check(v2); - } -} - -pub fn run_1(trait_: &dyn Trait) { - let v1 = (1, 1, 1); - let v2 = (1, 1, 1); - trait_.m(v1, v2); -} - -pub fn run_2(trait_: &dyn Trait) { - let v1 = (1, 1, 1); - let v2 = (1, 1, 1); - trait_.m(v1, v2); - check(v1); - check(v2); -} - -#[inline(never)] -fn check(v: T) { - assert_eq!(v, (1, 1, 1)); -} - -fn main() { - black_box(run_1 as fn(&dyn Trait)); - black_box(run_2 as fn(&dyn Trait)); - run_1(&()); - run_2(&()); -} diff --git a/tests/ui/wait-forked-but-failed-child.rs b/tests/ui/wait-forked-but-failed-child.rs deleted file mode 100644 index 4a7f2bee9d9..00000000000 --- a/tests/ui/wait-forked-but-failed-child.rs +++ /dev/null @@ -1,71 +0,0 @@ -//@ run-pass -//@ needs-subprocess -//@ ignore-vxworks no 'ps' -//@ ignore-fuchsia no 'ps' -//@ ignore-nto no 'ps' - -#![feature(rustc_private)] - -use std::process::Command; - -// The output from "ps -A -o pid,ppid,args" should look like this: -// PID PPID COMMAND -// 1 0 /sbin/init -// 2 0 [kthreadd] -// ... -// 6076 9064 /bin/zsh -// ... -// 7164 6076 ./spawn-failure -// 7165 7164 [spawn-failure] -// 7166 7164 [spawn-failure] -// ... -// 7197 7164 [spawn-failure] -// 7198 7164 ps -A -o pid,ppid,command -// ... - -#[cfg(unix)] -fn find_zombies() { - extern crate libc; - let my_pid = unsafe { libc::getpid() }; - - // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html - let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap(); - let ps_output = String::from_utf8_lossy(&ps_cmd_output.stdout); - // On AIX, the PPID is not always present, such as when a process is blocked - // (marked as ), or if a process is idle. In these situations, - // the PPID column contains a "-" for the respective process. - // Filter out any lines that have a "-" as the PPID as the PPID is - // expected to be an integer. - let filtered_ps: Vec<_> = ps_output - .lines() - .filter(|line| line.split_whitespace().nth(1) != Some("-")) - .collect(); - - for (line_no, line) in filtered_ps.into_iter().enumerate() { - if 0 < line_no && 0 < line.len() && - my_pid == line.split(' ').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); - } - } -} - -#[cfg(windows)] -fn find_zombies() { } - -fn main() { - let too_long = format!("/NoSuchCommand{:0300}", 0u8); - - let _failures = (0..100).map(|_| { - let mut cmd = Command::new(&too_long); - let failed = cmd.spawn(); - assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); - failed - }).collect::>(); - - find_zombies(); - // then _failures goes out of scope -} diff --git a/tests/ui/walk-struct-literal-with.rs b/tests/ui/walk-struct-literal-with.rs deleted file mode 100644 index ee1a77eb9a4..00000000000 --- a/tests/ui/walk-struct-literal-with.rs +++ /dev/null @@ -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` -} diff --git a/tests/ui/walk-struct-literal-with.stderr b/tests/ui/walk-struct-literal-with.stderr deleted file mode 100644 index 34b501f8ec8..00000000000 --- a/tests/ui/walk-struct-literal-with.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0382]: borrow of moved value: `start` - --> $DIR/walk-struct-literal-with.rs:16:20 - | -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 -LL | let end = Mine{other_val:1, ..start.make_string_bar()}; - | ----------------- `start` moved due to this method call -LL | println!("{}", start.test); - | ^^^^^^^^^^ value borrowed here after move - | -note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start` - --> $DIR/walk-struct-literal-with.rs:7:28 - | -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) - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/weak-new-uninhabited-issue-48493.rs b/tests/ui/weak-new-uninhabited-issue-48493.rs deleted file mode 100644 index ce7d5786b41..00000000000 --- a/tests/ui/weak-new-uninhabited-issue-48493.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -fn main() { - enum Void {} - let _ = std::rc::Weak::::new(); - let _ = std::sync::Weak::::new(); -} diff --git a/tests/ui/weird-exit-code.rs b/tests/ui/weird-exit-code.rs deleted file mode 100644 index e016343f8ba..00000000000 --- a/tests/ui/weird-exit-code.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs deleted file mode 100644 index 7db92d46067..00000000000 --- a/tests/ui/weird-exprs.rs +++ /dev/null @@ -1,303 +0,0 @@ -//@ run-pass - -#![feature(coroutines)] - -#![allow(non_camel_case_types)] -#![allow(dead_code)] -#![allow(redundant_semicolons)] -#![allow(unreachable_code)] -#![allow(unused_braces, unused_must_use, unused_parens)] -#![allow(uncommon_codepoints, confusable_idents)] -#![allow(unused_imports)] -#![allow(unreachable_patterns)] - -#![recursion_limit = "256"] - -extern crate core; -use std::cell::Cell; -use std::mem::swap; -use std::ops::Deref; - -// Just a grab bag of stuff that you wouldn't want to actually write. - -fn strange() -> bool { let _x: bool = return true; } - -fn funny() { - fn f(_x: ()) { } - f(return); -} - -fn what() { - fn the(x: &Cell) { - return while !x.get() { x.set(true); }; - } - let i = &Cell::new(false); - let dont = {||the(i)}; - dont(); - assert!(i.get()); -} - -fn zombiejesus() { - loop { - while (return) { - if (return) { - match (return) { - 1 => { - if (return) { - return - } else { - return - } - } - _ => { return } - }; - } else if (return) { - return; - } - } - if (return) { break; } - } -} - -fn notsure() { - let mut _x: isize; - let mut _y = (_x = 0) == (_x = 0); - let mut _z = (_x = 0) < (_x = 0); - let _a = (_x += 0) == (_x = 0); - let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z); -} - -fn canttouchthis() -> usize { - fn p() -> bool { true } - let _a = (assert!(true) == (assert!(p()))); - let _c = (assert!(p()) == ()); - let _b: bool = (println!("{}", 0) == (return 0)); -} - -fn angrydome() { - loop { if break { } } - let mut i = 0; - loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } } - break; } -} - -fn evil_lincoln() { let _evil: () = println!("lincoln"); } - -fn dots() { - assert_eq!(String::from(".................................................."), - format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. .. - .. .. .. .. .. .. .. .. .. .. .. ..)); -} - -fn u8(u8: u8) { - if u8 != 0u8 { - assert_eq!(8u8, { - macro_rules! u8 { - (u8) => { - mod u8 { - pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 { - "u8"; - u8 - } - } - }; - } - - u8!(u8); - let &u8: &u8 = u8::u8(&8u8); - crate::u8(0u8); - u8 - }); - } -} - -fn fishy() { - assert_eq!(String::from("><>"), - String::<>::from::<>("><>").chars::<>().rev::<>().collect::()); -} - -fn union() { - union union<'union> { union: &'union union<'union>, } -} - -fn special_characters() { - let val = !((|(..):(_,_),(|__@_|__)|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})// - ; - assert!(!val); -} - -fn punch_card() -> impl std::fmt::Debug { - ..=..=.. .. .. .. .. .. .. .. .. .. .. .. .. .. - ..=.. ..=.. .. .. .. .. .. .. .. .. .. ..=.. .. - ..=.. ..=.. ..=.. ..=.. .. ..=..=.. ..=..=..=.. - ..=..=.. .. ..=.. ..=.. ..=.. .. .. .. ..=.. .. - ..=.. ..=.. ..=.. ..=.. .. ..=.. .. .. ..=.. .. - ..=.. ..=.. ..=.. ..=.. .. .. ..=.. .. ..=.. .. - ..=.. ..=.. .. ..=..=.. ..=..=.. .. .. ..=..=.. -} - -fn r#match() { - let val: () = match match match match match () { - () => () - } { - () => () - } { - () => () - } { - () => () - } { - () => () - }; - assert_eq!(val, ()); -} - -fn i_yield() { - #[coroutine] - static || { - yield yield yield yield yield yield yield yield yield; - }; -} - -fn match_nested_if() { - let val = match () { - () if if if if true {true} else {false} {true} else {false} {true} else {false} => true, - _ => false, - }; - assert!(val); -} - -fn monkey_barrel() { - let val: () = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=(); - assert_eq!(val, ()); -} - -fn 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎() { - type 𝚕𝚘𝚘𝚙 = i32; - fn 𝚋𝚛𝚎𝚊𝚔() -> 𝚕𝚘𝚘𝚙 { - let 𝚛𝚎𝚝𝚞𝚛𝚗 = 42; - return 𝚛𝚎𝚝𝚞𝚛𝚗; - } - assert_eq!(loop { - break 𝚋𝚛𝚎𝚊𝚔 (); - }, 42); -} - -fn function() { - struct foo; - impl Deref for foo { - type Target = fn() -> Self; - fn deref(&self) -> &Self::Target { - &((|| foo) as _) - } - } - let foo = foo () ()() ()()() ()()()() ()()()()(); -} - -fn bathroom_stall() { - let mut i = 1; - matches!(2, _|_|_|_|_|_ if (i+=1) != (i+=1)); - assert_eq!(i, 13); -} - -fn closure_matching() { - let x = |_| Some(1); - let (|x| x) = match x(..) { - |_| Some(2) => |_| Some(3), - |_| _ => unreachable!(), - }; - assert!(matches!(x(..), |_| Some(4))); -} - -fn semisemisemisemisemi() { - ;;;;;;; ;;;;;;; ;;; ;;; ;; - ;; ;; ;;;; ;;;; ;; - ;;;;;;; ;;;;; ;; ;;;; ;; ;; - ;; ;; ;; ;; ;; ;; - ;;;;;;; ;;;;;;; ;; ;; ;; -} - -fn useful_syntax() { - use {{std::{{collections::{{HashMap}}}}}}; - use ::{{{{core}, {std}}}}; - use {{::{{core as core2}}}}; -} - -fn infcx() { - pub mod cx { - pub mod cx { - pub use super::cx; - pub struct Cx; - } - } - let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx; -} - -fn return_already() -> impl std::fmt::Debug { - loop { - return !!!!!!! - break !!!!!!1111 - } -} - -fn fake_macros() -> impl std::fmt::Debug { - loop { - if! { - match! ( - break! { - return! { - 1337 - } - } - ) - - {} - } - - {} - } -} - -fn fish_fight() { - trait Rope { - fn _____________(_: Self, _: U) where Self: Sized {} - } - - struct T; - - impl Rope for T {} - - fn tug_o_war(_: impl Fn(T, T)) {} - - tug_o_war(::_____________::); -} - -pub fn main() { - strange(); - funny(); - what(); - zombiejesus(); - notsure(); - canttouchthis(); - angrydome(); - evil_lincoln(); - dots(); - u8(8u8); - fishy(); - union(); - special_characters(); - punch_card(); - r#match(); - i_yield(); - match_nested_if(); - monkey_barrel(); - 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎(); - function(); - bathroom_stall(); - closure_matching(); - semisemisemisemisemi(); - useful_syntax(); - infcx(); - return_already(); - fake_macros(); - fish_fight(); -} diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs deleted file mode 100644 index b48fa3f11cc..00000000000 --- a/tests/ui/write-fmt-errors.rs +++ /dev/null @@ -1,55 +0,0 @@ -//@ run-pass -//@ needs-unwind - -#![feature(io_error_uncategorized)] - -use std::fmt; -use std::io::{self, Error, Write}; -use std::panic::catch_unwind; - -struct ErrorDisplay; - -impl fmt::Display for ErrorDisplay { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - Err(fmt::Error) - } -} - -struct ErrorWriter; - -const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected; - -impl Write for ErrorWriter { - fn write(&mut self, _buf: &[u8]) -> io::Result { - Err(Error::new(WRITER_ERROR, "not connected")) - } - - fn flush(&mut self) -> io::Result<()> { Ok(()) } -} - -fn main() { - // Test that an underlying error is propagated - let res = write!(ErrorWriter, "abc"); - assert!(res.is_err(), "writer error did not propagate"); - - // Test that the error from the formatter is detected. - let res = catch_unwind(|| write!(vec![], "{} {} {}", 1, ErrorDisplay, "bar")); - let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); - assert!( - err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err - ); - - // Writer error when there's some string before the first `{}` - let res = write!(ErrorWriter, "abc {}", ErrorDisplay); - assert!(res.is_err(), "writer error did not propagate"); - assert_eq!(res.unwrap_err().kind(), WRITER_ERROR); - - // Formatter error when the `{}` comes first - let res = catch_unwind(|| write!(ErrorWriter, "{} abc", ErrorDisplay)); - let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); - assert!( - err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err - ); -} diff --git a/tests/ui/wrong-hashset-issue-42918.rs b/tests/ui/wrong-hashset-issue-42918.rs deleted file mode 100644 index 5795cc527cf..00000000000 --- a/tests/ui/wrong-hashset-issue-42918.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ run-pass -// -#![allow(dead_code)] -//@ compile-flags: -O - -use std::collections::HashSet; - -#[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] -enum MyEnum { - E0, - - E1, - - E2, - E3, - E4, - - E5, - E6, - E7, -} - - -fn main() { - use MyEnum::*; - let s: HashSet<_> = [E4, E1].iter().cloned().collect(); - let mut v: Vec<_> = s.into_iter().collect(); - v.sort(); - - assert_eq!([E1, E4], &v[..]); -} -- cgit 1.4.1-3-g733a5 From ae5cb5f66d88f75d88eb9d37fc1bf73c169f47c5 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 7 Jul 2025 22:43:59 +0300 Subject: Mention more APIs in `ParseIntError` docs --- library/core/src/num/error.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index a5242d60bf1..f9c4cdd0ebe 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -45,8 +45,11 @@ impl From for TryFromIntError { /// An error which can be returned when parsing an integer. /// -/// This error is used as the error type for the `from_str_radix()` functions -/// on the primitive integer types, such as [`i8::from_str_radix`]. +/// For example, this error is returned by the `from_str_radix()` functions +/// on the primitive integer types (such as [`i8::from_str_radix`]) +/// and is used as the error type in their [`FromStr`] implementations. +/// +/// [`FromStr`]: crate::str::FromStr /// /// # Potential causes /// -- cgit 1.4.1-3-g733a5 From d8273d39978ed16528c9792f9c4a81cc596bf7f8 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Mon, 7 Jul 2025 14:16:41 +0530 Subject: std: sys: net: uefi: tcp4: Add timeout support - Implement timeout support for read, write and connect. - A software implementation using Instant. Signed-off-by: Ayush Singh --- library/std/src/sys/net/connection/uefi/mod.rs | 41 ++++++++++----- library/std/src/sys/net/connection/uefi/tcp.rs | 13 ++--- library/std/src/sys/net/connection/uefi/tcp4.rs | 68 ++++++++++++++++++++++--- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 6835ba44ee2..884cbd4ac1d 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -1,37 +1,54 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; +use crate::sync::{Arc, Mutex}; use crate::sys::unsupported; use crate::time::Duration; mod tcp; pub(crate) mod tcp4; -pub struct TcpStream(tcp::Tcp); +pub struct TcpStream { + inner: tcp::Tcp, + read_timeout: Arc>>, + write_timeout: Arc>>, +} impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result { - tcp::Tcp::connect(addr?).map(Self) + let inner = tcp::Tcp::connect(addr?, None)?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { - unsupported() + pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { + let inner = tcp::Tcp::connect(addr, Some(timeout))?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_read_timeout(&self, t: Option) -> io::Result<()> { + self.read_timeout.set(t).unwrap(); + Ok(()) } - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_write_timeout(&self, t: Option) -> io::Result<()> { + self.write_timeout.set(t).unwrap(); + Ok(()) } pub fn read_timeout(&self) -> io::Result> { - unsupported() + Ok(self.read_timeout.get_cloned().unwrap()) } pub fn write_timeout(&self) -> io::Result> { - unsupported() + Ok(self.write_timeout.get_cloned().unwrap()) } pub fn peek(&self, _: &mut [u8]) -> io::Result { @@ -39,7 +56,7 @@ impl TcpStream { } pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) + self.inner.read(buf, self.read_timeout()?) } pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { @@ -56,7 +73,7 @@ impl TcpStream { } pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) + self.inner.write(buf, self.write_timeout()?) } pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 55b6dbf2490..1152f69446e 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -1,33 +1,34 @@ use super::tcp4; use crate::io; use crate::net::SocketAddr; +use crate::time::Duration; pub(crate) enum Tcp { V4(tcp4::Tcp4), } impl Tcp { - pub(crate) fn connect(addr: &SocketAddr) -> io::Result { + pub(crate) fn connect(addr: &SocketAddr, timeout: Option) -> io::Result { match addr { SocketAddr::V4(x) => { let temp = tcp4::Tcp4::new()?; temp.configure(true, Some(x), None)?; - temp.connect()?; + temp.connect(timeout)?; Ok(Tcp::V4(temp)) } SocketAddr::V6(_) => todo!(), } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.write(buf), + Self::V4(client) => client.write(buf, timeout), } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.read(buf), + Self::V4(client) => client.read(buf, timeout), } } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index af1ba2be47a..6342718929a 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -6,6 +6,7 @@ use crate::net::SocketAddrV4; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::pal::helpers; +use crate::time::{Duration, Instant}; const TYPE_OF_SERVICE: u8 = 8; const TIME_TO_LIVE: u8 = 255; @@ -66,7 +67,7 @@ impl Tcp4 { if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } - pub(crate) fn connect(&self) -> io::Result<()> { + pub(crate) fn connect(&self, timeout: Option) -> io::Result<()> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -79,7 +80,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut conn_token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -88,7 +89,7 @@ impl Tcp4 { } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -119,7 +120,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -128,7 +129,7 @@ impl Tcp4 { } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -158,7 +159,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -167,6 +168,50 @@ impl Tcp4 { } } + /// Wait for an event to finish. This is checked by an atomic boolean that is supposed to be set + /// to true in the event callback. + /// + /// Optionally, allow specifying a timeout. + /// + /// If a timeout is provided, the operation (specified by its `EFI_TCP4_COMPLETION_TOKEN`) is + /// canceled and Error of kind TimedOut is returned. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` + unsafe fn wait_or_cancel( + &self, + timeout: Option, + token: *mut tcp4::CompletionToken, + ) -> io::Result<()> { + if !self.wait_for_flag(timeout) { + let _ = unsafe { self.cancel(token) }; + return Err(io::Error::new(io::ErrorKind::TimedOut, "Operation Timed out")); + } + + Ok(()) + } + + /// Abort an asynchronous connection, listen, transmission or receive request. + /// + /// If token is NULL, then all pending tokens issued by EFI_TCP4_PROTOCOL.Connect(), + /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive() are + /// aborted. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` or NULL + unsafe fn cancel(&self, token: *mut tcp4::CompletionToken) -> io::Result<()> { + let protocol = self.protocol.as_ptr(); + + let r = unsafe { ((*protocol).cancel)(protocol, token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } else { + Ok(()) + } + } + unsafe fn create_evt(&self) -> io::Result { self.flag.store(false, Ordering::Relaxed); helpers::OwnedEvent::new( @@ -177,10 +222,19 @@ impl Tcp4 { ) } - fn wait_for_flag(&self) { + fn wait_for_flag(&self, timeout: Option) -> bool { + let start = Instant::now(); + while !self.flag.load(Ordering::Relaxed) { let _ = self.poll(); + if let Some(t) = timeout { + if Instant::now().duration_since(start) >= t { + return false; + } + } } + + true } fn poll(&self) -> io::Result<()> { -- cgit 1.4.1-3-g733a5 From 425cd0f571b3888be81ebad295af8e3c903fb244 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 14:55:53 -0500 Subject: test: Verify frontmatter unpretty behavior --- tests/ui/unpretty/frontmatter.rs | 10 ++++++++++ tests/ui/unpretty/frontmatter.stdout | 7 +++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/unpretty/frontmatter.rs create mode 100644 tests/ui/unpretty/frontmatter.stdout diff --git a/tests/ui/unpretty/frontmatter.rs b/tests/ui/unpretty/frontmatter.rs new file mode 100644 index 00000000000..1971808e2a8 --- /dev/null +++ b/tests/ui/unpretty/frontmatter.rs @@ -0,0 +1,10 @@ +--- +--- + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() { +} diff --git a/tests/ui/unpretty/frontmatter.stdout b/tests/ui/unpretty/frontmatter.stdout new file mode 100644 index 00000000000..9ad6bbbe577 --- /dev/null +++ b/tests/ui/unpretty/frontmatter.stdout @@ -0,0 +1,7 @@ + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() {} -- cgit 1.4.1-3-g733a5 From 45a1e492b1adfc6f7664d1da736dff147e5c3168 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 16:40:22 -0500 Subject: feat(lexer): Allow including frontmatter with 'tokenize' --- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_lexer/src/lib.rs | 29 ++++++++++++++-------- compiler/rustc_lexer/src/tests.rs | 3 ++- .../clippy_lints/src/undocumented_unsafe_blocks.rs | 4 +-- .../src/utils/format_args_collector.rs | 4 +-- src/tools/clippy/clippy_utils/src/consts.rs | 12 +++------ src/tools/clippy/clippy_utils/src/hir_utils.rs | 4 +-- src/tools/clippy/clippy_utils/src/lib.rs | 6 ++--- src/tools/clippy/clippy_utils/src/source.rs | 7 +++--- .../rust-analyzer/crates/parser/src/lexed_str.rs | 10 +++++--- .../crates/proc-macro-srv/src/server_impl.rs | 2 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 2 +- 12 files changed, 47 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index aff98c63bcb..9d656253f72 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -120,7 +120,7 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec pos += shebang_len; } - for token in rustc_lexer::tokenize(&text[pos..]) { + for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::No) { let token_text = &text[pos..pos + token.len as usize]; match token.kind { rustc_lexer::TokenKind::Whitespace => { diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index e30dbe80248..e80196ed567 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -273,14 +273,15 @@ pub fn strip_shebang(input: &str) -> Option { if let Some(input_tail) = input.strip_prefix("#!") { // Ok, this is a shebang but if the next non-whitespace token is `[`, // then it may be valid Rust code, so consider it Rust code. - let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| { - !matches!( - tok, - TokenKind::Whitespace - | TokenKind::LineComment { doc_style: None } - | TokenKind::BlockComment { doc_style: None, .. } - ) - }); + let next_non_whitespace_token = + tokenize(input_tail, FrontmatterAllowed::No).map(|tok| tok.kind).find(|tok| { + !matches!( + tok, + TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } + ) + }); if next_non_whitespace_token != Some(TokenKind::OpenBracket) { // No other choice than to consider this a shebang. return Some(2 + input_tail.lines().next().unwrap_or_default().len()); @@ -303,8 +304,16 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> } /// Creates an iterator that produces tokens from the input string. -pub fn tokenize(input: &str) -> impl Iterator { - let mut cursor = Cursor::new(input, FrontmatterAllowed::No); +/// +/// When parsing a full Rust document, +/// first [`strip_shebang`] and then allow frontmatters with [`FrontmatterAllowed::Yes`]. +/// +/// When tokenizing a slice of a document, be sure to disallow frontmatters with [`FrontmatterAllowed::No`] +pub fn tokenize( + input: &str, + frontmatter_allowed: FrontmatterAllowed, +) -> impl Iterator { + let mut cursor = Cursor::new(input, frontmatter_allowed); std::iter::from_fn(move || { let token = cursor.advance_token(); if token.kind != TokenKind::Eof { Some(token) } else { None } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index fc8d9b9d57b..a9fcb481759 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -125,7 +125,8 @@ fn test_valid_shebang() { } fn check_lexing(src: &str, expect: Expect) { - let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect(); + let actual: String = + tokenize(src, FrontmatterAllowed::No).map(|token| format!("{:?}\n", token)).collect(); expect.assert_eq(&actual) } diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 6cc4b589a72..8906e654c97 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -9,7 +9,7 @@ use clippy_utils::visitors::{Descend, for_each_expr}; use hir::HirId; use rustc_hir as hir; use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext}; @@ -746,7 +746,7 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos loop { if line.starts_with("/*") { let src = &src[line_start..line_starts.last().unwrap().to_usize()]; - let mut tokens = tokenize(src); + let mut tokens = tokenize(src, FrontmatterAllowed::No); return (src[..tokens.next().unwrap().len as usize] .to_ascii_uppercase() .contains("SAFETY:") diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs index 8f314ce7a60..6629a67f78b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs @@ -3,7 +3,7 @@ use clippy_utils::source::SpanRangeExt; use itertools::Itertools; use rustc_ast::{Crate, Expr, ExprKind, FormatArgs}; use rustc_data_structures::fx::FxHashMap; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, hygiene}; @@ -82,7 +82,7 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool { .all(|sp| { sp.check_source_text(cx, |src| { // text should be either `, name` or `, name =` - let mut iter = tokenize(src).filter(|t| { + let mut iter = tokenize(src, FrontmatterAllowed::No).filter(|t| { !matches!( t.kind, TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index ba0376e4d40..25afa12e95d 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp, }; -use rustc_lexer::tokenize; +use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::{Scalar, alloc_range}; @@ -304,9 +304,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constan match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => { - Constant::Binary(s.as_byte_str().to_vec()) - } + LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(s.as_byte_str().to_vec()), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n.get()), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { @@ -568,9 +566,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { } else { match &lit.node { LitKind::Str(is, _) => Some(is.is_empty()), - LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => { - Some(s.as_byte_str().is_empty()) - } + LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => Some(s.as_byte_str().is_empty()), _ => None, } } @@ -715,7 +711,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { && let Some(src) = src.as_str() { use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; - if !tokenize(src) + if !tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) .eq([OpenBrace]) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 0ca494f16e3..6e8dccbccd5 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -12,7 +12,7 @@ use rustc_hir::{ Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::LateContext; use rustc_middle::ty::TypeckResults; use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym}; @@ -686,7 +686,7 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &' // `{}` => `()` ([], None) if block.span.check_source_text(cx, |src| { - tokenize(src) + tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| { !matches!( diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index c01f0ffaac9..98b4c183b12 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -106,7 +106,7 @@ use rustc_hir::{ Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp, def, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::hir::place::PlaceBase; @@ -2764,7 +2764,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx /// Tokenizes the input while keeping the text associated with each token. pub fn tokenize_with_text(s: &str) -> impl Iterator { let mut pos = 0; - tokenize(s).map(move |t| { + tokenize(s, FrontmatterAllowed::No).map(move |t| { let end = pos + t.len; let range = pos as usize..end as usize; let inner = InnerSpan::new(range.start, range.end); @@ -2779,7 +2779,7 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool { let Ok(snippet) = sm.span_to_snippet(span) else { return false; }; - return tokenize(&snippet).any(|token| { + return tokenize(&snippet, FrontmatterAllowed::No).any(|token| { matches!( token.kind, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. } diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs index 7f2bf99daff..7d21336be1c 100644 --- a/src/tools/clippy/clippy_utils/src/source.rs +++ b/src/tools/clippy/clippy_utils/src/source.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use rustc_ast::{LitKind, StrStyle}; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; -use rustc_lexer::{LiteralKind, TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, LiteralKind, TokenKind, tokenize}; use rustc_lint::{EarlyContext, LateContext}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -277,7 +277,7 @@ fn map_range( } fn ends_with_line_comment_or_broken(text: &str) -> bool { - let Some(last) = tokenize(text).last() else { + let Some(last) = tokenize(text, FrontmatterAllowed::No).last() else { return false; }; match last.kind { @@ -310,7 +310,8 @@ fn with_leading_whitespace_inner(lines: &[RelativeBytePos], src: &str, range: Ra && ends_with_line_comment_or_broken(&start[prev_start..]) && let next_line = lines.partition_point(|&pos| pos.to_usize() < range.end) && let next_start = lines.get(next_line).map_or(src.len(), |&x| x.to_usize()) - && tokenize(src.get(range.end..next_start)?).any(|t| !matches!(t.kind, TokenKind::Whitespace)) + && tokenize(src.get(range.end..next_start)?, FrontmatterAllowed::No) + .any(|t| !matches!(t.kind, TokenKind::Whitespace)) { Some(range.start) } else { diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index e6c92dec681..bff9acd78fa 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -11,8 +11,8 @@ use std::ops; use rustc_literal_escaper::{ - EscapeError, Mode, unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, - unescape_str, + unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, unescape_str, EscapeError, + Mode, }; use crate::{ @@ -44,7 +44,9 @@ impl<'a> LexedStr<'a> { // Re-create the tokenizer from scratch every token because `GuardedStrPrefix` is one token in the lexer // but we want to split it to two in edition <2024. - while let Some(token) = rustc_lexer::tokenize(&text[conv.offset..]).next() { + while let Some(token) = + rustc_lexer::tokenize(&text[conv.offset..], rustc_lexer::FrontmatterAllowed::No).next() + { let token_text = &text[conv.offset..][..token.len as usize]; conv.extend_token(&token.kind, token_text); @@ -58,7 +60,7 @@ impl<'a> LexedStr<'a> { return None; } - let token = rustc_lexer::tokenize(text).next()?; + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next()?; if token.len as usize != text.len() { return None; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index dd576f23ae9..662f6257642 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -121,7 +121,7 @@ pub(super) fn literal_from_str( use proc_macro::bridge::LitKind; use rustc_lexer::{LiteralKind, Token, TokenKind}; - let mut tokens = rustc_lexer::tokenize(s); + let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No); let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); let lit = if minus_or_lit.kind == TokenKind::Minus { diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 14574a6456b..44123385c8c 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -579,7 +579,7 @@ where { use rustc_lexer::LiteralKind; - let token = rustc_lexer::tokenize(text).next_tuple(); + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next_tuple(); let Some((rustc_lexer::Token { kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, .. -- cgit 1.4.1-3-g733a5 From e0f76871eddd0f1345eba7d09e5ab4812f8aa91d Mon Sep 17 00:00:00 2001 From: "LevitatingBusinessMan (Rein Fernhout)" Date: Thu, 12 Jun 2025 02:34:15 +0200 Subject: rust: library: Add setsid method to CommandExt trait Add a setsid method to the CommandExt trait so that callers can create a process in a new session and process group whilst still using the POSIX spawn fast path. Co-Authored-By: Harvey Hunt --- library/std/src/os/unix/process.rs | 8 ++++ library/std/src/sys/process/unix/common.rs | 9 ++++ library/std/src/sys/process/unix/common/tests.rs | 58 ++++++++++++++++++++++++ library/std/src/sys/process/unix/unix.rs | 14 ++++++ 4 files changed, 89 insertions(+) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 57ce3c5a4bf..baa922f75bc 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -210,6 +210,9 @@ pub trait CommandExt: Sealed { /// intentional difference from the underlying `chroot` system call.) #[unstable(feature = "process_chroot", issue = "141298")] fn chroot>(&mut self, dir: P) -> &mut process::Command; + + #[unstable(feature = "process_setsid", issue = "105376")] + fn setsid(&mut self, setsid: bool) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -260,6 +263,11 @@ impl CommandExt for process::Command { self.as_inner_mut().chroot(dir.as_ref()); self } + + fn setsid(&mut self, setsid: bool) -> &mut process::Command { + self.as_inner_mut().setsid(setsid); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index b6777b76668..6219be60caf 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -98,6 +98,7 @@ pub struct Command { #[cfg(target_os = "linux")] create_pidfd: bool, pgroup: Option, + setsid: bool, } // passed back to std::process with the pipes connected to the child, if any @@ -185,6 +186,7 @@ impl Command { #[cfg(target_os = "linux")] create_pidfd: false, pgroup: None, + setsid: false, } } @@ -220,6 +222,9 @@ impl Command { self.cwd(&OsStr::new("/")); } } + pub fn setsid(&mut self, setsid: bool) { + self.setsid = setsid; + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -298,6 +303,10 @@ impl Command { pub fn get_chroot(&self) -> Option<&CStr> { self.chroot.as_deref() } + #[allow(dead_code)] + pub fn get_setsid(&self) -> bool { + self.setsid + } pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/process/unix/common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs index e5c8dd6e341..5f71bf051f8 100644 --- a/library/std/src/sys/process/unix/common/tests.rs +++ b/library/std/src/sys/process/unix/common/tests.rs @@ -134,6 +134,64 @@ fn test_process_group_no_posix_spawn() { } } +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_posix_spawn() { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + unsafe { + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_no_posix_spawn() { + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawn path. + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec rather than posix spawn. + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + #[test] fn test_program_kind() { let vectors = &[ diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 4f595ac9a1c..9162573ba09 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -340,6 +340,10 @@ impl Command { cvt(libc::setpgid(0, pgroup))?; } + if self.get_setsid() { + cvt(libc::setsid())?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -741,6 +745,16 @@ impl Command { flags |= libc::POSIX_SPAWN_SETSIGDEF; } + if self.get_setsid() { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + flags |= libc::POSIX_SPAWN_SETSID; + } else { + return Ok(None); + } + } + } + cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource -- cgit 1.4.1-3-g733a5 From 58d7c2d5a760c1adfa4c3984eeb12787f5ad5b1d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 9 Jul 2025 22:30:15 -0700 Subject: Make UB transmutes really UB in LLVM Ralf suggested in that UB transmutes shouldn't be trapping, which happened for the one path that PR was changing, but there's another path as well, so this PR changes that other path to match. --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 12 +++++------- tests/codegen/intrinsics/transmute.rs | 22 +++++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index cbbb0196890..1e3b76e5f93 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -236,14 +236,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || operand.layout.is_uninhabited() || cast.is_uninhabited() { - if !operand.layout.is_uninhabited() { - // Since this is known statically and the input could have existed - // without already having hit UB, might as well trap for it. - bx.abort(); - } + // We can't use unreachable because that's a terminator, and we + // need something that can be in the middle of a basic block. + bx.assume(bx.cx().const_bool(false)); - // Because this transmute is UB, return something easy to generate, - // since it's fine that later uses of the value are probably UB. + // We still need to return a value of the appropriate type, but + // it's already UB so do the easiest thing available. return OperandValue::poison(bx, cast); } diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index e375724bc1b..36d6a2f722f 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -58,9 +58,9 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { { RET = CastTransmute(x); @@ -88,9 +88,9 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { let temp: BigNever; { @@ -104,6 +104,9 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call // CHECK: ret i16 poison mir! { { @@ -401,9 +404,9 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { pub unsafe fn check_unit_to_never(x: ()) { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { let temp: ZstNever; { @@ -420,6 +423,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. // CHECK: start + // CHECK-NEXT: call void @llvm.assume(i1 false) // CHECK-NEXT: ret void mir! { { -- cgit 1.4.1-3-g733a5 From 3ad95cccf9b3af7e527869a1eb130217971b7a57 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 21:46:28 +0500 Subject: cleaned up some tests --- tests/ui/auto-traits/auto-traits-type-parameter | 36 -------- tests/ui/auto-traits/auto-traits-type-parameter.rs | 37 +++++++++ tests/ui/auxiliary/typeid-intrinsic-aux1.rs | 29 ------- tests/ui/auxiliary/typeid-intrinsic-aux2.rs | 29 ------- tests/ui/consts/const-eval-array-len-in-impl.rs | 4 +- .../ui/consts/const-eval-array-len-in-impl.stderr | 2 +- .../let-binding-tuple-destructuring.rs | 2 + .../lifetimes/any-lifetime-escape-higher-rank.rs | 12 ++- tests/ui/limits/type-length-limit-enforcement.rs | 16 ++-- .../ui/limits/type-length-limit-enforcement.stderr | 4 +- .../macro-fragment-ident-underscore-error.rs | 7 +- .../macro-fragment-ident-underscore-error.stderr | 6 +- .../struct-type-and-function-name-coexistence.rs | 13 ++- .../integer-literal-method-call-underscore.rs | 6 +- tests/ui/ptr_ops/ptr-write-bool-representation.rs | 7 ++ tests/ui/ptr_ops/raw-pointer-type-basic.rs | 15 +++- .../ui/try-trait/try-operator-expansion-hygiene.rs | 16 ++-- .../ui/try-trait/try-operator-various-contexts.rs | 35 ++++---- .../type-inference-none-in-generic-ref.rs | 6 +- .../type-inference-none-in-generic-ref.stderr | 2 +- .../type-inference-unconstrained-none.rs | 2 +- .../type-inference-unconstrained-none.stderr | 2 +- tests/ui/type/auxiliary/typeid-consistency-aux1.rs | 29 +++++++ tests/ui/type/auxiliary/typeid-consistency-aux2.rs | 29 +++++++ tests/ui/type/type-name-basic.rs | 7 +- tests/ui/type/typeid-consistency-comprehensive.rs | 97 ---------------------- tests/ui/type/typeid-consistency.rs | 94 +++++++++++++++++++++ .../basic-underscore-lifetime-elision.rs | 8 +- 28 files changed, 299 insertions(+), 253 deletions(-) delete mode 100644 tests/ui/auto-traits/auto-traits-type-parameter create mode 100644 tests/ui/auto-traits/auto-traits-type-parameter.rs delete mode 100644 tests/ui/auxiliary/typeid-intrinsic-aux1.rs delete mode 100644 tests/ui/auxiliary/typeid-intrinsic-aux2.rs create mode 100644 tests/ui/type/auxiliary/typeid-consistency-aux1.rs create mode 100644 tests/ui/type/auxiliary/typeid-consistency-aux2.rs delete mode 100644 tests/ui/type/typeid-consistency-comprehensive.rs create mode 100644 tests/ui/type/typeid-consistency.rs diff --git a/tests/ui/auto-traits/auto-traits-type-parameter b/tests/ui/auto-traits/auto-traits-type-parameter deleted file mode 100644 index 83d81c0d833..00000000000 --- a/tests/ui/auto-traits/auto-traits-type-parameter +++ /dev/null @@ -1,36 +0,0 @@ -//@ run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] - -fn p_foo(_pinned: T) { } -fn s_foo(_shared: T) { } -fn u_foo(_unique: T) { } - -struct r { - i: isize, -} - -impl Drop for r { - fn drop(&mut self) {} -} - -fn r(i:isize) -> r { - r { - i: i - } -} - -pub fn main() { - p_foo(r(10)); - - p_foo::>(Box::new(r(10))); - p_foo::>(Box::new(10)); - p_foo(10); - - s_foo::>(Box::new(10)); - s_foo(10); - - u_foo::>(Box::new(10)); - u_foo(10); -} diff --git a/tests/ui/auto-traits/auto-traits-type-parameter.rs b/tests/ui/auto-traits/auto-traits-type-parameter.rs new file mode 100644 index 00000000000..0c448f58996 --- /dev/null +++ b/tests/ui/auto-traits/auto-traits-type-parameter.rs @@ -0,0 +1,37 @@ +//! Checks how type parameters interact with auto-traits like `Send` and `Sync` with implicit +//! bounds + +//@ run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + +fn p_foo(_pinned: T) {} +fn s_foo(_shared: T) {} +fn u_foo(_unique: T) {} + +struct r { + i: isize, +} + +impl Drop for r { + fn drop(&mut self) {} +} + +fn r(i: isize) -> r { + r { i } +} + +pub fn main() { + p_foo(r(10)); + + p_foo::>(Box::new(r(10))); + p_foo::>(Box::new(10)); + p_foo(10); + + s_foo::>(Box::new(10)); + s_foo(10); + + u_foo::>(Box::new(10)); + u_foo(10); +} diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux1.rs b/tests/ui/auxiliary/typeid-intrinsic-aux1.rs deleted file mode 100644 index a028008c6ae..00000000000 --- a/tests/ui/auxiliary/typeid-intrinsic-aux1.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::any::{Any, TypeId}; - -pub struct A; -pub struct B(Option); -pub struct C(Option); -pub struct D(Option<&'static str>); -pub struct E(Result<&'static str, isize>); - -pub type F = Option; -pub type G = usize; -pub type H = &'static str; -pub type I = Box; -pub type I32Iterator = dyn Iterator; -pub type U32Iterator = dyn Iterator; - -pub fn id_A() -> TypeId { TypeId::of::() } -pub fn id_B() -> TypeId { TypeId::of::() } -pub fn id_C() -> TypeId { TypeId::of::() } -pub fn id_D() -> TypeId { TypeId::of::() } -pub fn id_E() -> TypeId { TypeId::of::() } -pub fn id_F() -> TypeId { TypeId::of::() } -pub fn id_G() -> TypeId { TypeId::of::() } -pub fn id_H() -> TypeId { TypeId::of::() } -pub fn id_I() -> TypeId { TypeId::of::() } - -pub fn foo() -> TypeId { TypeId::of::() } - -pub fn id_i32_iterator() -> TypeId { TypeId::of::() } -pub fn id_u32_iterator() -> TypeId { TypeId::of::() } diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux2.rs b/tests/ui/auxiliary/typeid-intrinsic-aux2.rs deleted file mode 100644 index a028008c6ae..00000000000 --- a/tests/ui/auxiliary/typeid-intrinsic-aux2.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::any::{Any, TypeId}; - -pub struct A; -pub struct B(Option); -pub struct C(Option); -pub struct D(Option<&'static str>); -pub struct E(Result<&'static str, isize>); - -pub type F = Option; -pub type G = usize; -pub type H = &'static str; -pub type I = Box; -pub type I32Iterator = dyn Iterator; -pub type U32Iterator = dyn Iterator; - -pub fn id_A() -> TypeId { TypeId::of::() } -pub fn id_B() -> TypeId { TypeId::of::() } -pub fn id_C() -> TypeId { TypeId::of::() } -pub fn id_D() -> TypeId { TypeId::of::() } -pub fn id_E() -> TypeId { TypeId::of::() } -pub fn id_F() -> TypeId { TypeId::of::() } -pub fn id_G() -> TypeId { TypeId::of::() } -pub fn id_H() -> TypeId { TypeId::of::() } -pub fn id_I() -> TypeId { TypeId::of::() } - -pub fn foo() -> TypeId { TypeId::of::() } - -pub fn id_i32_iterator() -> TypeId { TypeId::of::() } -pub fn id_u32_iterator() -> TypeId { TypeId::of::() } diff --git a/tests/ui/consts/const-eval-array-len-in-impl.rs b/tests/ui/consts/const-eval-array-len-in-impl.rs index 6c545913dd9..0373274770d 100644 --- a/tests/ui/consts/const-eval-array-len-in-impl.rs +++ b/tests/ui/consts/const-eval-array-len-in-impl.rs @@ -1,4 +1,6 @@ -// https://github.com/rust-lang/rust/issues/49208 +//! This checks that compiler correctly evaluate constant array lengths within trait `impl` headers. +//! +//! Regression test for . trait Foo { fn foo(); diff --git a/tests/ui/consts/const-eval-array-len-in-impl.stderr b/tests/ui/consts/const-eval-array-len-in-impl.stderr index 43cc377006e..faff7aa3ff7 100644 --- a/tests/ui/consts/const-eval-array-len-in-impl.stderr +++ b/tests/ui/consts/const-eval-array-len-in-impl.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied - --> $DIR/unevaluated_fixed_size_array_len.rs:12:6 + --> $DIR/const-eval-array-len-in-impl.rs:14:6 | LL | <[(); 0] as Foo>::foo() | ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` diff --git a/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs index 3d0e79632bb..f62fae86219 100644 --- a/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs +++ b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs @@ -1,3 +1,5 @@ +//! Checks basic multiple variable declaration using tuple destructuring in a `let` binding. + //@ run-pass pub fn main() { diff --git a/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs index 7b0c7b53940..f9f38ee532d 100644 --- a/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs +++ b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs @@ -1,11 +1,15 @@ +//! Checks that `std::any::Any` cannot be used to circumvent lifetime rules +//! with higher-rank types. + //@ run-pass -// Test that we can't ignore lifetimes by going through Any. use std::any::Any; struct Foo<'a>(&'a str); -fn good(s: &String) -> Foo<'_> { Foo(s) } +fn good(s: &String) -> Foo<'_> { + Foo(s) +} fn bad1(s: String) -> Option<&'static str> { let a: Box = Box::new(good as fn(&String) -> Foo); @@ -17,7 +21,9 @@ trait AsStr<'a, 'b> { } impl<'a> AsStr<'a, 'a> for String { - fn get(&'a self) -> &'a str { self } + fn get(&'a self) -> &'a str { + self + } } fn bad2(s: String) -> Option<&'static str> { diff --git a/tests/ui/limits/type-length-limit-enforcement.rs b/tests/ui/limits/type-length-limit-enforcement.rs index 87f5ffd76d7..3b34d6eb5c8 100644 --- a/tests/ui/limits/type-length-limit-enforcement.rs +++ b/tests/ui/limits/type-length-limit-enforcement.rs @@ -1,17 +1,19 @@ -//@ build-fail +//~ ERROR reached the type-length limit + +//! Checks the enforcement of the type-length limit +//! and its configurability via `#![type_length_limit]`. + //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit -//~^^ ERROR reached the type-length limit -// Test that the type length limit can be changed. -// The exact type depends on optimizations, so disable them. +//@ build-fail #![allow(dead_code)] -#![type_length_limit="8"] +#![type_length_limit = "8"] macro_rules! link { ($id:ident, $t:ty) => { pub type $id = ($t, $t, $t); - } + }; } link! { A1, B1 } @@ -26,7 +28,7 @@ link! { D, E } link! { E, F } link! { F, G, Option> } -pub struct G(std::marker::PhantomData::<(T, K)>); +pub struct G(std::marker::PhantomData<(T, K)>); fn main() { drop::>(None); diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index 198d133c08c..516230ae832 100644 --- a/tests/ui/limits/type-length-limit-enforcement.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $DIR/type_length_limit.rs:32:5 + --> $DIR/type-length-limit-enforcement.rs:34:5 | LL | drop::>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.rs b/tests/ui/macros/macro-fragment-ident-underscore-error.rs index 77ec70d43d5..882dd167adc 100644 --- a/tests/ui/macros/macro-fragment-ident-underscore-error.rs +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.rs @@ -1,7 +1,10 @@ +//! Verifies that the reserved underscore `_` cannot be used as an `ident` fragment specifier +//! within a macro pattern, as it leads to a compilation error. + macro_rules! identity { - ($i: ident) => ( + ($i: ident) => { $i - ) + }; } fn main() { diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.stderr b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr index 0c3f980cf6c..929e4624e4b 100644 --- a/tests/ui/macros/macro-fragment-ident-underscore-error.stderr +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr @@ -1,5 +1,5 @@ error: no rules expected reserved identifier `_` - --> $DIR/underscore-ident-matcher.rs:8:19 + --> $DIR/macro-fragment-ident-underscore-error.rs:11:19 | LL | macro_rules! identity { | --------------------- when calling this macro @@ -8,9 +8,9 @@ LL | let identity!(_) = 10; | ^ no rules expected this token in macro call | note: while trying to match meta-variable `$i:ident` - --> $DIR/underscore-ident-matcher.rs:2:6 + --> $DIR/macro-fragment-ident-underscore-error.rs:5:6 | -LL | ($i: ident) => ( +LL | ($i: ident) => { | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs index 31dc684a214..8d5ab3781b5 100644 --- a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs +++ b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs @@ -1,7 +1,14 @@ //@ run-pass -struct A { a: isize } +struct A { + a: isize, +} -fn a(a: A) -> isize { return a.a; } +fn a(a: A) -> isize { + return a.a; +} -pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } +pub fn main() { + let x: A = A { a: 1 }; + assert_eq!(a(x), 1); +} diff --git a/tests/ui/parser/integer-literal-method-call-underscore.rs b/tests/ui/parser/integer-literal-method-call-underscore.rs index d9eb21894e8..9e4abf28cba 100644 --- a/tests/ui/parser/integer-literal-method-call-underscore.rs +++ b/tests/ui/parser/integer-literal-method-call-underscore.rs @@ -1,6 +1,10 @@ +//! Checks that methods with names starting with an underscore (`_`) can be +//! successfully called directly on integer literals, confirming the correct +//! parsing of such expressions where the underscore is part of the method identifier. + //@ run-pass -trait Tr : Sized { +trait Tr: Sized { fn _method_on_numbers(self) {} } diff --git a/tests/ui/ptr_ops/ptr-write-bool-representation.rs b/tests/ui/ptr_ops/ptr-write-bool-representation.rs index 4eb25329223..3dfc3e51ab2 100644 --- a/tests/ui/ptr_ops/ptr-write-bool-representation.rs +++ b/tests/ui/ptr_ops/ptr-write-bool-representation.rs @@ -1,3 +1,10 @@ +//! Validates the correct behavior of writing a `bool` value using `std::ptr::write`. +//! +//! This test addresses historical concerns regarding the internal representation of `bool` +//! (e.g., as `i1` in LLVM versus its byte-aligned memory layout) and checks that +//! `ptr::write` correctly handles this type without issues, confirming its memory +//! behavior is as expected. + //@ run-pass use std::ptr; diff --git a/tests/ui/ptr_ops/raw-pointer-type-basic.rs b/tests/ui/ptr_ops/raw-pointer-type-basic.rs index 5c8ed344ab3..349e8e67909 100644 --- a/tests/ui/ptr_ops/raw-pointer-type-basic.rs +++ b/tests/ui/ptr_ops/raw-pointer-type-basic.rs @@ -1,9 +1,18 @@ +//! Checks the basic usage of raw pointers (`*const isize`) as function argument and return types. + //@ run-pass #![allow(dead_code)] -fn f(a: *const isize) -> *const isize { return a; } +fn f(a: *const isize) -> *const isize { + return a; +} -fn g(a: *const isize) -> *const isize { let b = f(a); return b; } +fn g(a: *const isize) -> *const isize { + let b = f(a); + return b; +} -pub fn main() { return; } +pub fn main() { + return; +} diff --git a/tests/ui/try-trait/try-operator-expansion-hygiene.rs b/tests/ui/try-trait/try-operator-expansion-hygiene.rs index 20538e094c6..b6f4e533d8d 100644 --- a/tests/ui/try-trait/try-operator-expansion-hygiene.rs +++ b/tests/ui/try-trait/try-operator-expansion-hygiene.rs @@ -1,16 +1,14 @@ +//! This test verifies that the `?` operator expansion is hygienic, +//! i.e., it's not affected by other `val` and `err` bindings that may be in scope. +//! +//! Note: Prior to the Try trait stabilization, `expr?` expanded to a match +//! with `val` and `err` bindings. The current implementation uses Try::branch() +//! but this test remains relevant for hygiene verification. + //@ run-pass #![allow(non_upper_case_globals)] #![allow(dead_code)] -// `expr?` expands to: -// -// match expr { -// Ok(val) => val, -// Err(err) => return Err(From::from(err)), -// } -// -// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and -// `err` bindings that may be in scope. use std::num::ParseIntError; diff --git a/tests/ui/try-trait/try-operator-various-contexts.rs b/tests/ui/try-trait/try-operator-various-contexts.rs index b9978204557..41c3679c96f 100644 --- a/tests/ui/try-trait/try-operator-various-contexts.rs +++ b/tests/ui/try-trait/try-operator-various-contexts.rs @@ -1,9 +1,11 @@ +//! Checks the functionality of the `?` operator in various syntactic contexts. + //@ run-pass #![allow(dead_code)] use std::fs::File; -use std::io::{Read, self}; +use std::io::{self, Read}; use std::num::ParseIntError; use std::str::FromStr; @@ -35,7 +37,9 @@ fn on_path() -> Result { fn on_macro() -> Result { macro_rules! id { - ($e:expr) => { $e } + ($e:expr) => { + $e + }; } Ok(id!("7".parse::())?) @@ -50,11 +54,14 @@ fn on_parens() -> Result { fn on_block() -> Result { let x = "9".parse::(); - Ok({x}?) + Ok({ x }?) } fn on_field() -> Result { - struct Pair { a: A, b: B } + struct Pair { + a: A, + b: B, + } let x = Pair { a: "10".parse::(), b: 0 }; @@ -89,7 +96,9 @@ fn on_index() -> Result { } fn on_args() -> Result { - fn sub(x: i32, y: i32) -> i32 { x - y } + fn sub(x: i32, y: i32) -> i32 { + x - y + } let x = "20".parse(); let y = "21".parse(); @@ -98,19 +107,11 @@ fn on_args() -> Result { } fn on_if() -> Result { - Ok(if true { - "22".parse::() - } else { - "23".parse::() - }?) + Ok(if true { "22".parse::() } else { "23".parse::() }?) } fn on_if_let() -> Result { - Ok(if let Ok(..) = "24".parse::() { - "25".parse::() - } else { - "26".parse::() - }?) + Ok(if let Ok(..) = "24".parse::() { "25".parse::() } else { "26".parse::() }?) } fn on_match() -> Result { @@ -121,7 +122,9 @@ fn on_match() -> Result { } fn tight_binding() -> Result { - fn ok(x: T) -> Result { Ok(x) } + fn ok(x: T) -> Result { + Ok(x) + } let x = ok(true); Ok(!x?) diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs index 473ca954b23..9c1b7c19e3d 100644 --- a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs @@ -1,5 +1,7 @@ -struct S<'a, T:'a> { - o: &'a Option +//! Checks that unconstrained `None` is rejected through references and generics + +struct S<'a, T: 'a> { + o: &'a Option, } fn main() { diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr index 72fd0202f4e..d671c189b37 100644 --- a/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:5 + --> $DIR/type-inference-none-in-generic-ref.rs:8:5 | LL | S { o: &None }; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `S` diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.rs b/tests/ui/type-inference/type-inference-unconstrained-none.rs index e180b3163d4..38a506763c7 100644 --- a/tests/ui/type-inference/type-inference-unconstrained-none.rs +++ b/tests/ui/type-inference/type-inference-unconstrained-none.rs @@ -1,4 +1,4 @@ -// Issue #5062 +//! Regression test for . fn main() { None; //~ ERROR type annotations needed [E0282] diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.stderr b/tests/ui/type-inference/type-inference-unconstrained-none.stderr index 4af6f412e5b..80572b845e8 100644 --- a/tests/ui/type-inference/type-inference-unconstrained-none.stderr +++ b/tests/ui/type-inference/type-inference-unconstrained-none.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-none.rs:4:5 + --> $DIR/type-inference-unconstrained-none.rs:4:5 | LL | None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` diff --git a/tests/ui/type/auxiliary/typeid-consistency-aux1.rs b/tests/ui/type/auxiliary/typeid-consistency-aux1.rs new file mode 100644 index 00000000000..a028008c6ae --- /dev/null +++ b/tests/ui/type/auxiliary/typeid-consistency-aux1.rs @@ -0,0 +1,29 @@ +use std::any::{Any, TypeId}; + +pub struct A; +pub struct B(Option); +pub struct C(Option); +pub struct D(Option<&'static str>); +pub struct E(Result<&'static str, isize>); + +pub type F = Option; +pub type G = usize; +pub type H = &'static str; +pub type I = Box; +pub type I32Iterator = dyn Iterator; +pub type U32Iterator = dyn Iterator; + +pub fn id_A() -> TypeId { TypeId::of::() } +pub fn id_B() -> TypeId { TypeId::of::() } +pub fn id_C() -> TypeId { TypeId::of::() } +pub fn id_D() -> TypeId { TypeId::of::() } +pub fn id_E() -> TypeId { TypeId::of::() } +pub fn id_F() -> TypeId { TypeId::of::() } +pub fn id_G() -> TypeId { TypeId::of::() } +pub fn id_H() -> TypeId { TypeId::of::() } +pub fn id_I() -> TypeId { TypeId::of::() } + +pub fn foo() -> TypeId { TypeId::of::() } + +pub fn id_i32_iterator() -> TypeId { TypeId::of::() } +pub fn id_u32_iterator() -> TypeId { TypeId::of::() } diff --git a/tests/ui/type/auxiliary/typeid-consistency-aux2.rs b/tests/ui/type/auxiliary/typeid-consistency-aux2.rs new file mode 100644 index 00000000000..a028008c6ae --- /dev/null +++ b/tests/ui/type/auxiliary/typeid-consistency-aux2.rs @@ -0,0 +1,29 @@ +use std::any::{Any, TypeId}; + +pub struct A; +pub struct B(Option); +pub struct C(Option); +pub struct D(Option<&'static str>); +pub struct E(Result<&'static str, isize>); + +pub type F = Option; +pub type G = usize; +pub type H = &'static str; +pub type I = Box; +pub type I32Iterator = dyn Iterator; +pub type U32Iterator = dyn Iterator; + +pub fn id_A() -> TypeId { TypeId::of::() } +pub fn id_B() -> TypeId { TypeId::of::() } +pub fn id_C() -> TypeId { TypeId::of::() } +pub fn id_D() -> TypeId { TypeId::of::() } +pub fn id_E() -> TypeId { TypeId::of::() } +pub fn id_F() -> TypeId { TypeId::of::() } +pub fn id_G() -> TypeId { TypeId::of::() } +pub fn id_H() -> TypeId { TypeId::of::() } +pub fn id_I() -> TypeId { TypeId::of::() } + +pub fn foo() -> TypeId { TypeId::of::() } + +pub fn id_i32_iterator() -> TypeId { TypeId::of::() } +pub fn id_u32_iterator() -> TypeId { TypeId::of::() } diff --git a/tests/ui/type/type-name-basic.rs b/tests/ui/type/type-name-basic.rs index 068a42606c2..9381cb82578 100644 --- a/tests/ui/type/type-name-basic.rs +++ b/tests/ui/type/type-name-basic.rs @@ -1,3 +1,6 @@ +//! Checks the basic functionality of `std::any::type_name` for primitive types +//! and simple generic structs. + //@ run-pass #![allow(dead_code)] @@ -5,10 +8,10 @@ use std::any::type_name; struct Foo { - x: T + x: T, } pub fn main() { assert_eq!(type_name::(), "isize"); - assert_eq!(type_name::>(), "tydesc_name::Foo"); + assert_eq!(type_name::>(), "type_name_basic::Foo"); } diff --git a/tests/ui/type/typeid-consistency-comprehensive.rs b/tests/ui/type/typeid-consistency-comprehensive.rs deleted file mode 100644 index 7c4fb3f95a9..00000000000 --- a/tests/ui/type/typeid-consistency-comprehensive.rs +++ /dev/null @@ -1,97 +0,0 @@ -//@ run-pass - -#![allow(deprecated)] -//@ aux-build:typeid-intrinsic-aux1.rs -//@ aux-build:typeid-intrinsic-aux2.rs - -#![feature(core_intrinsics)] - -extern crate typeid_intrinsic_aux1 as other1; -extern crate typeid_intrinsic_aux2 as other2; - -use std::hash::{SipHasher, Hasher, Hash}; -use std::any::TypeId; - -struct A; -struct Test; - -pub fn main() { - assert_eq!(TypeId::of::(), other1::id_A()); - assert_eq!(TypeId::of::(), other1::id_B()); - assert_eq!(TypeId::of::(), other1::id_C()); - assert_eq!(TypeId::of::(), other1::id_D()); - assert_eq!(TypeId::of::(), other1::id_E()); - assert_eq!(TypeId::of::(), other1::id_F()); - assert_eq!(TypeId::of::(), other1::id_G()); - assert_eq!(TypeId::of::(), other1::id_H()); - assert_eq!(TypeId::of::(), other1::id_I()); - - assert_eq!(TypeId::of::(), other2::id_A()); - assert_eq!(TypeId::of::(), other2::id_B()); - assert_eq!(TypeId::of::(), other2::id_C()); - assert_eq!(TypeId::of::(), other2::id_D()); - assert_eq!(TypeId::of::(), other2::id_E()); - assert_eq!(TypeId::of::(), other2::id_F()); - assert_eq!(TypeId::of::(), other2::id_G()); - assert_eq!(TypeId::of::(), other2::id_H()); - assert_eq!(TypeId::of::(), other2::id_I()); - - assert_eq!(other1::id_F(), other2::id_F()); - assert_eq!(other1::id_G(), other2::id_G()); - assert_eq!(other1::id_H(), other2::id_H()); - assert_eq!(other1::id_I(), other2::id_I()); - - assert_eq!(TypeId::of::(), other2::foo::()); - assert_eq!(TypeId::of::(), other1::foo::()); - assert_eq!(other2::foo::(), other1::foo::()); - assert_eq!(TypeId::of::(), other2::foo::()); - assert_eq!(TypeId::of::(), other1::foo::()); - assert_eq!(other2::foo::(), other1::foo::()); - - // sanity test of TypeId - let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); - let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); - - assert!(a != b); - assert!(a != c); - assert!(b != c); - - assert_eq!(a, d); - assert_eq!(b, e); - assert_eq!(c, f); - - // check it has a hash - let (a, b) = (TypeId::of::(), TypeId::of::()); - - let mut s1 = SipHasher::new(); - a.hash(&mut s1); - let mut s2 = SipHasher::new(); - b.hash(&mut s2); - - assert_eq!(s1.finish(), s2.finish()); - - // Check projections - - assert_eq!(TypeId::of::(), other1::id_i32_iterator()); - assert_eq!(TypeId::of::(), other1::id_u32_iterator()); - assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); - assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); - assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); - assert_ne!(TypeId::of::(), TypeId::of::()); - - // Check fn pointer against collisions - assert_ne!( - TypeId::of:: A) -> A>(), - TypeId::of:: A, A) -> A>() - ); - assert_ne!( - TypeId::of:: fn(&'a i32) -> &'a i32>(), - TypeId::of:: fn(&'a i32) -> &'static i32>() - ); - assert_ne!( - TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), - TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() - ); -} diff --git a/tests/ui/type/typeid-consistency.rs b/tests/ui/type/typeid-consistency.rs new file mode 100644 index 00000000000..67ee1b6d839 --- /dev/null +++ b/tests/ui/type/typeid-consistency.rs @@ -0,0 +1,94 @@ +//! Checks the correctness and consistency of `std::any::TypeId::of`. + +//@ run-pass + +#![allow(deprecated)] +#![feature(core_intrinsics)] + +//@ aux-build:typeid-consistency-aux1.rs +//@ aux-build:typeid-consistency-aux2.rs + +extern crate typeid_consistency_aux1 as other1; +extern crate typeid_consistency_aux2 as other2; + +use std::any::TypeId; +use std::hash::{Hash, Hasher, SipHasher}; + +struct A; +struct Test; + +pub fn main() { + assert_eq!(TypeId::of::(), other1::id_A()); + assert_eq!(TypeId::of::(), other1::id_B()); + assert_eq!(TypeId::of::(), other1::id_C()); + assert_eq!(TypeId::of::(), other1::id_D()); + assert_eq!(TypeId::of::(), other1::id_E()); + assert_eq!(TypeId::of::(), other1::id_F()); + assert_eq!(TypeId::of::(), other1::id_G()); + assert_eq!(TypeId::of::(), other1::id_H()); + assert_eq!(TypeId::of::(), other1::id_I()); + + assert_eq!(TypeId::of::(), other2::id_A()); + assert_eq!(TypeId::of::(), other2::id_B()); + assert_eq!(TypeId::of::(), other2::id_C()); + assert_eq!(TypeId::of::(), other2::id_D()); + assert_eq!(TypeId::of::(), other2::id_E()); + assert_eq!(TypeId::of::(), other2::id_F()); + assert_eq!(TypeId::of::(), other2::id_G()); + assert_eq!(TypeId::of::(), other2::id_H()); + assert_eq!(TypeId::of::(), other2::id_I()); + + assert_eq!(other1::id_F(), other2::id_F()); + assert_eq!(other1::id_G(), other2::id_G()); + assert_eq!(other1::id_H(), other2::id_H()); + assert_eq!(other1::id_I(), other2::id_I()); + + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + + // sanity test of TypeId + let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), TypeId::of::()); + + assert!(a != b); + assert!(a != c); + assert!(b != c); + + assert_eq!(a, d); + assert_eq!(b, e); + assert_eq!(c, f); + + // check it has a hash + let (a, b) = (TypeId::of::(), TypeId::of::()); + + let mut s1 = SipHasher::new(); + a.hash(&mut s1); + let mut s2 = SipHasher::new(); + b.hash(&mut s2); + + assert_eq!(s1.finish(), s2.finish()); + + // Check projections + + assert_eq!(TypeId::of::(), other1::id_i32_iterator()); + assert_eq!(TypeId::of::(), other1::id_u32_iterator()); + assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); + assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); + assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); + assert_ne!(TypeId::of::(), TypeId::of::()); + + // Check fn pointer against collisions + assert_ne!(TypeId::of:: A) -> A>(), TypeId::of:: A, A) -> A>()); + assert_ne!( + TypeId::of:: fn(&'a i32) -> &'a i32>(), + TypeId::of:: fn(&'a i32) -> &'static i32>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), + TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() + ); +} diff --git a/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs index a372851f9cf..a2e3c8e26d4 100644 --- a/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs +++ b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs @@ -1,6 +1,9 @@ +//! Checks the correct usage and behavior of the anonymous lifetime `'_` (underscore lifetime) + //@ run-pass #![allow(dead_code, mismatched_lifetime_syntaxes)] + struct Foo<'a>(&'a u8); fn foo(x: &u8) -> Foo<'_> { @@ -31,8 +34,5 @@ fn main() { let _ = foo2(x); let _ = foo3(x); foo4(Foo(x)); - let _ = foo5(Foo2 { - a: x, - b: &6, - }); + let _ = foo5(Foo2 { a: x, b: &6 }); } -- cgit 1.4.1-3-g733a5 From 259512e3b6a920b1e1eb6034fbc738e7b9815337 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 23:37:49 +0500 Subject: cleaned up some tests --- tests/ui/allocator/weak-uninhabited-type.rs | 8 +++- .../underscore-prefixed-function-argument.rs | 12 +++--- .../ownership-struct-update-moved-error.rs | 16 ++++---- .../ownership-struct-update-moved-error.stderr | 12 +++--- tests/ui/closures/no-capture-closure-call.rs | 2 + .../box-drop-unused-value-statement-regression.rs | 14 +++---- tests/ui/hashmap/hashset-enum-variant.rs | 13 +++--- tests/ui/io-checks/write-macro-error.rs | 13 ++++-- .../lang-item-unknown-definition-error.rs | 4 +- .../lang-item-unknown-definition-error.stderr | 2 +- tests/ui/modules/module-qualified-paths-basic.rs | 15 +++++-- tests/ui/modules/module-use-nested-groups.rs | 2 + .../primitive-type-module-deprecated-paths.rs | 7 ++-- .../ui/modules/use-keyword-reexport-type-alias.rs | 10 +++-- .../unary-negation-unsigned-integer-error.rs | 2 + .../unary-negation-unsigned-integer-error.stderr | 6 +-- tests/ui/panics/unwind-force-no-unwind-tables.rs | 15 +++++-- tests/ui/process/process-spawn-failure.rs | 47 ++++++++++++++-------- tests/ui/process/windows-exit-code-still-active.rs | 24 +++++------ .../diverging-expressions-unreachable-code.rs | 20 ++++----- .../unreachable-code-diverging-expressions.rs | 10 +++-- tests/ui/traits/virtual-call-parameter-handling.rs | 6 ++- tests/ui/type/unit-type-basic-usages.rs | 18 ++++----- tests/ui/type/usize-no-generic-arguments.rs | 2 + tests/ui/type/usize-no-generic-arguments.stderr | 2 +- tests/ui/unsafe/maybe-uninit-zero-sized-types.rs | 7 +++- 26 files changed, 177 insertions(+), 112 deletions(-) diff --git a/tests/ui/allocator/weak-uninhabited-type.rs b/tests/ui/allocator/weak-uninhabited-type.rs index ce7d5786b41..74258eedc6a 100644 --- a/tests/ui/allocator/weak-uninhabited-type.rs +++ b/tests/ui/allocator/weak-uninhabited-type.rs @@ -1,7 +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 + //@ run-pass +enum Void {} + fn main() { - enum Void {} let _ = std::rc::Weak::::new(); let _ = std::sync::Weak::::new(); } diff --git a/tests/ui/binding/underscore-prefixed-function-argument.rs b/tests/ui/binding/underscore-prefixed-function-argument.rs index 2014e0d23d8..e5b2ec1b5f0 100644 --- a/tests/ui/binding/underscore-prefixed-function-argument.rs +++ b/tests/ui/binding/underscore-prefixed-function-argument.rs @@ -1,11 +1,13 @@ -//@ run-pass +//! Test that argument names starting with `_` are usable. -fn good(_a: &isize) { -} +//@ run-pass -// unnamed argument &isize is now parse x: &isize +fn good(_a: &isize) {} -fn called(_f: F) where F: FnOnce(&isize) { +fn called(_f: F) +where + F: FnOnce(&isize), +{ } pub fn main() { diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.rs b/tests/ui/borrowck/ownership-struct-update-moved-error.rs index ee1a77eb9a4..62fc1f42969 100644 --- a/tests/ui/borrowck/ownership-struct-update-moved-error.rs +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.rs @@ -1,17 +1,19 @@ -struct Mine{ +//! Checks borrow after move error when using `self` consuming method with struct update syntax. + +struct Mine { test: String, - other_val: isize + other_val: isize, } -impl Mine{ - fn make_string_bar(mut self) -> Mine{ +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()}; +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` } diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr index 34b501f8ec8..83cfc7bb412 100644 --- a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr @@ -1,17 +1,17 @@ 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 -LL | let end = Mine{other_val:1, ..start.make_string_bar()}; - | ----------------- `start` moved due to this method call +LL | let end = Mine { other_val: 1, ..start.make_string_bar() }; + | ----------------- `start` moved due to this method call LL | println!("{}", start.test); | ^^^^^^^^^^ value borrowed here after move | 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) diff --git a/tests/ui/closures/no-capture-closure-call.rs b/tests/ui/closures/no-capture-closure-call.rs index 5f42bcbe280..29e5ac635b4 100644 --- a/tests/ui/closures/no-capture-closure-call.rs +++ b/tests/ui/closures/no-capture-closure-call.rs @@ -1,3 +1,5 @@ +//! Sanity check for no capture closures + //@ run-pass pub fn main() { diff --git a/tests/ui/drop/box-drop-unused-value-statement-regression.rs b/tests/ui/drop/box-drop-unused-value-statement-regression.rs index 3d5eff2c48d..43865e08444 100644 --- a/tests/ui/drop/box-drop-unused-value-statement-regression.rs +++ b/tests/ui/drop/box-drop-unused-value-statement-regression.rs @@ -1,12 +1,12 @@ -//@ run-pass -// Issue #3878 -// Issue Name: Unused move causes a crash -// Abstract: zero-fill to block after drop - +//! 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 . -#![allow(path_statements)] +//@ run-pass pub fn main() { let y: Box<_> = Box::new(1); - y; + drop(y); } diff --git a/tests/ui/hashmap/hashset-enum-variant.rs b/tests/ui/hashmap/hashset-enum-variant.rs index 5795cc527cf..39a59d3a39b 100644 --- a/tests/ui/hashmap/hashset-enum-variant.rs +++ b/tests/ui/hashmap/hashset-enum-variant.rs @@ -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 + //@ run-pass -// -#![allow(dead_code)] //@ compile-flags: -O +#![allow(dead_code)] + use std::collections::HashSet; #[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] enum MyEnum { E0, - E1, - E2, E3, E4, - E5, E6, E7, } - fn main() { use MyEnum::*; let s: HashSet<_> = [E4, E1].iter().cloned().collect(); diff --git a/tests/ui/io-checks/write-macro-error.rs b/tests/ui/io-checks/write-macro-error.rs index b48fa3f11cc..857ea0024e1 100644 --- a/tests/ui/io-checks/write-macro-error.rs +++ b/tests/ui/io-checks/write-macro-error.rs @@ -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 //@ needs-unwind @@ -24,7 +27,9 @@ impl Write for ErrorWriter { Err(Error::new(WRITER_ERROR, "not connected")) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } fn main() { @@ -37,7 +42,8 @@ fn main() { let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); // 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(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); } diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.rs b/tests/ui/lang-items/lang-item-unknown-definition-error.rs index ce206d20358..22812128c2d 100644 --- a/tests/ui/lang-items/lang-item-unknown-definition-error.rs +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.rs @@ -1,9 +1,11 @@ +//! 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` + //~^^ ERROR definition of an unknown lang item: `foo` loop {} } diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.stderr b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr index 832f1342418..3b939757ac2 100644 --- a/tests/ui/lang-items/lang-item-unknown-definition-error.stderr +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr @@ -1,5 +1,5 @@ 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"] | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` diff --git a/tests/ui/modules/module-qualified-paths-basic.rs b/tests/ui/modules/module-qualified-paths-basic.rs index d948ffc1520..c02f6060caa 100644 --- a/tests/ui/modules/module-qualified-paths-basic.rs +++ b/tests/ui/modules/module-qualified-paths-basic.rs @@ -1,11 +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; } + pub fn x() -> isize { + return 1; + } } mod bar { - pub fn y() -> isize { return 1; } + pub fn y() -> isize { + return 1; + } } -pub fn main() { foo::x(); bar::y(); } +pub fn main() { + foo::x(); + bar::y(); +} diff --git a/tests/ui/modules/module-use-nested-groups.rs b/tests/ui/modules/module-use-nested-groups.rs index c5d66a86935..84d1f9141a8 100644 --- a/tests/ui/modules/module-use-nested-groups.rs +++ b/tests/ui/modules/module-use-nested-groups.rs @@ -1,3 +1,5 @@ +//! Checks complex `use` syntax and availability of types across nested modules. + //@ run-pass mod a { diff --git a/tests/ui/modules/primitive-type-module-deprecated-paths.rs b/tests/ui/modules/primitive-type-module-deprecated-paths.rs index 6e8c7053c57..5c9d2a616b3 100644 --- a/tests/ui/modules/primitive-type-module-deprecated-paths.rs +++ b/tests/ui/modules/primitive-type-module-deprecated-paths.rs @@ -1,9 +1,10 @@ +//! 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 -// 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}; +use std::{f32, u16}; fn main() { let _ = u16::MAX; diff --git a/tests/ui/modules/use-keyword-reexport-type-alias.rs b/tests/ui/modules/use-keyword-reexport-type-alias.rs index 4f3d1ee500d..c62bd9687ae 100644 --- a/tests/ui/modules/use-keyword-reexport-type-alias.rs +++ b/tests/ui/modules/use-keyword-reexport-type-alias.rs @@ -1,18 +1,20 @@ +//! Checks module re-exports, aliasing with `pub use`, +//! and calling private methods via `Self` in an impl block. + //@ run-pass #![allow(unused_variables)] pub struct A; mod test { - pub use super :: A; - - pub use self :: A as B; + pub use self::A as B; + pub use super::A; } impl A { fn f() {} fn g() { - Self :: f() + Self::f() } } diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs index 943c7f79742..4325c8b111b 100644 --- a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs @@ -1,3 +1,5 @@ +//! This test ensures that the unary negation operator (`-`) cannot be applied to unsigned ints + fn main() { let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr index 0bedbc1accd..4ce870ded9f 100644 --- a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr @@ -1,5 +1,5 @@ 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; | ^^ cannot apply unary operator `-` @@ -12,7 +12,7 @@ LL + let x = usize::MAX; | 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; | ^^^^ cannot apply unary operator `-` @@ -25,7 +25,7 @@ LL + let x = usize::MAX; | 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; | ^^ cannot apply unary operator `-` diff --git a/tests/ui/panics/unwind-force-no-unwind-tables.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs index fb8082e3188..2226e4dd03e 100644 --- a/tests/ui/panics/unwind-force-no-unwind-tables.rs +++ b/tests/ui/panics/unwind-force-no-unwind-tables.rs @@ -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 //@ needs-unwind //@ ignore-windows target requires uwtable @@ -26,9 +30,12 @@ fn increase(count: &mut u8) { fn main() { let mut count = 0; - assert!(panic::catch_unwind(AssertUnwindSafe( - #[inline(never)] - || increase(&mut count) - )).is_err()); + assert!( + panic::catch_unwind(AssertUnwindSafe( + #[inline(never)] + || increase(&mut count) + )) + .is_err() + ); assert_eq!(count, 1); } diff --git a/tests/ui/process/process-spawn-failure.rs b/tests/ui/process/process-spawn-failure.rs index 4a7f2bee9d9..0950b044c97 100644 --- a/tests/ui/process/process-spawn-failure.rs +++ b/tests/ui/process/process-spawn-failure.rs @@ -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 //@ needs-subprocess //@ ignore-vxworks no 'ps' @@ -36,35 +42,42 @@ fn find_zombies() { // the PPID column contains a "-" for the respective process. // Filter out any lines that have a "-" as the PPID as the PPID is // expected to be an integer. - let filtered_ps: Vec<_> = ps_output - .lines() - .filter(|line| line.split_whitespace().nth(1) != Some("-")) - .collect(); + let filtered_ps: Vec<_> = + ps_output.lines().filter(|line| line.split_whitespace().nth(1) != Some("-")).collect(); for (line_no, line) in filtered_ps.into_iter().enumerate() { - if 0 < line_no && 0 < line.len() && - my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1) - .expect("1st column should be PPID") - .parse().ok() - .expect("PPID string into integer") && - line.contains("defunct") { + if 0 < line_no + && 0 < line.len() + && my_pid + == line + .split(' ') + .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); } } } #[cfg(windows)] -fn find_zombies() { } +fn find_zombies() {} fn main() { let too_long = format!("/NoSuchCommand{:0300}", 0u8); - let _failures = (0..100).map(|_| { - let mut cmd = Command::new(&too_long); - let failed = cmd.spawn(); - assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); - failed - }).collect::>(); + let _failures = (0..100) + .map(|_| { + let mut cmd = Command::new(&too_long); + let failed = cmd.spawn(); + assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); + failed + }) + .collect::>(); find_zombies(); // then _failures goes out of scope diff --git a/tests/ui/process/windows-exit-code-still-active.rs b/tests/ui/process/windows-exit-code-still-active.rs index e016343f8ba..e661a4f6adc 100644 --- a/tests/ui/process/windows-exit-code-still-active.rs +++ b/tests/ui/process/windows-exit-code-still-active.rs @@ -1,23 +1,21 @@ +//! 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 -// 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; + use std::process::{self, Command}; if env::args().len() == 1 { - let status = Command::new(env::current_exe().unwrap()) - .arg("foo") - .status() - .unwrap(); + let status = Command::new(env::current_exe().unwrap()).arg("foo").status().unwrap(); assert_eq!(status.code(), Some(259)); } else { process::exit(259); diff --git a/tests/ui/reachable/diverging-expressions-unreachable-code.rs b/tests/ui/reachable/diverging-expressions-unreachable-code.rs index 9c5f7c8f451..bb56987775f 100644 --- a/tests/ui/reachable/diverging-expressions-unreachable-code.rs +++ b/tests/ui/reachable/diverging-expressions-unreachable-code.rs @@ -3,17 +3,17 @@ #![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 _id(x: bool) -> bool { + x } -fn call_id_3() { id(return) && id(return); } +fn _call_id() { + let _c = panic!(); + _id(_c); +} -pub fn main() { +fn _call_id_3() { + _id(return) && _id(return); } + +pub fn main() {} diff --git a/tests/ui/reachable/unreachable-code-diverging-expressions.rs b/tests/ui/reachable/unreachable-code-diverging-expressions.rs index 0c46a38d73f..00676418002 100644 --- a/tests/ui/reachable/unreachable-code-diverging-expressions.rs +++ b/tests/ui/reachable/unreachable-code-diverging-expressions.rs @@ -26,9 +26,13 @@ fn call_id_3() { fn ret_guard() { match 2 { - x if (return) => { x; } - x if let true = return => { x; } - _ => {} + x if (return) => { + x; + } + x if let true = return => { + x; + } + _ => {} } } diff --git a/tests/ui/traits/virtual-call-parameter-handling.rs b/tests/ui/traits/virtual-call-parameter-handling.rs index e80bd5768a4..71ed459d15a 100644 --- a/tests/ui/traits/virtual-call-parameter-handling.rs +++ b/tests/ui/traits/virtual-call-parameter-handling.rs @@ -1,5 +1,7 @@ -//! Regression test for https://github.com/rust-lang/rust/issues/137646. -//! The parameter value at all calls to `check` should be `(1, 1, 1)`. +//! This test checks the correct parameter handling during virtual method calls +//! through a `dyn Trait` object. +//! +//! Regression test for: //@ run-pass diff --git a/tests/ui/type/unit-type-basic-usages.rs b/tests/ui/type/unit-type-basic-usages.rs index 04404fc3f5e..c3ee8067f59 100644 --- a/tests/ui/type/unit-type-basic-usages.rs +++ b/tests/ui/type/unit-type-basic-usages.rs @@ -1,16 +1,14 @@ -//@ run-pass - -#![allow(unused_assignments)] -#![allow(unknown_lints)] +//! Checks the basic usage of unit type -#![allow(unused_variables)] -#![allow(dead_assignment)] +//@ run-pass -fn f(u: ()) { return u; } +fn f(u: ()) { + u +} pub fn main() { let u1: () = (); - let mut u2: () = f(u1); - u2 = (); - return (); + let mut _u2: () = f(u1); + _u2 = (); + () } diff --git a/tests/ui/type/usize-no-generic-arguments.rs b/tests/ui/type/usize-no-generic-arguments.rs index 4ab80d944a5..d4d1eea757c 100644 --- a/tests/ui/type/usize-no-generic-arguments.rs +++ b/tests/ui/type/usize-no-generic-arguments.rs @@ -1,3 +1,5 @@ +//! Sanity test that primitives cannot have const generics. + fn foo() { let x: usize; //~ ERROR const arguments are not allowed on builtin type `usize` } diff --git a/tests/ui/type/usize-no-generic-arguments.stderr b/tests/ui/type/usize-no-generic-arguments.stderr index 9c081a287ed..f1f3456461f 100644 --- a/tests/ui/type/usize-no-generic-arguments.stderr +++ b/tests/ui/type/usize-no-generic-arguments.stderr @@ -1,5 +1,5 @@ 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; | ----- ^^^ const argument not allowed diff --git a/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs index 82474d873b7..e587ca554fe 100644 --- a/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs +++ b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs @@ -1,6 +1,9 @@ -//@ build-pass -// Test the uninit() construct returning various empty types. +//! This test checks that ZSTs can be safely initialized from +//! `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; -- cgit 1.4.1-3-g733a5 From 61b172a34c94108d013a2d352901b4a5a06ad9ee Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 8 Jul 2025 18:10:58 -0600 Subject: test: Make one multi suggestion test unicode --- tests/ui/suggestions/multi-suggestion.ascii.stderr | 130 +++++++++++++++++++++ tests/ui/suggestions/multi-suggestion.rs | 22 ++++ .../ui/suggestions/multi-suggestion.unicode.stderr | 130 +++++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 tests/ui/suggestions/multi-suggestion.ascii.stderr create mode 100644 tests/ui/suggestions/multi-suggestion.rs create mode 100644 tests/ui/suggestions/multi-suggestion.unicode.stderr diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr new file mode 100644 index 00000000000..b6c7b9ed6df --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + --> $DIR/multi-suggestion.rs:17:13 + | +LL | let _ = std::collections::HashMap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + | + = note: `std::collections::HashMap` defined here + | +help: you might have meant to use an associated function to build this type + | +LL | let _ = std::collections::HashMap::new(); + | +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL | let _ = ::default(); + | + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/multi-suggestion.rs:11:19 + | +LL | wtf: Some(Box(U { + | ^^^ + | +note: constructor is not visible here due to private fields + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: private field + | + = note: private field +help: you might have meant to use an associated function to build this type + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + | + and 12 other candidates +help: consider using the `Default` trait + | +LL - wtf: Some(Box(U { +LL + wtf: Some(::default()), + | + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:19:13 + | +LL | let _ = std::collections::HashMap {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = ::default(); + | + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:21:13 + | +LL | let _ = Box {}; + | ^^^ + | + = note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = Box {}; +LL + let _ = Box::new(_); + | +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + | + and 12 other candidates +help: consider using the `Default` trait + | +LL - let _ = Box {}; +LL + let _ = ::default(); + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/suggestions/multi-suggestion.rs b/tests/ui/suggestions/multi-suggestion.rs new file mode 100644 index 00000000000..99d2407aa21 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.rs @@ -0,0 +1,22 @@ +//@ revisions: ascii unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode + +#![allow(dead_code)] +struct U { + wtf: Option>>, + x: T, +} +fn main() { + U { + wtf: Some(Box(U { //[ascii]~ ERROR cannot initialize a tuple struct which contains private fields + wtf: None, + x: (), + })), + x: () + }; + let _ = std::collections::HashMap(); + //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + let _ = std::collections::HashMap {}; + //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields +} diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr new file mode 100644 index 00000000000..e0933606de0 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + ╭▸ $DIR/multi-suggestion.rs:17:13 + │ +LL │ let _ = std::collections::HashMap(); + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ╭▸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + │ + ╰ note: `std::collections::HashMap` defined here + ╰╴ +help: you might have meant to use an associated function to build this type + ╭╴ +LL │ let _ = std::collections::HashMap::new(); + ├╴ +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL │ let _ = ::default(); + ╰╴ + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + ╭▸ $DIR/multi-suggestion.rs:11:19 + │ +LL │ wtf: Some(Box(U { + │ ━━━ + ╰╴ +note: constructor is not visible here due to private fields + ╭▸ $SRC_DIR/alloc/src/boxed.rs:LL:COL + │ + ╰ note: private field + │ + ╰ note: private field +help: you might have meant to use an associated function to build this type + ╭╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + ╰╴ + and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - wtf: Some(Box(U { +LL + wtf: Some(::default()), + ╰╴ + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:19:13 + │ +LL │ let _ = std::collections::HashMap {}; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = ::default(); + ╰╴ + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:21:13 + │ +LL │ let _ = Box {}; + │ ━━━ + │ + ╰ note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = Box {}; +LL + let _ = Box::new(_); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + ╰╴ + and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - let _ = Box {}; +LL + let _ = ::default(); + ╰╴ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. -- cgit 1.4.1-3-g733a5 From d67bf6095a9a3f278a223a20b316c235360c1c90 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 1 Jul 2025 19:09:45 -0600 Subject: chore: Improve how the other suggestions message gets rendered --- compiler/rustc_errors/src/emitter.rs | 9 +++++++-- .../associated-types-in-ambiguous-context.stderr | 2 +- tests/ui/const-generics/issues/issue-82956.stderr | 2 +- .../ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr | 4 ++-- tests/ui/impl-trait/call_method_without_import.no_import.stderr | 2 +- tests/ui/imports/issue-56125.stderr | 2 +- tests/ui/lint/use_suggestion_json.stderr | 2 +- tests/ui/privacy/suggest-box-new.stderr | 4 ++-- tests/ui/rust-2018/issue-52202-use-suggestions.stderr | 2 +- tests/ui/suggestions/multi-suggestion.ascii.stderr | 4 ++-- tests/ui/suggestions/multi-suggestion.unicode.stderr | 8 ++++---- tests/ui/suggestions/too-many-field-suggestions.stderr | 4 ++-- 12 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2f398cea926..1b581f93736 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2446,17 +2446,22 @@ impl HumanEmitter { | DisplaySuggestion::Underline => row_num - 1, DisplaySuggestion::None => row_num, }; - self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + if other_suggestions > 0 { + self.draw_col_separator_no_space(&mut buffer, row, max_line_num_len + 1); + } else { + self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + } row_num = row + 1; } } if other_suggestions > 0 { + self.draw_note_separator(&mut buffer, row_num, max_line_num_len + 1, false); let msg = format!( "and {} other candidate{}", other_suggestions, pluralize!(other_suggestions) ); - buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle); + buffer.append(row_num, &msg, Style::NoStyle); } emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index a7647cf26aa..71a1360cb5a 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -42,7 +42,7 @@ LL + type X = ::Target; LL - type X = std::ops::Deref::Target; LL + type X = as Deref>::Target; | - and N other candidates + = and N other candidates error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:13:23 diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index 5e380eea81c..fd93e5122a5 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -14,7 +14,7 @@ LL + use std::collections::btree_map::IntoIter; | LL + use std::collections::btree_set::IntoIter; | - and 9 other candidates + = and 9 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index 927f9e842e6..12965800a02 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -18,7 +18,7 @@ LL + fn setup() -> Determine { Set } LL - fn setup() -> Set { Set } LL + fn setup() -> PutDown { Set } | - and 3 other candidates + = and 3 other candidates error[E0425]: cannot find value `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 @@ -36,7 +36,7 @@ LL + use Determine::Set; | LL + use PutDown::Set; | - and 3 other candidates + = and 3 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr index 72982b695bb..e59409ea27e 100644 --- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -30,7 +30,7 @@ LL + use std::fmt::Display; | LL + use std::fmt::LowerExp; | - and 5 other candidates + = and 5 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-56125.stderr b/tests/ui/imports/issue-56125.stderr index 81336d51df4..371130facf9 100644 --- a/tests/ui/imports/issue-56125.stderr +++ b/tests/ui/imports/issue-56125.stderr @@ -18,7 +18,7 @@ LL + use ::issue_56125::issue_56125; LL - use empty::issue_56125; LL + use ::issue_56125::last_segment::issue_56125; | - and 1 other candidate + = and 1 other candidate error[E0659]: `issue_56125` is ambiguous --> $DIR/issue-56125.rs:6:9 diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 0d4304e2e2e..558c2260fce 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -419,7 +419,7 @@ mod foo { \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::hash_map::Iter;\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m and 9 other candidates\u001b[0m +\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0mand 9 other candidates\u001b[0m " } diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index b651348de29..6c47b52c9de 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index ee1a336ea98..0eb1d46637b 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -14,7 +14,7 @@ LL + use std::collections::hash_map::Drain; | LL + use std::collections::hash_set::Drain; | - and 3 other candidates + = and 3 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index b6c7b9ed6df..f2a146fbd52 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index e0933606de0..69df481579b 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -62,8 +62,8 @@ LL - wtf: None, LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), - ╰╴ - and 12 other candidates + │ + ╰ and 12 other candidates help: consider using the `Default` trait ╭╴ LL - wtf: Some(Box(U { @@ -117,8 +117,8 @@ LL + let _ = Box::new_zeroed(); ├╴ LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); - ╰╴ - and 12 other candidates + │ + ╰ and 12 other candidates help: consider using the `Default` trait ╭╴ LL - let _ = Box {}; diff --git a/tests/ui/suggestions/too-many-field-suggestions.stderr b/tests/ui/suggestions/too-many-field-suggestions.stderr index ac5c8cb60cc..0cb0c8bec07 100644 --- a/tests/ui/suggestions/too-many-field-suggestions.stderr +++ b/tests/ui/suggestions/too-many-field-suggestions.stderr @@ -17,7 +17,7 @@ LL | t.a2.bar(); | +++ LL | t.a3.bar(); | +++ - and 6 other candidates + = and 6 other candidates error[E0609]: no field `field` on type `Thing` --> $DIR/too-many-field-suggestions.rs:26:7 @@ -35,7 +35,7 @@ LL | t.a2.field; | +++ LL | t.a3.field; | +++ - and 6 other candidates + = and 6 other candidates error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From df53b3dc04950d980bd28ec4b04f48cd0cd01237 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 10 Jul 2025 10:25:29 -0500 Subject: test(lexer): Add frontmatter unit test --- compiler/rustc_lexer/src/tests.rs | 86 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index a9fcb481759..a7357ba38c8 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -124,9 +124,9 @@ fn test_valid_shebang() { assert_eq!(strip_shebang(input), None); } -fn check_lexing(src: &str, expect: Expect) { +fn check_lexing(src: &str, frontmatter_allowed: FrontmatterAllowed, expect: Expect) { let actual: String = - tokenize(src, FrontmatterAllowed::No).map(|token| format!("{:?}\n", token)).collect(); + tokenize(src, frontmatter_allowed).map(|token| format!("{:?}\n", token)).collect(); expect.assert_eq(&actual) } @@ -134,6 +134,7 @@ fn check_lexing(src: &str, expect: Expect) { fn smoke_test() { check_lexing( "/* my source file */ fn main() { println!(\"zebra\"); }\n", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 } Token { kind: Whitespace, len: 1 } @@ -172,6 +173,7 @@ fn comment_flavors() { /** outer doc block */ /*! inner doc block */ ", + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: LineComment { doc_style: None }, len: 7 } @@ -200,6 +202,7 @@ fn comment_flavors() { fn nested_block_comments() { check_lexing( "/* /* */ */'a'", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -211,6 +214,7 @@ fn nested_block_comments() { fn characters() { check_lexing( "'a' ' ' '\\n'", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } Token { kind: Whitespace, len: 1 } @@ -225,6 +229,7 @@ fn characters() { fn lifetime() { check_lexing( "'abc", + FrontmatterAllowed::No, expect![[r#" Token { kind: Lifetime { starts_with_number: false }, len: 4 } "#]], @@ -235,6 +240,7 @@ fn lifetime() { fn raw_string() { check_lexing( "r###\"\"#a\\b\x00c\"\"###", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: RawStr { n_hashes: Some(3) }, suffix_start: 17 }, len: 17 } "#]], @@ -258,6 +264,7 @@ b"a" r###"raw"###suffix br###"raw"###suffix "####, + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -287,3 +294,78 @@ br###"raw"###suffix "#]], ) } + +#[test] +fn frontmatter_allowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::Yes, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Frontmatter { has_invalid_preceding_whitespace: false, invalid_infostring: false }, len: 38 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} + +#[test] +fn frontmatter_disallowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::No, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Ident, len: 5 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBracket, len: 1 } + Token { kind: Ident, len: 12 } + Token { kind: CloseBracket, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Eq, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} -- cgit 1.4.1-3-g733a5 From a11ee5614c052d6339c56c2673780468c96dbc16 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 15:35:52 -0500 Subject: fix: Include frontmatter in -Zunpretty output In the implementation (#140035), this was left as an open question for the tracking issue (#136889). My assumption is that this should be carried over. Thankfully, either way, `-Zunpretty` is unstable and we can always change it even if we stabilize frontmatter. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 10 +++++++++- tests/ui/unpretty/frontmatter.stdout | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9d656253f72..def0cb74d29 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -120,7 +120,7 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec pos += shebang_len; } - for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::No) { + for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::Yes) { let token_text = &text[pos..pos + token.len as usize]; match token.kind { rustc_lexer::TokenKind::Whitespace => { @@ -171,6 +171,14 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec }) } } + rustc_lexer::TokenKind::Frontmatter { .. } => { + code_to_the_left = false; + comments.push(Comment { + style: CommentStyle::Isolated, + lines: vec![token_text.to_string()], + pos: start_bpos + BytePos(pos as u32), + }); + } _ => { code_to_the_left = true; } diff --git a/tests/ui/unpretty/frontmatter.stdout b/tests/ui/unpretty/frontmatter.stdout index 9ad6bbbe577..2ccbb1b2582 100644 --- a/tests/ui/unpretty/frontmatter.stdout +++ b/tests/ui/unpretty/frontmatter.stdout @@ -1,3 +1,5 @@ +--- +--- //@ compile-flags: -Zunpretty=normal //@ check-pass -- cgit 1.4.1-3-g733a5 From f5fc8727dbbf8c9e93bb0822b2e5bfa77dbd0208 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 10 Jul 2025 09:17:28 -0700 Subject: Add `BuilderMethods::unreachable_nonterminator` So places that need `unreachable` but in the middle of a basic block can call that instead of figuring out the best way to do it. --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 8 ++--- compiler/rustc_codegen_ssa/src/traits/builder.rs | 10 ++++++ tests/codegen/intrinsics/transmute.rs | 41 ++++++++++++------------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 1e3b76e5f93..bf3b1e73b94 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -207,9 +207,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { { // These cases are all UB to actually hit, so don't emit code for them. // (The size mismatches are reachable via `transmute_unchecked`.) - // We can't use unreachable because that's a terminator, and we - // need something that can be in the middle of a basic block. - bx.assume(bx.cx().const_bool(false)) + bx.unreachable_nonterminator(); } else { // Since in this path we have a place anyway, we can store or copy to it, // making sure we use the destination place's alignment even if the @@ -236,9 +234,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || operand.layout.is_uninhabited() || cast.is_uninhabited() { - // We can't use unreachable because that's a terminator, and we - // need something that can be in the middle of a basic block. - bx.assume(bx.cx().const_bool(false)); + bx.unreachable_nonterminator(); // We still need to return a value of the appropriate type, but // it's already UB so do the easiest thing available. diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9d367748c2a..0f1358ee508 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -136,6 +136,16 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> Self::Value; fn unreachable(&mut self); + /// Like [`Self::unreachable`], but for use in the middle of a basic block. + fn unreachable_nonterminator(&mut self) { + // This is the preferred LLVM incantation for this per + // https://llvm.org/docs/Frontend/PerformanceTips.html#other-things-to-consider + // Other backends may override if they have a better way. + let const_true = self.cx().const_bool(true); + let poison_ptr = self.const_poison(self.cx().type_ptr()); + self.store(const_true, poison_ptr, Align::ONE); + } + fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 36d6a2f722f..c9a1cd58af3 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -29,28 +29,28 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] pub unsafe fn check_bigger_size(x: u16) -> u32 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] pub unsafe fn check_smaller_size(x: u32) -> u16 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } @@ -58,9 +58,9 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -73,9 +73,9 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -88,9 +88,9 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: BigNever; { @@ -104,10 +104,9 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call - // CHECK: ret i16 poison + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret i16 poison mir! { { RET = CastTransmute(x); @@ -404,9 +403,9 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { pub unsafe fn check_unit_to_never(x: ()) { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: ZstNever; { @@ -423,7 +422,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. // CHECK: start - // CHECK-NEXT: call void @llvm.assume(i1 false) + // CHECK-NEXT: store i1 true, ptr poison, align 1 // CHECK-NEXT: ret void mir! { { -- cgit 1.4.1-3-g733a5