From c83bd8b5f3207b25207408be24fc940afc3d8c24 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 5 Jun 2025 10:33:13 +0000 Subject: [PATCH] wfcheck closures --- compiler/rustc_hir_analysis/src/check/check.rs | 9 +++++++++ compiler/rustc_hir_analysis/src/check/wfcheck.rs | 5 ++++- compiler/rustc_hir_analysis/src/collect.rs | 11 ----------- compiler/rustc_middle/src/hir/mod.rs | 9 +++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 6a2d353dbbbc..bcf0353498ee 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -860,6 +860,15 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } + DefKind::Closure => { + // This is guaranteed to be called by metadata encoding, + // we still call it in wfcheck eagerly to ensure errors in codegen + // attrs prevent lints from spamming the output. + tcx.ensure_ok().codegen_fn_attrs(def_id); + // We do not call `type_of` for closures here as that + // depends on typecheck and would therefore hide + // any further errors in case one typeck fails. + } _ => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3e872607e319..91486a1a0e49 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -195,7 +195,9 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua hir::Node::TraitItem(item) => check_trait_item(tcx, item), hir::Node::ImplItem(item) => check_impl_item(tcx, item), hir::Node::ForeignItem(item) => check_foreign_item(tcx, item), - hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)), + hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => { + Ok(crate::check::check::check_item_type(tcx, def_id)) + } _ => unreachable!("{node:?}"), }; @@ -2411,6 +2413,7 @@ fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { .and( items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)), ) + .and(items.par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item))) .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item))); super::entry::check_for_entry_fn(tcx); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index bab8732f0b15..e2ef7b90ff49 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -287,17 +287,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { intravisit::walk_item(self, item); } - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = expr.kind { - self.tcx.ensure_ok().generics_of(closure.def_id); - self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id); - // We do not call `type_of` for closures here as that - // depends on typecheck and would therefore hide - // any further errors in case one typeck fails. - } - intravisit::walk_expr(self, expr); - } - fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { lower_trait_item(self.tcx, trait_item.trait_item_id()); intravisit::walk_trait_item(self, trait_item); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a28dcb0cb8ef..d1f5caaafb2b 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -71,6 +71,7 @@ impl ModuleItems { self.opaques.iter().copied() } + /// Closures and inline consts pub fn nested_bodies(&self) -> impl Iterator { self.nested_bodies.iter().copied() } @@ -79,6 +80,14 @@ impl ModuleItems { self.owners().map(|id| id.def_id) } + /// Closures and inline consts + pub fn par_nested_bodies( + &self, + f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id)) + } + pub fn par_items( &self, f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,