Skip to content

Commit 7ae3bce

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents 42a0303 + 6e0c7d6 commit 7ae3bce

142 files changed

Lines changed: 2908 additions & 411 deletions

File tree

Some content is hidden

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

.github/workflows/clippy_mq.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ jobs:
135135
find $DIR ! -executable -o -type d ! -path $DIR | xargs rm -rf
136136
137137
- name: Upload Binaries
138-
uses: actions/upload-artifact@v4
138+
uses: actions/upload-artifact@v7
139139
with:
140140
name: binaries
141141
path: target/debug
@@ -179,7 +179,7 @@ jobs:
179179
180180
# Download
181181
- name: Download target dir
182-
uses: actions/download-artifact@v6
182+
uses: actions/download-artifact@v8
183183
with:
184184
name: binaries
185185
path: target/debug

.github/workflows/lintcheck.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
4545
- name: Cache lintcheck bin
4646
id: cache-lintcheck-bin
47-
uses: actions/cache@v4
47+
uses: actions/cache@v5
4848
with:
4949
path: target/debug/lintcheck
5050
key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}
@@ -59,7 +59,7 @@ jobs:
5959

6060
- name: Cache results JSON
6161
id: cache-json
62-
uses: actions/cache@v4
62+
uses: actions/cache@v5
6363
with:
6464
path: lintcheck-logs/ci_crates_logs.json
6565
key: ${{ steps.key.outputs.key }}
@@ -69,7 +69,7 @@ jobs:
6969
run: env CLIPPY_CONF_DIR="$PWD/lintcheck/ci-config" ./target/debug/lintcheck --format json --all-lints --crates-toml ./lintcheck/ci_crates.toml
7070

7171
- name: Upload base JSON
72-
uses: actions/upload-artifact@v4
72+
uses: actions/upload-artifact@v7
7373
with:
7474
name: base
7575
path: lintcheck-logs/ci_crates_logs.json
@@ -87,7 +87,7 @@ jobs:
8787

8888
- name: Cache lintcheck bin
8989
id: cache-lintcheck-bin
90-
uses: actions/cache@v4
90+
uses: actions/cache@v5
9191
with:
9292
path: target/debug/lintcheck
9393
key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}
@@ -100,7 +100,7 @@ jobs:
100100
run: env CLIPPY_CONF_DIR="$PWD/lintcheck/ci-config" ./target/debug/lintcheck --format json --all-lints --crates-toml ./lintcheck/ci_crates.toml
101101

102102
- name: Upload head JSON
103-
uses: actions/upload-artifact@v4
103+
uses: actions/upload-artifact@v7
104104
with:
105105
name: head
106106
path: lintcheck-logs/ci_crates_logs.json
@@ -119,14 +119,14 @@ jobs:
119119
persist-credentials: false
120120

121121
- name: Restore lintcheck bin
122-
uses: actions/cache/restore@v4
122+
uses: actions/cache/restore@v5
123123
with:
124124
path: target/debug/lintcheck
125125
key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}
126126
fail-on-cache-miss: true
127127

128128
- name: Download JSON
129-
uses: actions/download-artifact@v5
129+
uses: actions/download-artifact@v8
130130

131131
- name: Store PR number
132132
run: echo ${{ github.event.pull_request.number }} > pr.txt
@@ -140,13 +140,13 @@ jobs:
140140
./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --write-summary summary.json > full_diff.md
141141
142142
- name: Upload full diff
143-
uses: actions/upload-artifact@v4
143+
uses: actions/upload-artifact@v7
144144
with:
145145
name: full_diff
146146
path: full_diff.md
147147

148148
- name: Upload summary
149-
uses: actions/upload-artifact@v4
149+
uses: actions/upload-artifact@v7
150150
with:
151151
name: summary
152152
path: |

.github/workflows/lintcheck_summary.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ jobs:
2727
if: ${{ github.event.workflow_run.conclusion == 'success' }}
2828
steps:
2929
- name: Download artifact
30-
uses: actions/download-artifact@v5
30+
uses: actions/download-artifact@v8
3131
with:
3232
name: summary
3333
path: untrusted
3434
run-id: ${{ github.event.workflow_run.id }}
3535
github-token: ${{ github.token }}
3636

3737
- name: Format comment
38-
uses: actions/github-script@v8
38+
uses: actions/github-script@v9
3939
with:
4040
script: |
4141
const fs = require("fs");

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6804,6 +6804,7 @@ Released 2018-09-13
68046804
[`inline_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_att_syntax
68056805
[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_intel_syntax
68066806
[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body
6807+
[`inline_modules`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_modules
68076808
[`inspect_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#inspect_for_each
68086809
[`int_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#int_plus_one
68096810
[`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_arithmetic
@@ -6878,6 +6879,7 @@ Released 2018-09-13
68786879
[`main_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#main_recursion
68796880
[`manual_abs_diff`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff
68806881
[`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert
6882+
[`manual_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert_eq
68816883
[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
68826884
[`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits
68836885
[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals
@@ -7393,6 +7395,7 @@ Released 2018-09-13
73937395
[`used_underscore_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_items
73947396
[`useless_asref`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref
73957397
[`useless_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_attribute
7398+
[`useless_borrows_in_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_borrows_in_formatting
73967399
[`useless_concat`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_concat
73977400
[`useless_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
73987401
[`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format

clippy_dev/src/new_lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
502502
file_contents.replace_range(arr_start + 1..arr_end, &new_arr_content);
503503

504504
// Just add the mod declaration at the top, it'll be fixed by rustfmt
505-
file_contents.insert_str(0, &format!("mod {};\n", &lint.name));
505+
file_contents.insert_str(0, &format!("mod {};\n", lint.name));
506506

507507
let mut file = OpenOptions::new()
508508
.write(true)

clippy_lints/src/arbitrary_source_item_ordering.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,15 +307,15 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
307307
}
308308
},
309309
ItemKind::Trait {
310-
impl_restriction:_,
311-
constness:_,
310+
impl_restriction: _,
311+
constness: _,
312312
is_auto,
313-
safety:_,
314-
ident:_,
313+
safety: _,
314+
ident: _,
315315
generics: _,
316316
bounds: _,
317-
items: item_ref}
318-
if self.enable_ordering_for_trait && *is_auto == IsAuto::No => {
317+
items: item_ref,
318+
} if self.enable_ordering_for_trait && *is_auto == IsAuto::No => {
319319
let mut cur_t: Option<(TraitItemId, Ident)> = None;
320320

321321
for &item in *item_ref {

clippy_lints/src/bool_assert_comparison.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ use clippy_utils::source::walk_span_to_context;
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::sym;
66
use clippy_utils::ty::{implements_trait, is_copy};
7-
use rustc_middle::ty::Unnormalized;
87
use rustc_ast::ast::LitKind;
98
use rustc_errors::Applicability;
109
use rustc_hir::{Expr, ExprKind, Lit};
1110
use rustc_lint::{LateContext, LateLintPass, LintContext};
12-
use rustc_middle::ty::{self, Ty};
11+
use rustc_middle::ty::{self, Ty, Unnormalized};
1312
use rustc_session::declare_lint_pass;
1413
use rustc_span::symbol::Ident;
1514

@@ -65,7 +64,9 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
6564
})
6665
.is_some_and(|assoc_item| {
6766
let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
68-
let nty = cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(proj));
67+
let nty = cx
68+
.tcx
69+
.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(proj));
6970

7071
nty.is_bool()
7172
})

clippy_lints/src/booleans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ impl SuggestContext<'_, '_, '_> {
360360
if app != Applicability::MachineApplicable {
361361
return None;
362362
}
363-
let _cannot_fail = write!(&mut self.output, "{}", &(!snip));
363+
let _cannot_fail = write!(&mut self.output, "{}", !snip);
364364
}
365365
},
366366
True | False | Not(_) => {

clippy_lints/src/casts/cast_ptr_alignment.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
5959
if matches!(name.ident.name, sym::read_unaligned | sym::write_unaligned)
6060
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
6161
&& let Some(def_id) = cx.tcx.impl_of_assoc(def_id)
62-
&& cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().is_raw_ptr()
62+
&& cx
63+
.tcx
64+
.type_of(def_id)
65+
.instantiate_identity()
66+
.skip_norm_wip()
67+
.is_raw_ptr()
6368
{
6469
true
6570
} else {

clippy_lints/src/cloned_ref_to_slice_refs.rs

Lines changed: 107 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
use std::ops::ControlFlow;
2+
13
use clippy_config::Conf;
24
use clippy_utils::diagnostics::span_lint_and_sugg;
35
use clippy_utils::msrvs::{self, Msrv};
46
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
57
use clippy_utils::sugg::Sugg;
68
use clippy_utils::visitors::is_const_evaluatable;
7-
use clippy_utils::{is_in_const_context, is_mutable};
9+
use clippy_utils::{is_in_const_context, is_mutable, sym};
10+
use rustc_ast::Mutability;
811
use rustc_errors::Applicability;
9-
use rustc_hir::{Expr, ExprKind};
12+
use rustc_hir::{Expr, ExprKind, HirId, LangItem};
1013
use rustc_lint::{LateContext, LateLintPass};
14+
use rustc_middle::ty;
15+
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind, OverloadedDeref};
1116
use rustc_session::impl_lint_pass;
12-
use rustc_span::sym;
17+
use rustc_span::Symbol;
18+
19+
use crate::methods::is_clone_like;
1320

1421
declare_clippy_lint! {
1522
/// ### What it does
@@ -73,29 +80,116 @@ impl<'tcx> LateLintPass<'tcx> for ClonedRefToSliceRefs<'_> {
7380
&& let ExprKind::Array([item]) = &arr.kind
7481

7582
// check for clones
76-
&& let ExprKind::MethodCall(_, val, _, _) = item.kind
77-
&& cx.ty_based_def(item).opt_parent(cx).is_diag_item(cx, sym::Clone)
83+
&& let ExprKind::MethodCall(path, recv, _, _) = item.kind
84+
&& let Some(adjustment) = is_needless_clone_or_equivalent(cx, recv, path.ident.name, item.hir_id)
7885

7986
// check for immutability or purity
80-
&& (!is_mutable(cx, val) || is_const_evaluatable(cx, val))
87+
&& (!is_mutable(cx, recv) || is_const_evaluatable(cx, recv))
8188

8289
// get appropriate crate for `slice::from_ref`
8390
&& let Some(builtin_crate) = clippy_utils::std_or_core(cx)
8491
{
85-
let mut sugg = Sugg::hir(cx, val, "_");
86-
if !cx.typeck_results().expr_ty(val).is_ref() {
87-
sugg = sugg.addr();
88-
}
92+
let mut applicability = Applicability::MachineApplicable;
93+
let sugg = Sugg::hir_with_context(cx, recv, expr.span.ctxt(), "_", &mut applicability);
8994

9095
span_lint_and_sugg(
9196
cx,
9297
CLONED_REF_TO_SLICE_REFS,
9398
expr.span,
94-
format!("this call to `clone` can be replaced with `{builtin_crate}::slice::from_ref`"),
99+
format!(
100+
"unnecessary use of `{}` to create a slice from a reference",
101+
path.ident.name
102+
),
95103
"try",
96-
format!("{builtin_crate}::slice::from_ref({sugg})"),
97-
Applicability::MaybeIncorrect,
104+
format!("{builtin_crate}::slice::from_ref({adjustment}{sugg})"),
105+
applicability,
98106
);
99107
}
100108
}
101109
}
110+
111+
/// Checks if a method call is a needless clone or equivalent. If so, returns the necessary
112+
/// adjustments to use the method receiver directly without cloning.
113+
/// For example, in the code below:
114+
/// ```rust,no_run
115+
/// use std::path::PathBuf;
116+
///
117+
/// let w = &PathBuf::new();
118+
/// let b = &[w.to_path_buf()];
119+
/// ```
120+
/// We would replace `&[w.to_path_buf()]` with `std::slice::from_ref(&*w)`,
121+
/// hence we return `Some("&*")` as the adjustment.
122+
fn is_needless_clone_or_equivalent<'tcx>(
123+
cx: &LateContext<'tcx>,
124+
method_recv: &'tcx Expr<'tcx>,
125+
method_name: Symbol,
126+
hir_id: HirId,
127+
) -> Option<String> {
128+
let method_def = cx.ty_based_def(hir_id).opt_parent(cx)?;
129+
if !method_def.is_lang_item(cx, LangItem::Clone) && !is_clone_like(cx, method_name, method_def) {
130+
return None;
131+
}
132+
133+
let method_ret_ty = cx.typeck_results().node_type(hir_id);
134+
let method_recv_ty = cx.typeck_results().expr_ty_adjusted(method_recv);
135+
let ty::Ref(_, method_recv_ty_inner, Mutability::Not) = method_recv_ty.kind() else {
136+
return None;
137+
};
138+
139+
let method_recv_adjustments = cx.typeck_results().expr_adjustments(method_recv);
140+
141+
// The return type of the clone-like method should be the same as the inner type of the reference
142+
// being cloned, except for the following special cases:
143+
// 1. `OsString`, which is first dereferenced to `OsStr` and the borrowed as `&OsStr`.
144+
// 2. `PathBuf`, which is first dereferenced to `Path` and then borrowed as `&Path`.
145+
let adjust_target_ty = if method_ret_ty == *method_recv_ty_inner {
146+
method_ret_ty
147+
} else if let Some(after_special_case_ty_name @ (sym::OsStr | sym::Path)) = method_recv_ty_inner.opt_diag_name(cx)
148+
// Looking for the `OSString -> OSStr` or `PathBuf -> Path` adjustment in the abovementioned special cases
149+
&& let [preceeding_derefs @ .., special_case, last_borrow] = method_recv_adjustments
150+
&& matches!(
151+
special_case.kind,
152+
Adjust::Deref(DerefAdjustKind::Overloaded(OverloadedDeref {
153+
mutbl: Mutability::Not,
154+
..
155+
}))
156+
)
157+
&& matches!(last_borrow.kind, Adjust::Borrow(_))
158+
&& special_case.target.is_diag_item(cx, after_special_case_ty_name)
159+
&& let before_special_case_ty = preceeding_derefs
160+
.last().map_or_else(|| cx.typeck_results().expr_ty(method_recv), |a| a.target)
161+
&& matches!(
162+
(before_special_case_ty.opt_diag_name(cx)?, after_special_case_ty_name),
163+
(sym::OsString, sym::OsStr) | (sym::PathBuf, sym::Path))
164+
{
165+
before_special_case_ty
166+
} else {
167+
return None;
168+
};
169+
170+
// Find the number of adjustments required until `method_recv_ty_source` becomes `adjust_target_ty`
171+
let method_recv_ty_source = cx.typeck_results().expr_ty(method_recv);
172+
let adjust_count = method_recv_adjustments
173+
.iter()
174+
.enumerate()
175+
.try_fold(method_recv_ty_source, |ty, (i, a)| {
176+
if ty == adjust_target_ty {
177+
ControlFlow::Break(i)
178+
} else {
179+
ControlFlow::Continue(a.target)
180+
}
181+
})
182+
.break_value()?;
183+
184+
let (needs_borrow, deref_count) = if adjust_count == 0 || !method_recv_ty_source.is_ref() {
185+
(true, adjust_count)
186+
} else {
187+
(false, adjust_count - 1)
188+
};
189+
190+
Some(if needs_borrow {
191+
format!("&{}", "*".repeat(deref_count))
192+
} else {
193+
"*".repeat(deref_count)
194+
})
195+
}

0 commit comments

Comments
 (0)