Auto merge of #13157 - flip1995:rustup, r=flip1995

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2024-07-25 16:25:19 +00:00
commit 37f4fbb929
26 changed files with 112 additions and 76 deletions

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -15,7 +15,7 @@
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// '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,

View File

@ -16,6 +16,7 @@
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(

View File

@ -9,7 +9,7 @@
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! {

View File

@ -56,19 +56,18 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
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) {

View File

@ -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)
}

View File

@ -139,11 +139,11 @@ fn visit_id(&mut self, hir_id: HirId) {
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;
}

View File

@ -364,8 +364,8 @@
]);
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);
}
}

View File

@ -15,6 +15,7 @@
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 @@ fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
// 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;
}

View File

@ -234,7 +234,7 @@ fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, t
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(

View File

@ -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] => {

View File

@ -2,7 +2,7 @@
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
}
}
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
{

View File

@ -104,9 +104,9 @@ pub fn new(conf: &'static Conf) -> Self {
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 @@ fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<
}
#[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 @@ fn hash<H: Hasher>(&self, h: &mut H) {
}
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 Eq for SpanlessTy<'_, '_> {}
}
}
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()

View File

@ -57,7 +57,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) {
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>

View File

@ -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 @@ struct Visitor {
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 visit_pat(&mut self, p: &mut P<Pat>) {
// Deal with `Some(Some(0)) | Some(Some(1))`.
if this_level_changed {
noop_visit_pat(p, self);
walk_pat(self, p);
}
}
}

View File

@ -5,10 +5,9 @@
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 @@ fn qpath(&self, qpath: &Binding<&QPath<'_>>) {
}
}
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 @@ macro_rules! kind {
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);
},
}
},

View File

@ -5,7 +5,7 @@
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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &rustc_hir::Expr<'_>) {
// 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

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.81"
version = "0.1.82"
edition = "2021"
publish = false

View File

@ -7,9 +7,9 @@
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 @@ fn should_ignore(&mut self, expr: &Expr<'_>) -> bool {
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 @@ fn eq_expr_field(&mut self, left: &ExprField<'_>, right: &ExprField<'_>) -> bool
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 @@ fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> b
}
}
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 @@ pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
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 @@ pub fn hash_body(&mut self, body_id: BodyId) {
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()),
}
}

View File

@ -102,11 +102,11 @@
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);

View File

@ -1,6 +1,6 @@
[package]
name = "declare_clippy_lint"
version = "0.1.81"
version = "0.1.82"
edition = "2021"
publish = false

View File

@ -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"

View File

@ -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

View File

@ -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