-use crate::utils::{indent_of, span_lint_and_then};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::indent_of;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if_chain! {
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
- if cx.access_levels.is_exported(item.hir_id);
- if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
+ if cx.access_levels.is_exported(item.hir_id());
+ let attrs = cx.tcx.hir().attrs(item.hir_id());
+ if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
then {
- let (lint, msg) = if let ItemKind::Enum(..) = item.kind {
- (EXHAUSTIVE_ENUMS, "exported enums should not be exhaustive")
- } else {
+ let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
+ if v.fields().iter().any(|f| !f.vis.node.is_pub()) {
+ // skip structs with private fields
+ return;
+ }
(EXHAUSTIVE_STRUCTS, "exported structs should not be exhaustive")
+ } else {
+ (EXHAUSTIVE_ENUMS, "exported enums should not be exhaustive")
};
let suggestion_span = item.span.shrink_to_lo();
let indent = " ".repeat(indent_of(cx, item.span).unwrap_or(0));