@@ -46,9 +46,10 @@ use rustc_index::vec::IndexVec;
46
46
use rustc_metadata:: creader:: { CStore , CrateLoader } ;
47
47
use rustc_middle:: hir:: exports:: ExportMap ;
48
48
use rustc_middle:: middle:: cstore:: { CrateStore , MetadataLoaderDyn } ;
49
+ use rustc_middle:: middle:: privacy:: AccessLevel ;
49
50
use rustc_middle:: span_bug;
50
51
use rustc_middle:: ty:: query:: Providers ;
51
- use rustc_middle:: ty:: { self , DefIdTree , MainDefinition , ResolverOutputs } ;
52
+ use rustc_middle:: ty:: { self , DefIdTree , MainDefinition , ResolverOutputs , Visibility } ;
52
53
use rustc_session:: lint;
53
54
use rustc_session:: lint:: { BuiltinLintDiagnostics , LintBuffer } ;
54
55
use rustc_session:: Session ;
@@ -1032,6 +1033,8 @@ pub struct Resolver<'a> {
1032
1033
legacy_const_generic_args : FxHashMap < DefId , Option < Vec < usize > > > ,
1033
1034
1034
1035
main_def : Option < MainDefinition > ,
1036
+
1037
+ nodes_access_level : FxHashMap < LocalDefId , AccessLevel > ,
1035
1038
}
1036
1039
1037
1040
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1393,6 +1396,8 @@ impl<'a> Resolver<'a> {
1393
1396
trait_impl_items : Default :: default ( ) ,
1394
1397
legacy_const_generic_args : Default :: default ( ) ,
1395
1398
main_def : Default :: default ( ) ,
1399
+
1400
+ nodes_access_level : Default :: default ( ) ,
1396
1401
} ;
1397
1402
1398
1403
let root_parent_scope = ParentScope :: module ( graph_root, & resolver) ;
@@ -1435,10 +1440,12 @@ impl<'a> Resolver<'a> {
1435
1440
let maybe_unused_extern_crates = self . maybe_unused_extern_crates ;
1436
1441
let glob_map = self . glob_map ;
1437
1442
let main_def = self . main_def ;
1443
+ let access_levels = self . nodes_access_level ;
1438
1444
ResolverOutputs {
1439
1445
definitions,
1440
1446
cstore : Box :: new ( self . crate_loader . into_cstore ( ) ) ,
1441
1447
visibilities,
1448
+ access_levels,
1442
1449
extern_crate_map,
1443
1450
export_map,
1444
1451
glob_map,
@@ -1456,6 +1463,7 @@ impl<'a> Resolver<'a> {
1456
1463
pub fn clone_outputs ( & self ) -> ResolverOutputs {
1457
1464
ResolverOutputs {
1458
1465
definitions : self . definitions . clone ( ) ,
1466
+ access_levels : self . nodes_access_level . clone ( ) ,
1459
1467
cstore : Box :: new ( self . cstore ( ) . clone ( ) ) ,
1460
1468
visibilities : self . visibilities . clone ( ) ,
1461
1469
extern_crate_map : self . extern_crate_map . clone ( ) ,
@@ -1512,6 +1520,7 @@ impl<'a> Resolver<'a> {
1512
1520
pub fn resolve_crate ( & mut self , krate : & Crate ) {
1513
1521
self . session . time ( "resolve_crate" , || {
1514
1522
self . session . time ( "finalize_imports" , || ImportResolver { r : self } . finalize_imports ( ) ) ;
1523
+ self . session . time ( "resolve_export_privacy" , || self . resolve_export_privacy ( ) ) ;
1515
1524
self . session . time ( "finalize_macro_resolutions" , || self . finalize_macro_resolutions ( ) ) ;
1516
1525
self . session . time ( "late_resolve_crate" , || self . late_resolve_crate ( krate) ) ;
1517
1526
self . session . time ( "resolve_main" , || self . resolve_main ( ) ) ;
@@ -1521,6 +1530,58 @@ impl<'a> Resolver<'a> {
1521
1530
} ) ;
1522
1531
}
1523
1532
1533
+ /// Compute access levels for exports and intermediate use statements
1534
+ fn resolve_export_privacy ( & mut self ) {
1535
+ let root = self . graph_root ( ) ;
1536
+ let exports = root. def_id ( ) . and_then ( |id| self . export_map . get ( & id. expect_local ( ) ) ) ;
1537
+
1538
+ if let Some ( exports) = exports. cloned ( ) {
1539
+ let public_exports =
1540
+ exports. iter ( ) . filter ( |ex| ex. vis == Visibility :: Public ) . collect :: < Vec < _ > > ( ) ;
1541
+
1542
+ for export in public_exports {
1543
+ if let Some ( ns) = export. res . ns ( ) {
1544
+ let key = self . new_key ( export. ident , ns) ;
1545
+ let name_res = self . resolution ( root, key) ;
1546
+ if let Some ( binding) = name_res. borrow ( ) . binding ( ) {
1547
+ self . compute_binding_access_level ( binding) ;
1548
+ }
1549
+ }
1550
+ }
1551
+ }
1552
+
1553
+ tracing:: debug!( "nodes_access_level: {:?}" , self . nodes_access_level) ;
1554
+ }
1555
+
1556
+ /// Set the given binding access level to `AccessLevel::Public` and
1557
+ /// sets the rest of the `use` chain to `AccessLevel::Exported` until
1558
+ /// we hit the actual exported item
1559
+ fn compute_binding_access_level ( & mut self , mut binding : & NameBinding < ' a > ) {
1560
+ let mut access_level = AccessLevel :: Public ;
1561
+ while let NameBindingKind :: Import { binding : nested_binding, import, .. } = binding. kind {
1562
+ self . mark_node_with_access_level ( import. id , access_level) ;
1563
+
1564
+ match import. kind {
1565
+ ImportKind :: Single { additional_ids, .. } => {
1566
+ self . mark_node_with_access_level ( additional_ids. 0 , access_level) ;
1567
+ self . mark_node_with_access_level ( additional_ids. 1 , access_level) ;
1568
+ }
1569
+ _ => { }
1570
+ } ;
1571
+
1572
+ access_level = AccessLevel :: Exported ;
1573
+ binding = nested_binding;
1574
+ }
1575
+ }
1576
+
1577
+ fn mark_node_with_access_level ( & mut self , node_id : NodeId , access_level : AccessLevel ) -> bool {
1578
+ if let Some ( def_id) = self . opt_local_def_id ( node_id) {
1579
+ self . nodes_access_level . insert ( def_id, access_level) . is_none ( )
1580
+ } else {
1581
+ false
1582
+ }
1583
+ }
1584
+
1524
1585
pub fn traits_in_scope (
1525
1586
& mut self ,
1526
1587
current_trait : Option < Module < ' a > > ,
0 commit comments