]> git.lizzy.rs Git - rust.git/commitdiff
Incorporate feedback into diagnostics
authorTyler Mandry <tmandry@gmail.com>
Wed, 8 Apr 2020 18:54:31 +0000 (11:54 -0700)
committerTyler Mandry <tmandry@gmail.com>
Tue, 14 Apr 2020 01:58:17 +0000 (18:58 -0700)
13 files changed:
src/librustc_trait_selection/traits/error_reporting/suggestions.rs
src/test/ui/async-await/async-fn-nonsend.stderr
src/test/ui/async-await/issue-64130-1-sync.stderr
src/test/ui/async-await/issue-64130-2-send.stderr
src/test/ui/async-await/issue-64130-3-other.stderr
src/test/ui/async-await/issue-64130-4-async-move.stderr
src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
src/test/ui/async-await/issue-67252-unnamed-future.stderr
src/test/ui/async-await/issue-68112.rs
src/test/ui/async-await/issue-68112.stderr
src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
src/test/ui/generator/issue-68112.stderr
src/test/ui/generator/not-send-sync.stderr

index 99e91bbe089c7e5d4a99b441ea6e1533b87285e5..77ecdd08f78e0a88d610dba6b567182b992e20d0 100644 (file)
@@ -1318,7 +1318,8 @@ fn note_obligation_cause_for_async_await(
                 _ => 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 @@ fn note_obligation_cause_for_async_await(
             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 @@ fn note_obligation_cause_for_async_await(
                 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 @@ fn note_obligation_cause_for_async_await(
             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
                 ),
             );
         }
index 176c62fcd7d92ae4d632411707ba45eb22ba9643..d36d59f1f68f6b6be7d4493dc42084999b9cc7a2 100644 (file)
@@ -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
index b7a88c10e7411617e329ba2ae0ecf568aef21840..42e9e4642cea521257bf28b233038ef5b73d4266 100644 (file)
@@ -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 | }
index ec183088771771694b278d1e2dba1790c34c2ab4..f6f834618d36f26bb6c70df18b3a33cb84243522 100644 (file)
@@ -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 | }
index 6b40cc9184df03f55979dd70850a2daf9af36edd..3475b66b375dd6b4c471dcbf874cb2d6da7ee3b6 100644 (file)
@@ -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 | }
index edde947764afe263ed71c35f6ce6efd545280c7e..fc231d394c11f6ddbb1b175991e64d4a588383ef 100644 (file)
@@ -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
index 0f4441edb138542f1f634a30cd24e4d20e7d8866..f72757339cc5ef1e152116a3b708088f23d6df6e 100644 (file)
@@ -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 | }
index cec40b5510148f370cee2aaa3632b48e8cce4cdc..b43478ee2070bc4fe1d6cb04bec50d21ed8f80a3 100644 (file)
@@ -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 |     });
index 604cc51921e0e055ba6eafd0cd5454ae15dfc3b1..11b178368080745b1b1c2eb4a5e067587faf2ddb 100644 (file)
@@ -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();
index c0659bf944b8159daeb9c42aa351ef0774c055e6..78462868ede53b2f70dafe916e947fa459d081c0 100644 (file)
@@ -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
index a04ae7220ec8833150ba06df23c077606b27ff39..49cd30e11a0c17b8fd329662aa3c494d0afa202f 100644 (file)
@@ -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
index f40771d2826d65f540f3ec1462bcfc398a3c258e..4148b503ba8585c887dc65bb74b26bc59fba2992 100644 (file)
@@ -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 |     };
index fb59ef5f433a1b91a3df6c21f9dd9f4ba89cbb82..5df2c1b52fb8a0cae66ec01e14e75ecd01b9317e 100644 (file)
@@ -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 |     });