about summary refs log tree commit diff
diff options
context:
space:
mode:
authorcsmoe <csmoe@msn.com>2020-04-16 23:14:11 +0800
committercsmoe <csmoe@msn.com>2020-04-22 09:51:56 +0800
commit00d12ef9016f2eab194488ac7d51567175eddebc (patch)
tree9e997c23af174645c77a5d8671226e6a8d4a5c02
parentbc1595473bad5ab808b2734260286ba0f847546a (diff)
downloadrust-00d12ef9016f2eab194488ac7d51567175eddebc.tar.gz
rust-00d12ef9016f2eab194488ac7d51567175eddebc.zip
add test for correct await span
-rw-r--r--src/librustc_middle/ty/context.rs4
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs24
-rw-r--r--src/librustc_typeck/check/generator_interior.rs2
-rw-r--r--src/test/ui/async-await/issue-71137.rs21
-rw-r--r--src/test/ui/async-await/issue-71137.stderr23
5 files changed, 62 insertions, 12 deletions
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index e127c222dac..c6228a913cf 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -314,8 +314,8 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
     pub span: Span,
     /// Span of the scope of the captured binding.
     pub scope_span: Option<Span>,
-    /// Span of `.await` statement.
-    pub await_span: Span,
+    /// Span of `.await` or `yield` expression.
+    pub yield_span: Span,
     /// Expr which the type evaluated from.
     pub expr: Option<hir::HirId>,
 }
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index c0e14d044ec..51ac552c312 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -1261,13 +1261,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         ty_matches(ty)
                     })
                     .map(|expr| expr.span);
-                let ty::GeneratorInteriorTypeCause { span, scope_span, await_span, expr, .. } =
+                let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
                     cause;
                 (
                     span,
                     source_map.span_to_snippet(*span),
                     scope_span,
-                    await_span,
+                    yield_span,
                     expr,
                     from_awaited_ty,
                 )
@@ -1275,17 +1275,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
         debug!(
             "maybe_note_obligation_cause_for_async_await: target_ty={:?} \
-                generator_interior_types={:?} target_span={:?} await_span={:?}",
-            target_ty, tables.generator_interior_types, target_span, await_span
+                generator_interior_types={:?} target_span={:?}",
+            target_ty, tables.generator_interior_types, target_span
         );
-        if let Some((target_span, Ok(snippet), scope_span, await_span, expr, from_awaited_ty)) =
+        if let Some((target_span, Ok(snippet), scope_span, yield_span, expr, from_awaited_ty)) =
             target_span
         {
             self.note_obligation_cause_for_async_await(
                 err,
                 *target_span,
                 scope_span,
-                await_span,
+                *yield_span,
                 *expr,
                 snippet,
                 generator_body,
@@ -1310,7 +1310,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         target_span: Span,
         scope_span: &Option<Span>,
-        await_span: Span,
+        yield_span: Span,
         expr: Option<hir::HirId>,
         snippet: String,
         inner_generator_body: Option<&hir::Body<'_>>,
@@ -1386,6 +1386,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         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);
+
+            span.push_span_label(
+                await_span,
+                format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation),
+            );
+
             err.span_note(
                 span,
                 &format!(
@@ -1399,9 +1405,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 "note_obligation_cause_for_async_await generator_interior_types: {:#?}",
                 tables.generator_interior_types
             );
-            let mut span = MultiSpan::from_span(await_span);
+            let mut span = MultiSpan::from_span(yield_span);
             span.push_span_label(
-                await_span,
+                yield_span,
                 format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
             );
 
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 99e01a0332f..716d23b4d17 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -96,7 +96,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
                         span: source_span,
                         ty: &ty,
                         scope_span,
-                        await_span: yield_data.span,
+                        yield_span: yield_data.span,
                         expr: expr.map(|e| e.hir_id),
                     })
                     .or_insert(entries);
diff --git a/src/test/ui/async-await/issue-71137.rs b/src/test/ui/async-await/issue-71137.rs
new file mode 100644
index 00000000000..ebb392a4530
--- /dev/null
+++ b/src/test/ui/async-await/issue-71137.rs
@@ -0,0 +1,21 @@
+// edition:2018
+
+use std::future::Future;
+use std::sync::Mutex;
+
+fn fake_spawn<F: Future + Send + 'static>(f: F) { }
+
+async fn wrong_mutex() {
+  let m = Mutex::new(1);
+  {
+    let mut guard = m.lock().unwrap();
+    (async { "right"; }).await;
+    *guard += 1;
+  }
+
+  (async { "wrong"; }).await;
+}
+
+fn main() {
+  fake_spawn(wrong_mutex()); //~ Error future cannot be sent between threads safely
+}
diff --git a/src/test/ui/async-await/issue-71137.stderr b/src/test/ui/async-await/issue-71137.stderr
new file mode 100644
index 00000000000..788a9bc2c7e
--- /dev/null
+++ b/src/test/ui/async-await/issue-71137.stderr
@@ -0,0 +1,23 @@
+error: future cannot be sent between threads safely
+  --> $DIR/issue-71137.rs:20:3
+   |
+LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
+   |                           ---- required by this bound in `fake_spawn`
+...
+LL |   fake_spawn(wrong_mutex());
+   |   ^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
+   |
+   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, i32>`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/issue-71137.rs:12:5
+   |
+LL |     let mut guard = m.lock().unwrap();
+   |         --------- has type `std::sync::MutexGuard<'_, i32>` which is not `Send`
+LL |     (async { "right"; }).await;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later
+LL |     *guard += 1;
+LL |   }
+   |   - `mut guard` is later dropped here
+
+error: aborting due to previous error
+