Skip to content

Commit 6e99e2d

Browse files
committed
Use ConstArg for array lengths
1 parent 620a056 commit 6e99e2d

File tree

5 files changed

+42
-24
lines changed

5 files changed

+42
-24
lines changed

clippy_lints/src/large_stack_arrays.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,12 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
106106
///
107107
/// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
108108
/// correct result.
109-
fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
110-
let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else {
109+
fn repeat_expr_might_be_expanded<'tcx>(expr: &Expr<'tcx>) -> bool {
110+
let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else {
111111
return false;
112112
};
113-
let len_span = cx.tcx.def_span(anon_const.def_id);
114-
!expr.span.contains(len_span)
113+
!expr.span.contains(len_ct.span())
115114
}
116115

117-
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(cx, expr)
116+
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr)
118117
}

clippy_lints/src/trailing_empty_array.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::has_repr_attr;
33
use rustc_hir::{Item, ItemKind};
44
use rustc_lint::{LateContext, LateLintPass};
5-
use rustc_middle::ty::Const;
5+
use rustc_middle::ty::{Const, FeedConstTy};
66
use rustc_session::declare_lint_pass;
77

88
declare_clippy_lint! {
@@ -53,14 +53,14 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
5353
}
5454
}
5555

56-
fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
56+
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
5757
if let ItemKind::Struct(data, _) = &item.kind
5858
// First check if last field is an array
5959
&& let Some(last_field) = data.fields().last()
6060
&& let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind
6161

6262
// Then check if that array is zero-sized
63-
&& let length = Const::from_anon_const(cx.tcx, length.def_id)
63+
&& let length = Const::from_const_arg(cx.tcx, length, FeedConstTy::No)
6464
&& let length = length.try_eval_target_usize(cx.tcx, cx.param_env)
6565
&& let Some(length) = length
6666
{

clippy_lints/src/utils/author.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ use clippy_utils::{get_attr, higher};
55
use rustc_ast::ast::{LitFloatType, LitKind};
66
use rustc_ast::LitIntType;
77
use rustc_data_structures::fx::FxHashMap;
8-
use rustc_hir as hir;
98
use rustc_hir::{
10-
ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind,
11-
QPath, StmtKind, TyKind,
9+
self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
10+
ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
1211
};
1312
use rustc_lint::{LateContext, LateLintPass, LintContext};
1413
use rustc_session::declare_lint_pass;
@@ -270,6 +269,22 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
270269
}
271270
}
272271

272+
fn const_arg(&self, const_arg: &Binding<&ConstArg<'_>>) {
273+
match const_arg.value.kind {
274+
// FIXME: uncomment for ConstArgKind::Path
275+
// ConstArgKind::Path(ref qpath) => {
276+
// bind!(self, qpath);
277+
// chain!(self, "let ConstArgKind::Path(ref {qpath}) = {const_arg}.kind");
278+
// self.qpath(qpath);
279+
// },
280+
ConstArgKind::Anon(anon_const) => {
281+
bind!(self, anon_const);
282+
chain!(self, "let ConstArgKind::({anon_const}) = {const_arg}.kind");
283+
self.body(field!(anon_const.body));
284+
},
285+
}
286+
}
287+
273288
fn lit(&self, lit: &Binding<&Lit>) {
274289
let kind = |kind| chain!(self, "let LitKind::{kind} = {lit}.node");
275290
macro_rules! kind {
@@ -602,10 +617,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
602617
self.expr(value);
603618
match length.value {
604619
ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"),
605-
ArrayLen::Body(anon_const) => {
606-
bind!(self, anon_const);
607-
chain!(self, "let ArrayLen::Body({anon_const}) = {length}");
608-
self.body(field!(anon_const.body));
620+
ArrayLen::Body(const_arg) => {
621+
bind!(self, const_arg);
622+
chain!(self, "let ArrayLen::Body({const_arg}) = {length}");
623+
self.const_arg(const_arg);
609624
},
610625
}
611626
},

clippy_utils/src/hir_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl HirEqInterExpr<'_, '_, '_> {
227227
pub fn eq_array_length(&mut self, left: ArrayLen<'_>, right: ArrayLen<'_>) -> bool {
228228
match (left, right) {
229229
(ArrayLen::Infer(..), ArrayLen::Infer(..)) => true,
230-
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_body(l_ct.body, r_ct.body),
230+
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_const_arg(l_ct, r_ct),
231231
(_, _) => false,
232232
}
233233
}
@@ -1129,7 +1129,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
11291129
pub fn hash_array_length(&mut self, length: ArrayLen<'_>) {
11301130
match length {
11311131
ArrayLen::Infer(..) => {},
1132-
ArrayLen::Body(anon_const) => self.hash_body(anon_const.body),
1132+
ArrayLen::Body(ct) => self.hash_const_arg(ct),
11331133
}
11341134
}
11351135

clippy_utils/src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
102102
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
103103
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
104104
use rustc_hir::{
105-
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstContext,
106-
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
107-
ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
108-
PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
109-
TyKind, UnOp,
105+
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind,
106+
ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem,
107+
ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
108+
Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef,
109+
TraitRef, TyKind, UnOp,
110110
};
111111
use rustc_lexer::{tokenize, TokenKind};
112112
use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -904,7 +904,9 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
904904
},
905905
ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
906906
ExprKind::Repeat(x, ArrayLen::Body(len)) => {
907-
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
907+
#[allow(irrefutable_let_patterns)] // FIXME
908+
if let ConstArgKind::Anon(anon_const) = len.kind
909+
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
908910
&& let LitKind::Int(v, _) = const_lit.node
909911
&& v <= 32
910912
&& is_default_equivalent(cx, x)
@@ -933,7 +935,9 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
933935
}) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
934936
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
935937
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
936-
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
938+
#[allow(irrefutable_let_patterns)] // FIXME
939+
if let ConstArgKind::Anon(anon_const) = len.kind
940+
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
937941
&& let LitKind::Int(v, _) = const_lit.node
938942
{
939943
return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec);

0 commit comments

Comments
 (0)