Skip to content

Commit 889cfe1

Browse files
committed
Incorporate feedback into diagnostics
1 parent 9dba024 commit 889cfe1

13 files changed

+41
-49
lines changed

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+18-26
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12031203
_ => false,
12041204
})
12051205
.unwrap_or(false);
1206-
let await_or_yield = if is_async { "await" } else { "yield" };
1206+
let (await_or_yield, an_await_or_yield) =
1207+
if is_async { ("await", "an await") } else { ("yield", "a yield") };
12071208
let future_or_generator = if is_async { "future" } else { "generator" };
12081209

12091210
// Special case the primary error message when send or sync is the trait that was
@@ -1249,38 +1250,26 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12491250
span.push_span_label(original_span, message);
12501251
err.set_span(span);
12511252

1252-
format!("{} is not {}", future_or_generator, trait_name)
1253+
format!("is not {}", trait_name)
12531254
} else {
1254-
format!(
1255-
"{} does not implement `{}`",
1256-
future_or_generator,
1257-
trait_ref.print_only_trait_path()
1258-
)
1259-
};
1260-
1261-
let push_target_span_with_fallback = |span: &mut MultiSpan, fallback: &str| {
1262-
if target_ty.is_impl_trait() {
1263-
// It's not very useful to tell the user the type if it's opaque.
1264-
span.push_span_label(target_span, fallback.to_string());
1265-
} else {
1266-
span.push_span_label(target_span, format!("has type `{}`", target_ty));
1267-
}
1255+
format!("does not implement `{}`", trait_ref.print_only_trait_path())
12681256
};
12691257

12701258
if let Some(await_span) = from_awaited_ty {
12711259
// The type causing this obligation is one being awaited at await_span.
12721260
let mut span = MultiSpan::from_span(await_span);
12731261

1274-
if target_span == await_span {
1275-
push_target_span_with_fallback(&mut span, "await occurs here");
1276-
} else {
1277-
span.push_span_label(await_span, "await occurs here".to_string());
1278-
push_target_span_with_fallback(&mut span, "created here");
1279-
}
1262+
span.push_span_label(
1263+
await_span,
1264+
format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation),
1265+
);
12801266

12811267
err.span_note(
12821268
span,
1283-
&format!("{} as this value is used in an await", trait_explanation),
1269+
&format!(
1270+
"future {not_trait} as it awaits another future which {not_trait}",
1271+
not_trait = trait_explanation
1272+
),
12841273
);
12851274
} else {
12861275
// Look at the last interior type to get a span for the `.await`.
@@ -1295,7 +1284,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12951284
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
12961285
);
12971286

1298-
push_target_span_with_fallback(&mut span, "created here");
1287+
span.push_span_label(
1288+
target_span,
1289+
format!("has type `{}` which {}", target_ty, trait_explanation),
1290+
);
12991291

13001292
// If available, use the scope span to annotate the drop location.
13011293
if let Some(scope_span) = scope_span {
@@ -1308,8 +1300,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13081300
err.span_note(
13091301
span,
13101302
&format!(
1311-
"{} as this value is used across an {}",
1312-
trait_explanation, await_or_yield
1303+
"{} {} as this value is used across {}",
1304+
future_or_generator, trait_explanation, an_await_or_yield
13131305
),
13141306
);
13151307
}

src/test/ui/async-await/async-fn-nonsend.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
1212
--> $DIR/async-fn-nonsend.rs:24:5
1313
|
1414
LL | let x = non_send();
15-
| - created here
15+
| - has type `impl std::fmt::Debug` which is not `Send`
1616
LL | drop(x);
1717
LL | fut().await;
1818
| ^^^^^^^^^^^ 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
3333
--> $DIR/async-fn-nonsend.rs:33:20
3434
|
3535
LL | match Some(non_send()) {
36-
| ---------- created here
36+
| ---------- has type `impl std::fmt::Debug` which is not `Send`
3737
LL | Some(_) => fut().await,
3838
| ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later
3939
...
@@ -54,7 +54,7 @@ note: future is not `Send` as this value is used across an await
5454
--> $DIR/async-fn-nonsend.rs:42:9
5555
|
5656
LL | let f: &mut std::fmt::Formatter = panic!();
57-
| - has type `&mut std::fmt::Formatter<'_>`
57+
| - has type `&mut std::fmt::Formatter<'_>` which is not `Send`
5858
LL | if non_sync().fmt(f).unwrap() == () {
5959
LL | fut().await;
6060
| ^^^^^^^^^^^ await occurs here, with `f` maybe used later

src/test/ui/async-await/issue-64130-1-sync.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: future is not `Sync` as this value is used across an await
1212
--> $DIR/issue-64130-1-sync.rs:15:5
1313
|
1414
LL | let x = Foo;
15-
| - has type `Foo`
15+
| - has type `Foo` which is not `Sync`
1616
LL | baz().await;
1717
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
1818
LL | }

src/test/ui/async-await/issue-64130-2-send.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
1212
--> $DIR/issue-64130-2-send.rs:15:5
1313
|
1414
LL | let x = Foo;
15-
| - has type `Foo`
15+
| - has type `Foo` which is not `Send`
1616
LL | baz().await;
1717
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
1818
LL | }

src/test/ui/async-await/issue-64130-3-other.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ note: future does not implement `Qux` as this value is used across an await
1616
--> $DIR/issue-64130-3-other.rs:18:5
1717
|
1818
LL | let x = Foo;
19-
| - has type `Foo`
19+
| - has type `Foo` which does not implement `Qux`
2020
LL | baz().await;
2121
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
2222
LL | }

src/test/ui/async-await/issue-64130-4-async-move.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ note: future is not `Send` as this value is used across an await
1818
--> $DIR/issue-64130-4-async-move.rs:21:26
1919
|
2020
LL | match client.status() {
21-
| ------ has type `&Client`
21+
| ------ has type `&Client` which is not `Send`
2222
LL | 200 => {
2323
LL | let _x = get().await;
2424
| ^^^^^^^^^^^ await occurs here, with `client` maybe used later

src/test/ui/async-await/issue-64130-non-send-future-diags.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
1212
--> $DIR/issue-64130-non-send-future-diags.rs:15:5
1313
|
1414
LL | let g = x.lock().unwrap();
15-
| - has type `std::sync::MutexGuard<'_, u32>`
15+
| - has type `std::sync::MutexGuard<'_, u32>` which is not `Send`
1616
LL | baz().await;
1717
| ^^^^^^^^^^^ await occurs here, with `g` maybe used later
1818
LL | }

src/test/ui/async-await/issue-67252-unnamed-future.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
1212
--> $DIR/issue-67252-unnamed-future.rs:20:9
1313
|
1414
LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
15-
| -- has type `*mut ()`
15+
| -- has type `*mut ()` which is not `Send`
1616
LL | AFuture.await;
1717
| ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later
1818
LL | });

src/test/ui/async-await/issue-68112.rs

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
4949
ready2(Arc::new(RefCell::new(0)))
5050
}
5151

52+
// Ideally this test would have diagnostics similar to the test above, but right
53+
// now it doesn't.
5254
fn test2() {
5355
let send_fut = async {
5456
let non_send_fut = make_non_send_future2();

src/test/ui/async-await/issue-68112.stderr

+7-9
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ LL | require_send(send_fut);
88
| ^^^^^^^^^^^^ future created by async block is not `Send`
99
|
1010
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
11-
note: future is not `Send` as this value is used in an await
11+
note: future is not `Send` as it awaits another future which is not `Send`
1212
--> $DIR/issue-68112.rs:31:17
1313
|
14-
LL | let non_send_fut = make_non_send_future1();
15-
| ------------ created here
1614
LL | let _ = non_send_fut.await;
17-
| ^^^^^^^^^^^^ await occurs here
15+
| ^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
1816

1917
error: future cannot be sent between threads safely
2018
--> $DIR/issue-68112.rs:43:5
@@ -26,14 +24,14 @@ LL | require_send(send_fut);
2624
| ^^^^^^^^^^^^ future created by async block is not `Send`
2725
|
2826
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
29-
note: future is not `Send` as this value is used in an await
27+
note: future is not `Send` as it awaits another future which is not `Send`
3028
--> $DIR/issue-68112.rs:40:17
3129
|
3230
LL | let _ = make_non_send_future1().await;
33-
| ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here
31+
| ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
3432

3533
error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
36-
--> $DIR/issue-68112.rs:58:5
34+
--> $DIR/issue-68112.rs:60:5
3735
|
3836
LL | fn require_send(_: impl Send) {}
3937
| ------------ ---- required by this bound in `require_send`
@@ -49,8 +47,8 @@ LL | require_send(send_fut);
4947
= note: required because it appears within the type `impl std::future::Future`
5048
= note: required because it appears within the type `impl std::future::Future`
5149
= note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}`
52-
= 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>}]`
53-
= 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>}]>`
50+
= 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>}]`
51+
= 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>}]>`
5452
= note: required because it appears within the type `impl std::future::Future`
5553

5654
error: aborting due to 3 previous errors

src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ note: future is not `Send` as this value is used across an await
1414
LL | bar(Foo(std::ptr::null())).await;
1515
| ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here
1616
| | |
17-
| | has type `*const u8`
17+
| | has type `*const u8` which is not `Send`
1818
| await occurs here, with `std::ptr::null()` maybe used later
1919
help: consider moving this into a `let` binding to create a shorter lived borrow
2020
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:13

src/test/ui/generator/issue-68112.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ LL | require_send(send_gen);
88
| ^^^^^^^^^^^^ generator is not `Send`
99
|
1010
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
11-
note: generator is not `Send` as this value is used across an yield
11+
note: generator is not `Send` as this value is used across a yield
1212
--> $DIR/issue-68112.rs:31:9
1313
|
1414
LL | let _non_send_gen = make_non_send_generator();
15-
| ------------- created here
15+
| ------------- has type `impl std::ops::Generator` which is not `Send`
1616
LL | yield;
1717
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
1818
LL | };

src/test/ui/generator/not-send-sync.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ LL | assert_sync(|| {
2121
| ^^^^^^^^^^^ generator is not `Sync`
2222
|
2323
= 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>`
24-
note: generator is not `Sync` as this value is used across an yield
24+
note: generator is not `Sync` as this value is used across a yield
2525
--> $DIR/not-send-sync.rs:12:9
2626
|
2727
LL | let a = Cell::new(2);
28-
| - has type `std::cell::Cell<i32>`
28+
| - has type `std::cell::Cell<i32>` which is not `Sync`
2929
LL | yield;
3030
| ^^^^^ yield occurs here, with `a` maybe used later
3131
LL | });

0 commit comments

Comments
 (0)