diff options
Diffstat (limited to 'tests')
48 files changed, 2288 insertions, 103 deletions
diff --git a/tests/crashes/124833.rs b/tests/crashes/124833.rs new file mode 100644 index 00000000000..f1c4847b544 --- /dev/null +++ b/tests/crashes/124833.rs @@ -0,0 +1,10 @@ +//@ known-bug: rust-lang/rust#124833 +#![feature(generic_const_items)] + +trait Trait { + const C<'a>: &'a str; +} + +impl Trait for () { + const C<'a>: = "C"; +} diff --git a/tests/crashes/124857.rs b/tests/crashes/124857.rs new file mode 100644 index 00000000000..4b952fd64cc --- /dev/null +++ b/tests/crashes/124857.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#124857 +//@ compile-flags: -Znext-solver=coherence + +#![feature(effects)] + +#[const_trait] +trait Foo {} + +impl const Foo for i32 {} + +impl<T> const Foo for T where T: ~const Foo {} diff --git a/tests/crashes/124891.rs b/tests/crashes/124891.rs new file mode 100644 index 00000000000..9b5892418c8 --- /dev/null +++ b/tests/crashes/124891.rs @@ -0,0 +1,22 @@ +//@ known-bug: rust-lang/rust#124891 + +type Tait = impl FnOnce() -> (); + +fn reify_as_tait() -> Thunk<Tait> { + Thunk::new(|cont| cont) +} + +struct Thunk<F>(F); + +impl<F> Thunk<F> { + fn new(f: F) + where + F: ContFn, + { + todo!(); + } +} + +trait ContFn {} + +impl<F: FnOnce(Tait) -> ()> ContFn for F {} diff --git a/tests/crashes/124894.rs b/tests/crashes/124894.rs new file mode 100644 index 00000000000..230cf4a89c1 --- /dev/null +++ b/tests/crashes/124894.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#124894 +//@ compile-flags: -Znext-solver=coherence + +#![feature(generic_const_exprs)] + +pub trait IsTrue<const mem: bool> {} +impl<T> IsZST for T where (): IsTrue<{ std::mem::size_of::<T>() == 0 }> {} + +pub trait IsZST {} + +impl IsZST for IsZST {} diff --git a/tests/crashes/125081.rs b/tests/crashes/125081.rs new file mode 100644 index 00000000000..7139caaa00d --- /dev/null +++ b/tests/crashes/125081.rs @@ -0,0 +1,7 @@ +//@ known-bug: rust-lang/rust#125081 + +use std::cell::Cell; + +fn main() { + let _: Cell<&str, "a"> = Cell::new('β); +} diff --git a/tests/crashes/125099.rs b/tests/crashes/125099.rs new file mode 100644 index 00000000000..bfc8c8fdcf6 --- /dev/null +++ b/tests/crashes/125099.rs @@ -0,0 +1,24 @@ +//@ known-bug: rust-lang/rust#125099 + +pub trait ContFn<T>: Fn(T) -> Self::Future { + type Future; +} +impl<T, F> ContFn<T> for F +where + F: Fn(T), +{ + type Future = (); +} + +pub trait SeqHandler { + type Requires; + fn process<F: ContFn<Self::Requires>>() -> impl Sized; +} + +pub struct ConvertToU64; +impl SeqHandler for ConvertToU64 { + type Requires = u64; + fn process<F: ContFn<Self::Requires>>() -> impl Sized {} +} + +fn main() {} diff --git a/tests/crashes/125155.rs b/tests/crashes/125155.rs new file mode 100644 index 00000000000..165061d4b52 --- /dev/null +++ b/tests/crashes/125155.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#125155 + +enum NestedEnum { + First, + Second, + Third +} +enum Enum { + Variant2(Option<*mut &'a &'b ()>) +} + + +fn foo(x: Enum) -> isize { + match x { + Enum::Variant2(NestedEnum::Third) => 4, + } +} diff --git a/tests/crashes/125185.rs b/tests/crashes/125185.rs new file mode 100644 index 00000000000..8693d6c7662 --- /dev/null +++ b/tests/crashes/125185.rs @@ -0,0 +1,16 @@ +//@ known-bug: rust-lang/rust#125185 +//@ compile-flags: -Zvalidate-mir + +type Foo = impl Send; + +struct A; + +const VALUE: Foo = value(); + +fn test(foo: Foo<'a>, f: impl for<'b> FnMut()) { + match VALUE { + 0 | 0 => {} + + _ => (), + } +} diff --git a/tests/crashes/125249.rs b/tests/crashes/125249.rs new file mode 100644 index 00000000000..18196d7b34f --- /dev/null +++ b/tests/crashes/125249.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#125185 +#![feature(return_position_impl_trait_in_trait, return_type_notation)] + +trait IntFactory { + fn stream(&self) -> impl IntFactory<stream(): IntFactory<stream(): Send> + Send>; +} + +pub fn main() {} diff --git a/tests/debuginfo/empty-string.rs b/tests/debuginfo/empty-string.rs index 36240730e19..35b68ed91c0 100644 --- a/tests/debuginfo/empty-string.rs +++ b/tests/debuginfo/empty-string.rs @@ -23,7 +23,7 @@ // lldb-check:[...] empty_string = "" { vec = size=0 } // lldb-command:fr v empty_str -// lldb-check:[...] empty_str = "" { data_ptr = [...] length = 0 } +// lldb-check:[...] empty_str = "" fn main() { let empty_string = String::new(); diff --git a/tests/debuginfo/pretty-slices.rs b/tests/debuginfo/pretty-slices.rs index 5d2086fa478..9defa344be0 100644 --- a/tests/debuginfo/pretty-slices.rs +++ b/tests/debuginfo/pretty-slices.rs @@ -27,10 +27,10 @@ // lldb-check:(&mut [i32]) mut_slice = size=4 { [0] = 2 [1] = 3 [2] = 5 [3] = 7 } // lldb-command:v str_slice -// lldb-check:(&str) str_slice = "string slice" { data_ptr = [...] length = 12 } +// lldb-check:(&str) str_slice = "string slice" { [0] = 's' [1] = 't' [2] = 'r' [3] = 'i' [4] = 'n' [5] = 'g' [6] = ' ' [7] = 's' [8] = 'l' [9] = 'i' [10] = 'c' [11] = 'e' } // lldb-command:v mut_str_slice -// lldb-check:(&mut str) mut_str_slice = "mutable string slice" { data_ptr = [...] length = 20 } +// lldb-check:(&mut str) mut_str_slice = "mutable string slice" { [0] = 'm' [1] = 'u' [2] = 't' [3] = 'a' [4] = 'b' [5] = 'l' [6] = 'e' [7] = ' ' [8] = 's' [9] = 't' [10] = 'r' [11] = 'i' [12] = 'n' [13] = 'g' [14] = ' ' [15] = 's' [16] = 'l' [17] = 'i' [18] = 'c' [19] = 'e' } fn b() {} diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs new file mode 100644 index 00000000000..48d40d167ba --- /dev/null +++ b/tests/debuginfo/strings-and-strs.rs @@ -0,0 +1,63 @@ +//@ min-gdb-version: 14.0 +//@ min-lldb-version: 1800 + +//@ compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print plain_string +// gdbr-check:$1 = alloc::string::String {vec: alloc::vec::Vec<u8, alloc::alloc::Global> {buf: alloc::raw_vec::RawVec<u8, alloc::alloc::Global> {ptr: core::ptr::unique::Unique<u8> {pointer: core::ptr::non_null::NonNull<u8> {pointer: 0x55555555ab80}, _marker: core::marker::PhantomData<u8>}, cap: alloc::raw_vec::Cap (5), alloc: alloc::alloc::Global}, len: 5}} + +// gdb-command:print plain_str +// gdbr-check:$2 = "Hello" + +// gdb-command:print str_in_struct +// gdbr-check:$3 = strings_and_strs::Foo {inner: "Hello"} + +// gdb-command:print str_in_tuple +// gdbr-check:$4 = ("Hello", "World") + +// gdb-command:print str_in_rc +// gdbr-check:$5 = alloc::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull<alloc::rc::RcBox<&str>> {pointer: 0x55555555aae0}, phantom: core::marker::PhantomData<alloc::rc::RcBox<&str>>, alloc: alloc::alloc::Global} + + +// === LLDB TESTS ================================================================================== +// lldb-command:run +// lldb-command:v plain_string +// lldbg-check:(alloc::string::String) plain_string = "Hello" { vec = size=5 { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } } + +// lldb-command:v plain_str +// lldbg-check:(&str) plain_str = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } + +// lldb-command:v str_in_struct +// lldbg-check:((&str, &str)) str_in_tuple = { 0 = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } 1 = "World" { [0] = 'W' [1] = 'o' [2] = 'r' [3] = 'l' [4] = 'd' } } + +// lldb-command:v str_in_tuple +// lldbg-check:((&str, &str)) str_in_tuple = { 0 = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } 1 = "World" { [0] = 'W' [1] = 'o' [2] = 'r' [3] = 'l' [4] = 'd' } } + +// lldb-command:v str_in_rc +// lldbg-check:(alloc::rc::Rc<&str, alloc::alloc::Global>) str_in_rc = strong=1, weak=0 { value = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } } + + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +pub struct Foo<'a> { + inner: &'a str, +} + +fn main() { + let plain_string = String::from("Hello"); + let plain_str = "Hello"; + let str_in_struct = Foo { inner: "Hello" }; + let str_in_tuple = ("Hello", "World"); + + let str_in_rc = std::rc::Rc::new("Hello"); + zzz(); // #break +} + +fn zzz() { + () +} diff --git a/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs b/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs index 537d3e2d724..e9c54fa3922 100644 --- a/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs @@ -2,5 +2,5 @@ mod scrape; fn main() { - scrape::scrape(); + scrape::scrape(&[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs index 537d3e2d724..e9c54fa3922 100644 --- a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs @@ -2,5 +2,5 @@ mod scrape; fn main() { - scrape::scrape(); + scrape::scrape(&[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs b/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs index d9deaf279ce..4e3b895aef0 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/rmake.rs @@ -1,5 +1,5 @@ mod scrape; fn main() { - scrape::scrape(); + scrape::scrape(&[]); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs index 709388b5492..563e3aca9ae 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs @@ -2,7 +2,7 @@ use run_make_support::{htmldocck, rustc, rustdoc, source_path, tmp_dir}; use std::fs::read_dir; use std::path::Path; -pub fn scrape() { +pub fn scrape(extra_args: &[&str]) { let lib_dir = tmp_dir(); let out_dir = tmp_dir().join("rustdoc"); let crate_name = "foobar"; @@ -29,6 +29,7 @@ pub fn scrape() { .arg(&out_example) .arg("--scrape-examples-target-crate") .arg(crate_name) + .args(extra_args) .run(); out_deps.push(out_example); } diff --git a/tests/run-make/rustdoc-scrape-examples-test/Makefile b/tests/run-make/rustdoc-scrape-examples-test/Makefile deleted file mode 100644 index 1235ead6751..00000000000 --- a/tests/run-make/rustdoc-scrape-examples-test/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -extra_flags := --scrape-tests -deps := ex - -include ../rustdoc-scrape-examples-multiple/scrape.mk - -all: scrape diff --git a/tests/run-make/rustdoc-scrape-examples-test/rmake.rs b/tests/run-make/rustdoc-scrape-examples-test/rmake.rs new file mode 100644 index 00000000000..f96ba113ff7 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-test/rmake.rs @@ -0,0 +1,6 @@ +#[path = "../rustdoc-scrape-examples-remap/scrape.rs"] +mod scrape; + +fn main() { + scrape::scrape(&["--scrape-tests"]); +} diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs index d71697e9a83..43b0208461e 100644 --- a/tests/ui/associated-types/associated-types-eq-2.rs +++ b/tests/ui/associated-types/associated-types-eq-2.rs @@ -4,7 +4,7 @@ struct Bar; struct Qux; -// Tests for a a non generic trait +// Tests for a non generic trait pub trait Tr1 { type A; fn boo(&self) -> <Self as Tr1>::A; diff --git a/tests/ui/coherence/associated-type2.rs b/tests/ui/coherence/associated-type2.rs index 2aadfb04af0..68e98b62953 100644 --- a/tests/ui/coherence/associated-type2.rs +++ b/tests/ui/coherence/associated-type2.rs @@ -1,6 +1,6 @@ //! A regression test for #120343. The overlap error was previously //! silenced in coherence because projecting `<() as ToUnit>::Unit` -//! failed. Then then silenced the missing items error in the `ToUnit` +//! failed. Then silenced the missing items error in the `ToUnit` //! impl, causing us to not emit any errors and ICEing due to a //! `span_delay_bug`. diff --git a/tests/ui/coroutine/static-move-suggestion.fixed b/tests/ui/coroutine/static-move-suggestion.fixed new file mode 100644 index 00000000000..56445be4715 --- /dev/null +++ b/tests/ui/coroutine/static-move-suggestion.fixed @@ -0,0 +1,19 @@ +//@ run-rustfix + +// check to make sure that we suggest adding `move` after `static` + +#![feature(coroutines)] + +fn check() -> impl Sized { + let x = 0; + #[coroutine] + static move || { + //~^ ERROR E0373 + yield; + x + } +} + +fn main() { + check(); +} diff --git a/tests/ui/coroutine/static-move-suggestion.rs b/tests/ui/coroutine/static-move-suggestion.rs new file mode 100644 index 00000000000..1d6e4a62883 --- /dev/null +++ b/tests/ui/coroutine/static-move-suggestion.rs @@ -0,0 +1,19 @@ +//@ run-rustfix + +// check to make sure that we suggest adding `move` after `static` + +#![feature(coroutines)] + +fn check() -> impl Sized { + let x = 0; + #[coroutine] + static || { + //~^ ERROR E0373 + yield; + x + } +} + +fn main() { + check(); +} diff --git a/tests/ui/coroutine/static-move-suggestion.stderr b/tests/ui/coroutine/static-move-suggestion.stderr new file mode 100644 index 00000000000..6d890468b32 --- /dev/null +++ b/tests/ui/coroutine/static-move-suggestion.stderr @@ -0,0 +1,26 @@ +error[E0373]: coroutine may outlive the current function, but it borrows `x`, which is owned by the current function + --> $DIR/static-move-suggestion.rs:10:5 + | +LL | static || { + | ^^^^^^^^^ may outlive borrowed value `x` +... +LL | x + | - `x` is borrowed here + | +note: coroutine is returned here + --> $DIR/static-move-suggestion.rs:10:5 + | +LL | / static || { +LL | | +LL | | yield; +LL | | x +LL | | } + | |_____^ +help: to force the coroutine to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | static move || { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr new file mode 100644 index 00000000000..41f222e46a7 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr @@ -0,0 +1,12 @@ +error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied + --> $DIR/as_expression.rs:57:15 + | +LL | SelectInt.check("bar"); + | ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str` + | + = help: the trait `AsExpression<Text>` is implemented for `&str` + = help: for that trait implementation, expected `Text`, found `Integer` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr new file mode 100644 index 00000000000..47acf5b968b --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied + --> $DIR/as_expression.rs:57:21 + | +LL | SelectInt.check("bar"); + | ----- ^^^^^ the trait `AsExpression<<SelectInt as Expression>::SqlType>` is not implemented for `&str` + | | + | required by a bound introduced by this call + | + = help: the trait `AsExpression<Text>` is implemented for `&str` +note: required by a bound in `Foo::check` + --> $DIR/as_expression.rs:48:12 + | +LL | fn check<T>(&self, _: T) -> <T as AsExpression<<Self as Expression>::SqlType>>::Expression + | ----- required by a bound in this associated function +LL | where +LL | T: AsExpression<Self::SqlType>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs new file mode 100644 index 00000000000..9cdc193d386 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs @@ -0,0 +1,60 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +pub trait Expression { + type SqlType; +} + +pub trait AsExpression<ST> { + type Expression: Expression<SqlType = ST>; +} + +pub struct Text; +pub struct Integer; + +pub struct Bound<T>(T); +pub struct SelectInt; + +impl Expression for SelectInt { + type SqlType = Integer; +} + +impl<T> Expression for Bound<T> { + type SqlType = T; +} + +#[do_not_recommend] +impl<T, ST> AsExpression<ST> for T +where + T: Expression<SqlType = ST>, +{ + type Expression = T; +} + +impl AsExpression<Integer> for i32 { + type Expression = Bound<Integer>; +} + +impl AsExpression<Text> for &'_ str { + type Expression = Bound<Text>; +} + +trait Foo: Expression + Sized { + fn check<T>(&self, _: T) -> <T as AsExpression<<Self as Expression>::SqlType>>::Expression + where + T: AsExpression<Self::SqlType>, + { + todo!() + } +} + +impl<T> Foo for T where T: Expression {} + +fn main() { + SelectInt.check("bar"); + //[next]~^ ERROR the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied + //[current]~^^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied +} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr index a4d4b7b359e..729cb5694e2 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr @@ -1,16 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:19:17 + --> $DIR/simple.rs:17:17 | LL | needs_foo::<*mut ()>(); - | ^^^^^^^ the trait `Send` is not implemented for `*mut ()`, which is required by `*mut (): Foo` + | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | -note: required for `*mut ()` to implement `Foo` - --> $DIR/simple.rs:10:9 - | -LL | impl<T> Foo for T where T: Send {} - | ^^^ ^ ---- unsatisfied trait bound introduced here note: required by a bound in `needs_foo` - --> $DIR/simple.rs:14:17 + --> $DIR/simple.rs:12:17 | LL | fn needs_foo<T: Foo>() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr index 1341ca8175a..729cb5694e2 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:19:17 + --> $DIR/simple.rs:17:17 | LL | needs_foo::<*mut ()>(); | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | note: required by a bound in `needs_foo` - --> $DIR/simple.rs:14:17 + --> $DIR/simple.rs:12:17 | LL | fn needs_foo<T: Foo>() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs index 15ff80ae4d9..6fb15b90138 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs @@ -8,8 +8,6 @@ trait Foo {} #[do_not_recommend] impl<T> Foo for T where T: Send {} -//[current]~^ NOTE required for `*mut ()` to implement `Foo` -//[current]~| NOTE unsatisfied trait bound introduced here fn needs_foo<T: Foo>() {} //~^ NOTE required by a bound in `needs_foo` @@ -18,6 +16,5 @@ fn needs_foo<T: Foo>() {} fn main() { needs_foo::<*mut ()>(); //~^ ERROR the trait bound `*mut (): Foo` is not satisfied - //[current]~| NOTE the trait `Send` is not implemented for `*mut ()` - //[next]~| NOTE the trait `Foo` is not implemented for `*mut ()` + //~| NOTE the trait `Foo` is not implemented for `*mut ()` } diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr new file mode 100644 index 00000000000..41a10a61e1d --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): Root` is not satisfied + --> $DIR/stacked.rs:19:18 + | +LL | needs_root::<()>(); + | ^^ the trait `Root` is not implemented for `()` + | +note: required by a bound in `needs_root` + --> $DIR/stacked.rs:16:18 + | +LL | fn needs_root<T: Root>() {} + | ^^^^ required by this bound in `needs_root` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr new file mode 100644 index 00000000000..41a10a61e1d --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): Root` is not satisfied + --> $DIR/stacked.rs:19:18 + | +LL | needs_root::<()>(); + | ^^ the trait `Root` is not implemented for `()` + | +note: required by a bound in `needs_root` + --> $DIR/stacked.rs:16:18 + | +LL | fn needs_root<T: Root>() {} + | ^^^^ required by this bound in `needs_root` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs new file mode 100644 index 00000000000..695660d3596 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs @@ -0,0 +1,21 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +trait Root {} +trait DontRecommend {} +trait Other {} + +#[do_not_recommend] +impl<T> Root for T where T: DontRecommend {} + +impl<T> DontRecommend for T where T: Other {} + +fn needs_root<T: Root>() {} + +fn main() { + needs_root::<()>(); + //~^ ERROR the trait bound `(): Root` is not satisfied +} diff --git a/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs new file mode 100644 index 00000000000..96a0f2f40bf --- /dev/null +++ b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs @@ -0,0 +1,19 @@ +// Fix for <https://github.com/rust-lang/rust/issues/125196>. +//@ check-pass + +trait Tr { + type Gat<T>; +} + +struct W<T>(T); + +fn foo<T: Tr>() where for<'a> &'a T: Tr<Gat<W<i32>> = i32> { + let x: <&T as Tr>::Gat<W<_>> = 1i32; + // Previously, `match_projection_projections` only checked that + // `shallow_resolve(W<?0>) = W<?0>`. This won't prevent *all* inference guidance + // from projection predicates in the environment, just ones that guide the + // outermost type of each GAT constructor. This is definitely wrong, but there is + // code that relies on it in the wild :/ +} + +fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs index 2f53bd019b7..e0d2e44e6e7 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs @@ -49,7 +49,7 @@ fn function3<T: Trait<'static, Assoc = usize>>() { // Trying to normalize the type `for<'a> fn(<T as Trait<'a>>::Assoc)` // only gets to `<T as Trait<'a>>::Assoc` once `'a` has been already // instantiated, causing us to prefer the where-bound over the impl - // resulting in a placeholder error. Even if were were to also use the + // resulting in a placeholder error. Even if we were to also use the // leak check during candidate selection for normalization, this // case would still not compile. let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| (); diff --git a/tests/ui/macros/issue-98790.rs b/tests/ui/macros/issue-98790.rs deleted file mode 100644 index b489efe9ce9..00000000000 --- a/tests/ui/macros/issue-98790.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass - -macro_rules! stringify_item { - ($item:item) => { - stringify!($item) - }; -} - -macro_rules! repro { - ($expr:expr) => { - stringify_item! { - pub fn repro() -> bool { - $expr - } - } - }; -} - -fn main() { - assert_eq!( - repro!(match () { () => true } | true), - "pub fn repro() -> bool { (match () { () => true, }) | true }" - ); -} diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index 0ae498c134f..d65bfee843e 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -7,6 +7,7 @@ fn _zero() { if false { unsafe { mem::zeroed() } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -21,6 +22,7 @@ fn _trans() { struct Zst; core::mem::transmute(Zst) //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } } else { return; @@ -36,6 +38,7 @@ fn _union() { unsafe { Union { a: () }.b } //~^ warn: never type fallback affects this union access + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -45,6 +48,7 @@ fn _deref() { if false { unsafe { *ptr::from_ref(&()).cast() } //~^ warn: never type fallback affects this raw pointer dereference + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -62,6 +66,7 @@ fn _only_generics() { unsafe { internally_create(x) } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! x.unwrap() } else { @@ -73,9 +78,11 @@ fn _stored_function() { if false { let zeroed = mem::zeroed; //~^ warn: never type fallback affects this `unsafe` function + //~| warn: this will change its meaning in a future release! unsafe { zeroed() } //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! } else { return; }; @@ -90,6 +97,7 @@ fn _only_generics_stored_function() { let x = None; let f = internally_create; //~^ warn: never type fallback affects this `unsafe` function + //~| warn: this will change its meaning in a future release! unsafe { f(x) } @@ -113,6 +121,7 @@ fn _method() { unsafe { S(marker::PhantomData).create_out_of_thin_air() //~^ warn: never type fallback affects this call to an `unsafe` method + //~| warn: this will change its meaning in a future release! } } else { return; @@ -129,6 +138,7 @@ fn _objc() { () => { match send_message::<_ /* ?0 */>() { //~^ warn: never type fallback affects this call to an `unsafe` function + //~| warn: this will change its meaning in a future release! Ok(x) => x, Err(_) => loop {}, } diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr index 84c9385fd13..fbd92f8f662 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr @@ -4,75 +4,93 @@ warning: never type fallback affects this call to an `unsafe` function LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:22:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:23:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:37:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:39:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:49:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:63:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:67:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:77:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:83:18 | LL | unsafe { zeroed() } | ^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:74:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:98:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:122:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:130:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,6 +98,8 @@ LL | match send_message::<_ /* ?0 */>() { LL | msg_send!(); | ----------- in this macro invocation | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/parser/label-is-actually-char.rs b/tests/ui/parser/label-is-actually-char.rs index 74df898d191..915ce86d269 100644 --- a/tests/ui/parser/label-is-actually-char.rs +++ b/tests/ui/parser/label-is-actually-char.rs @@ -1,4 +1,4 @@ -// Note: it's ok to interpret 'a as 'a', but but not ok to interpret 'abc as +// Note: it's ok to interpret 'a as 'a', but not ok to interpret 'abc as // 'abc' because 'abc' is not a valid char literal. fn main() { diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr index 284dacf7000..e6f199445bf 100644 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr +++ b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr @@ -2,18 +2,8 @@ error[E0277]: the trait bound `u8: Bar` is not satisfied --> $DIR/feature-gate-do_not_recommend.rs:19:11 | LL | stuff(1u8); - | ----- ^^^ the trait `Foo` is not implemented for `u8`, which is required by `u8: Bar` - | | - | required by a bound introduced by this call + | ^^^ the trait `Bar` is not implemented for `u8` | - = help: the trait `Foo` is implemented for `i32` -note: required for `u8` to implement `Bar` - --> $DIR/feature-gate-do_not_recommend.rs:13:14 - | -LL | impl<T: Foo> Bar for T { - | --- ^^^ ^ - | | - | unsatisfied trait bound introduced here note: required by a bound in `stuff` --> $DIR/feature-gate-do_not_recommend.rs:16:13 | diff --git a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs index 0e1d44e7bb3..75a4fbdb5d6 100644 --- a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs +++ b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs @@ -1,4 +1,4 @@ -// User type annotation in fn bodies is a a valid defining site for opaque types. +// User type annotation in fn bodies is a valid defining site for opaque types. //@ check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs index 59ba2694a76..b209b4bc89d 100644 --- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs @@ -25,7 +25,7 @@ mod mod3 { } // This is similar to the previous cases in that 'a is equal to 'static, -// which is is some sense an implicit parameter to `Opaque`. +// which is some sense an implicit parameter to `Opaque`. // For example, given a defining use `Opaque<'a> := &'a ()`, // it is ambiguous whether `Opaque<'a> := &'a ()` or `Opaque<'a> := &'static ()` mod mod4 { diff --git a/tests/ui/unpretty/auxiliary/data.txt b/tests/ui/unpretty/auxiliary/data.txt new file mode 100644 index 00000000000..2f62e4609f4 --- /dev/null +++ b/tests/ui/unpretty/auxiliary/data.txt @@ -0,0 +1 @@ +data for include_bytes in ../expanded-exhaustive.rs diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs new file mode 100644 index 00000000000..6aa032d7ed8 --- /dev/null +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -0,0 +1,888 @@ +//@ compile-flags: -Zunpretty=expanded -Zunstable-options +//@ edition:2024 +//@ check-pass + +#![feature(async_closure)] +#![feature(auto_traits)] +#![feature(box_patterns)] +#![feature(builtin_syntax)] +#![feature(concat_idents)] +#![feature(const_trait_impl)] +#![feature(core_pattern_type)] +#![feature(decl_macro)] +#![feature(deref_patterns)] +#![feature(explicit_tail_calls)] +#![feature(gen_blocks)] +#![feature(let_chains)] +#![feature(more_qualified_paths)] +#![feature(never_patterns)] +#![feature(never_type)] +#![feature(pattern_types)] +#![feature(prelude_import)] +#![feature(raw_ref_op)] +#![feature(specialization)] +#![feature(trace_macros)] +#![feature(trait_alias)] +#![feature(try_blocks)] +#![feature(unnamed_fields)] +#![feature(yeet_expr)] +#![allow(incomplete_features)] + +#[prelude_import] +use self::prelude::*; + +mod prelude { + pub use std::prelude::rust_2024::*; + + pub type T = _; + + pub trait Trait { + const CONST: (); + } +} + +mod attributes { + //! inner single-line doc comment + /*! + * inner multi-line doc comment + */ + #![doc = "inner doc attribute"] + #![allow(dead_code, unused_variables)] + #![no_std] + + /// outer single-line doc comment + /** + * outer multi-line doc comment + */ + #[doc = "outer doc attribute"] + #[doc = concat!("mac", "ro")] + #[allow()] + #[repr(C)] + struct Struct; +} + +mod expressions { + /// ExprKind::Array + fn expr_array() { + []; + [true]; + [true,]; + [true, true]; + ["long........................................................................"]; + ["long............................................................", true]; + } + + /// ExprKind::ConstBlock + fn expr_const_block() { + const {}; + const { 1 }; + const { struct S; }; + } + + /// ExprKind::Call + fn expr_call() { + let f; + f(); + f::<u8>(); + f::<1>(); + f::<'static, u8, 1>(); + f(true); + f(true,); + ()(); + } + + /// ExprKind::MethodCall + fn expr_method_call() { + let x; + x.f(); + x.f::<u8>(); + x.collect::<Vec<_>>(); + } + + /// ExprKind::Tup + fn expr_tup() { + (); + (true,); + (true, false); + (true, false,); + } + + /// ExprKind::Binary + fn expr_binary() { + let (a, b, c, d, x, y); + true || false; + true || false && false; + a < 1 && 2 < b && c > 3 && 4 > d; + a & b & !c; + a + b * c - d + -1 * -2 - -3; + x = !y; + } + + /// ExprKind::Unary + fn expr_unary() { + let expr; + *expr; + !expr; + -expr; + } + + /// ExprKind::Lit + fn expr_lit() { + 'x'; + 1_000_i8; + 1.00000000000000000000001; + } + + /// ExprKind::Cast + fn expr_cast() { + let expr; + expr as T; + expr as T<u8>; + } + + /// ExprKind::Type + fn expr_type() { + let expr; + builtin # type_ascribe(expr, T); + } + + /// ExprKind::Let + fn expr_let() { + let b; + if let Some(a) = b {} + if let _ = true && false {} + if let _ = (true && false) {} + } + + /// ExprKind::If + fn expr_if() { + if true {} + if !true {} + if let true = true {} else {} + if true {} else if false {} + if true {} else if false {} else {} + if true { return; } else if false { 0 } else { 0 } + } + + /// ExprKind::While + fn expr_while() { + while false {} + 'a: while false {} + while let true = true {} + } + + /// ExprKind::ForLoop + fn expr_for_loop() { + let x; + for _ in x {} + 'a: for _ in x {} + } + + /// ExprKind::Loop + fn expr_loop() { + loop {} + 'a: loop {} + } + + /// ExprKind::Match + fn expr_match() { + let value; + match value {} + match value { ok => 1 } + match value { + ok => 1, + err => 0, + } + } + + /// ExprKind::Closure + fn expr_closure() { + let value; + || {}; + |x| {}; + |x: u8| {}; + || (); + move || value; + async || value; + async move || value; + static || value; + static move || value; + (static async || value); + (static async move || value); + || -> u8 { value }; + 1 + || {}; + } + + /// ExprKind::Block + fn expr_block() { + {} + unsafe {} + 'a: {} + #[allow()] {} + { #![allow()] } + } + + /// ExprKind::Gen + fn expr_gen() { + async {}; + async move {}; + gen {}; + gen move {}; + async gen {}; + async gen move {}; + } + + /// ExprKind::Await + fn expr_await() { + let fut; + fut.await; + } + + /// ExprKind::TryBlock + fn expr_try_block() { + try {} + try { return; } + } + + /// ExprKind::Assign + fn expr_assign() { + let expr; + expr = true; + } + + /// ExprKind::AssignOp + fn expr_assign_op() { + let expr; + expr += true; + } + + /// ExprKind::Field + fn expr_field() { + let expr; + expr.field; + expr.0; + } + + /// ExprKind::Index + fn expr_index() { + let expr; + expr[true]; + } + + /// ExprKind::Range + fn expr_range() { + let (lo, hi); + ..; + ..hi; + lo..; + lo..hi; + lo .. hi; + ..=hi; + lo..=hi; + -2..=-1; + } + + /// ExprKind::Underscore + fn expr_underscore() { + _; + } + + /// ExprKind::Path + fn expr_path() { + let x; + crate::expressions::expr_path; + crate::expressions::expr_path::<'static>; + <T as Default>::default; + <T as ::core::default::Default>::default::<>; + x::(); + x::(T, T) -> T; + crate::() -> ()::expressions::() -> ()::expr_path; + core::()::marker::()::PhantomData; + } + + /// ExprKind::AddrOf + fn expr_addr_of() { + let expr; + &expr; + &mut expr; + &raw const expr; + &raw mut expr; + } + + /// ExprKind::Break + fn expr_break() { + 'a: { + break; + break 'a; + break true; + break 'a true; + } + } + + /// ExprKind::Continue + fn expr_continue() { + 'a: { + continue; + continue 'a; + } + } + + /// ExprKind::Ret + fn expr_ret() { + return; + return true; + } + + /// ExprKind::InlineAsm + fn expr_inline_asm() { + let x; + core::arch::asm!( + "mov {tmp}, {x}", + "shl {tmp}, 1", + "shl {x}, 2", + "add {x}, {tmp}", + x = inout(reg) x, + tmp = out(reg) _, + ); + } + + /// ExprKind::OffsetOf + fn expr_offset_of() { + core::mem::offset_of!(T, field); + } + + /// ExprKind::MacCall + fn expr_mac_call() { + stringify!(...); + stringify![...]; + stringify! { ... }; + } + + /// ExprKind::Struct + fn expr_struct() { + struct Struct {} + let (x, base); + Struct {}; + <Struct as ToOwned>::Owned {}; + Struct { .. }; + Struct { .. base }; + Struct { x }; + Struct { x, ..base }; + Struct { x: true }; + Struct { x: true, .. }; + Struct { x: true, ..base }; + Struct { 0: true, ..base }; + } + + /// ExprKind::Repeat + fn expr_repeat() { + [(); 0]; + } + + /// ExprKind::Paren + fn expr_paren() { + let expr; + (expr); + } + + /// ExprKind::Try + fn expr_try() { + let expr; + expr?; + } + + /// ExprKind::Yield + fn expr_yield() { + yield; + yield true; + } + + /// ExprKind::Yeet + fn expr_yeet() { + do yeet; + do yeet 0; + } + + /// ExprKind::Become + fn expr_become() { + become true; + } + + /// ExprKind::IncludedBytes + fn expr_include_bytes() { + include_bytes!("auxiliary/data.txt"); + } + + /// ExprKind::FormatArgs + fn expr_format_args() { + let expr; + format_args!(""); + format_args!("{}", expr); + } +} + +mod items { + /// ItemKind::ExternCrate + mod item_extern_crate { + extern crate core; + extern crate self as unpretty; + pub extern crate core as _; + } + + /// ItemKind::Use + mod item_use { + use crate::{expressions, items::item_use}; + pub use core::*; + } + + /// ItemKind::Static + mod item_static { + pub static A: () = {}; + static mut B: () = {}; + } + + /// ItemKind::Const + mod item_const { + pub const A: () = {}; + + trait TraitItems { + const B: (); + const C: () = {}; + } + } + + /// ItemKind::Fn + mod item_fn { + pub const unsafe extern "C" fn f() {} + pub async unsafe extern fn g() {} + fn h<'a, T>() where T: 'a {} + + trait TraitItems { + unsafe extern fn f(); + } + + impl TraitItems for _ { + default unsafe extern fn f() {} + } + } + + /// ItemKind::Mod + mod item_mod { + // ... + } + + /// ItemKind::ForeignMod + mod item_foreign_mod { + extern "C++" {} + extern {} + } + + /// ItemKind::GlobalAsm + mod item_global_asm { + core::arch::global_asm!(".globl my_asm_func"); + } + + /// ItemKind::TyAlias + mod item_ty_alias { + pub type Type<'a> where T: 'a, = T; + } + + /// ItemKind::Enum + mod item_enum { + pub enum Void {} + enum Empty { + Unit, + Tuple(), + Struct {}, + } + enum Generic<'a, T> + where + T: 'a, + { + Tuple(T), + Struct { t: T }, + } + } + + /// ItemKind::Struct + mod item_struct { + pub struct Unit; + struct Tuple(); + struct Newtype(Unit); + struct Struct {} + struct Generic<'a, T> + where + T: 'a, + { + t: T, + } + } + + /// ItemKind::Union + mod item_union { + union Generic<'a, T> + where + T: 'a, + { + t: T, + } + } + + /// ItemKind::Trait + mod item_trait { + pub unsafe auto trait Send {} + trait Trait<'a>: Sized + where + Self: 'a, + { + } + } + + /// ItemKind::TraitAlias + mod item_trait_alias { + pub trait Trait<T> = Sized where for<'a> T: 'a; + } + + /// ItemKind::Impl + mod item_impl { + impl () {} + impl<T> () {} + impl Default for () {} + impl<T> const Default for () {} + } + + /// ItemKind::MacCall + mod item_mac_call { + trace_macros!(false); + trace_macros![false]; + trace_macros! { false } + } + + /// ItemKind::MacroDef + mod item_macro_def { + macro_rules! mac { () => {...}; } + pub macro stringify() {} + } + + /// ItemKind::Delegation + mod item_delegation { + /*! FIXME: todo */ + } + + /// ItemKind::DelegationMac + mod item_delegation_mac { + /*! FIXME: todo */ + } +} + +mod patterns { + /// PatKind::Wild + fn pat_wild() { + let _; + } + + /// PatKind::Ident + fn pat_ident() { + let x; + let ref x; + let mut x; + let ref mut x; + let ref mut x @ _; + } + + /// PatKind::Struct + fn pat_struct() { + let T {}; + let T::<T> {}; + let T::<'static> {}; + let T { x }; + let T { x: _x }; + let T { .. }; + let T { x, .. }; + let T { x: _x, .. }; + let T { 0: _x, .. }; + let <T as ToOwned>::Owned {}; + } + + /// PatKind::TupleStruct + fn pat_tuple_struct() { + struct Tuple(); + let Tuple(); + let Tuple::<T>(); + let Tuple::<'static>(); + let Tuple(x); + let Tuple(..); + let Tuple(x, ..); + } + + /// PatKind::Or + fn pat_or() { + let (true | false); + let (| true); + let (|true| false); + } + + /// PatKind::Path + fn pat_path() { + let core::marker::PhantomData; + let core::marker::PhantomData::<T>; + let core::marker::PhantomData::<'static>; + let <T as Trait>::CONST; + } + + /// PatKind::Tuple + fn pat_tuple() { + let (); + let (true,); + let (true, false); + } + + /// PatKind::Box + fn pat_box() { + let box pat; + } + + /// PatKind::Deref + fn pat_deref() { + let deref!(pat); + } + + /// PatKind::Ref + fn pat_ref() { + let &pat; + let &mut pat; + } + + /// PatKind::Lit + fn pat_lit() { + let 1_000_i8; + let -""; + } + + /// PatKind::Range + fn pat_range() { + let ..1; + let 0..; + let 0..1; + let 0..=1; + let -2..=-1; + } + + /// PatKind::Slice + fn pat_slice() { + let []; + let [true]; + let [true,]; + let [true, false]; + } + + /// PatKind::Rest + fn pat_rest() { + let ..; + } + + /// PatKind::Never + fn pat_never() { + let !; + let Some(!); + } + + /// PatKind::Paren + fn pat_paren() { + let (pat); + } + + /// PatKind::MacCall + fn pat_mac_call() { + let stringify!(); + let stringify![]; + let stringify! {}; + } +} + +mod statements { + /// StmtKind::Let + fn stmt_let() { + let _; + let _ = true; + let _: T = true; + let _ = true else { return; }; + } + + /// StmtKind::Item + fn stmt_item() { + struct Struct {} + struct Unit; + } + + /// StmtKind::Expr + fn stmt_expr() { + () + } + + /// StmtKind::Semi + fn stmt_semi() { + 1 + 1; + } + + /// StmtKind::Empty + fn stmt_empty() { + ; + } + + /// StmtKind::MacCall + fn stmt_mac_call() { + stringify!(...); + stringify![...]; + stringify! { ... }; + } +} + +mod types { + /// TyKind::Slice + fn ty_slice() { + let _: [T]; + } + + /// TyKind::Array + fn ty_array() { + let _: [T; 0]; + } + + /// TyKind::Ptr + fn ty_ptr() { + let _: *const T; + let _: *mut T; + } + + /// TyKind::Ref + fn ty_ref() { + let _: &T; + let _: &mut T; + let _: &'static T; + let _: &'static mut [T]; + let _: &T<T<T<T<T>>>>; + let _: &T<T<T<T<T> > > >; + } + + /// TyKind::BareFn + fn ty_bare_fn() { + let _: fn(); + let _: fn() -> (); + let _: fn(T); + let _: fn(t: T); + let _: for<> fn(); + let _: for<'a> fn(); + } + + /// TyKind::Never + fn ty_never() { + let _: !; + } + + /// TyKind::Tup + fn ty_tup() { + let _: (); + let _: (T,); + let _: (T, T); + } + + /// TyKind::AnonStruct + fn ty_anon_struct() { + struct Struct { + _: struct { t: T }, + } + } + + /// TyKind::AnonUnion + fn ty_anon_union() { + struct Struct { + _: union { t: T }, + } + } + + /// TyKind::Path + fn ty_path() { + let _: T; + let _: T<'static>; + let _: T<T>; + let _: T::<T>; + let _: T() -> !; + let _: <T as ToOwned>::Owned; + } + + /// TyKind::TraitObject + fn ty_trait_object() { + let _: dyn Send; + let _: dyn Send + 'static; + let _: dyn 'static + Send; + let _: dyn for<'a> Send; + } + + /// TyKind::ImplTrait + const fn ty_impl_trait() { + let _: impl Send; + let _: impl Send + 'static; + let _: impl 'static + Send; + let _: impl ?Sized; + let _: impl ~const Clone; + let _: impl for<'a> Send; + } + + /// TyKind::Paren + fn ty_paren() { + let _: (T); + } + + /// TyKind::Typeof + fn ty_typeof() { + /*! unused for now */ + } + + /// TyKind::Infer + fn ty_infer() { + let _: _; + } + + /// TyKind::ImplicitSelf + fn ty_implicit_self() { + /*! there is no syntax for this */ + } + + /// TyKind::MacCall + fn ty_mac_call() { + let _: concat_idents!(T); + let _: concat_idents![T]; + let _: concat_idents! { T }; + } + + /// TyKind::CVarArgs + fn ty_c_var_args() { + /*! FIXME: todo */ + } + + /// TyKind::Pat + fn ty_pat() { + let _: core::pattern_type!(u32 is 1..); + } +} + +mod visibilities { + /// VisibilityKind::Public + mod visibility_public { + pub struct Pub; + } + + /// VisibilityKind::Restricted + mod visibility_restricted { + pub(crate) struct PubCrate; + pub(self) struct PubSelf; + pub(super) struct PubSuper; + pub(in crate) struct PubInCrate; + pub(in self) struct PubInSelf; + pub(in super) struct PubInSuper; + pub(in crate::visibilities) struct PubInCrateVisibilities; + pub(in self::super) struct PubInSelfSuper; + pub(in super::visibility_restricted) struct PubInSuperMod; + } +} diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout new file mode 100644 index 00000000000..325bace7b56 --- /dev/null +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -0,0 +1,719 @@ +#![feature(prelude_import)] +//@ compile-flags: -Zunpretty=expanded -Zunstable-options +//@ edition:2024 +//@ check-pass + +#![feature(async_closure)] +#![feature(auto_traits)] +#![feature(box_patterns)] +#![feature(builtin_syntax)] +#![feature(concat_idents)] +#![feature(const_trait_impl)] +#![feature(core_pattern_type)] +#![feature(decl_macro)] +#![feature(deref_patterns)] +#![feature(explicit_tail_calls)] +#![feature(gen_blocks)] +#![feature(let_chains)] +#![feature(more_qualified_paths)] +#![feature(never_patterns)] +#![feature(never_type)] +#![feature(pattern_types)] +#![feature(prelude_import)] +#![feature(raw_ref_op)] +#![feature(specialization)] +#![feature(trace_macros)] +#![feature(trait_alias)] +#![feature(try_blocks)] +#![feature(unnamed_fields)] +#![feature(yeet_expr)] +#![allow(incomplete_features)] +#[prelude_import] +use std::prelude::rust_2024::*; +#[macro_use] +extern crate std; + +#[prelude_import] +use self::prelude::*; + +mod prelude { + pub use std::prelude::rust_2024::*; + + pub type T = _; + + pub trait Trait { + const CONST: (); + } +} + +mod attributes { + //! inner single-line doc comment + /*! + * inner multi-line doc comment + */ + #![doc = "inner doc attribute"] + #![allow(dead_code, unused_variables)] + #![no_std] + + /// outer single-line doc comment + /** + * outer multi-line doc comment + */ + #[doc = "outer doc attribute"] + #[doc = "macro"] + #[allow()] + #[repr(C)] + struct Struct; +} + +mod expressions { + /// ExprKind::Array + fn expr_array() { + []; + [true]; + [true]; + [true, true]; + ["long........................................................................"]; + ["long............................................................", + true]; + } + + /// ExprKind::ConstBlock + fn expr_const_block() { + const {}; + const { 1 }; + const { + struct S; + }; + } + + /// ExprKind::Call + fn expr_call() { + let f; + f(); + f::<u8>(); + f::<1>(); + f::<'static, u8, 1>(); + f(true); + f(true); + ()(); + } + + /// ExprKind::MethodCall + fn expr_method_call() { + let x; + x.f(); + x.f::<u8>(); + x.collect::<Vec<_>>(); + } + + /// ExprKind::Tup + fn expr_tup() { (); (true,); (true, false); (true, false); } + + /// ExprKind::Binary + fn expr_binary() { + let (a, b, c, d, x, y); + true || false; + true || false && false; + a < 1 && 2 < b && c > 3 && 4 > d; + a & b & !c; + a + b * c - d + -1 * -2 - -3; + x = !y; + } + + /// ExprKind::Unary + fn expr_unary() { let expr; *expr; !expr; -expr; } + + /// ExprKind::Lit + fn expr_lit() { 'x'; 1_000_i8; 1.00000000000000000000001; } + + /// ExprKind::Cast + fn expr_cast() { let expr; expr as T; expr as T<u8>; } + + /// ExprKind::Type + fn expr_type() { let expr; builtin # type_ascribe(expr, T); } + + /// ExprKind::Let + fn expr_let() { + let b; + if let Some(a) = b {} + if let _ = true && false {} + if let _ = (true && false) {} + } + + /// ExprKind::If + fn expr_if() { + if true {} + if !true {} + if let true = true {} else {} + if true {} else if false {} + if true {} else if false {} else {} + if true { return; } else if false { 0 } else { 0 } + } + + /// ExprKind::While + fn expr_while() { + while false {} + 'a: while false {} + while let true = true {} + } + + /// ExprKind::ForLoop + fn expr_for_loop() { let x; for _ in x {} 'a: for _ in x {} } + + /// ExprKind::Loop + fn expr_loop() { loop {} 'a: loop {} } + + /// ExprKind::Match + fn expr_match() { + let value; + match value {} + match value { ok => 1, } + match value { ok => 1, err => 0, } + } + + /// ExprKind::Closure + fn expr_closure() { + let value; + || {}; + |x| {}; + |x: u8| {}; + || (); + move || value; + async || value; + async move || value; + static || value; + static move || value; + (static async || value); + (static async move || value); + || -> u8 { value }; + 1 + (|| {}); + } + + /// ExprKind::Block + fn expr_block() { + {} + unsafe {} + 'a: {} + + #[allow()] + {} + { + #![allow()] + } + } + + /// ExprKind::Gen + fn expr_gen() { + async {}; + async move {}; + gen {}; + gen move {}; + async gen {}; + async gen move {}; + } + + /// ExprKind::Await + fn expr_await() { let fut; fut.await; } + + /// ExprKind::TryBlock + fn expr_try_block() { try {} try { return; } } + + /// ExprKind::Assign + fn expr_assign() { let expr; expr = true; } + + /// ExprKind::AssignOp + fn expr_assign_op() { let expr; expr += true; } + + /// ExprKind::Field + fn expr_field() { let expr; expr.field; expr.0; } + + /// ExprKind::Index + fn expr_index() { let expr; expr[true]; } + + /// ExprKind::Range + fn expr_range() { + let (lo, hi); + ..; + ..hi; + lo..; + lo..hi; + lo..hi; + ..=hi; + lo..=hi; + -2..=-1; + } + + /// ExprKind::Underscore + fn expr_underscore() { _; } + + /// ExprKind::Path + fn expr_path() { + let x; + crate::expressions::expr_path; + crate::expressions::expr_path::<'static>; + <T as Default>::default; + <T as ::core::default::Default>::default::<>; + x::(); + x::(T, T) -> T; + crate::() -> ()::expressions::() -> ()::expr_path; + core::()::marker::()::PhantomData; + } + + /// ExprKind::AddrOf + fn expr_addr_of() { + let expr; + &expr; + &mut expr; + &raw const expr; + &raw mut expr; + } + + /// ExprKind::Break + fn expr_break() { 'a: { break; break 'a; break true; break 'a true; } } + + /// ExprKind::Continue + fn expr_continue() { 'a: { continue; continue 'a; } } + + /// ExprKind::Ret + fn expr_ret() { return; return true; } + + /// ExprKind::InlineAsm + fn expr_inline_asm() { + let x; + asm!("mov {1}, {0}\nshl {1}, 1\nshl {0}, 2\nadd {0}, {1}", + inout(reg) + x, + out(reg) + _); + } + + /// ExprKind::OffsetOf + fn expr_offset_of() { + + + + + + + + + + + + + + + + + + + + // ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { builtin # offset_of(T, field) }; + } + /// ExprKind::MacCall + fn expr_mac_call() { "..."; "..."; "..."; } + /// ExprKind::Struct + fn expr_struct() { + struct Struct {} + let (x, base); + Struct {}; + <Struct as ToOwned>::Owned {}; + Struct { .. }; + Struct { ..base }; + Struct { x }; + Struct { x, ..base }; + Struct { x: true }; + Struct { x: true, .. }; + Struct { x: true, ..base }; + Struct { 0: true, ..base }; + } + /// ExprKind::Repeat + fn expr_repeat() { [(); 0]; } + /// ExprKind::Paren + fn expr_paren() { let expr; (expr); } + /// ExprKind::Try + fn expr_try() { let expr; expr?; } + /// ExprKind::Yield + fn expr_yield() { yield; yield true; } + /// ExprKind::Yeet + fn expr_yeet() { do yeet; do yeet 0; } + /// ExprKind::Become + fn expr_become() { become true; } + /// ExprKind::IncludedBytes + fn expr_include_bytes() { + b"data for include_bytes in ../expanded-exhaustive.rs\n"; + } + /// ExprKind::FormatArgs + fn expr_format_args() { + let expr; + format_args!(""); + format_args!("{0}", expr); + } +} +mod items { + /// ItemKind::ExternCrate + mod item_extern_crate { + extern crate core; + extern crate self as unpretty; + pub extern crate core as _; + } + /// ItemKind::Use + mod item_use { + use crate::{expressions, items::item_use}; + pub use core::*; + } + /// ItemKind::Static + mod item_static { + pub static A: () = {}; + static mut B: () = {}; + } + /// ItemKind::Const + mod item_const { + pub const A: () = {}; + trait TraitItems { + const B: (); + const C: () = {}; + } + } + /// ItemKind::Fn + mod item_fn { + pub const unsafe extern "C" fn f() {} + pub async unsafe extern fn g() {} + fn h<'a, T>() where T: 'a {} + trait TraitItems { + unsafe extern fn f(); + } + impl TraitItems for _ { + default unsafe extern fn f() {} + } + } + /// ItemKind::Mod + mod item_mod { } + /// ItemKind::ForeignMod + mod item_foreign_mod { + extern "C++" {} + extern {} + } + /// ItemKind::GlobalAsm + mod item_global_asm { + global_asm! (".globl my_asm_func"); + } + /// ItemKind::TyAlias + mod item_ty_alias { + pub type Type<'a> where T: 'a = T; + } + /// ItemKind::Enum + mod item_enum { + pub enum Void {} + enum Empty { Unit, Tuple(), Struct {}, } + enum Generic<'a, T> where T: 'a { + Tuple(T), + Struct { + t: T, + }, + } + } + /// ItemKind::Struct + mod item_struct { + pub struct Unit; + struct Tuple(); + struct Newtype(Unit); + struct Struct {} + struct Generic<'a, T> where T: 'a { + t: T, + } + } + /// ItemKind::Union + mod item_union { + union Generic<'a, T> where T: 'a { + t: T, + } + } + /// ItemKind::Trait + mod item_trait { + pub unsafe auto trait Send {} + trait Trait<'a>: Sized where Self: 'a {} + } + /// ItemKind::TraitAlias + mod item_trait_alias { + pub trait Trait<T> = Sized where for<'a> T: 'a; + } + /// ItemKind::Impl + mod item_impl { + impl () {} + impl<T> () {} + impl Default for () {} + impl<T> const Default for () {} + } + /// ItemKind::MacCall + mod item_mac_call { } + /// ItemKind::MacroDef + mod item_macro_def { + macro_rules! mac { () => { ... }; } + pub macro stringify { () => {} } + } + /// ItemKind::Delegation + mod item_delegation { + /*! FIXME: todo */ + } + /// ItemKind::DelegationMac + mod item_delegation_mac { + /*! FIXME: todo */ + } +} +mod patterns { + /// PatKind::Wild + fn pat_wild() { let _; } + /// PatKind::Ident + fn pat_ident() { + let x; + let ref x; + let mut x; + let ref mut x; + let ref mut x @ _; + } + /// PatKind::Struct + fn pat_struct() { + let T {}; + let T::<T> {}; + let T::<'static> {}; + let T { x }; + let T { x: _x }; + let T { .. }; + let T { x, .. }; + let T { x: _x, .. }; + let T { 0: _x, .. }; + let <T as ToOwned>::Owned {}; + } + /// PatKind::TupleStruct + fn pat_tuple_struct() { + struct Tuple(); + let Tuple(); + let Tuple::<T>(); + let Tuple::<'static>(); + let Tuple(x); + let Tuple(..); + let Tuple(x, ..); + } + /// PatKind::Or + fn pat_or() { let (true | false); let (true); let (true | false); } + /// PatKind::Path + fn pat_path() { + let core::marker::PhantomData; + let core::marker::PhantomData::<T>; + let core::marker::PhantomData::<'static>; + let <T as Trait>::CONST; + } + /// PatKind::Tuple + fn pat_tuple() { let (); let (true,); let (true, false); } + /// PatKind::Box + fn pat_box() { let box pat; } + /// PatKind::Deref + fn pat_deref() { let deref!(pat); } + /// PatKind::Ref + fn pat_ref() { let &pat; let &mut pat; } + /// PatKind::Lit + fn pat_lit() { let 1_000_i8; let -""; } + /// PatKind::Range + fn pat_range() { let ..1; let 0..; let 0..1; let 0..=1; let -2..=-1; } + /// PatKind::Slice + fn pat_slice() { let []; let [true]; let [true]; let [true, false]; } + /// PatKind::Rest + fn pat_rest() { let ..; } + /// PatKind::Never + fn pat_never() { let !; let Some(!); } + /// PatKind::Paren + fn pat_paren() { let (pat); } + /// PatKind::MacCall + fn pat_mac_call() { let ""; let ""; let ""; } +} +mod statements { + /// StmtKind::Let + fn stmt_let() { + let _; + let _ = true; + let _: T = true; + let _ = true else { return; }; + } + /// StmtKind::Item + fn stmt_item() { + struct Struct {} + struct Unit; + } + /// StmtKind::Expr + fn stmt_expr() { () } + /// StmtKind::Semi + fn stmt_semi() { 1 + 1; } + /// StmtKind::Empty + fn stmt_empty() { ; } + /// StmtKind::MacCall + fn stmt_mac_call() { "..."; "..."; "..."; } +} +mod types { + /// TyKind::Slice + fn ty_slice() { let _: [T]; } + /// TyKind::Array + fn ty_array() { let _: [T; 0]; } + /// TyKind::Ptr + fn ty_ptr() { let _: *const T; let _: *mut T; } + /// TyKind::Ref + fn ty_ref() { + let _: &T; + let _: &mut T; + let _: &'static T; + let _: &'static mut [T]; + let _: &T<T<T<T<T>>>>; + let _: &T<T<T<T<T>>>>; + } + /// TyKind::BareFn + fn ty_bare_fn() { + let _: fn(); + let _: fn() -> (); + let _: fn(T); + let _: fn(t: T); + let _: fn(); + let _: for<'a> fn(); + } + /// TyKind::Never + fn ty_never() { let _: !; } + /// TyKind::Tup + fn ty_tup() { let _: (); let _: (T,); let _: (T, T); } + /// TyKind::AnonStruct + fn ty_anon_struct() { + struct Struct { + _: struct { + t: T, + }, + } + } + /// TyKind::AnonUnion + fn ty_anon_union() { + struct Struct { + _: union { + t: T, + }, + } + } + /// TyKind::Path + fn ty_path() { + let _: T; + let _: T<'static>; + let _: T<T>; + let _: T<T>; + let _: T() -> !; + let _: <T as ToOwned>::Owned; + } + /// TyKind::TraitObject + fn ty_trait_object() { + let _: dyn Send; + let _: dyn Send + 'static; + let _: dyn 'static + Send; + let _: dyn for<'a> Send; + } + /// TyKind::ImplTrait + const fn ty_impl_trait() { + let _: impl Send; + let _: impl Send + 'static; + let _: impl 'static + Send; + let _: impl ?Sized; + let _: impl ~const Clone; + let _: impl for<'a> Send; + } + /// TyKind::Paren + fn ty_paren() { let _: (T); } + /// TyKind::Typeof + fn ty_typeof() { + /*! unused for now */ + } + /// TyKind::Infer + fn ty_infer() { let _: _; } + /// TyKind::ImplicitSelf + fn ty_implicit_self() { + /*! there is no syntax for this */ + } + /// TyKind::MacCall + fn ty_mac_call() { let _: T; let _: T; let _: T; } + /// TyKind::CVarArgs + fn ty_c_var_args() { + /*! FIXME: todo */ + } + /// TyKind::Pat + fn ty_pat() { let _: u32 is 1..; } +} +mod visibilities { + /// VisibilityKind::Public + mod visibility_public { + pub struct Pub; + } + /// VisibilityKind::Restricted + mod visibility_restricted { + pub(crate) struct PubCrate; + pub(self) struct PubSelf; + pub(super) struct PubSuper; + pub(in crate) struct PubInCrate; + pub(in self) struct PubInSelf; + pub(in super) struct PubInSuper; + pub(in crate::visibilities) struct PubInCrateVisibilities; + pub(in self::super) struct PubInSelfSuper; + pub(in super::visibility_restricted) struct PubInSuperMod; + } +} diff --git a/tests/ui/unpretty/expanded-interpolation.rs b/tests/ui/unpretty/expanded-interpolation.rs new file mode 100644 index 00000000000..8f0e21ce870 --- /dev/null +++ b/tests/ui/unpretty/expanded-interpolation.rs @@ -0,0 +1,106 @@ +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +// This test covers the AST pretty-printer's insertion of parentheses in some +// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in +// the syntax tree) need to be printed in order for the printed code to be valid +// Rust syntax. We also test negative cases: the pretty-printer should not be +// synthesizing parentheses indiscriminately; only where necessary. + +#![feature(let_chains)] +#![feature(if_let_guard)] + +macro_rules! expr { + ($expr:expr) => { $expr }; +} + +macro_rules! stmt { + ($stmt:stmt) => { $stmt }; +} + +fn if_let() { + macro_rules! if_let { + ($pat:pat, $expr:expr) => { + if let $pat = $expr {} + }; + } + + if let no_paren = true && false {} + if_let!(paren_around_binary, true && false); + if_let!(no_paren, true); + + struct Struct {} + match () { + _ if let no_paren = Struct {} => {} + } +} + +fn let_else() { + let no_paren = expr!(1 + 1) else { return; }; + let paren_around_loop = expr!(loop {}) else { return; }; +} + +fn local() { + macro_rules! let_expr_minus_one { + ($pat:pat, $expr:expr) => { + let $pat = $expr - 1; + }; + } + + let void; + let_expr_minus_one!(no_paren, match void {}); + + macro_rules! let_expr_else_return { + ($pat:pat, $expr:expr) => { + let $pat = $expr else { return; }; + }; + } + + let_expr_else_return!(no_paren, void()); +} + +fn match_arm() { + macro_rules! match_arm { + ($pat:pat, $expr:expr) => { + match () { $pat => $expr } + }; + } + + match_arm!(no_paren, 1 - 1); + match_arm!(paren_around_brace, { 1 } - 1); +} + +/// https://github.com/rust-lang/rust/issues/98790 +fn stmt_boundary() { + macro_rules! expr_as_stmt { + ($expr:expr) => { + stmt!($expr) + }; + } + + let paren_around_match; + expr_as_stmt!(match paren_around_match {} | true); + + macro_rules! minus_one { + ($expr:expr) => { + expr_as_stmt!($expr - 1) + }; + } + + let (no_paren, paren_around_loop); + minus_one!(no_paren); + minus_one!(match paren_around_match {}); + minus_one!(match paren_around_match {}()); + minus_one!(match paren_around_match {}[0]); + minus_one!(loop { break paren_around_loop; }); +} + +fn vis_inherited() { + macro_rules! vis_inherited { + ($vis:vis struct) => { + $vis struct Struct; + }; + } + + vis_inherited!(struct); +} diff --git a/tests/ui/unpretty/expanded-interpolation.stdout b/tests/ui/unpretty/expanded-interpolation.stdout new file mode 100644 index 00000000000..73322b50f2d --- /dev/null +++ b/tests/ui/unpretty/expanded-interpolation.stdout @@ -0,0 +1,92 @@ +#![feature(prelude_import)] +#![no_std] +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +// This test covers the AST pretty-printer's insertion of parentheses in some +// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in +// the syntax tree) need to be printed in order for the printed code to be valid +// Rust syntax. We also test negative cases: the pretty-printer should not be +// synthesizing parentheses indiscriminately; only where necessary. + +#![feature(let_chains)] +#![feature(if_let_guard)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +macro_rules! expr { ($expr:expr) => { $expr }; } + +macro_rules! stmt { ($stmt:stmt) => { $stmt }; } + +fn if_let() { + macro_rules! if_let { + ($pat:pat, $expr:expr) => { if let $pat = $expr {} }; + } + + if let no_paren = true && false {} + if let paren_around_binary = (true && false) {}; + if let no_paren = true {}; + + struct Struct {} + match () { _ if let no_paren = Struct {} => {} } +} + +fn let_else() { + let no_paren = 1 + 1 else { return; }; + let paren_around_loop = (loop {}) else { return; }; +} + +fn local() { + macro_rules! let_expr_minus_one { + ($pat:pat, $expr:expr) => { let $pat = $expr - 1; }; + } + + let void; + let no_paren = match void {} - 1; + + macro_rules! let_expr_else_return { + ($pat:pat, $expr:expr) => { let $pat = $expr else { return; }; }; + } + let + + no_paren = void() else { return; }; +} + +fn match_arm() { + macro_rules! match_arm { + ($pat:pat, $expr:expr) => { match () { $pat => $expr } }; + } + match () { + + + no_paren => 1 - 1, + }; + match () { paren_around_brace => ({ 1 }) - 1, }; +} + +/// https://github.com/rust-lang/rust/issues/98790 +fn stmt_boundary() { + macro_rules! expr_as_stmt { ($expr:expr) => { stmt!($expr) }; } + + let paren_around_match; + (match paren_around_match {}) | true; + + macro_rules! minus_one { ($expr:expr) => { expr_as_stmt!($expr - 1) }; } + + let (no_paren, paren_around_loop); + no_paren - 1; + (match paren_around_match {}) - 1; + (match paren_around_match {})() - 1; + (match paren_around_match {})[0] - 1; + (loop { break paren_around_loop; }) - 1; +} + +fn vis_inherited() { + macro_rules! vis_inherited { + ($vis:vis struct) => { $vis struct Struct; }; + } + struct Struct; + +} diff --git a/tests/ui/unpretty/let-else.rs b/tests/ui/unpretty/let-else.rs deleted file mode 100644 index 4db6eca99b1..00000000000 --- a/tests/ui/unpretty/let-else.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ compile-flags: -Zunpretty=expanded -//@ check-pass - -macro_rules! expr { - ($e:expr) => { $e }; -} - -fn main() { - let _ = expr!(1 + 1) else { return; }; - let _ = expr!(loop {}) else { return; }; -} diff --git a/tests/ui/unpretty/let-else.stdout b/tests/ui/unpretty/let-else.stdout deleted file mode 100644 index 4bc4d9e085f..00000000000 --- a/tests/ui/unpretty/let-else.stdout +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(prelude_import)] -#![no_std] -#[prelude_import] -use ::std::prelude::rust_2015::*; -#[macro_use] -extern crate std; -//@ compile-flags: -Zunpretty=expanded -//@ check-pass - -macro_rules! expr { ($e:expr) => { $e }; } - -fn main() { - let _ = 1 + 1 else { return; }; - let _ = (loop {}) else { return; }; -} |
