@@ -23,13 +23,12 @@ use crate::type_error_struct;
2323
2424use super :: suggest_call_constructor;
2525use crate :: errors:: { AddressOfTemporaryTaken , ReturnStmtOutsideOfFnBody , StructExprNonExhaustive } ;
26- use itertools:: { Either , Itertools } ;
2726use rustc_ast as ast;
2827use rustc_data_structures:: fx:: FxHashMap ;
2928use rustc_data_structures:: stack:: ensure_sufficient_stack;
3029use rustc_errors:: {
3130 pluralize, struct_span_err, Applicability , Diagnostic , DiagnosticBuilder , DiagnosticId ,
32- EmissionGuarantee , ErrorGuaranteed , MultiSpan ,
31+ EmissionGuarantee , ErrorGuaranteed ,
3332} ;
3433use rustc_hir as hir;
3534use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
@@ -1682,11 +1681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16821681 } )
16831682 . collect ( ) ;
16841683
1685- if !private_fields. is_empty ( )
1686- && tcx
1687- . visibility ( variant. def_id )
1688- . is_accessible_from ( tcx. parent_module ( expr_id) . to_def_id ( ) , tcx)
1689- {
1684+ if !private_fields. is_empty ( ) {
16901685 self . report_private_fields ( adt_ty, span, private_fields, ast_fields) ;
16911686 } else {
16921687 self . report_missing_fields (
@@ -1826,49 +1821,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18261821 private_fields : Vec < & ty:: FieldDef > ,
18271822 used_fields : & ' tcx [ hir:: ExprField < ' tcx > ] ,
18281823 ) {
1829- let field_names = |fields : Vec < Symbol > , len : usize | match & fields
1824+ let mut err = self . tcx . sess . struct_span_err (
1825+ span,
1826+ & format ! (
1827+ "cannot construct `{adt_ty}` with struct literal syntax due to private fields" ,
1828+ ) ,
1829+ ) ;
1830+ let ( used_private_fields, remaining_private_fields) : (
1831+ Vec < ( Symbol , Span , bool ) > ,
1832+ Vec < ( Symbol , Span , bool ) > ,
1833+ ) = private_fields
1834+ . iter ( )
1835+ . map ( |field| {
1836+ match used_fields. iter ( ) . find ( |used_field| field. name == used_field. ident . name ) {
1837+ Some ( used_field) => ( field. name , used_field. span , true ) ,
1838+ None => ( field. name , self . tcx . def_span ( field. did ) , false ) ,
1839+ }
1840+ } )
1841+ . partition ( |field| field. 2 ) ;
1842+ let remaining_private_fields_len = remaining_private_fields. len ( ) ;
1843+ let names = match & remaining_private_fields
18301844 . iter ( )
1831- . map ( |field| field . to_string ( ) )
1845+ . map ( |( name , _ , _ ) | name . to_string ( ) )
18321846 . collect :: < Vec < _ > > ( ) [ ..]
18331847 {
1834- _ if len > 6 => String :: new ( ) ,
1848+ _ if remaining_private_fields_len > 6 => String :: new ( ) ,
18351849 [ name] => format ! ( "`{name}` " ) ,
18361850 [ names @ .., last] => {
18371851 let names = names. iter ( ) . map ( |name| format ! ( "`{name}`" ) ) . collect :: < Vec < _ > > ( ) ;
18381852 format ! ( "{} and `{last}` " , names. join( ", " ) )
18391853 }
18401854 [ ] => unreachable ! ( ) ,
18411855 } ;
1842-
1843- let mut err = self . tcx . sess . struct_span_err (
1844- span,
1845- & format ! (
1846- "cannot construct `{adt_ty}` with struct literal syntax due to private fields" ,
1847- ) ,
1848- ) ;
1849- let ( used_private_fields, remaining_private_fields) : (
1850- Vec < ( Symbol , Span ) > ,
1851- Vec < ( Symbol , Span ) > ,
1852- ) = private_fields. iter ( ) . partition_map ( |field| {
1853- match used_fields. iter ( ) . find ( |used_field| field. name == used_field. ident . name ) {
1854- Some ( used_field) => Either :: Left ( ( field. name , used_field. span ) ) ,
1855- None => Either :: Right ( ( field. name , self . tcx . def_span ( field. did ) ) ) ,
1856- }
1857- } ) ;
1858- let remaining_private_fields_len = remaining_private_fields. len ( ) ;
1859- err. span_labels ( used_private_fields. iter ( ) . map ( |( _, span) | * span) , "private field" ) ;
1860- err. span_note (
1861- MultiSpan :: from_spans ( remaining_private_fields. iter ( ) . map ( |( _, span) | * span) . collect ( ) ) ,
1862- format ! (
1863- "missing field{s} {names}{are} private" ,
1864- s = pluralize!( remaining_private_fields_len) ,
1865- are = pluralize!( "is" , remaining_private_fields_len) ,
1866- names = field_names(
1867- remaining_private_fields. iter( ) . map( |( name, _) | * name) . collect( ) ,
1868- remaining_private_fields_len
1869- )
1870- ) ,
1871- ) ;
1856+ err. span_labels ( used_private_fields. iter ( ) . map ( |( _, span, _) | * span) , "private field" ) ;
1857+ err. note ( format ! (
1858+ "... and other private field{s} {names}that were not provided" ,
1859+ s = pluralize!( remaining_private_fields_len) ,
1860+ ) ) ;
18721861 err. emit ( ) ;
18731862 }
18741863
0 commit comments