fix(zero_repeat_side_effects): don't suggest unsuggestable types (#15815)

Fixes https://github.com/rust-lang/rust-clippy/issues/14998

changelog: [`zero_repeat_side_effects`]: don't suggest unsuggestable
types
This commit is contained in:
Jason Newcomb 2025-10-11 04:15:13 +00:00 committed by GitHub
commit 42f2ba1869
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 83 additions and 7 deletions

View file

@ -6,6 +6,7 @@ use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability;
use rustc_hir::{ConstArgKind, ExprKind, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::IsSuggestable;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -72,6 +73,7 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
// check if expr is a call or has a call inside it
if inner_expr.can_have_side_effects() {
let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id);
let inner_expr_ty = cx.typeck_results().expr_ty(inner_expr);
let return_type = cx.typeck_results().expr_ty(expr);
let inner_expr = snippet(cx, inner_expr.span.source_callsite(), "..");
@ -94,18 +96,25 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
),
_ => (expr.span, format!("{{ {inner_expr}; {vec}[] as {return_type} }}")),
};
let span = span.source_callsite();
span_lint_and_then(
cx,
ZERO_REPEAT_SIDE_EFFECTS,
span.source_callsite(),
span,
"expression with side effects as the initial value in a zero-sized array initializer",
|diag| {
diag.span_suggestion_verbose(
span.source_callsite(),
"consider performing the side effect separately",
sugg,
Applicability::Unspecified,
);
if (!inner_expr_ty.is_never() || cx.tcx.features().never_type())
&& return_type.is_suggestable(cx.tcx, true)
{
diag.span_suggestion_verbose(
span,
"consider performing the side effect separately",
sugg,
Applicability::Unspecified,
);
} else {
diag.help("consider performing the side effect separately");
}
},
);
}

View file

@ -0,0 +1,9 @@
#![warn(clippy::zero_repeat_side_effects)]
#![allow(clippy::diverging_sub_expression)]
#![feature(never_type)]
fn issue_14998() {
// nameable type thanks to `never_type` being enabled, suggest
panic!(); let _data: [!; 0] = [];
//~^ zero_repeat_side_effects
}

View file

@ -0,0 +1,9 @@
#![warn(clippy::zero_repeat_side_effects)]
#![allow(clippy::diverging_sub_expression)]
#![feature(never_type)]
fn issue_14998() {
// nameable type thanks to `never_type` being enabled, suggest
let _data = [panic!(); 0];
//~^ zero_repeat_side_effects
}

View file

@ -0,0 +1,16 @@
error: expression with side effects as the initial value in a zero-sized array initializer
--> tests/ui/zero_repeat_side_effects_never_pattern.rs:7:5
|
LL | let _data = [panic!(); 0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::zero-repeat-side-effects` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
help: consider performing the side effect separately
|
LL - let _data = [panic!(); 0];
LL + panic!(); let _data: [!; 0] = [];
|
error: aborting due to 1 previous error

View file

@ -0,0 +1,13 @@
//@no-rustfix
#![warn(clippy::zero_repeat_side_effects)]
#![expect(clippy::diverging_sub_expression)]
fn issue_14998() {
// unnameable types, don't suggest
let _data = [|| 3i32; 0];
//~^ zero_repeat_side_effects
// unnameable type because `never_type` is not enabled, don't suggest
let _data = [panic!(); 0];
//~^ zero_repeat_side_effects
}

View file

@ -0,0 +1,20 @@
error: expression with side effects as the initial value in a zero-sized array initializer
--> tests/ui/zero_repeat_side_effects_unfixable.rs:7:5
|
LL | let _data = [|| 3i32; 0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider performing the side effect separately
= note: `-D clippy::zero-repeat-side-effects` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
error: expression with side effects as the initial value in a zero-sized array initializer
--> tests/ui/zero_repeat_side_effects_unfixable.rs:11:5
|
LL | let _data = [panic!(); 0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider performing the side effect separately
error: aborting due to 2 previous errors