commit
c950602c01
54 changed files with 277 additions and 213 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.89"
|
||||
version = "0.1.90"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
@ -59,6 +59,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
|
|||
[features]
|
||||
integration = ["dep:tempfile"]
|
||||
internal = ["dep:clippy_lints_internal", "dep:tempfile"]
|
||||
jemalloc = []
|
||||
|
||||
[package.metadata.rust-analyzer]
|
||||
# This package uses #[feature(rustc_private)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_config"
|
||||
version = "0.1.89"
|
||||
version = "0.1.90"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
|
|
|
|||
|
|
@ -386,17 +386,13 @@ pub fn read_deprecated_lints() -> (Vec<DeprecatedLint>, Vec<RenamedLint>) {
|
|||
|
||||
/// Removes the line splices and surrounding quotes from a string literal
|
||||
fn parse_str_lit(s: &str) -> String {
|
||||
let (s, mode) = if let Some(s) = s.strip_prefix("r") {
|
||||
(s.trim_matches('#'), rustc_literal_escaper::Mode::RawStr)
|
||||
} else {
|
||||
(s, rustc_literal_escaper::Mode::Str)
|
||||
};
|
||||
let s = s.strip_prefix("r").unwrap_or(s).trim_matches('#');
|
||||
let s = s
|
||||
.strip_prefix('"')
|
||||
.and_then(|s| s.strip_suffix('"'))
|
||||
.unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
|
||||
let mut res = String::with_capacity(s.len());
|
||||
rustc_literal_escaper::unescape_unicode(s, mode, &mut |_, ch| {
|
||||
rustc_literal_escaper::unescape_str(s, &mut |_, ch| {
|
||||
if let Ok(ch) = ch {
|
||||
res.push(ch);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.89"
|
||||
version = "0.1.90"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
|
|
|||
|
|
@ -1,29 +1,22 @@
|
|||
use super::INLINE_ALWAYS;
|
||||
use super::utils::is_word;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr};
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
|
||||
if span.from_expansion() {
|
||||
return;
|
||||
}
|
||||
|
||||
for attr in attrs {
|
||||
if let Some(values) = attr.meta_item_list() {
|
||||
if values.len() != 1 || !attr.has_name(sym::inline) {
|
||||
continue;
|
||||
}
|
||||
if is_word(&values[0], sym::always) {
|
||||
span_lint(
|
||||
cx,
|
||||
INLINE_ALWAYS,
|
||||
attr.span(),
|
||||
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(span) = find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, span) => *span) {
|
||||
span_lint(
|
||||
cx,
|
||||
INLINE_ALWAYS,
|
||||
span,
|
||||
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
|
|||
.and_then(|trait_id| {
|
||||
cx.tcx.associated_items(trait_id).find_by_ident_and_kind(
|
||||
cx.tcx,
|
||||
Ident::from_str("Output"),
|
||||
Ident::with_dummy_span(sym::Output),
|
||||
ty::AssocTag::Type,
|
||||
trait_id,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::{expr_or_init, path_def_id, paths, std_or_core};
|
||||
use clippy_utils::{expr_or_init, is_path_diagnostic_item, std_or_core, sym};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind};
|
||||
|
|
@ -53,8 +53,7 @@ fn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) ->
|
|||
|
||||
fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {
|
||||
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind
|
||||
&& let Some(fun_id) = path_def_id(cx, fun)
|
||||
&& paths::ALIGN_OF.matches(cx, fun_id)
|
||||
&& is_path_diagnostic_item(cx, fun, sym::mem_align_of)
|
||||
&& let Some(args) = path.segments.last().and_then(|seg| seg.args)
|
||||
&& let [GenericArg::Type(generic_ty)] = args.args
|
||||
{
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ pub(super) fn check<'tcx>(
|
|||
Node::Expr(parent) if is_borrow_expr(cx, parent) && !is_in_allowed_macro(cx, parent) => {
|
||||
MaybeParenOrBlock::Block
|
||||
},
|
||||
Node::Expr(parent) if cast_expr.precedence() < parent.precedence() => MaybeParenOrBlock::Paren,
|
||||
Node::Expr(parent) if cx.precedence(cast_expr) < cx.precedence(parent) => MaybeParenOrBlock::Paren,
|
||||
_ => MaybeParenOrBlock::Nothing,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
#[clippy::version = "1.88.0"]
|
||||
pub COERCE_CONTAINER_TO_ANY,
|
||||
suspicious,
|
||||
nursery,
|
||||
"coercing to `&dyn Any` when dereferencing could produce a `dyn Any` without coercion is usually not intended"
|
||||
}
|
||||
declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);
|
||||
|
|
|
|||
|
|
@ -972,7 +972,7 @@ fn report<'tcx>(
|
|||
"&"
|
||||
};
|
||||
|
||||
let expr_str = if !expr_is_macro_call && is_ufcs && expr.precedence() < ExprPrecedence::Prefix {
|
||||
let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix {
|
||||
Cow::Owned(format!("({expr_str})"))
|
||||
} else {
|
||||
expr_str
|
||||
|
|
@ -1015,10 +1015,10 @@ fn report<'tcx>(
|
|||
Node::Expr(e) => match e.kind {
|
||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,
|
||||
ExprKind::Call(..) => {
|
||||
expr.precedence() < ExprPrecedence::Unambiguous
|
||||
cx.precedence(expr) < ExprPrecedence::Unambiguous
|
||||
|| matches!(expr.kind, ExprKind::Field(..))
|
||||
},
|
||||
_ => expr.precedence() < e.precedence(),
|
||||
_ => cx.precedence(expr) < cx.precedence(e),
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
|
@ -1066,7 +1066,7 @@ fn report<'tcx>(
|
|||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
};
|
||||
(prefix, expr.precedence() < ExprPrecedence::Prefix)
|
||||
(prefix, cx.precedence(expr) < ExprPrecedence::Prefix)
|
||||
},
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false),
|
||||
_ => ("", false),
|
||||
|
|
@ -1172,7 +1172,7 @@ impl<'tcx> Dereferencing<'tcx> {
|
|||
},
|
||||
Some(parent) if !parent.span.from_expansion() => {
|
||||
// Double reference might be needed at this point.
|
||||
if parent.precedence() == ExprPrecedence::Unambiguous {
|
||||
if cx.precedence(parent) == ExprPrecedence::Unambiguous {
|
||||
// Parentheses would be needed here, don't lint.
|
||||
*outer_pat = None;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::attr::AttributeExt as _;
|
||||
use rustc_ast::token::CommentKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{AttrStyle, Attribute};
|
||||
|
|
@ -43,13 +44,15 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F
|
|||
"looks like a footnote ref, but has no matching footnote",
|
||||
|diag| {
|
||||
if this_fragment.kind == DocFragmentKind::SugaredDoc {
|
||||
let (doc_attr, (_, doc_attr_comment_kind)) = attrs
|
||||
let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.span().overlaps(this_fragment.span))
|
||||
.rev()
|
||||
.find_map(|attr| Some((attr, attr.doc_str_and_comment_kind()?)))
|
||||
.find_map(|attr| {
|
||||
Some((attr, attr.doc_str_and_comment_kind()?, attr.doc_resolution_scope()?))
|
||||
})
|
||||
.unwrap();
|
||||
let (to_add, terminator) = match (doc_attr_comment_kind, doc_attr.style()) {
|
||||
let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) {
|
||||
(CommentKind::Line, AttrStyle::Outer) => ("\n///\n/// ", ""),
|
||||
(CommentKind::Line, AttrStyle::Inner) => ("\n//!\n//! ", ""),
|
||||
(CommentKind::Block, AttrStyle::Outer) => ("\n/** ", " */"),
|
||||
|
|
|
|||
|
|
@ -42,9 +42,8 @@ pub fn check(
|
|||
let mut test_attr_spans = vec![];
|
||||
let filename = FileName::anon_source_code(&code);
|
||||
|
||||
let fallback_bundle =
|
||||
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
|
||||
let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
|
||||
let translator = rustc_driver::default_translator();
|
||||
let emitter = HumanEmitter::new(Box::new(io::sink()), translator);
|
||||
let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
|
||||
#[expect(clippy::arc_with_non_send_sync)] // `Arc` is expected by with_dcx
|
||||
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use clippy_utils::{
|
|||
get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
|
||||
};
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
|
|
@ -161,7 +162,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
|
|||
let sig = match callee_ty_adjusted.kind() {
|
||||
ty::FnDef(def, _) => {
|
||||
// Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`
|
||||
if cx.tcx.has_attr(*def, sym::track_caller) {
|
||||
if find_attr!(cx.tcx.get_all_attrs(*def), AttributeKind::TrackCaller(..)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +250,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
|
|||
},
|
||||
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
|
||||
if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)
|
||||
&& !cx.tcx.has_attr(method_def_id, sym::track_caller)
|
||||
&& !find_attr!(cx.tcx.get_all_attrs(method_def_id), AttributeKind::TrackCaller(..))
|
||||
&& check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
|
||||
{
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ use clippy_utils::source::SpanRangeExt;
|
|||
use clippy_utils::ty::is_must_use_ty;
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{return_ty, trait_ref_of_method};
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
|
||||
use core::ops::ControlFlow;
|
||||
|
|
@ -22,7 +24,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
|
|||
|
||||
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
|
||||
let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
|
||||
if let hir::ItemKind::Fn {
|
||||
ref sig,
|
||||
body: ref body_id,
|
||||
|
|
@ -31,9 +33,19 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
|
|||
{
|
||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
|
||||
} else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
|
||||
if let Some((attr_span, reason)) = attr {
|
||||
check_needless_must_use(
|
||||
cx,
|
||||
sig.decl,
|
||||
item.owner_id,
|
||||
item.span,
|
||||
fn_header_span,
|
||||
*attr_span,
|
||||
*reason,
|
||||
attrs,
|
||||
sig,
|
||||
);
|
||||
} else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs, AttributeKind::NoMangle(..)) {
|
||||
check_must_use_candidate(
|
||||
cx,
|
||||
sig.decl,
|
||||
|
|
@ -52,9 +64,20 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
|
|||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
|
||||
let attr =
|
||||
find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
|
||||
if let Some((attr_span, reason)) = attr {
|
||||
check_needless_must_use(
|
||||
cx,
|
||||
sig.decl,
|
||||
item.owner_id,
|
||||
item.span,
|
||||
fn_header_span,
|
||||
*attr_span,
|
||||
*reason,
|
||||
attrs,
|
||||
sig,
|
||||
);
|
||||
} else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() {
|
||||
check_must_use_candidate(
|
||||
cx,
|
||||
|
|
@ -75,9 +98,20 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
|||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
|
||||
let attr =
|
||||
find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
|
||||
if let Some((attr_span, reason)) = attr {
|
||||
check_needless_must_use(
|
||||
cx,
|
||||
sig.decl,
|
||||
item.owner_id,
|
||||
item.span,
|
||||
fn_header_span,
|
||||
*attr_span,
|
||||
*reason,
|
||||
attrs,
|
||||
sig,
|
||||
);
|
||||
} else if let hir::TraitFn::Provided(eid) = *eid {
|
||||
let body = cx.tcx.hir_body(eid);
|
||||
if attr.is_none() && is_public && !is_proc_macro(attrs) {
|
||||
|
|
@ -103,7 +137,8 @@ fn check_needless_must_use(
|
|||
item_id: hir::OwnerId,
|
||||
item_span: Span,
|
||||
fn_header_span: Span,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
reason: Option<Symbol>,
|
||||
attrs: &[Attribute],
|
||||
sig: &FnSig<'_>,
|
||||
) {
|
||||
|
|
@ -118,12 +153,7 @@ fn check_needless_must_use(
|
|||
fn_header_span,
|
||||
"this unit-returning function has a `#[must_use]` attribute",
|
||||
|diag| {
|
||||
diag.span_suggestion(
|
||||
attr.span(),
|
||||
"remove the attribute",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
diag.span_suggestion(attr_span, "remove the attribute", "", Applicability::MachineApplicable);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
|
|
@ -137,11 +167,11 @@ fn check_needless_must_use(
|
|||
MUST_USE_UNIT,
|
||||
fn_header_span,
|
||||
"this unit-returning function has a `#[must_use]` attribute",
|
||||
Some(attr.span()),
|
||||
Some(attr_span),
|
||||
"remove `must_use`",
|
||||
);
|
||||
}
|
||||
} else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
|
||||
} else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
|
||||
// Ignore async functions unless Future::Output type is a must_use type
|
||||
if sig.header.is_async() {
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::sugg::DiagExt;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{TraitFn, TraitItem, TraitItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -32,15 +32,19 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);
|
|||
impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
||||
if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind
|
||||
&& let Some(attr) = cx.tcx.hir_attrs(item.hir_id()).iter().find(|a| a.has_name(sym::inline))
|
||||
&& let Some(attr_span) = find_attr!(cx
|
||||
.tcx
|
||||
.hir_attrs(item.hir_id()),
|
||||
AttributeKind::Inline(_, span) => *span
|
||||
)
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
INLINE_FN_WITHOUT_BODY,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
format!("use of `#[inline]` on trait method `{}` which has no body", item.ident),
|
||||
|diag| {
|
||||
diag.suggest_remove_item(cx, attr.span(), "remove", Applicability::MachineApplicable);
|
||||
diag.suggest_remove_item(cx, attr_span, "remove", Applicability::MachineApplicable);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() <= ExprPrecedence::Prefix || is_range_literal(arg_expression)
|
||||
cx.precedence(arg_expression) <= ExprPrecedence::Prefix || is_range_literal(arg_expression)
|
||||
)
|
||||
{
|
||||
arg_snip = format!("({arg_snip})").into();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use clippy_utils::{is_none_arm, msrvs, paths, peel_hir_expr_refs, sym};
|
||||
use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal};
|
||||
|
|
@ -220,5 +220,5 @@ fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
}
|
||||
|
||||
fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
paths::SLICE_FROM_REF.matches_path(cx, expr)
|
||||
clippy_utils::is_path_diagnostic_item(cx, expr, sym::slice_from_ref)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() < ExprPrecedence::Unambiguous {
|
||||
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && cx.precedence(scrutinee) < ExprPrecedence::Unambiguous {
|
||||
format!("({scrutinee_str})")
|
||||
} else {
|
||||
scrutinee_str.into()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{expr_or_init, paths};
|
||||
use clippy_utils::{expr_or_init, is_path_diagnostic_item, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -10,8 +10,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args
|
|||
&& !expr.span.from_expansion()
|
||||
&& !error_kind.span.from_expansion()
|
||||
&& let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind
|
||||
&& paths::IO_ERROR_NEW.matches_path(cx, path)
|
||||
&& paths::IO_ERRORKIND_OTHER_CTOR.matches_path(cx, expr_or_init(cx, error_kind))
|
||||
&& is_path_diagnostic_item(cx, path, sym::io_error_new)
|
||||
&& let ExprKind::Path(QPath::Resolved(_, init_path)) = &expr_or_init(cx, error_kind).kind
|
||||
&& let [.., error_kind_ty, error_kind_variant] = init_path.segments
|
||||
&& cx.tcx.is_diagnostic_item(sym::io_errorkind, error_kind_ty.res.def_id())
|
||||
&& error_kind_variant.ident.name == sym::Other
|
||||
&& msrv.meets(cx, msrvs::IO_ERROR_OTHER)
|
||||
{
|
||||
span_lint_and_then(
|
||||
|
|
|
|||
|
|
@ -388,9 +388,11 @@ fn check_other_call_arg<'tcx>(
|
|||
&& let (input, n_refs) = peel_middle_ty_refs(*input)
|
||||
&& let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input)
|
||||
&& let Some(sized_def_id) = cx.tcx.lang_items().sized_trait()
|
||||
&& let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait()
|
||||
&& let [trait_predicate] = trait_predicates
|
||||
.iter()
|
||||
.filter(|trait_predicate| trait_predicate.def_id() != sized_def_id)
|
||||
.filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id)
|
||||
.collect::<Vec<_>>()[..]
|
||||
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
|
||||
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::AssocItemContainer;
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_span::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -64,8 +65,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) {
|
||||
let has_inline = attrs.iter().any(|a| a.has_name(sym::inline));
|
||||
if !has_inline {
|
||||
if !find_attr!(attrs, AttributeKind::Inline(..)) {
|
||||
span_lint(
|
||||
cx,
|
||||
MISSING_INLINE_IN_PUBLIC_ITEMS,
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ fn path_has_args(p: &QPath<'_>) -> bool {
|
|||
/// - `Copy` itself, or
|
||||
/// - the only use of a mutable reference, or
|
||||
/// - not a variable (created by a function call)
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
#[expect(clippy::too_many_arguments, clippy::too_many_lines)]
|
||||
fn needless_borrow_count<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
||||
|
|
@ -174,6 +174,7 @@ fn needless_borrow_count<'tcx>(
|
|||
) -> usize {
|
||||
let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
|
||||
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
|
||||
let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait();
|
||||
let drop_trait_def_id = cx.tcx.lang_items().drop_trait();
|
||||
|
||||
let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
|
||||
|
|
@ -209,6 +210,7 @@ fn needless_borrow_count<'tcx>(
|
|||
.all(|trait_def_id| {
|
||||
Some(trait_def_id) == destruct_trait_def_id
|
||||
|| Some(trait_def_id) == sized_trait_def_id
|
||||
|| Some(trait_def_id) == meta_sized_trait_def_id
|
||||
|| cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
|
||||
})
|
||||
{
|
||||
|
|
@ -230,11 +232,11 @@ fn needless_borrow_count<'tcx>(
|
|||
let mut args_with_referent_ty = callee_args.to_vec();
|
||||
|
||||
let mut check_reference_and_referent = |reference: &Expr<'tcx>, referent: &Expr<'tcx>| {
|
||||
if let ExprKind::Field(base, _) = &referent.kind {
|
||||
let base_ty = cx.typeck_results().expr_ty(base);
|
||||
if drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[])) {
|
||||
return false;
|
||||
}
|
||||
if let ExprKind::Field(base, _) = &referent.kind
|
||||
&& let base_ty = cx.typeck_results().expr_ty(base)
|
||||
&& drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let referent_ty = cx.typeck_results().expr_ty(referent);
|
||||
|
|
|
|||
|
|
@ -116,13 +116,18 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||
];
|
||||
|
||||
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
||||
let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait());
|
||||
|
||||
let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter())
|
||||
.filter(|p| !p.is_global())
|
||||
.filter_map(|pred| {
|
||||
// Note that we do not want to deal with qualified predicates here.
|
||||
match pred.kind().no_bound_vars() {
|
||||
Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred),
|
||||
Some(ty::ClauseKind::Trait(pred))
|
||||
if pred.def_id() != sized_trait && pred.def_id() != meta_sized_trait =>
|
||||
{
|
||||
Some(pred)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -64,7 +64,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() < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
|
||||
let suggestion = if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
|
||||
format!("-({snip})")
|
||||
} else {
|
||||
format!("-{snip}")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::{snippet, snippet_with_applicability};
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Item, ItemKind};
|
||||
use rustc_hir::{Attribute, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{BytePos, Pos};
|
||||
|
|
@ -44,8 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
|
|||
let mut app = Applicability::MaybeIncorrect;
|
||||
let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app);
|
||||
for attr in attrs {
|
||||
if let Some(ident) = attr.ident()
|
||||
&& ident.name == rustc_span::sym::no_mangle
|
||||
if let Attribute::Parsed(AttributeKind::NoMangle(attr_span)) = attr
|
||||
&& fn_sig.header.abi == ExternAbi::Rust
|
||||
&& let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn")
|
||||
&& !fn_attrs.contains("extern")
|
||||
|
|
@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
|
|||
.span
|
||||
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
|
||||
.shrink_to_lo();
|
||||
let attr_snippet = snippet(cx, attr.span(), "..");
|
||||
let attr_snippet = snippet(cx, *attr_span, "..");
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};
|
|||
use clippy_utils::{is_self, is_self_ty};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::attr;
|
||||
use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -270,11 +270,13 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
|||
return;
|
||||
}
|
||||
let attrs = cx.tcx.hir_attrs(hir_id);
|
||||
if find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, _)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for a in attrs {
|
||||
if let Some(meta_items) = a.meta_item_list()
|
||||
&& (a.has_name(sym::proc_macro_derive)
|
||||
|| (a.has_name(sym::inline) && attr::list_contains_name(&meta_items, sym::always)))
|
||||
{
|
||||
// FIXME(jdonszelmann): make part of the find_attr above
|
||||
if a.has_name(sym::proc_macro_derive) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
|||
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() > ExprPrecedence::Prefix);
|
||||
parent_expr.is_some_and(|parent| cx.precedence(parent) > ExprPrecedence::Prefix);
|
||||
|
||||
if expr_ty == indexed_ty {
|
||||
if expr_ref_count > indexed_ref_count {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::is_must_use_ty;
|
||||
use clippy_utils::{nth_arg, return_ty};
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_span::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -74,7 +75,10 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
|
|||
// We only show this warning for public exported methods.
|
||||
&& cx.effective_visibilities.is_exported(fn_def)
|
||||
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
|
||||
&& !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use))
|
||||
&& !find_attr!(
|
||||
cx.tcx.hir_attrs(owner_id.into()),
|
||||
AttributeKind::MustUse { .. }
|
||||
)
|
||||
&& cx.tcx.visibility(fn_def.to_def_id()).is_public()
|
||||
&& let ret_ty = return_ty(cx, owner_id)
|
||||
&& let self_arg = nth_arg(cx, owner_id, 0)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use clippy_utils::higher::VecArgs;
|
|||
use clippy_utils::macros::root_macro_call_first_node;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{is_no_std_crate, paths};
|
||||
use clippy_utils::{is_no_std_crate, sym};
|
||||
use rustc_ast::{LitIntType, LitKind, UintTy};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, LangItem, QPath, StructTailExpr};
|
||||
|
|
@ -100,7 +100,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
|
|||
&& let Some(start_snippet) = start.span.get_source_text(cx)
|
||||
&& let Some(end_snippet) = end.span.get_source_text(cx)
|
||||
{
|
||||
let should_emit_every_value = if let Some(step_def_id) = paths::ITER_STEP.only(cx)
|
||||
let should_emit_every_value = if let Some(step_def_id) = cx.tcx.get_diagnostic_item(sym::range_step)
|
||||
&& implements_trait(cx, ty, step_def_id, &[])
|
||||
{
|
||||
true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{is_in_const_context, paths, sym};
|
||||
use clippy_utils::{is_in_const_context, is_path_diagnostic_item, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
|
|||
}
|
||||
},
|
||||
hir::ExprKind::Call(to_digits_call, [char_arg, radix_arg]) => {
|
||||
if paths::CHAR_TO_DIGIT.matches_path(cx, to_digits_call) {
|
||||
if is_path_diagnostic_item(cx, to_digits_call, sym::char_to_digit) {
|
||||
Some((false, char_arg, radix_arg))
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
|
|||
};
|
||||
|
||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
|
||||
&& parent.precedence() > ExprPrecedence::Cast
|
||||
&& cx.precedence(parent) > ExprPrecedence::Cast
|
||||
{
|
||||
sugg = format!("({sugg})");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ fn remove_all_parens(pat: &mut P<Pat>) {
|
|||
}
|
||||
|
||||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, pat: &mut P<Pat>) {
|
||||
fn visit_pat(&mut self, pat: &mut Pat) {
|
||||
let is_inner = mem::replace(&mut self.is_inner, true);
|
||||
walk_pat(self, pat);
|
||||
let inner = match &mut pat.kind {
|
||||
|
|
@ -145,7 +145,7 @@ fn remove_all_parens(pat: &mut P<Pat>) {
|
|||
fn insert_necessary_parens(pat: &mut P<Pat>) {
|
||||
struct Visitor;
|
||||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, pat: &mut P<Pat>) {
|
||||
fn visit_pat(&mut self, pat: &mut Pat) {
|
||||
use ast::BindingMode;
|
||||
walk_pat(self, pat);
|
||||
let target = match &mut pat.kind {
|
||||
|
|
@ -167,7 +167,7 @@ fn unnest_or_patterns(pat: &mut P<Pat>) -> bool {
|
|||
changed: bool,
|
||||
}
|
||||
impl MutVisitor for Visitor {
|
||||
fn visit_pat(&mut self, p: &mut P<Pat>) {
|
||||
fn visit_pat(&mut self, p: &mut Pat) {
|
||||
// This is a bottom up transformation, so recurse first.
|
||||
walk_pat(self, p);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::macros::macro_backtrace;
|
||||
use clippy_utils::paths::CONCAT;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::tokenize_with_text;
|
||||
use clippy_utils::{sym, tokenize_with_text};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
|
|
@ -43,7 +42,7 @@ impl LateLintPass<'_> for UselessConcat {
|
|||
// Get the direct parent of the expression.
|
||||
&& let Some(macro_call) = macro_backtrace(expr.span).next()
|
||||
// Check if the `concat` macro from the `core` library.
|
||||
&& CONCAT.matches(cx, macro_call.def_id)
|
||||
&& cx.tcx.is_diagnostic_item(sym::macro_concat, macro_call.def_id)
|
||||
// We get the original code to parse it.
|
||||
&& let Some(original_code) = snippet_opt(cx, macro_call.span)
|
||||
// This check allows us to ensure that the code snippet:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.89"
|
||||
version = "0.1.90"
|
||||
edition = "2024"
|
||||
description = "Helpful tools for writing lints, provided as they are used in Clippy"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
|
|||
|
||||
<!-- begin autogenerated nightly -->
|
||||
```
|
||||
nightly-2025-06-12
|
||||
nightly-2025-06-26
|
||||
```
|
||||
<!-- end autogenerated nightly -->
|
||||
|
||||
|
|
|
|||
|
|
@ -1886,7 +1886,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
did.is_some_and(|did| cx.tcx.has_attr(did, sym::must_use))
|
||||
did.is_some_and(|did| find_attr!(cx.tcx.get_all_attrs(did), AttributeKind::MustUse { .. }))
|
||||
}
|
||||
|
||||
/// Checks if a function's body represents the identity function. Looks for bodies of the form:
|
||||
|
|
|
|||
|
|
@ -126,15 +126,6 @@ path_macros! {
|
|||
macro_path: PathNS::Macro,
|
||||
}
|
||||
|
||||
// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
|
||||
pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of);
|
||||
pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit);
|
||||
pub static CONCAT: PathLookup = macro_path!(core::concat);
|
||||
pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new);
|
||||
pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other);
|
||||
pub static ITER_STEP: PathLookup = type_path!(core::iter::Step);
|
||||
pub static SLICE_FROM_REF: PathLookup = value_path!(core::slice::from_ref);
|
||||
|
||||
// Paths in external crates
|
||||
pub static FUTURES_IO_ASYNCREADEXT: PathLookup = type_path!(futures_util::AsyncReadExt);
|
||||
pub static FUTURES_IO_ASYNCWRITEEXT: PathLookup = type_path!(futures_util::AsyncWriteExt);
|
||||
|
|
|
|||
|
|
@ -34,10 +34,12 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms
|
|||
}
|
||||
if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND)
|
||||
&& let Some(sized_did) = cx.tcx.lang_items().sized_trait()
|
||||
&& let Some(meta_sized_did) = cx.tcx.lang_items().meta_sized_trait()
|
||||
&& cx.tcx.param_env(def_id).caller_bounds().iter().any(|bound| {
|
||||
bound
|
||||
.as_trait_clause()
|
||||
.is_some_and(|clause| clause.def_id() != sized_did)
|
||||
bound.as_trait_clause().is_some_and(|clause| {
|
||||
let did = clause.def_id();
|
||||
did != sized_did && did != meta_sized_did
|
||||
})
|
||||
})
|
||||
{
|
||||
return Err((
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ generate! {
|
|||
DOUBLE_QUOTE: "\"",
|
||||
Deserialize,
|
||||
EarlyLintPass,
|
||||
ErrorKind,
|
||||
IntoIter,
|
||||
Itertools,
|
||||
LF: "\n",
|
||||
|
|
@ -65,7 +64,6 @@ generate! {
|
|||
RegexBuilder,
|
||||
RegexSet,
|
||||
Start,
|
||||
Step,
|
||||
Symbol,
|
||||
SyntaxContext,
|
||||
TBD,
|
||||
|
|
@ -76,7 +74,6 @@ generate! {
|
|||
Visitor,
|
||||
Weak,
|
||||
abs,
|
||||
align_of,
|
||||
ambiguous_glob_reexports,
|
||||
append,
|
||||
arg,
|
||||
|
|
@ -159,7 +156,6 @@ generate! {
|
|||
from_ne_bytes,
|
||||
from_ptr,
|
||||
from_raw,
|
||||
from_ref,
|
||||
from_str,
|
||||
from_str_radix,
|
||||
fs,
|
||||
|
|
@ -218,7 +214,6 @@ generate! {
|
|||
max_by_key,
|
||||
max_value,
|
||||
maximum,
|
||||
mem,
|
||||
min,
|
||||
min_by,
|
||||
min_by_key,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use core::ops::ControlFlow;
|
|||
use itertools::Itertools;
|
||||
use rustc_abi::VariantIdx;
|
||||
use rustc_ast::ast::Mutability;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
|
|
@ -20,8 +21,8 @@ use rustc_middle::traits::EvaluationResult;
|
|||
use rustc_middle::ty::layout::ValidityRequirement;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
|
||||
GenericParamDefKind, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
|
||||
GenericParamDefKind, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
|
||||
};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
|
|
@ -326,8 +327,8 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
// Returns whether the type has #[must_use] attribute
|
||||
pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::Adt(adt, _) => cx.tcx.has_attr(adt.did(), sym::must_use),
|
||||
ty::Foreign(did) => cx.tcx.has_attr(*did, sym::must_use),
|
||||
ty::Adt(adt, _) => find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::MustUse { .. }),
|
||||
ty::Foreign(did) => find_attr!(cx.tcx.get_all_attrs(*did), AttributeKind::MustUse { .. }),
|
||||
ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => {
|
||||
// for the Array case we don't need to care for the len == 0 case
|
||||
// because we don't want to lint functions returning empty arrays
|
||||
|
|
@ -337,7 +338,10 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
|
||||
for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() {
|
||||
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||
&& cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use)
|
||||
&& find_attr!(
|
||||
cx.tcx.get_all_attrs(trait_predicate.trait_ref.def_id),
|
||||
AttributeKind::MustUse { .. }
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -347,7 +351,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
ty::Dynamic(binder, _, _) => {
|
||||
for predicate in *binder {
|
||||
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()
|
||||
&& cx.tcx.has_attr(trait_ref.def_id, sym::must_use)
|
||||
&& find_attr!(cx.tcx.get_all_attrs(trait_ref.def_id), AttributeKind::MustUse { .. })
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -853,7 +857,7 @@ pub fn for_each_top_level_late_bound_region<B>(
|
|||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
|
||||
self.index += 1;
|
||||
let res = t.super_visit_with(self);
|
||||
self.index -= 1;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "declare_clippy_lint"
|
||||
version = "0.1.89"
|
||||
version = "0.1.90"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[toolchain]
|
||||
# begin autogenerated nightly
|
||||
channel = "nightly-2025-06-12"
|
||||
channel = "nightly-2025-06-26"
|
||||
# end autogenerated nightly
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ extern crate rustc_interface;
|
|||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
|
||||
// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs
|
||||
// about jemalloc.
|
||||
#[cfg(feature = "jemalloc")]
|
||||
extern crate tikv_jemalloc_sys as jemalloc_sys;
|
||||
|
||||
use clippy_utils::sym;
|
||||
use declare_clippy_lint::LintListBuilder;
|
||||
use rustc_interface::interface;
|
||||
|
|
@ -187,6 +192,36 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne
|
|||
#[allow(clippy::too_many_lines)]
|
||||
#[allow(clippy::ignored_unit_patterns)]
|
||||
pub fn main() {
|
||||
// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs
|
||||
// about jemalloc.
|
||||
#[cfg(feature = "jemalloc")]
|
||||
{
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
||||
#[used]
|
||||
static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
|
||||
#[used]
|
||||
static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = jemalloc_sys::posix_memalign;
|
||||
#[used]
|
||||
static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
|
||||
#[used]
|
||||
static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
|
||||
#[used]
|
||||
static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
|
||||
#[used]
|
||||
static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
unsafe extern "C" {
|
||||
fn _rjem_je_zone_register();
|
||||
}
|
||||
|
||||
#[used]
|
||||
static _F7: unsafe extern "C" fn() = _rjem_je_zone_register;
|
||||
}
|
||||
}
|
||||
|
||||
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
rustc_driver::init_rustc_env_logger(&early_dcx);
|
||||
|
|
|
|||
|
|
@ -9,28 +9,35 @@ if let StmtKind::Let(local) = stmt.kind
|
|||
&& let ExprKind::Call(func, args) = e.kind
|
||||
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = args[0].kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 2
|
||||
&& let ExprKind::Block(block1, None) = args[0].kind
|
||||
&& block1.stmts.len() == 1
|
||||
&& let StmtKind::Let(local1) = block1.stmts[0].kind
|
||||
&& let Some(init1) = local1.init
|
||||
&& let ExprKind::Array(elements) = init1.kind
|
||||
&& elements.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = elements[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
|
||||
&& let ExprKind::Array(elements) = inner.kind
|
||||
&& elements.len() == 2
|
||||
&& let ExprKind::Lit(ref lit) = elements[0].kind
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind
|
||||
&& name.as_str() == "args"
|
||||
&& let Some(trailing_expr) = block1.expr
|
||||
&& let ExprKind::Call(func2, args2) = trailing_expr.kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 2
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 2
|
||||
&& let ExprKind::Lit(ref lit) = elements1[0].kind
|
||||
&& let LitKind::Str(s, _) = lit.node
|
||||
&& s.as_str() == ""
|
||||
&& let ExprKind::Lit(ref lit1) = elements[1].kind
|
||||
&& let ExprKind::Lit(ref lit1) = elements1[1].kind
|
||||
&& let LitKind::Str(s1, _) = lit1.node
|
||||
&& s1.as_str() == "\n"
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 1
|
||||
&& let ExprKind::Call(func2, args2) = elements1[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind
|
||||
&& block.expr.is_none()
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind
|
||||
&& name.as_str() == "print_text"
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind
|
||||
&& name1.as_str() == "print_text"
|
||||
{
|
||||
// report your lint here
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,25 +19,32 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
|
|||
&& let ExprKind::Call(func, args) = e1.kind
|
||||
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = args[0].kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 2
|
||||
&& let ExprKind::Block(block2, None) = args[0].kind
|
||||
&& block2.stmts.len() == 1
|
||||
&& let StmtKind::Let(local) = block2.stmts[0].kind
|
||||
&& let Some(init) = local.init
|
||||
&& let ExprKind::Array(elements) = init.kind
|
||||
&& elements.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = elements[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
|
||||
&& let ExprKind::Array(elements) = inner.kind
|
||||
&& elements.len() == 2
|
||||
&& let ExprKind::Lit(ref lit2) = elements[0].kind
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind
|
||||
&& name1.as_str() == "args"
|
||||
&& let Some(trailing_expr) = block2.expr
|
||||
&& let ExprKind::Call(func2, args2) = trailing_expr.kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 2
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 2
|
||||
&& let ExprKind::Lit(ref lit2) = elements1[0].kind
|
||||
&& let LitKind::Str(s, _) = lit2.node
|
||||
&& s.as_str() == ""
|
||||
&& let ExprKind::Lit(ref lit3) = elements[1].kind
|
||||
&& let ExprKind::Lit(ref lit3) = elements1[1].kind
|
||||
&& let LitKind::Str(s1, _) = lit3.node
|
||||
&& s1.as_str() == "\n"
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 1
|
||||
&& let ExprKind::Call(func2, args2) = elements1[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind
|
||||
&& block1.expr.is_none()
|
||||
&& block.expr.is_none()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,8 +7,14 @@
|
|||
#[link(name = "c")]
|
||||
unsafe extern "C" {}
|
||||
|
||||
#[lang = "pointee_sized"]
|
||||
pub trait PointeeSized {}
|
||||
|
||||
#[lang = "meta_sized"]
|
||||
pub trait MetaSized: PointeeSized {}
|
||||
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
pub trait Sized: MetaSized {}
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
#[lang = "freeze"]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
|
||||
--> tests/ui/def_id_nocore.rs:27:19
|
||||
--> tests/ui/def_id_nocore.rs:33:19
|
||||
|
|
||||
LL | pub fn as_ref(self) -> &'static str {
|
||||
| ^^^^
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
//@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR"
|
||||
//@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR"
|
||||
#![allow(unused, incomplete_features)]
|
||||
#![allow(unused)]
|
||||
#![warn(clippy::large_stack_frames)]
|
||||
#![feature(unsized_locals)]
|
||||
|
||||
use std::hint::black_box;
|
||||
|
||||
|
|
@ -11,11 +10,6 @@ fn generic<T: Default>() {
|
|||
black_box(&x);
|
||||
}
|
||||
|
||||
fn unsized_local() {
|
||||
let x: dyn std::fmt::Display = *(Box::new(1) as Box<dyn std::fmt::Display>);
|
||||
black_box(&x);
|
||||
}
|
||||
|
||||
struct ArrayDefault<const N: usize>([u8; N]);
|
||||
|
||||
impl<const N: usize> Default for ArrayDefault<N> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this function may allocate 250$PTR bytes on the stack
|
||||
--> tests/ui/large_stack_frames.rs:27:4
|
||||
--> tests/ui/large_stack_frames.rs:21:4
|
||||
|
|
||||
LL | fn many_small_arrays() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -13,7 +13,7 @@ LL | let x5 = [0u8; 500_000];
|
|||
= help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
|
||||
|
||||
error: this function may allocate 1000000 bytes on the stack
|
||||
--> tests/ui/large_stack_frames.rs:38:4
|
||||
--> tests/ui/large_stack_frames.rs:32:4
|
||||
|
|
||||
LL | fn large_return_value() -> ArrayDefault<1_000_000> {
|
||||
| ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
||||
|
|
@ -21,7 +21,7 @@ LL | fn large_return_value() -> ArrayDefault<1_000_000> {
|
|||
= note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
||||
|
||||
error: this function may allocate 100$PTR bytes on the stack
|
||||
--> tests/ui/large_stack_frames.rs:44:4
|
||||
--> tests/ui/large_stack_frames.rs:38:4
|
||||
|
|
||||
LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
|
||||
| ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
||||
|
|
@ -29,7 +29,7 @@ LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
|
|||
= note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
||||
|
||||
error: this function may allocate 100$PTR bytes on the stack
|
||||
--> tests/ui/large_stack_frames.rs:51:13
|
||||
--> tests/ui/large_stack_frames.rs:45:13
|
||||
|
|
||||
LL | let f = || black_box(&[0u8; 1_000_000]);
|
||||
| ^^^^^^^^^^^^^^----------------^
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ fn main() {
|
|||
});
|
||||
|
||||
let _ = [0]
|
||||
//~^ suspicious_map
|
||||
.into_iter()
|
||||
.inspect(|&x| {
|
||||
//~^ manual_inspect
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ fn main() {
|
|||
});
|
||||
|
||||
let _ = [0]
|
||||
//~^ suspicious_map
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
//~^ manual_inspect
|
||||
|
|
|
|||
|
|
@ -157,25 +157,8 @@ LL |
|
|||
LL ~ println!("{}", x);
|
||||
|
|
||||
|
||||
error: this call to `map()` won't have an effect on the call to `count()`
|
||||
--> tests/ui/manual_inspect.rs:167:13
|
||||
|
|
||||
LL | let _ = [0]
|
||||
| _____________^
|
||||
LL | |
|
||||
LL | | .into_iter()
|
||||
LL | | .map(|x| {
|
||||
... |
|
||||
LL | | })
|
||||
LL | | .count();
|
||||
| |________________^
|
||||
|
|
||||
= help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
|
||||
= note: `-D clippy::suspicious-map` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`
|
||||
|
||||
error: using `map` over `inspect`
|
||||
--> tests/ui/manual_inspect.rs:170:10
|
||||
--> tests/ui/manual_inspect.rs:169:10
|
||||
|
|
||||
LL | .map(|x| {
|
||||
| ^^^
|
||||
|
|
@ -188,7 +171,7 @@ LL ~ println!("{}", x);
|
|||
|
|
||||
|
||||
error: using `map` over `inspect`
|
||||
--> tests/ui/manual_inspect.rs:203:30
|
||||
--> tests/ui/manual_inspect.rs:202:30
|
||||
|
|
||||
LL | if let Some(x) = Some(1).map(|x| { println!("{x}");
|
||||
| ^^^
|
||||
|
|
@ -200,5 +183,5 @@ LL | // Do not collapse code into this comment
|
|||
LL ~ }) {
|
||||
|
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
//@no-rustfix: overlapping suggestions
|
||||
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec, unused)]
|
||||
#![warn(clippy::single_range_in_vec_init)]
|
||||
#![feature(generic_arg_infer)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macros;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: an array of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:26:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:25:5
|
||||
|
|
||||
LL | [0..200];
|
||||
| ^^^^^^^^
|
||||
|
|
@ -18,7 +18,7 @@ LL + [0; 200];
|
|||
|
|
||||
|
||||
error: a `Vec` of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:28:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:27:5
|
||||
|
|
||||
LL | vec![0..200];
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -35,7 +35,7 @@ LL + vec![0; 200];
|
|||
|
|
||||
|
||||
error: an array of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:30:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:29:5
|
||||
|
|
||||
LL | [0u8..200];
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -52,7 +52,7 @@ LL + [0u8; 200];
|
|||
|
|
||||
|
||||
error: an array of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:32:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:31:5
|
||||
|
|
||||
LL | [0usize..200];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -69,7 +69,7 @@ LL + [0usize; 200];
|
|||
|
|
||||
|
||||
error: an array of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:34:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:33:5
|
||||
|
|
||||
LL | [0..200usize];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -86,7 +86,7 @@ LL + [0; 200usize];
|
|||
|
|
||||
|
||||
error: a `Vec` of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:36:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:35:5
|
||||
|
|
||||
LL | vec![0u8..200];
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -103,7 +103,7 @@ LL + vec![0u8; 200];
|
|||
|
|
||||
|
||||
error: a `Vec` of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:38:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:37:5
|
||||
|
|
||||
LL | vec![0usize..200];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -120,7 +120,7 @@ LL + vec![0usize; 200];
|
|||
|
|
||||
|
||||
error: a `Vec` of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:40:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:39:5
|
||||
|
|
||||
LL | vec![0..200usize];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -137,7 +137,7 @@ LL + vec![0; 200usize];
|
|||
|
|
||||
|
||||
error: an array of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:43:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:42:5
|
||||
|
|
||||
LL | [0..200isize];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -149,7 +149,7 @@ LL + (0..200isize).collect::<std::vec::Vec<isize>>();
|
|||
|
|
||||
|
||||
error: a `Vec` of `Range` that is only one element
|
||||
--> tests/ui/single_range_in_vec_init.rs:45:5
|
||||
--> tests/ui/single_range_in_vec_init.rs:44:5
|
||||
|
|
||||
LL | vec![0..200isize];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue