about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-06-07 07:05:47 +0200
committerGitHub <noreply@github.com>2025-06-07 07:05:47 +0200
commitcf7ffa1aec3c71eed1a50b3cbfafc0866889df42 (patch)
treed6acb046c77c3055b73d60799c1264acdb16b6ab
parent0d2bf86284c257f42949be172dc802bfe0493d26 (diff)
parentac980cace8038f3fa3be1953092e92bede52a5bb (diff)
downloadrust-cf7ffa1aec3c71eed1a50b3cbfafc0866889df42.tar.gz
rust-cf7ffa1aec3c71eed1a50b3cbfafc0866889df42.zip
Rollup merge of #142045 - estebank:obligation-cause-code-suggestion, r=compiler-errors
Make obligation cause code suggestions verbose

```
error[E0277]: `()` is not a future
  --> $DIR/unnecessary-await.rs:28:10
   |
LL |     e!().await;
   |          ^^^^^ `()` is not a future
   |
   = help: the trait `Future` is not implemented for `()`
   = note: () must be a future or must implement `IntoFuture` to be awaited
   = note: required for `()` to implement `IntoFuture`
help: remove the `.await`
   |
LL -     e!().await;
LL +     e!();
   |
```
```
error[E0277]: the trait bound `String: Copy` is not satisfied
  --> $DIR/const-fn-in-vec.rs:1:47
   |
LL | static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
   |                                               ^^^^ the trait `Copy` is not implemented for `String`
   |
   = note: required for `Option<String>` to implement `Copy`
   = note: the `Copy` trait is required because this value will be copied for each element of the array
help: create an inline `const` block
   |
LL | static _MAYBE_STRINGS: [Option<String>; 5] = [const { None }; 5];
   |                                               +++++++      +
```

Part of rust-lang/rust#141973
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs20
-rw-r--r--tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr10
-rw-r--r--tests/ui/async-await/drop-track-bad-field-in-fru.stderr10
-rw-r--r--tests/ui/async-await/issue-101715.stderr9
-rw-r--r--tests/ui/async-await/unnecessary-await.stderr20
-rw-r--r--tests/ui/consts/const-blocks/fn-call-in-non-const.stderr5
-rw-r--r--tests/ui/consts/const-blocks/trait-error.stderr9
-rw-r--r--tests/ui/consts/const-fn-in-vec.stderr27
-rw-r--r--tests/ui/coroutine/unresolved-ct-var.stderr11
-rw-r--r--tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr7
11 files changed, 80 insertions, 57 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 3b7fd8b7a20..68bd9440538 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1411,7 +1411,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
         }
 
-        err.span_suggestion(
+        err.span_suggestion_verbose(
             obligation.cause.span.shrink_to_lo(),
             format!(
                 "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
@@ -1574,7 +1574,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .span_extend_while_whitespace(expr_span)
                     .shrink_to_hi()
                     .to(await_expr.span.shrink_to_hi());
-                err.span_suggestion(
+                err.span_suggestion_verbose(
                     removal_span,
                     "remove the `.await`",
                     "",
@@ -2126,7 +2126,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 ));
 
                 if !assoc_item.is_impl_trait_in_trait() {
-                    err.span_suggestion(
+                    err.span_suggestion_verbose(
                         span,
                         "use the fully qualified path to an implementation",
                         format!(
@@ -2924,12 +2924,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 );
                 let sm = tcx.sess.source_map();
                 if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
-                    && let Ok(snip) = sm.span_to_snippet(elt_span)
+                    && let Ok(_) = sm.span_to_snippet(elt_span)
                 {
-                    err.span_suggestion(
-                        elt_span,
+                    err.multipart_suggestion(
                         "create an inline `const` block",
-                        format!("const {{ {snip} }}"),
+                        vec![
+                            (elt_span.shrink_to_lo(), "const { ".to_string()),
+                            (elt_span.shrink_to_hi(), " }".to_string()),
+                        ],
                         Applicability::MachineApplicable,
                     );
                 } else {
@@ -3127,13 +3129,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                 }
                 err.help("change the field's type to have a statically known size");
-                err.span_suggestion(
+                err.span_suggestion_verbose(
                     span.shrink_to_lo(),
                     "borrowed types always have a statically known size",
                     "&",
                     Applicability::MachineApplicable,
                 );
-                err.multipart_suggestion(
+                err.multipart_suggestion_verbose(
                     "the `Box` type always has a statically known size and allocates its contents \
                      in the heap",
                     vec![
diff --git a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
index 8c9d06c79ca..40d44db205f 100644
--- a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
+++ b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
@@ -2,14 +2,16 @@ error[E0277]: `[usize; usize::MAX]` is not a future
   --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:8:37
    |
 LL |     [0usize; 0xffff_ffff_ffff_ffff].await;
-   |                                    -^^^^^
-   |                                    ||
-   |                                    |`[usize; usize::MAX]` is not a future
-   |                                    help: remove the `.await`
+   |                                     ^^^^^ `[usize; usize::MAX]` is not a future
    |
    = help: the trait `Future` is not implemented for `[usize; usize::MAX]`
    = note: [usize; usize::MAX] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[usize; usize::MAX]` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     [0usize; 0xffff_ffff_ffff_ffff].await;
+LL +     [0usize; 0xffff_ffff_ffff_ffff];
+   |
 
 error[E0752]: `main` function is not allowed to be `async`
   --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:6:1
diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
index 721e0106293..644a7c7717c 100644
--- a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
+++ b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
@@ -10,14 +10,16 @@ error[E0277]: `Option<_>` is not a future
   --> $DIR/drop-track-bad-field-in-fru.rs:6:46
    |
 LL |     None { value: (), ..Default::default() }.await;
-   |                                             -^^^^^
-   |                                             ||
-   |                                             |`Option<_>` is not a future
-   |                                             help: remove the `.await`
+   |                                              ^^^^^ `Option<_>` is not a future
    |
    = help: the trait `Future` is not implemented for `Option<_>`
    = note: Option<_> must be a future or must implement `IntoFuture` to be awaited
    = note: required for `Option<_>` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     None { value: (), ..Default::default() }.await;
+LL +     None { value: (), ..Default::default() };
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/async-await/issue-101715.stderr b/tests/ui/async-await/issue-101715.stderr
index f6af15c00d6..87302dce130 100644
--- a/tests/ui/async-await/issue-101715.stderr
+++ b/tests/ui/async-await/issue-101715.stderr
@@ -2,14 +2,15 @@ error[E0277]: `()` is not a future
   --> $DIR/issue-101715.rs:11:10
    |
 LL |         .await
-   |         -^^^^^
-   |         ||
-   |         |`()` is not a future
-   |         help: remove the `.await`
+   |          ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -         .await
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/unnecessary-await.stderr b/tests/ui/async-await/unnecessary-await.stderr
index 620370a6113..f60b4ecb990 100644
--- a/tests/ui/async-await/unnecessary-await.stderr
+++ b/tests/ui/async-await/unnecessary-await.stderr
@@ -23,14 +23,16 @@ error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:28:10
    |
 LL |     e!().await;
-   |         -^^^^^
-   |         ||
-   |         |`()` is not a future
-   |         help: remove the `.await`
+   |          ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     e!().await;
+LL +     e!();
+   |
 
 error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:22:15
@@ -53,14 +55,16 @@ error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:36:20
    |
 LL |     for x in [] {}.await
-   |                   -^^^^^
-   |                   ||
-   |                   |`()` is not a future
-   |                   help: remove the `.await`
+   |                    ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     for x in [] {}.await
+LL +     for x in [] {}
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
index a3d5054ced3..54982391b66 100644
--- a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
+++ b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
@@ -13,9 +13,8 @@ LL | struct Bar;
    |
 help: create an inline `const` block
    |
-LL -     let _: [Option<Bar>; 2] = [no_copy(); 2];
-LL +     let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
-   |
+LL |     let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
+   |                                +++++++           +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr
index 58ddc047d03..601d067e3d8 100644
--- a/tests/ui/consts/const-blocks/trait-error.stderr
+++ b/tests/ui/consts/const-blocks/trait-error.stderr
@@ -2,10 +2,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/trait-error.rs:5:6
    |
 LL |     [Foo(String::new()); 4];
-   |      ^^^^^^^^^^^^^^^^^^
-   |      |
-   |      the trait `Copy` is not implemented for `String`
-   |      help: create an inline `const` block: `const { Foo(String::new()) }`
+   |      ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
 note: required for `Foo<String>` to implement `Copy`
   --> $DIR/trait-error.rs:1:10
@@ -13,6 +10,10 @@ note: required for `Foo<String>` to implement `Copy`
 LL | #[derive(Copy, Clone)]
    |          ^^^^ unsatisfied trait bound introduced in this `derive` macro
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     [const { Foo(String::new()) }; 4];
+   |      +++++++                    +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr
index 5be26d7c121..890eb8040b9 100644
--- a/tests/ui/consts/const-fn-in-vec.stderr
+++ b/tests/ui/consts/const-fn-in-vec.stderr
@@ -2,36 +2,39 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:1:47
    |
 LL | static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
-   |                                               ^^^^
-   |                                               |
-   |                                               the trait `Copy` is not implemented for `String`
-   |                                               help: create an inline `const` block: `const { None }`
+   |                                               ^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: required for `Option<String>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL | static _MAYBE_STRINGS: [Option<String>; 5] = [const { None }; 5];
+   |                                               +++++++      +
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:7:34
    |
 LL |     let _strings: [String; 5] = [String::new(); 5];
-   |                                  ^^^^^^^^^^^^^
-   |                                  |
-   |                                  the trait `Copy` is not implemented for `String`
-   |                                  help: create an inline `const` block: `const { String::new() }`
+   |                                  ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let _strings: [String; 5] = [const { String::new() }; 5];
+   |                                  +++++++               +
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:12:48
    |
 LL |     let _maybe_strings: [Option<String>; 5] = [None; 5];
-   |                                                ^^^^
-   |                                                |
-   |                                                the trait `Copy` is not implemented for `String`
-   |                                                help: create an inline `const` block: `const { None }`
+   |                                                ^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: required for `Option<String>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let _maybe_strings: [Option<String>; 5] = [const { None }; 5];
+   |                                                +++++++      +
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/coroutine/unresolved-ct-var.stderr b/tests/ui/coroutine/unresolved-ct-var.stderr
index da2ec272f9f..86b73e4b062 100644
--- a/tests/ui/coroutine/unresolved-ct-var.stderr
+++ b/tests/ui/coroutine/unresolved-ct-var.stderr
@@ -2,15 +2,18 @@ error[E0277]: `[(); _]` is not a future
   --> $DIR/unresolved-ct-var.rs:6:45
    |
 LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ----------------------------^^^^^
-   |                 |                          ||
-   |                 |                          |`[(); _]` is not a future
-   |                 |                          help: remove the `.await`
+   |                 --------------------------- ^^^^^ `[(); _]` is not a future
+   |                 |
    |                 this call returns `[(); _]`
    |
    = help: the trait `Future` is not implemented for `[(); _]`
    = note: [(); _] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[(); _]` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -         let s = std::array::from_fn(|_| ()).await;
+LL +         let s = std::array::from_fn(|_| ());
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr b/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
index d974f5add50..1c862f2b606 100644
--- a/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
+++ b/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
@@ -2,12 +2,13 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/copy-check-when-count-inferred-later.rs:8:14
    |
 LL |     let a = [String::new(); _];
-   |              ^^^^^^^^^^^^^
-   |              |
-   |              the trait `Copy` is not implemented for `String`
-   |              help: create an inline `const` block: `const { String::new() }`
+   |              ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let a = [const { String::new() }; _];
+   |              +++++++               +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
index 7c09ab6a91a..72a253c4be8 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
   --> $DIR/constrain_in_projection2.rs:28:14
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
-   |              ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
+   |              ^^^
    |
 note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
   --> $DIR/constrain_in_projection2.rs:18:1
@@ -13,6 +13,11 @@ LL | impl Trait<()> for Foo {
 LL | impl Trait<u32> for Foo {
    | ^^^^^^^^^^^^^^^^^^^^^^^
    = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+help: use the fully qualified path to an implementation
+   |
+LL -     let x = <Foo as Trait<Bar>>::Assoc::default();
+LL +     let x = <<Type as Trait>::Assoc as Trait<Bar>>::Assoc::default();
+   |
 
 error: aborting due to 1 previous error