@@ -110,15 +110,14 @@ fn tag_base_type<'ll, 'tcx>(
110110 _ => false ,
111111 } ) ;
112112
113- // FIXME(mw): Why are niche and regular tags treated differently? Because we want to preserve
114- // the sign?
115113 match enum_type_and_layout. layout . variants ( ) {
116114 // A single-variant enum has no discriminant.
117115 Variants :: Single { .. } => {
118116 bug ! ( "tag_base_type() called for enum without tag: {:?}" , enum_type_and_layout)
119117 }
120118
121119 Variants :: Multiple { tag_encoding : TagEncoding :: Niche { .. } , tag, .. } => {
120+ // Niche tags are always normalized to unsized integers of the correct size.
122121 match tag. value {
123122 Primitive :: Int ( t, _) => t,
124123 Primitive :: F32 => Integer :: I32 ,
@@ -134,26 +133,34 @@ fn tag_base_type<'ll, 'tcx>(
134133 }
135134
136135 Variants :: Multiple { tag_encoding : TagEncoding :: Direct , tag, .. } => {
136+ // Direct tags preserve the sign.
137137 tag. value . to_ty ( cx. tcx )
138138 }
139139 }
140140}
141141
142- /// This is a helper function. FIXME: elaborate docs.
142+ /// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
143+ /// This is a helper function and does not register anything in the type map by itself.
144+ ///
145+ /// `variants` is an iterator of (discr-value, variant-name).
146+ ///
147+ // NOTE: Handling of discriminant values is somewhat inconsistent. They can appear as u128,
148+ // u64, and i64. Here everything gets mapped to i64 because that's what LLVM's API expects.
143149fn build_enumeration_type_di_node < ' ll , ' tcx > (
144150 cx : & CodegenCx < ' ll , ' tcx > ,
145151 type_name : & str ,
146152 base_type : Ty < ' tcx > ,
147153 variants : & mut dyn Iterator < Item = ( Discr < ' tcx > , Cow < ' tcx , str > ) > ,
148154 containing_scope : & ' ll DIType ,
149155) -> & ' ll DIType {
156+ let is_unsigned = match base_type. kind ( ) {
157+ ty:: Int ( _) => false ,
158+ ty:: Uint ( _) => true ,
159+ _ => bug ! ( "build_enumeration_type_di_node() called with non-integer tag type." ) ,
160+ } ;
161+
150162 let enumerator_di_nodes: SmallVec < Option < & ' ll DIType > > = variants
151163 . map ( |( discr, variant_name) | {
152- let is_unsigned = match discr. ty . kind ( ) {
153- ty:: Int ( _) => false ,
154- ty:: Uint ( _) => true ,
155- _ => bug ! ( "build_enumeration_type_di_node() called with non-integer tag type." ) ,
156- } ;
157164 unsafe {
158165 Some ( llvm:: LLVMRustDIBuilderCreateEnumerator (
159166 DIB ( cx) ,
0 commit comments