@@ -1280,6 +1280,31 @@ fn prepare_struct_metadata(
12801280// Tuples
12811281//=-----------------------------------------------------------------------------
12821282
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+
12831308/// Creates `MemberDescription`s for the fields of a tuple.
12841309struct TupleMemberDescriptionFactory < ' tcx > {
12851310 ty : Ty < ' tcx > ,
@@ -1289,34 +1314,23 @@ struct TupleMemberDescriptionFactory<'tcx> {
12891314
12901315impl < ' tcx > TupleMemberDescriptionFactory < ' tcx > {
12911316 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) )
13061320 }
13071321 _ => None ,
13081322 } ;
1309-
13101323 let layout = cx. layout_of ( self . ty ) ;
13111324 self . component_types
13121325 . iter ( )
13131326 . enumerate ( )
13141327 . map ( |( i, & component_type) | {
13151328 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+ } ;
13201334 MemberDescription {
13211335 name,
13221336 type_metadata : type_metadata ( cx, component_type, self . span ) ,
0 commit comments