diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3ec07572d1d60..417a55cdafad5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2083,13 +2083,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .opt_item_name(self.mir_def_id().to_def_id()) .map(|name| format!("function `{name}`")) .unwrap_or_else(|| { - match &self.infcx.tcx.def_kind(self.mir_def_id()) { - DefKind::Closure - if self - .infcx - .tcx - .is_coroutine(self.mir_def_id().to_def_id()) => - { + let def_id = self.mir_def_id(); + match &self.infcx.tcx.def_kind(def_id) { + DefKind::Closure if self.infcx.tcx.is_coroutine(def_id) => { "enclosing coroutine" } DefKind::Closure => "enclosing closure", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 80575e30a8d23..f787a61eb080f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2663,9 +2663,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id); let parent_args = match tcx.def_kind(def_id) { - DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => { - args.as_coroutine().parent_args() - } + DefKind::Closure if tcx.is_coroutine(def_id) => args.as_coroutine().parent_args(), DefKind::Closure => args.as_closure().parent_args(), DefKind::InlineConst => args.as_inline_const().parent_args(), other => bug!("unexpected item {:?}", other), diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d2e96ac74df84..a55aad533ca60 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1446,7 +1446,7 @@ fn opaque_type_cycle_error( label_match(capture.place.ty(), capture.get_path_span(tcx)); } // Label any coroutine locals that capture the opaque - if tcx.is_coroutine(closure_def_id) + if tcx.is_coroutine(closure_local_did) && let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id) { for interior_ty in &coroutine_layout.field_tys { @@ -1467,7 +1467,7 @@ pub(super) fn check_coroutine_obligations( tcx: TyCtxt<'_>, def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - debug_assert!(tcx.is_coroutine(def_id.to_def_id())); + debug_assert!(tcx.is_coroutine(def_id)); let typeck = tcx.typeck(def_id); let param_env = tcx.param_env(def_id); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 559874641c3d5..e3d847c5527d1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -762,7 +762,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { }); tcx.hir().par_body_owners(|def_id| { - if tcx.is_coroutine(def_id.to_def_id()) { + if tcx.is_coroutine(def_id) { tcx.ensure().mir_coroutine_witnesses(def_id); tcx.ensure().check_coroutine_obligations(def_id); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index aca7a66596e64..3b0556b680351 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -875,7 +875,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { } } -fn should_encode_attrs(def_kind: DefKind) -> bool { +fn should_encode_attrs(def_kind: DefKind, is_coroutine: bool) -> bool { match def_kind { DefKind::Mod | DefKind::Struct @@ -899,7 +899,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { // closures from upstream crates, too. This is used by // https://github.com/model-checking/kani and is not a performance // or maintenance issue for us. - DefKind::Closure => true, + DefKind::Closure => !is_coroutine, DefKind::TyParam | DefKind::ConstParam | DefKind::Ctor(..) @@ -1058,7 +1058,7 @@ fn should_encode_mir( | DefKind::Static(..) | DefKind::Const => (true, false), // Coroutines require optimized MIR to compute layout. - DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true), + DefKind::Closure if tcx.is_coroutine(def_id) => (false, true), // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { let generics = tcx.generics_of(def_id); @@ -1241,11 +1241,11 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { } } -fn should_encode_constness(def_kind: DefKind) -> bool { +fn should_encode_constness(def_kind: DefKind, is_coroutine: bool) -> bool { match def_kind { + DefKind::Closure => !is_coroutine, DefKind::Fn | DefKind::AssocFn - | DefKind::Closure | DefKind::Impl { of_trait: true } | DefKind::Variant | DefKind::Ctor(..) => true, @@ -1358,12 +1358,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); + let is_coroutine = def_kind == DefKind::Closure && tcx.is_coroutine(local_id); self.tables.def_kind.set_some(def_id.index, def_kind); if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); } - if should_encode_attrs(def_kind) { + if should_encode_attrs(def_kind, is_coroutine) { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { @@ -1418,7 +1419,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir { record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } - if should_encode_constness(def_kind) { + if should_encode_constness(def_kind, is_coroutine) { self.tables.constness.set_some(def_id.index, self.tcx.constness(def_id)); } if let DefKind::Fn | DefKind::AssocFn = def_kind { @@ -1639,7 +1640,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); - if self.tcx.is_coroutine(def_id.to_def_id()) + if self.tcx.is_coroutine(def_id) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); @@ -1666,7 +1667,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); - if self.tcx.is_coroutine(def_id.to_def_id()) + if self.tcx.is_coroutine(def_id) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6807eacb7f177..e266bef6b266e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -843,7 +843,7 @@ impl<'tcx> TyCtxt<'tcx> { self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did) } - pub fn is_coroutine(self, def_id: DefId) -> bool { + pub fn is_coroutine(self, def_id: LocalDefId) -> bool { self.coroutine_kind(def_id).is_some() } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e0199fb876717..1726e4ce8ffa1 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -480,7 +480,9 @@ fn construct_fn<'tcx>( }; let mut abi = fn_sig.abi; - if let DefKind::Closure = tcx.def_kind(fn_def) { + if let DefKind::Closure = tcx.def_kind(fn_def) + && !tcx.is_coroutine(fn_def) + { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi::Rust; diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index fa3dd2afa85db..74442fd5bf4bb 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -37,7 +37,7 @@ pub(crate) fn thir_body( // The resume argument may be missing, in that case we need to provide it here. // It will always be `()` in this case. - if tcx.is_coroutine(owner_def.to_def_id()) && body.params.is_empty() { + if tcx.is_coroutine(owner_def) && body.params.is_empty() { cx.thir.params.push(Param { ty: Ty::new_unit(tcx), pat: None, @@ -119,7 +119,7 @@ impl<'tcx> Cx<'tcx> { fn closure_env_param(&self, owner_def: LocalDefId, owner_id: HirId) -> Option> { match self.tcx.def_kind(owner_def) { - DefKind::Closure if self.tcx.is_coroutine(owner_def.to_def_id()) => { + DefKind::Closure if self.tcx.is_coroutine(owner_def) => { let coroutine_ty = self.typeck_results.node_type(owner_id); let coroutine_param = Param { ty: coroutine_ty, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 99eecb567f277..fb5777ceb8e1d 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -61,7 +61,7 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint { // FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles // computing their layout. - if tcx.is_coroutine(def_id.to_def_id()) { + if def_kind == DefKind::Closure && tcx.is_coroutine(def_id) { trace!("ConstPropLint skipped for coroutine {:?}", def_id); return; } diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 5f01b841867ea..ee4949e5818dc 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -42,6 +42,14 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { _ => {} } + // This just reproduces the logic from Instance::requires_inline. + match tcx.def_kind(def_id) { + DefKind::Closure if tcx.is_coroutine(def_id) => return false, + DefKind::Ctor(..) | DefKind::Closure => return true, + DefKind::Fn | DefKind::AssocFn => {} + _ => return false, + } + // Don't do any inference when incremental compilation is enabled; the additional inlining that // inference permits also creates more work for small edits. if tcx.sess.opts.incremental.is_some() { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5562ae7f3bdef..cded649de68ee 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -324,6 +324,7 @@ fn mir_promoted( // Also this means promotion can rely on all const checks having been done. let const_qualifs = match tcx.def_kind(def) { + DefKind::Closure if tcx.is_coroutine(def) => ConstQualifs::default(), DefKind::Fn | DefKind::AssocFn | DefKind::Closure if tcx.constness(def) == hir::Constness::Const || tcx.is_const_default_method(def.to_def_id()) => @@ -396,7 +397,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't /// end up missing the source MIR due to stealing happening. fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { - if tcx.is_coroutine(def.to_def_id()) { + if tcx.is_coroutine(def) { tcx.ensure_with_value().mir_coroutine_witnesses(def); } let mir_borrowck = tcx.mir_borrowck(def);