rustc_attr_parsing/attributes/
non_exhaustive.rs1use rustc_ast::VariantData;
2use rustc_attr_ir::target::AstTarget;
3use rustc_feature::AttributeStability;
4
5use super::prelude::*;
6use crate::diagnostics::NonExhaustiveWithDefaultFieldValues;
7
8pub(crate) struct NonExhaustiveParser;
9
10impl NoArgsAttributeParser for NonExhaustiveParser {
11 const PATH: &[Symbol] = &[sym::non_exhaustive];
12 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
13 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
14 Allow(Target::Enum),
15 Allow(Target::Struct),
16 Allow(Target::Variant),
17 Warn(Target::Field),
18 Warn(Target::Arm),
19 Warn(Target::MacroDef),
20 Warn(Target::MacroCall),
21 ]);
22 const STABILITY: AttributeStability = AttributeStability::Stable;
23 const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive;
24
25 fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) {
26 let AstTarget::Struct(_, _, data) = cx.ast_target else {
27 return;
28 };
29 if let VariantData::Struct { fields, .. } = data
30 && fields.iter().any(|f| f.default_value().is_some())
31 {
32 cx.emit_err(NonExhaustiveWithDefaultFieldValues {
33 attr_span,
34 defn_span: cx.target_span,
35 });
36 }
37 }
38}