about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2025-04-27 18:53:00 +0900
committerGitHub <noreply@github.com>2025-04-27 18:53:00 +0900
commitd91ffb6da5c306150e53f73a361f69837bc39851 (patch)
treeee6518c803de044596ce0e095d38bd7cab0f4a57 /compiler/rustc_ty_utils/src
parent89bb181106817c7828c16dc75ce5b2a367664471 (diff)
parent1b315ad92df192895fb2d1f0532270c54f6f8436 (diff)
downloadrust-d91ffb6da5c306150e53f73a361f69837bc39851.tar.gz
rust-d91ffb6da5c306150e53f73a361f69837bc39851.zip
Merge pull request #2351 from rust-lang/rustc-pull
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs2
-rw-r--r--compiler/rustc_ty_utils/src/stalled_generators.rs54
2 files changed, 56 insertions, 0 deletions
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 35cc6f39856..57051e0df55 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -32,6 +32,7 @@ mod needs_drop;
 mod opaque_types;
 mod representability;
 pub mod sig_types;
+mod stalled_generators;
 mod structural_match;
 mod ty;
 
@@ -50,4 +51,5 @@ pub fn provide(providers: &mut Providers) {
     ty::provide(providers);
     instance::provide(providers);
     structural_match::provide(providers);
+    stalled_generators::provide(providers);
 }
diff --git a/compiler/rustc_ty_utils/src/stalled_generators.rs b/compiler/rustc_ty_utils/src/stalled_generators.rs
new file mode 100644
index 00000000000..8b45e8b0f6f
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/stalled_generators.rs
@@ -0,0 +1,54 @@
+use rustc_hir as hir;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit;
+use rustc_hir::intravisit::Visitor;
+use rustc_middle::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
+
+fn stalled_generators_within<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    item: LocalDefId,
+) -> &'tcx ty::List<LocalDefId> {
+    if !tcx.next_trait_solver_globally() {
+        return ty::List::empty();
+    }
+
+    let body = tcx.hir_body_owned_by(item);
+    let mut collector =
+        StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] };
+    collector.visit_body(body);
+    tcx.mk_local_def_ids(&collector.stalled_coroutines)
+}
+
+struct StalledGeneratorVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    root_def_id: DefId,
+    stalled_coroutines: Vec<LocalDefId>,
+}
+
+impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> {
+    fn visit_nested_body(&mut self, id: hir::BodyId) {
+        if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id())
+            == self.root_def_id
+        {
+            let body = self.tcx.hir_body(id);
+            self.visit_body(body);
+        }
+    }
+
+    fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
+        if let hir::ExprKind::Closure(&hir::Closure {
+            def_id,
+            kind: hir::ClosureKind::Coroutine(_),
+            ..
+        }) = ex.kind
+        {
+            self.stalled_coroutines.push(def_id);
+        }
+        intravisit::walk_expr(self, ex);
+    }
+}
+
+pub(super) fn provide(providers: &mut Providers) {
+    *providers = Providers { stalled_generators_within, ..*providers };
+}