From e08944fdafac547aecc1a94e44cc978a202eec86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 13 Dec 2019 15:27:55 -0800 Subject: [PATCH] Do not ICE on unnamed future --- src/librustc/hir/map/mod.rs | 13 +++++++--- src/librustc/traits/error_reporting.rs | 2 +- .../async-await/issue-67252-unnamed-future.rs | 24 +++++++++++++++++++ .../issue-67252-unnamed-future.stderr | 22 +++++++++++++++++ 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/async-await/issue-67252-unnamed-future.rs create mode 100644 src/test/ui/async-await/issue-67252-unnamed-future.stderr diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 5bf5a93ad0102..69e772697f846 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1016,8 +1016,8 @@ impl<'hir> Map<'hir> { } } - pub fn name(&self, id: HirId) -> Name { - match self.get(id) { + pub fn opt_name(&self, id: HirId) -> Option { + Some(match self.get(id) { Node::Item(i) => i.ident.name, Node::ForeignItem(fi) => fi.ident.name, Node::ImplItem(ii) => ii.ident.name, @@ -1028,7 +1028,14 @@ impl<'hir> Map<'hir> { Node::GenericParam(param) => param.name.ident().name, Node::Binding(&Pat { kind: PatKind::Binding(_, _, l, _), .. }) => l.name, Node::Ctor(..) => self.name(self.get_parent_item(id)), - _ => bug!("no name for {}", self.node_to_string(id)) + _ => return None, + }) + } + + pub fn name(&self, id: HirId) -> Name { + match self.opt_name(id) { + Some(name) => name, + None => bug!("no name for {}", self.node_to_string(id)), } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 6a111895b5637..1a92d1eb8c5d3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2353,7 +2353,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let message = if let Some(name) = last_generator .and_then(|generator_did| self.tcx.parent(generator_did)) .and_then(|parent_did| self.tcx.hir().as_local_hir_id(parent_did)) - .map(|parent_hir_id| self.tcx.hir().name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir().opt_name(parent_hir_id)) { format!("future returned by `{}` is not {}", name, trait_name) } else { diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.rs b/src/test/ui/async-await/issue-67252-unnamed-future.rs new file mode 100644 index 0000000000000..1a7ff613341ec --- /dev/null +++ b/src/test/ui/async-await/issue-67252-unnamed-future.rs @@ -0,0 +1,24 @@ +// edition:2018 +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +fn spawn(_: T) {} + +pub struct AFuture; +impl Future for AFuture{ + type Output = (); + + fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<()> { + unimplemented!() + } +} + +async fn foo() { + spawn(async { //~ ERROR future cannot be sent between threads safely + let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` + AFuture.await; + }); +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr new file mode 100644 index 0000000000000..24aedeb96597a --- /dev/null +++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr @@ -0,0 +1,22 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-67252-unnamed-future.rs:18:5 + | +LL | fn spawn(_: T) {} + | ----- ---- required by this bound in `spawn` +... +LL | spawn(async { + | ^^^^^ future is not `Send` + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*mut ()` +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 ()` +LL | AFuture.await; + | ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later +LL | }); + | - `_a` is later dropped here + +error: aborting due to previous error +