Skip to content

Commit f893f3c

Browse files
committed
Make Clippy understand generic consts
1 parent d1077df commit f893f3c

File tree

10 files changed

+31
-7
lines changed

10 files changed

+31
-7
lines changed

src/tools/clippy/clippy_lints/src/large_const_arrays.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
5050
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
5151
if_chain! {
5252
if !item.span.from_expansion();
53-
if let ItemKind::Const(hir_ty, _) = &item.kind;
53+
if let ItemKind::Const(hir_ty, generics, _) = &item.kind;
54+
// Since static items may not have generics, skip generic consts.
55+
// FIXME(generic_consts): I don't think checking `generics.hwcp` suffices as it doesn't
56+
// account for empty where-clauses that only consist of keyword `where` (IIRC).
57+
if generics.params.is_empty() && !generics.has_where_clause_predicates;
5458
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
5559
if let ty::Array(element_type, cst) = ty.kind();
5660
if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();

src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs

+2
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
284284
if index_used_directly {
285285
self.indexed_directly.insert(
286286
seqvar.segments[0].ident.name,
287+
// FIXME(generic_consts): Do we need to subst anything here or has
288+
// that already been taken care of?
287289
(None, self.cx.typeck_results().node_type(seqexpr.hir_id)),
288290
);
289291
} else {

src/tools/clippy/clippy_lints/src/non_copy_const.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ declare_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTER
286286

287287
impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
288288
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
289-
if let ItemKind::Const(hir_ty, body_id) = it.kind {
289+
if let ItemKind::Const(hir_ty, _generics, body_id) = it.kind {
290+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here like
291+
// replacing params with placeholders or can `is_unfrozen` handle params on its own?
290292
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
291293
if !ignored_macro(cx, it) && is_unfrozen(cx, ty) && is_value_unfrozen_poly(cx, body_id, ty) {
292294
lint(cx, Source::Item { item: it.span });
@@ -295,6 +297,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
295297
}
296298

297299
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
300+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here.
298301
if let TraitItemKind::Const(hir_ty, body_id_opt) = &trait_item.kind {
299302
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
300303

@@ -322,6 +325,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
322325
}
323326

324327
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
328+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here
325329
if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
326330
let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
327331
let item = cx.tcx.hir().expect_item(item_def_id);

src/tools/clippy/clippy_lints/src/types/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ impl<'tcx> LateLintPass<'tcx> for Types {
349349
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
350350

351351
match item.kind {
352-
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => self.check_ty(
352+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here like
353+
// replacing params with placeholders or can relate routines handle params on their own?
354+
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty(
353355
cx,
354356
ty,
355357
CheckTyContext {
@@ -364,6 +366,8 @@ impl<'tcx> LateLintPass<'tcx> for Types {
364366

365367
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
366368
match item.kind {
369+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here like
370+
// replacing params with placeholders or can relate routines handle params on their own?
367371
ImplItemKind::Const(ty, _) => {
368372
let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx
369373
.tcx
@@ -413,6 +417,8 @@ impl<'tcx> LateLintPass<'tcx> for Types {
413417
};
414418

415419
match item.kind {
420+
// FIXME(generic_consts): Not sure if we need to handle generics explicitly here like
421+
// replacing params with placeholders or can relate routines handle params on their own?
416422
TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => {
417423
self.check_ty(cx, ty, context);
418424
},

src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
7777
for def_id in def_path_def_ids(cx, module) {
7878
for item in cx.tcx.module_children(def_id) {
7979
if_chain! {
80+
// FIXME(generic_consts): Shouldn't we subst here now?
8081
if let Res::Def(DefKind::Const, item_def_id) = item.res;
8182
let ty = cx.tcx.type_of(item_def_id).subst_identity();
8283
if match_type(cx, ty, &paths::SYMBOL);

src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
3434
if_chain! {
3535
if mod_name.as_str() == "paths";
3636
if let hir::ItemKind::Const(ty, body_id) = item.kind;
37+
// FIXME(generic_consts): Is this compatible with generic consts?
3738
let ty = hir_ty_to_ty(cx.tcx, ty);
3839
if let ty::Array(el_ty, _) = &ty.kind();
3940
if let ty::Ref(_, el_ty, _) = &el_ty.kind();

src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs

+1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
231231
cx.tcx.eval_static_initializer(def_id).ok()?.inner(),
232232
cx.tcx.type_of(def_id).subst_identity(),
233233
),
234+
// FIXME(generic_consts): Shouldn't we subst here first before `const_eval_poly`?
234235
Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? {
235236
ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => {
236237
read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).subst_identity())

src/tools/clippy/clippy_utils/src/ast_utils.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -301,15 +301,17 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
301301
(
302302
Const(box ast::ConstItem {
303303
defaultness: ld,
304+
generics: lg,
304305
ty: lt,
305306
expr: le,
306307
}),
307308
Const(box ast::ConstItem {
308309
defaultness: rd,
310+
generics: rg,
309311
ty: rt,
310312
expr: re,
311313
}),
312-
) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
314+
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
313315
(
314316
Fn(box ast::Fn {
315317
defaultness: ld,
@@ -476,15 +478,17 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
476478
(
477479
Const(box ast::ConstItem {
478480
defaultness: ld,
481+
generics: lg,
479482
ty: lt,
480483
expr: le,
481484
}),
482485
Const(box ast::ConstItem {
483486
defaultness: rd,
487+
generics: rg,
484488
ty: rt,
485489
expr: re,
486490
}),
487-
) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
491+
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
488492
(
489493
Fn(box ast::Fn {
490494
defaultness: ld,

src/tools/clippy/clippy_utils/src/consts.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
463463
// Check if this constant is based on `cfg!(..)`,
464464
// which is NOT constant for our purposes.
465465
if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id)
466-
&& let Node::Item(Item { kind: ItemKind::Const(_, body_id), .. }) = node
466+
&& let Node::Item(Item { kind: ItemKind::Const(.., body_id), .. }) = node
467467
&& let Node::Expr(Expr { kind: ExprKind::Lit(_), span, .. }) = self.lcx
468468
.tcx
469469
.hir()
@@ -473,6 +473,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
473473
return None;
474474
}
475475

476+
// FIXME(generic_consts): Does this already account for generic consts?
476477
let substs = self.typeck_results.node_substs(id);
477478
let substs = if self.substs.is_empty() {
478479
substs

src/tools/clippy/clippy_utils/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalDefId, f: impl Fn(&[Symbol
23852385
for id in tcx.hir().module_items(module) {
23862386
if matches!(tcx.def_kind(id.owner_id), DefKind::Const)
23872387
&& let item = tcx.hir().item(id)
2388-
&& let ItemKind::Const(ty, _body) = item.kind {
2388+
&& let ItemKind::Const(ty, _generics, _body) = item.kind {
23892389
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
23902390
// We could also check for the type name `test::TestDescAndFn`
23912391
if let Res::Def(DefKind::Struct, _) = path.res {

0 commit comments

Comments
 (0)