Skip to content

Commit c2ea544

Browse files
committed
Merge branch 'master' into subtree-push-nightly-2025-10-07
2 parents d8424bd + 0332da0 commit c2ea544

Some content is hidden

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

48 files changed

+1040
-29
lines changed

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
# Changelog
22

3+
## [Unreleased]
4+
5+
6+
## [1.9.0] 2025-01-03
7+
8+
### Fixed
9+
- No longer strip `r#` prefix from `break` and `continue` labels [#6411](https://github.com/rust-lang/rustfmt/issues/6411)
10+
```rust
11+
fn main() {
12+
'r#if: {
13+
break 'r#if;
14+
}
15+
}
16+
```
17+
- Fix panic when sorting imports [#6333](https://github.com/rust-lang/rustfmt/issues/6333)
18+
- Fix issue with `wrap_comments` invalidating code blocks [#6417](https://github.com/rust-lang/rustfmt/pull/6417)
19+
- No longer remove closure block label within a macro call [#6465](https://github.com/rust-lang/rustfmt/issues/6465)
20+
21+
### Changed
22+
- Stabilize `style_edition=2024` and stabilize the `style_edition` command line option [#6431](https://github.com/rust-lang/rustfmt/pull/6431) [rust-lang/rust#134929](https://github.com/rust-lang/rust/pull/134929)
23+
- Apply version sorting to module declarations when using `style_edition=2024` [#6368](https://github.com/rust-lang/rustfmt/pull/6368)
24+
- When users set the deprecated `version` config, rustfmt now gives a hint about which equivalent `style_edition` they should use [#6361](https://github.com/rust-lang/rustfmt/pull/6361)
25+
- Correct version chunk splitting in the internal version sort algorithm [#6407](https://github.com/rust-lang/rustfmt/pull/6407)
26+
- Extend support for single line let-chain formatting to include cases where the left hand side operand is a literal, in alignment with finalized style rules as part of let-chain stabilization [#6492](https://github.com/rust-lang/rustfmt/pull/6492)
27+
- Begin initial formatting for `use closures` and `use chains` (`#![feature(ergonomic_clones)]`). Previously, the closure and chain was left as the developer wrote it [#6532](https://github.com/rust-lang/rustfmt/pull/6532)
28+
29+
### Added
30+
- Add `style_edition=2027` to gate unstable formatting [#6324](https://github.com/rust-lang/rustfmt/pull/6324)
31+
- Support discovering and formatting files via external mods imported within `cfg_match`, similar to `cfg_if` behavior [#6522](https://github.com/rust-lang/rustfmt/pull/6522)
32+
- Add new nightly-only `match_arm_indent` option [#6525](https://github.com/rust-lang/rustfmt/pull/6525)
33+
- more details in the [configuration section for this new option](https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#match_arm_indent)
34+
35+
336
## [1.8.0] 2024-09-20
437

538
### Fixed

Configurations.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,42 @@ fn foo() {
18621862
}
18631863
```
18641864

1865+
## `match_arm_indent`
1866+
1867+
Controls whether match arms are indented. If disabled, match arms will be formatted at the same indentation level as the outer `match` statement. Meaning that match blocks will only be indented once, not twice.
1868+
1869+
- **Default value**: `true`
1870+
- **Possible values**: `true`, `false`
1871+
- **Stable**: No (tracking issue: [#6533](https://github.com/rust-lang/rustfmt/issues/6533))
1872+
1873+
#### `true` (default):
1874+
1875+
```rust
1876+
fn main() {
1877+
match value {
1878+
Enum::A => {
1879+
let mut work = first();
1880+
work += second();
1881+
}
1882+
Enum::B => short_work(),
1883+
}
1884+
}
1885+
```
1886+
1887+
#### `false`:
1888+
1889+
```rust
1890+
fn main() {
1891+
match value {
1892+
Enum::A => {
1893+
let mut work = first();
1894+
work += second();
1895+
}
1896+
Enum::B => short_work(),
1897+
}
1898+
}
1899+
```
1900+
18651901
## `match_block_trailing_comma`
18661902

18671903
Put a trailing comma after a block based match arm (non-block arms are not affected)
@@ -2209,7 +2245,7 @@ fn example() {
22092245

22102246
Remove nested parens.
22112247

2212-
- **Default value**: `true`,
2248+
- **Default value**: `true`
22132249
- **Possible values**: `true`, `false`
22142250
- **Stable**: Yes
22152251

@@ -3010,6 +3046,7 @@ fn main() {
30103046
let y = 2;
30113047
let z = 3;
30123048
let a = Foo { x, y, z };
3049+
let b = Foo { x, y, z };
30133050
}
30143051
```
30153052

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ See [GitHub page](https://rust-lang.github.io/rustfmt/) for details.
172172

173173
The `edition` option determines the Rust language edition used for parsing the code. This is important for syntax compatibility but does not directly control formatting behavior (see [Style Editions](#style-editions)).
174174

175-
When running `cargo fmt`, the `edition` is automatically read from the `Cargo.toml` file. However, when running `rustfmt` directly the `edition` defaults to 2015 if not explicitly configured. For consistent parsing between rustfmt and `cargo fmt` you should configure the `edition`.
176-
For example in your `rustfmt.toml` file:
175+
When running `cargo fmt`, the `edition` is automatically read from the `Cargo.toml` file. However, when running `rustfmt` directly, the `edition` defaults to 2015. For consistent parsing between rustfmt and `cargo fmt`, you should configure the `edition` in your `rustfmt.toml` file:
177176

178177
```toml
179178
edition = "2018"

src/cargo-fmt/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use std::cmp::Ordering;
77
use std::collections::{BTreeMap, BTreeSet};
88
use std::env;
9-
use std::ffi::OsStr;
109
use std::fs;
1110
use std::hash::{Hash, Hasher};
1211
use std::io::{self, Write};
@@ -151,11 +150,13 @@ fn execute() -> i32 {
151150
}
152151

153152
fn rustfmt_command() -> Command {
154-
let rustfmt_var = env::var_os("RUSTFMT");
155-
let rustfmt = match &rustfmt_var {
156-
Some(rustfmt) => rustfmt,
157-
None => OsStr::new("rustfmt"),
153+
let rustfmt = match env::var_os("RUSTFMT") {
154+
Some(rustfmt) => PathBuf::from(rustfmt),
155+
None => env::current_exe()
156+
.expect("current executable path invalid")
157+
.with_file_name("rustfmt"),
158158
};
159+
159160
Command::new(rustfmt)
160161
}
161162

src/chains.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ enum ChainItemKind {
195195
StructField(symbol::Ident),
196196
TupleField(symbol::Ident, bool),
197197
Await,
198+
Use,
198199
Yield,
199200
Comment(String, CommentPosition),
200201
}
@@ -207,6 +208,7 @@ impl ChainItemKind {
207208
| ChainItemKind::StructField(..)
208209
| ChainItemKind::TupleField(..)
209210
| ChainItemKind::Await
211+
| ChainItemKind::Use
210212
| ChainItemKind::Yield
211213
| ChainItemKind::Comment(..) => false,
212214
}
@@ -262,6 +264,10 @@ impl ChainItemKind {
262264
let span = mk_sp(nested.span.hi(), expr.span.hi());
263265
(ChainItemKind::Await, span)
264266
}
267+
ast::ExprKind::Use(ref nested, _) => {
268+
let span = mk_sp(nested.span.hi(), expr.span.hi());
269+
(ChainItemKind::Use, span)
270+
}
265271
ast::ExprKind::Yield(ast::YieldKind::Postfix(ref nested)) => {
266272
let span = mk_sp(nested.span.hi(), expr.span.hi());
267273
(ChainItemKind::Yield, span)
@@ -313,6 +319,7 @@ impl Rewrite for ChainItem {
313319
rewrite_ident(context, ident)
314320
),
315321
ChainItemKind::Await => ".await".to_owned(),
322+
ChainItemKind::Use => ".use".to_owned(),
316323
ChainItemKind::Yield => ".yield".to_owned(),
317324
ChainItemKind::Comment(ref comment, _) => {
318325
rewrite_comment(comment, false, shape, context.config)?
@@ -517,6 +524,7 @@ impl Chain {
517524
ast::ExprKind::Field(ref subexpr, _)
518525
| ast::ExprKind::Try(ref subexpr)
519526
| ast::ExprKind::Await(ref subexpr, _)
527+
| ast::ExprKind::Use(ref subexpr, _)
520528
| ast::ExprKind::Yield(ast::YieldKind::Postfix(ref subexpr)) => Some(SubExpr {
521529
expr: Self::convert_try(subexpr, context),
522530
is_method_call_receiver: false,

src/closures.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,14 @@ fn rewrite_closure_fn_decl(
294294
Some(ast::CoroutineKind::AsyncGen { .. }) => "async gen ",
295295
None => "",
296296
};
297-
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
298-
"move "
299-
} else {
300-
""
297+
let capture_str = match capture {
298+
ast::CaptureBy::Value { .. } => "move ",
299+
ast::CaptureBy::Use { .. } => "use ",
300+
ast::CaptureBy::Ref => "",
301301
};
302302
// 4 = "|| {".len(), which is overconservative when the closure consists of
303303
// a single expression.
304-
let offset = binder.len() + const_.len() + immovable.len() + coro.len() + mover.len();
304+
let offset = binder.len() + const_.len() + immovable.len() + coro.len() + capture_str.len();
305305
let nested_shape = shape.shrink_left(offset, span)?.sub_width(4, span)?;
306306

307307
// 1 = |
@@ -339,7 +339,7 @@ fn rewrite_closure_fn_decl(
339339
.tactic(tactic)
340340
.preserve_newline(true);
341341
let list_str = write_list(&item_vec, &fmt)?;
342-
let mut prefix = format!("{binder}{const_}{immovable}{coro}{mover}|{list_str}|");
342+
let mut prefix = format!("{binder}{const_}{immovable}{coro}{capture_str}|{list_str}|");
343343

344344
if !ret_str.is_empty() {
345345
if prefix.contains('\n') {

src/config/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ create_config! {
131131
on the same line with the pattern of arms";
132132
match_arm_leading_pipes: MatchArmLeadingPipeConfig, true,
133133
"Determines whether leading pipes are emitted on match arms";
134+
match_arm_indent: MatchArmIndent, false,
135+
"Determines whether match arms are indented";
134136
force_multiline_blocks: ForceMultilineBlocks, false,
135137
"Force multiline closure bodies and match arms to be wrapped in a block";
136138
fn_args_layout: FnArgsLayout, true,
@@ -802,6 +804,7 @@ struct_field_align_threshold = 0
802804
enum_discrim_align_threshold = 0
803805
match_arm_blocks = true
804806
match_arm_leading_pipes = "Never"
807+
match_arm_indent = true
805808
force_multiline_blocks = false
806809
fn_params_layout = "Tall"
807810
brace_style = "SameLineWhere"
@@ -893,6 +896,7 @@ struct_field_align_threshold = 0
893896
enum_discrim_align_threshold = 0
894897
match_arm_blocks = true
895898
match_arm_leading_pipes = "Never"
899+
match_arm_indent = true
896900
force_multiline_blocks = false
897901
fn_params_layout = "Tall"
898902
brace_style = "SameLineWhere"

src/config/options.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ config_option_with_style_edition_default!(
665665
EnumDiscrimAlignThreshold, usize, _ => 0;
666666
MatchArmBlocks, bool, _ => true;
667667
MatchArmLeadingPipeConfig, MatchArmLeadingPipe, _ => MatchArmLeadingPipe::Never;
668+
MatchArmIndent, bool, _ => true;
668669
ForceMultilineBlocks, bool, _ => false;
669670
FnArgsLayout, Density, _ => Density::Tall;
670671
FnParamsLayout, Density, _ => Density::Tall;

src/expr.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,6 @@ pub(crate) fn format_expr(
161161
ast::ExprKind::Tup(ref items) => {
162162
rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1)
163163
}
164-
ast::ExprKind::Use(_, _) => {
165-
// FIXME: properly implement this
166-
Ok(context.snippet(expr.span()).to_owned())
167-
}
168164
ast::ExprKind::Let(ref pat, ref expr, _span, _) => rewrite_let(context, shape, pat, expr),
169165
ast::ExprKind::If(..)
170166
| ast::ExprKind::ForLoop { .. }
@@ -276,6 +272,7 @@ pub(crate) fn format_expr(
276272
| ast::ExprKind::Field(..)
277273
| ast::ExprKind::MethodCall(..)
278274
| ast::ExprKind::Await(_, _)
275+
| ast::ExprKind::Use(_, _)
279276
| ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape),
280277
ast::ExprKind::MacCall(ref mac) => {
281278
rewrite_macro(mac, context, shape, MacroPosition::Expression).or_else(|_| {
@@ -1999,7 +1996,11 @@ fn rewrite_let(
19991996
// TODO(ytmimi) comments could appear between `let` and the `pat`
20001997

20011998
// 4 = "let ".len()
2002-
let pat_shape = shape.offset_left(4, pat.span)?;
1999+
let mut pat_shape = shape.offset_left(4, pat.span)?;
2000+
if context.config.style_edition() >= StyleEdition::Edition2027 {
2001+
// 2 for the length of " ="
2002+
pat_shape = pat_shape.sub_width(2, pat.span)?;
2003+
}
20032004
let pat_str = pat.rewrite_result(context, pat_shape)?;
20042005
result.push_str(&pat_str);
20052006

src/imports.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,13 @@ impl UseTree {
566566

567567
// Normalise foo::self -> foo.
568568
if let UseSegmentKind::Slf(None) = last.kind {
569-
if !self.path.is_empty() {
570-
return self;
569+
if let Some(second_last) = self.path.pop() {
570+
if matches!(second_last.kind, UseSegmentKind::Slf(_)) {
571+
self.path.push(second_last);
572+
} else {
573+
self.path.push(second_last);
574+
return self;
575+
}
571576
}
572577
}
573578

0 commit comments

Comments
 (0)