Skip to content

Commit e2e4278

Browse files
authored
Merge branch 'rust-lang:master' into master
2 parents 7a8b355 + 08c429f commit e2e4278

21 files changed

+247
-148
lines changed

book/src/development/adding_lints.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ impl EarlyLintPass for FooFunctions {}
261261
[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
262262
[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
263263
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
264-
[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
264+
[category_level_mapping]: ../index.html
265265

266266
## Lint registration
267267

clippy_lints/src/implicit_hasher.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use rustc_hir as hir;
66
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
77
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
88
use rustc_hir_analysis::hir_ty_to_ty;
9-
use rustc_lint::{LateContext, LateLintPass, LintContext};
9+
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_middle::hir::nested_filter;
11-
use rustc_middle::lint::in_external_macro;
1211
use rustc_middle::ty::{Ty, TypeckResults};
1312
use rustc_session::{declare_lint_pass, declare_tool_lint};
1413
use rustc_span::source_map::Span;
@@ -162,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
162161
vis.visit_ty(ty);
163162

164163
for target in &vis.found {
165-
if in_external_macro(cx.sess(), generics.span) {
164+
if generics.span.from_expansion() {
166165
continue;
167166
}
168167
let generics_suggestion_span = generics.span.substitute_dummy({

clippy_lints/src/needless_pass_by_ref_mut.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ declare_clippy_lint! {
4949
/// ```
5050
#[clippy::version = "1.72.0"]
5151
pub NEEDLESS_PASS_BY_REF_MUT,
52-
suspicious,
52+
nursery,
5353
"using a `&mut` argument when it's not mutated"
5454
}
5555

clippy_lints/src/write.rs

+47-3
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,9 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
486486
&& let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind
487487
&& !arg.expr.span.from_expansion()
488488
&& let Some(value_string) = snippet_opt(cx, arg.expr.span)
489-
{
489+
{
490490
let (replacement, replace_raw) = match lit.kind {
491-
LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {
491+
LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {
492492
Some(extracted) => extracted,
493493
None => return,
494494
},
@@ -538,7 +538,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
538538
// `format!("{}", "a")`, `format!("{named}", named = "b")
539539
// ~~~~~ ~~~~~~~~~~~~~
540540
&& let Some(removal_span) = format_arg_removal_span(format_args, index) {
541-
let replacement = replacement.replace('{', "{{").replace('}', "}}");
541+
let replacement = escape_braces(&replacement, !format_string_is_raw && !replace_raw);
542542
suggestion.push((*placeholder_span, replacement));
543543
suggestion.push((removal_span, String::new()));
544544
}
@@ -631,3 +631,47 @@ fn conservative_unescape(literal: &str) -> Result<String, UnescapeErr> {
631631

632632
if err { Err(UnescapeErr::Lint) } else { Ok(unescaped) }
633633
}
634+
635+
/// Replaces `{` with `{{` and `}` with `}}`. If `preserve_unicode_escapes` is `true` the braces in
636+
/// `\u{xxxx}` are left unmodified
637+
#[expect(clippy::match_same_arms)]
638+
fn escape_braces(literal: &str, preserve_unicode_escapes: bool) -> String {
639+
#[derive(Clone, Copy)]
640+
enum State {
641+
Normal,
642+
Backslash,
643+
UnicodeEscape,
644+
}
645+
646+
let mut escaped = String::with_capacity(literal.len());
647+
let mut state = State::Normal;
648+
649+
for ch in literal.chars() {
650+
state = match (ch, state) {
651+
// Escape braces outside of unicode escapes by doubling them up
652+
('{' | '}', State::Normal) => {
653+
escaped.push(ch);
654+
State::Normal
655+
},
656+
// If `preserve_unicode_escapes` isn't enabled stay in `State::Normal`, otherwise:
657+
//
658+
// \u{aaaa} \\ \x01
659+
// ^ ^ ^
660+
('\\', State::Normal) if preserve_unicode_escapes => State::Backslash,
661+
// \u{aaaa}
662+
// ^
663+
('u', State::Backslash) => State::UnicodeEscape,
664+
// \xAA \\
665+
// ^ ^
666+
(_, State::Backslash) => State::Normal,
667+
// \u{aaaa}
668+
// ^
669+
('}', State::UnicodeEscape) => State::Normal,
670+
_ => state,
671+
};
672+
673+
escaped.push(ch);
674+
}
675+
676+
escaped
677+
}

tests/ui/infinite_loop.rs

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ fn fn_constref(i: &i32) -> i32 {
77
unimplemented!()
88
}
99
fn fn_mutref(i: &mut i32) {
10-
//~^ ERROR: this argument is a mutable reference, but not used mutably
11-
//~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
1210
unimplemented!()
1311
}
1412
fn fooi() -> i32 {

tests/ui/infinite_loop.stderr

+12-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: variables in the condition are not mutated in the loop body
2-
--> $DIR/infinite_loop.rs:24:11
2+
--> $DIR/infinite_loop.rs:22:11
33
|
44
LL | while y < 10 {
55
| ^^^^^^
@@ -8,71 +8,71 @@ LL | while y < 10 {
88
= note: `#[deny(clippy::while_immutable_condition)]` on by default
99

1010
error: variables in the condition are not mutated in the loop body
11-
--> $DIR/infinite_loop.rs:31:11
11+
--> $DIR/infinite_loop.rs:29:11
1212
|
1313
LL | while y < 10 && x < 3 {
1414
| ^^^^^^^^^^^^^^^
1515
|
1616
= note: this may lead to an infinite or to a never running loop
1717

1818
error: variables in the condition are not mutated in the loop body
19-
--> $DIR/infinite_loop.rs:40:11
19+
--> $DIR/infinite_loop.rs:38:11
2020
|
2121
LL | while !cond {
2222
| ^^^^^
2323
|
2424
= note: this may lead to an infinite or to a never running loop
2525

2626
error: variables in the condition are not mutated in the loop body
27-
--> $DIR/infinite_loop.rs:86:11
27+
--> $DIR/infinite_loop.rs:84:11
2828
|
2929
LL | while i < 3 {
3030
| ^^^^^
3131
|
3232
= note: this may lead to an infinite or to a never running loop
3333

3434
error: variables in the condition are not mutated in the loop body
35-
--> $DIR/infinite_loop.rs:93:11
35+
--> $DIR/infinite_loop.rs:91:11
3636
|
3737
LL | while i < 3 && j > 0 {
3838
| ^^^^^^^^^^^^^^
3939
|
4040
= note: this may lead to an infinite or to a never running loop
4141

4242
error: variables in the condition are not mutated in the loop body
43-
--> $DIR/infinite_loop.rs:99:11
43+
--> $DIR/infinite_loop.rs:97:11
4444
|
4545
LL | while i < 3 {
4646
| ^^^^^
4747
|
4848
= note: this may lead to an infinite or to a never running loop
4949

5050
error: variables in the condition are not mutated in the loop body
51-
--> $DIR/infinite_loop.rs:116:11
51+
--> $DIR/infinite_loop.rs:114:11
5252
|
5353
LL | while i < 3 {
5454
| ^^^^^
5555
|
5656
= note: this may lead to an infinite or to a never running loop
5757

5858
error: variables in the condition are not mutated in the loop body
59-
--> $DIR/infinite_loop.rs:123:11
59+
--> $DIR/infinite_loop.rs:121:11
6060
|
6161
LL | while i < 3 {
6262
| ^^^^^
6363
|
6464
= note: this may lead to an infinite or to a never running loop
6565

6666
error: variables in the condition are not mutated in the loop body
67-
--> $DIR/infinite_loop.rs:191:15
67+
--> $DIR/infinite_loop.rs:189:15
6868
|
6969
LL | while self.count < n {
7070
| ^^^^^^^^^^^^^^
7171
|
7272
= note: this may lead to an infinite or to a never running loop
7373

7474
error: variables in the condition are not mutated in the loop body
75-
--> $DIR/infinite_loop.rs:201:11
75+
--> $DIR/infinite_loop.rs:199:11
7676
|
7777
LL | while y < 10 {
7878
| ^^^^^^
@@ -82,7 +82,7 @@ LL | while y < 10 {
8282
= help: rewrite it as `if cond { loop { } }`
8383

8484
error: variables in the condition are not mutated in the loop body
85-
--> $DIR/infinite_loop.rs:210:11
85+
--> $DIR/infinite_loop.rs:208:11
8686
|
8787
LL | while y < 10 {
8888
| ^^^^^^
@@ -91,14 +91,5 @@ LL | while y < 10 {
9191
= note: this loop contains `return`s or `break`s
9292
= help: rewrite it as `if cond { loop { } }`
9393

94-
error: this argument is a mutable reference, but not used mutably
95-
--> $DIR/infinite_loop.rs:9:17
96-
|
97-
LL | fn fn_mutref(i: &mut i32) {
98-
| ^^^^^^^^ help: consider changing to: `&i32`
99-
|
100-
= note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
101-
= help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
102-
103-
error: aborting due to 12 previous errors
94+
error: aborting due to 11 previous errors
10495

tests/ui/let_underscore_future.rs

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ fn custom() -> impl Future<Output = ()> {
99
}
1010

1111
fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
12-
//~^ ERROR: this argument is a mutable reference, but not used mutably
13-
//~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
1412

1513
fn main() {
1614
let _ = some_async_fn();

tests/ui/let_underscore_future.stderr

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: non-binding `let` on a future
2-
--> $DIR/let_underscore_future.rs:16:5
2+
--> $DIR/let_underscore_future.rs:14:5
33
|
44
LL | let _ = some_async_fn();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,29 +9,20 @@ LL | let _ = some_async_fn();
99
= help: to override `-D warnings` add `#[allow(clippy::let_underscore_future)]`
1010

1111
error: non-binding `let` on a future
12-
--> $DIR/let_underscore_future.rs:18:5
12+
--> $DIR/let_underscore_future.rs:16:5
1313
|
1414
LL | let _ = custom();
1515
| ^^^^^^^^^^^^^^^^^
1616
|
1717
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
1818

1919
error: non-binding `let` on a future
20-
--> $DIR/let_underscore_future.rs:23:5
20+
--> $DIR/let_underscore_future.rs:21:5
2121
|
2222
LL | let _ = future;
2323
| ^^^^^^^^^^^^^^^
2424
|
2525
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
2626

27-
error: this argument is a mutable reference, but not used mutably
28-
--> $DIR/let_underscore_future.rs:11:35
29-
|
30-
LL | fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&impl Future<Output = ()>`
32-
|
33-
= note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
34-
= help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
35-
36-
error: aborting due to 4 previous errors
27+
error: aborting due to 3 previous errors
3728

tests/ui/mut_key.rs

-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<K
3232
//~^ ERROR: mutable key type
3333
//~| NOTE: `-D clippy::mutable-key-type` implied by `-D warnings`
3434
//~| ERROR: mutable key type
35-
//~| ERROR: this argument is a mutable reference, but not used mutably
36-
//~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
3735
let _other: HashMap<Key, bool> = HashMap::new();
3836
//~^ ERROR: mutable key type
3937
m.keys().cloned().collect()

0 commit comments

Comments
 (0)