@@ -1942,44 +1942,77 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
19421942 return true ;
19431943 } ;
19441944
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+ } ;
19451981 let is_accessible = self . r . is_accessible_from ( ctor_vis, self . parent_scope . module ) ;
1982+ if let Some ( use_span) = self . r . inaccessible_ctor_reexport . get ( & span)
1983+ && is_accessible
1984+ {
1985+ err. span_note (
1986+ * use_span,
1987+ "the type is accessed through this re-export, but the type's constructor \
1988+ is not visible in this import's scope due to private fields",
1989+ ) ;
1990+ if is_accessible
1991+ && fields
1992+ . iter ( )
1993+ . all ( |vis| self . r . is_accessible_from ( * vis, self . parent_scope . module ) )
1994+ {
1995+ err. span_suggestion_verbose (
1996+ span,
1997+ "the type can be constructed directly, because its fields are \
1998+ available from the current scope",
1999+ // Using `tcx.def_path_str` causes the compiler to hang.
2000+ // We don't need to handle foreign crate types because in that case you
2001+ // can't access the ctor either way.
2002+ format ! (
2003+ "crate{}" , // The method already has leading `::`.
2004+ self . r. tcx. def_path( def_id) . to_string_no_crate_verbose( ) ,
2005+ ) ,
2006+ Applicability :: MachineApplicable ,
2007+ ) ;
2008+ }
2009+ update_message ( self , err, & source) ;
2010+ }
19462011 if !is_expected ( ctor_def) || is_accessible {
19472012 return true ;
19482013 }
19492014
1950- let field_spans = match source {
1951- // e.g. `if let Enum::TupleVariant(field1, field2) = _`
1952- PathSource :: TupleStruct ( _, pattern_spans) => {
1953- err. primary_message (
1954- "cannot match against a tuple struct which contains private fields" ,
1955- ) ;
1956-
1957- // Use spans of the tuple struct pattern.
1958- Some ( Vec :: from ( pattern_spans) )
1959- }
1960- // e.g. `let _ = Enum::TupleVariant(field1, field2);`
1961- PathSource :: Expr ( Some ( Expr {
1962- kind : ExprKind :: Call ( path, args) ,
1963- span : call_span,
1964- ..
1965- } ) ) => {
1966- err. primary_message (
1967- "cannot initialize a tuple struct which contains private fields" ,
1968- ) ;
1969- self . suggest_alternative_construction_methods (
1970- def_id,
1971- err,
1972- path. span ,
1973- * call_span,
1974- & args[ ..] ,
1975- ) ;
1976- // Use spans of the tuple struct definition.
1977- self . r
1978- . field_idents ( def_id)
1979- . map ( |fields| fields. iter ( ) . map ( |f| f. span ) . collect :: < Vec < _ > > ( ) )
1980- }
1981- _ => None ,
1982- } ;
2015+ let field_spans = update_message ( self , err, & source) ;
19832016
19842017 if let Some ( spans) =
19852018 field_spans. filter ( |spans| spans. len ( ) > 0 && fields. len ( ) == spans. len ( ) )
0 commit comments