diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 765bb7a362e5a..9fc323ca0aeba 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -862,7 +862,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 @@ -886,7 +886,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(..) @@ -1228,11 +1228,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, @@ -1345,12 +1345,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(def_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) { @@ -1405,7 +1406,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 { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index da93f7f8ae653..33c3d61fbed9e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2467,10 +2467,16 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn is_const_fn_raw(self, def_id: DefId) -> bool { - matches!( - self.def_kind(def_id), - DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure - ) && self.constness(def_id) == hir::Constness::Const + let def_kind = self.def_kind(def_id); + if def_kind == DefKind::Closure + && !self.is_coroutine(def_id) + && self.constness(def_id) == hir::Constness::Const + { + true + } else { + matches!(def_kind, DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..)) + && self.constness(def_id) == hir::Constness::Const + } } #[inline] diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 19b6496b102ef..9040f89038e14 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -474,7 +474,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.to_def_id()) + { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi::Rust; diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 261d9dd448d47..0468ec04799b6 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -32,6 +32,7 @@ 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.to_def_id()) => return false, DefKind::Ctor(..) | DefKind::Closure => return true, DefKind::Fn | DefKind::AssocFn => {} _ => return false, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index fff760ba399be..5e3ea7dbdf385 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -323,6 +323,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.to_def_id()) => ConstQualifs::default(), DefKind::Fn | DefKind::AssocFn | DefKind::Closure if tcx.constness(def) == hir::Constness::Const || tcx.is_const_default_method(def.to_def_id()) =>