diff options
| author | Philipp Krones <hello@philkrones.com> | 2025-01-28 18:28:57 +0100 |
|---|---|---|
| committer | Philipp Krones <hello@philkrones.com> | 2025-01-28 19:14:45 +0100 |
| commit | 145d5adf04fecbc48bdf2ab2a356ca4c8df0c149 (patch) | |
| tree | 1783d720a01e7ef83d143293961fd83200728556 /clippy_lints/src/unneeded_struct_pattern.rs | |
| parent | c5196736b27a32b688b957f2937dd4affadbe14f (diff) | |
| parent | 25509e71359ea0b218309d4b7e94bf40e1ef716e (diff) | |
| download | rust-145d5adf04fecbc48bdf2ab2a356ca4c8df0c149.tar.gz rust-145d5adf04fecbc48bdf2ab2a356ca4c8df0c149.zip | |
Merge remote-tracking branch 'upstream/master' into rustup
Diffstat (limited to 'clippy_lints/src/unneeded_struct_pattern.rs')
| -rw-r--r-- | clippy_lints/src/unneeded_struct_pattern.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/clippy_lints/src/unneeded_struct_pattern.rs b/clippy_lints/src/unneeded_struct_pattern.rs new file mode 100644 index 00000000000..40ba70d451d --- /dev/null +++ b/clippy_lints/src/unneeded_struct_pattern.rs @@ -0,0 +1,76 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_from_proc_macro; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Pat, PatKind, QPath}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Checks for struct patterns that match against unit variant. + /// + /// ### Why is this bad? + /// Struct pattern `{ }` or `{ .. }` is not needed for unit variant. + /// + /// ### Example + /// ```no_run + /// match Some(42) { + /// Some(v) => v, + /// None { .. } => 0, + /// }; + /// // Or + /// match Some(42) { + /// Some(v) => v, + /// None { } => 0, + /// }; + /// ``` + /// Use instead: + /// ```no_run + /// match Some(42) { + /// Some(v) => v, + /// None => 0, + /// }; + /// ``` + #[clippy::version = "1.83.0"] + pub UNNEEDED_STRUCT_PATTERN, + style, + "using struct pattern to match against unit variant" +} + +declare_lint_pass!(UnneededStructPattern => [UNNEEDED_STRUCT_PATTERN]); + +impl LateLintPass<'_> for UnneededStructPattern { + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { + if !pat.span.from_expansion() + && let PatKind::Struct(path, [], _) = &pat.kind + && let QPath::Resolved(_, path) = path + && let Res::Def(DefKind::Variant, did) = path.res + { + let enum_did = cx.tcx.parent(did); + let variant = cx.tcx.adt_def(enum_did).variant_with_id(did); + + let has_only_fields_brackets = variant.ctor.is_some() && variant.fields.is_empty(); + let non_exhaustive_activated = !variant.def_id.is_local() && variant.is_field_list_non_exhaustive(); + if !has_only_fields_brackets || non_exhaustive_activated { + return; + } + + if is_from_proc_macro(cx, *path) { + return; + } + + if let Some(brackets_span) = pat.span.trim_start(path.span) { + span_lint_and_sugg( + cx, + UNNEEDED_STRUCT_PATTERN, + brackets_span, + "struct pattern is not needed for a unit variant", + "remove the struct pattern", + String::new(), + Applicability::MachineApplicable, + ); + } + } + } +} |
