Auto merge of #138761 - flip1995:clippy-subtree-update, r=Manishearth
Clippy subtree update r? `@Manishearth` Cargo.lock update is because of the `ui_test` dependency bump in Clippy.
This commit is contained in:
commit
4f2ee8ca2a
215 changed files with 4612 additions and 1145 deletions
|
|
@ -85,7 +85,7 @@ fn validate_diag(diag: &Diag<'_, impl EmissionGuarantee>) {
|
|||
/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
|
||||
/// highlighted in the displayed warning.
|
||||
///
|
||||
/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
|
||||
/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
|
||||
/// where you would expect it to.
|
||||
/// If it doesn't, you likely need to use [`span_lint_hir`] instead.
|
||||
///
|
||||
|
|
@ -128,7 +128,7 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
|
|||
/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
|
||||
/// highlighted in the displayed warning.
|
||||
///
|
||||
/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
|
||||
/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
|
||||
/// where you would expect it to.
|
||||
/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
|
||||
///
|
||||
|
|
@ -183,7 +183,7 @@ pub fn span_lint_and_help<T: LintContext>(
|
|||
/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
|
||||
/// highlighted in the displayed warning.
|
||||
///
|
||||
/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
|
||||
/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
|
||||
/// where you would expect it to.
|
||||
/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
|
||||
///
|
||||
|
|
@ -241,7 +241,7 @@ pub fn span_lint_and_note<T: LintContext>(
|
|||
/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
|
||||
/// highlighted in the displayed warning.
|
||||
///
|
||||
/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
|
||||
/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
|
||||
/// where you would expect it to.
|
||||
/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
|
||||
pub fn span_lint_and_then<C, S, M, F>(cx: &C, lint: &'static Lint, sp: S, msg: M, f: F)
|
||||
|
|
@ -358,7 +358,7 @@ pub fn span_lint_hir_and_then(
|
|||
/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
|
||||
/// highlighted in the displayed warning.
|
||||
///
|
||||
/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
|
||||
/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
|
||||
/// where you would expect it to.
|
||||
/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
|||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
|
||||
use rustc_hir::{
|
||||
self as hir, Arm, 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,
|
||||
PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind,
|
||||
TraitItemRef, TraitRef, TyKind, UnOp, def,
|
||||
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItem,
|
||||
ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
|
||||
Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitFn, TraitItem,
|
||||
TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, def,
|
||||
};
|
||||
use rustc_lexer::{TokenKind, tokenize};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
|
|
@ -434,7 +434,7 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
|
|||
.map_or(&[][..], |a| a.args)
|
||||
.iter()
|
||||
.filter_map(|a| match a {
|
||||
hir::GenericArg::Type(ty) => Some(ty.as_unambig_ty()),
|
||||
GenericArg::Type(ty) => Some(ty.as_unambig_ty()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
@ -1420,8 +1420,7 @@ pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
|
|||
let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;
|
||||
match cx.tcx.hir_node_by_def_id(parent_id) {
|
||||
Node::Item(item) => item.kind.ident().map(|ident| ident.name),
|
||||
Node::TraitItem(TraitItem { ident, .. })
|
||||
| Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
|
||||
Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -2334,6 +2333,18 @@ pub fn is_expr_final_block_expr(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
|
|||
matches!(tcx.parent_hir_node(expr.hir_id), Node::Block(..))
|
||||
}
|
||||
|
||||
/// Checks if the expression is a temporary value.
|
||||
// This logic is the same as the one used in rustc's `check_named_place_expr function`.
|
||||
// https://github.com/rust-lang/rust/blob/3ed2a10d173d6c2e0232776af338ca7d080b1cd4/compiler/rustc_hir_typeck/src/expr.rs#L482-L499
|
||||
pub fn is_expr_temporary_value(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
!expr.is_place_expr(|base| {
|
||||
cx.typeck_results()
|
||||
.adjustments()
|
||||
.get(base.hir_id)
|
||||
.is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
|
||||
if !is_no_std_crate(cx) {
|
||||
Some("std")
|
||||
|
|
@ -3548,7 +3559,7 @@ pub fn is_block_like(expr: &Expr<'_>) -> bool {
|
|||
pub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool {
|
||||
fn contains_block(expr: &Expr<'_>, is_operand: bool) -> bool {
|
||||
match expr.kind {
|
||||
ExprKind::Binary(_, lhs, _) => contains_block(lhs, true),
|
||||
ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) => contains_block(lhs, true),
|
||||
_ if is_block_like(expr) => is_operand,
|
||||
_ => false,
|
||||
}
|
||||
|
|
@ -3695,3 +3706,21 @@ pub fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Peel `Option<…>` from `hir_ty` as long as the HIR name is `Option` and it corresponds to the
|
||||
/// `core::Option<_>` type.
|
||||
pub fn peel_hir_ty_options<'tcx>(cx: &LateContext<'tcx>, mut hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
|
||||
let Some(option_def_id) = cx.tcx.get_diagnostic_item(sym::Option) else {
|
||||
return hir_ty;
|
||||
};
|
||||
while let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind
|
||||
&& let Some(segment) = path.segments.last()
|
||||
&& segment.ident.name == sym::Option
|
||||
&& let Res::Def(DefKind::Enum, def_id) = segment.res
|
||||
&& def_id == option_def_id
|
||||
&& let [GenericArg::Type(arg_ty)] = segment.args().args
|
||||
{
|
||||
hir_ty = arg_ty.as_unambig_ty();
|
||||
}
|
||||
hir_ty
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ use rustc_index::bit_set::DenseBitSet;
|
|||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{self, Mutability};
|
||||
use rustc_middle::ty::TypeVisitor;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitor};
|
||||
use rustc_mir_dataflow::impls::MaybeStorageLive;
|
||||
use rustc_mir_dataflow::{Analysis, ResultsCursor};
|
||||
use std::borrow::Cow;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ msrv_aliases! {
|
|||
1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
|
||||
1,75,0 { OPTION_AS_SLICE }
|
||||
1,74,0 { REPR_RUST, IO_ERROR_OTHER }
|
||||
1,73,0 { MANUAL_DIV_CEIL }
|
||||
1,73,0 { DIV_CEIL }
|
||||
1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
|
||||
1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
|
||||
1,68,0 { PATH_MAIN_SEPARATOR_STR }
|
||||
|
|
@ -74,6 +74,7 @@ msrv_aliases! {
|
|||
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
|
||||
1,16,0 { STR_REPEAT }
|
||||
1,15,0 { MAYBE_BOUND_IN_WHERE }
|
||||
1,13,0 { QUESTION_MARK_OPERATOR }
|
||||
}
|
||||
|
||||
/// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic
|
||||
|
|
|
|||
|
|
@ -395,24 +395,32 @@ fn check_terminator<'tcx>(
|
|||
|
||||
fn is_stable_const_fn(cx: &LateContext<'_>, def_id: DefId, msrv: Msrv) -> bool {
|
||||
cx.tcx.is_const_fn(def_id)
|
||||
&& cx.tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
|
||||
if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
&& cx
|
||||
.tcx
|
||||
.lookup_const_stability(def_id)
|
||||
.or_else(|| {
|
||||
cx.tcx
|
||||
.trait_of_item(def_id)
|
||||
.and_then(|trait_def_id| cx.tcx.lookup_const_stability(trait_def_id))
|
||||
})
|
||||
.is_none_or(|const_stab| {
|
||||
if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
|
||||
let const_stab_rust_version = match since {
|
||||
StableSince::Version(version) => version,
|
||||
StableSince::Current => RustcVersion::CURRENT,
|
||||
StableSince::Err => return false,
|
||||
};
|
||||
let const_stab_rust_version = match since {
|
||||
StableSince::Version(version) => version,
|
||||
StableSince::Current => RustcVersion::CURRENT,
|
||||
StableSince::Err => return false,
|
||||
};
|
||||
|
||||
msrv.meets(cx, const_stab_rust_version)
|
||||
} else {
|
||||
// Unstable const fn, check if the feature is enabled.
|
||||
cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none()
|
||||
}
|
||||
})
|
||||
msrv.meets(cx, const_stab_rust_version)
|
||||
} else {
|
||||
// Unstable const fn, check if the feature is enabled.
|
||||
cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context};
|
||||
use crate::ty::expr_sig;
|
||||
use crate::{get_parent_expr_for_hir, higher};
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::ast;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
|
||||
|
|
@ -444,7 +444,7 @@ impl<'a> Not for Sugg<'a> {
|
|||
type Output = Sugg<'a>;
|
||||
fn not(self) -> Sugg<'a> {
|
||||
use AssocOp::Binary;
|
||||
use ast::BinOpKind::{Eq, Gt, Ge, Lt, Le, Ne};
|
||||
use ast::BinOpKind::{Eq, Ge, Gt, Le, Lt, Ne};
|
||||
|
||||
if let Sugg::BinOp(op, lhs, rhs) = self {
|
||||
let to_op = match op {
|
||||
|
|
@ -515,10 +515,10 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static>
|
|||
op,
|
||||
AssocOp::Binary(
|
||||
ast::BinOpKind::Add
|
||||
| ast::BinOpKind::Sub
|
||||
| ast::BinOpKind::Mul
|
||||
| ast::BinOpKind::Div
|
||||
| ast::BinOpKind::Rem
|
||||
| ast::BinOpKind::Sub
|
||||
| ast::BinOpKind::Mul
|
||||
| ast::BinOpKind::Div
|
||||
| ast::BinOpKind::Rem
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -578,10 +578,8 @@ enum Associativity {
|
|||
/// associative.
|
||||
#[must_use]
|
||||
fn associativity(op: AssocOp) -> Associativity {
|
||||
use ast::BinOpKind::{Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub};
|
||||
use rustc_ast::util::parser::AssocOp::{Assign, AssignOp, Binary, Cast, Range};
|
||||
use ast::BinOpKind::{
|
||||
Add, BitAnd, BitOr, BitXor, Div, Eq, Gt, Ge, And, Or, Lt, Le, Rem, Mul, Ne, Shl, Shr, Sub,
|
||||
};
|
||||
|
||||
match op {
|
||||
Assign | AssignOp(_) => Associativity::Right,
|
||||
|
|
@ -994,6 +992,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
|
|||
mod test {
|
||||
use super::Sugg;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
|
@ -1011,15 +1010,15 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn binop_maybe_par() {
|
||||
let sugg = Sugg::BinOp(AssocOp::Add, "1".into(), "1".into());
|
||||
let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), "1".into(), "1".into());
|
||||
assert_eq!("(1 + 1)", sugg.maybe_par().to_string());
|
||||
|
||||
let sugg = Sugg::BinOp(AssocOp::Add, "(1 + 1)".into(), "(1 + 1)".into());
|
||||
let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), "(1 + 1)".into(), "(1 + 1)".into());
|
||||
assert_eq!("((1 + 1) + (1 + 1))", sugg.maybe_par().to_string());
|
||||
}
|
||||
#[test]
|
||||
fn not_op() {
|
||||
use AssocOp::{Add, Equal, Greater, GreaterEqual, LAnd, LOr, Less, LessEqual, NotEqual};
|
||||
use ast::BinOpKind::{Add, And, Eq, Ge, Gt, Le, Lt, Ne, Or};
|
||||
|
||||
fn test_not(op: AssocOp, correct: &str) {
|
||||
let sugg = Sugg::BinOp(op, "x".into(), "y".into());
|
||||
|
|
@ -1027,16 +1026,16 @@ mod test {
|
|||
}
|
||||
|
||||
// Invert the comparison operator.
|
||||
test_not(Equal, "x != y");
|
||||
test_not(NotEqual, "x == y");
|
||||
test_not(Less, "x >= y");
|
||||
test_not(LessEqual, "x > y");
|
||||
test_not(Greater, "x <= y");
|
||||
test_not(GreaterEqual, "x < y");
|
||||
test_not(AssocOp::Binary(Eq), "x != y");
|
||||
test_not(AssocOp::Binary(Ne), "x == y");
|
||||
test_not(AssocOp::Binary(Lt), "x >= y");
|
||||
test_not(AssocOp::Binary(Le), "x > y");
|
||||
test_not(AssocOp::Binary(Gt), "x <= y");
|
||||
test_not(AssocOp::Binary(Ge), "x < y");
|
||||
|
||||
// Other operators are inverted like !(..).
|
||||
test_not(Add, "!(x + y)");
|
||||
test_not(LAnd, "!(x && y)");
|
||||
test_not(LOr, "!(x || y)");
|
||||
test_not(AssocOp::Binary(Add), "!(x + y)");
|
||||
test_not(AssocOp::Binary(And), "!(x && y)");
|
||||
test_not(AssocOp::Binary(Or), "!(x || y)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue