@@ -392,6 +392,7 @@ fn vec_slice_metadata(
392392 align: pointer_align,
393393 flags: DIFlags :: FlagZero ,
394394 discriminant: None ,
395+ source_info: None ,
395396 } ,
396397 MemberDescription {
397398 name: "length" . to_owned( ) ,
@@ -401,6 +402,7 @@ fn vec_slice_metadata(
401402 align: usize_align,
402403 flags: DIFlags :: FlagZero ,
403404 discriminant: None ,
405+ source_info: None ,
404406 } ,
405407 ] ;
406408
@@ -508,6 +510,7 @@ fn trait_pointer_metadata(
508510 align: data_ptr_field. align. abi,
509511 flags: DIFlags :: FlagArtificial ,
510512 discriminant: None ,
513+ source_info: None ,
511514 } ,
512515 MemberDescription {
513516 name: "vtable" . to_owned( ) ,
@@ -517,6 +520,7 @@ fn trait_pointer_metadata(
517520 align: vtable_field. align. abi,
518521 flags: DIFlags :: FlagArtificial ,
519522 discriminant: None ,
523+ source_info: None ,
520524 } ,
521525 ] ;
522526
@@ -1026,6 +1030,12 @@ impl MetadataCreationResult<'ll> {
10261030 }
10271031}
10281032
1033+ #[ derive( Debug ) ]
1034+ struct SourceInfo < ' ll > {
1035+ file : & ' ll DIFile ,
1036+ line : u32 ,
1037+ }
1038+
10291039/// Description of a type member, which can either be a regular field (as in
10301040/// structs or tuples) or an enum variant.
10311041#[ derive( Debug ) ]
@@ -1037,6 +1047,7 @@ struct MemberDescription<'ll> {
10371047 align : Align ,
10381048 flags : DIFlags ,
10391049 discriminant : Option < u64 > ,
1050+ source_info : Option < SourceInfo < ' ll > > ,
10401051}
10411052
10421053impl < ' ll > MemberDescription < ' ll > {
@@ -1045,14 +1056,18 @@ impl<'ll> MemberDescription<'ll> {
10451056 cx : & CodegenCx < ' ll , ' _ > ,
10461057 composite_type_metadata : & ' ll DIScope ,
10471058 ) -> & ' ll DIType {
1059+ let ( file, line) = self
1060+ . source_info
1061+ . map ( |info| ( info. file , info. line ) )
1062+ . unwrap_or_else ( || ( unknown_file_metadata ( cx) , UNKNOWN_LINE_NUMBER ) ) ;
10481063 unsafe {
10491064 llvm:: LLVMRustDIBuilderCreateVariantMemberType (
10501065 DIB ( cx) ,
10511066 composite_type_metadata,
10521067 self . name . as_ptr ( ) . cast ( ) ,
10531068 self . name . len ( ) ,
1054- unknown_file_metadata ( cx ) ,
1055- UNKNOWN_LINE_NUMBER ,
1069+ file ,
1070+ line ,
10561071 self . size . bits ( ) ,
10571072 self . align . bits ( ) as u32 ,
10581073 self . offset . bits ( ) ,
@@ -1124,6 +1139,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
11241139 align : field. align . abi ,
11251140 flags : DIFlags :: FlagZero ,
11261141 discriminant : None ,
1142+ source_info : None ,
11271143 }
11281144 } )
11291145 . collect ( )
@@ -1185,6 +1201,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
11851201 align,
11861202 flags : DIFlags :: FlagZero ,
11871203 discriminant : None ,
1204+ source_info : None ,
11881205 }
11891206 } )
11901207 . collect ( )
@@ -1244,6 +1261,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
12441261 align : field. align . abi ,
12451262 flags : DIFlags :: FlagZero ,
12461263 discriminant : None ,
1264+ source_info : None ,
12471265 }
12481266 } )
12491267 . collect ( )
@@ -1351,10 +1369,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13511369
13521370 let variant_info_for = |index : VariantIdx | match self . enum_type . kind {
13531371 ty:: Adt ( adt, _) => VariantInfo :: Adt ( & adt. variants [ index] ) ,
1354- ty:: Generator ( _ , substs, _) => {
1372+ ty:: Generator ( def_id , substs, _) => {
13551373 let ( generator_layout, generator_saved_local_names) =
13561374 generator_variant_info_data. as_ref ( ) . unwrap ( ) ;
13571375 VariantInfo :: Generator {
1376+ def_id,
13581377 substs,
13591378 generator_layout : * generator_layout,
13601379 generator_saved_local_names,
@@ -1406,6 +1425,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
14061425 align: self . layout. align. abi,
14071426 flags: DIFlags :: FlagZero ,
14081427 discriminant: None ,
1428+ source_info: variant_info. source_info( cx) ,
14091429 } ]
14101430 }
14111431 Variants :: Multiple {
@@ -1462,6 +1482,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
14621482 self . layout . ty . discriminant_for_variant ( cx. tcx , i) . unwrap ( ) . val
14631483 as u64 ,
14641484 ) ,
1485+ source_info : variant_info. source_info ( cx) ,
14651486 }
14661487 } )
14671488 . collect ( )
@@ -1527,7 +1548,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15271548 self . layout . fields . offset ( discr_index) ,
15281549 self . layout . field ( cx, discr_index) . size ,
15291550 ) ;
1530- variant_info_for ( * niche_variants. start ( ) ) . map_struct_name ( |variant_name| {
1551+ let variant_info = variant_info_for ( * niche_variants. start ( ) ) ;
1552+ variant_info. map_struct_name ( |variant_name| {
15311553 name. push_str ( variant_name) ;
15321554 } ) ;
15331555
@@ -1540,6 +1562,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15401562 align: variant. align. abi,
15411563 flags: DIFlags :: FlagZero ,
15421564 discriminant: None ,
1565+ source_info: variant_info. source_info( cx) ,
15431566 } ]
15441567 } else {
15451568 variants
@@ -1589,6 +1612,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
15891612 align : self . layout . align . abi ,
15901613 flags : DIFlags :: FlagZero ,
15911614 discriminant : niche_value,
1615+ source_info : variant_info. source_info ( cx) ,
15921616 }
15931617 } )
15941618 . collect ( )
@@ -1631,6 +1655,7 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> {
16311655 align,
16321656 flags : DIFlags :: FlagZero ,
16331657 discriminant : None ,
1658+ source_info : None ,
16341659 }
16351660 } )
16361661 . collect ( )
@@ -1648,6 +1673,7 @@ enum EnumDiscriminantInfo<'ll> {
16481673enum VariantInfo < ' a , ' tcx > {
16491674 Adt ( & ' tcx ty:: VariantDef ) ,
16501675 Generator {
1676+ def_id : DefId ,
16511677 substs : SubstsRef < ' tcx > ,
16521678 generator_layout : & ' tcx GeneratorLayout < ' tcx > ,
16531679 generator_saved_local_names : & ' a IndexVec < mir:: GeneratorSavedLocal , Option < Symbol > > ,
@@ -1696,6 +1722,24 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
16961722 } ;
16971723 field_name. map ( |name| name. to_string ( ) ) . unwrap_or_else ( || format ! ( "__{}" , i) )
16981724 }
1725+
1726+ fn source_info ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> Option < SourceInfo < ' ll > > {
1727+ match self {
1728+ VariantInfo :: Generator { def_id, variant_index, .. } => {
1729+ let span =
1730+ cx. tcx . generator_layout ( * def_id) . variant_source_info [ * variant_index] . span ;
1731+ if !span. is_dummy ( ) {
1732+ let loc = cx. lookup_debug_loc ( span. lo ( ) ) ;
1733+ return Some ( SourceInfo {
1734+ file : file_metadata ( cx, & loc. file , def_id. krate ) ,
1735+ line : loc. line . unwrap_or ( UNKNOWN_LINE_NUMBER ) ,
1736+ } ) ;
1737+ }
1738+ }
1739+ _ => { }
1740+ }
1741+ None
1742+ }
16991743}
17001744
17011745/// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
@@ -1775,7 +1819,8 @@ fn prepare_enum_metadata(
17751819 span : Span ,
17761820 outer_field_tys : Vec < Ty < ' tcx > > ,
17771821) -> RecursiveTypeDescription < ' ll , ' tcx > {
1778- let enum_name = compute_debuginfo_type_name ( cx. tcx , enum_type, false ) ;
1822+ let tcx = cx. tcx ;
1823+ let enum_name = compute_debuginfo_type_name ( tcx, enum_type, false ) ;
17791824
17801825 let containing_scope = get_namespace_for_item ( cx, enum_def_id) ;
17811826 // FIXME: This should emit actual file metadata for the enum, but we
@@ -1789,7 +1834,7 @@ fn prepare_enum_metadata(
17891834 let discriminant_type_metadata = |discr : Primitive | {
17901835 let enumerators_metadata: Vec < _ > = match enum_type. kind {
17911836 ty:: Adt ( def, _) => def
1792- . discriminants ( cx . tcx )
1837+ . discriminants ( tcx)
17931838 . zip ( & def. variants )
17941839 . map ( |( ( _, discr) , v) | {
17951840 let name = v. ident . as_str ( ) ;
@@ -1812,15 +1857,16 @@ fn prepare_enum_metadata(
18121857 . collect ( ) ,
18131858 ty:: Generator ( _, substs, _) => substs
18141859 . as_generator ( )
1815- . variant_range ( enum_def_id, cx . tcx )
1860+ . variant_range ( enum_def_id, tcx)
18161861 . map ( |variant_index| {
1862+ debug_assert_eq ! ( tcx. types. u32 , substs. as_generator( ) . discr_ty( tcx) ) ;
18171863 let name = substs. as_generator ( ) . variant_name ( variant_index) ;
18181864 unsafe {
18191865 Some ( llvm:: LLVMRustDIBuilderCreateEnumerator (
18201866 DIB ( cx) ,
18211867 name. as_ptr ( ) . cast ( ) ,
18221868 name. len ( ) ,
1823- // Generators use u32 as discriminant type.
1869+ // Generators use u32 as discriminant type, verified above .
18241870 variant_index. as_u32 ( ) . into ( ) ,
18251871 true , // IsUnsigned
18261872 ) )
@@ -1838,12 +1884,12 @@ fn prepare_enum_metadata(
18381884 None => {
18391885 let ( discriminant_size, discriminant_align) = ( discr. size ( cx) , discr. align ( cx) ) ;
18401886 let discriminant_base_type_metadata =
1841- type_metadata ( cx, discr. to_ty ( cx . tcx ) , rustc_span:: DUMMY_SP ) ;
1887+ type_metadata ( cx, discr. to_ty ( tcx) , rustc_span:: DUMMY_SP ) ;
18421888
18431889 let item_name;
18441890 let discriminant_name = match enum_type. kind {
18451891 ty:: Adt ( ..) => {
1846- item_name = cx . tcx . item_name ( enum_def_id) . as_str ( ) ;
1892+ item_name = tcx. item_name ( enum_def_id) . as_str ( ) ;
18471893 & * item_name
18481894 }
18491895 ty:: Generator ( ..) => enum_name. as_str ( ) ,
0 commit comments