Skip to content

Add coroutine info to v0 symbol mangling (via DefPath/DefPathData) #143259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, MultiSpan, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def::{CoroutineDefKind, DefKind, Res};
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr};
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField};
use rustc_middle::bug;
Expand Down Expand Up @@ -2983,15 +2983,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.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()) =>
{
"enclosing coroutine"
}
DefKind::Closure => "enclosing closure",
DefKind::Closure { coroutine_kind } => match coroutine_kind {
None => "enclosing closure",
Some(CoroutineDefKind::Desugared(
hir::CoroutineDesugaring::Async,
)) => "enclosing async closure",
Some(CoroutineDefKind::Desugared(
hir::CoroutineDesugaring::Gen,
)) => "enclosing gen closure",
Some(CoroutineDefKind::Desugared(
hir::CoroutineDesugaring::AsyncGen,
)) => "enclosing async gen closure",
Some(CoroutineDefKind::Coroutine) => "enclosing coroutine",
},
kind => bug!("expected closure or coroutine, found {:?}", kind),
}
.to_string()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2515,7 +2515,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// We don't want to dispatch on 3 different kind of closures here, so take
// advantage of the fact that the `parent_args` is the same length as the
// `typeck_root_args`.
DefKind::Closure => {
DefKind::Closure { .. } => {
// FIXME(async_closures): It may be useful to add a debug assert here
// to actually call `type_of` and check the `parent_args` are the same
// length as the `typeck_root_args`.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ fn push_unqualified_item_name(
DefPathData::CrateRoot => {
output.push_str(tcx.crate_name(def_id.krate).as_str());
}
DefPathData::Closure => {
DefPathData::Closure { .. } => {
let label = coroutine_kind_label(tcx.coroutine_kind(def_id));

push_disambiguated_special_name(
Expand All @@ -619,7 +619,7 @@ fn push_unqualified_item_name(
DefPathDataName::Named(name) => {
output.push_str(name.as_str());
}
DefPathDataName::Anon { namespace } => {
DefPathDataName::Anon { namespace, kind: _ } => {
push_disambiguated_special_name(
namespace.as_str(),
disambiguated_data.disambiguator,
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,10 @@ pub struct FrameInfo<'tcx> {
impl<'tcx> fmt::Display for FrameInfo<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
if matches!(
tcx.def_key(self.instance.def_id()).disambiguated_data.data,
DefPathData::Closure { .. }
) {
write!(f, "inside closure")
} else {
// Note: this triggers a `must_produce_diag` state, which means that if we ever
Expand All @@ -232,7 +235,10 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
impl<'tcx> FrameInfo<'tcx> {
pub fn as_note(&self, tcx: TyCtxt<'tcx>) -> errors::FrameNote {
let span = self.span;
if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
if matches!(
tcx.def_key(self.instance.def_id()).disambiguated_data.data,
DefPathData::Closure { .. }
) {
errors::FrameNote {
where_: "closure",
span,
Expand Down
60 changes: 53 additions & 7 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use rustc_ast::NodeId;
use rustc_data_structures::stable_hasher::ToStableHashKey;
use rustc_data_structures::unord::UnordMap;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::Symbol;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::hygiene::MacroKind;
use rustc_span::{Symbol, kw, sym};

use crate::definitions::DefPathData;
use crate::hir;
Expand Down Expand Up @@ -45,6 +45,14 @@ pub enum NonMacroAttrKind {
DeriveHelperCompat,
}

#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum CoroutineDefKind {
/// A desugared coroutine from `async` or similar
Desugared(hir::CoroutineDesugaring),
/// An explicit `#[coroutine]`
Coroutine,
}

/// What kind of definition something is; e.g., `mod` vs `struct`.
/// `enum DefPathData` may need to be updated if a new variant is added here.
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
Expand Down Expand Up @@ -140,7 +148,9 @@ pub enum DefKind {
/// which makes it difficult to distinguish these during def collection. Therefore,
/// we treat them all the same, and code which needs to distinguish them can match
/// or `hir::ClosureKind` or `type_of`.
Closure,
Closure {
coroutine_kind: Option<CoroutineDefKind>,
},
/// The definition of a synthetic coroutine body created by the lowering of a
/// coroutine-closure, such as an async closure.
SyntheticCoroutineBody,
Expand Down Expand Up @@ -185,7 +195,17 @@ impl DefKind {
DefKind::InlineConst => "inline constant",
DefKind::Field => "field",
DefKind::Impl { .. } => "implementation",
DefKind::Closure => "closure",
DefKind::Closure { coroutine_kind } => match coroutine_kind {
None => "closure",
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Async)) => {
"async closure"
}
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Gen)) => "gen closure",
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::AsyncGen)) => {
"async gen closure"
}
Some(CoroutineDefKind::Coroutine) => "coroutine",
},
DefKind::ExternCrate => "extern crate",
DefKind::GlobalAsm => "global assembly block",
DefKind::SyntheticCoroutineBody => "synthetic mir body",
Expand All @@ -209,6 +229,15 @@ impl DefKind {
| DefKind::InlineConst
| DefKind::ExternCrate => "an",
DefKind::Macro(macro_kind) => macro_kind.article(),

DefKind::Closure { coroutine_kind } => match coroutine_kind {
None => "a",
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Async)) => "an",
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Gen)) => "a",
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::AsyncGen)) => "an",
Some(CoroutineDefKind::Coroutine) => "a",
},

_ => "a",
}
}
Expand Down Expand Up @@ -243,7 +272,7 @@ impl DefKind {
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::ExternCrate
| DefKind::Closure
| DefKind::Closure { .. }
| DefKind::Use
| DefKind::ForeignMod
| DefKind::GlobalAsm
Expand Down Expand Up @@ -290,7 +319,21 @@ impl DefKind {
DefKind::OpaqueTy => DefPathData::OpaqueTy,
DefKind::GlobalAsm => DefPathData::GlobalAsm,
DefKind::Impl { .. } => DefPathData::Impl,
DefKind::Closure => DefPathData::Closure,
DefKind::Closure { coroutine_kind } => match coroutine_kind {
None => DefPathData::Closure { coroutine_kind: None },
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Async)) => {
DefPathData::Closure { coroutine_kind: Some(kw::Async) }
}
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::Gen)) => {
DefPathData::Closure { coroutine_kind: Some(kw::Gen) }
}
Some(CoroutineDefKind::Desugared(hir::CoroutineDesugaring::AsyncGen)) => {
DefPathData::Closure { coroutine_kind: Some(sym::async_gen) }
}
Some(CoroutineDefKind::Coroutine) => {
DefPathData::Closure { coroutine_kind: Some(sym::coroutine) }
}
},
DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody,
}
}
Expand All @@ -299,7 +342,10 @@ impl DefKind {
pub fn is_fn_like(self) -> bool {
matches!(
self,
DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody
DefKind::Fn
| DefKind::AssocFn
| DefKind::Closure { .. }
| DefKind::SyntheticCoroutineBody
)
}

Expand All @@ -309,7 +355,7 @@ impl DefKind {
DefKind::Fn
| DefKind::AssocFn
| DefKind::Ctor(..)
| DefKind::Closure
| DefKind::Closure { .. }
| DefKind::Static { .. }
| DefKind::SyntheticCoroutineBody => true,
DefKind::Mod
Expand Down
58 changes: 37 additions & 21 deletions compiler/rustc_hir/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,20 @@ impl DisambiguatedDefPathData {
writer.write_str(name.as_str())
}
}
DefPathDataName::Anon { namespace } => {
if let DefPathData::AnonAssocTy(method) = self.data {
DefPathDataName::Anon { namespace, kind } => match (self.data, kind) {
(DefPathData::AnonAssocTy(method), None) => {
write!(writer, "{}::{{{}#{}}}", method, namespace, self.disambiguator)
} else {
}
(DefPathData::AnonAssocTy(method), Some(kind)) => {
write!(writer, "{}::{{{}:{}#{}}}", method, namespace, kind, self.disambiguator)
}
(_, None) => {
write!(writer, "{{{}#{}}}", namespace, self.disambiguator)
}
}
(_, Some(kind)) => {
write!(writer, "{{{}:{}#{}}}", namespace, kind, self.disambiguator)
}
},
}
}
}
Expand Down Expand Up @@ -299,7 +306,7 @@ pub enum DefPathData {
/// Something in the lifetime namespace.
LifetimeNs(Symbol),
/// A closure expression.
Closure,
Closure { coroutine_kind: Option<Symbol> },

// Subportions of items:
/// Implicit constructor for a unit or tuple-like struct or enum variant.
Expand Down Expand Up @@ -440,7 +447,7 @@ impl Definitions {
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum DefPathDataName {
Named(Symbol),
Anon { namespace: Symbol },
Anon { namespace: Symbol, kind: Option<Symbol> },
}

impl DefPathData {
Expand All @@ -450,12 +457,13 @@ impl DefPathData {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
| OpaqueLifetime(name) => Some(name),

Closure { coroutine_kind } => coroutine_kind,

Impl
| ForeignMod
| CrateRoot
| Use
| GlobalAsm
| Closure
| Ctor
| AnonConst
| OpaqueTy
Expand All @@ -471,12 +479,13 @@ impl DefPathData {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
| OpaqueLifetime(name) => Some(name),

Closure { coroutine_kind } => coroutine_kind,

Impl
| ForeignMod
| CrateRoot
| Use
| GlobalAsm
| Closure
| Ctor
| AnonConst
| OpaqueTy
Expand All @@ -491,18 +500,22 @@ impl DefPathData {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
| OpaqueLifetime(name) => DefPathDataName::Named(name),
// Note that this does not show up in user print-outs.
CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
Impl => DefPathDataName::Anon { namespace: kw::Impl },
ForeignMod => DefPathDataName::Anon { namespace: kw::Extern },
Use => DefPathDataName::Anon { namespace: kw::Use },
GlobalAsm => DefPathDataName::Anon { namespace: sym::global_asm },
Closure => DefPathDataName::Anon { namespace: sym::closure },
Ctor => DefPathDataName::Anon { namespace: sym::constructor },
AnonConst => DefPathDataName::Anon { namespace: sym::constant },
OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque },
AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc },
SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic },
NestedStatic => DefPathDataName::Anon { namespace: sym::nested },
CrateRoot => DefPathDataName::Anon { namespace: kw::Crate, kind: None },
Impl => DefPathDataName::Anon { namespace: kw::Impl, kind: None },
ForeignMod => DefPathDataName::Anon { namespace: kw::Extern, kind: None },
Use => DefPathDataName::Anon { namespace: kw::Use, kind: None },
GlobalAsm => DefPathDataName::Anon { namespace: sym::global_asm, kind: None },
Closure { coroutine_kind } => {
DefPathDataName::Anon { namespace: sym::closure, kind: coroutine_kind }
}
Ctor => DefPathDataName::Anon { namespace: sym::constructor, kind: None },
AnonConst => DefPathDataName::Anon { namespace: sym::constant, kind: None },
OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque, kind: None },
AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc, kind: None },
SyntheticCoroutineBody => {
DefPathDataName::Anon { namespace: sym::synthetic, kind: None }
}
NestedStatic => DefPathDataName::Anon { namespace: sym::nested, kind: None },
}
}
}
Expand All @@ -512,7 +525,10 @@ impl fmt::Display for DefPathData {
match self.name() {
DefPathDataName::Named(name) => f.write_str(name.as_str()),
// FIXME(#70334): this will generate legacy {{closure}}, {{impl}}, etc
DefPathDataName::Anon { namespace } => write!(f, "{{{{{namespace}}}}}"),
DefPathDataName::Anon { namespace, kind: None } => write!(f, "{{{{{namespace}}}}}"),
DefPathDataName::Anon { namespace, kind: Some(n) } => {
write!(f, "{{{{{namespace}:{n}}}}}")
}
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
}
}
DefKind::Closure => {
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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2407,7 +2407,7 @@ fn lint_redundant_lifetimes<'tcx>(
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Closure
| DefKind::Closure { .. }
| DefKind::SyntheticCoroutineBody => return,
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2289,7 +2289,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
| DefKind::InlineConst
| DefKind::Field
| DefKind::Impl { .. }
| DefKind::Closure
| DefKind::Closure { .. }
| DefKind::ExternCrate
| DefKind::GlobalAsm
| DefKind::SyntheticCoroutineBody,
Expand Down
Loading
Loading