use rustc::ty::{self, Ty};
use rustc::{lint, util};
use hir::Node;
-use util::nodemap::NodeSet;
+use util::nodemap::HirIdSet;
use lint::{LateContext, LintContext, LintArray};
use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
hir::ItemKind::Enum(..) |
hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) => {
- let def_id = cx.tcx.hir().local_def_id(it.id);
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id))
}
_ => ()
hir::ItemKind::Struct(ref struct_def, _) |
hir::ItemKind::Union(ref struct_def, _) => {
for struct_field in struct_def.fields() {
- let def_id = cx.tcx.hir().local_def_id(struct_field.id);
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(struct_field.hir_id);
self.check_heap_type(cx, struct_field.span,
cx.tcx.type_of(def_id));
}
// (Issue #49588)
continue;
}
- if let PatKind::Binding(_, _, _, ident, None) = fieldpat.node.pat.node {
+ if let PatKind::Binding(_, _, ident, None) = fieldpat.node.pat.node {
if cx.tcx.find_field_index(ident, &variant) ==
- Some(cx.tcx.field_index(fieldpat.node.id, cx.tables)) {
+ Some(cx.tcx.field_index(fieldpat.node.hir_id, cx.tables)) {
let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS,
fieldpat.span,
&format!("the `{}:` in this pattern is redundant", ident));
doc_hidden_stack: Vec<bool>,
/// Private traits or trait items that leaked through. Don't check their methods.
- private_traits: FxHashSet<ast::NodeId>,
+ private_traits: FxHashSet<hir::HirId>,
}
fn has_doc(attr: &ast::Attribute) -> bool {
fn check_missing_docs_attrs(&self,
cx: &LateContext<'_, '_>,
- id: Option<ast::NodeId>,
+ id: Option<hir::HirId>,
attrs: &[ast::Attribute],
sp: Span,
desc: &'static str) {
// It's an option so the crate root can also use this function (it doesn't
// have a NodeId).
if let Some(id) = id {
- if !cx.access_levels.is_exported(id) {
+ let node_id = cx.tcx.hir().hir_to_node_id(id);
+ if !cx.access_levels.is_exported(node_id) {
return;
}
}
hir::ItemKind::Trait(.., ref trait_item_refs) => {
// Issue #11592, traits are always considered exported, even when private.
if let hir::VisibilityKind::Inherited = it.vis.node {
- self.private_traits.insert(it.id);
+ self.private_traits.insert(it.hir_id);
for trait_item_ref in trait_item_refs {
- self.private_traits.insert(trait_item_ref.id.node_id);
+ self.private_traits.insert(trait_item_ref.id.hir_id);
}
return;
}
// If the trait is private, add the impl items to private_traits so they don't get
// reported for missing docs.
let real_trait = trait_ref.path.def.def_id();
- if let Some(node_id) = cx.tcx.hir().as_local_node_id(real_trait) {
- match cx.tcx.hir().find(node_id) {
+ if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(real_trait) {
+ match cx.tcx.hir().find_by_hir_id(hir_id) {
Some(Node::Item(item)) => {
if let hir::VisibilityKind::Inherited = item.vis.node {
for impl_item_ref in impl_item_refs {
- self.private_traits.insert(impl_item_ref.id.node_id);
+ self.private_traits.insert(impl_item_ref.id.hir_id);
}
}
}
_ => return,
};
- self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
+ self.check_missing_docs_attrs(cx, Some(it.hir_id), &it.attrs, it.span, desc);
}
fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, trait_item: &hir::TraitItem) {
- if self.private_traits.contains(&trait_item.id) {
+ if self.private_traits.contains(&trait_item.hir_id) {
return;
}
};
self.check_missing_docs_attrs(cx,
- Some(trait_item.id),
+ Some(trait_item.hir_id),
&trait_item.attrs,
trait_item.span,
desc);
fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) {
// If the method is an impl for a trait, don't doc.
- if method_context(cx, impl_item.id) == MethodLateContext::TraitImpl {
+ if method_context(cx, impl_item.hir_id) == MethodLateContext::TraitImpl {
return;
}
hir::ImplItemKind::Existential(_) => "an associated existential type",
};
self.check_missing_docs_attrs(cx,
- Some(impl_item.id),
+ Some(impl_item.hir_id),
&impl_item.attrs,
impl_item.span,
desc);
fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, sf: &hir::StructField) {
if !sf.is_positional() {
self.check_missing_docs_attrs(cx,
- Some(sf.id),
+ Some(sf.hir_id),
&sf.attrs,
sf.span,
"a struct field")
fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant, _: &hir::Generics) {
self.check_missing_docs_attrs(cx,
- Some(v.node.data.id()),
+ Some(v.node.data.hir_id()),
&v.node.attrs,
v.span,
"a variant");
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
- if !cx.access_levels.is_reachable(item.id) {
+ let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id);
+ if !cx.access_levels.is_reachable(node_id) {
return;
}
let (def, ty) = match item.node {
if !ast_generics.params.is_empty() {
return;
}
- let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+ let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
}
hir::ItemKind::Union(_, ref ast_generics) => {
if !ast_generics.params.is_empty() {
return;
}
- let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+ let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
}
hir::ItemKind::Enum(_, ref ast_generics) => {
if !ast_generics.params.is_empty() {
return;
}
- let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+ let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
}
_ => return,
}
pub struct MissingDebugImplementations {
- impling_types: Option<NodeSet>,
+ impling_types: Option<HirIdSet>,
}
impl MissingDebugImplementations {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
- if !cx.access_levels.is_reachable(item.id) {
+ let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id);
+ if !cx.access_levels.is_reachable(node_id) {
return;
}
};
if self.impling_types.is_none() {
- let mut impls = NodeSet::default();
+ let mut impls = HirIdSet::default();
cx.tcx.for_each_impl(debug, |d| {
if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
- if let Some(node_id) = cx.tcx.hir().as_local_node_id(ty_def.did) {
- impls.insert(node_id);
+ if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(ty_def.did) {
+ impls.insert(hir_id);
}
}
});
debug!("{:?}", self.impling_types);
}
- if !self.impling_types.as_ref().unwrap().contains(&item.id) {
+ if !self.impling_types.as_ref().unwrap().contains(&item.hir_id) {
cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
item.span,
"type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
}
impl UnusedDocComment {
- fn warn_if_doc<'a, 'tcx,
- I: Iterator<Item=&'a ast::Attribute>,
- C: LintContext<'tcx>>(&self, mut attrs: I, cx: &C) {
- if let Some(attr) = attrs.find(|a| a.is_value_str() && a.check_name("doc")) {
- cx.struct_span_lint(UNUSED_DOC_COMMENTS, attr.span, "doc comment not used by rustdoc")
- .emit();
+ fn warn_if_doc(&self, cx: &EarlyContext, attrs: &[ast::Attribute]) {
+ let mut attrs = attrs.into_iter().peekable();
+
+ // Accumulate a single span for sugared doc comments.
+ let mut sugared_span: Option<Span> = None;
+
+ while let Some(attr) = attrs.next() {
+ if attr.is_sugared_doc {
+ sugared_span = Some(
+ sugared_span.map_or_else(
+ || attr.span,
+ |span| span.with_hi(attr.span.hi()),
+ ),
+ );
+ }
+
+ if attrs.peek().map(|next_attr| next_attr.is_sugared_doc).unwrap_or_default() {
+ continue;
+ }
+
+ let span = sugared_span.take().unwrap_or_else(|| attr.span);
+
+ if attr.name() == "doc" {
+ cx.struct_span_lint(
+ UNUSED_DOC_COMMENTS,
+ span,
+ "doc comment not used by rustdoc",
+ ).emit();
+ }
}
}
}
impl EarlyLintPass for UnusedDocComment {
fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) {
- self.warn_if_doc(decl.attrs.iter(), cx);
+ self.warn_if_doc(cx, &decl.attrs);
}
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
- self.warn_if_doc(arm.attrs.iter(), cx);
+ self.warn_if_doc(cx, &arm.attrs);
}
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
- self.warn_if_doc(expr.attrs.iter(), cx);
+ self.warn_if_doc(cx, &expr.attrs);
}
}
_ => return,
};
- let def_id = cx.tcx.hir().local_def_id(it.id);
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) {
Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
None => {
fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) {
if let hir::ItemKind::Union(ref vdata, _) = item.node {
for field in vdata.fields() {
- let field_ty = ctx.tcx.type_of(ctx.tcx.hir().local_def_id(field.id));
+ let field_ty = ctx.tcx.type_of(
+ ctx.tcx.hir().local_def_id_from_hir_id(field.hir_id));
if field_ty.needs_drop(ctx.tcx, ctx.param_env) {
ctx.span_lint(UNIONS_WITH_DROP_FIELDS,
field.span,
}
impl UnreachablePub {
- fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: ast::NodeId,
+ fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: hir::HirId,
vis: &hir::Visibility, span: Span, exportable: bool) {
let mut applicability = Applicability::MachineApplicable;
+ let node_id = cx.tcx.hir().hir_to_node_id(id);
match vis.node {
- hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
+ hir::VisibilityKind::Public if !cx.access_levels.is_reachable(node_id) => {
if span.ctxt().outer().expn_info().is_some() {
applicability = Applicability::MaybeIncorrect;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
- self.perform_lint(cx, "item", item.id, &item.vis, item.span, true);
+ self.perform_lint(cx, "item", item.hir_id, &item.vis, item.span, true);
}
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, foreign_item: &hir::ForeignItem) {
- self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis,
+ self.perform_lint(cx, "item", foreign_item.hir_id, &foreign_item.vis,
foreign_item.span, true);
}
fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &hir::StructField) {
- self.perform_lint(cx, "field", field.id, &field.vis, field.span, false);
+ self.perform_lint(cx, "field", field.hir_id, &field.vis, field.span, false);
}
fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) {
- self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false);
+ self.perform_lint(cx, "item", impl_item.hir_id, &impl_item.vis, impl_item.span, false);
}
}
if cx.tcx.features().trivial_bounds {
- let def_id = cx.tcx.hir().local_def_id(item.id);
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
let predicates = cx.tcx.predicates_of(def_id);
for &(predicate, span) in &predicates.predicates {
let predicate_kind_name = match predicate {
}
pub struct UnnameableTestItems {
- boundary: ast::NodeId, // NodeId of the item under which things are not nameable
+ boundary: hir::HirId, // HirId of the item under which things are not nameable
items_nameable: bool,
}
impl UnnameableTestItems {
pub fn new() -> Self {
Self {
- boundary: ast::DUMMY_NODE_ID,
+ boundary: hir::DUMMY_HIR_ID,
items_nameable: true
}
}
if let hir::ItemKind::Mod(..) = it.node {}
else {
self.items_nameable = false;
- self.boundary = it.id;
+ self.boundary = it.hir_id;
}
return;
}
}
fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item) {
- if !self.items_nameable && self.boundary == it.id {
+ if !self.items_nameable && self.boundary == it.hir_id {
self.items_nameable = true;
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
let infer_static = cx.tcx.features().infer_static_outlives_requirements;
- let def_id = cx.tcx.hir().local_def_id(item.id);
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
if let hir::ItemKind::Struct(_, ref generics) = item.node {
let mut bound_count = 0;
let mut lint_spans = Vec::new();