@@ -1789,6 +1789,52 @@ fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<De
1789
1789
false
1790
1790
}
1791
1791
1792
+ /// Emit an error when encountering more or less than one variant in a transparent enum.
1793
+ fn bad_variant_count < ' tcx > ( tcx : TyCtxt < ' tcx > , adt : & ' tcx ty:: AdtDef , sp : Span , did : DefId ) {
1794
+ let variant_spans: Vec < _ > = adt. variants . iter ( ) . map ( |variant| {
1795
+ tcx. hir ( ) . span_if_local ( variant. def_id ) . unwrap ( )
1796
+ } ) . collect ( ) ;
1797
+ let msg = format ! (
1798
+ "needs exactly one variant, but has {}" ,
1799
+ adt. variants. len( ) ,
1800
+ ) ;
1801
+ let mut err = struct_span_err ! ( tcx. sess, sp, E0731 , "transparent enum {}" , msg) ;
1802
+ err. span_label ( sp, & msg) ;
1803
+ if let & [ ref start.., ref end] = & variant_spans[ ..] {
1804
+ for variant_span in start {
1805
+ err. span_label ( * variant_span, "" ) ;
1806
+ }
1807
+ err. span_label ( * end, & format ! ( "too many variants in `{}`" , tcx. def_path_str( did) ) ) ;
1808
+ }
1809
+ err. emit ( ) ;
1810
+ }
1811
+
1812
+ /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
1813
+ /// enum.
1814
+ fn bad_non_zero_sized_fields < ' tcx > (
1815
+ tcx : TyCtxt < ' tcx > ,
1816
+ adt : & ' tcx ty:: AdtDef ,
1817
+ field_count : usize ,
1818
+ field_spans : impl Iterator < Item = Span > ,
1819
+ sp : Span ,
1820
+ ) {
1821
+ let msg = format ! ( "needs exactly one non-zero-sized field, but has {}" , field_count) ;
1822
+ let mut err = struct_span_err ! (
1823
+ tcx. sess,
1824
+ sp,
1825
+ E0690 ,
1826
+ "{}transparent {} {}" ,
1827
+ if adt. is_enum( ) { "the variant of a " } else { "" } ,
1828
+ adt. descr( ) ,
1829
+ msg,
1830
+ ) ;
1831
+ err. span_label ( sp, & msg) ;
1832
+ for sp in field_spans {
1833
+ err. span_label ( sp, "this field is non-zero-sized" ) ;
1834
+ }
1835
+ err. emit ( ) ;
1836
+ }
1837
+
1792
1838
fn check_transparent < ' tcx > ( tcx : TyCtxt < ' tcx > , sp : Span , def_id : DefId ) {
1793
1839
let adt = tcx. adt_def ( def_id) ;
1794
1840
if !adt. repr . transparent ( ) {
@@ -1807,28 +1853,7 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1807
1853
) ;
1808
1854
}
1809
1855
if adt. variants . len ( ) != 1 {
1810
- let variant_spans: Vec < _ > = adt. variants . iter ( ) . map ( |variant| {
1811
- tcx. hir ( ) . span_if_local ( variant. def_id ) . unwrap ( )
1812
- } ) . collect ( ) ;
1813
- let msg = format ! (
1814
- "needs exactly one variant, but has {}" ,
1815
- adt. variants. len( ) ,
1816
- ) ;
1817
- let mut err = struct_span_err ! ( tcx. sess, sp, E0731 , "transparent enum {}" , msg) ;
1818
- err. span_label ( sp, & msg) ;
1819
- match & variant_spans[ ..] {
1820
- & [ ] => { } ,
1821
- & [ ref start.., ref end] => {
1822
- for variant_span in start {
1823
- err. span_label ( * variant_span, "" ) ;
1824
- }
1825
- err. span_label ( * end, & format ! (
1826
- "too many variants in `{}`" ,
1827
- tcx. def_path_str( def_id) ,
1828
- ) ) ;
1829
- } ,
1830
- }
1831
- err. emit ( ) ;
1856
+ bad_variant_count ( tcx, adt, sp, def_id) ;
1832
1857
if adt. variants . is_empty ( ) {
1833
1858
// Don't bother checking the fields. No variants (and thus no fields) exist.
1834
1859
return ;
@@ -1856,26 +1881,14 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1856
1881
( span, zst, align1)
1857
1882
} ) ;
1858
1883
1859
- let non_zst_fields = field_infos. clone ( ) . filter ( |( _span, zst, _align1) | !* zst) ;
1884
+ let non_zst_fields = field_infos. clone ( ) . filter_map ( |( span, zst, _align1) | if !zst {
1885
+ Some ( span)
1886
+ } else {
1887
+ None
1888
+ } ) ;
1860
1889
let non_zst_count = non_zst_fields. clone ( ) . count ( ) ;
1861
1890
if non_zst_count != 1 {
1862
- let field_spans: Vec < _ > = non_zst_fields. map ( |( span, _zst, _align1) | span) . collect ( ) ;
1863
-
1864
- let msg = format ! ( "needs exactly one non-zero-sized field, but has {}" , non_zst_count) ;
1865
- let mut err = struct_span_err ! (
1866
- tcx. sess,
1867
- sp,
1868
- E0690 ,
1869
- "{}transparent {} {}" ,
1870
- if adt. is_enum( ) { "the variant of a " } else { "" } ,
1871
- adt. descr( ) ,
1872
- msg,
1873
- ) ;
1874
- err. span_label ( sp, & msg) ;
1875
- for sp in & field_spans {
1876
- err. span_label ( * sp, "this field is non-zero-sized" ) ;
1877
- }
1878
- err. emit ( ) ;
1891
+ bad_non_zero_sized_fields ( tcx, adt, non_zst_count, non_zst_fields, sp) ;
1879
1892
}
1880
1893
for ( span, zst, align1) in field_infos {
1881
1894
if zst && !align1 {
0 commit comments