Skip to content

Commit 31a5285

Browse files
committed
lint: handle private traits better
Due to a long-standing conservative approach to trait exports, all traits are considered exported. However, the missing_docs lint uses the export map to determine if something is public and ought to have documentation. This commit modifies the lint to check if traits are private before emitting the warning. Closes #11592
1 parent 199bdcf commit 31a5285

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/librustc_lint/builtin.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use util::ppaux::{ty_to_string};
3939
use util::nodemap::{FnvHashMap, NodeSet};
4040
use lint::{Level, Context, LintPass, LintArray, Lint};
4141

42-
use std::collections::BitSet;
42+
use std::collections::{HashSet, BitSet};
4343
use std::collections::hash_map::Entry::{Occupied, Vacant};
4444
use std::num::SignedInt;
4545
use std::{cmp, slice};
@@ -1437,6 +1437,9 @@ pub struct MissingDoc {
14371437
/// Stack of whether #[doc(hidden)] is set
14381438
/// at each level which has lint attributes.
14391439
doc_hidden_stack: Vec<bool>,
1440+
1441+
/// Private traits or trait items that leaked through. Don't check their methods.
1442+
private_traits: HashSet<ast::NodeId>,
14401443
}
14411444

14421445
impl MissingDoc {
@@ -1445,6 +1448,7 @@ impl MissingDoc {
14451448
struct_def_stack: vec!(),
14461449
in_variant: false,
14471450
doc_hidden_stack: vec!(false),
1451+
private_traits: HashSet::new(),
14481452
}
14491453
}
14501454

@@ -1531,18 +1535,46 @@ impl LintPass for MissingDoc {
15311535
ast::ItemMod(..) => "a module",
15321536
ast::ItemEnum(..) => "an enum",
15331537
ast::ItemStruct(..) => "a struct",
1534-
ast::ItemTrait(..) => "a trait",
1538+
ast::ItemTrait(_, _, _, ref items) => {
1539+
// Issue #11592, traits are always considered exported, even when private.
1540+
if it.vis == ast::Visibility::Inherited {
1541+
self.private_traits.insert(it.id);
1542+
for itm in items {
1543+
self.private_traits.insert(itm.id);
1544+
}
1545+
return
1546+
}
1547+
"a trait"
1548+
},
15351549
ast::ItemTy(..) => "a type alias",
1550+
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
1551+
// If the trait is private, add the impl items to private_traits so they don't get
1552+
// reported for missing docs.
1553+
let real_trait = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
1554+
match cx.tcx.map.find(real_trait.node) {
1555+
Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
1556+
for itm in impl_items {
1557+
self.private_traits.insert(itm.id);
1558+
}
1559+
},
1560+
_ => { }
1561+
}
1562+
return
1563+
},
15361564
_ => return
15371565
};
1566+
15381567
self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
15391568
}
15401569

15411570
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
1571+
if self.private_traits.contains(&trait_item.id) { return }
1572+
15421573
let desc = match trait_item.node {
15431574
ast::MethodTraitItem(..) => "a trait method",
15441575
ast::TypeTraitItem(..) => "an associated type"
15451576
};
1577+
15461578
self.check_missing_docs_attrs(cx, Some(trait_item.id),
15471579
&trait_item.attrs,
15481580
trait_item.span, desc);

src/test/run-pass/issue-11592.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Ensure the private trait Bar isn't complained about.
12+
13+
#![deny(missing_docs)]
14+
15+
mod foo {
16+
trait Bar { fn bar(&self) { } }
17+
impl Bar for i8 { fn bar(&self) { } }
18+
}
19+
20+
fn main() { }

0 commit comments

Comments
 (0)