From d5cbae90f9e3f323f18d9234b3e55b98c52fed52 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 23 Dec 2021 10:02:05 +0100 Subject: [PATCH] fix clippy --- clippy_lints/src/trailing_empty_array.rs | 1 + clippy_lints/src/utils/author.rs | 11 +++++-- clippy_lints/src/utils/inspector.rs | 9 ++++-- clippy_utils/src/hir_utils.rs | 39 ++++++++++++++++-------- clippy_utils/src/lib.rs | 7 +++-- tests/ui/author/repeat.stdout | 3 +- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/trailing_empty_array.rs b/clippy_lints/src/trailing_empty_array.rs index 47c0a84cd4630..af36f7267004d 100644 --- a/clippy_lints/src/trailing_empty_array.rs +++ b/clippy_lints/src/trailing_empty_array.rs @@ -59,6 +59,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx if let ItemKind::Struct(data, _) = &item.kind; if let Some(last_field) = data.fields().last(); if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind; + if let rustc_hir::ArrayLen::Body(length) = length; // Then check if that that array zero-sized let length_ldid = cx.tcx.hir().local_def_id(length.hir_id); diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index c1b811c217440..9b06ca4e82493 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -6,7 +6,7 @@ use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_ast::LitIntType; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; -use rustc_hir::{ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind}; +use rustc_hir::{ArrayLen, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::{Ident, Symbol}; @@ -567,7 +567,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { bind!(self, value, length); kind!("Repeat({value}, {length})"); self.expr(value); - self.body(field!(length.body)); + match length.value { + ArrayLen::Infer(..) => out!("if let ArrayLen::Infer(..) = length;"), + ArrayLen::Body(anon_const) => { + bind!(self, anon_const); + out!("if let ArrayLen::Body({anon_const}) = {length};"); + self.body(field!(anon_const.body)); + } + } }, ExprKind::Err => kind!("Err"), ExprKind::DropTemps(expr) => { diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index abf4826a06917..c96766e56784f 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -334,12 +334,17 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { println!("{}anon_const:", ind); print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1); }, - hir::ExprKind::Repeat(val, ref anon_const) => { + hir::ExprKind::Repeat(val, length) => { println!("{}Repeat", ind); println!("{}value:", ind); print_expr(cx, val, indent + 1); println!("{}repeat count:", ind); - print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1); + match length { + hir::ArrayLen::Infer(_, _) => println!("{}repeat count: _", ind), + hir::ArrayLen::Body(anon_const) => { + print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1) + } + } }, hir::ExprKind::Err => { println!("{}Err", ind); diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index ad50759effaf8..ac2b1a0259e3e 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -8,7 +8,7 @@ use rustc_hir::HirIdMap; use rustc_hir::{ BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt, - StmtKind, Ty, TyKind, TypeBinding, + StmtKind, Ty, TyKind, TypeBinding, ArrayLen }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; @@ -170,6 +170,14 @@ impl HirEqInterExpr<'_, '_, '_> { } } + pub fn eq_array_length(&mut self, left: ArrayLen, right: ArrayLen) -> bool { + match (left, right) { + (ArrayLen::Infer(..), ArrayLen::Infer(..)) => true, + (ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_body(l_ct.body, r_ct.body), + (_, _) => false, + } + } + pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool { let cx = self.inner.cx; let eval_const = |body| constant_context(cx, cx.tcx.typeck_body(body)).expr(&cx.tcx.hir().body(body).value); @@ -194,8 +202,8 @@ impl HirEqInterExpr<'_, '_, '_> { } let is_eq = match ( - &reduce_exprkind(self.inner.cx, &left.kind), - &reduce_exprkind(self.inner.cx, &right.kind), + reduce_exprkind(self.inner.cx, &left.kind), + reduce_exprkind(self.inner.cx, &right.kind), ) { (&ExprKind::AddrOf(lb, l_mut, le), &ExprKind::AddrOf(rb, r_mut, re)) => { lb == rb && l_mut == r_mut && self.eq_expr(le, re) @@ -232,7 +240,7 @@ impl HirEqInterExpr<'_, '_, '_> { }, (&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri), (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => { - self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r)) + self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r)) }, (&ExprKind::Let(l), &ExprKind::Let(r)) => { self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init) @@ -253,8 +261,8 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::MethodCall(l_path, _, l_args, _), &ExprKind::MethodCall(r_path, _, r_args, _)) => { self.inner.allow_side_effects && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args) }, - (&ExprKind::Repeat(le, ref ll_id), &ExprKind::Repeat(re, ref rl_id)) => { - self.eq_expr(le, re) && self.eq_body(ll_id.body, rl_id.body) + (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => { + self.eq_expr(le, re) && self.eq_array_length(ll, rl) }, (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)), (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r), @@ -391,8 +399,8 @@ impl HirEqInterExpr<'_, '_, '_> { fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool { match (&left.kind, &right.kind) { (&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec), - (&TyKind::Array(lt, ref ll_id), &TyKind::Array(rt, ref rl_id)) => { - self.eq_ty(lt, rt) && self.eq_body(ll_id.body, rl_id.body) + (&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => { + self.eq_ty(lt, rt) && self.eq_array_length(ll, rl) }, (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => { l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty) @@ -714,9 +722,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { ExprKind::ConstBlock(ref l_id) => { self.hash_body(l_id.body); }, - ExprKind::Repeat(e, ref l_id) => { + ExprKind::Repeat(e, len) => { self.hash_expr(e); - self.hash_body(l_id.body); + self.hash_array_length(len); }, ExprKind::Ret(ref e) => { if let Some(e) = *e { @@ -906,9 +914,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { TyKind::Slice(ty) => { self.hash_ty(ty); }, - TyKind::Array(ty, anon_const) => { + &TyKind::Array(ty, len) => { self.hash_ty(ty); - self.hash_body(anon_const.body); + self.hash_array_length(len); }, TyKind::Ptr(ref mut_ty) => { self.hash_ty(mut_ty.ty); @@ -953,6 +961,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } + pub fn hash_array_length(&mut self, length: ArrayLen) { + match length { + ArrayLen::Infer(..) => {} + ArrayLen::Body(anon_const) => self.hash_body(anon_const.body), + } + } + pub fn hash_body(&mut self, body_id: BodyId) { // swap out TypeckResults when hashing a body let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id)); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 7e054a54c3c02..be8558f36ca76 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -75,7 +75,7 @@ use rustc_hir::{ def, Arm, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl, ForeignItem, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, - TraitItemKind, TraitRef, TyKind, UnOp, + TraitItemKind, TraitRef, TyKind, UnOp, ArrayLen }; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::exports::Export; @@ -675,8 +675,9 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { _ => false, }, ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), - ExprKind::Repeat(x, y) => if_chain! { - if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(y.body).value.kind; + ExprKind::Repeat(x, len) => if_chain! { + if let ArrayLen::Body(len) = len; + if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind; if let LitKind::Int(v, _) = const_lit.node; if v <= 32 && is_default_equivalent(cx, x); then { diff --git a/tests/ui/author/repeat.stdout b/tests/ui/author/repeat.stdout index f16350e4b5e6d..471bbce4f4185 100644 --- a/tests/ui/author/repeat.stdout +++ b/tests/ui/author/repeat.stdout @@ -2,7 +2,8 @@ if_chain! { if let ExprKind::Repeat(value, length) = expr.kind; if let ExprKind::Lit(ref lit) = value.kind; if let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node; - let expr1 = &cx.tcx.hir().body(length.body).value; + if let ArrayLen::Body(anon_const) = length; + let expr1 = &cx.tcx.hir().body(anon_const.body).value; if let ExprKind::Lit(ref lit1) = expr1.kind; if let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node; then {