@@ -35,9 +35,10 @@ use crate::imports::{ImportData, ImportKind, OnUnknownData};
3535use crate :: macros:: { MacroRulesDecl , MacroRulesScope , MacroRulesScopeRef } ;
3636use crate :: ref_mut:: CmCell ;
3737use crate :: {
38- BindingKey , Decl , DeclData , DeclKind , ExternModule , ExternPreludeEntry , Finalize , IdentKey ,
39- LocalModule , MacroData , Module , ModuleKind , ModuleOrUniformRoot , ParentScope , PathResult , Res ,
40- Resolver , Segment , Used , VisResolutionError , errors,
38+ BindingKey , Decl , DeclData , DeclKind , DelayedVisResolutionError , ExternModule ,
39+ ExternPreludeEntry , Finalize , IdentKey , LocalModule , MacroData , Module , ModuleKind ,
40+ ModuleOrUniformRoot , ParentScope , PathResult , Res , Resolver , Segment , Used , VisResolutionError ,
41+ errors,
4142} ;
4243
4344impl < ' ra , ' tcx > Resolver < ' ra , ' tcx > {
@@ -237,6 +238,111 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
237238 }
238239 }
239240
241+ pub ( crate ) fn try_resolve_visibility (
242+ & mut self ,
243+ parent_scope : & ParentScope < ' ra > ,
244+ vis : & ast:: Visibility ,
245+ finalize : bool ,
246+ ) -> Result < Visibility , VisResolutionError > {
247+ match vis. kind {
248+ ast:: VisibilityKind :: Public => Ok ( Visibility :: Public ) ,
249+ ast:: VisibilityKind :: Inherited => {
250+ Ok ( match parent_scope. module . kind {
251+ // Any inherited visibility resolved directly inside an enum or trait
252+ // (i.e. variants, fields, and trait items) inherits from the visibility
253+ // of the enum or trait.
254+ ModuleKind :: Def ( DefKind :: Enum | DefKind :: Trait , def_id, _) => {
255+ self . tcx . visibility ( def_id) . expect_local ( )
256+ }
257+ // Otherwise, the visibility is restricted to the nearest parent `mod` item.
258+ _ => Visibility :: Restricted (
259+ parent_scope. module . nearest_parent_mod ( ) . expect_local ( ) ,
260+ ) ,
261+ } )
262+ }
263+ ast:: VisibilityKind :: Restricted { ref path, id, .. } => {
264+ // For visibilities we are not ready to provide correct implementation of "uniform
265+ // paths" right now, so on 2018 edition we only allow module-relative paths for now.
266+ // On 2015 edition visibilities are resolved as crate-relative by default,
267+ // so we are prepending a root segment if necessary.
268+ let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
269+ let crate_root = if ident. is_path_segment_keyword ( ) {
270+ None
271+ } else if ident. span . is_rust_2015 ( ) {
272+ Some ( Segment :: from_ident ( Ident :: new (
273+ kw:: PathRoot ,
274+ path. span . shrink_to_lo ( ) . with_ctxt ( ident. span . ctxt ( ) ) ,
275+ ) ) )
276+ } else {
277+ return Err ( VisResolutionError :: Relative2018 (
278+ ident. span ,
279+ path. as_ref ( ) . clone ( ) ,
280+ ) ) ;
281+ } ;
282+ let segments = crate_root
283+ . into_iter ( )
284+ . chain ( path. segments . iter ( ) . map ( |seg| seg. into ( ) ) )
285+ . collect :: < Vec < _ > > ( ) ;
286+ let expected_found_error = |res| {
287+ Err ( VisResolutionError :: ExpectedFound (
288+ path. span ,
289+ Segment :: names_to_string ( & segments) ,
290+ res,
291+ ) )
292+ } ;
293+ match self . cm ( ) . resolve_path (
294+ & segments,
295+ None ,
296+ parent_scope,
297+ finalize. then ( || Finalize :: new ( id, path. span ) ) ,
298+ None ,
299+ None ,
300+ ) {
301+ PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
302+ let res = module. res ( ) . expect ( "visibility resolved to unnamed block" ) ;
303+ if module. is_normal ( ) {
304+ match res {
305+ Res :: Err => {
306+ if finalize {
307+ self . record_partial_res ( id, PartialRes :: new ( res) ) ;
308+ }
309+ Ok ( Visibility :: Public )
310+ }
311+ _ => {
312+ let vis = Visibility :: Restricted ( res. def_id ( ) ) ;
313+ if self . is_accessible_from ( vis, parent_scope. module ) {
314+ if finalize {
315+ self . record_partial_res ( id, PartialRes :: new ( res) ) ;
316+ }
317+ Ok ( vis. expect_local ( ) )
318+ } else {
319+ Err ( VisResolutionError :: AncestorOnly ( path. span ) )
320+ }
321+ }
322+ }
323+ } else {
324+ expected_found_error ( res)
325+ }
326+ }
327+ PathResult :: Module ( ..) => Err ( VisResolutionError :: ModuleOnly ( path. span ) ) ,
328+ PathResult :: NonModule ( partial_res) => {
329+ expected_found_error ( partial_res. expect_full_res ( ) )
330+ }
331+ PathResult :: Failed {
332+ span, label, suggestion, message, segment_name, ..
333+ } => Err ( VisResolutionError :: FailedToResolve (
334+ span,
335+ segment_name,
336+ label,
337+ suggestion,
338+ message,
339+ ) ) ,
340+ PathResult :: Indeterminate => Err ( VisResolutionError :: Indeterminate ( path. span ) ) ,
341+ }
342+ }
343+ }
344+ }
345+
240346 pub ( crate ) fn build_reduced_graph_external ( & self , module : ExternModule < ' ra > ) {
241347 let def_id = module. def_id ( ) ;
242348 let children = self . tcx . module_children ( def_id) ;
@@ -364,106 +470,15 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
364470 }
365471
366472 fn resolve_visibility ( & mut self , vis : & ast:: Visibility ) -> Visibility {
367- self . try_resolve_visibility ( vis, true ) . unwrap_or_else ( |err| {
368- self . r . report_vis_error ( err) ;
369- Visibility :: Public
370- } )
371- }
372-
373- fn try_resolve_visibility < ' ast > (
374- & mut self ,
375- vis : & ' ast ast:: Visibility ,
376- finalize : bool ,
377- ) -> Result < Visibility , VisResolutionError < ' ast > > {
378- let parent_scope = & self . parent_scope ;
379- match vis. kind {
380- ast:: VisibilityKind :: Public => Ok ( Visibility :: Public ) ,
381- ast:: VisibilityKind :: Inherited => {
382- Ok ( match self . parent_scope . module . kind {
383- // Any inherited visibility resolved directly inside an enum or trait
384- // (i.e. variants, fields, and trait items) inherits from the visibility
385- // of the enum or trait.
386- ModuleKind :: Def ( DefKind :: Enum | DefKind :: Trait , def_id, _) => {
387- self . r . tcx . visibility ( def_id) . expect_local ( )
388- }
389- // Otherwise, the visibility is restricted to the nearest parent `mod` item.
390- _ => Visibility :: Restricted (
391- self . parent_scope . module . nearest_parent_mod ( ) . expect_local ( ) ,
392- ) ,
393- } )
394- }
395- ast:: VisibilityKind :: Restricted { ref path, id, .. } => {
396- // For visibilities we are not ready to provide correct implementation of "uniform
397- // paths" right now, so on 2018 edition we only allow module-relative paths for now.
398- // On 2015 edition visibilities are resolved as crate-relative by default,
399- // so we are prepending a root segment if necessary.
400- let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
401- let crate_root = if ident. is_path_segment_keyword ( ) {
402- None
403- } else if ident. span . is_rust_2015 ( ) {
404- Some ( Segment :: from_ident ( Ident :: new (
405- kw:: PathRoot ,
406- path. span . shrink_to_lo ( ) . with_ctxt ( ident. span . ctxt ( ) ) ,
407- ) ) )
408- } else {
409- return Err ( VisResolutionError :: Relative2018 ( ident. span , path) ) ;
410- } ;
411-
412- let segments = crate_root
413- . into_iter ( )
414- . chain ( path. segments . iter ( ) . map ( |seg| seg. into ( ) ) )
415- . collect :: < Vec < _ > > ( ) ;
416- let expected_found_error = |res| {
417- Err ( VisResolutionError :: ExpectedFound (
418- path. span ,
419- Segment :: names_to_string ( & segments) ,
420- res,
421- ) )
422- } ;
423- match self . r . cm ( ) . resolve_path (
424- & segments,
425- None ,
426- parent_scope,
427- finalize. then ( || Finalize :: new ( id, path. span ) ) ,
428- None ,
429- None ,
430- ) {
431- PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
432- let res = module. res ( ) . expect ( "visibility resolved to unnamed block" ) ;
433- if finalize {
434- self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
435- }
436- if module. is_normal ( ) {
437- match res {
438- Res :: Err => Ok ( Visibility :: Public ) ,
439- _ => {
440- let vis = Visibility :: Restricted ( res. def_id ( ) ) ;
441- if self . r . is_accessible_from ( vis, parent_scope. module ) {
442- Ok ( vis. expect_local ( ) )
443- } else {
444- Err ( VisResolutionError :: AncestorOnly ( path. span ) )
445- }
446- }
447- }
448- } else {
449- expected_found_error ( res)
450- }
451- }
452- PathResult :: Module ( ..) => Err ( VisResolutionError :: ModuleOnly ( path. span ) ) ,
453- PathResult :: NonModule ( partial_res) => {
454- expected_found_error ( partial_res. expect_full_res ( ) )
455- }
456- PathResult :: Failed {
457- span, label, suggestion, message, segment_name, ..
458- } => Err ( VisResolutionError :: FailedToResolve (
459- span,
460- segment_name,
461- label,
462- suggestion,
463- message,
464- ) ) ,
465- PathResult :: Indeterminate => Err ( VisResolutionError :: Indeterminate ( path. span ) ) ,
466- }
473+ match self . r . try_resolve_visibility ( & self . parent_scope , vis, true ) {
474+ Ok ( vis) => vis,
475+ Err ( error) => {
476+ self . r . delayed_vis_resolution_errors . push ( DelayedVisResolutionError {
477+ vis : vis. clone ( ) ,
478+ parent_scope : self . parent_scope ,
479+ error,
480+ } ) ;
481+ Visibility :: Public
467482 }
468483 }
469484 }
@@ -906,7 +921,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
906921 // correct visibilities for unnamed field placeholders specifically, so the
907922 // constructor visibility should still be determined correctly.
908923 let field_vis = self
909- . try_resolve_visibility ( & field. vis , false )
924+ . r
925+ . try_resolve_visibility ( & self . parent_scope , & field. vis , false )
910926 . unwrap_or ( Visibility :: Public ) ;
911927 if ctor_vis. greater_than ( field_vis, self . r . tcx ) {
912928 ctor_vis = field_vis;
@@ -1341,9 +1357,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
13411357 let vis = match item. kind {
13421358 // Visibilities must not be resolved non-speculatively twice
13431359 // and we already resolved this one as a `fn` item visibility.
1344- ItemKind :: Fn ( ..) => {
1345- self . try_resolve_visibility ( & item. vis , false ) . unwrap_or ( Visibility :: Public )
1346- }
1360+ ItemKind :: Fn ( ..) => self
1361+ . r
1362+ . try_resolve_visibility ( & self . parent_scope , & item. vis , false )
1363+ . unwrap_or ( Visibility :: Public ) ,
13471364 _ => self . resolve_visibility ( & item. vis ) ,
13481365 } ;
13491366 if !vis. is_public ( ) {
0 commit comments