Skip to content

Commit 98bf525

Browse files
committed
---
yaml --- r: 96071 b: refs/heads/dist-snap c: c2c7a24 h: refs/heads/master i: 96069: 70d4a07 96067: 0e04ea8 96063: f06627b v: v3
1 parent a1802b9 commit 98bf525

File tree

15 files changed

+366
-377
lines changed

15 files changed

+366
-377
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 314d6f693f9442ab40879b58f34c6d0afb76f447
9+
refs/heads/dist-snap: c2c7a2497d2005f92834a2c2d6204cc7db783ec9
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/librustc/driver/driver.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,11 @@ pub fn phase_3_run_analysis_passes(sess: Session,
302302

303303
let reachable_map =
304304
time(time_passes, "reachability checking", (), |_|
305-
reachable::find_reachable(ty_cx, method_map, &exported_items));
305+
reachable::find_reachable(ty_cx, method_map, exp_map2,
306+
&exported_items));
306307

307308
time(time_passes, "lint checking", (), |_|
308-
lint::check_crate(ty_cx, &exported_items, crate));
309+
lint::check_crate(ty_cx, crate));
309310

310311
CrateAnalysis {
311312
exp_map2: exp_map2,

branches/dist-snap/src/librustc/middle/lint.rs

Lines changed: 117 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
//! Context itself, span_lint should be used instead of add_lint.
3535
3636
use driver::session;
37-
use middle::privacy;
3837
use middle::trans::adt; // for `adt::is_ffi_safe`
3938
use middle::ty;
4039
use middle::pat_util;
@@ -310,28 +309,21 @@ pub fn get_lint_dict() -> LintDict {
310309
return map;
311310
}
312311

313-
struct Context<'self> {
312+
struct Context {
314313
// All known lint modes (string versions)
315314
dict: @LintDict,
316315
// Current levels of each lint warning
317316
cur: SmallIntMap<(level, LintSource)>,
318317
// context we're checking in (used to access fields like sess)
319318
tcx: ty::ctxt,
320-
// Items exported by the crate; used by the missing_doc lint.
321-
exported_items: &'self privacy::ExportedItems,
322-
// The id of the current `ast::struct_def` being walked.
323-
cur_struct_def_id: ast::NodeId,
324-
// Whether some ancestor of the current node was marked
325-
// #[doc(hidden)].
326-
is_doc_hidden: bool,
327319

328320
// When recursing into an attributed node of the ast which modifies lint
329321
// levels, this stack keeps track of the previous lint levels of whatever
330322
// was modified.
331323
lint_stack: ~[(lint, level, LintSource)],
332324
}
333325

334-
impl<'self> Context<'self> {
326+
impl Context {
335327
fn get_level(&self, lint: lint) -> level {
336328
match self.cur.find(&(lint as uint)) {
337329
Some(&(lvl, _)) => lvl,
@@ -440,16 +432,9 @@ impl<'self> Context<'self> {
440432
true
441433
};
442434

443-
let old_is_doc_hidden = self.is_doc_hidden;
444-
self.is_doc_hidden = self.is_doc_hidden ||
445-
attrs.iter().any(|attr| ("doc" == attr.name() && match attr.meta_item_list()
446-
{ None => false,
447-
Some(l) => attr::contains_name(l, "hidden") }));
448-
449435
f(self);
450436

451437
// rollback
452-
self.is_doc_hidden = old_is_doc_hidden;
453438
do pushed.times {
454439
let (lint, lvl, src) = self.lint_stack.pop();
455440
self.set_level(lint, lvl, src);
@@ -877,81 +862,123 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
877862
}
878863
}
879864

880-
fn check_missing_doc_attrs(cx: &Context,
881-
id: ast::NodeId,
882-
attrs: &[ast::Attribute],
883-
sp: Span,
884-
desc: &'static str) {
885-
// If we're building a test harness, then warning about
886-
// documentation is probably not really relevant right now.
887-
if cx.tcx.sess.opts.test { return }
888-
889-
// `#[doc(hidden)]` disables missing_doc check.
890-
if cx.is_doc_hidden { return }
891-
892-
// Only check publicly-visible items, using the result from the
893-
// privacy pass.
894-
if !cx.exported_items.contains(&id) { return }
895-
896-
if !attrs.iter().any(|a| a.node.is_sugared_doc) {
897-
cx.span_lint(missing_doc, sp,
898-
format!("missing documentation for {}", desc));
899-
}
900-
}
865+
struct MissingDocLintVisitor(ty::ctxt);
901866

902-
fn check_missing_doc_item(cx: &mut Context, it: &ast::item) { // XXX doesn't need to be mut
903-
let desc = match it.node {
904-
ast::item_fn(*) => "a function",
905-
ast::item_mod(*) => "a module",
906-
ast::item_enum(*) => "an enum",
907-
ast::item_struct(*) => "a struct",
908-
ast::item_trait(*) => "a trait",
909-
_ => return
910-
};
911-
check_missing_doc_attrs(cx, it.id, it.attrs, it.span, desc);
912-
}
867+
impl MissingDocLintVisitor {
868+
fn check_attrs(&self, attrs: &[ast::Attribute], id: ast::NodeId,
869+
sp: Span, msg: ~str) {
870+
if !attrs.iter().any(|a| a.node.is_sugared_doc) {
871+
self.sess.add_lint(missing_doc, id, sp, msg);
872+
}
873+
}
913874

914-
fn check_missing_doc_method(cx: &Context, m: &ast::method) {
915-
let did = ast::DefId {
916-
crate: ast::LOCAL_CRATE,
917-
node: m.id
918-
};
919-
match cx.tcx.methods.find(&did) {
920-
None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"),
921-
Some(md) => {
922-
match md.container {
923-
// Always check default methods defined on traits.
924-
ty::TraitContainer(*) => {}
925-
// For methods defined on impls, it depends on whether
926-
// it is an implementation for a trait or is a plain
927-
// impl.
928-
ty::ImplContainer(cid) => {
929-
match ty::impl_trait_ref(cx.tcx, cid) {
930-
Some(*) => return, // impl for trait: don't doc
931-
None => {} // plain impl: doc according to privacy
932-
}
875+
fn check_struct(&self, sdef: &ast::struct_def) {
876+
for field in sdef.fields.iter() {
877+
match field.node.kind {
878+
ast::named_field(_, vis) if vis != ast::private => {
879+
self.check_attrs(field.node.attrs, field.node.id, field.span,
880+
~"missing documentation for a field");
933881
}
882+
ast::unnamed_field | ast::named_field(*) => {}
934883
}
935884
}
936885
}
937-
check_missing_doc_attrs(cx, m.id, m.attrs, m.span, "a method");
938-
}
939886

940-
fn check_missing_doc_ty_method(cx: &Context, tm: &ast::TypeMethod) {
941-
check_missing_doc_attrs(cx, tm.id, tm.attrs, tm.span, "a type method");
887+
fn doc_hidden(&self, attrs: &[ast::Attribute]) -> bool {
888+
do attrs.iter().any |attr| {
889+
"doc" == attr.name() &&
890+
match attr.meta_item_list() {
891+
Some(l) => attr::contains_name(l, "hidden"),
892+
None => false // not of the form #[doc(...)]
893+
}
894+
}
895+
}
942896
}
943897

944-
fn check_missing_doc_struct_field(cx: &Context, sf: &ast::struct_field) {
945-
match sf.node.kind {
946-
ast::named_field(_, vis) if vis != ast::private =>
947-
check_missing_doc_attrs(cx, cx.cur_struct_def_id, sf.node.attrs,
948-
sf.span, "a struct field"),
949-
_ => {}
898+
impl Visitor<()> for MissingDocLintVisitor {
899+
fn visit_ty_method(&mut self, m:&ast::TypeMethod, _: ()) {
900+
if self.doc_hidden(m.attrs) { return }
901+
902+
// All ty_method objects are linted about because they're part of a
903+
// trait (no visibility)
904+
self.check_attrs(m.attrs, m.id, m.span,
905+
~"missing documentation for a method");
906+
visit::walk_ty_method(self, m, ());
950907
}
951-
}
952908

953-
fn check_missing_doc_variant(cx: &Context, v: &ast::variant) {
954-
check_missing_doc_attrs(cx, v.node.id, v.node.attrs, v.span, "a variant");
909+
fn visit_fn(&mut self, fk: &visit::fn_kind, d: &ast::fn_decl,
910+
b: &ast::Block, sp: Span, id: ast::NodeId, _: ()) {
911+
// Only warn about explicitly public methods.
912+
match *fk {
913+
visit::fk_method(_, _, m) => {
914+
if self.doc_hidden(m.attrs) {
915+
return;
916+
}
917+
// If we're in a trait implementation, no need to duplicate
918+
// documentation
919+
if m.vis == ast::public {
920+
self.check_attrs(m.attrs, id, sp,
921+
~"missing documentation for a method");
922+
}
923+
}
924+
_ => {}
925+
}
926+
visit::walk_fn(self, fk, d, b, sp, id, ());
927+
}
928+
929+
fn visit_item(&mut self, it: @ast::item, _: ()) {
930+
// If we're building a test harness, then warning about documentation is
931+
// probably not really relevant right now
932+
if self.sess.opts.test { return }
933+
if self.doc_hidden(it.attrs) { return }
934+
935+
match it.node {
936+
ast::item_struct(sdef, _) if it.vis == ast::public => {
937+
self.check_attrs(it.attrs, it.id, it.span,
938+
~"missing documentation for a struct");
939+
self.check_struct(sdef);
940+
}
941+
942+
// Skip implementations because they inherit documentation from the
943+
// trait (which was already linted)
944+
ast::item_impl(_, Some(*), _, _) => return,
945+
946+
ast::item_trait(*) if it.vis != ast::public => return,
947+
ast::item_trait(*) => self.check_attrs(it.attrs, it.id, it.span,
948+
~"missing documentation for a trait"),
949+
950+
ast::item_fn(*) if it.vis == ast::public => {
951+
self.check_attrs(it.attrs, it.id, it.span,
952+
~"missing documentation for a function");
953+
}
954+
955+
ast::item_mod(*) if it.vis == ast::public => {
956+
self.check_attrs(it.attrs, it.id, it.span,
957+
~"missing documentation for a module");
958+
}
959+
960+
ast::item_enum(ref edef, _) if it.vis == ast::public => {
961+
self.check_attrs(it.attrs, it.id, it.span,
962+
~"missing documentation for an enum");
963+
for variant in edef.variants.iter() {
964+
if variant.node.vis == ast::private { continue; }
965+
966+
self.check_attrs(variant.node.attrs, variant.node.id,
967+
variant.span,
968+
~"missing documentation for a variant");
969+
match variant.node.kind {
970+
ast::struct_variant_kind(sdef) => {
971+
self.check_struct(sdef);
972+
}
973+
_ => ()
974+
}
975+
}
976+
}
977+
978+
_ => {}
979+
}
980+
visit::walk_item(self, it, ());
981+
}
955982
}
956983

957984
/// Checks for use of items with #[deprecated], #[experimental] and
@@ -1027,14 +1054,13 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
10271054
cx.span_lint(lint, e.span, msg);
10281055
}
10291056

1030-
impl<'self> Visitor<()> for Context<'self> {
1057+
impl Visitor<()> for Context {
10311058
fn visit_item(&mut self, it: @ast::item, _: ()) {
10321059
do self.with_lint_attrs(it.attrs) |cx| {
10331060
check_item_ctypes(cx, it);
10341061
check_item_non_camel_case_types(cx, it);
10351062
check_item_non_uppercase_statics(cx, it);
10361063
check_heap_item(cx, it);
1037-
check_missing_doc_item(cx, it);
10381064

10391065
do cx.visit_ids |v| {
10401066
v.visit_item(it, ());
@@ -1077,8 +1103,6 @@ impl<'self> Visitor<()> for Context<'self> {
10771103
match *fk {
10781104
visit::fk_method(_, _, m) => {
10791105
do self.with_lint_attrs(m.attrs) |cx| {
1080-
check_missing_doc_method(cx, m);
1081-
10821106
do cx.visit_ids |v| {
10831107
v.visit_fn(fk, decl, body, span, id, ());
10841108
}
@@ -1088,45 +1112,9 @@ impl<'self> Visitor<()> for Context<'self> {
10881112
_ => recurse(self),
10891113
}
10901114
}
1091-
1092-
fn visit_ty_method(&mut self, t: &ast::TypeMethod, _: ()) {
1093-
do self.with_lint_attrs(t.attrs) |cx| {
1094-
check_missing_doc_ty_method(cx, t);
1095-
1096-
visit::walk_ty_method(cx, t, ());
1097-
}
1098-
}
1099-
1100-
fn visit_struct_def(&mut self,
1101-
s: @ast::struct_def,
1102-
i: ast::Ident,
1103-
g: &ast::Generics,
1104-
id: ast::NodeId,
1105-
_: ()) {
1106-
let old_id = self.cur_struct_def_id;
1107-
self.cur_struct_def_id = id;
1108-
visit::walk_struct_def(self, s, i, g, id, ());
1109-
self.cur_struct_def_id = old_id;
1110-
}
1111-
1112-
fn visit_struct_field(&mut self, s: @ast::struct_field, _: ()) {
1113-
do self.with_lint_attrs(s.node.attrs) |cx| {
1114-
check_missing_doc_struct_field(cx, s);
1115-
1116-
visit::walk_struct_field(cx, s, ());
1117-
}
1118-
}
1119-
1120-
fn visit_variant(&mut self, v: &ast::variant, g: &ast::Generics, _: ()) {
1121-
do self.with_lint_attrs(v.node.attrs) |cx| {
1122-
check_missing_doc_variant(cx, v);
1123-
1124-
visit::walk_variant(cx, v, g, ());
1125-
}
1126-
}
11271115
}
11281116

1129-
impl<'self> ast_util::IdVisitingOperation for Context<'self> {
1117+
impl ast_util::IdVisitingOperation for Context {
11301118
fn visit_id(&self, id: ast::NodeId) {
11311119
match self.tcx.sess.lints.pop(&id) {
11321120
None => {}
@@ -1139,16 +1127,17 @@ impl<'self> ast_util::IdVisitingOperation for Context<'self> {
11391127
}
11401128
}
11411129

1142-
pub fn check_crate(tcx: ty::ctxt,
1143-
exported_items: &privacy::ExportedItems,
1144-
crate: &ast::Crate) {
1130+
pub fn check_crate(tcx: ty::ctxt, crate: &ast::Crate) {
1131+
// This visitor contains more state than is currently maintained in Context,
1132+
// and there's no reason for the Context to keep track of this information
1133+
// really
1134+
let mut dox = MissingDocLintVisitor(tcx);
1135+
visit::walk_crate(&mut dox, crate, ());
1136+
11451137
let mut cx = Context {
11461138
dict: @get_lint_dict(),
11471139
cur: SmallIntMap::new(),
11481140
tcx: tcx,
1149-
exported_items: exported_items,
1150-
cur_struct_def_id: -1,
1151-
is_doc_hidden: false,
11521141
lint_stack: ~[],
11531142
};
11541143

0 commit comments

Comments
 (0)