diff options
| author | bors <bors@rust-lang.org> | 2024-11-12 05:51:31 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-11-12 05:51:31 +0000 |
| commit | 9a9daddd0dacfe8c5e8eaa07cfd054a3631bcde7 (patch) | |
| tree | 6c6eced9db68af0b60126546d65467b5f899c942 /tests | |
| parent | 67f21277cd40cd12e69aa34089f4a20926fd6dc5 (diff) | |
| parent | 506f52c7f3ecbd42e163b1577f1d4e0a2f84c8d3 (diff) | |
| download | rust-9a9daddd0dacfe8c5e8eaa07cfd054a3631bcde7.tar.gz rust-9a9daddd0dacfe8c5e8eaa07cfd054a3631bcde7.zip | |
Auto merge of #132940 - matthiaskrgr:rollup-f0czmkq, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #132487 (Provide placeholder generics for traits in "no method found for type parameter" suggestions) - #132627 (cleanup: Remove outdated comment of `thir_body`) - #132653 (Don't use `maybe_unwrap_block` when checking for macro calls in a block expr) - #132793 (Update mdbook to 0.4.42) - #132847 (elem_offset / subslice_range: use addr() instead of 'as usize') - #132869 (split up the first paragraph of doc comments for better summaries) - #132929 (Check for null in the `alloc_zeroed` example) - #132933 (Make sure that we suggest turbofishing the right type arg for never suggestion) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'tests')
10 files changed, 635 insertions, 22 deletions
diff --git a/tests/crashes/131915.rs b/tests/crashes/131915.rs deleted file mode 100644 index 58d45adcb3b..00000000000 --- a/tests/crashes/131915.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #131915 - -macro_rules! y { - ( $($matcher:tt)*) => { - x - }; -} - -const _: A< - { - y! { test.tou8 } - }, ->; diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs new file mode 100644 index 00000000000..bce7ac5708a --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs @@ -0,0 +1,20 @@ +// Regression test for #131915 where we did not handle macro calls as +// statements correctly when determining if a const argument should +// have a `DefId` created or not. + +macro_rules! y { + ( $($matcher:tt)*) => { + x + //~^ ERROR: cannot find value `x` in this scope + }; +} + +const _: A< + //~^ ERROR: free constant item without body + //~| ERROR: cannot find type `A` in this scope + { + y! { test.tou8 } + }, +>; + +fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr new file mode 100644 index 00000000000..a3211b77623 --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr @@ -0,0 +1,39 @@ +error: free constant item without body + --> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1 + | +LL | / const _: A< +LL | | +LL | | +LL | | { +LL | | y! { test.tou8 } +LL | | }, +LL | | >; + | | ^ help: provide a definition for the constant: `= <expr>;` + | |__| + | + +error[E0412]: cannot find type `A` in this scope + --> $DIR/const_arg_trivial_macro_expansion-2.rs:12:10 + | +LL | const _: A< + | ^ not found in this scope + +error[E0425]: cannot find value `x` in this scope + --> $DIR/const_arg_trivial_macro_expansion-2.rs:7:9 + | +LL | x + | ^ not found in this scope +... +LL | y! { test.tou8 } + | ---------------- in this macro invocation + | + = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might be missing a const parameter + | +LL | const _<const x: /* Type */>: A< + | +++++++++++++++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs new file mode 100644 index 00000000000..2fdd703ab6f --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs @@ -0,0 +1,366 @@ +//@ known-bug: #132647 +//@ dont-check-compiler-stderr +#![allow(unused_braces)] + +// FIXME(bootstrap): This isn't a known bug, we just don't want to write any error annotations. +// this is hard because macro expansion errors have their span be inside the *definition* of the +// macro rather than the line *invoking* it. This means we would wind up with hundreds of error +// annotations on the macro definitions below rather than on any of the actual lines +// that act as a "test". +// +// It's also made more complicated by the fact that compiletest generates "extra" expected +// notes to give an assertable macro backtrace as otherwise there would *nothing* to annotate +// on the actual test lines. All of these extra notes result in needing to write hundreds of +// unnecessary notes on almost every line in this file. +// +// Even though this is marked `known-bug` it should still fail if this test starts ICEing which +// is "enough" in this case. + +// Test that we correctly create definitions for anon consts even when +// the trivial-ness of the expression is obscured by macro expansions. +// +// Acts as a regression test for: #131915 130321 128016 + +// macros expanding to idents + +macro_rules! unbraced_ident { + () => { + ident + }; +} + +macro_rules! braced_ident { + () => {{ ident }}; +} + +macro_rules! unbraced_unbraced_ident { + () => { + unbraced_ident!() + }; +} + +macro_rules! braced_unbraced_ident { + () => {{ unbraced_ident!() }}; +} + +macro_rules! unbraced_braced_ident { + () => { + braced_ident!() + }; +} + +macro_rules! braced_braced_ident { + () => {{ braced_ident!() }}; +} + +// macros expanding to complex expr + +macro_rules! unbraced_expr { + () => { + ident.other + }; +} + +macro_rules! braced_expr { + () => {{ ident.otherent }}; +} + +macro_rules! unbraced_unbraced_expr { + () => { + unbraced_expr!() + }; +} + +macro_rules! braced_unbraced_expr { + () => {{ unbraced_expr!() }}; +} + +macro_rules! unbraced_braced_expr { + () => { + braced_expr!() + }; +} + +macro_rules! braced_braced_expr { + () => {{ braced_expr!() }}; +} + +#[rustfmt::skip] +mod array_paren_call { + // Arrays where the expanded result is a `Res::Err` + fn array_0() -> [(); unbraced_unbraced_ident!()] { loop {} } + fn array_1() -> [(); braced_unbraced_ident!()] { loop {} } + fn array_2() -> [(); unbraced_braced_ident!()] { loop {} } + fn array_3() -> [(); braced_braced_ident!()] { loop {} } + fn array_4() -> [(); { unbraced_unbraced_ident!() }] { loop {} } + fn array_5() -> [(); { braced_unbraced_ident!() }] { loop {} } + fn array_6() -> [(); { unbraced_braced_ident!() }] { loop {} } + fn array_7() -> [(); { braced_braced_ident!() }] { loop {} } + fn array_8() -> [(); unbraced_ident!()] { loop {} } + fn array_9() -> [(); braced_ident!()] { loop {} } + fn array_10() -> [(); { unbraced_ident!() }] { loop {} } + fn array_11() -> [(); { braced_ident!() }] { loop {} } + + // Arrays where the expanded result is a `Res::ConstParam` + fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!()] { loop {} } + fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!()] { loop {} } + fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!()] { loop {} } + fn array_15<const ident: usize>() -> [(); braced_braced_ident!()] { loop {} } + fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!() }] { loop {} } + fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!() }] { loop {} } + fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!() }] { loop {} } + fn array_19<const ident: usize>() -> [(); { braced_braced_ident!() }] { loop {} } + fn array_20<const ident: usize>() -> [(); unbraced_ident!()] { loop {} } + fn array_21<const ident: usize>() -> [(); braced_ident!()] { loop {} } + fn array_22<const ident: usize>() -> [(); { unbraced_ident!() }] { loop {} } + fn array_23<const ident: usize>() -> [(); { braced_ident!() }] { loop {} } + + // Arrays where the expanded result is a complex expr + fn array_24() -> [(); unbraced_unbraced_expr!()] { loop {} } + fn array_25() -> [(); braced_unbraced_expr!()] { loop {} } + fn array_26() -> [(); unbraced_braced_expr!()] { loop {} } + fn array_27() -> [(); braced_braced_expr!()] { loop {} } + fn array_28() -> [(); { unbraced_unbraced_expr!() }] { loop {} } + fn array_29() -> [(); { braced_unbraced_expr!() }] { loop {} } + fn array_30() -> [(); { unbraced_braced_expr!() }] { loop {} } + fn array_31() -> [(); { braced_braced_expr!() }] { loop {} } + fn array_32() -> [(); unbraced_expr!()] { loop {} } + fn array_33() -> [(); braced_expr!()] { loop {} } + fn array_34() -> [(); { unbraced_expr!() }] { loop {} } + fn array_35() -> [(); { braced_expr!() }] { loop {} } +} + +#[rustfmt::skip] +mod array_brace_call { + // Arrays where the expanded result is a `Res::Err` + fn array_0() -> [(); unbraced_unbraced_ident!{}] { loop {} } + fn array_1() -> [(); braced_unbraced_ident!{}] { loop {} } + fn array_2() -> [(); unbraced_braced_ident!{}] { loop {} } + fn array_3() -> [(); braced_braced_ident!{}] { loop {} } + fn array_4() -> [(); { unbraced_unbraced_ident!{} }] { loop {} } + fn array_5() -> [(); { braced_unbraced_ident!{} }] { loop {} } + fn array_6() -> [(); { unbraced_braced_ident!{} }] { loop {} } + fn array_7() -> [(); { braced_braced_ident!{} }] { loop {} } + fn array_8() -> [(); unbraced_ident!{}] { loop {} } + fn array_9() -> [(); braced_ident!{}] { loop {} } + fn array_10() -> [(); { unbraced_ident!{} }] { loop {} } + fn array_11() -> [(); { braced_ident!{} }] { loop {} } + + // Arrays where the expanded result is a `Res::ConstParam` + fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!{}] { loop {} } + fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!{}] { loop {} } + fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!{}] { loop {} } + fn array_15<const ident: usize>() -> [(); braced_braced_ident!{}] { loop {} } + fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!{} }] { loop {} } + fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!{} }] { loop {} } + fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!{} }] { loop {} } + fn array_19<const ident: usize>() -> [(); { braced_braced_ident!{} }] { loop {} } + fn array_20<const ident: usize>() -> [(); unbraced_ident!{}] { loop {} } + fn array_21<const ident: usize>() -> [(); braced_ident!{}] { loop {} } + fn array_22<const ident: usize>() -> [(); { unbraced_ident!{} }] { loop {} } + fn array_23<const ident: usize>() -> [(); { braced_ident!{} }] { loop {} } + + // Arrays where the expanded result is a complex expr + fn array_24() -> [(); unbraced_unbraced_expr!{}] { loop {} } + fn array_25() -> [(); braced_unbraced_expr!{}] { loop {} } + fn array_26() -> [(); unbraced_braced_expr!{}] { loop {} } + fn array_27() -> [(); braced_braced_expr!{}] { loop {} } + fn array_28() -> [(); { unbraced_unbraced_expr!{} }] { loop {} } + fn array_29() -> [(); { braced_unbraced_expr!{} }] { loop {} } + fn array_30() -> [(); { unbraced_braced_expr!{} }] { loop {} } + fn array_31() -> [(); { braced_braced_expr!{} }] { loop {} } + fn array_32() -> [(); unbraced_expr!{}] { loop {} } + fn array_33() -> [(); braced_expr!{}] { loop {} } + fn array_34() -> [(); { unbraced_expr!{} }] { loop {} } + fn array_35() -> [(); { braced_expr!{} }] { loop {} } +} + +#[rustfmt::skip] +mod array_square_call { + // Arrays where the expanded result is a `Res::Err` + fn array_0() -> [(); unbraced_unbraced_ident![]] { loop {} } + fn array_1() -> [(); braced_unbraced_ident![]] { loop {} } + fn array_2() -> [(); unbraced_braced_ident![]] { loop {} } + fn array_3() -> [(); braced_braced_ident![]] { loop {} } + fn array_4() -> [(); { unbraced_unbraced_ident![] }] { loop {} } + fn array_5() -> [(); { braced_unbraced_ident![] }] { loop {} } + fn array_6() -> [(); { unbraced_braced_ident![] }] { loop {} } + fn array_7() -> [(); { braced_braced_ident![] }] { loop {} } + fn array_8() -> [(); unbraced_ident![]] { loop {} } + fn array_9() -> [(); braced_ident![]] { loop {} } + fn array_10() -> [(); { unbraced_ident![] }] { loop {} } + fn array_11() -> [(); { braced_ident![] }] { loop {} } + + // Arrays where the expanded result is a `Res::ConstParam` + fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident![]] { loop {} } + fn array_13<const ident: usize>() -> [(); braced_unbraced_ident![]] { loop {} } + fn array_14<const ident: usize>() -> [(); unbraced_braced_ident![]] { loop {} } + fn array_15<const ident: usize>() -> [(); braced_braced_ident![]] { loop {} } + fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident![] }] { loop {} } + fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident![] }] { loop {} } + fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident![] }] { loop {} } + fn array_19<const ident: usize>() -> [(); { braced_braced_ident![] }] { loop {} } + fn array_20<const ident: usize>() -> [(); unbraced_ident![]] { loop {} } + fn array_21<const ident: usize>() -> [(); braced_ident![]] { loop {} } + fn array_22<const ident: usize>() -> [(); { unbraced_ident![] }] { loop {} } + fn array_23<const ident: usize>() -> [(); { braced_ident![] }] { loop {} } + + // Arrays where the expanded result is a complex expr + fn array_24() -> [(); unbraced_unbraced_expr![]] { loop {} } + fn array_25() -> [(); braced_unbraced_expr![]] { loop {} } + fn array_26() -> [(); unbraced_braced_expr![]] { loop {} } + fn array_27() -> [(); braced_braced_expr![]] { loop {} } + fn array_28() -> [(); { unbraced_unbraced_expr![] }] { loop {} } + fn array_29() -> [(); { braced_unbraced_expr![] }] { loop {} } + fn array_30() -> [(); { unbraced_braced_expr![] }] { loop {} } + fn array_31() -> [(); { braced_braced_expr![] }] { loop {} } + fn array_32() -> [(); unbraced_expr![]] { loop {} } + fn array_33() -> [(); braced_expr![]] { loop {} } + fn array_34() -> [(); { unbraced_expr![] }] { loop {} } + fn array_35() -> [(); { braced_expr![] }] { loop {} } +} + +struct Foo<const N: usize>; + +#[rustfmt::skip] +mod adt_paren_call { + use super::Foo; + + // An ADT where the expanded result is a `Res::Err` + fn adt_0() -> Foo<unbraced_unbraced_ident!()> { loop {} } + fn adt_1() -> Foo<braced_unbraced_ident!()> { loop {} } + fn adt_2() -> Foo<unbraced_braced_ident!()> { loop {} } + fn adt_3() -> Foo<braced_braced_ident!()> { loop {} } + fn adt_4() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} } + fn adt_5() -> Foo<{ braced_unbraced_ident!() }> { loop {} } + fn adt_6() -> Foo<{ unbraced_braced_ident!() }> { loop {} } + fn adt_7() -> Foo<{ braced_braced_ident!() }> { loop {} } + fn adt_8() -> Foo<unbraced_ident!()> { loop {} } + fn adt_9() -> Foo<braced_ident!()> { loop {} } + fn adt_10() -> Foo<{ unbraced_ident!() }> { loop {} } + fn adt_11() -> Foo<{ braced_ident!() }> { loop {} } + + // An ADT where the expanded result is a `Res::ConstParam` + fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!()> { loop {} } + fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!()> { loop {} } + fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!()> { loop {} } + fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!()> { loop {} } + fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} } + fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!() }> { loop {} } + fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!() }> { loop {} } + fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!() }> { loop {} } + fn adt_20<const ident: usize>() -> Foo<unbraced_ident!()> { loop {} } + fn adt_21<const ident: usize>() -> Foo<braced_ident!()> { loop {} } + fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!() }> { loop {} } + fn adt_23<const ident: usize>() -> Foo<{ braced_ident!() }> { loop {} } + + // An ADT where the expanded result is a complex expr + fn array_24() -> Foo<unbraced_unbraced_expr!()> { loop {} } + fn array_25() -> Foo<braced_unbraced_expr!()> { loop {} } + fn array_26() -> Foo<unbraced_braced_expr!()> { loop {} } + fn array_27() -> Foo<braced_braced_expr!()> { loop {} } + fn array_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} } + fn array_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} } + fn array_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} } + fn array_31() -> Foo<{ braced_braced_expr!() }> { loop {} } + fn array_32() -> Foo<unbraced_expr!()> { loop {} } + fn array_33() -> Foo<braced_expr!()> { loop {} } + fn array_34() -> Foo<{ unbraced_expr!() }> { loop {} } + fn array_35() -> Foo<{ braced_expr!() }> { loop {} } +} + +#[rustfmt::skip] +mod adt_brace_call { + use super::Foo; + + // An ADT where the expanded result is a `Res::Err` + fn adt_0() -> Foo<unbraced_unbraced_ident!{}> { loop {} } + fn adt_1() -> Foo<braced_unbraced_ident!{}> { loop {} } + fn adt_2() -> Foo<unbraced_braced_ident!{}> { loop {} } + fn adt_3() -> Foo<braced_braced_ident!{}> { loop {} } + fn adt_4() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} } + fn adt_5() -> Foo<{ braced_unbraced_ident!{} }> { loop {} } + fn adt_6() -> Foo<{ unbraced_braced_ident!{} }> { loop {} } + fn adt_7() -> Foo<{ braced_braced_ident!{} }> { loop {} } + fn adt_8() -> Foo<unbraced_ident!{}> { loop {} } + fn adt_9() -> Foo<braced_ident!{}> { loop {} } + fn adt_10() -> Foo<{ unbraced_ident!{} }> { loop {} } + fn adt_11() -> Foo<{ braced_ident!{} }> { loop {} } + + // An ADT where the expanded result is a `Res::ConstParam` + fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!{}> { loop {} } + fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!{}> { loop {} } + fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!{}> { loop {} } + fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!{}> { loop {} } + fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} } + fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!{} }> { loop {} } + fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!{} }> { loop {} } + fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!{} }> { loop {} } + fn adt_20<const ident: usize>() -> Foo<unbraced_ident!{}> { loop {} } + fn adt_21<const ident: usize>() -> Foo<braced_ident!{}> { loop {} } + fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!{} }> { loop {} } + fn adt_23<const ident: usize>() -> Foo<{ braced_ident!{} }> { loop {} } + + // An ADT where the expanded result is a complex expr + fn array_24() -> Foo<unbraced_unbraced_expr!{}> { loop {} } + fn array_25() -> Foo<braced_unbraced_expr!{}> { loop {} } + fn array_26() -> Foo<unbraced_braced_expr!{}> { loop {} } + fn array_27() -> Foo<braced_braced_expr!{}> { loop {} } + fn array_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} } + fn array_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} } + fn array_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} } + fn array_31() -> Foo<{ braced_braced_expr!{} }> { loop {} } + fn array_32() -> Foo<unbraced_expr!{}> { loop {} } + fn array_33() -> Foo<braced_expr!{}> { loop {} } + fn array_34() -> Foo<{ unbraced_expr!{} }> { loop {} } + fn array_35() -> Foo<{ braced_expr!{} }> { loop {} } +} + +#[rustfmt::skip] +mod adt_square_call { + use super::Foo; + + // An ADT where the expanded result is a `Res::Err` + fn adt_0() -> Foo<unbraced_unbraced_ident![]> { loop {} } + fn adt_1() -> Foo<braced_unbraced_ident![]> { loop {} } + fn adt_2() -> Foo<unbraced_braced_ident![]> { loop {} } + fn adt_3() -> Foo<braced_braced_ident![]> { loop {} } + fn adt_4() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} } + fn adt_5() -> Foo<{ braced_unbraced_ident![] }> { loop {} } + fn adt_6() -> Foo<{ unbraced_braced_ident![] }> { loop {} } + fn adt_7() -> Foo<{ braced_braced_ident![] }> { loop {} } + fn adt_8() -> Foo<unbraced_ident![]> { loop {} } + fn adt_9() -> Foo<braced_ident![]> { loop {} } + fn adt_10() -> Foo<{ unbraced_ident![] }> { loop {} } + fn adt_11() -> Foo<{ braced_ident![] }> { loop {} } + + // An ADT where the expanded result is a `Res::ConstParam` + fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident![]> { loop {} } + fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident![]> { loop {} } + fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident![]> { loop {} } + fn adt_15<const ident: usize>() -> Foo<braced_braced_ident![]> { loop {} } + fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} } + fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident![] }> { loop {} } + fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident![] }> { loop {} } + fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident![] }> { loop {} } + fn adt_20<const ident: usize>() -> Foo<unbraced_ident![]> { loop {} } + fn adt_21<const ident: usize>() -> Foo<braced_ident![]> { loop {} } + fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident![] }> { loop {} } + fn adt_23<const ident: usize>() -> Foo<{ braced_ident![] }> { loop {} } + + // An ADT where the expanded result is a complex expr + fn array_24() -> Foo<unbraced_unbraced_expr![]> { loop {} } + fn array_25() -> Foo<braced_unbraced_expr![]> { loop {} } + fn array_26() -> Foo<unbraced_braced_expr![]> { loop {} } + fn array_27() -> Foo<braced_braced_expr![]> { loop {} } + fn array_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} } + fn array_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} } + fn array_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} } + fn array_31() -> Foo<{ braced_braced_expr![] }> { loop {} } + fn array_32() -> Foo<unbraced_expr![]> { loop {} } + fn array_33() -> Foo<braced_expr![]> { loop {} } + fn array_34() -> Foo<{ unbraced_expr![] }> { loop {} } + fn array_35() -> Foo<{ braced_expr![] }> { loop {} } +} + +fn main() {} diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed new file mode 100644 index 00000000000..3fed16f0ee7 --- /dev/null +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed @@ -0,0 +1,52 @@ +//@ revisions: e2021 e2024 +// +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +// +//@[e2021] run-pass +//@[e2021] run-rustfix +//@[e2024] check-fail + +fn main() { + m(); + q(); + let _ = meow(); +} + +fn m() { + //[e2021]~^ this function depends on never type fallback being `()` + //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + let x: () = match true { + true => Default::default(), + //[e2024]~^ error: the trait bound `!: Default` is not satisfied + false => panic!("..."), + }; + + dbg!(x); +} + +fn q() -> Option<()> { + //[e2021]~^ this function depends on never type fallback being `()` + //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + fn deserialize<T: Default>() -> Option<T> { + Some(T::default()) + } + + deserialize::<()>()?; + //[e2024]~^ error: the trait bound `!: Default` is not satisfied + + None +} + +// Make sure we turbofish the right argument +fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> { + Err(()) +} +fn meow() -> Result<(), ()> { + //[e2021]~^ this function depends on never type fallback being `()` + //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + help::<(), _>(1)?; + //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied + Ok(()) +} diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 79eee2a3def..fdc97e54d4e 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -1,5 +1,5 @@ warning: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:15:1 + --> $DIR/never-type-fallback-breaking.rs:17:1 | LL | fn m() { | ^^^^^^ @@ -8,7 +8,7 @@ LL | fn m() { = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:19:17 + --> $DIR/never-type-fallback-breaking.rs:21:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let x: () = match true { | ++++ warning: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:27:1 + --> $DIR/never-type-fallback-breaking.rs:29:1 | LL | fn q() -> Option<()> { | ^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | fn q() -> Option<()> { = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:34:5 + --> $DIR/never-type-fallback-breaking.rs:36:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ @@ -37,5 +37,24 @@ help: use `()` annotations to avoid fallback changes LL | deserialize::<()>()?; | ++++++ -warning: 2 warnings emitted +warning: this function depends on never type fallback being `()` + --> $DIR/never-type-fallback-breaking.rs:46:1 + | +LL | fn meow() -> Result<(), ()> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the types explicitly +note: in edition 2024, the requirement `(): From<!>` will fail + --> $DIR/never-type-fallback-breaking.rs:49:5 + | +LL | help(1)?; + | ^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | help::<(), _>(1)?; + | +++++++++ + +warning: 3 warnings emitted diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr index 461e4ae0bdf..6258247f8b2 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:19:17 + --> $DIR/never-type-fallback-breaking.rs:21:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -8,7 +8,7 @@ LL | true => Default::default(), = help: did you intend to use the type `()` here instead? error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:34:5 + --> $DIR/never-type-fallback-breaking.rs:36:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -16,11 +16,34 @@ LL | deserialize()?; = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information) = help: did you intend to use the type `()` here instead? note: required by a bound in `deserialize` - --> $DIR/never-type-fallback-breaking.rs:30:23 + --> $DIR/never-type-fallback-breaking.rs:32:23 | LL | fn deserialize<T: Default>() -> Option<T> { | ^^^^^^^ required by this bound in `deserialize` -error: aborting due to 2 previous errors +error[E0277]: the trait bound `(): From<!>` is not satisfied + --> $DIR/never-type-fallback-breaking.rs:49:5 + | +LL | help(1)?; + | ^^^^^^^ the trait `From<!>` is not implemented for `()` + | + = help: the following other types implement trait `From<T>`: + `(T, T)` implements `From<[T; 2]>` + `(T, T, T)` implements `From<[T; 3]>` + `(T, T, T, T)` implements `From<[T; 4]>` + `(T, T, T, T, T)` implements `From<[T; 5]>` + `(T, T, T, T, T, T)` implements `From<[T; 6]>` + `(T, T, T, T, T, T, T)` implements `From<[T; 7]>` + `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>` + `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>` + and 4 others + = note: required for `!` to implement `Into<()>` +note: required by a bound in `help` + --> $DIR/never-type-fallback-breaking.rs:43:20 + | +LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> { + | ^^^^^^^^ required by this bound in `help` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs index 7b4a1b1de04..71d36f3a2d9 100644 --- a/tests/ui/editions/never-type-fallback-breaking.rs +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -5,11 +5,13 @@ //@[e2024] compile-flags: -Zunstable-options // //@[e2021] run-pass +//@[e2021] run-rustfix //@[e2024] check-fail fn main() { m(); q(); + let _ = meow(); } fn m() { @@ -36,3 +38,15 @@ fn q() -> Option<()> { None } + +// Make sure we turbofish the right argument +fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> { + Err(()) +} +fn meow() -> Result<(), ()> { + //[e2021]~^ this function depends on never type fallback being `()` + //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + help(1)?; + //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied + Ok(()) +} diff --git a/tests/ui/suggestions/no-method-found-suggest-trait-args.rs b/tests/ui/suggestions/no-method-found-suggest-trait-args.rs new file mode 100644 index 00000000000..d51f86b29e8 --- /dev/null +++ b/tests/ui/suggestions/no-method-found-suggest-trait-args.rs @@ -0,0 +1,30 @@ +/// Tests that suggestions to add trait bounds that would enable using a method include appropriate +/// placeholder arguments for that trait. + +trait Trait<I> { + fn method(&self) {} +} + +trait Trait2<'a, A, const B: u8, C = (), const D: u8 = 0> { + fn method2(&self) {} +} + +fn foo<T>(value: T) { + //~^ SUGGESTION : Trait</* I */> + //~| SUGGESTION : Trait2</* 'a, A, B */> + value.method(); + //~^ ERROR no method named `method` found for type parameter `T` in the current scope [E0599] + value.method2(); + //~^ ERROR no method named `method2` found for type parameter `T` in the current scope [E0599] +} + +fn bar(value: impl Copy) { + //~^ SUGGESTION + Trait</* I */> + //~| SUGGESTION + Trait2</* 'a, A, B */> + value.method(); + //~^ ERROR no method named `method` found for type parameter `impl Copy` in the current scope [E0599] + value.method2(); + //~^ ERROR no method named `method2` found for type parameter `impl Copy` in the current scope [E0599] +} + +fn main() {} diff --git a/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr b/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr new file mode 100644 index 00000000000..3dcd4667fa0 --- /dev/null +++ b/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr @@ -0,0 +1,63 @@ +error[E0599]: no method named `method` found for type parameter `T` in the current scope + --> $DIR/no-method-found-suggest-trait-args.rs:15:11 + | +LL | fn foo<T>(value: T) { + | - method `method` not found for this type parameter +... +LL | value.method(); + | ^^^^^^ method not found in `T` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it: + | +LL | fn foo<T: Trait</* I */>>(value: T) { + | ++++++++++++++++ + +error[E0599]: no method named `method2` found for type parameter `T` in the current scope + --> $DIR/no-method-found-suggest-trait-args.rs:17:11 + | +LL | fn foo<T>(value: T) { + | - method `method2` not found for this type parameter +... +LL | value.method2(); + | ^^^^^^^ method not found in `T` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `T` with it: + | +LL | fn foo<T: Trait2</* 'a, A, B */>>(value: T) { + | ++++++++++++++++++++++++ + +error[E0599]: no method named `method` found for type parameter `impl Copy` in the current scope + --> $DIR/no-method-found-suggest-trait-args.rs:24:11 + | +LL | fn bar(value: impl Copy) { + | --------- method `method` not found for this type parameter +... +LL | value.method(); + | ^^^^^^ method not found in `impl Copy` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method`, perhaps you need to restrict type parameter `impl Copy` with it: + | +LL | fn bar(value: impl Copy + Trait</* I */>) { + | ++++++++++++++++ + +error[E0599]: no method named `method2` found for type parameter `impl Copy` in the current scope + --> $DIR/no-method-found-suggest-trait-args.rs:26:11 + | +LL | fn bar(value: impl Copy) { + | --------- method `method2` not found for this type parameter +... +LL | value.method2(); + | ^^^^^^^ method not found in `impl Copy` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `impl Copy` with it: + | +LL | fn bar(value: impl Copy + Trait2</* 'a, A, B */>) { + | ++++++++++++++++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0599`. |
