Skip to content

Commit c950602

Browse files
authored
Rustup (#15148)
r? @ghost changelog: none
2 parents 8050e59 + 32fcff8 commit c950602

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+277
-213
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clippy"
3-
version = "0.1.89"
3+
version = "0.1.90"
44
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
55
repository = "https://github.com/rust-lang/rust-clippy"
66
readme = "README.md"
@@ -59,6 +59,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
5959
[features]
6060
integration = ["dep:tempfile"]
6161
internal = ["dep:clippy_lints_internal", "dep:tempfile"]
62+
jemalloc = []
6263

6364
[package.metadata.rust-analyzer]
6465
# This package uses #[feature(rustc_private)]

clippy_config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clippy_config"
3-
version = "0.1.89"
3+
version = "0.1.90"
44
edition = "2024"
55
publish = false
66

clippy_dev/src/update_lints.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,17 +386,13 @@ pub fn read_deprecated_lints() -> (Vec<DeprecatedLint>, Vec<RenamedLint>) {
386386

387387
/// Removes the line splices and surrounding quotes from a string literal
388388
fn parse_str_lit(s: &str) -> String {
389-
let (s, mode) = if let Some(s) = s.strip_prefix("r") {
390-
(s.trim_matches('#'), rustc_literal_escaper::Mode::RawStr)
391-
} else {
392-
(s, rustc_literal_escaper::Mode::Str)
393-
};
389+
let s = s.strip_prefix("r").unwrap_or(s).trim_matches('#');
394390
let s = s
395391
.strip_prefix('"')
396392
.and_then(|s| s.strip_suffix('"'))
397393
.unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
398394
let mut res = String::with_capacity(s.len());
399-
rustc_literal_escaper::unescape_unicode(s, mode, &mut |_, ch| {
395+
rustc_literal_escaper::unescape_str(s, &mut |_, ch| {
400396
if let Ok(ch) = ch {
401397
res.push(ch);
402398
}

clippy_lints/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clippy_lints"
3-
version = "0.1.89"
3+
version = "0.1.90"
44
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
55
repository = "https://github.com/rust-lang/rust-clippy"
66
readme = "README.md"
Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
use super::INLINE_ALWAYS;
2-
use super::utils::is_word;
32
use clippy_utils::diagnostics::span_lint;
3+
use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr};
44
use rustc_hir::Attribute;
55
use rustc_lint::LateContext;
6+
use rustc_span::Span;
67
use rustc_span::symbol::Symbol;
7-
use rustc_span::{Span, sym};
88

99
pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
1010
if span.from_expansion() {
1111
return;
1212
}
1313

14-
for attr in attrs {
15-
if let Some(values) = attr.meta_item_list() {
16-
if values.len() != 1 || !attr.has_name(sym::inline) {
17-
continue;
18-
}
19-
if is_word(&values[0], sym::always) {
20-
span_lint(
21-
cx,
22-
INLINE_ALWAYS,
23-
attr.span(),
24-
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
25-
);
26-
}
27-
}
14+
if let Some(span) = find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, span) => *span) {
15+
span_lint(
16+
cx,
17+
INLINE_ALWAYS,
18+
span,
19+
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
20+
);
2821
}
2922
}

clippy_lints/src/bool_assert_comparison.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
5656
.and_then(|trait_id| {
5757
cx.tcx.associated_items(trait_id).find_by_ident_and_kind(
5858
cx.tcx,
59-
Ident::from_str("Output"),
59+
Ident::with_dummy_span(sym::Output),
6060
ty::AssocTag::Type,
6161
trait_id,
6262
)

clippy_lints/src/casts/manual_dangling_ptr.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::SpanRangeExt;
3-
use clippy_utils::{expr_or_init, path_def_id, paths, std_or_core};
3+
use clippy_utils::{expr_or_init, is_path_diagnostic_item, std_or_core, sym};
44
use rustc_ast::LitKind;
55
use rustc_errors::Applicability;
66
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<'_>) ->
5353

5454
fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {
5555
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind
56-
&& let Some(fun_id) = path_def_id(cx, fun)
57-
&& paths::ALIGN_OF.matches(cx, fun_id)
56+
&& is_path_diagnostic_item(cx, fun, sym::mem_align_of)
5857
&& let Some(args) = path.segments.last().and_then(|seg| seg.args)
5958
&& let [GenericArg::Type(generic_ty)] = args.args
6059
{

clippy_lints/src/casts/unnecessary_cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ pub(super) fn check<'tcx>(
185185
Node::Expr(parent) if is_borrow_expr(cx, parent) && !is_in_allowed_macro(cx, parent) => {
186186
MaybeParenOrBlock::Block
187187
},
188-
Node::Expr(parent) if cast_expr.precedence() < parent.precedence() => MaybeParenOrBlock::Paren,
188+
Node::Expr(parent) if cx.precedence(cast_expr) < cx.precedence(parent) => MaybeParenOrBlock::Paren,
189189
_ => MaybeParenOrBlock::Nothing,
190190
};
191191

clippy_lints/src/coerce_container_to_any.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ declare_clippy_lint! {
4242
/// ```
4343
#[clippy::version = "1.88.0"]
4444
pub COERCE_CONTAINER_TO_ANY,
45-
suspicious,
45+
nursery,
4646
"coercing to `&dyn Any` when dereferencing could produce a `dyn Any` without coercion is usually not intended"
4747
}
4848
declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);

clippy_lints/src/dereference.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ fn report<'tcx>(
972972
"&"
973973
};
974974

975-
let expr_str = if !expr_is_macro_call && is_ufcs && expr.precedence() < ExprPrecedence::Prefix {
975+
let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix {
976976
Cow::Owned(format!("({expr_str})"))
977977
} else {
978978
expr_str
@@ -1015,10 +1015,10 @@ fn report<'tcx>(
10151015
Node::Expr(e) => match e.kind {
10161016
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,
10171017
ExprKind::Call(..) => {
1018-
expr.precedence() < ExprPrecedence::Unambiguous
1018+
cx.precedence(expr) < ExprPrecedence::Unambiguous
10191019
|| matches!(expr.kind, ExprKind::Field(..))
10201020
},
1021-
_ => expr.precedence() < e.precedence(),
1021+
_ => cx.precedence(expr) < cx.precedence(e),
10221022
},
10231023
_ => false,
10241024
};
@@ -1066,7 +1066,7 @@ fn report<'tcx>(
10661066
Mutability::Not => "&",
10671067
Mutability::Mut => "&mut ",
10681068
};
1069-
(prefix, expr.precedence() < ExprPrecedence::Prefix)
1069+
(prefix, cx.precedence(expr) < ExprPrecedence::Prefix)
10701070
},
10711071
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false),
10721072
_ => ("", false),
@@ -1172,7 +1172,7 @@ impl<'tcx> Dereferencing<'tcx> {
11721172
},
11731173
Some(parent) if !parent.span.from_expansion() => {
11741174
// Double reference might be needed at this point.
1175-
if parent.precedence() == ExprPrecedence::Unambiguous {
1175+
if cx.precedence(parent) == ExprPrecedence::Unambiguous {
11761176
// Parentheses would be needed here, don't lint.
11771177
*outer_pat = None;
11781178
} else {

clippy_lints/src/doc/doc_suspicious_footnotes.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2+
use rustc_ast::attr::AttributeExt as _;
23
use rustc_ast::token::CommentKind;
34
use rustc_errors::Applicability;
45
use rustc_hir::{AttrStyle, Attribute};
@@ -43,13 +44,15 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F
4344
"looks like a footnote ref, but has no matching footnote",
4445
|diag| {
4546
if this_fragment.kind == DocFragmentKind::SugaredDoc {
46-
let (doc_attr, (_, doc_attr_comment_kind)) = attrs
47+
let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs
4748
.iter()
4849
.filter(|attr| attr.span().overlaps(this_fragment.span))
4950
.rev()
50-
.find_map(|attr| Some((attr, attr.doc_str_and_comment_kind()?)))
51+
.find_map(|attr| {
52+
Some((attr, attr.doc_str_and_comment_kind()?, attr.doc_resolution_scope()?))
53+
})
5154
.unwrap();
52-
let (to_add, terminator) = match (doc_attr_comment_kind, doc_attr.style()) {
55+
let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) {
5356
(CommentKind::Line, AttrStyle::Outer) => ("\n///\n/// ", ""),
5457
(CommentKind::Line, AttrStyle::Inner) => ("\n//!\n//! ", ""),
5558
(CommentKind::Block, AttrStyle::Outer) => ("\n/** ", " */"),

clippy_lints/src/doc/needless_doctest_main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ pub fn check(
4242
let mut test_attr_spans = vec![];
4343
let filename = FileName::anon_source_code(&code);
4444

45-
let fallback_bundle =
46-
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
47-
let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
45+
let translator = rustc_driver::default_translator();
46+
let emitter = HumanEmitter::new(Box::new(io::sink()), translator);
4847
let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
4948
#[expect(clippy::arc_with_non_send_sync)] // `Arc` is expected by with_dcx
5049
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));

clippy_lints/src/eta_reduction.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use clippy_utils::{
77
get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
88
};
99
use rustc_abi::ExternAbi;
10+
use rustc_attr_data_structures::{AttributeKind, find_attr};
1011
use rustc_errors::Applicability;
1112
use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind};
1213
use rustc_infer::infer::TyCtxtInferExt;
@@ -161,7 +162,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
161162
let sig = match callee_ty_adjusted.kind() {
162163
ty::FnDef(def, _) => {
163164
// Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`
164-
if cx.tcx.has_attr(*def, sym::track_caller) {
165+
if find_attr!(cx.tcx.get_all_attrs(*def), AttributeKind::TrackCaller(..)) {
165166
return;
166167
}
167168

@@ -249,7 +250,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
249250
},
250251
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
251252
if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)
252-
&& !cx.tcx.has_attr(method_def_id, sym::track_caller)
253+
&& !find_attr!(cx.tcx.get_all_attrs(method_def_id), AttributeKind::TrackCaller(..))
253254
&& check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
254255
{
255256
let mut app = Applicability::MachineApplicable;

clippy_lints/src/functions/must_use.rs

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use clippy_utils::source::SpanRangeExt;
1414
use clippy_utils::ty::is_must_use_ty;
1515
use clippy_utils::visitors::for_each_expr_without_closures;
1616
use clippy_utils::{return_ty, trait_ref_of_method};
17+
use rustc_attr_data_structures::{AttributeKind, find_attr};
18+
use rustc_span::Symbol;
1719
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
1820

1921
use core::ops::ControlFlow;
@@ -22,7 +24,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
2224

2325
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
2426
let attrs = cx.tcx.hir_attrs(item.hir_id());
25-
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
27+
let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
2628
if let hir::ItemKind::Fn {
2729
ref sig,
2830
body: ref body_id,
@@ -31,9 +33,19 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
3133
{
3234
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
3335
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
34-
if let Some(attr) = attr {
35-
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
36-
} else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
36+
if let Some((attr_span, reason)) = attr {
37+
check_needless_must_use(
38+
cx,
39+
sig.decl,
40+
item.owner_id,
41+
item.span,
42+
fn_header_span,
43+
*attr_span,
44+
*reason,
45+
attrs,
46+
sig,
47+
);
48+
} else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs, AttributeKind::NoMangle(..)) {
3749
check_must_use_candidate(
3850
cx,
3951
sig.decl,
@@ -52,9 +64,20 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
5264
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
5365
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
5466
let attrs = cx.tcx.hir_attrs(item.hir_id());
55-
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
56-
if let Some(attr) = attr {
57-
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
67+
let attr =
68+
find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
69+
if let Some((attr_span, reason)) = attr {
70+
check_needless_must_use(
71+
cx,
72+
sig.decl,
73+
item.owner_id,
74+
item.span,
75+
fn_header_span,
76+
*attr_span,
77+
*reason,
78+
attrs,
79+
sig,
80+
);
5881
} else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() {
5982
check_must_use_candidate(
6083
cx,
@@ -75,9 +98,20 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
7598
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
7699

77100
let attrs = cx.tcx.hir_attrs(item.hir_id());
78-
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
79-
if let Some(attr) = attr {
80-
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
101+
let attr =
102+
find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
103+
if let Some((attr_span, reason)) = attr {
104+
check_needless_must_use(
105+
cx,
106+
sig.decl,
107+
item.owner_id,
108+
item.span,
109+
fn_header_span,
110+
*attr_span,
111+
*reason,
112+
attrs,
113+
sig,
114+
);
81115
} else if let hir::TraitFn::Provided(eid) = *eid {
82116
let body = cx.tcx.hir_body(eid);
83117
if attr.is_none() && is_public && !is_proc_macro(attrs) {
@@ -103,7 +137,8 @@ fn check_needless_must_use(
103137
item_id: hir::OwnerId,
104138
item_span: Span,
105139
fn_header_span: Span,
106-
attr: &Attribute,
140+
attr_span: Span,
141+
reason: Option<Symbol>,
107142
attrs: &[Attribute],
108143
sig: &FnSig<'_>,
109144
) {
@@ -118,12 +153,7 @@ fn check_needless_must_use(
118153
fn_header_span,
119154
"this unit-returning function has a `#[must_use]` attribute",
120155
|diag| {
121-
diag.span_suggestion(
122-
attr.span(),
123-
"remove the attribute",
124-
"",
125-
Applicability::MachineApplicable,
126-
);
156+
diag.span_suggestion(attr_span, "remove the attribute", "", Applicability::MachineApplicable);
127157
},
128158
);
129159
} else {
@@ -137,11 +167,11 @@ fn check_needless_must_use(
137167
MUST_USE_UNIT,
138168
fn_header_span,
139169
"this unit-returning function has a `#[must_use]` attribute",
140-
Some(attr.span()),
170+
Some(attr_span),
141171
"remove `must_use`",
142172
);
143173
}
144-
} else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
174+
} else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
145175
// Ignore async functions unless Future::Output type is a must_use type
146176
if sig.header.is_async() {
147177
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());

0 commit comments

Comments
 (0)