commit
1dddeab7c9
113 changed files with 400 additions and 572 deletions
|
|
@ -9,7 +9,11 @@ use rustc_span::sym;
|
|||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||
if let AttrKind::Normal(normal_attr) = &attr.kind {
|
||||
if let AttrArgs::Eq(_, AttrArgsEq::Ast(_)) = &normal_attr.item.args {
|
||||
if let AttrArgs::Eq {
|
||||
value: AttrArgsEq::Ast(_),
|
||||
..
|
||||
} = &normal_attr.item.args
|
||||
{
|
||||
// `#[should_panic = ".."]` found, good
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -747,7 +747,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::unit_types::LET_UNIT_VALUE_INFO,
|
||||
crate::unit_types::UNIT_ARG_INFO,
|
||||
crate::unit_types::UNIT_CMP_INFO,
|
||||
crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
|
||||
crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
|
||||
crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO,
|
||||
crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use clippy_utils::{contains_name, get_parent_expr, in_automatically_derived, is_
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
|
||||
use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
|
|
@ -285,7 +285,7 @@ fn field_reassigned_by_stmt<'tcx>(this: &Stmt<'tcx>, binding_name: Symbol) -> Op
|
|||
/// Returns whether `expr` is the update syntax base: `Foo { a: 1, .. base }`
|
||||
fn is_update_syntax_base<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
|
||||
if let Some(parent) = get_parent_expr(cx, expr)
|
||||
&& let ExprKind::Struct(_, _, Some(base)) = parent.kind
|
||||
&& let ExprKind::Struct(_, _, StructTailExpr::Base(base)) = parent.kind
|
||||
{
|
||||
base.hir_id == expr.hir_id
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use clippy_utils::source::snippet_opt;
|
|||
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr, walk_stmt};
|
||||
use rustc_hir::{Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Stmt, StmtKind};
|
||||
use rustc_hir::{Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Stmt, StmtKind, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
|
||||
|
|
@ -198,7 +198,7 @@ impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> {
|
|||
}
|
||||
|
||||
// Visit base with no bound.
|
||||
if let Some(base) = base {
|
||||
if let StructTailExpr::Base(base) = base {
|
||||
self.ty_bounds.push(ExplicitTyBound(false));
|
||||
self.visit_expr(base);
|
||||
self.ty_bounds.pop();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
|
|||
#[clippy::version = "1.53.0"]
|
||||
("clippy::filter_map", "clippy::manual_filter_map"),
|
||||
#[clippy::version = ""]
|
||||
("clippy::fn_address_comparisons", "unpredictable_function_pointer_comparisons"),
|
||||
#[clippy::version = ""]
|
||||
("clippy::identity_conversion", "clippy::useless_conversion"),
|
||||
#[clippy::version = "pre 1.29.0"]
|
||||
("clippy::if_let_redundant_pattern_matching", "clippy::redundant_pattern_matching"),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use clippy_utils::{
|
|||
peel_middle_ty_refs,
|
||||
};
|
||||
use core::mem;
|
||||
use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS};
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
@ -814,12 +814,13 @@ impl TyCoercionStability {
|
|||
| TyKind::Tup(_)
|
||||
| TyKind::Path(_) => Self::Deref,
|
||||
TyKind::OpaqueDef(..)
|
||||
| TyKind::TraitAscription(..)
|
||||
| TyKind::Infer
|
||||
| TyKind::Typeof(..)
|
||||
| TyKind::TraitObject(..)
|
||||
| TyKind::InferDelegation(..)
|
||||
| TyKind::AnonAdt(..)
|
||||
| TyKind::Err(_) => Self::Reborrow,
|
||||
TyKind::UnsafeBinder(..) => Self::None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -963,7 +964,7 @@ fn report<'tcx>(
|
|||
// expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
|
||||
// `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
|
||||
/*
|
||||
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX {
|
||||
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < ExprPrecedence::Prefix {
|
||||
Cow::Owned(format!("({expr_str})"))
|
||||
} else {
|
||||
expr_str
|
||||
|
|
@ -999,13 +1000,16 @@ fn report<'tcx>(
|
|||
data.first_expr.span,
|
||||
state.msg,
|
||||
|diag| {
|
||||
let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
|
||||
let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
|
||||
Node::Expr(e) => match e.kind {
|
||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
|
||||
ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
|
||||
_ => (e.precedence(), false),
|
||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,
|
||||
ExprKind::Call(..) => {
|
||||
expr.precedence() < ExprPrecedence::Unambiguous
|
||||
|| matches!(expr.kind, ExprKind::Field(..))
|
||||
},
|
||||
_ => expr.precedence() < e.precedence(),
|
||||
},
|
||||
_ => (0, false),
|
||||
_ => false,
|
||||
};
|
||||
let is_in_tuple = matches!(
|
||||
get_parent_expr(cx, data.first_expr),
|
||||
|
|
@ -1015,11 +1019,7 @@ fn report<'tcx>(
|
|||
})
|
||||
);
|
||||
|
||||
let sugg = if !snip_is_macro
|
||||
&& (calls_field || expr.precedence() < precedence)
|
||||
&& !has_enclosing_paren(&snip)
|
||||
&& !is_in_tuple
|
||||
{
|
||||
let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple {
|
||||
format!("({snip})")
|
||||
} else {
|
||||
snip.into()
|
||||
|
|
@ -1049,16 +1049,16 @@ fn report<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let (prefix, precedence) = match mutability {
|
||||
let (prefix, needs_paren) = match mutability {
|
||||
Some(mutability) if !ty.is_ref() => {
|
||||
let prefix = match mutability {
|
||||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
};
|
||||
(prefix, PREC_PREFIX)
|
||||
(prefix, expr.precedence() < ExprPrecedence::Prefix)
|
||||
},
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", 0),
|
||||
_ => ("", 0),
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false),
|
||||
_ => ("", false),
|
||||
};
|
||||
span_lint_hir_and_then(
|
||||
cx,
|
||||
|
|
@ -1070,7 +1070,7 @@ fn report<'tcx>(
|
|||
let mut app = Applicability::MachineApplicable;
|
||||
let (snip, snip_is_macro) =
|
||||
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
|
||||
let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
|
||||
let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) {
|
||||
format!("{prefix}({snip})")
|
||||
} else {
|
||||
format!("{prefix}{snip}")
|
||||
|
|
@ -1157,7 +1157,7 @@ impl<'tcx> Dereferencing<'tcx> {
|
|||
},
|
||||
Some(parent) if !parent.span.from_expansion() => {
|
||||
// Double reference might be needed at this point.
|
||||
if parent.precedence() == PREC_UNAMBIGUOUS {
|
||||
if parent.precedence() == ExprPrecedence::Unambiguous {
|
||||
// Parentheses would be needed here, don't lint.
|
||||
*outer_pat = None;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
|
|||
if !attr.span.from_expansion()
|
||||
&& let AttrKind::Normal(ref normal) = attr.kind
|
||||
&& normal.item.path == sym::doc
|
||||
&& let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
|
||||
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
|
||||
&& !attr.span.contains(meta.span)
|
||||
// Since the `include_str` is already expanded at this point, we can only take the
|
||||
// whole attribute snippet and then modify for our suggestion.
|
||||
|
|
|
|||
|
|
@ -948,11 +948,11 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
);
|
||||
refdefrange.start - range.start
|
||||
} else {
|
||||
let mut start = next_range.start;
|
||||
if start > 0 && doc.as_bytes().get(start - 1) == Some(&b'\\') {
|
||||
// backslashes aren't in the event stream...
|
||||
start -= 1;
|
||||
}
|
||||
let mut start = next_range.start;
|
||||
if start > 0 && doc.as_bytes().get(start - 1) == Some(&b'\\') {
|
||||
// backslashes aren't in the event stream...
|
||||
start -= 1;
|
||||
}
|
||||
start - range.start
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
|
|||
|
||||
impl EarlyLintPass for DuplicateMod {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans)) = &item.kind
|
||||
if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
|
||||
&& let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
|
||||
&& let Some(local_path) = real.into_local_path()
|
||||
&& let Ok(absolute_path) = local_path.canonicalize()
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ impl Visitor<'_> for NestingVisitor<'_, '_> {
|
|||
}
|
||||
|
||||
match &item.kind {
|
||||
ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => {
|
||||
ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _, _)) => {
|
||||
self.nest_level += 1;
|
||||
|
||||
if !self.check_indent(item.span, item.id) {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
|
|||
// match call to write_fmt
|
||||
&& let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)
|
||||
&& let ExprKind::Call(write_recv_path, []) = write_recv.kind
|
||||
&& write_fun.ident.name.as_str() == "write_fmt"
|
||||
&& write_fun.ident.name == sym::write_fmt
|
||||
&& let Some(def_id) = path_def_id(cx, write_recv_path)
|
||||
{
|
||||
// match calls to std::io::stdout() / std::io::stderr ()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use clippy_utils::fulfill_or_allowed;
|
|||
use clippy_utils::source::snippet;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{self as hir, ExprKind};
|
||||
use rustc_hir::{self as hir, ExprKind, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
|
@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
|
|||
}
|
||||
fields_snippet.push_str(&last_ident.to_string());
|
||||
|
||||
let base_snippet = if let Some(base) = base {
|
||||
let base_snippet = if let StructTailExpr::Base(base) = base {
|
||||
format!(", ..{}", snippet(cx, base.span, ".."))
|
||||
} else {
|
||||
String::new()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_hir::{Expr, ExprKind, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::SyntaxContext;
|
||||
|
|
@ -43,7 +43,7 @@ declare_lint_pass!(NumberedFields => [INIT_NUMBERED_FIELDS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for NumberedFields {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Struct(path, fields @ [field, ..], None) = e.kind
|
||||
if let ExprKind::Struct(path, fields @ [field, ..], StructTailExpr::None) = e.kind
|
||||
// If the first character of any field is a digit it has to be a tuple.
|
||||
&& field.ident.as_str().as_bytes().first().is_some_and(u8::is_ascii_digit)
|
||||
// Type aliases can't be used as functions.
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ impl LateLintPass<'_> for LargeIncludeFile {
|
|||
&& let AttrKind::Normal(ref normal) = attr.kind
|
||||
&& let Some(doc) = attr.doc_str()
|
||||
&& doc.as_str().len() as u64 > self.max_file_size
|
||||
&& let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
|
||||
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
|
||||
&& !attr.span.contains(meta.span)
|
||||
// Since the `include_str` is already expanded at this point, we can only take the
|
||||
// whole attribute snippet and then modify for our suggestion.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::macros::macro_backtrace;
|
||||
use clippy_utils::source::snippet;
|
||||
use rustc_hir::{ArrayLen, Expr, ExprKind, Item, ItemKind, Node};
|
||||
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, ConstKind};
|
||||
|
|
@ -118,13 +118,13 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
|
|||
|
||||
/// Only giving help messages if the expr does not contains macro expanded codes.
|
||||
fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
|
||||
/// Check if the span of `ArrayLen` of a repeat expression is within the expr's span,
|
||||
/// Check if the span of `ConstArg` of a repeat expression is within the expr's span,
|
||||
/// if not, meaning this repeat expr is definitely from some proc-macro.
|
||||
///
|
||||
/// 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(expr: &Expr<'_>) -> bool {
|
||||
let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else {
|
||||
let ExprKind::Repeat(_, len_ct) = expr.kind else {
|
||||
return false;
|
||||
};
|
||||
!expr.span.contains(len_ct.span())
|
||||
|
|
|
|||
|
|
@ -366,7 +366,6 @@ mod uninhabited_references;
|
|||
mod uninit_vec;
|
||||
mod unit_return_expecting_ord;
|
||||
mod unit_types;
|
||||
mod unnamed_address;
|
||||
mod unnecessary_box_returns;
|
||||
mod unnecessary_literal_bound;
|
||||
mod unnecessary_map_on_constructor;
|
||||
|
|
@ -789,7 +788,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
|||
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
|
||||
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(conf)));
|
||||
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
|
||||
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
|
||||
store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
|
||||
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
|
||||
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use clippy_utils::higher::ForLoop;
|
|||
use clippy_utils::macros::root_macro_call_first_node;
|
||||
use clippy_utils::source::snippet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
|
||||
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind, StructTailExpr};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{Span, sym};
|
||||
use std::iter::once;
|
||||
|
|
@ -156,7 +156,8 @@ fn never_loop_expr<'tcx>(
|
|||
| ExprKind::Field(e, _)
|
||||
| ExprKind::AddrOf(_, _, e)
|
||||
| ExprKind::Repeat(e, _)
|
||||
| ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id),
|
||||
| ExprKind::DropTemps(e)
|
||||
| ExprKind::UnsafeBinderCast(_, e, _) => never_loop_expr(cx, e, local_labels, main_loop_id),
|
||||
ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),
|
||||
ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),
|
||||
ExprKind::MethodCall(_, receiver, es, _) => {
|
||||
|
|
@ -164,7 +165,7 @@ fn never_loop_expr<'tcx>(
|
|||
},
|
||||
ExprKind::Struct(_, fields, base) => {
|
||||
let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id);
|
||||
if let Some(base) = base {
|
||||
if let StructTailExpr::Base(base) = base {
|
||||
combine_seq(fields, || never_loop_expr(cx, base, local_labels, main_loop_id))
|
||||
} else {
|
||||
fields
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
|||
use clippy_utils::source::{indent_of, snippet, snippet_with_applicability};
|
||||
use clippy_utils::visitors::contains_break_or_continue;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind, is_range_literal};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
|
|||
if !prefix.is_empty()
|
||||
&& (
|
||||
// Precedence of internal expression is less than or equal to precedence of `&expr`.
|
||||
arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression)
|
||||
arg_expression.precedence() <= ExprPrecedence::Prefix || is_range_literal(arg_expression)
|
||||
)
|
||||
{
|
||||
arg_snip = format!("({arg_snip})").into();
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ use clippy_utils::msrvs::{self, Msrv};
|
|||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::{is_from_proc_macro, path_to_local};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::impl_lint_pass;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
@ -94,6 +97,42 @@ impl ManualFloatMethods {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::Macro(..)
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::SyntheticCoroutineBody
|
||||
| DefKind::TyParam => true,
|
||||
|
||||
DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::Const
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Static { .. }
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::AssocConst => false,
|
||||
|
||||
DefKind::Fn | DefKind::AssocFn | DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
||||
|
|
@ -105,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
|||
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||
&& !in_external_macro(cx.sess(), expr.span)
|
||||
&& (
|
||||
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
||||
is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
|
||||
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
|
||||
)
|
||||
&& let [first, second, const_1, const_2] = exprs
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use clippy_utils::{
|
|||
CaptureKind, can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res,
|
||||
path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,
|
||||
};
|
||||
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::def::Res;
|
||||
|
|
@ -117,7 +117,7 @@ where
|
|||
// it's being passed by value.
|
||||
let scrutinee = peel_hir_expr_refs(scrutinee).0;
|
||||
let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
|
||||
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS {
|
||||
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < ExprPrecedence::Unambiguous {
|
||||
format!("({scrutinee_str})")
|
||||
} else {
|
||||
scrutinee_str.into()
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
|
|||
_ => {},
|
||||
}
|
||||
}
|
||||
requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
|
||||
requires_copy |= !cx.type_is_copy_modulo_regions(ty);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
|
@ -158,7 +158,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
|
|||
}
|
||||
|
||||
if can_lint
|
||||
&& (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()))
|
||||
&& (!requires_copy || cx.type_is_copy_modulo_regions(arg_ty))
|
||||
// This case could be handled, but a fair bit of care would need to be taken.
|
||||
&& (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
|||
use clippy_utils::ty::is_copy;
|
||||
use clippy_utils::usage::mutated_variables;
|
||||
use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
|
||||
use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
|
||||
use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::sym;
|
||||
|
||||
|
|
@ -44,7 +43,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
|
|||
if name == "filter_map"
|
||||
&& let hir::ExprKind::Call(expr, args) = body.value.kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
|
||||
&& arg_id.ty_def_id() == args[0].hir_id().ty_def_id()
|
||||
&& let hir::ExprKind::Path(_) = args[0].kind
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||
cx.param_env,
|
||||
ty,
|
||||
traits::ObligationCause::dummy_with_span(span),
|
||||
rustc_hir::Safety::Safe,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_hir::{Expr, ExprKind, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -51,7 +51,7 @@ declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Struct(_, fields, Some(base)) = expr.kind {
|
||||
if let ExprKind::Struct(_, fields, StructTailExpr::Base(base)) = expr.kind {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if let ty::Adt(def, _) = ty.kind() {
|
||||
if fields.len() == def.non_enum_variant().fields.len()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_utils::consts::{self, Constant};
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sugg::has_enclosing_paren;
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
|
|||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
|
||||
let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) {
|
||||
let suggestion = if !from_macro && exp.precedence() < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
|
||||
format!("-({snip})")
|
||||
} else {
|
||||
format!("-{snip}")
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{
|
||||
BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind,
|
||||
UnsafeSource, is_range_literal,
|
||||
StructTailExpr, UnsafeSource, is_range_literal,
|
||||
};
|
||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
|
|
@ -238,7 +238,10 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
ExprKind::Struct(_, fields, ref base) => {
|
||||
!has_drop(cx, cx.typeck_results().expr_ty(expr))
|
||||
&& fields.iter().all(|field| has_no_effect(cx, field.expr))
|
||||
&& base.as_ref().is_none_or(|base| has_no_effect(cx, base))
|
||||
&& match &base {
|
||||
StructTailExpr::None | StructTailExpr::DefaultFields(_) => true,
|
||||
StructTailExpr::Base(base) => has_no_effect(cx, base),
|
||||
}
|
||||
},
|
||||
ExprKind::Call(callee, args) => {
|
||||
if let ExprKind::Path(ref qpath) = callee.kind {
|
||||
|
|
@ -342,6 +345,10 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
|
|||
if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
|
||||
None
|
||||
} else {
|
||||
let base = match base {
|
||||
StructTailExpr::Base(base) => Some(base),
|
||||
StructTailExpr::None | StructTailExpr::DefaultFields(_) => None,
|
||||
};
|
||||
Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect())
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_hir::{
|
|||
BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId, ReportedErrorInfo};
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::impl_lint_pass;
|
||||
|
|
@ -302,7 +302,10 @@ impl<'tcx> NonCopyConst<'tcx> {
|
|||
tcx.const_eval_global_id_for_typeck(typing_env, cid, span)
|
||||
},
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span)),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span)),
|
||||
Err(err) => Err(ErrorHandled::Reported(
|
||||
ReportedErrorInfo::non_const_eval_error(err),
|
||||
span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
|
|||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
|
||||
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
|
||||
let by_ref = !cx.type_is_copy_modulo_regions(caller_ty)
|
||||
&& !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
|
||||
let sugg = if let Some(else_inner) = r#else {
|
||||
if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{get_parent_expr, peel_middle_ty_refs};
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
|
|
@ -85,7 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
|||
let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
|
||||
let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
|
||||
let parent_expr = get_parent_expr(cx, expr);
|
||||
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX);
|
||||
let needs_parens_for_prefix =
|
||||
parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix);
|
||||
|
||||
if expr_ty == indexed_ty {
|
||||
if expr_ref_count > indexed_ref_count {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use clippy_utils::source::SpanRangeExt;
|
|||
use clippy_utils::ty::implements_trait;
|
||||
use rustc_ast::{LitIntType, LitKind, UintTy};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, QPath};
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, QPath, StructTailExpr};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
|
@ -86,7 +86,8 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
|
|||
return;
|
||||
};
|
||||
|
||||
let ExprKind::Struct(QPath::LangItem(lang_item, ..), [start, end], None) = inner_expr.kind else {
|
||||
let ExprKind::Struct(QPath::LangItem(lang_item, ..), [start, end], StructTailExpr::None) = inner_expr.kind
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, Node};
|
||||
use rustc_hir_typeck::cast::check_cast;
|
||||
|
|
@ -44,8 +44,7 @@ pub(super) fn check<'tcx>(
|
|||
};
|
||||
|
||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
|
||||
&& parent.precedence()
|
||||
> i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128")
|
||||
&& parent.precedence() > ExprPrecedence::Cast
|
||||
{
|
||||
sugg = format!("({sugg})");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for comparisons with an address of a function item.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Function item address is not guaranteed to be unique and could vary
|
||||
/// between different code generation units. Furthermore different function items could have
|
||||
/// the same address after being merged together.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// type F = fn();
|
||||
/// fn a() {}
|
||||
/// let f: F = a;
|
||||
/// if f == a {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.44.0"]
|
||||
pub FN_ADDRESS_COMPARISONS,
|
||||
correctness,
|
||||
"comparison with an address of a function item"
|
||||
}
|
||||
|
||||
declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS]);
|
||||
|
||||
impl LateLintPass<'_> for UnnamedAddress {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
fn is_comparison(binop: BinOpKind) -> bool {
|
||||
matches!(
|
||||
binop,
|
||||
BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt
|
||||
)
|
||||
}
|
||||
|
||||
fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
matches!(cx.typeck_results().expr_ty(expr).kind(), ty::FnDef(..))
|
||||
}
|
||||
|
||||
if let ExprKind::Binary(binop, left, right) = expr.kind
|
||||
&& is_comparison(binop.node)
|
||||
&& cx.typeck_results().expr_ty_adjusted(left).is_fn_ptr()
|
||||
&& cx.typeck_results().expr_ty_adjusted(right).is_fn_ptr()
|
||||
&& (is_fn_def(cx, left) || is_fn_def(cx, right))
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
FN_ADDRESS_COMPARISONS,
|
||||
expr.span,
|
||||
"comparing with a non-unique address of a function item",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
|||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_copy;
|
||||
use clippy_utils::{get_parent_expr, path_to_local};
|
||||
use rustc_hir::{BindingMode, Expr, ExprField, ExprKind, Node, PatKind, Path, QPath, UnOp};
|
||||
use rustc_hir::{BindingMode, Expr, ExprField, ExprKind, Node, PatKind, Path, QPath, StructTailExpr, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
||||
|
|
@ -59,15 +59,17 @@ impl LateLintPass<'_> for UnnecessaryStruct {
|
|||
let field_path = same_path_in_all_fields(cx, expr, fields);
|
||||
|
||||
let sugg = match (field_path, base) {
|
||||
(Some(&path), None) => {
|
||||
(Some(&path), StructTailExpr::None | StructTailExpr::DefaultFields(_)) => {
|
||||
// all fields match, no base given
|
||||
path.span
|
||||
},
|
||||
(Some(path), Some(base)) if base_is_suitable(cx, expr, base) && path_matches_base(path, base) => {
|
||||
(Some(path), StructTailExpr::Base(base))
|
||||
if base_is_suitable(cx, expr, base) && path_matches_base(path, base) =>
|
||||
{
|
||||
// all fields match, has base: ensure that the path of the base matches
|
||||
base.span
|
||||
},
|
||||
(None, Some(base)) if fields.is_empty() && base_is_suitable(cx, expr, base) => {
|
||||
(None, StructTailExpr::Base(base)) if fields.is_empty() && base_is_suitable(cx, expr, base) => {
|
||||
// just the base, no explicit fields
|
||||
base.span
|
||||
},
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
|
|||
// In the case of only two patterns, replacement adds net characters.
|
||||
| Ref(_, Mutability::Not)
|
||||
// Dealt with elsewhere.
|
||||
| Or(_) | Paren(_) | Deref(_) => false,
|
||||
| Or(_) | Paren(_) | Deref(_) | Guard(..) => false,
|
||||
// Transform `box x | ... | box y` into `box (x | y)`.
|
||||
//
|
||||
// The cases below until `Slice(...)` deal with *singleton* products.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
|||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
@ -422,14 +422,7 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME: Add ControlFlow diagnostic item
|
||||
let def_path = cx.get_def_path(recv_ty_defid);
|
||||
if def_path
|
||||
.iter()
|
||||
.map(Symbol::as_str)
|
||||
.zip(["core", "ops", "control_flow", "ControlFlow"])
|
||||
.all(|(sym, s)| sym == s)
|
||||
{
|
||||
if cx.tcx.is_diagnostic_item(sym::ControlFlow, recv_ty_defid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use rustc_ast::LitIntType;
|
|||
use rustc_ast::ast::{LitFloatType, LitKind};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::{
|
||||
self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
|
||||
ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
|
||||
self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind, ExprKind,
|
||||
FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, StructTailExpr, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -278,6 +278,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind");
|
||||
self.body(field!(anon_const.body));
|
||||
},
|
||||
ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +598,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
},
|
||||
ExprKind::Struct(qpath, fields, base) => {
|
||||
bind!(self, qpath, fields);
|
||||
opt_bind!(self, base);
|
||||
let base = OptionPat::new(match base {
|
||||
StructTailExpr::Base(base) => Some(self.bind("base", base)),
|
||||
StructTailExpr::None | StructTailExpr::DefaultFields(_) => None,
|
||||
});
|
||||
kind!("Struct({qpath}, {fields}, {base})");
|
||||
self.qpath(qpath);
|
||||
self.slice(fields, |field| {
|
||||
|
|
@ -611,14 +615,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
bind!(self, value, length);
|
||||
kind!("Repeat({value}, {length})");
|
||||
self.expr(value);
|
||||
match length.value {
|
||||
ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"),
|
||||
ArrayLen::Body(const_arg) => {
|
||||
bind!(self, const_arg);
|
||||
chain!(self, "let ArrayLen::Body({const_arg}) = {length}");
|
||||
self.const_arg(const_arg);
|
||||
},
|
||||
}
|
||||
self.const_arg(length);
|
||||
},
|
||||
ExprKind::Err(_) => kind!("Err(_)"),
|
||||
ExprKind::DropTemps(expr) => {
|
||||
|
|
@ -626,6 +623,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
kind!("DropTemps({expr})");
|
||||
self.expr(expr);
|
||||
},
|
||||
ExprKind::UnsafeBinderCast(..) => {
|
||||
unimplemented!("unsafe binders are not implemented yet");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
|
|||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Call(func, [arg]) = &expr.kind
|
||||
&& let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(func).kind()
|
||||
&& match_def_path(cx, *def_id, &paths::SYMBOL_INTERN)
|
||||
&& cx.tcx.is_diagnostic_item(sym::SymbolIntern, *def_id)
|
||||
&& let Some(Constant::Str(arg)) = ConstEvalCtxt::new(cx).eval_simple(arg)
|
||||
&& let value = Symbol::intern(&arg).as_u32()
|
||||
&& let Some(&def_id) = self.symbol_map.get(&value)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::paths;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::match_type;
|
||||
use clippy_utils::{match_function_call, paths};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -34,7 +34,12 @@ fn check_slow_comparison<'tcx>(
|
|||
op2: &'tcx Expr<'tcx>,
|
||||
) -> Option<(Span, String)> {
|
||||
if match_type(cx, cx.typeck_results().expr_ty(op1), &paths::SYMBOL)
|
||||
&& let Some([symbol_name_expr]) = match_function_call(cx, op2, &paths::SYMBOL_INTERN)
|
||||
&& let ExprKind::Call(fun, args) = op2.kind
|
||||
&& let ExprKind::Path(ref qpath) = fun.kind
|
||||
&& cx
|
||||
.tcx
|
||||
.is_diagnostic_item(sym::SymbolIntern, cx.qpath_res(qpath, fun.hir_id).opt_def_id()?)
|
||||
&& let [symbol_name_expr] = args
|
||||
&& let Some(Constant::Str(symbol_name)) = ConstEvalCtxt::new(cx).eval_simple(symbol_name_expr)
|
||||
{
|
||||
Some((op1.span, symbol_name))
|
||||
|
|
|
|||
|
|
@ -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, ConstArgKind, ExprKind, Node};
|
||||
use rustc_hir::{ConstArgKind, ExprKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -60,8 +60,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects {
|
|||
// doesn't seem as confusing as `[f(); 0]`. It would also have false positives when eg.
|
||||
// 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(const_arg) = length
|
||||
else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& let length_expr = hir_map.body(anon_const.body).value
|
||||
&& !length_expr.span.from_expansion()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
|
|||
|
||||
<!-- begin autogenerated nightly -->
|
||||
```
|
||||
nightly-2024-11-28
|
||||
nightly-2024-12-15
|
||||
```
|
||||
<!-- end autogenerated nightly -->
|
||||
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
(Mod(lu, lmk), Mod(ru, rmk)) => {
|
||||
lu == ru
|
||||
&& match (lmk, rmk) {
|
||||
(ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => {
|
||||
(ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
|
||||
linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))
|
||||
},
|
||||
(ModKind::Unloaded, ModKind::Unloaded) => true,
|
||||
|
|
@ -872,8 +872,26 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
|
|||
match (l, r) {
|
||||
(Empty, Empty) => true,
|
||||
(Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),
|
||||
(Eq(_, AttrArgsEq::Ast(le)), Eq(_, AttrArgsEq::Ast(re))) => eq_expr(le, re),
|
||||
(Eq(_, AttrArgsEq::Hir(ll)), Eq(_, AttrArgsEq::Hir(rl))) => ll.kind == rl.kind,
|
||||
(
|
||||
Eq {
|
||||
value: AttrArgsEq::Ast(le),
|
||||
..
|
||||
},
|
||||
Eq {
|
||||
value: AttrArgsEq::Ast(re),
|
||||
..
|
||||
},
|
||||
) => eq_expr(le, re),
|
||||
(
|
||||
Eq {
|
||||
value: AttrArgsEq::Hir(ll),
|
||||
..
|
||||
},
|
||||
Eq {
|
||||
value: AttrArgsEq::Hir(rl),
|
||||
..
|
||||
},
|
||||
) => ll.kind == rl.kind,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,7 +303,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
|||
| ExprKind::AddrOf(..)
|
||||
| ExprKind::Repeat(..)
|
||||
| ExprKind::Block(Block { stmts: [], .. }, _)
|
||||
| ExprKind::OffsetOf(..) => (),
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::UnsafeBinderCast(..) => (),
|
||||
|
||||
// Assignment might be to a local defined earlier, so don't eagerly evaluate.
|
||||
// Blocks with multiple statements might be expensive, so don't eagerly evaluate.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::ty::is_type_diagnostic_item;
|
|||
|
||||
use rustc_ast::ast;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath};
|
||||
use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StructTailExpr};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{Span, sym, symbol};
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ impl<'a> Range<'a> {
|
|||
limits: ast::RangeLimits::Closed,
|
||||
})
|
||||
},
|
||||
ExprKind::Struct(path, fields, None) => match (path, fields) {
|
||||
ExprKind::Struct(path, fields, StructTailExpr::None) => match (path, fields) {
|
||||
(QPath::LangItem(hir::LangItem::RangeFull, ..), []) => Some(Range {
|
||||
start: None,
|
||||
end: None,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ use rustc_data_structures::fx::FxHasher;
|
|||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{
|
||||
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, TraitBoundModifiers, Ty,
|
||||
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, StructTailExpr, TraitBoundModifiers, Ty,
|
||||
TyKind,
|
||||
};
|
||||
use rustc_lexer::{TokenKind, tokenize};
|
||||
|
|
@ -266,14 +266,6 @@ 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_const_arg(l_ct, r_ct),
|
||||
(_, _) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {
|
||||
// swap out TypeckResults when hashing a body
|
||||
let old_maybe_typeck_results = self.inner.maybe_typeck_results.replace((
|
||||
|
|
@ -378,17 +370,26 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
&& self.eq_expr(l_receiver, r_receiver)
|
||||
&& self.eq_exprs(l_args, r_args)
|
||||
},
|
||||
(&ExprKind::UnsafeBinderCast(lkind, le, None), &ExprKind::UnsafeBinderCast(rkind, re, None)) =>
|
||||
lkind == rkind && self.eq_expr(le, re),
|
||||
(&ExprKind::UnsafeBinderCast(lkind, le, Some(lt)), &ExprKind::UnsafeBinderCast(rkind, re, Some(rt))) =>
|
||||
lkind == rkind && self.eq_expr(le, re) && self.eq_ty(lt, rt),
|
||||
(&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => {
|
||||
self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name)
|
||||
},
|
||||
(ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
|
||||
self.eq_expr(le, re) && self.eq_const_arg(ll, rl)
|
||||
},
|
||||
(ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)),
|
||||
(&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
|
||||
self.eq_qpath(l_path, r_path)
|
||||
&& both(lo.as_ref(), ro.as_ref(), |l, r| self.eq_expr(l, r))
|
||||
&& match (lo, ro) {
|
||||
(StructTailExpr::Base(l),StructTailExpr::Base(r)) => self.eq_expr(l, r),
|
||||
(StructTailExpr::None, StructTailExpr::None) |
|
||||
(StructTailExpr::DefaultFields(_), StructTailExpr::DefaultFields(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
&& over(lf, rf, |l, r| self.eq_expr_field(l, r))
|
||||
},
|
||||
(&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup),
|
||||
|
|
@ -427,6 +428,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
| &ExprKind::Type(..)
|
||||
| &ExprKind::Unary(..)
|
||||
| &ExprKind::Yield(..)
|
||||
| &ExprKind::UnsafeBinderCast(..)
|
||||
|
||||
// --- Special cases that do not have a positive branch.
|
||||
|
||||
|
|
@ -469,10 +471,12 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
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),
|
||||
(ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true,
|
||||
// Use explicit match for now since ConstArg is undergoing flux.
|
||||
(ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) => {
|
||||
false
|
||||
},
|
||||
(ConstArgKind::Path(..), ConstArgKind::Anon(..))
|
||||
| (ConstArgKind::Anon(..), ConstArgKind::Path(..))
|
||||
| (ConstArgKind::Infer(..), _)
|
||||
| (_, ConstArgKind::Infer(..)) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -589,7 +593,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
pub 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, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
|
||||
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_const_arg(ll, rl),
|
||||
(TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
|
||||
(TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => {
|
||||
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
|
||||
|
|
@ -597,7 +601,6 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
|
||||
(&TyKind::Infer, &TyKind::Infer) => true,
|
||||
(TyKind::AnonAdt(l_item_id), TyKind::AnonAdt(r_item_id)) => l_item_id == r_item_id,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -1008,7 +1011,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
},
|
||||
ExprKind::Repeat(e, len) => {
|
||||
self.hash_expr(e);
|
||||
self.hash_array_length(len);
|
||||
self.hash_const_arg(len);
|
||||
},
|
||||
ExprKind::Ret(ref e) => {
|
||||
if let Some(e) = *e {
|
||||
|
|
@ -1023,7 +1026,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(f.expr);
|
||||
}
|
||||
|
||||
if let Some(e) = *expr {
|
||||
if let StructTailExpr::Base(e) = *expr {
|
||||
self.hash_expr(e);
|
||||
}
|
||||
},
|
||||
|
|
@ -1034,6 +1037,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
std::mem::discriminant(&lop).hash(&mut self.s);
|
||||
self.hash_expr(le);
|
||||
},
|
||||
ExprKind::UnsafeBinderCast(kind, expr, ty) => {
|
||||
std::mem::discriminant(&kind).hash(&mut self.s);
|
||||
self.hash_expr(expr);
|
||||
if let Some(ty) = ty {
|
||||
self.hash_ty(ty);
|
||||
}
|
||||
},
|
||||
ExprKind::Err(_) => {},
|
||||
}
|
||||
}
|
||||
|
|
@ -1201,7 +1211,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
},
|
||||
&TyKind::Array(ty, len) => {
|
||||
self.hash_ty(ty);
|
||||
self.hash_array_length(len);
|
||||
self.hash_const_arg(len);
|
||||
},
|
||||
TyKind::Pat(ty, pat) => {
|
||||
self.hash_ty(ty);
|
||||
|
|
@ -1243,19 +1253,15 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
TyKind::Typeof(anon_const) => {
|
||||
self.hash_body(anon_const.body);
|
||||
},
|
||||
TyKind::UnsafeBinder(binder) => {
|
||||
self.hash_ty(binder.inner_ty);
|
||||
},
|
||||
TyKind::Err(_)
|
||||
| TyKind::Infer
|
||||
| TyKind::Never
|
||||
| TyKind::InferDelegation(..)
|
||||
| TyKind::OpaqueDef(_)
|
||||
| TyKind::AnonAdt(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_array_length(&mut self, length: ArrayLen<'_>) {
|
||||
match length {
|
||||
ArrayLen::Infer(..) => {},
|
||||
ArrayLen::Body(ct) => self.hash_const_arg(ct),
|
||||
| TyKind::TraitAscription(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1270,6 +1276,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
match &const_arg.kind {
|
||||
ConstArgKind::Path(path) => self.hash_qpath(path),
|
||||
ConstArgKind::Anon(anon) => self.hash_body(anon.body),
|
||||
ConstArgKind::Infer(..) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ use rustc_hir::definitions::{DefPath, DefPathData};
|
|||
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
||||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
|
||||
use rustc_hir::{
|
||||
self as hir, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
|
||||
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,
|
||||
PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
|
||||
|
|
@ -910,7 +910,7 @@ 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, ArrayLen::Body(len)) => {
|
||||
ExprKind::Repeat(x, len) => {
|
||||
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
|
||||
|
|
@ -940,7 +940,7 @@ 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)) => {
|
||||
ExprKind::Repeat(_, len) => {
|
||||
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
|
||||
|
|
@ -1949,43 +1949,6 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
/// Matches a function call with the given path and returns the arguments.
|
||||
///
|
||||
/// Usage:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// if let Some(args) = match_function_call(cx, cmp_max_call, &paths::CMP_MAX);
|
||||
/// ```
|
||||
/// This function is deprecated. Use [`match_function_call_with_def_id`].
|
||||
pub fn match_function_call<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx Expr<'_>,
|
||||
path: &[&str],
|
||||
) -> Option<&'tcx [Expr<'tcx>]> {
|
||||
if let ExprKind::Call(fun, args) = expr.kind
|
||||
&& let ExprKind::Path(ref qpath) = fun.kind
|
||||
&& let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
|
||||
&& match_def_path(cx, fun_def_id, path)
|
||||
{
|
||||
return Some(args);
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
pub fn match_function_call_with_def_id<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx Expr<'_>,
|
||||
fun_def_id: DefId,
|
||||
) -> Option<&'tcx [Expr<'tcx>]> {
|
||||
if let ExprKind::Call(fun, args) = expr.kind
|
||||
&& let ExprKind::Path(ref qpath) = fun.kind
|
||||
&& cx.qpath_res(qpath, fun.hir_id).opt_def_id() == Some(fun_def_id)
|
||||
{
|
||||
return Some(args);
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
/// Checks if the given `DefId` matches any of the paths. Returns the index of matching path, if
|
||||
/// any.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use super::possible_origin::PossibleOriginVisitor;
|
|||
use super::transitive_relation::TransitiveRelation;
|
||||
use crate::ty::is_copy;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::bit_set::{BitSet, HybridBitSet};
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{self, Mutability};
|
||||
|
|
@ -21,14 +21,14 @@ struct PossibleBorrowerVisitor<'a, 'b, 'tcx> {
|
|||
possible_borrower: TransitiveRelation,
|
||||
body: &'b mir::Body<'tcx>,
|
||||
cx: &'a LateContext<'tcx>,
|
||||
possible_origin: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
|
||||
possible_origin: FxHashMap<mir::Local, BitSet<mir::Local>>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {
|
||||
fn new(
|
||||
cx: &'a LateContext<'tcx>,
|
||||
body: &'b mir::Body<'tcx>,
|
||||
possible_origin: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
|
||||
possible_origin: FxHashMap<mir::Local, BitSet<mir::Local>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
possible_borrower: TransitiveRelation::default(),
|
||||
|
|
@ -119,7 +119,7 @@ impl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> {
|
|||
let mut mutable_variables: Vec<mir::Local> = mutable_borrowers
|
||||
.iter()
|
||||
.filter_map(|r| self.possible_origin.get(r))
|
||||
.flat_map(HybridBitSet::iter)
|
||||
.flat_map(BitSet::iter)
|
||||
.collect();
|
||||
|
||||
if ContainsRegion.visit_ty(self.body.local_decls[*dest].ty).is_break() {
|
||||
|
|
@ -171,7 +171,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
|
|||
#[allow(clippy::module_name_repetitions)]
|
||||
pub struct PossibleBorrowerMap<'b, 'tcx> {
|
||||
/// Mapping `Local -> its possible borrowers`
|
||||
pub map: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
|
||||
pub map: FxHashMap<mir::Local, BitSet<mir::Local>>,
|
||||
maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>,
|
||||
// Caches to avoid allocation of `BitSet` on every query
|
||||
pub bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::transitive_relation::TransitiveRelation;
|
||||
use crate::ty::is_copy;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::bit_set::HybridBitSet;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir;
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap<mir::Local, HybridBitSet<mir::Local>> {
|
||||
pub fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap<mir::Local, BitSet<mir::Local>> {
|
||||
let mut map = FxHashMap::default();
|
||||
for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {
|
||||
if is_copy(cx, self.body.local_decls[row].ty) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::bit_set::HybridBitSet;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir;
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -12,8 +12,8 @@ impl TransitiveRelation {
|
|||
self.relations.entry(a).or_default().push(b);
|
||||
}
|
||||
|
||||
pub fn reachable_from(&self, a: mir::Local, domain_size: usize) -> HybridBitSet<mir::Local> {
|
||||
let mut seen = HybridBitSet::new_empty(domain_size);
|
||||
pub fn reachable_from(&self, a: mir::Local, domain_size: usize) -> BitSet<mir::Local> {
|
||||
let mut seen = BitSet::new_empty(domain_size);
|
||||
let mut stack = vec![a];
|
||||
while let Some(u) = stack.pop() {
|
||||
if let Some(edges) = self.relations.get(&u) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
|
|||
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
|
||||
pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
|
||||
pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
|
||||
pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
|
||||
pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
|
||||
pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
|
||||
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
|
||||
|
|
|
|||
|
|
@ -151,7 +151,8 @@ impl<'a> Sugg<'a> {
|
|||
| ExprKind::Become(..)
|
||||
| ExprKind::Struct(..)
|
||||
| ExprKind::Tup(..)
|
||||
| ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
|
||||
| ExprKind::Err(_)
|
||||
| ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(get_snippet(expr.span)),
|
||||
ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
|
||||
ExprKind::Assign(lhs, rhs, _) => {
|
||||
Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
|
||||
|
|
@ -226,7 +227,8 @@ impl<'a> Sugg<'a> {
|
|||
| ast::ExprKind::While(..)
|
||||
| ast::ExprKind::Await(..)
|
||||
| ast::ExprKind::Err(_)
|
||||
| ast::ExprKind::Dummy => Sugg::NonParen(snippet(expr.span)),
|
||||
| ast::ExprKind::Dummy
|
||||
| ast::ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(snippet(expr.span)),
|
||||
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
|
||||
AssocOp::DotDot,
|
||||
lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pub use type_certainty::expr_type_is_certain;
|
|||
|
||||
/// Checks if the given type implements copy.
|
||||
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty.is_copy_modulo_regions(cx.tcx, cx.typing_env())
|
||||
cx.type_is_copy_modulo_regions(ty)
|
||||
}
|
||||
|
||||
/// This checks whether a given type is known to implement Debug.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
|||
use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
|
||||
use rustc_hir::{
|
||||
AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
|
||||
Safety, Stmt, UnOp, UnsafeSource,
|
||||
Safety, Stmt, StructTailExpr, UnOp, UnsafeSource,
|
||||
};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
|
@ -663,7 +663,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
for field in fields {
|
||||
helper(typeck, true, field.expr, f)?;
|
||||
}
|
||||
if let Some(default) = default {
|
||||
if let StructTailExpr::Base(default) = default {
|
||||
helper(typeck, false, default, f)?;
|
||||
}
|
||||
},
|
||||
|
|
@ -694,6 +694,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
| ExprKind::Continue(_)
|
||||
| ExprKind::InlineAsm(_)
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::UnsafeBinderCast(..)
|
||||
| ExprKind::Err(_) => (),
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[toolchain]
|
||||
# begin autogenerated nightly
|
||||
channel = "nightly-2024-11-28"
|
||||
channel = "nightly-2024-12-15"
|
||||
# end autogenerated nightly
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -236,7 +236,8 @@ pub fn main() {
|
|||
let mut args: Vec<String> = orig_args.clone();
|
||||
pass_sysroot_env_if_given(&mut args, sys_root_env);
|
||||
|
||||
return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
|
||||
rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if orig_args.iter().any(|a| a == "--version" || a == "-V") {
|
||||
|
|
@ -296,12 +297,13 @@ pub fn main() {
|
|||
args.extend(clippy_args);
|
||||
rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var })
|
||||
.set_using_internal_features(using_internal_features)
|
||||
.run()
|
||||
.run();
|
||||
} else {
|
||||
rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var })
|
||||
.set_using_internal_features(using_internal_features)
|
||||
.run()
|
||||
.run();
|
||||
}
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ LL | | fn clone_self(&self) -> Self {
|
|||
LL | | Self {
|
||||
LL | | a: true,
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -32,7 +31,6 @@ LL | | fn default() -> Self {
|
|||
LL | | Self {
|
||||
LL | | a: true,
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ error: this block is too nested
|
|||
LL | if true {
|
||||
| _________________________^
|
||||
LL | | if true {
|
||||
LL | |
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
| |_________________^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -286,7 +286,6 @@ LL | | if unsafe { true } {
|
|||
LL | | todo!();
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -294,7 +294,6 @@ LL | | if unsafe { true } {
|
|||
LL | | todo!();
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::async_yields_async)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::async_yields_async)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:38:9
|
||||
--> tests/ui/async_yields_async.rs:37:9
|
||||
|
|
||||
LL | let _h = async {
|
||||
| _____________________-
|
||||
|
|
@ -20,7 +20,7 @@ LL + }.await
|
|||
|
|
||||
|
||||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:43:9
|
||||
--> tests/ui/async_yields_async.rs:42:9
|
||||
|
|
||||
LL | let _i = async {
|
||||
| ____________________-
|
||||
|
|
@ -33,7 +33,7 @@ LL | | };
|
|||
| |_____- outer async construct
|
||||
|
||||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:49:9
|
||||
--> tests/ui/async_yields_async.rs:48:9
|
||||
|
|
||||
LL | let _j = async || {
|
||||
| ________________________-
|
||||
|
|
@ -52,7 +52,7 @@ LL + }.await
|
|||
|
|
||||
|
||||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:54:9
|
||||
--> tests/ui/async_yields_async.rs:53:9
|
||||
|
|
||||
LL | let _k = async || {
|
||||
| _______________________-
|
||||
|
|
@ -65,7 +65,7 @@ LL | | };
|
|||
| |_____- outer async construct
|
||||
|
||||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:56:23
|
||||
--> tests/ui/async_yields_async.rs:55:23
|
||||
|
|
||||
LL | let _l = async || CustomFutureType;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
@ -75,12 +75,11 @@ LL | let _l = async || CustomFutureType;
|
|||
| help: consider awaiting this value: `CustomFutureType.await`
|
||||
|
||||
error: an async construct yields a type which is itself awaitable
|
||||
--> tests/ui/async_yields_async.rs:62:9
|
||||
--> tests/ui/async_yields_async.rs:61:9
|
||||
|
|
||||
LL | let _m = async || {
|
||||
| _______________________-
|
||||
LL | | println!("I'm bored");
|
||||
LL | | // Some more stuff
|
||||
... |
|
||||
LL | | CustomFutureType
|
||||
| | ^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#![allow(redundant_semicolons, clippy::no_effect)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(async_closure)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
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(const_arg) = length
|
||||
&& let ConstArgKind::Anon(anon_const) = const_arg.kind
|
||||
&& let ConstArgKind::Anon(anon_const) = length.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
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ LL | | if {
|
|||
LL | | if s == "43" {
|
||||
LL | | return Some(43);
|
||||
... |
|
||||
LL | | }
|
||||
LL | | });
|
||||
| |______^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -115,8 +115,7 @@ error: all if blocks contain the same code at the end
|
|||
--> tests/ui/branches_sharing_code/shared_at_bottom.rs:183:5
|
||||
|
|
||||
LL | / x << 2
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -131,8 +130,7 @@ error: all if blocks contain the same code at the end
|
|||
--> tests/ui/branches_sharing_code/shared_at_bottom.rs:192:5
|
||||
|
|
||||
LL | / x * 4
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -43,9 +43,7 @@ LL | } else {
|
|||
| ____________^
|
||||
LL | | if y == "world" {
|
||||
LL | | println!("world")
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -66,9 +64,7 @@ LL | } else {
|
|||
| ____________^
|
||||
LL | | if let Some(42) = Some(42) {
|
||||
LL | | println!("world")
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -89,9 +85,7 @@ LL | } else {
|
|||
| ____________^
|
||||
LL | | if let Some(42) = Some(42) {
|
||||
LL | | println!("world")
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -112,9 +106,7 @@ LL | } else {
|
|||
| ____________^
|
||||
LL | | if x == "hello" {
|
||||
LL | | println!("world")
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -135,9 +127,7 @@ LL | } else {
|
|||
| ____________^
|
||||
LL | | if let Some(42) = Some(42) {
|
||||
LL | | println!("world")
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | |
|
|||
LL | |
|
||||
LL | | type Item = u8;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@ error: this loop never actually loops
|
|||
--> tests/ui/crashes/ice-360.rs:5:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -16,11 +12,7 @@ error: this loop could be written as a `while let` loop
|
|||
--> tests/ui/crashes/ice-360.rs:5:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____^ help: try: `while let Some(ele) = iter.next() { .. }`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ error: this looks like you are trying to swap `a` and `b`
|
|||
--> tests/ui/crate_level_checks/no_std_swap.rs:12:5
|
||||
|
|
||||
LL | / a = b;
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | b = a;
|
||||
| |_________^ help: try: `core::mem::swap(&mut a, &mut b)`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | | fn default() -> Self {
|
|||
LL | | Self {
|
||||
LL | | a: false,
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -99,8 +99,7 @@ LL | / /// for OldA
|
|||
LL | | // struct OldA;
|
||||
LL | |
|
||||
LL | | /// Docs
|
||||
LL | | /// for OldB
|
||||
LL | | // struct OldB;
|
||||
... |
|
||||
LL | |
|
||||
| |_^
|
||||
...
|
||||
|
|
|
|||
|
|
@ -103,8 +103,7 @@ error: empty lines after outer attribute
|
|||
--> tests/ui/empty_line_after/outer_attribute.rs:64:1
|
||||
|
|
||||
LL | / #[allow(unused)]
|
||||
LL | |
|
||||
LL | | // This comment is isolated
|
||||
... |
|
||||
LL | |
|
||||
| |_^
|
||||
LL | pub fn isolated_comment() {}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ LL | / if !m.contains_key(&k) {
|
|||
LL | | if true {
|
||||
LL | | m.insert(k, v);
|
||||
LL | | } else {
|
||||
LL | | m.insert(k, v2);
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -63,7 +62,6 @@ LL | | if true {
|
|||
LL | | m.insert(k, v);
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -154,7 +152,6 @@ LL | | foo();
|
|||
LL | | match 0 {
|
||||
LL | | 0 if false => {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ error: all variants have the same prefix: `c`
|
|||
LL | / enum Foo {
|
||||
LL | |
|
||||
LL | | cFoo,
|
||||
LL | |
|
||||
... |
|
||||
LL | | cBaz,
|
||||
LL | | }
|
||||
|
|
@ -45,9 +44,7 @@ error: all variants have the same prefix: `Food`
|
|||
LL | / enum Food {
|
||||
LL | |
|
||||
LL | | FoodGood,
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ LL | |
|
|||
LL | | fn from(i: usize) -> Invalid {
|
||||
LL | | if i != 42 {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -49,7 +48,6 @@ LL | |
|
|||
LL | | fn from(s: Option<String>) -> Invalid {
|
||||
LL | | let s = s.unwrap();
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -76,7 +74,6 @@ LL | |
|
|||
LL | | fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {
|
||||
LL | | if s.parse::<u32>().ok().unwrap() != 42 {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
use std::fmt::Debug;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn a() {}
|
||||
|
||||
#[warn(clippy::fn_address_comparisons)]
|
||||
fn main() {
|
||||
type F = fn();
|
||||
let f: F = a;
|
||||
let g: F = f;
|
||||
|
||||
// These should fail:
|
||||
let _ = f == a;
|
||||
//~^ ERROR: comparing with a non-unique address of a function item
|
||||
//~| NOTE: `-D clippy::fn-address-comparisons` implied by `-D warnings`
|
||||
let _ = f != a;
|
||||
//~^ ERROR: comparing with a non-unique address of a function item
|
||||
|
||||
// These should be fine:
|
||||
let _ = f == g;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
error: comparing with a non-unique address of a function item
|
||||
--> tests/ui/fn_address_comparisons.rs:15:13
|
||||
|
|
||||
LL | let _ = f == a;
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `-D clippy::fn-address-comparisons` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::fn_address_comparisons)]`
|
||||
|
||||
error: comparing with a non-unique address of a function item
|
||||
--> tests/ui/fn_address_comparisons.rs:18:13
|
||||
|
|
||||
LL | let _ = f != a;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
@ -7,7 +7,6 @@ LL | | for _ in &[42] {
|
|||
LL | | let foo: &Option<_> = &Some::<u8>(42);
|
||||
LL | | if foo.is_some() {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -20,7 +19,6 @@ LL | | for _ in &[42] {
|
|||
LL | | let bar: &Option<_> = &Some::<u8>(42);
|
||||
LL | | if bar.is_some() {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
= note: `-D clippy::if-same-then-else` implied by `-D warnings`
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#![allow(clippy::never_loop)]
|
||||
#![warn(clippy::infinite_loop)]
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, with_span};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:14:5
|
||||
--> tests/ui/infinite_loops.rs:13:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -15,12 +15,11 @@ LL | fn no_break() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:21:5
|
||||
--> tests/ui/infinite_loops.rs:20:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | loop {
|
||||
LL | |
|
||||
... |
|
||||
LL | | do_something();
|
||||
LL | | }
|
||||
|
|
@ -32,14 +31,12 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:23:9
|
||||
--> tests/ui/infinite_loops.rs:22:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | loop {
|
||||
LL | |
|
||||
LL | | do_something();
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
|
||||
|
|
@ -49,7 +46,7 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:25:13
|
||||
--> tests/ui/infinite_loops.rs:24:13
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -63,7 +60,7 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:39:5
|
||||
--> tests/ui/infinite_loops.rs:38:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -74,13 +71,12 @@ LL | | }
|
|||
= help: if this is not intended, try adding a `break` or `return` condition in the loop
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:52:5
|
||||
--> tests/ui/infinite_loops.rs:51:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | | fn inner_fn() -> ! {
|
||||
LL | | std::process::exit(0);
|
||||
LL | | }
|
||||
LL | | do_something();
|
||||
... |
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -90,14 +86,13 @@ LL | fn no_break_never_ret_noise() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:95:5
|
||||
--> tests/ui/infinite_loops.rs:94:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | loop {
|
||||
LL | | if cond {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -107,14 +102,13 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:106:5
|
||||
--> tests/ui/infinite_loops.rs:105:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | 'inner: loop {
|
||||
LL | | loop {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -124,7 +118,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:120:9
|
||||
--> tests/ui/infinite_loops.rs:119:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -138,14 +132,13 @@ LL | fn break_outer_but_not_inner() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:143:9
|
||||
--> tests/ui/infinite_loops.rs:142:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | 'inner: loop {
|
||||
LL | | loop {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
|
||||
|
|
@ -155,14 +148,13 @@ LL | fn break_wrong_loop(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:183:5
|
||||
--> tests/ui/infinite_loops.rs:182:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | match opt {
|
||||
LL | | Some(v) => {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -172,7 +164,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:224:5
|
||||
--> tests/ui/infinite_loops.rs:223:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -186,7 +178,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:229:5
|
||||
--> tests/ui/infinite_loops.rs:228:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -203,7 +195,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:334:9
|
||||
--> tests/ui/infinite_loops.rs:333:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -217,7 +209,7 @@ LL | fn problematic_trait_method() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:344:9
|
||||
--> tests/ui/infinite_loops.rs:343:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -231,7 +223,7 @@ LL | fn could_be_problematic() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:353:9
|
||||
--> tests/ui/infinite_loops.rs:352:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -245,7 +237,7 @@ LL | let _loop_forever = || -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:367:8
|
||||
--> tests/ui/infinite_loops.rs:366:8
|
||||
|
|
||||
LL | Ok(loop {
|
||||
| ________^
|
||||
|
|
@ -256,7 +248,7 @@ LL | | })
|
|||
= help: if this is not intended, try adding a `break` or `return` condition in the loop
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:409:5
|
||||
--> tests/ui/infinite_loops.rs:408:5
|
||||
|
|
||||
LL | / 'infinite: loop {
|
||||
LL | |
|
||||
|
|
@ -272,14 +264,13 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:416:5
|
||||
--> tests/ui/infinite_loops.rs:415:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | | 'inner: loop {
|
||||
LL | | loop {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -289,7 +280,7 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:418:9
|
||||
--> tests/ui/infinite_loops.rs:417:9
|
||||
|
|
||||
LL | / 'inner: loop {
|
||||
LL | | loop {
|
||||
|
|
@ -304,7 +295,7 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:426:5
|
||||
--> tests/ui/infinite_loops.rs:425:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | |
|
|||
LL | | type IntoIter = std::slice::Iter<'a, u8>;
|
||||
LL | | type Item = &'a u8;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -30,7 +29,6 @@ LL | |
|
|||
LL | | type IntoIter = std::slice::IterMut<'a, u8>;
|
||||
LL | | type Item = &'a mut u8;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -52,7 +50,6 @@ LL | |
|
|||
LL | | type IntoIter = std::slice::Iter<'a, T>;
|
||||
LL | | type Item = &'a T;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -74,7 +71,6 @@ LL | |
|
|||
LL | | type IntoIter = std::slice::IterMut<'a, T>;
|
||||
LL | | type Item = &'a mut T;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -96,7 +92,6 @@ LL | |
|
|||
LL | | type IntoIter = std::slice::IterMut<'a, T>;
|
||||
LL | | type Item = &'a mut T;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -117,8 +112,7 @@ LL | / impl<'a> IntoIterator for &'a Issue12037 {
|
|||
LL | | type IntoIter = std::slice::Iter<'a, u8>;
|
||||
LL | | type Item = &'a u8;
|
||||
LL | | fn into_iter(self) -> Self::IntoIter {
|
||||
LL | | todo!()
|
||||
LL | | }
|
||||
... |
|
||||
LL | | }
|
||||
| |_________^
|
||||
...
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | |
|
|||
LL | |
|
||||
LL | | if s == String::new() {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())`
|
||||
|
|
||||
|
|
@ -22,7 +21,6 @@ LL | |
|
|||
LL | |
|
||||
LL | | if s == String::new() {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for &v in ARRAY {
|
||||
LL | | if v == n {
|
||||
LL | | return Some(v);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `ARRAY.iter().find(|&&v| v == n).copied()`
|
||||
|
|
||||
|
|
@ -18,8 +17,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for (a, _) in arr {
|
||||
LL | | if a % 2 == 0 {
|
||||
LL | | return Some(a);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)`
|
||||
|
||||
|
|
@ -29,8 +27,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for el in arr {
|
||||
LL | | if el.name.len() == 10 {
|
||||
LL | | return Some(el);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.name.len() == 10)`
|
||||
|
|
||||
|
|
@ -42,8 +39,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for Tuple(a, _) in arr {
|
||||
LL | | if a >= 3 {
|
||||
LL | | return Some(a);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)`
|
||||
|
||||
|
|
@ -53,8 +49,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for el in arr {
|
||||
LL | | if el.should_keep() {
|
||||
LL | | return Some(el);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.should_keep())`
|
||||
|
|
||||
|
|
@ -66,8 +61,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for el in arr {
|
||||
LL | | if f(el) == 20 {
|
||||
LL | | return Some(el);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().find(|&el| f(el) == 20)`
|
||||
|
||||
|
|
@ -77,8 +71,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for &el in arr.values() {
|
||||
LL | | if f(el) {
|
||||
LL | | return Some(el);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.values().find(|&&el| f(el)).copied()`
|
||||
|
||||
|
|
@ -88,8 +81,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for el in arr {
|
||||
LL | | if el.is_true {
|
||||
LL | | return Some(el);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.is_true)`
|
||||
|
|
||||
|
|
@ -101,8 +93,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for (_, &x) in v {
|
||||
LL | | if x > 10 {
|
||||
LL | | return Some(x);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)`
|
||||
|
||||
|
|
@ -112,8 +103,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for &(_, &x) in v {
|
||||
LL | | if x > 10 {
|
||||
LL | | return Some(x);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `v.iter().map(|&(_, &x)| x).find(|&x| x > 10)`
|
||||
|
||||
|
|
@ -123,8 +113,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for x in arr {
|
||||
LL | | if x >= 5 {
|
||||
LL | | return Some(x);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | return None;
|
||||
| |________________^ help: replace with an iterator: `arr.into_iter().find(|&x| x >= 5)`
|
||||
|
||||
|
|
@ -134,8 +123,7 @@ error: manual implementation of `Iterator::find`
|
|||
LL | / for x in arr {
|
||||
LL | | if x < 1 {
|
||||
LL | | return Some(x);
|
||||
LL | | }
|
||||
LL | | }
|
||||
... |
|
||||
LL | | None
|
||||
| |____________^ help: replace with an iterator: `arr.into_iter().find(|&x| x < 1)`
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,6 @@ LL | |
|
|||
LL | | Some(1),
|
||||
LL | | Some(2),
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ LL | |
|
|||
LL | | v_some
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
@ -175,7 +174,6 @@ LL | |
|
|||
LL | | v_some
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
@ -197,7 +195,6 @@ LL | |
|
|||
LL | | v_some
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
@ -306,7 +303,6 @@ LL | |
|
|||
LL | | v_some
|
||||
LL | | } else {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |______^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ LL | | Some(i) => i,
|
|||
LL | | None => {
|
||||
LL | | 42 + 42
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -130,7 +129,6 @@ LL | | Ok(i) => i,
|
|||
LL | | Err(_) => {
|
||||
LL | | 42 + 42
|
||||
... |
|
||||
LL | | }
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -77,9 +77,6 @@ error: called `map(..).flatten()` on `Option`
|
|||
|
|
||||
LL | .map(|_| {
|
||||
| __________^
|
||||
LL | | // we need some newlines
|
||||
LL | | // so that the span is big enough
|
||||
LL | | // for a split output of the diagnostic
|
||||
... |
|
||||
LL | | })
|
||||
LL | | .flatten();
|
||||
|
|
|
|||
|
|
@ -75,9 +75,6 @@ error: you seem to be trying to match on a boolean expression
|
|||
--> tests/ui/match_bool.rs:36:5
|
||||
|
|
||||
LL | / match test && test {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | _ => (),
|
||||
LL | | };
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ LL | let _ans = match x {
|
|||
| ____________________^
|
||||
LL | | E::A(_) => {
|
||||
LL | | true
|
||||
LL | | }
|
||||
LL | | E::B(_) => true,
|
||||
... |
|
||||
LL | | _ => false,
|
||||
LL | | };
|
||||
| |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ LL | | /// dox
|
|||
LL | | pub fn documented() {}
|
||||
LL | | pub fn undocumented1() {}
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ error: missing documentation for the crate
|
|||
--> tests/ui/missing_doc_crate_missing.rs:1:1
|
||||
|
|
||||
LL | / #![warn(clippy::missing_docs_in_private_items)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | |
|
|||
LL | | // unused field: hidden
|
||||
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -28,7 +27,6 @@ LL | |
|
|||
LL | | // unused fields: hidden, hidden2, hidden4
|
||||
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
@ -58,7 +56,6 @@ LL | |
|
|||
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
LL | | let mut f = formatter.debug_struct("MultiExprDebugImpl");
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ LL | |
|
|||
LL | |
|
||||
LL | | if *v == 10 {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | });
|
||||
| |_______^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ error: this `if` branch is empty
|
|||
LL | / if {
|
||||
LL | | if let true = true
|
||||
LL | | && true
|
||||
LL | | {
|
||||
... |
|
||||
LL | | } && true
|
||||
LL | | {}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@ error: this loop never actually loops
|
|||
--> tests/ui/never_loop.rs:12:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | // clippy::never_loop
|
||||
... |
|
||||
LL | | break;
|
||||
LL | | }
|
||||
|
|
@ -75,7 +72,6 @@ LL | |
|
|||
LL | | // never loops
|
||||
LL | | match x {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
|
|
@ -126,7 +122,6 @@ LL | |
|
|||
LL | | 'b: {
|
||||
LL | | break 'b 'c: {
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,7 @@ LL | let _ = if let Some(x) = arg {
|
|||
| _____________^
|
||||
LL | | x
|
||||
LL | | } else {
|
||||
LL | | // map_or_else must be suggested
|
||||
LL | | side_effect()
|
||||
... |
|
||||
LL | | };
|
||||
| |_____^ help: try: `arg.map_or_else(side_effect, |x| x)`
|
||||
|
||||
|
|
|
|||
|
|
@ -183,8 +183,7 @@ error: this block may be rewritten with the `?` operator
|
|||
|
|
||||
LL | / if a.is_none() {
|
||||
LL | | return None;
|
||||
LL | | // do lint here, the outer `try` is not relevant here
|
||||
LL | | // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867
|
||||
... |
|
||||
LL | | }
|
||||
| |_____________^ help: replace it with: `a?;`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::redundant_closure_call)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::redundant_closure_call)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:16:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:15:13
|
||||
|
|
||||
LL | let a = (|| 42)();
|
||||
| ^^^^^^^^^ help: try doing something like: `42`
|
||||
|
|
@ -8,7 +8,7 @@ LL | let a = (|| 42)();
|
|||
= help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:17:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:16:13
|
||||
|
|
||||
LL | let b = (async || {
|
||||
| _____________^
|
||||
|
|
@ -28,7 +28,7 @@ LL ~ };
|
|||
|
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:22:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:21:13
|
||||
|
|
||||
LL | let c = (|| {
|
||||
| _____________^
|
||||
|
|
@ -48,13 +48,13 @@ LL ~ };
|
|||
|
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:27:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:26:13
|
||||
|
|
||||
LL | let d = (async || something().await)();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:36:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:35:13
|
||||
|
|
||||
LL | (|| m!())()
|
||||
| ^^^^^^^^^^^ help: try doing something like: `m!()`
|
||||
|
|
@ -65,7 +65,7 @@ LL | m2!();
|
|||
= note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:31:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:30:13
|
||||
|
|
||||
LL | (|| 0)()
|
||||
| ^^^^^^^^ help: try doing something like: `0`
|
||||
|
|
@ -76,67 +76,67 @@ LL | m2!();
|
|||
= note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:44:16
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:43:16
|
||||
|
|
||||
LL | assert_eq!((|| || 43)()(), 42);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `43`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:53:10
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:52:10
|
||||
|
|
||||
LL | dbg!((|| 42)());
|
||||
| ^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:56:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:55:13
|
||||
|
|
||||
LL | let a = (|| || || 123)();
|
||||
| ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:60:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:59:13
|
||||
|
|
||||
LL | let a = (|| || || || async || 1)()()()()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:69:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:68:13
|
||||
|
|
||||
LL | let a = (|| echo!(|| echo!(|| 1)))()()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:71:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:70:13
|
||||
|
|
||||
LL | let a = (|| echo!((|| 123)))()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:84:11
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:83:11
|
||||
|
|
||||
LL | bar()((|| || 42)()(), 5);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:85:9
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:84:9
|
||||
|
|
||||
LL | foo((|| || 42)()(), 5);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:89:5
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:88:5
|
||||
|
|
||||
LL | (|| async {})().await;
|
||||
| ^^^^^^^^^^^^^^^ help: try doing something like: `async {}`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:98:18
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:97:18
|
||||
|
|
||||
LL | spawn_on((|| async move {})());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:103:28
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:102:28
|
||||
|
|
||||
LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue