about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2020-04-08 11:54:31 -0700
committerTyler Mandry <tmandry@gmail.com>2020-04-13 18:58:17 -0700
commitdf64c5d260d3841ded8affe68f1be6e47ed1fb26 (patch)
tree7760084b954794850e135f70324162d0fcf7e787 /src
parent00795a99401865e6ade63600619eb5ee5a34e7c6 (diff)
downloadrust-df64c5d260d3841ded8affe68f1be6e47ed1fb26.tar.gz
rust-df64c5d260d3841ded8affe68f1be6e47ed1fb26.zip
Incorporate feedback into diagnostics
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs44
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.stderr6
-rw-r--r--src/test/ui/async-await/issue-64130-1-sync.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-2-send.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-3-other.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-non-send-future-diags.stderr2
-rw-r--r--src/test/ui/async-await/issue-67252-unnamed-future.stderr2
-rw-r--r--src/test/ui/async-await/issue-68112.rs2
-rw-r--r--src/test/ui/async-await/issue-68112.stderr16
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr2
-rw-r--r--src/test/ui/generator/issue-68112.stderr4
-rw-r--r--src/test/ui/generator/not-send-sync.stderr4
13 files changed, 41 insertions, 49 deletions
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 99e91bbe089..77ecdd08f78 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -1318,7 +1318,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 _ => false,
             })
             .unwrap_or(false);
-        let await_or_yield = if is_async { "await" } else { "yield" };
+        let (await_or_yield, an_await_or_yield) =
+            if is_async { ("await", "an await") } else { ("yield", "a yield") };
         let future_or_generator = if is_async { "future" } else { "generator" };
 
         // Special case the primary error message when send or sync is the trait that was
@@ -1364,38 +1365,26 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             span.push_span_label(original_span, message);
             err.set_span(span);
 
-            format!("{} is not {}", future_or_generator, trait_name)
+            format!("is not {}", trait_name)
         } else {
-            format!(
-                "{} does not implement `{}`",
-                future_or_generator,
-                trait_ref.print_only_trait_path()
-            )
-        };
-
-        let push_target_span_with_fallback = |span: &mut MultiSpan, fallback: &str| {
-            if target_ty.is_impl_trait() {
-                // It's not very useful to tell the user the type if it's opaque.
-                span.push_span_label(target_span, fallback.to_string());
-            } else {
-                span.push_span_label(target_span, format!("has type `{}`", target_ty));
-            }
+            format!("does not implement `{}`", trait_ref.print_only_trait_path())
         };
 
         if let Some(await_span) = from_awaited_ty {
             // The type causing this obligation is one being awaited at await_span.
             let mut span = MultiSpan::from_span(await_span);
 
-            if target_span == await_span {
-                push_target_span_with_fallback(&mut span, "await occurs here");
-            } else {
-                span.push_span_label(await_span, "await occurs here".to_string());
-                push_target_span_with_fallback(&mut span, "created here");
-            }
+            span.push_span_label(
+                await_span,
+                format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation),
+            );
 
             err.span_note(
                 span,
-                &format!("{} as this value is used in an await", trait_explanation),
+                &format!(
+                    "future {not_trait} as it awaits another future which {not_trait}",
+                    not_trait = trait_explanation
+                ),
             );
         } else {
             // Look at the last interior type to get a span for the `.await`.
@@ -1410,7 +1399,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
             );
 
-            push_target_span_with_fallback(&mut span, "created here");
+            span.push_span_label(
+                target_span,
+                format!("has type `{}` which {}", target_ty, trait_explanation),
+            );
 
             // If available, use the scope span to annotate the drop location.
             if let Some(scope_span) = scope_span {
@@ -1423,8 +1415,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             err.span_note(
                 span,
                 &format!(
-                    "{} as this value is used across an {}",
-                    trait_explanation, await_or_yield
+                    "{} {} as this value is used across {}",
+                    future_or_generator, trait_explanation, an_await_or_yield
                 ),
             );
         }
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 176c62fcd7d..d36d59f1f68 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:24:5
    |
 LL |     let x = non_send();
-   |         - created here
+   |         - has type `impl std::fmt::Debug` which is not `Send`
 LL |     drop(x);
 LL |     fut().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
@@ -33,7 +33,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:33:20
    |
 LL |     match Some(non_send()) {
-   |                ---------- created here
+   |                ---------- has type `impl std::fmt::Debug` which is not `Send`
 LL |         Some(_) => fut().await,
    |                    ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later
 ...
@@ -54,7 +54,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:42:9
    |
 LL |     let f: &mut std::fmt::Formatter = panic!();
-   |         - has type `&mut std::fmt::Formatter<'_>`
+   |         - has type `&mut std::fmt::Formatter<'_>` which is not `Send`
 LL |     if non_sync().fmt(f).unwrap() == () {
 LL |         fut().await;
    |         ^^^^^^^^^^^ await occurs here, with `f` maybe used later
diff --git a/src/test/ui/async-await/issue-64130-1-sync.stderr b/src/test/ui/async-await/issue-64130-1-sync.stderr
index b7a88c10e74..42e9e4642ce 100644
--- a/src/test/ui/async-await/issue-64130-1-sync.stderr
+++ b/src/test/ui/async-await/issue-64130-1-sync.stderr
@@ -12,7 +12,7 @@ note: future is not `Sync` as this value is used across an await
   --> $DIR/issue-64130-1-sync.rs:15:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which is not `Sync`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-2-send.stderr b/src/test/ui/async-await/issue-64130-2-send.stderr
index ec183088771..f6f834618d3 100644
--- a/src/test/ui/async-await/issue-64130-2-send.stderr
+++ b/src/test/ui/async-await/issue-64130-2-send.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-2-send.rs:15:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which is not `Send`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr
index 6b40cc9184d..3475b66b375 100644
--- a/src/test/ui/async-await/issue-64130-3-other.stderr
+++ b/src/test/ui/async-await/issue-64130-3-other.stderr
@@ -16,7 +16,7 @@ note: future does not implement `Qux` as this value is used across an await
   --> $DIR/issue-64130-3-other.rs:18:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which does not implement `Qux`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr
index edde947764a..fc231d394c1 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.stderr
+++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr
@@ -18,7 +18,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-4-async-move.rs:21:26
    |
 LL |         match client.status() {
-   |               ------ has type `&Client`
+   |               ------ has type `&Client` which is not `Send`
 LL |             200 => {
 LL |                 let _x = get().await;
    |                          ^^^^^^^^^^^ await occurs here, with `client` maybe used later
diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
index 0f4441edb13..f72757339cc 100644
--- a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
+++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-non-send-future-diags.rs:15:5
    |
 LL |     let g = x.lock().unwrap();
-   |         - has type `std::sync::MutexGuard<'_, u32>`
+   |         - has type `std::sync::MutexGuard<'_, u32>` which is not `Send`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `g` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
index cec40b55101..b43478ee207 100644
--- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:20:9
    |
 LL |         let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-   |             -- has type `*mut ()`
+   |             -- has type `*mut ()` which is not `Send`
 LL |         AFuture.await;
    |         ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later
 LL |     });
diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs
index 604cc51921e..11b17836808 100644
--- a/src/test/ui/async-await/issue-68112.rs
+++ b/src/test/ui/async-await/issue-68112.rs
@@ -49,6 +49,8 @@ fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
     ready2(Arc::new(RefCell::new(0)))
 }
 
+// Ideally this test would have diagnostics similar to the test above, but right
+// now it doesn't.
 fn test2() {
     let send_fut = async {
         let non_send_fut = make_non_send_future2();
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr
index c0659bf944b..78462868ede 100644
--- a/src/test/ui/async-await/issue-68112.stderr
+++ b/src/test/ui/async-await/issue-68112.stderr
@@ -8,13 +8,11 @@ LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
-note: future is not `Send` as this value is used in an await
+note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:31:17
    |
-LL |         let non_send_fut = make_non_send_future1();
-   |             ------------ created here
 LL |         let _ = non_send_fut.await;
-   |                 ^^^^^^^^^^^^ await occurs here
+   |                 ^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
 
 error: future cannot be sent between threads safely
   --> $DIR/issue-68112.rs:43:5
@@ -26,14 +24,14 @@ LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
-note: future is not `Send` as this value is used in an await
+note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:40:17
    |
 LL |         let _ = make_non_send_future1().await;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
 
 error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:58:5
+  --> $DIR/issue-68112.rs:60:5
    |
 LL | fn require_send(_: impl Send) {}
    |    ------------         ---- required by this bound in `require_send`
@@ -49,8 +47,8 @@ LL |     require_send(send_fut);
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}`
-   = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:53:26: 57:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]`
-   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:53:26: 57:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]>`
+   = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]>`
    = note: required because it appears within the type `impl std::future::Future`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
index a04ae7220ec..49cd30e11a0 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
@@ -14,7 +14,7 @@ note: future is not `Send` as this value is used across an await
 LL |         bar(Foo(std::ptr::null())).await;
    |         ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here
    |         |       |
-   |         |       has type `*const u8`
+   |         |       has type `*const u8` which is not `Send`
    |         await occurs here, with `std::ptr::null()` maybe used later
 help: consider moving this into a `let` binding to create a shorter lived borrow
   --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr
index f40771d2826..4148b503ba8 100644
--- a/src/test/ui/generator/issue-68112.stderr
+++ b/src/test/ui/generator/issue-68112.stderr
@@ -8,11 +8,11 @@ LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ generator is not `Send`
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
-note: generator is not `Send` as this value is used across an yield
+note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-68112.rs:31:9
    |
 LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- created here
+   |             ------------- has type `impl std::ops::Generator` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
 LL |     };
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index fb59ef5f433..5df2c1b52fb 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -21,11 +21,11 @@ LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
-note: generator is not `Sync` as this value is used across an yield
+note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:12:9
    |
 LL |         let a = Cell::new(2);
-   |             - has type `std::cell::Cell<i32>`
+   |             - has type `std::cell::Cell<i32>` which is not `Sync`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 LL |     });