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