Skip to content

Rustup #15148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Jun 26, 2025
Merged

Rustup #15148

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dd0fa3d
Add jemalloc feature to Clippy
Kobzol Jun 10, 2025
4cb48c8
stabilize gai
BoxyUwU Jun 11, 2025
d03d226
avoid `&mut P<T>` in `visit_expr` etc methods
fee1-dead Jun 11, 2025
97a2d5b
intrinsics: rename min_align_of to align_of
RalfJung Jun 12, 2025
88d2983
Unimplement unsized_locals
mejrs Jun 12, 2025
cbd683f
Merge commit '4ef75291b5dd6739212f1f61666d19d4e086690d' into clippy-s…
flip1995 Jun 13, 2025
7e25bb1
Move COERCE_CONTAINER_TO_ANY to nursery, as it has FPs
flip1995 Jun 13, 2025
3dbb497
Auto merge of #142451 - flip1995:clippy-subtree-update, r=Manishearth
bors Jun 13, 2025
81f9f08
TypeVisiting binders no longer requires TypeFolding its interior
compiler-errors Jun 12, 2025
3d8d575
Reduce precedence of expressions that have an outer attr
dtolnay Jun 13, 2025
252a6dd
Rollup merge of #141811 - mejrs:bye_locals, r=compiler-errors
matthiaskrgr Jun 14, 2025
9f96120
Rollup merge of #134661 - dtolnay:prefixattr, r=fmease
fmease Jun 15, 2025
c7ee095
clippy: add `MetaSized` conditions
davidtwco Mar 3, 2025
765015d
clippy: `{Meta,Pointee,}Sized` in non-minicore
davidtwco Mar 3, 2025
697b4f8
convert entire codebase to parsed inline attrs
jdonszelmann Mar 7, 2025
4b60d49
Rollup merge of #142371 - fee1-dead-contrib:push-xqlkumzurkus, r=petr…
jhpratt Jun 17, 2025
bc2ed2c
fix clippy
jdonszelmann Jun 10, 2025
76d583b
Auto merge of #138165 - jdonszelmann:inline, r=oli-obk
bors Jun 18, 2025
a01dd1e
Update/bless clippy tests.
m-ou-se Jun 4, 2025
62a36e6
Rollup merge of #141610 - BoxyUwU:stabilize_generic_arg_infer, r=lcnr…
Kobzol Jun 18, 2025
ade2682
Extract Translator struct
camsteffen Jun 19, 2025
73273f2
Auto merge of #140748 - m-ou-se:super-format-args3, r=jdonszelmann
bors Jun 19, 2025
ee648ed
Avoid some unnecessary symbol interning.
nnethercote May 29, 2025
42614bf
Auto merge of #142286 - Kobzol:clippy-jemalloc, r=flip1995,blyxyas
bors Jun 20, 2025
65402ab
clippy: replace path uses by diagnostic items
samueltardieu Jun 20, 2025
5f759a9
Rollup merge of #142650 - camsteffen:refactor-translator, r=petrochenkov
tgross35 Jun 20, 2025
f337ae6
Rollup merge of #142767 - nnethercote:symbol-cleanups, r=petrochenkov
Kobzol Jun 20, 2025
f53cd2b
Auto merge of #142794 - tgross35:rollup-iae7okj, r=tgross35
bors Jun 20, 2025
f027fc8
Rollup merge of #142787 - samueltardieu:diag-items-for-clippy, r=Mani…
matthiaskrgr Jun 21, 2025
953bf2b
All HIR attributes are outer
dtolnay Jun 20, 2025
b92cccb
Port `#[must_use]` to new attribute parsing infrastructure
JonathanBrouwer Jun 22, 2025
1d764e0
Port `#[no_mangle]` to new attribute parsing infrastructure
JonathanBrouwer Jun 22, 2025
05b74d5
update to literal-escaper 0.0.4 for better API without `unreachable` …
hkBst Mar 7, 2025
ae6ab44
fix clippy
jdonszelmann Jun 21, 2025
4a4d672
Auto merge of #140999 - hkBst:update-escaper, r=nnethercote
bors Jun 25, 2025
708ffd5
Auto merge of #142997 - workingjubilee:rollup-6lxec87, r=workingjubilee
bors Jun 25, 2025
90364dd
Merge remote-tracking branch 'upstream/master' into rustup
flip1995 Jun 26, 2025
9b41d8f
Bump nightly version -> 2025-06-26
flip1995 Jun 26, 2025
32fcff8
Bump Clippy version -> 0.1.90
flip1995 Jun 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion clippy_config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clippy_config"
version = "0.1.89"
version = "0.1.90"
edition = "2024"
publish = false

Expand Down
8 changes: 2 additions & 6 deletions clippy_dev/src/update_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
25 changes: 9 additions & 16 deletions clippy_lints/src/attrs/inline_always.rs
Original file line number Diff line number Diff line change
@@ -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"),
);
}
}
2 changes: 1 addition & 1 deletion clippy_lints/src/bool_assert_comparison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down
5 changes: 2 additions & 3 deletions clippy_lints/src/casts/manual_dangling_ptr.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/casts/unnecessary_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/coerce_container_to_any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
10 changes: 5 additions & 5 deletions clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 6 additions & 3 deletions clippy_lints/src/doc/doc_suspicious_footnotes.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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/** ", " */"),
Expand Down
5 changes: 2 additions & 3 deletions clippy_lints/src/doc/needless_doctest_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
5 changes: 3 additions & 2 deletions clippy_lints/src/eta_reduction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
68 changes: 49 additions & 19 deletions clippy_lints/src/functions/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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) {
Expand All @@ -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<'_>,
) {
Expand All @@ -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 {
Expand All @@ -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());
Expand Down
Loading