@@ -1280,6 +1280,31 @@ fn prepare_struct_metadata(
1280
1280
// Tuples
1281
1281
//=-----------------------------------------------------------------------------
1282
1282
1283
+ /// Returns names of captured upvars for closures and generators.
1284
+ ///
1285
+ /// Here are some examples:
1286
+ /// - `name__field1__field2` when the upvar is captured by value.
1287
+ /// - `_ref__name__field` when the upvar is captured by reference.
1288
+ fn closure_saved_names_of_captured_variables ( tcx : TyCtxt < ' tcx > , def_id : DefId ) -> Vec < String > {
1289
+ let body = tcx. optimized_mir ( def_id) ;
1290
+
1291
+ body. var_debug_info
1292
+ . iter ( )
1293
+ . filter_map ( |var| {
1294
+ let is_ref = match var. value {
1295
+ mir:: VarDebugInfoContents :: Place ( place) if place. local == mir:: Local :: new ( 1 ) => {
1296
+ // The projection is either `[.., Field, Deref]` or `[.., Field]`. It
1297
+ // implies whether the variable is captured by value or by reference.
1298
+ matches ! ( place. projection. last( ) . unwrap( ) , mir:: ProjectionElem :: Deref )
1299
+ }
1300
+ _ => return None ,
1301
+ } ;
1302
+ let prefix = if is_ref { "_ref__" } else { "" } ;
1303
+ Some ( prefix. to_owned ( ) + & var. name . as_str ( ) )
1304
+ } )
1305
+ . collect :: < Vec < _ > > ( )
1306
+ }
1307
+
1283
1308
/// Creates `MemberDescription`s for the fields of a tuple.
1284
1309
struct TupleMemberDescriptionFactory < ' tcx > {
1285
1310
ty : Ty < ' tcx > ,
@@ -1289,34 +1314,23 @@ struct TupleMemberDescriptionFactory<'tcx> {
1289
1314
1290
1315
impl < ' tcx > TupleMemberDescriptionFactory < ' tcx > {
1291
1316
fn create_member_descriptions ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Vec < MemberDescription < ' ll > > {
1292
- // For closures and generators, name the captured upvars
1293
- // with the help of `CapturedPlace::to_mangled_name`.
1294
- let closure_def_id = match * self . ty . kind ( ) {
1295
- ty:: Generator ( def_id, ..) => def_id. as_local ( ) ,
1296
- ty:: Closure ( def_id, ..) => def_id. as_local ( ) ,
1297
- _ => None ,
1298
- } ;
1299
- let captures = match closure_def_id {
1300
- Some ( local_def_id) => {
1301
- let typeck_results = cx. tcx . typeck ( local_def_id) ;
1302
- let captures = typeck_results
1303
- . closure_min_captures_flattened ( local_def_id. to_def_id ( ) )
1304
- . collect :: < Vec < _ > > ( ) ;
1305
- Some ( captures)
1317
+ let capture_names = match * self . ty . kind ( ) {
1318
+ ty:: Generator ( def_id, ..) | ty:: Closure ( def_id, ..) => {
1319
+ Some ( closure_saved_names_of_captured_variables ( cx. tcx , def_id) )
1306
1320
}
1307
1321
_ => None ,
1308
1322
} ;
1309
-
1310
1323
let layout = cx. layout_of ( self . ty ) ;
1311
1324
self . component_types
1312
1325
. iter ( )
1313
1326
. enumerate ( )
1314
1327
. map ( |( i, & component_type) | {
1315
1328
let ( size, align) = cx. size_and_align_of ( component_type) ;
1316
- let name = captures
1317
- . as_ref ( )
1318
- . map ( |c| c[ i] . to_mangled_name ( cx. tcx ) )
1319
- . unwrap_or_else ( || format ! ( "__{}" , i) ) ;
1329
+ let name = if let Some ( names) = capture_names. as_ref ( ) {
1330
+ names[ i] . clone ( )
1331
+ } else {
1332
+ format ! ( "__{}" , i)
1333
+ } ;
1320
1334
MemberDescription {
1321
1335
name,
1322
1336
type_metadata : type_metadata ( cx, component_type, self . span ) ,
0 commit comments