mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 07:04:18 +00:00
Auto merge of #13157 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
37f4fbb929
26 changed files with 112 additions and 76 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_config"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc_middle::ty::{
|
|||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::InferCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
@ -178,7 +178,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
|||
// 'cuz currently nothing changes after deleting this check.
|
||||
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
|
||||
}) {
|
||||
match cx.tcx.infer_ctxt().build().type_implements_fn_trait(
|
||||
match cx.tcx.infer_ctxt().build().err_ctxt().type_implements_fn_trait(
|
||||
cx.param_env,
|
||||
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
|
||||
ty::PredicatePolarity::Positive,
|
||||
|
|
|
@ -16,6 +16,7 @@ use clippy_utils::source::snippet_opt;
|
|||
use clippy_utils::ty::is_must_use_ty;
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{return_ty, trait_ref_of_method};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
|
||||
use core::ops::ControlFlow;
|
||||
|
||||
|
@ -117,11 +118,11 @@ fn check_needless_must_use(
|
|||
// Ignore async functions unless Future::Output type is a must_use type
|
||||
if sig.header.is_async() {
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
if let Some(future_ty) = infcx.get_impl_future_output_ty(return_ty(cx, item_id))
|
||||
if let Some(future_ty) = infcx.err_ctxt().get_impl_future_output_ty(return_ty(cx, item_id))
|
||||
&& !is_must_use_ty(cx, future_ty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
span_lint_and_help(
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
|
|||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
|
@ -56,19 +56,18 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
|
|||
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
|
||||
return;
|
||||
};
|
||||
let inherent_impls = cx
|
||||
.tcx
|
||||
.with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true));
|
||||
|
||||
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
|
||||
impls.len() > 1
|
||||
for (&id, impl_ids) in &impls.inherent_impls {
|
||||
if impl_ids.len() < 2
|
||||
// Check for `#[allow]` on the type definition
|
||||
&& !is_lint_allowed(
|
||||
|| is_lint_allowed(
|
||||
cx,
|
||||
MULTIPLE_INHERENT_IMPL,
|
||||
cx.tcx.local_def_id_to_hir_id(id),
|
||||
)
|
||||
}) {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for impl_id in impl_ids.iter().map(|id| id.expect_local()) {
|
||||
let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity();
|
||||
match type_map.entry(impl_ty) {
|
||||
|
|
|
@ -106,13 +106,12 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
|
|||
///
|
||||
/// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
|
||||
/// correct result.
|
||||
fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
|
||||
let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else {
|
||||
fn repeat_expr_might_be_expanded(expr: &Expr<'_>) -> bool {
|
||||
let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else {
|
||||
return false;
|
||||
};
|
||||
let len_span = cx.tcx.def_span(anon_const.def_id);
|
||||
!expr.span.contains(len_span)
|
||||
!expr.span.contains(len_ct.span())
|
||||
}
|
||||
|
||||
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(cx, expr)
|
||||
expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr)
|
||||
}
|
||||
|
|
|
@ -139,11 +139,11 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
|
|||
return;
|
||||
}
|
||||
|
||||
// `struct Awa<T>(T)`
|
||||
// ^
|
||||
// `struct Array<T, const N: usize>([T; N])`
|
||||
// ^ ^
|
||||
if let Node::PathSegment(path) = node {
|
||||
if let Res::Def(def_kind, ..) = path.res
|
||||
&& let DefKind::TyParam = def_kind
|
||||
&& let DefKind::TyParam | DefKind::ConstParam = def_kind
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -364,8 +364,8 @@ declare_lint_pass!(MiscEarlyLints => [
|
|||
]);
|
||||
|
||||
impl EarlyLintPass for MiscEarlyLints {
|
||||
fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
|
||||
for param in &gen.params {
|
||||
fn check_generics(&mut self, cx: &EarlyContext<'_>, generics: &Generics) {
|
||||
for param in &generics.params {
|
||||
builtin_type_shadow::check(cx, param);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
|
|||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use std::ops::Deref;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -159,7 +160,7 @@ impl NoEffect {
|
|||
// Remove `impl Future<Output = T>` to get `T`
|
||||
if cx.tcx.ty_is_opaque_future(ret_ty)
|
||||
&& let Some(true_ret_ty) =
|
||||
cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty)
|
||||
cx.tcx.infer_ctxt().build().err_ctxt().get_impl_future_output_ty(ret_ty)
|
||||
{
|
||||
ret_ty = true_ret_ty;
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ impl<'tcx> NonCopyConst<'tcx> {
|
|||
|
||||
fn is_value_unfrozen_raw(
|
||||
cx: &LateContext<'tcx>,
|
||||
result: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
|
||||
result: Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
result.map_or_else(
|
||||
|
|
|
@ -394,8 +394,8 @@ fn check_final_expr<'tcx>(
|
|||
|
||||
// Returns may be used to turn an expression into a statement in rustc's AST.
|
||||
// This allows the addition of attributes, like `#[allow]` (See: clippy#9361)
|
||||
// `#[expect(clippy::needless_return)]` needs to be handled separately to
|
||||
// actually fulfill the expectation (clippy::#12998)
|
||||
// `#[expect(clippy::needless_return)]` needs to be handled separatly to
|
||||
// actually fullfil the expectation (clippy::#12998)
|
||||
match cx.tcx.hir().attrs(expr.hir_id) {
|
||||
[] => {},
|
||||
[attr] => {
|
||||
|
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
|
|||
use clippy_utils::has_repr_attr;
|
||||
use rustc_hir::{Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Const;
|
||||
use rustc_middle::ty::{Const, FeedConstTy};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -53,14 +53,14 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
|
||||
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
|
||||
if let ItemKind::Struct(data, _) = &item.kind
|
||||
// First check if last field is an array
|
||||
&& let Some(last_field) = data.fields().last()
|
||||
&& let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind
|
||||
|
||||
// Then check if that array is zero-sized
|
||||
&& let length = Const::from_anon_const(cx.tcx, length.def_id)
|
||||
&& let length = Const::from_const_arg(cx.tcx, length, FeedConstTy::No)
|
||||
&& let length = length.try_eval_target_usize(cx.tcx, cx.param_env)
|
||||
&& let Some(length) = length
|
||||
{
|
||||
|
|
|
@ -104,9 +104,9 @@ impl TraitBounds {
|
|||
impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS, TRAIT_DUPLICATION_IN_BOUNDS]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for TraitBounds {
|
||||
fn check_generics(&mut self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
|
||||
self.check_type_repetition(cx, gen);
|
||||
check_trait_bound_duplication(cx, gen);
|
||||
fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {
|
||||
self.check_type_repetition(cx, generics);
|
||||
check_trait_bound_duplication(cx, generics);
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
|
@ -240,7 +240,7 @@ impl TraitBounds {
|
|||
}
|
||||
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
|
||||
fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {
|
||||
struct SpanlessTy<'cx, 'tcx> {
|
||||
ty: &'tcx Ty<'tcx>,
|
||||
cx: &'cx LateContext<'tcx>,
|
||||
|
@ -260,12 +260,12 @@ impl TraitBounds {
|
|||
}
|
||||
impl Eq for SpanlessTy<'_, '_> {}
|
||||
|
||||
if gen.span.from_expansion() {
|
||||
if generics.span.from_expansion() {
|
||||
return;
|
||||
}
|
||||
let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
for bound in gen.predicates {
|
||||
for bound in generics.predicates {
|
||||
if let WherePredicate::BoundPredicate(ref p) = bound
|
||||
&& p.origin != PredicateOrigin::ImplTrait
|
||||
&& p.bounds.len() as u64 <= self.max_trait_bounds
|
||||
|
@ -303,8 +303,8 @@ impl TraitBounds {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
|
||||
if gen.span.from_expansion() {
|
||||
fn check_trait_bound_duplication(cx: &LateContext<'_>, generics: &'_ Generics<'_>) {
|
||||
if generics.span.from_expansion() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
|
|||
// |
|
||||
// collects each of these where clauses into a set keyed by generic name and comparable trait
|
||||
// eg. (T, Clone)
|
||||
let where_predicates = gen
|
||||
let where_predicates = generics
|
||||
.predicates
|
||||
.iter()
|
||||
.filter_map(|pred| {
|
||||
|
@ -344,7 +344,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
|
|||
// |
|
||||
// compare trait bounds keyed by generic name and comparable trait to collected where
|
||||
// predicates eg. (T, Clone)
|
||||
for predicate in gen.predicates.iter().filter(|pred| !pred.in_where_clause()) {
|
||||
for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) {
|
||||
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
|
||||
&& bound_predicate.origin != PredicateOrigin::ImplTrait
|
||||
&& !bound_predicate.span.from_expansion()
|
||||
|
|
|
@ -57,7 +57,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
|||
bound
|
||||
.bound_generic_params
|
||||
.iter()
|
||||
.any(|gen| matches!(gen.kind, GenericParamKind::Lifetime { .. }))
|
||||
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
||||
});
|
||||
if has_lifetime_parameters {
|
||||
// complex trait bounds like A<'a, 'b>
|
||||
|
|
|
@ -123,7 +123,7 @@ fn remove_all_parens(pat: &mut P<Pat>) {
|
|||
struct Visitor;
|
||||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, pat: &mut P<Pat>) {
|
||||
noop_visit_pat(pat, self);
|
||||
walk_pat(self, pat);
|
||||
let inner = match &mut pat.kind {
|
||||
Paren(i) => mem::replace(&mut i.kind, Wild),
|
||||
_ => return,
|
||||
|
@ -140,7 +140,7 @@ fn insert_necessary_parens(pat: &mut P<Pat>) {
|
|||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, pat: &mut P<Pat>) {
|
||||
use ast::BindingMode;
|
||||
noop_visit_pat(pat, self);
|
||||
walk_pat(self, pat);
|
||||
let target = match &mut pat.kind {
|
||||
// `i @ a | b`, `box a | b`, and `& mut? a | b`.
|
||||
Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p,
|
||||
|
@ -162,7 +162,7 @@ fn unnest_or_patterns(pat: &mut P<Pat>) -> bool {
|
|||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, p: &mut P<Pat>) {
|
||||
// This is a bottom up transformation, so recurse first.
|
||||
noop_visit_pat(p, self);
|
||||
walk_pat(self, p);
|
||||
|
||||
// Don't have an or-pattern? Just quit early on.
|
||||
let Or(alternatives) = &mut p.kind else { return };
|
||||
|
@ -191,7 +191,7 @@ fn unnest_or_patterns(pat: &mut P<Pat>) -> bool {
|
|||
|
||||
// Deal with `Some(Some(0)) | Some(Some(1))`.
|
||||
if this_level_changed {
|
||||
noop_visit_pat(p, self);
|
||||
walk_pat(self, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,9 @@ use clippy_utils::{get_attr, higher};
|
|||
use rustc_ast::ast::{LitFloatType, LitKind};
|
||||
use rustc_ast::LitIntType;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{
|
||||
ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind,
|
||||
QPath, StmtKind, TyKind,
|
||||
self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
|
||||
ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
@ -270,6 +269,21 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn const_arg(&self, const_arg: &Binding<&ConstArg<'_>>) {
|
||||
match const_arg.value.kind {
|
||||
ConstArgKind::Path(ref qpath) => {
|
||||
bind!(self, qpath);
|
||||
chain!(self, "let ConstArgKind::Path(ref {qpath}) = {const_arg}.kind");
|
||||
self.qpath(qpath);
|
||||
},
|
||||
ConstArgKind::Anon(anon_const) => {
|
||||
bind!(self, anon_const);
|
||||
chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind");
|
||||
self.body(field!(anon_const.body));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn lit(&self, lit: &Binding<&Lit>) {
|
||||
let kind = |kind| chain!(self, "let LitKind::{kind} = {lit}.node");
|
||||
macro_rules! kind {
|
||||
|
@ -602,10 +616,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
self.expr(value);
|
||||
match length.value {
|
||||
ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"),
|
||||
ArrayLen::Body(anon_const) => {
|
||||
bind!(self, anon_const);
|
||||
chain!(self, "let ArrayLen::Body({anon_const}) = {length}");
|
||||
self.body(field!(anon_const.body));
|
||||
ArrayLen::Body(const_arg) => {
|
||||
bind!(self, const_arg);
|
||||
chain!(self, "let ArrayLen::Body({const_arg}) = {length}");
|
||||
self.const_arg(const_arg);
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@ use clippy_utils::visitors::for_each_expr_without_closures;
|
|||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{ArrayLen, ExprKind, Node};
|
||||
use rustc_hir::{ArrayLen, ConstArgKind, ExprKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
@ -61,7 +61,8 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects {
|
|||
// the const item depends on `#[cfg]s` and has different values in different compilation
|
||||
// sessions).
|
||||
else if let ExprKind::Repeat(inner_expr, length) = expr.kind
|
||||
&& let ArrayLen::Body(anon_const) = length
|
||||
&& let ArrayLen::Body(const_arg) = length
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& let length_expr = hir_map.body(anon_const.body).value
|
||||
&& !length_expr.span.from_expansion()
|
||||
&& let ExprKind::Lit(literal) = length_expr.kind
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ use rustc_data_structures::fx::FxHasher;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_hir::{
|
||||
ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy,
|
||||
GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField,
|
||||
PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind,
|
||||
ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
|
||||
ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
|
||||
LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
@ -227,7 +227,7 @@ 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),
|
||||
(ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_const_arg(l_ct, r_ct),
|
||||
(_, _) => false,
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
|
||||
fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> bool {
|
||||
match (left, right) {
|
||||
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body),
|
||||
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_const_arg(l, r),
|
||||
(GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),
|
||||
(GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
|
||||
(GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()),
|
||||
|
@ -419,6 +419,17 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn eq_const_arg(&mut self, left: &ConstArg<'_>, right: &ConstArg<'_>) -> bool {
|
||||
match (&left.kind, &right.kind) {
|
||||
(ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p),
|
||||
(ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body),
|
||||
// Use explicit match for now since ConstArg is undergoing flux.
|
||||
(ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) => {
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_lifetime(left: &Lifetime, right: &Lifetime) -> bool {
|
||||
left.res == right.res
|
||||
}
|
||||
|
@ -1123,7 +1134,7 @@ 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),
|
||||
ArrayLen::Body(ct) => self.hash_const_arg(ct),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,12 +1145,19 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
self.maybe_typeck_results = old_maybe_typeck_results;
|
||||
}
|
||||
|
||||
fn hash_const_arg(&mut self, const_arg: &ConstArg<'_>) {
|
||||
match &const_arg.kind {
|
||||
ConstArgKind::Path(path) => self.hash_qpath(path),
|
||||
ConstArgKind::Anon(anon) => self.hash_body(anon.body),
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_generic_args(&mut self, arg_list: &[GenericArg<'_>]) {
|
||||
for arg in arg_list {
|
||||
match *arg {
|
||||
GenericArg::Lifetime(l) => self.hash_lifetime(l),
|
||||
GenericArg::Type(ty) => self.hash_ty(ty),
|
||||
GenericArg::Const(ref ca) => self.hash_body(ca.value.body),
|
||||
GenericArg::Const(ca) => self.hash_const_arg(ca),
|
||||
GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,11 +102,11 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
|||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstContext,
|
||||
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
|
||||
ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
|
||||
PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
|
||||
TyKind, UnOp,
|
||||
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind,
|
||||
ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem,
|
||||
ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
|
||||
Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef,
|
||||
TraitRef, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
|
@ -914,7 +914,8 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
|||
},
|
||||
ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
|
||||
ExprKind::Repeat(x, ArrayLen::Body(len)) => {
|
||||
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
|
||||
if let ConstArgKind::Anon(anon_const) = len.kind
|
||||
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
|
||||
&& let LitKind::Int(v, _) = const_lit.node
|
||||
&& v <= 32
|
||||
&& is_default_equivalent(cx, x)
|
||||
|
@ -943,7 +944,8 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
|
|||
}) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
|
||||
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
|
||||
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
|
||||
if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind
|
||||
if let ConstArgKind::Anon(anon_const) = len.kind
|
||||
&& let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind
|
||||
&& let LitKind::Int(v, _) = const_lit.node
|
||||
{
|
||||
return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "declare_clippy_lint"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2024-07-11"
|
||||
channel = "nightly-2024-07-25"
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
profile = "minimal"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
if let ExprKind::Repeat(value, length) = expr.kind
|
||||
&& let ExprKind::Lit(ref lit) = value.kind
|
||||
&& let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node
|
||||
&& let ArrayLen::Body(anon_const) = length
|
||||
&& let ArrayLen::Body(const_arg) = length
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& expr1 = &cx.tcx.hir().body(anon_const.body).value
|
||||
&& let ExprKind::Lit(ref lit1) = expr1.kind
|
||||
&& let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node
|
||||
|
|
|
@ -3,7 +3,7 @@ error[E0308]: mismatched types
|
|||
|
|
||||
LL | const S: A = B;
|
||||
| ^ expected `A`, found `B`
|
||||
-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
|
||||
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
Loading…
Reference in a new issue