Skip to content

Commit 00d12ef

Browse files
committed
add test for correct await span
1 parent bc15954 commit 00d12ef

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

src/librustc_middle/ty/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
314314
pub span: Span,
315315
/// Span of the scope of the captured binding.
316316
pub scope_span: Option<Span>,
317-
/// Span of `.await` statement.
318-
pub await_span: Span,
317+
/// Span of `.await` or `yield` expression.
318+
pub yield_span: Span,
319319
/// Expr which the type evaluated from.
320320
pub expr: Option<hir::HirId>,
321321
}

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1261,31 +1261,31 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12611261
ty_matches(ty)
12621262
})
12631263
.map(|expr| expr.span);
1264-
let ty::GeneratorInteriorTypeCause { span, scope_span, await_span, expr, .. } =
1264+
let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
12651265
cause;
12661266
(
12671267
span,
12681268
source_map.span_to_snippet(*span),
12691269
scope_span,
1270-
await_span,
1270+
yield_span,
12711271
expr,
12721272
from_awaited_ty,
12731273
)
12741274
});
12751275

12761276
debug!(
12771277
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
1278-
generator_interior_types={:?} target_span={:?} await_span={:?}",
1279-
target_ty, tables.generator_interior_types, target_span, await_span
1278+
generator_interior_types={:?} target_span={:?}",
1279+
target_ty, tables.generator_interior_types, target_span
12801280
);
1281-
if let Some((target_span, Ok(snippet), scope_span, await_span, expr, from_awaited_ty)) =
1281+
if let Some((target_span, Ok(snippet), scope_span, yield_span, expr, from_awaited_ty)) =
12821282
target_span
12831283
{
12841284
self.note_obligation_cause_for_async_await(
12851285
err,
12861286
*target_span,
12871287
scope_span,
1288-
await_span,
1288+
*yield_span,
12891289
*expr,
12901290
snippet,
12911291
generator_body,
@@ -1310,7 +1310,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13101310
err: &mut DiagnosticBuilder<'_>,
13111311
target_span: Span,
13121312
scope_span: &Option<Span>,
1313-
await_span: Span,
1313+
yield_span: Span,
13141314
expr: Option<hir::HirId>,
13151315
snippet: String,
13161316
inner_generator_body: Option<&hir::Body<'_>>,
@@ -1386,6 +1386,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13861386
if let Some(await_span) = from_awaited_ty {
13871387
// The type causing this obligation is one being awaited at await_span.
13881388
let mut span = MultiSpan::from_span(await_span);
1389+
1390+
span.push_span_label(
1391+
await_span,
1392+
format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation),
1393+
);
1394+
13891395
err.span_note(
13901396
span,
13911397
&format!(
@@ -1399,9 +1405,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13991405
"note_obligation_cause_for_async_await generator_interior_types: {:#?}",
14001406
tables.generator_interior_types
14011407
);
1402-
let mut span = MultiSpan::from_span(await_span);
1408+
let mut span = MultiSpan::from_span(yield_span);
14031409
span.push_span_label(
1404-
await_span,
1410+
yield_span,
14051411
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
14061412
);
14071413

src/librustc_typeck/check/generator_interior.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
9696
span: source_span,
9797
ty: &ty,
9898
scope_span,
99-
await_span: yield_data.span,
99+
yield_span: yield_data.span,
100100
expr: expr.map(|e| e.hir_id),
101101
})
102102
.or_insert(entries);
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// edition:2018
2+
3+
use std::future::Future;
4+
use std::sync::Mutex;
5+
6+
fn fake_spawn<F: Future + Send + 'static>(f: F) { }
7+
8+
async fn wrong_mutex() {
9+
let m = Mutex::new(1);
10+
{
11+
let mut guard = m.lock().unwrap();
12+
(async { "right"; }).await;
13+
*guard += 1;
14+
}
15+
16+
(async { "wrong"; }).await;
17+
}
18+
19+
fn main() {
20+
fake_spawn(wrong_mutex()); //~ Error future cannot be sent between threads safely
21+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error: future cannot be sent between threads safely
2+
--> $DIR/issue-71137.rs:20:3
3+
|
4+
LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
5+
| ---- required by this bound in `fake_spawn`
6+
...
7+
LL | fake_spawn(wrong_mutex());
8+
| ^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
9+
|
10+
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, i32>`
11+
note: future is not `Send` as this value is used across an await
12+
--> $DIR/issue-71137.rs:12:5
13+
|
14+
LL | let mut guard = m.lock().unwrap();
15+
| --------- has type `std::sync::MutexGuard<'_, i32>` which is not `Send`
16+
LL | (async { "right"; }).await;
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later
18+
LL | *guard += 1;
19+
LL | }
20+
| - `mut guard` is later dropped here
21+
22+
error: aborting due to previous error
23+

0 commit comments

Comments
 (0)