@@ -1942,44 +1942,77 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1942
1942
return true ;
1943
1943
} ;
1944
1944
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
+ } ;
1945
1981
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
+ }
1946
2011
if !is_expected ( ctor_def) || is_accessible {
1947
2012
return true ;
1948
2013
}
1949
2014
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) ;
1983
2016
1984
2017
if let Some ( spans) =
1985
2018
field_spans. filter ( |spans| spans. len ( ) > 0 && fields. len ( ) == spans. len ( ) )
0 commit comments