@@ -180,6 +180,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
180180 let mut expected = source. descr_expected ( ) ;
181181 let path_str = Segment :: names_to_string ( path) ;
182182 let item_str = path. last ( ) . unwrap ( ) . ident ;
183+
183184 if let Some ( res) = res {
184185 BaseError {
185186 msg : format ! ( "expected {}, found {} `{}`" , expected, res. descr( ) , path_str) ,
@@ -821,12 +822,18 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
821822 args_snippet = snippet;
822823 }
823824
824- err. span_suggestion (
825- call_span,
826- format ! ( "try calling `{ident}` as a method" ) ,
827- format ! ( "self.{path_str}({args_snippet})" ) ,
828- Applicability :: MachineApplicable ,
829- ) ;
825+ if let Some ( Res :: Def ( DefKind :: Struct , def_id) ) = res {
826+ self . update_err_for_private_tuple_struct_fields ( err, & source, def_id) ;
827+ err. note ( "constructor is not visible here due to private fields" ) ;
828+ } else {
829+ err. span_suggestion (
830+ call_span,
831+ format ! ( "try calling `{ident}` as a method" ) ,
832+ format ! ( "self.{path_str}({args_snippet})" ) ,
833+ Applicability :: MachineApplicable ,
834+ ) ;
835+ }
836+
830837 return ( true , suggested_candidates, candidates) ;
831838 }
832839 }
@@ -1611,6 +1618,47 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
16111618 }
16121619 }
16131620
1621+ fn update_err_for_private_tuple_struct_fields (
1622+ & mut self ,
1623+ err : & mut Diag < ' _ > ,
1624+ source : & PathSource < ' _ , ' _ , ' _ > ,
1625+ def_id : DefId ,
1626+ ) -> Option < Vec < Span > > {
1627+ match source {
1628+ // e.g. `if let Enum::TupleVariant(field1, field2) = _`
1629+ PathSource :: TupleStruct ( _, pattern_spans) => {
1630+ err. primary_message (
1631+ "cannot match against a tuple struct which contains private fields" ,
1632+ ) ;
1633+
1634+ // Use spans of the tuple struct pattern.
1635+ Some ( Vec :: from ( * pattern_spans) )
1636+ }
1637+ // e.g. `let _ = Enum::TupleVariant(field1, field2);`
1638+ PathSource :: Expr ( Some ( Expr {
1639+ kind : ExprKind :: Call ( path, args) ,
1640+ span : call_span,
1641+ ..
1642+ } ) ) => {
1643+ err. primary_message (
1644+ "cannot initialize a tuple struct which contains private fields" ,
1645+ ) ;
1646+ self . suggest_alternative_construction_methods (
1647+ def_id,
1648+ err,
1649+ path. span ,
1650+ * call_span,
1651+ & args[ ..] ,
1652+ ) ;
1653+ // Use spans of the tuple struct definition.
1654+ self . r
1655+ . field_idents ( def_id)
1656+ . map ( |fields| fields. iter ( ) . map ( |f| f. span ) . collect :: < Vec < _ > > ( ) )
1657+ }
1658+ _ => None ,
1659+ }
1660+ }
1661+
16141662 /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment`
16151663 /// function.
16161664 /// Returns `true` if able to provide context-dependent help.
@@ -1942,42 +1990,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
19421990 return true ;
19431991 } ;
19441992
1945- let update_message =
1946- |this : & mut Self , err : & mut Diag < ' _ > , source : & PathSource < ' _ , ' _ , ' _ > | {
1947- match source {
1948- // e.g. `if let Enum::TupleVariant(field1, field2) = _`
1949- PathSource :: TupleStruct ( _, pattern_spans) => {
1950- err. primary_message (
1951- "cannot match against a tuple struct which contains private fields" ,
1952- ) ;
1953-
1954- // Use spans of the tuple struct pattern.
1955- Some ( Vec :: from ( * pattern_spans) )
1956- }
1957- // e.g. `let _ = Enum::TupleVariant(field1, field2);`
1958- PathSource :: Expr ( Some ( Expr {
1959- kind : ExprKind :: Call ( path, args) ,
1960- span : call_span,
1961- ..
1962- } ) ) => {
1963- err. primary_message (
1964- "cannot initialize a tuple struct which contains private fields" ,
1965- ) ;
1966- this. suggest_alternative_construction_methods (
1967- def_id,
1968- err,
1969- path. span ,
1970- * call_span,
1971- & args[ ..] ,
1972- ) ;
1973- // Use spans of the tuple struct definition.
1974- this. r
1975- . field_idents ( def_id)
1976- . map ( |fields| fields. iter ( ) . map ( |f| f. span ) . collect :: < Vec < _ > > ( ) )
1977- }
1978- _ => None ,
1979- }
1980- } ;
19811993 let is_accessible = self . r . is_accessible_from ( ctor_vis, self . parent_scope . module ) ;
19821994 if let Some ( use_span) = self . r . inaccessible_ctor_reexport . get ( & span)
19831995 && is_accessible
@@ -2006,13 +2018,14 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
20062018 Applicability :: MachineApplicable ,
20072019 ) ;
20082020 }
2009- update_message ( self , err, & source) ;
2021+ self . update_err_for_private_tuple_struct_fields ( err, & source, def_id ) ;
20102022 }
20112023 if !is_expected ( ctor_def) || is_accessible {
20122024 return true ;
20132025 }
20142026
2015- let field_spans = update_message ( self , err, & source) ;
2027+ let field_spans =
2028+ self . update_err_for_private_tuple_struct_fields ( err, & source, def_id) ;
20162029
20172030 if let Some ( spans) =
20182031 field_spans. filter ( |spans| spans. len ( ) > 0 && fields. len ( ) == spans. len ( ) )
0 commit comments