From ef788bc2765d2c0c6710efc793827a89c5156612 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Sat, 12 Nov 2022 19:48:12 +0100 Subject: [PATCH] Thread `GeneratorKind` through to symbol mangling The current symbol mangling (legacy and v0) do not differentiate between closures and async fns / blocks, which is suboptimal when looking at debuginfo or stack traces. This lays the groundwork to eventually add these special kinds of closures to the mangling scheme. --- .../src/debuginfo/type_names.rs | 4 +-- .../src/interpret/eval_context.rs | 4 +-- compiler/rustc_hir/src/definitions.rs | 9 +++--- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/print/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 19 +++++++++--- .../src/typeid/typeid_itanium_cxx_abi.rs | 30 +++++++++---------- compiler/rustc_symbol_mangling/src/v0.rs | 12 +++++++- 9 files changed, 53 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 8647fbace2a75..edb656093203c 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -573,8 +573,8 @@ fn push_unqualified_item_name( DefPathData::CrateRoot => { output.push_str(tcx.crate_name(def_id.krate).as_str()); } - DefPathData::ClosureExpr => { - let label = generator_kind_label(tcx.generator_kind(def_id)); + DefPathData::ClosureExpr(generator_kind) => { + let label = generator_kind_label(generator_kind); push_disambiguated_special_name( label, diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index f7d64f6d4f48a..7a7adb8740f9d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -253,8 +253,8 @@ impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> { 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::ClosureExpr + if let DefPathData::ClosureExpr(_) = + tcx.def_key(self.instance.def_id()).disambiguated_data.data { write!(f, "inside closure")?; } else { diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d85ac960f9b2f..dde124dd5dd40 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,6 +7,7 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::def_path_hash_map::DefPathHashMap; +use crate::GeneratorKind; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; @@ -272,7 +273,7 @@ pub enum DefPathData { /// Something in the lifetime namespace. LifetimeNs(Symbol), /// A closure expression. - ClosureExpr, + ClosureExpr(Option), // Subportions of items: /// Implicit constructor for a unit or tuple-like struct or enum variant. @@ -403,8 +404,8 @@ impl DefPathData { match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait => None, + Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr(..) | Ctor + | AnonConst | ImplTrait => None, } } @@ -420,7 +421,7 @@ impl DefPathData { ForeignMod => DefPathDataName::Anon { namespace: kw::Extern }, Use => DefPathDataName::Anon { namespace: kw::Use }, GlobalAsm => DefPathDataName::Anon { namespace: sym::global_asm }, - ClosureExpr => DefPathDataName::Anon { namespace: sym::closure }, + ClosureExpr(..) => DefPathDataName::Anon { namespace: sym::closure }, Ctor => DefPathDataName::Anon { namespace: sym::constructor }, AnonConst => DefPathDataName::Anon { namespace: sym::constant }, ImplTrait => DefPathDataName::Anon { namespace: sym::opaque }, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ae0f158ede99a..b8a17dc13d22c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -204,7 +204,7 @@ impl<'tcx> InstanceDef<'tcx> { }; matches!( tcx.def_key(def_id).disambiguated_data.data, - DefPathData::Ctor | DefPathData::ClosureExpr + DefPathData::Ctor | DefPathData::ClosureExpr(..) ) } diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 44b9548db89c8..b798302c15fa9 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -139,7 +139,7 @@ pub trait Printer<'tcx>: Sized { match key.disambiguated_data.data { // Closures' own generics are only captures, don't print them. - DefPathData::ClosureExpr => {} + DefPathData::ClosureExpr(..) => {} // This covers both `DefKind::AnonConst` and `DefKind::InlineConst`. // Anon consts doesn't have their own generics, and inline consts' own // generics are their inferred types, so don't print them. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2432b5175197b..b7234893c1484 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1638,7 +1638,7 @@ fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace { DefPathData::ValueNs(..) | DefPathData::AnonConst - | DefPathData::ClosureExpr + | DefPathData::ClosureExpr(..) | DefPathData::Ctor => Namespace::ValueNS, DefPathData::MacroNs(..) => Namespace::MacroNS, diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index d36e0f61d9161..dd82ba6a05920 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -4,6 +4,7 @@ use rustc_ast::*; use rustc_expand::expand::AstFragment; use rustc_hir::def_id::LocalDefId; use rustc_hir::definitions::*; +use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::sym; use rustc_span::Span; @@ -151,7 +152,9 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { // then the closure_def will never be used, and we should avoid generating a // def-id for it. if let Some(body) = body { - let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); + let generator_kind = Some(GeneratorKind::Async(AsyncGeneratorKind::Fn)); + let closure_def = + self.create_def(closure_id, DefPathData::ClosureExpr(generator_kind), span); self.with_parent(closure_def, |this| this.visit_block(body)); } return; @@ -265,16 +268,24 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ExprKind::Closure(_, _, asyncness, ..) => { // Async closures desugar to closures inside of closures, so // we must create two defs. - let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); + let closure_def = + self.create_def(expr.id, DefPathData::ClosureExpr(None), expr.span); match asyncness { Async::Yes { closure_id, .. } => { - self.create_def(closure_id, DefPathData::ClosureExpr, expr.span) + let generator_kind = + Some(GeneratorKind::Async(AsyncGeneratorKind::Closure)); + self.create_def( + closure_id, + DefPathData::ClosureExpr(generator_kind), + expr.span, + ) } Async::No => closure_def, } } ExprKind::Async(_, async_id, _) => { - self.create_def(async_id, DefPathData::ClosureExpr, expr.span) + let generator_kind = Some(GeneratorKind::Async(AsyncGeneratorKind::Block)); + self.create_def(async_id, DefPathData::ClosureExpr(generator_kind), expr.span) } _ => self.parent_def, }; diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 6aa031c8378e6..f0c9c13163151 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -9,7 +9,7 @@ use bitflags::bitflags; use core::fmt::Display; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; -use rustc_hir as hir; +use rustc_hir::definitions::DefPathData; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ self, Binder, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind, @@ -388,20 +388,20 @@ fn encode_ty_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> String { def_path.data.reverse(); for disambiguated_data in &def_path.data { s.push('N'); - s.push_str(match disambiguated_data.data { - hir::definitions::DefPathData::Impl => "I", // Not specified in v0's - hir::definitions::DefPathData::ForeignMod => "F", // Not specified in v0's - hir::definitions::DefPathData::TypeNs(..) => "t", - hir::definitions::DefPathData::ValueNs(..) => "v", - hir::definitions::DefPathData::ClosureExpr => "C", - hir::definitions::DefPathData::Ctor => "c", - hir::definitions::DefPathData::AnonConst => "k", - hir::definitions::DefPathData::ImplTrait => "i", - hir::definitions::DefPathData::CrateRoot - | hir::definitions::DefPathData::Use - | hir::definitions::DefPathData::GlobalAsm - | hir::definitions::DefPathData::MacroNs(..) - | hir::definitions::DefPathData::LifetimeNs(..) => { + s.push(match disambiguated_data.data { + DefPathData::Impl => 'I', // Not specified in v0's + DefPathData::ForeignMod => 'F', // Not specified in v0's + DefPathData::TypeNs(..) => 't', + DefPathData::ValueNs(..) => 'v', + DefPathData::ClosureExpr(_generator_kind) => 'C', + DefPathData::Ctor => 'c', + DefPathData::AnonConst => 'k', + DefPathData::ImplTrait => 'i', + DefPathData::CrateRoot + | DefPathData::Use + | DefPathData::GlobalAsm + | DefPathData::MacroNs(..) + | DefPathData::LifetimeNs(..) => { bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data); } }); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index e540e2f2a2192..3ffac7b935f38 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -779,7 +779,17 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // Uppercase categories are more stable than lowercase ones. DefPathData::TypeNs(_) => 't', DefPathData::ValueNs(_) => 'v', - DefPathData::ClosureExpr => 'C', + DefPathData::ClosureExpr(generator_kind) => { + // FIXME(swatinem): figure out how to move forward with closure-type aware mangling + // use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + match generator_kind { + // Some(GeneratorKind::Async(AsyncGeneratorKind::Block)) => 'B', + // Some(GeneratorKind::Async(AsyncGeneratorKind::Closure)) => 'a', + // Some(GeneratorKind::Async(AsyncGeneratorKind::Fn)) => 'A', + // Some(GeneratorKind::Gen) => 'G', + _ => 'C', + } + } DefPathData::Ctor => 'c', DefPathData::AnonConst => 'k', DefPathData::ImplTrait => 'i',