@@ -6,7 +6,7 @@ use super::*;
66use rustc_attr as attr;
77use rustc_errors:: { Applicability , ErrorGuaranteed , MultiSpan } ;
88use rustc_hir as hir;
9- use rustc_hir:: def:: { DefKind , Res } ;
9+ use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
1010use rustc_hir:: def_id:: { DefId , LocalDefId } ;
1111use rustc_hir:: intravisit:: Visitor ;
1212use rustc_hir:: { ItemKind , Node , PathSegment } ;
@@ -75,15 +75,15 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
7575 check_simd ( tcx, span, def_id) ;
7676 }
7777
78- check_transparent ( tcx, span , def) ;
78+ check_transparent ( tcx, def) ;
7979 check_packed ( tcx, span, def) ;
8080}
8181
8282fn check_union ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) {
8383 let def = tcx. adt_def ( def_id) ;
8484 let span = tcx. def_span ( def_id) ;
8585 def. destructor ( tcx) ; // force the destructor to be evaluated
86- check_transparent ( tcx, span , def) ;
86+ check_transparent ( tcx, def) ;
8787 check_union_fields ( tcx, span, def_id) ;
8888 check_packed ( tcx, span, def) ;
8989}
@@ -506,11 +506,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
506506 tcx. ensure ( ) . typeck ( id. owner_id . def_id ) ;
507507 }
508508 DefKind :: Enum => {
509- let item = tcx. hir ( ) . item ( id) ;
510- let hir:: ItemKind :: Enum ( ref enum_definition, _) = item. kind else {
511- return ;
512- } ;
513- check_enum ( tcx, & enum_definition. variants , item. owner_id . def_id ) ;
509+ check_enum ( tcx, id. owner_id . def_id ) ;
514510 }
515511 DefKind :: Fn => { } // entirely within check_item_body
516512 DefKind :: Impl => {
@@ -1026,7 +1022,7 @@ pub(super) fn check_packed_inner(
10261022 None
10271023}
10281024
1029- pub ( super ) fn check_transparent < ' tcx > ( tcx : TyCtxt < ' tcx > , sp : Span , adt : ty:: AdtDef < ' tcx > ) {
1025+ pub ( super ) fn check_transparent < ' tcx > ( tcx : TyCtxt < ' tcx > , adt : ty:: AdtDef < ' tcx > ) {
10301026 if !adt. repr ( ) . transparent ( ) {
10311027 return ;
10321028 }
@@ -1035,14 +1031,14 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
10351031 feature_err (
10361032 & tcx. sess . parse_sess ,
10371033 sym:: transparent_unions,
1038- sp ,
1034+ tcx . def_span ( adt . did ( ) ) ,
10391035 "transparent unions are unstable" ,
10401036 )
10411037 . emit ( ) ;
10421038 }
10431039
10441040 if adt. variants ( ) . len ( ) != 1 {
1045- bad_variant_count ( tcx, adt, sp , adt. did ( ) ) ;
1041+ bad_variant_count ( tcx, adt, tcx . def_span ( adt . did ( ) ) , adt. did ( ) ) ;
10461042 if adt. variants ( ) . is_empty ( ) {
10471043 // Don't bother checking the fields. No variants (and thus no fields) exist.
10481044 return ;
@@ -1103,7 +1099,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
11031099 . filter_map ( |( span, zst, _align1, _non_exhaustive) | if !zst { Some ( span) } else { None } ) ;
11041100 let non_zst_count = non_zst_fields. clone ( ) . count ( ) ;
11051101 if non_zst_count >= 2 {
1106- bad_non_zero_sized_fields ( tcx, adt, non_zst_count, non_zst_fields, sp ) ;
1102+ bad_non_zero_sized_fields ( tcx, adt, non_zst_count, non_zst_fields, tcx . def_span ( adt . did ( ) ) ) ;
11071103 }
11081104 let incompatible_zst_fields =
11091105 field_infos. clone ( ) . filter ( |( _, _, _, opt) | opt. is_some ( ) ) . count ( ) ;
@@ -1143,20 +1139,19 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
11431139}
11441140
11451141#[ allow( trivial_numeric_casts) ]
1146- fn check_enum < ' tcx > ( tcx : TyCtxt < ' tcx > , vs : & ' tcx [ hir :: Variant < ' tcx > ] , def_id : LocalDefId ) {
1142+ fn check_enum < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) {
11471143 let def = tcx. adt_def ( def_id) ;
1148- let sp = tcx. def_span ( def_id) ;
11491144 def. destructor ( tcx) ; // force the destructor to be evaluated
11501145
1151- if vs . is_empty ( ) {
1146+ if def . variants ( ) . is_empty ( ) {
11521147 if let Some ( attr) = tcx. get_attrs ( def_id. to_def_id ( ) , sym:: repr) . next ( ) {
11531148 struct_span_err ! (
11541149 tcx. sess,
11551150 attr. span,
11561151 E0084 ,
11571152 "unsupported representation for zero-variant enum"
11581153 )
1159- . span_label ( sp , "zero-variant enum" )
1154+ . span_label ( tcx . def_span ( def_id ) , "zero-variant enum" )
11601155 . emit ( ) ;
11611156 }
11621157 }
@@ -1167,88 +1162,96 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
11671162 feature_err (
11681163 & tcx. sess . parse_sess ,
11691164 sym:: repr128,
1170- sp ,
1165+ tcx . def_span ( def_id ) ,
11711166 "repr with 128-bit type is unstable" ,
11721167 )
11731168 . emit ( ) ;
11741169 }
11751170 }
11761171
1177- for v in vs {
1178- if let Some ( ref e ) = v. disr_expr {
1179- tcx. ensure ( ) . typeck ( tcx . hir ( ) . local_def_id ( e . hir_id ) ) ;
1172+ for v in def . variants ( ) {
1173+ if let ty :: VariantDiscr :: Explicit ( discr_def_id ) = v. discr {
1174+ tcx. ensure ( ) . typeck ( discr_def_id . expect_local ( ) ) ;
11801175 }
11811176 }
11821177
1183- if tcx. adt_def ( def_id) . repr ( ) . int . is_none ( ) {
1184- let is_unit = |var : & hir:: Variant < ' _ > | matches ! ( var. data, hir:: VariantData :: Unit ( ..) ) ;
1178+ if def. repr ( ) . int . is_none ( ) {
1179+ let is_unit = |var : & ty:: VariantDef | matches ! ( var. ctor_kind, CtorKind :: Const ) ;
1180+ let has_disr = |var : & ty:: VariantDef | matches ! ( var. discr, ty:: VariantDiscr :: Explicit ( _) ) ;
11851181
1186- let has_disr = |var : & hir:: Variant < ' _ > | var. disr_expr . is_some ( ) ;
1187- let has_non_units = vs. iter ( ) . any ( |var| !is_unit ( var) ) ;
1188- let disr_units = vs. iter ( ) . any ( |var| is_unit ( & var) && has_disr ( & var) ) ;
1189- let disr_non_unit = vs. iter ( ) . any ( |var| !is_unit ( & var) && has_disr ( & var) ) ;
1182+ let has_non_units = def. variants ( ) . iter ( ) . any ( |var| !is_unit ( var) ) ;
1183+ let disr_units = def. variants ( ) . iter ( ) . any ( |var| is_unit ( & var) && has_disr ( & var) ) ;
1184+ let disr_non_unit = def. variants ( ) . iter ( ) . any ( |var| !is_unit ( & var) && has_disr ( & var) ) ;
11901185
11911186 if disr_non_unit || ( disr_units && has_non_units) {
1192- let mut err =
1193- struct_span_err ! ( tcx. sess, sp, E0732 , "`#[repr(inttype)]` must be specified" ) ;
1187+ let mut err = struct_span_err ! (
1188+ tcx. sess,
1189+ tcx. def_span( def_id) ,
1190+ E0732 ,
1191+ "`#[repr(inttype)]` must be specified"
1192+ ) ;
11941193 err. emit ( ) ;
11951194 }
11961195 }
11971196
1198- detect_discriminant_duplicate ( tcx, def. discriminants ( tcx) . collect ( ) , vs, sp) ;
1199-
1200- check_transparent ( tcx, sp, def) ;
1197+ detect_discriminant_duplicate ( tcx, def) ;
1198+ check_transparent ( tcx, def) ;
12011199}
12021200
12031201/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
1204- fn detect_discriminant_duplicate < ' tcx > (
1205- tcx : TyCtxt < ' tcx > ,
1206- mut discrs : Vec < ( VariantIdx , Discr < ' tcx > ) > ,
1207- vs : & ' tcx [ hir:: Variant < ' tcx > ] ,
1208- self_span : Span ,
1209- ) {
1202+ fn detect_discriminant_duplicate < ' tcx > ( tcx : TyCtxt < ' tcx > , adt : ty:: AdtDef < ' tcx > ) {
12101203 // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate.
12111204 // Here `idx` refers to the order of which the discriminant appears, and its index in `vs`
1212- let report = |dis : Discr < ' tcx > , idx : usize , err : & mut Diagnostic | {
1213- let var = & vs [ idx] ; // HIR for the duplicate discriminant
1214- let ( span, display_discr) = match var. disr_expr {
1215- Some ( ref expr ) => {
1205+ let report = |dis : Discr < ' tcx > , idx, err : & mut Diagnostic | {
1206+ let var = adt . variant ( idx) ; // HIR for the duplicate discriminant
1207+ let ( span, display_discr) = match var. discr {
1208+ ty :: VariantDiscr :: Explicit ( discr_def_id ) => {
12161209 // In the case the discriminant is both a duplicate and overflowed, let the user know
1217- if let hir:: ExprKind :: Lit ( lit) = & tcx. hir ( ) . body ( expr. body ) . value . kind
1210+ if let hir:: Node :: AnonConst ( expr) = tcx. hir ( ) . get_by_def_id ( discr_def_id. expect_local ( ) )
1211+ && let hir:: ExprKind :: Lit ( lit) = & tcx. hir ( ) . body ( expr. body ) . value . kind
12181212 && let rustc_ast:: LitKind :: Int ( lit_value, _int_kind) = & lit. node
12191213 && * lit_value != dis. val
12201214 {
1221- ( tcx. hir ( ) . span ( expr. hir_id ) , format ! ( "`{dis}` (overflowed from `{lit_value}`)" ) )
1222- // Otherwise, format the value as-is
1215+ ( tcx. def_span ( discr_def_id) , format ! ( "`{dis}` (overflowed from `{lit_value}`)" ) )
12231216 } else {
1224- ( tcx. hir ( ) . span ( expr. hir_id ) , format ! ( "`{dis}`" ) )
1217+ // Otherwise, format the value as-is
1218+ ( tcx. def_span ( discr_def_id) , format ! ( "`{dis}`" ) )
12251219 }
12261220 }
1227- None => {
1221+ // This should not happen.
1222+ ty:: VariantDiscr :: Relative ( 0 ) => ( tcx. def_span ( var. def_id ) , format ! ( "`{dis}`" ) ) ,
1223+ ty:: VariantDiscr :: Relative ( distance_to_explicit) => {
12281224 // At this point we know this discriminant is a duplicate, and was not explicitly
12291225 // assigned by the user. Here we iterate backwards to fetch the HIR for the last
12301226 // explicitly assigned discriminant, and letting the user know that this was the
12311227 // increment startpoint, and how many steps from there leading to the duplicate
1232- if let Some ( ( n , hir :: Variant { span , ident , .. } ) ) =
1233- vs [ .. idx] . iter ( ) . rev ( ) . enumerate ( ) . find ( |v| v . 1 . disr_expr . is_some ( ) )
1228+ if let Some ( explicit_idx ) =
1229+ idx. as_u32 ( ) . checked_sub ( distance_to_explicit ) . map ( VariantIdx :: from_u32 )
12341230 {
1235- let ve_ident = var. ident ;
1236- let n = n + 1 ;
1237- let sp = if n > 1 { "variants" } else { "variant" } ;
1231+ let explicit_variant = adt. variant ( explicit_idx) ;
1232+ let ve_ident = var. name ;
1233+ let ex_ident = explicit_variant. name ;
1234+ let sp = if distance_to_explicit > 1 { "variants" } else { "variant" } ;
12381235
12391236 err. span_label (
1240- * span,
1241- format ! ( "discriminant for `{ve_ident}` incremented from this startpoint (`{ident}` + {n} {sp} later => `{ve_ident}` = {dis})" ) ,
1237+ tcx. def_span ( explicit_variant. def_id ) ,
1238+ format ! (
1239+ "discriminant for `{ve_ident}` incremented from this startpoint \
1240+ (`{ex_ident}` + {distance_to_explicit} {sp} later \
1241+ => `{ve_ident}` = {dis})"
1242+ ) ,
12421243 ) ;
12431244 }
12441245
1245- ( vs [ idx ] . span , format ! ( "`{dis}`" ) )
1246+ ( tcx . def_span ( var . def_id ) , format ! ( "`{dis}`" ) )
12461247 }
12471248 } ;
12481249
12491250 err. span_label ( span, format ! ( "{display_discr} assigned here" ) ) ;
12501251 } ;
12511252
1253+ let mut discrs = adt. discriminants ( tcx) . collect :: < Vec < _ > > ( ) ;
1254+
12521255 // Here we loop through the discriminants, comparing each discriminant to another.
12531256 // When a duplicate is detected, we instantiate an error and point to both
12541257 // initial and duplicate value. The duplicate discriminant is then discarded by swapping
@@ -1257,29 +1260,29 @@ fn detect_discriminant_duplicate<'tcx>(
12571260 // style as we are mutating `discrs` on the fly).
12581261 let mut i = 0 ;
12591262 while i < discrs. len ( ) {
1260- let hir_var_i_idx = discrs[ i] . 0 . index ( ) ;
1263+ let var_i_idx = discrs[ i] . 0 ;
12611264 let mut error: Option < DiagnosticBuilder < ' _ , _ > > = None ;
12621265
12631266 let mut o = i + 1 ;
12641267 while o < discrs. len ( ) {
1265- let hir_var_o_idx = discrs[ o] . 0 . index ( ) ;
1268+ let var_o_idx = discrs[ o] . 0 ;
12661269
12671270 if discrs[ i] . 1 . val == discrs[ o] . 1 . val {
12681271 let err = error. get_or_insert_with ( || {
12691272 let mut ret = struct_span_err ! (
12701273 tcx. sess,
1271- self_span ,
1274+ tcx . def_span ( adt . did ( ) ) ,
12721275 E0081 ,
12731276 "discriminant value `{}` assigned more than once" ,
12741277 discrs[ i] . 1 ,
12751278 ) ;
12761279
1277- report ( discrs[ i] . 1 , hir_var_i_idx , & mut ret) ;
1280+ report ( discrs[ i] . 1 , var_i_idx , & mut ret) ;
12781281
12791282 ret
12801283 } ) ;
12811284
1282- report ( discrs[ o] . 1 , hir_var_o_idx , err) ;
1285+ report ( discrs[ o] . 1 , var_o_idx , err) ;
12831286
12841287 // Safe to unwrap here, as we wouldn't reach this point if `discrs` was empty
12851288 discrs[ o] = * discrs. last ( ) . unwrap ( ) ;
0 commit comments