about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-12 05:51:31 +0000
committerbors <bors@rust-lang.org>2024-11-12 05:51:31 +0000
commit9a9daddd0dacfe8c5e8eaa07cfd054a3631bcde7 (patch)
tree6c6eced9db68af0b60126546d65467b5f899c942 /tests
parent67f21277cd40cd12e69aa34089f4a20926fd6dc5 (diff)
parent506f52c7f3ecbd42e163b1577f1d4e0a2f84c8d3 (diff)
downloadrust-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')
-rw-r--r--tests/crashes/131915.rs13
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs20
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr39
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs366
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.fixed52
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr29
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2024.stderr31
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs14
-rw-r--r--tests/ui/suggestions/no-method-found-suggest-trait-args.rs30
-rw-r--r--tests/ui/suggestions/no-method-found-suggest-trait-args.stderr63
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`.