From 6721f9122e7139ce691ce87b226112c1ac9ecfd0 Mon Sep 17 00:00:00 2001 From: Wafarm Date: Sun, 18 Aug 2024 10:44:17 +0800 Subject: [PATCH] Check if enclosing body owner exists in `get_fn_id_for_return_block` --- compiler/rustc_middle/src/hir/map/mod.rs | 18 +++++++--- .../async-fn/recurse-ice-129215.rs | 9 +++++ .../async-fn/recurse-ice-129215.stderr | 34 +++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 tests/ui/async-await/async-fn/recurse-ice-129215.rs create mode 100644 tests/ui/async-await/async-fn/recurse-ice-129215.stderr diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0f85998204ccb..33f14ee6e1a07 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -246,14 +246,22 @@ impl<'hir> Map<'hir> { self.tcx.hir_node(hir_id).fn_sig() } - #[track_caller] - pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { + pub fn opt_enclosing_body_owner(self, hir_id: HirId) -> Option { for (_, node) in self.parent_iter(hir_id) { if let Some((def_id, _)) = node.associated_body() { - return def_id; + return Some(def_id); } } + None + } + + #[track_caller] + pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { + if let Some(hir_id) = self.opt_enclosing_body_owner(hir_id) { + return hir_id; + } + bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id); } @@ -554,7 +562,9 @@ impl<'hir> Map<'hir> { /// } /// ``` pub fn get_fn_id_for_return_block(self, id: HirId) -> Option { - let enclosing_body_owner = self.tcx.local_def_id_to_hir_id(self.enclosing_body_owner(id)); + // Id may not have a owner if it's a fn itself + let enclosing_body_owner = + self.tcx.local_def_id_to_hir_id(self.opt_enclosing_body_owner(id)?); // Return `None` if the `id` expression is not the returned value of the enclosing body let mut iter = [id].into_iter().chain(self.parent_id_iter(id)).peekable(); diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.rs b/tests/ui/async-await/async-fn/recurse-ice-129215.rs new file mode 100644 index 0000000000000..06a2d7be9efb5 --- /dev/null +++ b/tests/ui/async-await/async-fn/recurse-ice-129215.rs @@ -0,0 +1,9 @@ +//@ edition: 2021 + +async fn a() { + //~^ ERROR `()` is not a future + //~| ERROR mismatched types + a() //~ ERROR `()` is not a future +} + +fn main() {} diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr new file mode 100644 index 0000000000000..98c7be2a5a3f2 --- /dev/null +++ b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr @@ -0,0 +1,34 @@ +error[E0277]: `()` is not a future + --> $DIR/recurse-ice-129215.rs:6:5 + | +LL | a() + | ^^^ `()` is not a future + | + = help: the trait `Future` is not implemented for `()` + +error[E0277]: `()` is not a future + --> $DIR/recurse-ice-129215.rs:3:1 + | +LL | async fn a() { + | ^^^^^^^^^^^^ `()` is not a future + | + = help: the trait `Future` is not implemented for `()` + +error[E0308]: mismatched types + --> $DIR/recurse-ice-129215.rs:3:14 + | +LL | async fn a() { + | ______________^ +LL | | +LL | | +LL | | a() +LL | | } + | |_^ expected `()`, found `async` fn body + | + = note: expected unit type `()` + found `async` fn body `{async fn body of a()}` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`.