From 7d5b2e4926385bb247c4e1f2480258ca3faf4f10 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 18 Jun 2023 07:55:04 +0000 Subject: [PATCH 1/3] Make closure_saved_names_of_captured_variables a query. --- .../src/debuginfo/metadata.rs | 2 +- .../src/debuginfo/metadata/enums/mod.rs | 7 ++-- .../src/stable_hasher.rs | 14 +++++++- .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 2 ++ compiler/rustc_metadata/src/rmeta/mod.rs | 3 +- compiler/rustc_middle/src/arena.rs | 5 +++ compiler/rustc_middle/src/query/erase.rs | 4 +++ compiler/rustc_middle/src/query/mod.rs | 13 ++++++++ compiler/rustc_middle/src/ty/util.rs | 32 ------------------- compiler/rustc_mir_build/src/build/mod.rs | 23 +++++++++++++ compiler/rustc_mir_build/src/lib.rs | 2 ++ compiler/rustc_ty_utils/src/layout.rs | 2 +- 13 files changed, 71 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 1a8618e0c5577..4b88ab8a97a85 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1031,7 +1031,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( build_field_di_node( cx, closure_or_generator_di_node, - capture_name, + capture_name.as_str(), cx.size_and_align_of(up_var_ty), layout.fields.offset(index), DIFlags::FlagZero, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 9e0e847a15565..7a23fd31d1c6a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -324,7 +324,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( generator_type_di_node: &'ll DIType, generator_layout: &GeneratorLayout<'tcx>, state_specific_upvar_names: &IndexSlice>, - common_upvar_names: &[String], + common_upvar_names: &IndexSlice, ) -> &'ll DIType { let variant_name = GeneratorSubsts::variant_name(variant_index); let unique_type_id = UniqueTypeId::for_enum_variant_struct_type( @@ -380,12 +380,13 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( // Fields that are common to all states let common_fields: SmallVec<_> = generator_substs .prefix_tys() + .zip(common_upvar_names) .enumerate() - .map(|(index, upvar_ty)| { + .map(|(index, (upvar_ty, upvar_name))| { build_field_di_node( cx, variant_struct_type_di_node, - &common_upvar_names[index], + upvar_name.as_str(), cx.size_and_align_of(upvar_ty), generator_type_and_layout.fields.offset(index), DIFlags::FlagZero, diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 0c1fb7518fa3b..6d75b0fb8a0ca 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -1,6 +1,6 @@ use crate::sip128::SipHasher128; use rustc_index::bit_set::{self, BitSet}; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use smallvec::SmallVec; use std::fmt; use std::hash::{BuildHasher, Hash, Hasher}; @@ -597,6 +597,18 @@ where } } +impl HashStable for IndexSlice +where + T: HashStable, +{ + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.len().hash_stable(ctx, hasher); + for v in &self.raw { + v.hash_stable(ctx, hasher); + } + } +} + impl HashStable for IndexVec where T: HashStable, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 77f9fcfc5e6b4..848535fb39521 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -218,6 +218,7 @@ provide! { tcx, def_id, other, cdata, thir_abstract_const => { table } optimized_mir => { table } mir_for_ctfe => { table } + closure_saved_names_of_captured_variables => { table } mir_generator_witnesses => { table } promoted_mir => { table } def_span => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9c3b8780d97aa..12f3a0fc2c215 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1520,6 +1520,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] + <- tcx.closure_saved_names_of_captured_variables(def_id)); if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 66048f3ece747..b6b89b41a55fa 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -32,7 +32,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnIndex, MacroKind}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use std::marker::PhantomData; @@ -416,6 +416,7 @@ define_tables! { object_lifetime_default: Table>, optimized_mir: Table>>, mir_for_ctfe: Table>>, + closure_saved_names_of_captured_variables: Table>>, mir_generator_witnesses: Table>>, promoted_mir: Table>>>, thir_abstract_const: Table>>>, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 6c404fbb7c684..ac4cef34fdd3a 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -27,6 +27,11 @@ macro_rules! arena_types { rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> >, + [decode] closure_debuginfo: + rustc_index::IndexVec< + rustc_target::abi::FieldIdx, + rustc_span::symbol::Symbol, + >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, [decode] borrowck_result: rustc_middle::mir::BorrowCheckResult<'tcx>, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index fd02a16130fc5..7d962b92caa82 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -55,6 +55,10 @@ impl EraseType for &'_ ty::List { type Result = [u8; size_of::<*const ()>()]; } +impl EraseType for &'_ rustc_index::IndexSlice { + type Result = [u8; size_of::<&'static rustc_index::IndexSlice>()]; +} + impl EraseType for Result<&'_ T, traits::query::NoSolution> { type Result = [u8; size_of::>()]; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 132b11b29eb32..ee8f3201ddd2d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -531,6 +531,19 @@ rustc_queries! { } } + /// Returns names of captured upvars for closures and generators. + /// + /// Here are some examples: + /// - `name__field1__field2` when the upvar is captured by value. + /// - `_ref__name__field` when the upvar is captured by reference. + /// + /// For generators this only contains upvars that are shared by all states. + query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec { + arena_cache + desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + query mir_generator_witnesses(key: DefId) -> &'tcx Option> { arena_cache desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c9f69c37782e3..2e841e261fcc4 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -738,38 +738,6 @@ impl<'tcx> TyCtxt<'tcx> { if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } - /// Returns names of captured upvars for closures and generators. - /// - /// Here are some examples: - /// - `name__field1__field2` when the upvar is captured by value. - /// - `_ref__name__field` when the upvar is captured by reference. - /// - /// For generators this only contains upvars that are shared by all states. - pub fn closure_saved_names_of_captured_variables( - self, - def_id: DefId, - ) -> SmallVec<[String; 16]> { - let body = self.optimized_mir(def_id); - - body.var_debug_info - .iter() - .filter_map(|var| { - let is_ref = match var.value { - mir::VarDebugInfoContents::Place(place) - if place.local == mir::Local::new(1) => - { - // The projection is either `[.., Field, Deref]` or `[.., Field]`. It - // implies whether the variable is captured by value or by reference. - matches!(place.projection.last().unwrap(), mir::ProjectionElem::Deref) - } - _ => return None, - }; - let prefix = if is_ref { "_ref__" } else { "" }; - Some(prefix.to_owned() + var.name.as_str()) - }) - .collect() - } - // FIXME(eddyb) maybe precompute this? Right now it's computed once // per generator monomorphization, but it doesn't depend on substs. pub fn generator_layout_and_saved_local_names( diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 7f0c1d53f729a..1868496f99dc5 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -36,6 +36,29 @@ pub(crate) fn mir_built( tcx.alloc_steal_mir(mir_build(tcx, def)) } +/// Returns names of captured upvars for closures and generators. +/// +/// Here are some examples: +/// - `name__field1__field2` when the upvar is captured by value. +/// - `_ref__name__field` when the upvar is captured by reference. +/// +/// For generators this only contains upvars that are shared by all states. +pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> IndexVec { + tcx.closure_captures(def_id) + .iter() + .map(|captured_place| { + let name = captured_place.to_symbol(); + match captured_place.info.capture_kind { + ty::UpvarCapture::ByValue => name, + ty::UpvarCapture::ByRef(..) => Symbol::intern(&format!("_ref__{name}")), + } + }) + .collect() +} + /// Construct the MIR for a given `DefId`. fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // Ensure unsafeck and abstract const building is ran before we steal the THIR. diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 0eaab9b57036c..4fdc3178c4e1f 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -33,6 +33,8 @@ pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; providers.mir_built = build::mir_built; + providers.closure_saved_names_of_captured_variables = + build::closure_saved_names_of_captured_variables; providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; providers.thir_body = thir::cx::thir_body; providers.thir_tree = thir::print::thir_tree; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 7015778e24b85..f8445c6395c6b 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -959,7 +959,7 @@ fn variant_info_for_generator<'tcx>( upvars_size = upvars_size.max(offset + field_layout.size); FieldInfo { kind: FieldKind::Upvar, - name: Symbol::intern(&name), + name: *name, offset: offset.bytes(), size: field_layout.size.bytes(), align: field_layout.align.abi.bytes(), From 3a1edd8212381d0b825a5bcb876a8f05ff3ff35a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 18 Jun 2023 08:19:16 +0000 Subject: [PATCH 2/3] Store generator field names in GeneratorLayout. --- .../src/debuginfo/metadata/enums/cpp_like.rs | 4 +- .../src/debuginfo/metadata/enums/mod.rs | 5 +-- .../src/debuginfo/metadata/enums/native.rs | 5 +-- compiler/rustc_middle/src/mir/query.rs | 4 ++ compiler/rustc_middle/src/ty/util.rs | 44 ------------------- compiler/rustc_mir_transform/src/generator.rs | 28 +++++++++--- compiler/rustc_ty_utils/src/layout.rs | 9 ++-- 7 files changed, 36 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index ecb0912d32881..b2765ffc93464 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -676,8 +676,7 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>( _ => unreachable!(), }; - let (generator_layout, state_specific_upvar_names) = - cx.tcx.generator_layout_and_saved_local_names(generator_def_id); + let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap(); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx); @@ -714,7 +713,6 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>( generator_type_and_layout, generator_type_di_node, generator_layout, - &state_specific_upvar_names, &common_upvar_names, ); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 7a23fd31d1c6a..8746ce0c5b137 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -6,7 +6,7 @@ use rustc_hir::def::CtorKind; use rustc_index::IndexSlice; use rustc_middle::{ bug, - mir::{GeneratorLayout, GeneratorSavedLocal}, + mir::GeneratorLayout, ty::{ self, layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout}, @@ -323,7 +323,6 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( generator_type_and_layout: TyAndLayout<'tcx>, generator_type_di_node: &'ll DIType, generator_layout: &GeneratorLayout<'tcx>, - state_specific_upvar_names: &IndexSlice>, common_upvar_names: &IndexSlice, ) -> &'ll DIType { let variant_name = GeneratorSubsts::variant_name(variant_index); @@ -357,7 +356,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( .map(|field_index| { let generator_saved_local = generator_layout.variant_fields[variant_index] [FieldIdx::from_usize(field_index)]; - let field_name_maybe = state_specific_upvar_names[generator_saved_local]; + let field_name_maybe = generator_layout.field_names[generator_saved_local]; let field_name = field_name_maybe .as_ref() .map(|s| Cow::from(s.as_str())) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 666b9762f5a76..4d1cd64865f5e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -155,8 +155,8 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>( DIFlags::FlagZero, ), |cx, generator_type_di_node| { - let (generator_layout, state_specific_upvar_names) = - cx.tcx.generator_layout_and_saved_local_names(generator_def_id); + let generator_layout = + cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap(); let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = generator_type_and_layout.variants else { bug!( @@ -195,7 +195,6 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>( generator_type_and_layout, generator_type_di_node, generator_layout, - &state_specific_upvar_names, &common_upvar_names, ), source_info, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index a15c419da7aca..13a1011e328ee 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitMatrix; use rustc_index::{Idx, IndexVec}; +use rustc_span::symbol::Symbol; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use smallvec::SmallVec; @@ -150,6 +151,9 @@ pub struct GeneratorLayout<'tcx> { /// The type of every local stored inside the generator. pub field_tys: IndexVec>, + /// The name for debuginfo. + pub field_names: IndexVec>, + /// Which of the above fields are in each variant. Note that one field may /// be stored in multiple variants. pub variant_fields: IndexVec>, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 2e841e261fcc4..87a5b038a85d9 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1,7 +1,6 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::mir; use crate::query::Providers; use crate::ty::layout::IntegerExt; use crate::ty::{ @@ -17,7 +16,6 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; -use rustc_index::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_session::Limit; use rustc_span::sym; @@ -738,48 +736,6 @@ impl<'tcx> TyCtxt<'tcx> { if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } - // FIXME(eddyb) maybe precompute this? Right now it's computed once - // per generator monomorphization, but it doesn't depend on substs. - pub fn generator_layout_and_saved_local_names( - self, - def_id: DefId, - ) -> ( - &'tcx ty::GeneratorLayout<'tcx>, - IndexVec>, - ) { - let tcx = self; - let body = tcx.optimized_mir(def_id); - let generator_layout = body.generator_layout().unwrap(); - let mut generator_saved_local_names = - IndexVec::from_elem(None, &generator_layout.field_tys); - - let state_arg = mir::Local::new(1); - for var in &body.var_debug_info { - let mir::VarDebugInfoContents::Place(place) = &var.value else { continue }; - if place.local != state_arg { - continue; - } - match place.projection[..] { - [ - // Deref of the `Pin<&mut Self>` state argument. - mir::ProjectionElem::Field(..), - mir::ProjectionElem::Deref, - // Field of a variant of the state. - mir::ProjectionElem::Downcast(_, variant), - mir::ProjectionElem::Field(field, _), - ] => { - let name = &mut generator_saved_local_names - [generator_layout.variant_fields[variant][field]]; - if name.is_none() { - name.replace(var.name); - } - } - _ => {} - } - } - (generator_layout, generator_saved_local_names) - } - /// Query and get an English description for the item's kind. pub fn def_descr(self, def_id: DefId) -> &'static str { self.def_kind_descr(self.def_kind(def_id), def_id) diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index fe3f8ed047a70..9706a7987d9da 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -230,7 +230,7 @@ struct TransformVisitor<'tcx> { // Mapping from Local to (type of local, generator struct index) // FIXME(eddyb) This should use `IndexVec>`. - remap: FxHashMap, VariantIdx, usize)>, + remap: FxHashMap, VariantIdx, FieldIdx)>, // A map from a suspension point in a block to the locals which have live storage at that point storage_liveness: IndexVec>>, @@ -295,11 +295,11 @@ impl<'tcx> TransformVisitor<'tcx> { } // Create a Place referencing a generator struct field - fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> { + fn make_field(&self, variant_index: VariantIdx, idx: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> { let self_place = Place::from(SELF_ARG); let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index); let mut projection = base.projection.to_vec(); - projection.push(ProjectionElem::Field(FieldIdx::new(idx), ty)); + projection.push(ProjectionElem::Field(idx, ty)); Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) } } @@ -904,7 +904,7 @@ fn compute_layout<'tcx>( liveness: LivenessInfo, body: &Body<'tcx>, ) -> ( - FxHashMap, VariantIdx, usize)>, + FxHashMap, VariantIdx, FieldIdx)>, GeneratorLayout<'tcx>, IndexVec>>, ) { @@ -982,6 +982,7 @@ fn compute_layout<'tcx>( // just use the first one here. That's fine; fields do not move // around inside generators, so it doesn't matter which variant // index we access them by. + let idx = FieldIdx::from_usize(idx); remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx)); } variant_fields.push(fields); @@ -990,8 +991,23 @@ fn compute_layout<'tcx>( debug!("generator variant_fields = {:?}", variant_fields); debug!("generator storage_conflicts = {:#?}", storage_conflicts); - let layout = - GeneratorLayout { field_tys: tys, variant_fields, variant_source_info, storage_conflicts }; + let mut field_names = IndexVec::from_elem(None, &tys); + for var in &body.var_debug_info { + let VarDebugInfoContents::Place(place) = &var.value else { continue }; + let Some(local) = place.as_local() else { continue }; + let Some(&(_, variant, field)) = remap.get(&local) else { continue }; + + let saved_local = variant_fields[variant][field]; + field_names.get_or_insert_with(saved_local, || var.name); + } + + let layout = GeneratorLayout { + field_tys: tys, + field_names, + variant_fields, + variant_source_info, + storage_conflicts, + }; debug!(?layout); (remap, layout, storage_liveness) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index f8445c6395c6b..f48bba241327e 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -944,7 +944,7 @@ fn variant_info_for_generator<'tcx>( return (vec![], None); }; - let (generator, state_specific_names) = cx.tcx.generator_layout_and_saved_local_names(def_id); + let generator = cx.tcx.optimized_mir(def_id).generator_layout().unwrap(); let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let mut upvars_size = Size::ZERO; @@ -983,9 +983,10 @@ fn variant_info_for_generator<'tcx>( variant_size = variant_size.max(offset + field_layout.size); FieldInfo { kind: FieldKind::GeneratorLocal, - name: state_specific_names.get(*local).copied().flatten().unwrap_or( - Symbol::intern(&format!(".generator_field{}", local.as_usize())), - ), + name: generator.field_names[*local].unwrap_or(Symbol::intern(&format!( + ".generator_field{}", + local.as_usize() + ))), offset: offset.bytes(), size: field_layout.size.bytes(), align: field_layout.align.abi.bytes(), From 689607e7a3c601a4982fb5dbddc99ee79b08a525 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 19 Jun 2023 16:52:12 +0000 Subject: [PATCH 3/3] Remove duplicated comment. --- compiler/rustc_mir_build/src/build/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 1868496f99dc5..49cbe3e2c9b4e 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -36,13 +36,6 @@ pub(crate) fn mir_built( tcx.alloc_steal_mir(mir_build(tcx, def)) } -/// Returns names of captured upvars for closures and generators. -/// -/// Here are some examples: -/// - `name__field1__field2` when the upvar is captured by value. -/// - `_ref__name__field` when the upvar is captured by reference. -/// -/// For generators this only contains upvars that are shared by all states. pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId,