Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
c1ad5af4
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c1ad5af4
编写于
11月 19, 2015
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Changes to data produced by privacy pass
上级
3e48b0e3
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
205 addition
and
274 deletion
+205
-274
src/librustc/lint/context.rs
src/librustc/lint/context.rs
+7
-8
src/librustc/middle/dead.rs
src/librustc/middle/dead.rs
+6
-27
src/librustc/middle/privacy.rs
src/librustc/middle/privacy.rs
+42
-8
src/librustc/middle/reachable.rs
src/librustc/middle/reachable.rs
+5
-5
src/librustc/middle/stability.rs
src/librustc/middle/stability.rs
+5
-5
src/librustc/middle/ty/mod.rs
src/librustc/middle/ty/mod.rs
+1
-3
src/librustc_driver/driver.rs
src/librustc_driver/driver.rs
+6
-9
src/librustc_lint/builtin.rs
src/librustc_lint/builtin.rs
+6
-6
src/librustc_privacy/lib.rs
src/librustc_privacy/lib.rs
+103
-172
src/librustdoc/core.rs
src/librustdoc/core.rs
+9
-14
src/librustdoc/html/render.rs
src/librustdoc/html/render.rs
+6
-6
src/librustdoc/passes.rs
src/librustdoc/passes.rs
+8
-10
src/librustdoc/visit_ast.rs
src/librustdoc/visit_ast.rs
+1
-1
未找到文件。
src/librustc/lint/context.rs
浏览文件 @
c1ad5af4
...
...
@@ -25,7 +25,7 @@
//! for all lint attributes.
use
self
::
TargetLint
::
*
;
use
middle
::
privacy
::
ExportedItem
s
;
use
middle
::
privacy
::
AccessLevel
s
;
use
middle
::
ty
::{
self
,
Ty
};
use
session
::{
early_error
,
Session
};
use
lint
::{
Level
,
LevelSource
,
Lint
,
LintId
,
LintArray
,
LintPass
};
...
...
@@ -277,8 +277,8 @@ pub struct LateContext<'a, 'tcx: 'a> {
/// The crate being checked.
pub
krate
:
&
'a
hir
::
Crate
,
/// Items
exported
from the crate being checked.
pub
exported_items
:
&
'a
ExportedItem
s
,
/// Items
accessible
from the crate being checked.
pub
access_levels
:
&
'a
AccessLevel
s
,
/// The store of registered lints.
lints
:
LintStore
,
...
...
@@ -564,7 +564,7 @@ fn visit_ids<F>(&mut self, f: F)
impl
<
'a
,
'tcx
>
LateContext
<
'a
,
'tcx
>
{
fn
new
(
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
krate
:
&
'a
hir
::
Crate
,
exported_items
:
&
'a
ExportedItem
s
)
->
LateContext
<
'a
,
'tcx
>
{
access_levels
:
&
'a
AccessLevel
s
)
->
LateContext
<
'a
,
'tcx
>
{
// We want to own the lint store, so move it out of the session.
let
lint_store
=
mem
::
replace
(
&
mut
*
tcx
.sess.lint_store
.borrow_mut
(),
LintStore
::
new
());
...
...
@@ -572,7 +572,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
LateContext
{
tcx
:
tcx
,
krate
:
krate
,
exported_items
:
exported_item
s
,
access_levels
:
access_level
s
,
lints
:
lint_store
,
level_stack
:
vec!
[],
node_levels
:
RefCell
::
new
(
FnvHashMap
()),
...
...
@@ -1014,10 +1014,9 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
/// Perform lint checking on a crate.
///
/// Consumes the `lint_store` field of the `Session`.
pub
fn
check_crate
(
tcx
:
&
ty
::
ctxt
,
exported_items
:
&
ExportedItems
)
{
pub
fn
check_crate
(
tcx
:
&
ty
::
ctxt
,
access_levels
:
&
AccessLevels
)
{
let
krate
=
tcx
.map
.krate
();
let
mut
cx
=
LateContext
::
new
(
tcx
,
krate
,
exported_item
s
);
let
mut
cx
=
LateContext
::
new
(
tcx
,
krate
,
access_level
s
);
// Visit the whole crate.
cx
.with_lint_attrs
(
&
krate
.attrs
,
|
cx
|
{
...
...
src/librustc/middle/dead.rs
浏览文件 @
c1ad5af4
...
...
@@ -19,7 +19,6 @@
use
middle
::{
def
,
pat_util
,
privacy
,
ty
};
use
middle
::
def_id
::{
DefId
};
use
lint
;
use
util
::
nodemap
::
NodeSet
;
use
std
::
collections
::
HashSet
;
use
syntax
::{
ast
,
codemap
};
...
...
@@ -370,25 +369,10 @@ fn visit_item(&mut self, item: &hir::Item) {
}
fn
create_and_seed_worklist
(
tcx
:
&
ty
::
ctxt
,
exported_items
:
&
privacy
::
ExportedItems
,
reachable_symbols
:
&
NodeSet
,
access_levels
:
&
privacy
::
AccessLevels
,
krate
:
&
hir
::
Crate
)
->
Vec
<
ast
::
NodeId
>
{
let
mut
worklist
=
Vec
::
new
();
// Preferably, we would only need to seed the worklist with reachable
// symbols. However, since the set of reachable symbols differs
// depending on whether a crate is built as bin or lib, and we want
// the warning to be consistent, we also seed the worklist with
// exported symbols.
for
id
in
exported_items
{
worklist
.push
(
*
id
);
}
for
id
in
reachable_symbols
{
// Reachable variants can be dead, because we warn about
// variants never constructed, not variants never used.
if
let
Some
(
ast_map
::
NodeVariant
(
..
))
=
tcx
.map
.find
(
*
id
)
{
continue
;
}
for
(
id
,
_
)
in
&
access_levels
.map
{
worklist
.push
(
*
id
);
}
...
...
@@ -408,12 +392,10 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
}
fn
find_live
(
tcx
:
&
ty
::
ctxt
,
exported_items
:
&
privacy
::
ExportedItems
,
reachable_symbols
:
&
NodeSet
,
access_levels
:
&
privacy
::
AccessLevels
,
krate
:
&
hir
::
Crate
)
->
Box
<
HashSet
<
ast
::
NodeId
>>
{
let
worklist
=
create_and_seed_worklist
(
tcx
,
exported_items
,
reachable_symbols
,
krate
);
let
worklist
=
create_and_seed_worklist
(
tcx
,
access_levels
,
krate
);
let
mut
symbol_visitor
=
MarkSymbolVisitor
::
new
(
tcx
,
worklist
);
symbol_visitor
.mark_live_symbols
();
symbol_visitor
.live_symbols
...
...
@@ -607,12 +589,9 @@ fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
}
}
pub
fn
check_crate
(
tcx
:
&
ty
::
ctxt
,
exported_items
:
&
privacy
::
ExportedItems
,
reachable_symbols
:
&
NodeSet
)
{
pub
fn
check_crate
(
tcx
:
&
ty
::
ctxt
,
access_levels
:
&
privacy
::
AccessLevels
)
{
let
krate
=
tcx
.map
.krate
();
let
live_symbols
=
find_live
(
tcx
,
exported_items
,
reachable_symbols
,
krate
);
let
live_symbols
=
find_live
(
tcx
,
access_levels
,
krate
);
let
mut
visitor
=
DeadVisitor
{
tcx
:
tcx
,
live_symbols
:
live_symbols
};
intravisit
::
walk_crate
(
&
mut
visitor
,
krate
);
}
src/librustc/middle/privacy.rs
浏览文件 @
c1ad5af4
...
...
@@ -17,20 +17,54 @@
pub
use
self
::
LastPrivate
::
*
;
use
middle
::
def_id
::
DefId
;
use
util
::
nodemap
::{
DefIdSet
,
NodeSet
};
use
util
::
nodemap
::{
DefIdSet
,
FnvHashMap
};
/// A set of AST nodes exported by the crate.
pub
type
ExportedItems
=
NodeSet
;
use
std
::
hash
::
Hash
;
use
syntax
::
ast
::
NodeId
;
// Accessibility levels, sorted in ascending order
#[derive(Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord)]
pub
enum
AccessLevel
{
// Exported items + items participating in various kinds of public interfaces,
// but not directly nameable. For example, if function `fn f() -> T {...}` is
// public, then type `T` is exported. Its values can be obtained by other crates
// even if the type itseld is not nameable.
// FIXME: Mostly unimplemented. Only `type` aliases export items currently.
Reachable
,
// Public items + items accessible to other crates with help of `pub use` reexports
Exported
,
// Items accessible to other crates directly, without help of reexports
Public
,
}
// Accessibility levels for reachable HIR nodes
#[derive(Clone)]
pub
struct
AccessLevels
<
Id
=
NodeId
>
{
pub
map
:
FnvHashMap
<
Id
,
AccessLevel
>
}
impl
<
Id
:
Hash
+
Eq
>
AccessLevels
<
Id
>
{
pub
fn
is_reachable
(
&
self
,
id
:
Id
)
->
bool
{
self
.map
.contains_key
(
&
id
)
}
pub
fn
is_exported
(
&
self
,
id
:
Id
)
->
bool
{
self
.map
.get
(
&
id
)
>=
Some
(
&
AccessLevel
::
Exported
)
}
pub
fn
is_public
(
&
self
,
id
:
Id
)
->
bool
{
self
.map
.get
(
&
id
)
>=
Some
(
&
AccessLevel
::
Public
)
}
}
impl
<
Id
:
Hash
+
Eq
>
Default
for
AccessLevels
<
Id
>
{
fn
default
()
->
Self
{
AccessLevels
{
map
:
Default
::
default
()
}
}
}
/// A set containing all exported definitions from external crates.
/// The set does not contain any entries from local crates.
pub
type
ExternalExports
=
DefIdSet
;
/// A set of AST nodes that are fully public in the crate. This map is used for
/// documentation purposes (reexporting a private struct inlines the doc,
/// reexporting a public struct doesn't inline the doc).
pub
type
PublicItems
=
NodeSet
;
#[derive(Copy,
Clone,
Debug)]
pub
enum
LastPrivate
{
LastMod
(
PrivateDep
),
...
...
src/librustc/middle/reachable.rs
浏览文件 @
c1ad5af4
...
...
@@ -329,7 +329,7 @@ fn propagate_node(&mut self, node: &ast_map::Node,
// trait items are used from inlinable code through method call syntax or UFCS, or their
// trait is a lang item.
struct
CollectPrivateImplItemsVisitor
<
'a
>
{
exported_items
:
&
'a
privacy
::
ExportedItem
s
,
access_levels
:
&
'a
privacy
::
AccessLevel
s
,
worklist
:
&
'a
mut
Vec
<
ast
::
NodeId
>
,
}
...
...
@@ -337,7 +337,7 @@ impl<'a, 'v> Visitor<'v> for CollectPrivateImplItemsVisitor<'a> {
fn
visit_item
(
&
mut
self
,
item
:
&
hir
::
Item
)
{
// We need only trait impls here, not inherent impls, and only non-exported ones
if
let
hir
::
ItemImpl
(
_
,
_
,
_
,
Some
(
_
),
_
,
ref
impl_items
)
=
item
.node
{
if
!
self
.
exported_items
.contains
(
&
item
.id
)
{
if
!
self
.
access_levels
.is_reachable
(
item
.id
)
{
for
impl_item
in
impl_items
{
self
.worklist
.push
(
impl_item
.id
);
}
...
...
@@ -347,7 +347,7 @@ fn visit_item(&mut self, item: &hir::Item) {
}
pub
fn
find_reachable
(
tcx
:
&
ty
::
ctxt
,
exported_items
:
&
privacy
::
ExportedItem
s
)
access_levels
:
&
privacy
::
AccessLevel
s
)
->
NodeSet
{
let
mut
reachable_context
=
ReachableContext
::
new
(
tcx
);
...
...
@@ -357,7 +357,7 @@ pub fn find_reachable(tcx: &ty::ctxt,
// If other crates link to us, they're going to expect to be able to
// use the lang items, so we need to be sure to mark them as
// exported.
for
id
in
exported_items
{
for
(
id
,
_
)
in
&
access_levels
.map
{
reachable_context
.worklist
.push
(
*
id
);
}
for
(
_
,
item
)
in
tcx
.lang_items
.items
()
{
...
...
@@ -369,7 +369,7 @@ pub fn find_reachable(tcx: &ty::ctxt,
}
{
let
mut
collect_private_impl_items
=
CollectPrivateImplItemsVisitor
{
exported_items
:
exported_item
s
,
access_levels
:
access_level
s
,
worklist
:
&
mut
reachable_context
.worklist
,
};
tcx
.map
.krate
()
.visit_all_items
(
&
mut
collect_private_impl_items
);
...
...
src/librustc/middle/stability.rs
浏览文件 @
c1ad5af4
...
...
@@ -19,7 +19,7 @@
use
middle
::
def
;
use
middle
::
def_id
::{
CRATE_DEF_INDEX
,
DefId
};
use
middle
::
ty
;
use
middle
::
privacy
::
PublicItem
s
;
use
middle
::
privacy
::
AccessLevel
s
;
use
metadata
::
csearch
;
use
syntax
::
parse
::
token
::
InternedString
;
use
syntax
::
codemap
::{
Span
,
DUMMY_SP
};
...
...
@@ -73,7 +73,7 @@ struct Annotator<'a, 'tcx: 'a> {
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
index
:
&
'a
mut
Index
<
'tcx
>
,
parent
:
Option
<&
'tcx
Stability
>
,
export_map
:
&
'a
PublicItem
s
,
access_levels
:
&
'a
AccessLevel
s
,
in_trait_impl
:
bool
,
in_enum
:
bool
,
}
...
...
@@ -143,7 +143,7 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>,
}
else
{
debug!
(
"annotate: not found, parent = {:?}"
,
self
.parent
);
let
mut
is_error
=
kind
==
AnnotationKind
::
Required
&&
self
.
export_map
.contains
(
&
id
)
&&
self
.
access_levels
.is_reachable
(
id
)
&&
!
self
.tcx.sess.opts.test
;
if
let
Some
(
stab
)
=
self
.parent
{
if
stab
.level
.is_unstable
()
{
...
...
@@ -266,12 +266,12 @@ fn visit_macro_def(&mut self, md: &'v hir::MacroDef) {
impl
<
'tcx
>
Index
<
'tcx
>
{
/// Construct the stability index for a crate being compiled.
pub
fn
build
(
&
mut
self
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
krate
:
&
'tcx
Crate
,
export_map
:
&
PublicItem
s
)
{
pub
fn
build
(
&
mut
self
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
krate
:
&
Crate
,
access_levels
:
&
AccessLevel
s
)
{
let
mut
annotator
=
Annotator
{
tcx
:
tcx
,
index
:
self
,
parent
:
None
,
export_map
:
export_map
,
access_levels
:
access_levels
,
in_trait_impl
:
false
,
in_enum
:
false
,
};
...
...
src/librustc/middle/ty/mod.rs
浏览文件 @
c1ad5af4
...
...
@@ -104,14 +104,12 @@
/// produced by the driver and fed to trans and later passes.
pub
struct
CrateAnalysis
<
'a
>
{
pub
export_map
:
ExportMap
,
pub
exported_items
:
middle
::
privacy
::
ExportedItems
,
pub
public_items
:
middle
::
privacy
::
PublicItems
,
pub
access_levels
:
middle
::
privacy
::
AccessLevels
,
pub
reachable
:
NodeSet
,
pub
name
:
&
'a
str
,
pub
glob_map
:
Option
<
GlobMap
>
,
}
#[derive(Copy,
Clone)]
pub
enum
DtorKind
{
NoDtor
,
...
...
src/librustc_driver/driver.rs
浏览文件 @
c1ad5af4
...
...
@@ -746,7 +746,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"const checking"
,
||
middle
::
check_const
::
check_crate
(
tcx
));
let
(
exported_items
,
public_items
)
=
let
access_levels
=
time
(
time_passes
,
"privacy checking"
,
||
{
rustc_privacy
::
check_crate
(
tcx
,
&
export_map
,
...
...
@@ -755,7 +755,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// Do not move this check past lint
time
(
time_passes
,
"stability index"
,
||
{
tcx
.stability
.borrow_mut
()
.build
(
tcx
,
krate
,
&
exported_item
s
)
tcx
.stability
.borrow_mut
()
.build
(
tcx
,
krate
,
&
access_level
s
)
});
time
(
time_passes
,
...
...
@@ -807,12 +807,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
let
reachable_map
=
time
(
time_passes
,
"reachability checking"
,
||
reachable
::
find_reachable
(
tcx
,
&
exported_item
s
));
||
reachable
::
find_reachable
(
tcx
,
&
access_level
s
));
time
(
time_passes
,
"death checking"
,
||
{
middle
::
dead
::
check_crate
(
tcx
,
&
exported_items
,
&
reachable_map
)
middle
::
dead
::
check_crate
(
tcx
,
&
access_levels
);
});
let
ref
lib_features_used
=
...
...
@@ -827,7 +825,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
time
(
time_passes
,
"lint checking"
,
||
lint
::
check_crate
(
tcx
,
&
exported_item
s
));
||
lint
::
check_crate
(
tcx
,
&
access_level
s
));
// The above three passes generate errors w/o aborting
tcx
.sess
.abort_if_errors
();
...
...
@@ -836,8 +834,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
mir_map
,
ty
::
CrateAnalysis
{
export_map
:
export_map
,
exported_items
:
exported_items
,
public_items
:
public_items
,
access_levels
:
access_levels
,
reachable
:
reachable_map
,
name
:
name
,
glob_map
:
glob_map
,
...
...
src/librustc_lint/builtin.rs
浏览文件 @
c1ad5af4
...
...
@@ -301,8 +301,8 @@ fn check_missing_docs_attrs(&self,
// Only check publicly-visible items, using the result from the privacy pass.
// It's an option so the crate root can also use this function (it doesn't
// have a NodeId).
if
let
Some
(
ref
id
)
=
id
{
if
!
cx
.
exported_items
.contains
(
id
)
{
if
let
Some
(
id
)
=
id
{
if
!
cx
.
access_levels
.is_exported
(
id
)
{
return
;
}
}
...
...
@@ -470,7 +470,7 @@ fn get_lints(&self) -> LintArray {
impl
LateLintPass
for
MissingCopyImplementations
{
fn
check_item
(
&
mut
self
,
cx
:
&
LateContext
,
item
:
&
hir
::
Item
)
{
if
!
cx
.
exported_items
.contains
(
&
item
.id
)
{
if
!
cx
.
access_levels
.is_reachable
(
item
.id
)
{
return
;
}
let
(
def
,
ty
)
=
match
item
.node
{
...
...
@@ -534,7 +534,7 @@ fn get_lints(&self) -> LintArray {
impl
LateLintPass
for
MissingDebugImplementations
{
fn
check_item
(
&
mut
self
,
cx
:
&
LateContext
,
item
:
&
hir
::
Item
)
{
if
!
cx
.
exported_items
.contains
(
&
item
.id
)
{
if
!
cx
.
access_levels
.is_reachable
(
item
.id
)
{
return
;
}
...
...
@@ -987,7 +987,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
match
it
.node
{
hir
::
ItemFn
(
..
)
=>
{
if
attr
::
contains_name
(
&
it
.attrs
,
"no_mangle"
)
&&
!
cx
.
exported_items
.contains
(
&
it
.id
)
{
!
cx
.
access_levels
.is_reachable
(
it
.id
)
{
let
msg
=
format!
(
"function {} is marked #[no_mangle], but not exported"
,
it
.name
);
cx
.span_lint
(
PRIVATE_NO_MANGLE_FNS
,
it
.span
,
&
msg
);
...
...
@@ -995,7 +995,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
},
hir
::
ItemStatic
(
..
)
=>
{
if
attr
::
contains_name
(
&
it
.attrs
,
"no_mangle"
)
&&
!
cx
.
exported_items
.contains
(
&
it
.id
)
{
!
cx
.
access_levels
.is_reachable
(
it
.id
)
{
let
msg
=
format!
(
"static {} is marked #[no_mangle], but not exported"
,
it
.name
);
cx
.span_lint
(
PRIVATE_NO_MANGLE_STATICS
,
it
.span
,
&
msg
);
...
...
src/librustc_privacy/lib.rs
浏览文件 @
c1ad5af4
...
...
@@ -32,6 +32,7 @@
use
self
::
PrivacyResult
::
*
;
use
self
::
FieldName
::
*
;
use
std
::
cmp
;
use
std
::
mem
::
replace
;
use
rustc_front
::
hir
;
...
...
@@ -39,12 +40,13 @@
use
rustc
::
middle
::
def
;
use
rustc
::
middle
::
def_id
::
DefId
;
use
rustc
::
middle
::
privacy
::{
AccessLevel
,
AccessLevels
};
use
rustc
::
middle
::
privacy
::
ImportUse
::
*
;
use
rustc
::
middle
::
privacy
::
LastPrivate
::
*
;
use
rustc
::
middle
::
privacy
::
PrivateDep
::
*
;
use
rustc
::
middle
::
privacy
::
{
ExternalExports
,
ExportedItems
,
PublicItems
}
;
use
rustc
::
middle
::
privacy
::
ExternalExports
;
use
rustc
::
middle
::
ty
::{
self
,
Ty
};
use
rustc
::
util
::
nodemap
::
{
NodeMap
,
NodeSet
}
;
use
rustc
::
util
::
nodemap
::
NodeMap
;
use
rustc
::
front
::
map
as
ast_map
;
use
syntax
::
ast
;
...
...
@@ -159,64 +161,57 @@ struct EmbargoVisitor<'a, 'tcx: 'a> {
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
export_map
:
&
'a
def
::
ExportMap
,
// This flag is an indicator of whether the previous item in the
// hierarchical chain was exported or not. This is the indicator of whether
// children should be exported as well. Note that this can flip from false
// to true if a reexported module is entered (or an action similar).
prev_exported
:
bool
,
// This is a list of all exported items in the AST. An exported item is any
// function/method/item which is usable by external crates. This essentially
// means that the result is "public all the way down", but the "path down"
// may jump across private boundaries through reexport statements or type aliases.
exported_items
:
ExportedItems
,
// Items that are directly public without help of reexports or type aliases.
// These two fields are closely related to one another in that they are only
// used for generation of the `public_items` set, not for privacy checking at
// all. Invariant: at any moment public items are a subset of exported items.
public_items
:
PublicItems
,
prev_public
:
bool
,
// Accessibility levels for reachable nodes
access_levels
:
AccessLevels
,
// Previous accessibility level, None means unreachable
prev_level
:
Option
<
AccessLevel
>
,
// Have something changed in the level map?
changed
:
bool
,
}
impl
<
'a
,
'tcx
>
EmbargoVisitor
<
'a
,
'tcx
>
{
// Returns tuple (is_public, is_exported) for a type
fn
is_public_exported_ty
(
&
self
,
ty
:
&
hir
::
Ty
)
->
(
bool
,
bool
)
{
fn
ty_level
(
&
self
,
ty
:
&
hir
::
Ty
)
->
Option
<
AccessLevel
>
{
if
let
hir
::
TyPath
(
..
)
=
ty
.node
{
match
self
.tcx.def_map
.borrow
()
.get
(
&
ty
.id
)
.unwrap
()
.full_def
()
{
def
::
DefPrimTy
(
..
)
|
def
::
DefSelfTy
(
..
)
|
def
::
DefTyParam
(
..
)
=>
{
(
true
,
true
)
Some
(
AccessLevel
::
Public
)
}
def
=>
{
if
let
Some
(
node_id
)
=
self
.tcx.map
.as_local_node_id
(
def
.def_id
())
{
(
self
.public_items
.contains
(
&
node_id
),
self
.exported_items
.contains
(
&
node_id
))
self
.get
(
node_id
)
}
else
{
(
true
,
true
)
Some
(
AccessLevel
::
Public
)
}
}
}
}
else
{
(
true
,
true
)
Some
(
AccessLevel
::
Public
)
}
}
// Returns tuple (is_public, is_exported) for a trait
fn
is_public_exported_trait
(
&
self
,
trait_ref
:
&
hir
::
TraitRef
)
->
(
bool
,
bool
)
{
fn
trait_level
(
&
self
,
trait_ref
:
&
hir
::
TraitRef
)
->
Option
<
AccessLevel
>
{
let
did
=
self
.tcx
.trait_ref_to_def_id
(
trait_ref
);
if
let
Some
(
node_id
)
=
self
.tcx.map
.as_local_node_id
(
did
)
{
(
self
.public_items
.contains
(
&
node_id
),
self
.exported_items
.contains
(
&
node_id
)
)
self
.get
(
node_id
)
}
else
{
(
true
,
true
)
Some
(
AccessLevel
::
Public
)
}
}
fn
maybe_insert_id
(
&
mut
self
,
id
:
ast
::
NodeId
)
{
if
self
.prev_public
{
self
.public_items
.insert
(
id
);
}
if
self
.prev_exported
{
self
.exported_items
.insert
(
id
);
fn
get
(
&
self
,
id
:
ast
::
NodeId
)
->
Option
<
AccessLevel
>
{
self
.access_levels.map
.get
(
&
id
)
.cloned
()
}
// Updates node level and returns the updated level
fn
update
(
&
mut
self
,
id
:
ast
::
NodeId
,
level
:
Option
<
AccessLevel
>
)
->
Option
<
AccessLevel
>
{
let
old_level
=
self
.get
(
id
);
// Accessibility levels can only grow
if
level
>
old_level
{
self
.access_levels.map
.insert
(
id
,
level
.unwrap
());
self
.changed
=
true
;
level
}
else
{
old_level
}
}
}
...
...
@@ -227,187 +222,126 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
fn
visit_nested_item
(
&
mut
self
,
item
:
hir
::
ItemId
)
{
self
.visit_item
(
self
.tcx.map
.expect_item
(
item
.id
))
}
fn
visit_item
(
&
mut
self
,
item
:
&
hir
::
Item
)
{
let
orig_all_public
=
self
.prev_public
;
let
orig_all_exported
=
self
.prev_exported
;
match
item
.node
{
// impls/extern blocks do not break the "public chain" because they
// cannot have visibility qualifiers on them anyway. Impls are also not
// added to public/exported sets based on inherited publicity.
hir
::
ItemImpl
(
..
)
|
hir
::
ItemDefaultImpl
(
..
)
=>
{}
let
inherited_item_level
=
match
item
.node
{
// Impls inherit level from their types and traits
hir
::
ItemImpl
(
_
,
_
,
_
,
None
,
ref
ty
,
_
)
=>
{
self
.ty_level
(
&
ty
)
}
hir
::
ItemImpl
(
_
,
_
,
_
,
Some
(
ref
trait_ref
),
ref
ty
,
_
)
=>
{
cmp
::
min
(
self
.ty_level
(
&
ty
),
self
.trait_level
(
trait_ref
))
}
hir
::
ItemDefaultImpl
(
_
,
ref
trait_ref
)
=>
{
self
.trait_level
(
trait_ref
)
}
// Foreign mods inherit level from parents
hir
::
ItemForeignMod
(
..
)
=>
{
self
.
maybe_insert_id
(
item
.id
);
self
.
prev_level
}
// Private by default, hence we only retain the "public chain" if
// `pub` is explicitly listed.
// Other `pub` items inherit levels from parents
_
=>
{
self
.prev_public
=
self
.prev_public
&&
item
.vis
==
hir
::
Public
;
self
.prev_exported
=
(
self
.prev_exported
&&
item
.vis
==
hir
::
Public
)
||
self
.exported_items
.contains
(
&
item
.id
);
self
.maybe_insert_id
(
item
.id
);
if
item
.vis
==
hir
::
Public
{
self
.prev_level
}
else
{
None
}
}
}
}
;
// Update id of the item itself
let
item_level
=
self
.update
(
item
.id
,
inherited_item_level
);
// Update ids of nested things
match
item
.node
{
// Enum variants inherit from their parent, so if the enum is
// public all variants are public
hir
::
ItemEnum
(
ref
def
,
_
)
=>
{
for
variant
in
&
def
.variants
{
self
.maybe_insert_id
(
variant
.node.data
.id
()
);
let
variant_level
=
self
.update
(
variant
.node.data
.id
(),
item_level
);
for
field
in
variant
.node.data
.fields
()
{
// Variant fields are always public
self
.maybe_insert_id
(
field
.node.id
);
self
.update
(
field
.node.id
,
variant_level
);
}
}
}
// Inherent impls for public/exported types and their public items are public/exported
hir
::
ItemImpl
(
_
,
_
,
_
,
None
,
ref
ty
,
ref
impl_items
)
=>
{
let
(
public_ty
,
exported_ty
)
=
self
.is_public_exported_ty
(
&
ty
);
if
public_ty
{
self
.public_items
.insert
(
item
.id
);
}
if
exported_ty
{
self
.exported_items
.insert
(
item
.id
);
}
hir
::
ItemImpl
(
_
,
_
,
_
,
None
,
_
,
ref
impl_items
)
=>
{
for
impl_item
in
impl_items
{
if
impl_item
.vis
==
hir
::
Public
{
if
public_ty
{
self
.public_items
.insert
(
impl_item
.id
);
}
if
exported_ty
{
self
.exported_items
.insert
(
impl_item
.id
);
}
self
.update
(
impl_item
.id
,
item_level
);
}
}
}
// Trait impl and its items are public/exported if both the self type and the trait
// of this impl are public/exported
hir
::
ItemImpl
(
_
,
_
,
_
,
Some
(
ref
trait_ref
),
ref
ty
,
ref
impl_items
)
=>
{
let
(
public_ty
,
exported_ty
)
=
self
.is_public_exported_ty
(
&
ty
);
let
(
public_trait
,
exported_trait
)
=
self
.is_public_exported_trait
(
trait_ref
);
if
public_ty
&&
public_trait
{
self
.public_items
.insert
(
item
.id
);
}
if
exported_ty
&&
exported_trait
{
self
.exported_items
.insert
(
item
.id
);
}
hir
::
ItemImpl
(
_
,
_
,
_
,
Some
(
_
),
_
,
ref
impl_items
)
=>
{
for
impl_item
in
impl_items
{
if
public_ty
&&
public_trait
{
self
.public_items
.insert
(
impl_item
.id
);
}
if
exported_ty
&&
exported_trait
{
self
.exported_items
.insert
(
impl_item
.id
);
}
}
}
// Default trait impls are public/exported for public/exported traits
hir
::
ItemDefaultImpl
(
_
,
ref
trait_ref
)
=>
{
let
(
public_trait
,
exported_trait
)
=
self
.is_public_exported_trait
(
trait_ref
);
if
public_trait
{
self
.public_items
.insert
(
item
.id
);
}
if
exported_trait
{
self
.exported_items
.insert
(
item
.id
);
self
.update
(
impl_item
.id
,
item_level
);
}
}
// Default methods on traits are all public/exported so long as the trait
// is public/exported
hir
::
ItemTrait
(
_
,
_
,
_
,
ref
trait_items
)
=>
{
for
trait_item
in
trait_items
{
self
.
maybe_insert_id
(
trait_item
.id
);
self
.
update
(
trait_item
.id
,
item_level
);
}
}
// Struct constructors are public if the struct is all public.
hir
::
ItemStruct
(
ref
def
,
_
)
=>
{
if
!
def
.is_struct
()
{
self
.
maybe_insert_id
(
def
.id
()
);
self
.
update
(
def
.id
(),
item_level
);
}
for
field
in
def
.fields
()
{
// Struct fields can be public or private, so lets check
if
field
.node.kind
.visibility
()
==
hir
::
Public
{
self
.
maybe_insert_id
(
field
.node.id
);
self
.
update
(
field
.node.id
,
item_level
);
}
}
}
hir
::
ItemTy
(
ref
ty
,
_
)
if
self
.prev_exported
=>
{
hir
::
ItemForeignMod
(
ref
foreign_mod
)
=>
{
for
foreign_item
in
&
foreign_mod
.items
{
if
foreign_item
.vis
==
hir
::
Public
{
self
.update
(
foreign_item
.id
,
item_level
);
}
}
}
hir
::
ItemTy
(
ref
ty
,
_
)
if
item_level
.is_some
()
=>
{
if
let
hir
::
TyPath
(
..
)
=
ty
.node
{
match
self
.tcx.def_map
.borrow
()
.get
(
&
ty
.id
)
.unwrap
()
.full_def
()
{
def
::
DefPrimTy
(
..
)
|
def
::
DefSelfTy
(
..
)
|
def
::
DefTyParam
(
..
)
=>
{},
def
=>
{
if
let
Some
(
node_id
)
=
self
.tcx.map
.as_local_node_id
(
def
.def_id
())
{
self
.
exported_items
.insert
(
node_id
);
self
.
update
(
node_id
,
Some
(
AccessLevel
::
Reachable
)
);
}
}
}
}
}
hir
::
ItemForeignMod
(
ref
foreign_mod
)
=>
{
for
foreign_item
in
&
foreign_mod
.items
{
let
public
=
self
.prev_public
&&
foreign_item
.vis
==
hir
::
Public
;
let
exported
=
(
self
.prev_exported
&&
foreign_item
.vis
==
hir
::
Public
)
||
self
.exported_items
.contains
(
&
foreign_item
.id
);
if
public
{
self
.public_items
.insert
(
foreign_item
.id
);
}
if
exported
{
self
.exported_items
.insert
(
foreign_item
.id
);
}
}
}
_
=>
{}
}
let
orig_level
=
self
.prev_level
;
self
.prev_level
=
item_level
;
intravisit
::
walk_item
(
self
,
item
);
self
.prev_public
=
orig_all_public
;
self
.prev_exported
=
orig_all_exported
;
self
.prev_level
=
orig_level
;
}
fn
visit_block
(
&
mut
self
,
b
:
&
'v
hir
::
Block
)
{
let
orig_all_public
=
replace
(
&
mut
self
.prev_public
,
false
);
let
orig_all_exported
=
replace
(
&
mut
self
.prev_exported
,
false
);
let
orig_level
=
replace
(
&
mut
self
.prev_level
,
None
);
// Blocks can have
exported and
public items, for example impls, but they always
// start as
non-public and non-exported
regardless of publicity of a function,
// Blocks can have public items, for example impls, but they always
// start as
completely private
regardless of publicity of a function,
// constant, type, field, etc. in which this block resides
intravisit
::
walk_block
(
self
,
b
);
self
.prev_public
=
orig_all_public
;
self
.prev_exported
=
orig_all_exported
;
self
.prev_level
=
orig_level
;
}
fn
visit_mod
(
&
mut
self
,
m
:
&
hir
::
Mod
,
_
sp
:
Span
,
id
:
ast
::
NodeId
)
{
// This code is here instead of in visit_item so that the
// crate module gets processed as well.
if
self
.prev_exported
{
assert
!
(
self
.export_map
.contains_key
(
&
id
),
"wut {}"
,
id
);
for
export
in
self
.export_map
.get
(
&
id
)
.unwrap
()
{
if
self
.prev_level
.is_some
()
{
for
export
in
self
.export_map
.get
(
&
id
)
.expect
(
"module isn't found in export map"
)
{
if
let
Some
(
node_id
)
=
self
.tcx.map
.as_local_node_id
(
export
.def_id
)
{
self
.
exported_items
.insert
(
node_id
);
self
.
update
(
node_id
,
Some
(
AccessLevel
::
Exported
)
);
}
}
}
intravisit
::
walk_mod
(
self
,
m
)
intravisit
::
walk_mod
(
self
,
m
);
}
fn
visit_macro_def
(
&
mut
self
,
md
:
&
'v
hir
::
MacroDef
)
{
self
.
maybe_insert_id
(
md
.id
);
self
.
update
(
md
.id
,
Some
(
AccessLevel
::
Public
)
);
}
}
...
...
@@ -1169,8 +1103,7 @@ fn check_all_inherited(&self, item: &hir::Item) {
struct
VisiblePrivateTypesVisitor
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
exported_items
:
&
'a
ExportedItems
,
public_items
:
&
'a
PublicItems
,
access_levels
:
&
'a
AccessLevels
,
in_variant
:
bool
,
}
...
...
@@ -1210,7 +1143,7 @@ fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
fn
trait_is_public
(
&
self
,
trait_id
:
ast
::
NodeId
)
->
bool
{
// FIXME: this would preferably be using `exported_items`, but all
// traits are exported currently (see `EmbargoVisitor.exported_trait`)
self
.
public_items
.contains
(
&
trait_id
)
self
.
access_levels
.is_public
(
trait_id
)
}
fn
check_ty_param_bound
(
&
self
,
...
...
@@ -1226,7 +1159,7 @@ fn check_ty_param_bound(&self,
}
fn
item_is_public
(
&
self
,
id
:
&
ast
::
NodeId
,
vis
:
hir
::
Visibility
)
->
bool
{
self
.
exported_items
.contains
(
id
)
||
vis
==
hir
::
Public
self
.
access_levels
.is_reachable
(
*
id
)
||
vis
==
hir
::
Public
}
}
...
...
@@ -1332,7 +1265,7 @@ fn visit_item(&mut self, item: &hir::Item) {
match
impl_item
.node
{
hir
::
ImplItemKind
::
Const
(
..
)
|
hir
::
ImplItemKind
::
Method
(
..
)
=>
{
self
.
exported_items
.contains
(
&
impl_item
.id
)
self
.
access_levels
.is_reachable
(
impl_item
.id
)
}
hir
::
ImplItemKind
::
Type
(
_
)
=>
false
,
}
...
...
@@ -1461,7 +1394,7 @@ fn visit_generics(&mut self, generics: &hir::Generics) {
}
fn
visit_foreign_item
(
&
mut
self
,
item
:
&
hir
::
ForeignItem
)
{
if
self
.
exported_items
.contains
(
&
item
.id
)
{
if
self
.
access_levels
.is_reachable
(
item
.id
)
{
intravisit
::
walk_foreign_item
(
self
,
item
)
}
}
...
...
@@ -1479,7 +1412,7 @@ fn visit_ty(&mut self, t: &hir::Ty) {
}
fn
visit_variant
(
&
mut
self
,
v
:
&
hir
::
Variant
,
g
:
&
hir
::
Generics
,
item_id
:
ast
::
NodeId
)
{
if
self
.
exported_items
.contains
(
&
v
.node.data
.id
())
{
if
self
.
access_levels
.is_reachable
(
v
.node.data
.id
())
{
self
.in_variant
=
true
;
intravisit
::
walk_variant
(
self
,
v
,
g
,
item_id
);
self
.in_variant
=
false
;
...
...
@@ -1509,7 +1442,7 @@ fn visit_expr(&mut self, _: &hir::Expr) {}
pub
fn
check_crate
(
tcx
:
&
ty
::
ctxt
,
export_map
:
&
def
::
ExportMap
,
external_exports
:
ExternalExports
)
->
(
ExportedItems
,
PublicItems
)
{
->
AccessLevels
{
let
krate
=
tcx
.map
.krate
();
// Sanity check to make sure that all privacy usage and controls are
...
...
@@ -1544,33 +1477,31 @@ pub fn check_crate(tcx: &ty::ctxt,
// items which are reachable from external crates based on visibility.
let
mut
visitor
=
EmbargoVisitor
{
tcx
:
tcx
,
exported_items
:
NodeSet
(),
public_items
:
NodeSet
(),
export_map
:
export_map
,
prev_exported
:
true
,
prev_public
:
true
,
access_levels
:
Default
::
default
(),
prev_level
:
Some
(
AccessLevel
::
Public
),
changed
:
false
,
};
visitor
.exported_items
.insert
(
ast
::
CRATE_NODE_ID
);
visitor
.public_items
.insert
(
ast
::
CRATE_NODE_ID
);
loop
{
let
before
=
(
visitor
.exported_items
.len
(),
visitor
.public_items
.len
());
intravisit
::
walk_crate
(
&
mut
visitor
,
krate
);
let
after
=
(
visitor
.exported_items
.len
(),
visitor
.public_items
.len
());
if
after
==
before
{
if
visitor
.changed
{
visitor
.changed
=
false
;
}
else
{
break
}
}
visitor
.update
(
ast
::
CRATE_NODE_ID
,
Some
(
AccessLevel
::
Public
));
let
EmbargoVisitor
{
exported_items
,
public_item
s
,
..
}
=
visitor
;
let
EmbargoVisitor
{
access_level
s
,
..
}
=
visitor
;
{
let
mut
visitor
=
VisiblePrivateTypesVisitor
{
tcx
:
tcx
,
exported_items
:
&
exported_items
,
public_items
:
&
public_items
,
access_levels
:
&
access_levels
,
in_variant
:
false
,
};
intravisit
::
walk_crate
(
&
mut
visitor
,
krate
);
}
return
(
exported_items
,
public_items
);
access_levels
}
src/librustdoc/core.rs
浏览文件 @
c1ad5af4
...
...
@@ -13,10 +13,10 @@
use
rustc_driver
::{
driver
,
target_features
};
use
rustc
::
session
::{
self
,
config
};
use
rustc
::
middle
::
def_id
::
DefId
;
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
middle
::
ty
;
use
rustc
::
front
::
map
as
hir_map
;
use
rustc
::
lint
;
use
rustc
::
util
::
nodemap
::
DefIdSet
;
use
rustc_trans
::
back
::
link
;
use
rustc_resolve
as
resolve
;
use
rustc_front
::
lowering
::{
lower_crate
,
LoweringContext
};
...
...
@@ -77,8 +77,7 @@ pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
}
pub
struct
CrateAnalysis
{
pub
exported_items
:
DefIdSet
,
pub
public_items
:
DefIdSet
,
pub
access_levels
:
AccessLevels
<
DefId
>
,
pub
external_paths
:
ExternalPaths
,
pub
external_typarams
:
RefCell
<
Option
<
HashMap
<
DefId
,
String
>>>
,
pub
inlined
:
RefCell
<
Option
<
HashSet
<
DefId
>>>
,
...
...
@@ -147,18 +146,15 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
&
name
,
resolve
::
MakeGlobMap
::
No
,
|
tcx
,
_
,
analysis
|
{
let
ty
::
CrateAnalysis
{
exported_items
,
public_item
s
,
..
}
=
analysis
;
let
ty
::
CrateAnalysis
{
access_level
s
,
..
}
=
analysis
;
// Convert from a NodeId set to a DefId set since we don't always have easy access
// to the map from defid -> nodeid
let
exported_items
:
DefIdSet
=
exported_items
.into_iter
()
.map
(|
n
|
tcx
.map
.local_def_id
(
n
))
.collect
();
let
public_items
:
DefIdSet
=
public_items
.into_iter
()
.map
(|
n
|
tcx
.map
.local_def_id
(
n
))
.collect
();
let
access_levels
=
AccessLevels
{
map
:
access_levels
.map
.into_iter
()
.map
(|(
k
,
v
)|
(
tcx
.map
.local_def_id
(
k
),
v
))
.collect
()
};
let
ctxt
=
DocContext
{
map
:
&
tcx
.map
,
...
...
@@ -174,8 +170,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
debug!
(
"crate: {:?}"
,
ctxt
.map
.krate
());
let
mut
analysis
=
CrateAnalysis
{
exported_items
:
exported_items
,
public_items
:
public_items
,
access_levels
:
access_levels
,
external_paths
:
RefCell
::
new
(
None
),
external_typarams
:
RefCell
::
new
(
None
),
inlined
:
RefCell
::
new
(
None
),
...
...
src/librustdoc/html/render.rs
浏览文件 @
c1ad5af4
...
...
@@ -56,8 +56,8 @@
use
syntax
::{
abi
,
ast
};
use
rustc
::
metadata
::
cstore
::
LOCAL_CRATE
;
use
rustc
::
middle
::
def_id
::{
CRATE_DEF_INDEX
,
DefId
};
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
middle
::
stability
;
use
rustc
::
util
::
nodemap
::
DefIdSet
;
use
rustc_front
::
hir
;
use
clean
::{
self
,
SelfTy
};
...
...
@@ -244,7 +244,7 @@ pub struct Cache {
search_index
:
Vec
<
IndexItem
>
,
privmod
:
bool
,
remove_priv
:
bool
,
public_items
:
DefIdSet
,
access_levels
:
AccessLevels
<
DefId
>
,
deref_trait_did
:
Option
<
DefId
>
,
// In rare case where a structure is defined in one module but implemented
...
...
@@ -415,8 +415,8 @@ pub fn run(mut krate: clean::Crate,
// Crawl the crate to build various caches used for the output
let
analysis
=
::
ANALYSISKEY
.with
(|
a
|
a
.clone
());
let
analysis
=
analysis
.borrow
();
let
public_items
=
analysis
.as_ref
()
.map
(|
a
|
a
.public_item
s
.clone
());
let
public_items
=
public_items
.unwrap_or
(
DefIdSe
t
());
let
access_levels
=
analysis
.as_ref
()
.map
(|
a
|
a
.access_level
s
.clone
());
let
access_levels
=
access_levels
.unwrap_or
(
Default
::
defaul
t
());
let
paths
:
HashMap
<
DefId
,
(
Vec
<
String
>
,
ItemType
)
>
=
analysis
.as_ref
()
.map
(|
a
|
{
let
paths
=
a
.external_paths
.borrow_mut
()
.take
()
.unwrap
();
...
...
@@ -435,7 +435,7 @@ pub fn run(mut krate: clean::Crate,
primitive_locations
:
HashMap
::
new
(),
remove_priv
:
cx
.passes
.contains
(
"strip-private"
),
privmod
:
false
,
public_items
:
public_item
s
,
access_levels
:
access_level
s
,
orphan_methods
:
Vec
::
new
(),
traits
:
mem
::
replace
(
&
mut
krate
.external_traits
,
HashMap
::
new
()),
deref_trait_did
:
analysis
.as_ref
()
.and_then
(|
a
|
a
.deref_trait_did
),
...
...
@@ -1053,7 +1053,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
if
!
self
.paths
.contains_key
(
&
item
.def_id
)
||
!
item
.def_id
.is_local
()
||
self
.
public_items
.contains
(
&
item
.def_id
)
self
.
access_levels
.is_public
(
item
.def_id
)
{
self
.paths
.insert
(
item
.def_id
,
(
self
.stack
.clone
(),
shortty
(
&
item
)));
...
...
src/librustdoc/passes.rs
浏览文件 @
c1ad5af4
...
...
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
rustc
::
middle
::
def_id
::
DefId
;
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
util
::
nodemap
::
DefIdSet
;
use
std
::
cmp
;
use
std
::
string
::
String
;
...
...
@@ -96,13 +98,13 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
let
analysis
=
super
::
ANALYSISKEY
.with
(|
a
|
a
.clone
());
let
analysis
=
analysis
.borrow
();
let
analysis
=
analysis
.as_ref
()
.unwrap
();
let
exported_items
=
analysis
.exported_item
s
.clone
();
let
access_levels
=
analysis
.access_level
s
.clone
();
// strip all private items
{
let
mut
stripper
=
Stripper
{
retained
:
&
mut
retained
,
exported_items
:
&
exported_item
s
,
access_levels
:
&
access_level
s
,
};
krate
=
stripper
.fold_crate
(
krate
);
}
...
...
@@ -117,7 +119,7 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
struct
Stripper
<
'a
>
{
retained
:
&
'a
mut
DefIdSet
,
exported_items
:
&
'a
DefIdSet
,
access_levels
:
&
'a
AccessLevels
<
DefId
>
,
}
impl
<
'a
>
fold
::
DocFolder
for
Stripper
<
'a
>
{
...
...
@@ -130,18 +132,14 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
clean
::
VariantItem
(
..
)
|
clean
::
MethodItem
(
..
)
|
clean
::
ForeignFunctionItem
(
..
)
|
clean
::
ForeignStaticItem
(
..
)
=>
{
if
i
.def_id
.is_local
()
{
if
!
self
.exported_items
.contains
(
&
i
.def_id
)
{
return
None
;
}
// Traits are in exported_items even when they're totally private.
if
i
.is_trait
()
&&
i
.visibility
!=
Some
(
hir
::
Public
)
{
if
!
self
.access_levels
.is_exported
(
i
.def_id
)
{
return
None
;
}
}
}
clean
::
ConstantItem
(
..
)
=>
{
if
i
.def_id
.is_local
()
&&
!
self
.
exported_items
.contains
(
&
i
.def_id
)
{
if
i
.def_id
.is_local
()
&&
!
self
.
access_levels
.is_exported
(
i
.def_id
)
{
return
None
;
}
}
...
...
@@ -168,7 +166,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
clean
::
ImplItem
(
clean
::
Impl
{
for_
:
clean
::
ResolvedPath
{
did
,
..
},
..
})
=>
{
if
did
.is_local
()
&&
!
self
.
exported_items
.contains
(
&
did
)
{
if
did
.is_local
()
&&
!
self
.
access_levels
.is_exported
(
did
)
{
return
None
;
}
}
...
...
src/librustdoc/visit_ast.rs
浏览文件 @
c1ad5af4
...
...
@@ -214,7 +214,7 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Name>,
let
analysis
=
match
self
.analysis
{
Some
(
analysis
)
=>
analysis
,
None
=>
return
false
};
if
!
please_inline
&&
analysis
.
public_items
.contains
(
&
def
)
{
if
!
please_inline
&&
analysis
.
access_levels
.is_public
(
def
)
{
return
false
}
if
!
self
.view_item_stack
.insert
(
def_node_id
)
{
return
false
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录