@@ -12,7 +12,7 @@ use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleIm
1212use crate :: { Module , ModuleData , ModuleKind , NameBinding , NameBindingKind , Segment , ToNameBinding } ;
1313use crate :: { ModuleOrUniformRoot , ParentScope , PerNS , Resolver , ResolverArenas , ExternPreludeEntry } ;
1414use crate :: Namespace :: { self , TypeNS , ValueNS , MacroNS } ;
15- use crate :: { ResolutionError , Determinacy , PathResult , CrateLint } ;
15+ use crate :: { ResolutionError , VisResolutionError , Determinacy , PathResult , CrateLint } ;
1616
1717use rustc:: bug;
1818use rustc:: hir:: def:: { self , * } ;
@@ -32,8 +32,7 @@ use syntax::attr;
3232use syntax:: ast:: { self , Block , ForeignItem , ForeignItemKind , Item , ItemKind , NodeId } ;
3333use syntax:: ast:: { MetaItemKind , StmtKind , TraitItem , TraitItemKind } ;
3434use syntax:: token:: { self , Token } ;
35- use syntax:: print:: pprust;
36- use syntax:: { span_err, struct_span_err} ;
35+ use syntax:: span_err;
3736use syntax:: source_map:: { respan, Spanned } ;
3837use syntax:: symbol:: { kw, sym} ;
3938use syntax:: visit:: { self , Visitor } ;
@@ -192,14 +191,25 @@ impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
192191
193192impl < ' a , ' b > BuildReducedGraphVisitor < ' a , ' b > {
194193 fn resolve_visibility ( & mut self , vis : & ast:: Visibility ) -> ty:: Visibility {
194+ self . resolve_visibility_speculative ( vis, false ) . unwrap_or_else ( |err| {
195+ self . r . report_vis_error ( err) ;
196+ ty:: Visibility :: Public
197+ } )
198+ }
199+
200+ fn resolve_visibility_speculative < ' ast > (
201+ & mut self ,
202+ vis : & ' ast ast:: Visibility ,
203+ speculative : bool ,
204+ ) -> Result < ty:: Visibility , VisResolutionError < ' ast > > {
195205 let parent_scope = & self . parent_scope ;
196206 match vis. node {
197- ast:: VisibilityKind :: Public => ty:: Visibility :: Public ,
207+ ast:: VisibilityKind :: Public => Ok ( ty:: Visibility :: Public ) ,
198208 ast:: VisibilityKind :: Crate ( ..) => {
199- ty:: Visibility :: Restricted ( DefId :: local ( CRATE_DEF_INDEX ) )
209+ Ok ( ty:: Visibility :: Restricted ( DefId :: local ( CRATE_DEF_INDEX ) ) )
200210 }
201211 ast:: VisibilityKind :: Inherited => {
202- ty:: Visibility :: Restricted ( parent_scope. module . normal_ancestor_id )
212+ Ok ( ty:: Visibility :: Restricted ( parent_scope. module . normal_ancestor_id ) )
203213 }
204214 ast:: VisibilityKind :: Restricted { ref path, id, .. } => {
205215 // For visibilities we are not ready to provide correct implementation of "uniform
@@ -209,86 +219,67 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
209219 let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
210220 let crate_root = if ident. is_path_segment_keyword ( ) {
211221 None
212- } else if ident. span . rust_2018 ( ) {
213- let msg = "relative paths are not supported in visibilities on 2018 edition" ;
214- self . r . session . struct_span_err ( ident. span , msg)
215- . span_suggestion (
216- path. span ,
217- "try" ,
218- format ! ( "crate::{}" , pprust:: path_to_string( & path) ) ,
219- Applicability :: MaybeIncorrect ,
220- )
221- . emit ( ) ;
222- return ty:: Visibility :: Public ;
223- } else {
224- let ctxt = ident. span . ctxt ( ) ;
222+ } else if ident. span . rust_2015 ( ) {
225223 Some ( Segment :: from_ident ( Ident :: new (
226- kw:: PathRoot , path. span . shrink_to_lo ( ) . with_ctxt ( ctxt)
224+ kw:: PathRoot , path. span . shrink_to_lo ( ) . with_ctxt ( ident . span . ctxt ( ) )
227225 ) ) )
226+ } else {
227+ return Err ( VisResolutionError :: Relative2018 ( ident. span , path) ) ;
228228 } ;
229229
230230 let segments = crate_root. into_iter ( )
231231 . chain ( path. segments . iter ( ) . map ( |seg| seg. into ( ) ) ) . collect :: < Vec < _ > > ( ) ;
232- let expected_found_error = |this : & Self , res : Res | {
233- let path_str = Segment :: names_to_string ( & segments) ;
234- struct_span_err ! ( this. r. session, path. span, E0577 ,
235- "expected module, found {} `{}`" , res. descr( ) , path_str)
236- . span_label ( path. span , "not a module" ) . emit ( ) ;
237- } ;
232+ let expected_found_error = |res| Err ( VisResolutionError :: ExpectedFound (
233+ path. span , Segment :: names_to_string ( & segments) , res
234+ ) ) ;
238235 match self . r . resolve_path (
239236 & segments,
240237 Some ( TypeNS ) ,
241238 parent_scope,
242- true ,
239+ !speculative ,
243240 path. span ,
244241 CrateLint :: SimplePath ( id) ,
245242 ) {
246243 PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
247244 let res = module. res ( ) . expect ( "visibility resolved to unnamed block" ) ;
248- self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
245+ if !speculative {
246+ self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
247+ }
249248 if module. is_normal ( ) {
250249 if res == Res :: Err {
251- ty:: Visibility :: Public
250+ Ok ( ty:: Visibility :: Public )
252251 } else {
253252 let vis = ty:: Visibility :: Restricted ( res. def_id ( ) ) ;
254253 if self . r . is_accessible_from ( vis, parent_scope. module ) {
255- vis
254+ Ok ( vis)
256255 } else {
257- struct_span_err ! ( self . r. session, path. span, E0742 ,
258- "visibilities can only be restricted to ancestor modules" )
259- . emit ( ) ;
260- ty:: Visibility :: Public
256+ Err ( VisResolutionError :: AncestorOnly ( path. span ) )
261257 }
262258 }
263259 } else {
264- expected_found_error ( self , res) ;
265- ty:: Visibility :: Public
260+ expected_found_error ( res)
266261 }
267262 }
268- PathResult :: Module ( ..) => {
269- self . r . session . span_err ( path. span , "visibility must resolve to a module" ) ;
270- ty:: Visibility :: Public
271- }
272- PathResult :: NonModule ( partial_res) => {
273- expected_found_error ( self , partial_res. base_res ( ) ) ;
274- ty:: Visibility :: Public
275- }
276- PathResult :: Failed { span, label, suggestion, .. } => {
277- self . r . report_error (
278- span, ResolutionError :: FailedToResolve { label, suggestion }
279- ) ;
280- ty:: Visibility :: Public
281- }
282- PathResult :: Indeterminate => {
283- span_err ! ( self . r. session, path. span, E0578 ,
284- "cannot determine resolution for the visibility" ) ;
285- ty:: Visibility :: Public
286- }
263+ PathResult :: Module ( ..) =>
264+ Err ( VisResolutionError :: ModuleOnly ( path. span ) ) ,
265+ PathResult :: NonModule ( partial_res) =>
266+ expected_found_error ( partial_res. base_res ( ) ) ,
267+ PathResult :: Failed { span, label, suggestion, .. } =>
268+ Err ( VisResolutionError :: FailedToResolve ( span, label, suggestion) ) ,
269+ PathResult :: Indeterminate =>
270+ Err ( VisResolutionError :: Indeterminate ( path. span ) ) ,
287271 }
288272 }
289273 }
290274 }
291275
276+ fn insert_field_names_local ( & mut self , def_id : DefId , vdata : & ast:: VariantData ) {
277+ let field_names = vdata. fields ( ) . iter ( ) . map ( |field| {
278+ respan ( field. span , field. ident . map_or ( kw:: Invalid , |ident| ident. name ) )
279+ } ) . collect ( ) ;
280+ self . insert_field_names ( def_id, field_names) ;
281+ }
282+
292283 fn insert_field_names ( & mut self , def_id : DefId , field_names : Vec < Spanned < Name > > ) {
293284 if !field_names. is_empty ( ) {
294285 self . r . field_names . insert ( def_id, field_names) ;
@@ -726,59 +717,52 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
726717 }
727718
728719 // These items live in both the type and value namespaces.
729- ItemKind :: Struct ( ref struct_def , _) => {
720+ ItemKind :: Struct ( ref vdata , _) => {
730721 // Define a name in the type namespace.
731722 let def_id = self . r . definitions . local_def_id ( item. id ) ;
732723 let res = Res :: Def ( DefKind :: Struct , def_id) ;
733724 self . r . define ( parent, ident, TypeNS , ( res, vis, sp, expansion) ) ;
734725
735- let mut ctor_vis = vis;
736-
737- let has_non_exhaustive = attr:: contains_name ( & item. attrs , sym:: non_exhaustive) ;
738-
739- // If the structure is marked as non_exhaustive then lower the visibility
740- // to within the crate.
741- if has_non_exhaustive && vis == ty:: Visibility :: Public {
742- ctor_vis = ty:: Visibility :: Restricted ( DefId :: local ( CRATE_DEF_INDEX ) ) ;
743- }
744-
745726 // Record field names for error reporting.
746- let field_names = struct_def. fields ( ) . iter ( ) . map ( |field| {
747- // NOTE: The field may be an expansion placeholder, but expansion sets correct
748- // visibilities for unnamed field placeholders specifically, so the constructor
749- // visibility should still be determined correctly.
750- let field_vis = self . resolve_visibility ( & field. vis ) ;
751- if ctor_vis. is_at_least ( field_vis, & * self . r ) {
752- ctor_vis = field_vis;
753- }
754- respan ( field. span , field. ident . map_or ( kw:: Invalid , |ident| ident. name ) )
755- } ) . collect ( ) ;
756- let item_def_id = self . r . definitions . local_def_id ( item. id ) ;
757- self . insert_field_names ( item_def_id, field_names) ;
727+ self . insert_field_names_local ( def_id, vdata) ;
758728
759729 // If this is a tuple or unit struct, define a name
760730 // in the value namespace as well.
761- if let Some ( ctor_node_id) = struct_def. ctor_id ( ) {
731+ if let Some ( ctor_node_id) = vdata. ctor_id ( ) {
732+ let mut ctor_vis = vis;
733+ // If the structure is marked as non_exhaustive then lower the visibility
734+ // to within the crate.
735+ if vis == ty:: Visibility :: Public &&
736+ attr:: contains_name ( & item. attrs , sym:: non_exhaustive) {
737+ ctor_vis = ty:: Visibility :: Restricted ( DefId :: local ( CRATE_DEF_INDEX ) ) ;
738+ }
739+ for field in vdata. fields ( ) {
740+ // NOTE: The field may be an expansion placeholder, but expansion sets
741+ // correct visibilities for unnamed field placeholders specifically, so the
742+ // constructor visibility should still be determined correctly.
743+ if let Ok ( field_vis) =
744+ self . resolve_visibility_speculative ( & field. vis , true ) {
745+ if ctor_vis. is_at_least ( field_vis, & * self . r ) {
746+ ctor_vis = field_vis;
747+ }
748+ }
749+ }
762750 let ctor_res = Res :: Def (
763- DefKind :: Ctor ( CtorOf :: Struct , CtorKind :: from_ast ( struct_def ) ) ,
751+ DefKind :: Ctor ( CtorOf :: Struct , CtorKind :: from_ast ( vdata ) ) ,
764752 self . r . definitions . local_def_id ( ctor_node_id) ,
765753 ) ;
766754 self . r . define ( parent, ident, ValueNS , ( ctor_res, ctor_vis, sp, expansion) ) ;
767- self . r . struct_constructors . insert ( res . def_id ( ) , ( ctor_res, ctor_vis) ) ;
755+ self . r . struct_constructors . insert ( def_id, ( ctor_res, ctor_vis) ) ;
768756 }
769757 }
770758
771759 ItemKind :: Union ( ref vdata, _) => {
772- let res = Res :: Def ( DefKind :: Union , self . r . definitions . local_def_id ( item. id ) ) ;
760+ let def_id = self . r . definitions . local_def_id ( item. id ) ;
761+ let res = Res :: Def ( DefKind :: Union , def_id) ;
773762 self . r . define ( parent, ident, TypeNS , ( res, vis, sp, expansion) ) ;
774763
775764 // Record field names for error reporting.
776- let field_names = vdata. fields ( ) . iter ( ) . map ( |field| {
777- self . resolve_visibility ( & field. vis ) ;
778- respan ( field. span , field. ident . map_or ( kw:: Invalid , |ident| ident. name ) )
779- } ) . collect ( ) ;
780- let item_def_id = self . r . definitions . local_def_id ( item. id ) ;
781- self . insert_field_names ( item_def_id, field_names) ;
765+ self . insert_field_names_local ( def_id, vdata) ;
782766 }
783767
784768 ItemKind :: Impl ( .., ref impl_items) => {
@@ -1281,6 +1265,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
12811265 if sf. is_placeholder {
12821266 self . visit_invoc ( sf. id ) ;
12831267 } else {
1268+ self . resolve_visibility ( & sf. vis ) ;
12841269 visit:: walk_struct_field ( self , sf) ;
12851270 }
12861271 }
0 commit comments