Skip to content

Commit

Permalink
use closure.movability to judge coroutine
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanjoi committed Nov 29, 2023
1 parent efa2fff commit 77f9a77
Show file tree
Hide file tree
Showing 13 changed files with 35 additions and 37 deletions.
10 changes: 3 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2071,13 +2071,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",
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2678,9 +2678,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),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,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 {
Expand All @@ -1470,7 +1470,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);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,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);
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,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);
Expand Down Expand Up @@ -1345,7 +1345,7 @@ 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);
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);
Expand Down Expand Up @@ -1627,7 +1627,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);
Expand All @@ -1654,7 +1654,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);
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,8 +807,18 @@ 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 {
self.coroutine_kind(def_id).is_some()
pub fn is_coroutine(self, def_id: LocalDefId) -> bool {
let hir_id = self.local_def_id_to_hir_id(def_id);
let Some(node) = self.hir().find(hir_id) else {
return false;
};
if let hir::Node::Expr(expr) = node
&& let hir::ExprKind::Closure(closure) = expr.kind
{
closure.movability.is_some()
} else {
false
}
}

/// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
Expand Down
14 changes: 4 additions & 10 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2464,16 +2464,10 @@ impl<'tcx> TyCtxt<'tcx> {

#[inline]
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
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
}
matches!(
self.def_kind(def_id),
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure
) && self.constness(def_id) == hir::Constness::Const
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ fn construct_fn<'tcx>(

let mut abi = fn_sig.abi;
if let DefKind::Closure = tcx.def_kind(fn_def)
&& !tcx.is_coroutine(fn_def.to_def_id())
&& !tcx.is_coroutine(fn_def)
{
// HACK(eddyb) Avoid having RustCall on closures,
// as it adds unnecessary (and wrong) auto-tupling.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -119,7 +119,7 @@ impl<'tcx> Cx<'tcx> {

fn closure_env_param(&self, owner_def: LocalDefId, owner_id: HirId) -> Option<Param<'tcx>> {
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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {

// 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!("ConstProp skipped for coroutine {:?}", def_id);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/const_prop_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +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::Closure if tcx.is_coroutine(def_id) => return false,
DefKind::Ctor(..) | DefKind::Closure => return true,
DefKind::Fn | DefKind::AssocFn => {}
_ => return false,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +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::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()) =>
Expand Down Expand Up @@ -396,7 +396,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<Body<'_>> {
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);
Expand Down

0 comments on commit 77f9a77

Please sign in to comment.