@@ -1789,6 +1789,52 @@ fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<De
17891789 false
17901790}
17911791
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+
17921838fn check_transparent < ' tcx > ( tcx : TyCtxt < ' tcx > , sp : Span , def_id : DefId ) {
17931839 let adt = tcx. adt_def ( def_id) ;
17941840 if !adt. repr . transparent ( ) {
@@ -1807,28 +1853,7 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
18071853 ) ;
18081854 }
18091855 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) ;
18321857 if adt. variants . is_empty ( ) {
18331858 // Don't bother checking the fields. No variants (and thus no fields) exist.
18341859 return ;
@@ -1856,26 +1881,14 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
18561881 ( span, zst, align1)
18571882 } ) ;
18581883
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+ } ) ;
18601889 let non_zst_count = non_zst_fields. clone ( ) . count ( ) ;
18611890 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) ;
18791892 }
18801893 for ( span, zst, align1) in field_infos {
18811894 if zst && !align1 {
0 commit comments