@@ -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 > {
@@ -355,38 +356,50 @@ impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for DefCollector<'_, 'ra, 'tcx> {
355356 }
356357}
357358
358- impl < ' a , ' ra , ' tcx > DefCollector < ' a , ' ra , ' tcx > {
359- fn res ( & self , def_id : impl Into < DefId > ) -> Res {
360- let def_id = def_id. into ( ) ;
361- Res :: Def ( self . r . tcx . def_kind ( def_id) , def_id)
362- }
359+ impl < ' ra , ' tcx > Resolver < ' ra , ' tcx > {
360+ fn visibility_path_segments (
361+ & self ,
362+ path : & ast:: Path ,
363+ ) -> Result < Vec < Segment > , VisResolutionError > {
364+ let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
365+ let crate_root = if ident. is_path_segment_keyword ( ) {
366+ None
367+ } else if ident. span . is_rust_2015 ( ) {
368+ Some ( Segment :: from_ident ( Ident :: new (
369+ kw:: PathRoot ,
370+ path. span . shrink_to_lo ( ) . with_ctxt ( ident. span . ctxt ( ) ) ,
371+ ) ) )
372+ } else {
373+ return Err ( VisResolutionError :: Relative2018 ( ident. span , path. clone ( ) ) ) ;
374+ } ;
363375
364- 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- } )
376+ Ok ( crate_root
377+ . into_iter ( )
378+ . chain ( path. segments . iter ( ) . map ( |seg| seg. into ( ) ) )
379+ . collect :: < Vec < _ > > ( ) )
369380 }
370381
371- fn try_resolve_visibility < ' ast > (
382+ pub ( crate ) fn try_resolve_visibility (
372383 & mut self ,
373- vis : & ' ast ast:: Visibility ,
384+ parent_scope : ParentScope < ' ra > ,
385+ vis : & ast:: Visibility ,
374386 finalize : bool ,
375- ) -> Result < Visibility , VisResolutionError < ' ast > > {
376- let parent_scope = & self . parent_scope ;
387+ record_partial_res : bool ,
388+ ) -> Result < Visibility , VisResolutionError > {
389+ let parent_scope_ref = & parent_scope;
377390 match vis. kind {
378391 ast:: VisibilityKind :: Public => Ok ( Visibility :: Public ) ,
379392 ast:: VisibilityKind :: Inherited => {
380- Ok ( match self . parent_scope . module . kind {
393+ Ok ( match parent_scope. module . kind {
381394 // Any inherited visibility resolved directly inside an enum or trait
382395 // (i.e. variants, fields, and trait items) inherits from the visibility
383396 // of the enum or trait.
384397 ModuleKind :: Def ( DefKind :: Enum | DefKind :: Trait , def_id, _) => {
385- self . r . tcx . visibility ( def_id) . expect_local ( )
398+ self . tcx . visibility ( def_id) . expect_local ( )
386399 }
387400 // Otherwise, the visibility is restricted to the nearest parent `mod` item.
388401 _ => Visibility :: Restricted (
389- self . parent_scope . module . nearest_parent_mod ( ) . expect_local ( ) ,
402+ parent_scope. module . nearest_parent_mod ( ) . expect_local ( ) ,
390403 ) ,
391404 } )
392405 }
@@ -395,48 +408,33 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
395408 // paths" right now, so on 2018 edition we only allow module-relative paths for now.
396409 // On 2015 edition visibilities are resolved as crate-relative by default,
397410 // 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 < _ > > ( ) ;
411+ let segments = self . visibility_path_segments ( path) ?;
414412 let expected_found_error = |res| {
415413 Err ( VisResolutionError :: ExpectedFound (
416414 path. span ,
417415 Segment :: names_to_string ( & segments) ,
418416 res,
419417 ) )
420418 } ;
421- match self . r . cm ( ) . resolve_path (
419+ match self . cm ( ) . resolve_path (
422420 & segments,
423421 None ,
424- parent_scope ,
422+ parent_scope_ref ,
425423 finalize. then ( || Finalize :: new ( id, path. span ) ) ,
426424 None ,
427425 None ,
428426 ) {
429427 PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
430428 let res = module. res ( ) . expect ( "visibility resolved to unnamed block" ) ;
431- if finalize {
432- self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
429+ if record_partial_res {
430+ self . record_partial_res ( id, PartialRes :: new ( res) ) ;
433431 }
434432 if module. is_normal ( ) {
435433 match res {
436434 Res :: Err => Ok ( Visibility :: Public ) ,
437435 _ => {
438436 let vis = Visibility :: Restricted ( res. def_id ( ) ) ;
439- if self . r . is_accessible_from ( vis, parent_scope. module ) {
437+ if self . is_accessible_from ( vis, parent_scope. module ) {
440438 Ok ( vis. expect_local ( ) )
441439 } else {
442440 Err ( VisResolutionError :: AncestorOnly ( path. span ) )
@@ -465,6 +463,27 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
465463 }
466464 }
467465 }
466+ }
467+
468+ impl < ' a , ' ra , ' tcx > DefCollector < ' a , ' ra , ' tcx > {
469+ fn res ( & self , def_id : impl Into < DefId > ) -> Res {
470+ let def_id = def_id. into ( ) ;
471+ Res :: Def ( self . r . tcx . def_kind ( def_id) , def_id)
472+ }
473+
474+ fn resolve_visibility ( & mut self , vis : & ast:: Visibility ) -> Visibility {
475+ match self . r . try_resolve_visibility ( self . parent_scope , vis, true , true ) {
476+ Ok ( vis) => vis,
477+ Err ( error) => {
478+ self . r . delayed_vis_resolution_errors . push ( DelayedVisResolutionError {
479+ vis : vis. clone ( ) ,
480+ parent_scope : self . parent_scope ,
481+ error,
482+ } ) ;
483+ Visibility :: Public
484+ }
485+ }
486+ }
468487
469488 fn insert_field_idents ( & mut self , def_id : LocalDefId , fields : & [ ast:: FieldDef ] ) {
470489 if fields. iter ( ) . any ( |field| field. is_placeholder ) {
@@ -904,7 +923,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
904923 // correct visibilities for unnamed field placeholders specifically, so the
905924 // constructor visibility should still be determined correctly.
906925 let field_vis = self
907- . try_resolve_visibility ( & field. vis , false )
926+ . r
927+ . try_resolve_visibility ( self . parent_scope , & field. vis , false , false )
908928 . unwrap_or ( Visibility :: Public ) ;
909929 if ctor_vis. greater_than ( field_vis, self . r . tcx ) {
910930 ctor_vis = field_vis;
@@ -1339,9 +1359,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
13391359 let vis = match item. kind {
13401360 // Visibilities must not be resolved non-speculatively twice
13411361 // 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- }
1362+ ItemKind :: Fn ( ..) => self
1363+ . r
1364+ . try_resolve_visibility ( self . parent_scope , & item. vis , false , false )
1365+ . unwrap_or ( Visibility :: Public ) ,
13451366 _ => self . resolve_visibility ( & item. vis ) ,
13461367 } ;
13471368 if !vis. is_public ( ) {
0 commit comments