From 2b3bceb89f4a1c8e122edfce1f25e01fd5edcb7b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Mar 2025 09:33:02 +1100 Subject: [PATCH 01/49] Add `{ast,hir,thir}::PatKind::Missing` variants. "Missing" patterns are possible in bare fn types (`fn f(u32)`) and similar places. Currently these are represented in the AST with `ast::PatKind::Ident` with no `by_ref`, no `mut`, an empty ident, and no sub-pattern. This flows through to `{hir,thir}::PatKind::Binding` for HIR and THIR. This is a bit nasty. It's very non-obvious, and easy to forget to check for the exceptional empty identifier case. This commit adds a new variant, `PatKind::Missing`, to do it properly. The process I followed: - Add a `Missing` variant to `{ast,hir,thir}::PatKind`. - Chang `parse_param_general` to produce `ast::PatKind::Missing` instead of `ast::PatKind::Missing`. - Look through `kw::Empty` occurrences to find functions where an existing empty ident check needs replacing with a `PatKind::Missing` check: `print_param`, `check_trait_item`, `is_named_param`. - Add a `PatKind::Missing => unreachable!(),` arm to every exhaustive match identified by the compiler. - Find which arms are actually reachable by running the test suite, changing them to something appropriate, usually by looking at what would happen to a `PatKind::Ident`/`PatKind::Binding` with no ref, no `mut`, an empty ident, and no subpattern. Quite a few of the `unreachable!()` arms were never reached. This makes sense because `PatKind::Missing` can't happen in every pattern, only in places like bare fn tys and trait fn decls. I also tried an alternative approach: modifying `ast::Param::pat` to hold an `Option>` instead of a `P`, but that quickly turned into a very large and painful change. Adding `PatKind::Missing` is much easier. --- src/items.rs | 6 +----- src/patterns.rs | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/items.rs b/src/items.rs index 3fb3284e3d7..81ff6327a4f 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2433,11 +2433,7 @@ pub(crate) fn span_hi_for_param(context: &RewriteContext<'_>, param: &ast::Param } pub(crate) fn is_named_param(param: &ast::Param) -> bool { - if let ast::PatKind::Ident(_, ident, _) = param.pat.kind { - ident.name != symbol::kw::Empty - } else { - true - } + !matches!(param.pat.kind, ast::PatKind::Missing) } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/src/patterns.rs b/src/patterns.rs index bafed41e39f..8ec3de286dc 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -42,6 +42,7 @@ pub(crate) fn is_short_pattern( fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool { match &pat.kind { + ast::PatKind::Missing => unreachable!(), ast::PatKind::Rest | ast::PatKind::Never | ast::PatKind::Wild | ast::PatKind::Err(_) => { true } @@ -100,6 +101,7 @@ impl Rewrite for Pat { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match self.kind { + PatKind::Missing => unreachable!(), PatKind::Or(ref pats) => { let pat_strs = pats .iter() From ce70a7999c172ec6e02d0d704802c5fa840ee692 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 May 2024 09:22:37 +1000 Subject: [PATCH 02/49] Impl `Copy` for `Token` and `TokenKind`. --- src/macros.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index ddf3d2ce96a..1e16aace304 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -858,18 +858,18 @@ impl MacroArgParser { }; self.result.push(ParsedMacroArg { - kind: MacroArgKind::Repeat(delim, inner, another, self.last_tok.clone()), + kind: MacroArgKind::Repeat(delim, inner, another, self.last_tok), }); Some(()) } - fn update_buffer(&mut self, t: &Token) { + fn update_buffer(&mut self, t: Token) { if self.buf.is_empty() { - self.start_tok = t.clone(); + self.start_tok = t; } else { let needs_space = match next_space(&self.last_tok.kind) { - SpaceState::Ident => ident_like(t), - SpaceState::Punctuation => !ident_like(t), + SpaceState::Ident => ident_like(&t), + SpaceState::Punctuation => !ident_like(&t), SpaceState::Always => true, SpaceState::Never => false, }; @@ -878,7 +878,7 @@ impl MacroArgParser { } } - self.buf.push_str(&pprust::token_to_string(t)); + self.buf.push_str(&pprust::token_to_string(&t)); } fn need_space_prefix(&self) -> bool { @@ -937,7 +937,7 @@ impl MacroArgParser { ) if self.is_meta_var => { self.add_meta_variable(&mut iter)?; } - TokenTree::Token(ref t, _) => self.update_buffer(t), + &TokenTree::Token(t, _) => self.update_buffer(t), &TokenTree::Delimited(_dspan, _spacing, delimited, ref tts) => { if !self.buf.is_empty() { if next_space(&self.last_tok.kind) == SpaceState::Always { From 409c7b8501d207efdc3fc34afdf56c9e72ca0bea Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Dec 2024 10:15:05 +1100 Subject: [PATCH 03/49] Tighten up assignment operator representations. In the AST, currently we use `BinOpKind` within `ExprKind::AssignOp` and `AssocOp::AssignOp`, even though this allows some nonsensical combinations. E.g. there is no `&&=` operator. Likewise for HIR and THIR. This commit introduces `AssignOpKind` which only includes the ten assignable operators, and uses it in `ExprKind::AssignOp` and `AssocOp::AssignOp`. (And does similar things for `hir::ExprKind` and `thir::ExprKind`.) This avoids the possibility of nonsensical combinations, as seen by the removal of the `bug!` case in `lang_item_for_binop`. The commit is mostly plumbing, including: - Adds an `impl From for BinOpKind` (AST) and `impl From for BinOp` (MIR/THIR). - `BinOpCategory` can now be created from both `BinOpKind` and `AssignOpKind`. - Replaces the `IsAssign` type with `Op`, which has more information and a few methods. - `suggest_swapping_lhs_and_rhs`: moves the condition to the call site, it's easier that way. - `check_expr_inner`: had to factor out some code into a separate method. I'm on the fence about whether avoiding the nonsensical combinations is worth the extra code. --- src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr.rs b/src/expr.rs index 65120770edd..be6b483bfff 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2058,7 +2058,7 @@ fn rewrite_assignment( context: &RewriteContext<'_>, lhs: &ast::Expr, rhs: &ast::Expr, - op: Option<&ast::BinOp>, + op: Option<&ast::AssignOp>, shape: Shape, ) -> RewriteResult { let operator_str = match op { From 1abbb9219ec5cb2d2e5aa0ccfe539ea5bd1b3c5a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Apr 2025 16:13:50 +1000 Subject: [PATCH 04/49] Remove `token::{Open,Close}Delim`. By replacing them with `{Open,Close}{Param,Brace,Bracket,Invisible}`. PR #137902 made `ast::TokenKind` more like `lexer::TokenKind` by replacing the compound `BinOp{,Eq}(BinOpToken)` variants with fieldless variants `Plus`, `Minus`, `Star`, etc. This commit does a similar thing with delimiters. It also makes `ast::TokenKind` more similar to `parser::TokenType`. This requires a few new methods: - `TokenKind::is_{,open_,close_}delim()` replace various kinds of pattern matches. - `Delimiter::as_{open,close}_token_kind` are used to convert `Delimiter` values to `TokenKind`. Despite these additions, it's a net reduction in lines of code. This is because e.g. `token::OpenParen` is so much shorter than `token::OpenDelim(Delimiter::Parenthesis)` that many multi-line forms reduce to single line forms. And many places where the number of lines doesn't change are still easier to read, just because the names are shorter, e.g.: ``` - } else if self.token != token::CloseDelim(Delimiter::Brace) { + } else if self.token != token::CloseBrace { ``` --- src/macros.rs | 12 +++++++++--- src/parse/macros/cfg_if.rs | 6 ++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 1e16aace304..0ff0aad7a2d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -722,7 +722,7 @@ fn last_tok(tt: &TokenTree) -> Token { match *tt { TokenTree::Token(ref t, _) => t.clone(), TokenTree::Delimited(delim_span, _, delim, _) => Token { - kind: TokenKind::CloseDelim(delim), + kind: delim.as_open_token_kind(), span: delim_span.close, }, } @@ -1124,8 +1124,14 @@ fn next_space(tok: &TokenKind) -> SpaceState { TokenKind::PathSep | TokenKind::Pound | TokenKind::Dollar - | TokenKind::OpenDelim(_) - | TokenKind::CloseDelim(_) => SpaceState::Never, + | TokenKind::OpenParen + | TokenKind::CloseParen + | TokenKind::OpenBrace + | TokenKind::CloseBrace + | TokenKind::OpenBracket + | TokenKind::CloseBracket + | TokenKind::OpenInvisible(_) + | TokenKind::CloseInvisible(_) => SpaceState::Never, TokenKind::Literal(..) | TokenKind::Ident(..) | TokenKind::Lifetime(..) => { SpaceState::Ident diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index 0b7b6c4d361..30b83373c17 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -1,7 +1,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::ast; -use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_ast::token::TokenKind; use rustc_parse::exp; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -60,9 +60,7 @@ fn parse_cfg_if_inner<'a>( return Err("Expected an opening brace"); } - while parser.token != TokenKind::CloseDelim(Delimiter::Brace) - && parser.token.kind != TokenKind::Eof - { + while parser.token != TokenKind::CloseBrace && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { Ok(Some(item_ptr)) => item_ptr.into_inner(), Ok(None) => continue, From 31d40e5e580066f2e5cc2b1f6b6179e767e9016b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Feb 2025 09:46:46 +0000 Subject: [PATCH 05/49] Add or-patterns to pattern types --- src/types.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/types.rs b/src/types.rs index 75a5a8532b8..7ec1032dcb4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1093,6 +1093,19 @@ impl Rewrite for ast::TyPat { ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => { rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) } + ast::TyPatKind::Or(ref variants) => { + let mut first = true; + let mut s = String::new(); + for variant in variants { + if first { + first = false + } else { + s.push_str(" | "); + } + s.push_str(&variant.rewrite_result(context, shape)?); + } + Ok(s) + } ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), } } From ce64001450d155d995f3d6e663717fce4832dfc0 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 29 Apr 2025 15:36:23 -0500 Subject: [PATCH 06/49] Also allow bool literals as first item of let chain Co-authored-by: est31 --- src/pairs.rs | 14 +++++++++----- tests/source/let_chains.rs | 10 +++++----- tests/target/let_chains.rs | 8 +++----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/pairs.rs b/src/pairs.rs index 9c51298416b..17ff041d775 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast::{ast, token}; use rustc_span::Span; use crate::config::IndentStyle; @@ -272,13 +272,17 @@ struct PairList<'a, 'b, T: Rewrite> { span: Span, } -fn is_ident(expr: &ast::Expr) -> bool { +fn is_ident_or_bool_lit(expr: &ast::Expr) -> bool { match &expr.kind { ast::ExprKind::Path(None, path) if path.segments.len() == 1 => true, + ast::ExprKind::Lit(token::Lit { + kind: token::LitKind::Bool, + .. + }) => true, ast::ExprKind::Unary(_, expr) | ast::ExprKind::AddrOf(_, _, expr) | ast::ExprKind::Paren(expr) - | ast::ExprKind::Try(expr) => is_ident(expr), + | ast::ExprKind::Try(expr) => is_ident_or_bool_lit(expr), _ => false, } } @@ -296,10 +300,10 @@ impl<'a, 'b> PairList<'a, 'b, ast::Expr> { return false; } - let fist_item_is_ident = is_ident(self.list[0].0); + let fist_item_is_ident_or_bool_lit = is_ident_or_bool_lit(self.list[0].0); let second_item_is_let_chain = matches!(self.list[1].0.kind, ast::ExprKind::Let(..)); - fist_item_is_ident && second_item_is_let_chain + fist_item_is_ident_or_bool_lit && second_item_is_let_chain } } diff --git a/tests/source/let_chains.rs b/tests/source/let_chains.rs index b7c1f811096..0c4d8aa85ea 100644 --- a/tests/source/let_chains.rs +++ b/tests/source/let_chains.rs @@ -20,6 +20,11 @@ fn test_single_line_let_chain() { if a && let Some(b) = foo() { } + // first item in let-chain is a bool literal + if true && let Some(x) = y { + + } + // first item in let-chain is a unary ! with an ident let unary_not = if !from_hir_call && let Some(p) = parent @@ -94,11 +99,6 @@ fn test_multi_line_let_chain() { } - // bool literal - if true && let Some(x) = y { - - } - // cast to a bool if 1 as bool && let Some(x) = y { diff --git a/tests/target/let_chains.rs b/tests/target/let_chains.rs index 1ceecac8abc..204937b4cac 100644 --- a/tests/target/let_chains.rs +++ b/tests/target/let_chains.rs @@ -50,6 +50,9 @@ fn test_single_line_let_chain() { // first item in let-chain is an ident if a && let Some(b) = foo() {} + // first item in let-chain is a bool literal + if true && let Some(x) = y {} + // first item in let-chain is a unary ! with an ident let unary_not = if !from_hir_call && let Some(p) = parent {}; @@ -102,11 +105,6 @@ fn test_multi_line_let_chain() { && let Some(x) = y {} - // bool literal - if true - && let Some(x) = y - {} - // cast to a bool if 1 as bool && let Some(x) = y From 266da42737a328d14429c97e43de22c056899208 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 12 May 2025 15:30:48 +0000 Subject: [PATCH 07/49] Do not remove super keyword from super-let --- src/items.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/items.rs b/src/items.rs index 5c3be769f9e..e79b7803c60 100644 --- a/src/items.rs +++ b/src/items.rs @@ -63,6 +63,11 @@ impl Rewrite for ast::Local { return Err(RewriteError::SkipFormatting); } + // FIXME(super_let): Implement formatting + if self.super_.is_some() { + return Err(RewriteError::SkipFormatting); + } + let attrs_str = self.attrs.rewrite_result(context, shape)?; let mut result = if attrs_str.is_empty() { "let ".to_owned() From 6210ac1a15cb75ea95e9ad51e665d19eeb13d2f4 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 30 Apr 2025 01:06:38 +0200 Subject: [PATCH 08/49] attempt to have rustfmt use the new logic apparently it doesn't really use the asm parsing at present, so this may work? --- src/parse/macros/asm.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/parse/macros/asm.rs b/src/parse/macros/asm.rs index 58c8d21bd7a..18e3386f4f1 100644 --- a/src/parse/macros/asm.rs +++ b/src/parse/macros/asm.rs @@ -1,11 +1,14 @@ use rustc_ast::ast; -use rustc_builtin_macros::asm::{AsmArgs, parse_asm_args}; +use rustc_builtin_macros::asm::{RawAsmArg, parse_raw_asm_args}; use crate::rewrite::RewriteContext; #[allow(dead_code)] -pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option { +pub(crate) fn parse_asm( + context: &RewriteContext<'_>, + mac: &ast::MacCall, +) -> Option> { let ts = mac.args.tokens.clone(); let mut parser = super::build_parser(context, ts); - parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok() + parse_raw_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok() } From 2f3a0a55364d31a39d09ba1a3d62d74e92b8c08a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 17 May 2025 23:17:06 +0200 Subject: [PATCH 09/49] rename to get rid of the 'raw' concept --- src/parse/macros/asm.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/parse/macros/asm.rs b/src/parse/macros/asm.rs index 18e3386f4f1..1a9614bacec 100644 --- a/src/parse/macros/asm.rs +++ b/src/parse/macros/asm.rs @@ -1,14 +1,11 @@ use rustc_ast::ast; -use rustc_builtin_macros::asm::{RawAsmArg, parse_raw_asm_args}; +use rustc_builtin_macros::asm::{AsmArg, parse_asm_args}; use crate::rewrite::RewriteContext; #[allow(dead_code)] -pub(crate) fn parse_asm( - context: &RewriteContext<'_>, - mac: &ast::MacCall, -) -> Option> { +pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option> { let ts = mac.args.tokens.clone(); let mut parser = super::build_parser(context, ts); - parse_raw_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok() + parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok() } From 79a989770dd8efd377fb6fe20f938393f2d7bfdf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 May 2025 02:32:22 +1000 Subject: [PATCH 10/49] Reduce `P` to a typedef of `Box`. Keep the `P` constructor function for now, to minimize immediate churn. All the `into_inner` calls are removed, which is nice. --- src/modules.rs | 2 +- src/parse/macros/cfg_if.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules.rs b/src/modules.rs index bc5a6d3e704..44c8123517c 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -174,7 +174,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(&item) { - self.visit_cfg_if(Cow::Owned(item.into_inner()))?; + self.visit_cfg_if(Cow::Owned(*item))?; continue; } diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index 30b83373c17..26bf6c5326f 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -62,7 +62,7 @@ fn parse_cfg_if_inner<'a>( while parser.token != TokenKind::CloseBrace && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { - Ok(Some(item_ptr)) => item_ptr.into_inner(), + Ok(Some(item_ptr)) => *item_ptr, Ok(None) => continue, Err(err) => { err.cancel(); From 4718757845dd5baf85849e430520f478662c835f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 5 May 2025 15:24:14 +0200 Subject: [PATCH 11/49] move asm parsing code into `rustc_parse` --- src/lib.rs | 1 - src/parse/macros/asm.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 08cda6913b9..942b42ec5f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,6 @@ // N.B. these crates are loaded from the sysroot, so they need extern crate. extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_builtin_macros; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_expand; diff --git a/src/parse/macros/asm.rs b/src/parse/macros/asm.rs index 1a9614bacec..bfa9c6300c4 100644 --- a/src/parse/macros/asm.rs +++ b/src/parse/macros/asm.rs @@ -1,5 +1,5 @@ use rustc_ast::ast; -use rustc_builtin_macros::asm::{AsmArg, parse_asm_args}; +use rustc_parse::parser::asm::{AsmArg, parse_asm_args}; use crate::rewrite::RewriteContext; From 2d7453d602012352a1c5f121fb72c1810da9a3b3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 May 2025 08:20:30 +1000 Subject: [PATCH 12/49] Reorder `ast::ItemKind::{Struct,Enum,Union}` fields. So they match the order of the parts in the source code, e.g.: ``` struct Foo { t: T, u: U } <-><----> <------------> / | \ ident generics variant_data ``` --- src/items.rs | 4 ++-- src/visitor.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items.rs b/src/items.rs index e79b7803c60..1a3897b51cb 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1110,10 +1110,10 @@ impl<'a> StructParts<'a> { pub(crate) fn from_item(item: &'a ast::Item) -> Self { let (prefix, def, ident, generics) = match item.kind { - ast::ItemKind::Struct(ident, ref def, ref generics) => { + ast::ItemKind::Struct(ident, ref generics, ref def) => { ("struct ", def, ident, generics) } - ast::ItemKind::Union(ident, ref def, ref generics) => ("union ", def, ident, generics), + ast::ItemKind::Union(ident, ref generics, ref def) => ("union ", def, ident, generics), _ => unreachable!(), }; StructParts { diff --git a/src/visitor.rs b/src/visitor.rs index 16d1f5105d5..f6a9a3f2cd1 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -521,7 +521,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => { self.visit_struct(&StructParts::from_item(item)); } - ast::ItemKind::Enum(ident, ref def, ref generics) => { + ast::ItemKind::Enum(ident, ref generics, ref def) => { self.format_missing_with_indent(source!(self, item.span).lo()); self.visit_enum(ident, &item.vis, def, generics, item.span); self.last_pos = source!(self, item.span).hi(); From d37c63f4cd9069445bdb71cb125ea71ca744edc2 Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 19 Jan 2025 22:01:11 +0800 Subject: [PATCH 13/49] Implement pinned borrows, part of `pin_ergonomics` --- src/expr.rs | 2 ++ tests/source/pin_sugar.rs | 10 ++++++++++ tests/target/pin_sugar.rs | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/src/expr.rs b/src/expr.rs index be6b483bfff..08aedff2b20 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2289,8 +2289,10 @@ fn rewrite_expr_addrof( ) -> RewriteResult { let operator_str = match (mutability, borrow_kind) { (ast::Mutability::Not, ast::BorrowKind::Ref) => "&", + (ast::Mutability::Not, ast::BorrowKind::Pin) => "&pin const ", (ast::Mutability::Not, ast::BorrowKind::Raw) => "&raw const ", (ast::Mutability::Mut, ast::BorrowKind::Ref) => "&mut ", + (ast::Mutability::Mut, ast::BorrowKind::Pin) => "&pin mut ", (ast::Mutability::Mut, ast::BorrowKind::Raw) => "&raw mut ", }; rewrite_unary_prefix(context, operator_str, expr, shape) diff --git a/tests/source/pin_sugar.rs b/tests/source/pin_sugar.rs index 370dfbc196a..e5b47339b92 100644 --- a/tests/source/pin_sugar.rs +++ b/tests/source/pin_sugar.rs @@ -18,3 +18,13 @@ impl Foo { mut self) {} fn i(&pin mut self) {} } + +fn borrows() { + let mut foo = 0_i32; + let x: Pin<&mut _> = & pin + mut foo; + + let x: Pin<&_> = & + pin const + foo; +} diff --git a/tests/target/pin_sugar.rs b/tests/target/pin_sugar.rs index 7d04efb1b32..09ad23a5807 100644 --- a/tests/target/pin_sugar.rs +++ b/tests/target/pin_sugar.rs @@ -16,3 +16,10 @@ impl Foo { fn h<'a>(&'a pin mut self) {} fn i(&pin mut self) {} } + +fn borrows() { + let mut foo = 0_i32; + let x: Pin<&mut _> = &pin mut foo; + + let x: Pin<&_> = &pin const foo; +} From 928d1dc5b91dadfc1dc7f69953b0b73d931cc4cc Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 19 Jun 2025 13:02:04 -0500 Subject: [PATCH 14/49] Extract Translator struct --- src/parse/session.rs | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index afd847f9515..73a89072f14 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter, stderr_destination}; use rustc_errors::registry::Registry; -use rustc_errors::translation::Translate; +use rustc_errors::translation::Translator; use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ @@ -47,16 +47,6 @@ impl SilentOnIgnoredFilesEmitter { } } -impl Translate for SilentOnIgnoredFilesEmitter { - fn fluent_bundle(&self) -> Option<&rustc_errors::FluentBundle> { - self.emitter.fluent_bundle() - } - - fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { - self.emitter.fallback_fluent_bundle() - } -} - impl Emitter for SilentOnIgnoredFilesEmitter { fn source_map(&self) -> Option<&SourceMap> { None @@ -84,6 +74,10 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } self.handle_non_ignoreable_error(diag, registry); } + + fn translator(&self) -> &Translator { + self.emitter.translator() + } } impl From for ColorConfig { @@ -110,12 +104,9 @@ fn default_dcx( ColorConfig::Never }; - let fallback_bundle = rustc_errors::fallback_fluent_bundle( - rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), - false, - ); + let translator = rustc_driver::default_translator(); let emitter = Box::new( - HumanEmitter::new(stderr_destination(emit_color), fallback_bundle) + HumanEmitter::new(stderr_destination(emit_color), translator) .sm(Some(source_map.clone())), ); @@ -335,16 +326,6 @@ mod tests { num_emitted_errors: Arc, } - impl Translate for TestEmitter { - fn fluent_bundle(&self) -> Option<&rustc_errors::FluentBundle> { - None - } - - fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { - panic!("test emitter attempted to translate a diagnostic"); - } - } - impl Emitter for TestEmitter { fn source_map(&self) -> Option<&SourceMap> { None @@ -353,6 +334,10 @@ mod tests { fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) { self.num_emitted_errors.fetch_add(1, Ordering::Release); } + + fn translator(&self) -> &Translator { + panic!("test emitter attempted to translate a diagnostic"); + } } fn build_diagnostic(level: DiagnosticLevel, span: Option) -> DiagInner { From e9d0738467380dcc32de35c33e14d1d7a3197c05 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 17 Jun 2025 16:59:57 -0500 Subject: [PATCH 15/49] Rename SilentEmitter -> FatalOnlyEmitter --- src/parse/session.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 73a89072f14..c50d4ef0489 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::IntoDynSyncSend; -use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter, stderr_destination}; +use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, FatalOnlyEmitter, stderr_destination}; use rustc_errors::registry::Registry; use rustc_errors::translation::Translator; use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; @@ -111,7 +111,7 @@ fn default_dcx( ); let emitter: Box = if !show_parse_errors { - Box::new(SilentEmitter { + Box::new(FatalOnlyEmitter { fatal_emitter: emitter, fatal_note: None, emit_fatal_diagnostic: false, From ced2bb075e8c24dc62dd7981604bfc859dcd5f2a Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 19 Jun 2025 13:05:01 -0500 Subject: [PATCH 16/49] Extract SilentEmitter --- src/parse/session.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index c50d4ef0489..10e2809e58b 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::IntoDynSyncSend; -use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, FatalOnlyEmitter, stderr_destination}; +use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter, stderr_destination}; use rustc_errors::registry::Registry; use rustc_errors::translation::Translator; use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; @@ -105,19 +105,14 @@ fn default_dcx( }; let translator = rustc_driver::default_translator(); - let emitter = Box::new( - HumanEmitter::new(stderr_destination(emit_color), translator) - .sm(Some(source_map.clone())), - ); - - let emitter: Box = if !show_parse_errors { - Box::new(FatalOnlyEmitter { - fatal_emitter: emitter, - fatal_note: None, - emit_fatal_diagnostic: false, - }) + + let emitter: Box = if show_parse_errors { + Box::new( + HumanEmitter::new(stderr_destination(emit_color), translator) + .sm(Some(source_map.clone())), + ) } else { - emitter + Box::new(SilentEmitter { translator }) }; DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, @@ -196,7 +191,7 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.raw_psess.dcx().make_silent(None, false); + self.raw_psess.dcx().make_silent(); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { From f81941c038505626abdeb3743f59840ec881988b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 May 2025 15:06:56 +1000 Subject: [PATCH 17/49] Remove an unnecessary check in rustfmt. "{{root}}" is an internal-only name, and cannot appear in Rust code being formatted. --- src/imports.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports.rs b/src/imports.rs index b741dd9b5da..788fed013ad 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -184,7 +184,7 @@ impl UseSegment { modsep: bool, ) -> Option { let name = rewrite_ident(context, path_seg.ident); - if name.is_empty() || name == "{{root}}" { + if name.is_empty() { return None; } let kind = match name { From 9debb8f171b19e3f07f508f60820b40012d45cf1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Mar 2025 12:08:45 +0000 Subject: [PATCH 18/49] Change const trait bound syntax from ~const to [const] --- tests/source/type.rs | 12 ++++++------ tests/target/type.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/source/type.rs b/tests/source/type.rs index 7a232f85198..213fad7cb16 100644 --- a/tests/source/type.rs +++ b/tests/source/type.rs @@ -142,18 +142,18 @@ type MyFn = fn(a: SomeLongComplexType, b: SomeOtherLongComplexType,) -> Box() -> i32 { ::CONST } +const fn not_quite_const() -> i32 { ::CONST } -impl ~ const T {} +impl const T for U {} -fn apit(_: impl ~ const T) {} +fn apit(_: impl [ const ] T) {} -fn rpit() -> impl ~ const T { S } +fn rpit() -> impl [ const] T { S } pub struct Foo(T); -impl Foo { +impl Foo { fn new(t: T) -> Self { Self(t) } diff --git a/tests/target/type.rs b/tests/target/type.rs index 325adb52f3f..93479f8b484 100644 --- a/tests/target/type.rs +++ b/tests/target/type.rs @@ -147,22 +147,22 @@ type MyFn = fn( // Const bound -trait T: ~const Super {} +trait T: [const] Super {} -const fn not_quite_const() -> i32 { +const fn not_quite_const() -> i32 { ::CONST } -impl ~const T {} +impl const T for U {} -fn apit(_: impl ~const T) {} +fn apit(_: impl [const] T) {} -fn rpit() -> impl ~const T { +fn rpit() -> impl [const] T { S } pub struct Foo(T); -impl Foo { +impl Foo { fn new(t: T) -> Self { Self(t) } From a22fa5b897314f398ac2c78d459bb7f65c0c1674 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Sun, 29 Jun 2025 13:06:21 -0500 Subject: [PATCH 19/49] Remove let_chains feature --- tests/source/let_chains.rs | 2 ++ tests/target/let_chains.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/source/let_chains.rs b/tests/source/let_chains.rs index 0c4d8aa85ea..fc2a9310569 100644 --- a/tests/source/let_chains.rs +++ b/tests/source/let_chains.rs @@ -1,3 +1,5 @@ +// rustfmt-edition: 2024 + fn main() { if let x = x && x {} diff --git a/tests/target/let_chains.rs b/tests/target/let_chains.rs index 204937b4cac..4fd6048d914 100644 --- a/tests/target/let_chains.rs +++ b/tests/target/let_chains.rs @@ -1,3 +1,5 @@ +// rustfmt-edition: 2024 + fn main() { if let x = x && x From a5c21f93c66b60cbaad8cd2547f8e43d60a0efa1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Jun 2025 02:01:38 +0000 Subject: [PATCH 20/49] Remove support for dyn* --- src/types.rs | 6 ------ tests/target/issue_5542.rs | 10 ---------- 2 files changed, 16 deletions(-) delete mode 100644 tests/target/issue_5542.rs diff --git a/src/types.rs b/src/types.rs index 7ec1032dcb4..dd1515805e5 100644 --- a/src/types.rs +++ b/src/types.rs @@ -835,12 +835,6 @@ impl Rewrite for ast::Ty { .max_width_error(shape.width, self.span())?; (shape, "dyn ") } - ast::TraitObjectSyntax::DynStar => { - let shape = shape - .offset_left(5) - .max_width_error(shape.width, self.span())?; - (shape, "dyn* ") - } ast::TraitObjectSyntax::None => (shape, ""), }; let mut res = bounds.rewrite_result(context, shape)?; diff --git a/tests/target/issue_5542.rs b/tests/target/issue_5542.rs deleted file mode 100644 index 730bb7b681a..00000000000 --- a/tests/target/issue_5542.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(dyn_star)] -#![allow(incomplete_features)] - -use core::fmt::Debug; - -fn main() { - let i = 42; - let dyn_i = i as dyn* Debug; - dbg!(dyn_i); -} From 97b6e88265e714ab194e7fc29037c533b44bbe8e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Jul 2024 09:38:49 +0000 Subject: [PATCH 21/49] Replace kw_span by full span. --- src/spanned.rs | 2 +- src/types.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/spanned.rs b/src/spanned.rs index 507647566d4..ac132999b62 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -122,7 +122,7 @@ impl Spanned for ast::GenericParam { fn span(&self) -> Span { let lo = match self.kind { _ if !self.attrs.is_empty() => self.attrs[0].span.lo(), - ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(), + ast::GenericParamKind::Const { span, .. } => span.lo(), _ => self.ident.span.lo(), }; let hi = if self.bounds.is_empty() { diff --git a/src/types.rs b/src/types.rs index dd1515805e5..c0df01edd6d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -689,7 +689,7 @@ impl Rewrite for ast::GenericParam { let param_start = if let ast::GenericParamKind::Const { ref ty, - kw_span, + span, default, } = &self.kind { @@ -711,7 +711,7 @@ impl Rewrite for ast::GenericParam { default.rewrite_result(context, Shape::legacy(budget, shape.indent))?; param.push_str(&rewrite); } - kw_span.lo() + span.lo() } else { param.push_str(rewrite_ident(context, self.ident)); self.ident.span.lo() From c5916cf926d0d9356c9df997d3b194f02791cb97 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 6 Jul 2025 14:02:19 -0700 Subject: [PATCH 22/49] rustfmt: migrate BareFn -> FnPtr --- src/types.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/types.rs b/src/types.rs index c0df01edd6d..9ee10d86270 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1009,7 +1009,7 @@ impl Rewrite for ast::Ty { }) } } - ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape), + ast::TyKind::FnPtr(ref fn_ptr) => rewrite_fn_ptr(fn_ptr, self.span, context, shape), ast::TyKind::Never => Ok(String::from("!")), ast::TyKind::MacCall(ref mac) => { rewrite_macro(mac, context, shape, MacroPosition::Expression) @@ -1105,8 +1105,8 @@ impl Rewrite for ast::TyPat { } } -fn rewrite_bare_fn( - bare_fn: &ast::BareFnTy, +fn rewrite_fn_ptr( + fn_ptr: &ast::FnPtrTy, span: Span, context: &RewriteContext<'_>, shape: Shape, @@ -1115,7 +1115,7 @@ fn rewrite_bare_fn( let mut result = String::with_capacity(128); - if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &bare_fn.generic_params) { + if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &fn_ptr.generic_params) { result.push_str("for<"); // 6 = "for<> ".len(), 4 = "for<". // This doesn't work out so nicely for multiline situation with lots of @@ -1124,10 +1124,10 @@ fn rewrite_bare_fn( result.push_str("> "); } - result.push_str(crate::utils::format_safety(bare_fn.safety)); + result.push_str(crate::utils::format_safety(fn_ptr.safety)); result.push_str(&format_extern( - bare_fn.ext, + fn_ptr.ext, context.config.force_explicit_abi(), )); @@ -1145,9 +1145,9 @@ fn rewrite_bare_fn( }; let rewrite = format_function_type( - bare_fn.decl.inputs.iter(), - &bare_fn.decl.output, - bare_fn.decl.c_variadic(), + fn_ptr.decl.inputs.iter(), + &fn_ptr.decl.output, + fn_ptr.decl.c_variadic(), span, context, func_ty_shape, From a1cfe86dda8efb2a6343c3117b558bfda5e8d129 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 13 Jul 2025 16:49:19 +0800 Subject: [PATCH 23/49] parse `const trait Trait` --- src/items.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/items.rs b/src/items.rs index 1a3897b51cb..7084639aca9 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1172,6 +1172,7 @@ pub(crate) fn format_trait( unreachable!(); }; let ast::Trait { + constness, is_auto, safety, ident, @@ -1182,7 +1183,8 @@ pub(crate) fn format_trait( let mut result = String::with_capacity(128); let header = format!( - "{}{}{}trait ", + "{}{}{}{}trait ", + format_constness(constness), format_visibility(context, &item.vis), format_safety(safety), format_auto(is_auto), From 340e59001479ef3d85ed027c4af9bf2707e30557 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 11 Sep 2023 00:59:31 -0400 Subject: [PATCH 24/49] Print thread ID in panic message if thread name is unknown `panic!` does not print any identifying information for threads that are unnamed. However, in many cases, the thread ID can be determined. This changes the panic message from something like this: thread '' panicked at src/main.rs:3:5: explicit panic To something like this: thread '' (0xff9bf) panicked at src/main.rs:3:5: explicit panic Stack overflow messages are updated as well. This change applies to both named and unnamed threads. The ID printed is the OS integer thread ID rather than the Rust thread ID, which should also be what debuggers print. --- tests/rustfmt/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index a9f58b9328e..4a9399377d1 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -185,10 +185,11 @@ fn dont_emit_ICE() { "tests/target/issue-6105.rs", ]; + let panic_re = regex::Regex::new("thread.*panicked").unwrap(); for file in files { let args = [file]; let (_stdout, stderr) = rustfmt(&args); - assert!(!stderr.contains("thread 'main' panicked")); + assert!(!panic_re.is_match(&stderr)); } } From 4501819ed04e691901e67a4b4c76b0bf8dfc5b3f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 9 Aug 2025 13:24:06 +0800 Subject: [PATCH 25/49] remove `P` --- src/chains.rs | 6 +++--- src/closures.rs | 4 ++-- src/expr.rs | 6 +++--- src/items.rs | 10 +++++----- src/macros.rs | 10 +++++----- src/matches.rs | 6 +++--- src/modules.rs | 8 ++++---- src/overflow.rs | 4 ++-- src/parse/macros/lazy_static.rs | 3 +-- src/parse/macros/mod.rs | 14 +++++++------- src/parse/parser.rs | 4 ++-- src/patterns.rs | 13 ++++++------- src/rewrite.rs | 3 +-- src/spanned.rs | 4 ++-- src/types.rs | 5 ++--- src/utils.rs | 6 +++--- src/visitor.rs | 2 +- 17 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 034ecde068a..2f388197ea1 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -58,7 +58,7 @@ use std::borrow::Cow; use std::cmp::min; -use rustc_ast::{ast, ptr}; +use rustc_ast::ast; use rustc_span::{BytePos, Span, symbol}; use tracing::debug; @@ -187,7 +187,7 @@ enum ChainItemKind { MethodCall( ast::PathSegment, Vec, - ThinVec>, + ThinVec>, ), StructField(symbol::Ident), TupleField(symbol::Ident, bool), @@ -343,7 +343,7 @@ impl ChainItem { fn rewrite_method_call( method_name: symbol::Ident, types: &[ast::GenericArg], - args: &[ptr::P], + args: &[Box], span: Span, context: &RewriteContext<'_>, shape: Shape, diff --git a/src/closures.rs b/src/closures.rs index 61e148cdf18..bb10a7946b8 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ast, ptr}; +use rustc_ast::ast; use rustc_span::Span; use thin_vec::thin_vec; use tracing::debug; @@ -165,7 +165,7 @@ fn rewrite_closure_with_block( let block = ast::Block { stmts: thin_vec![ast::Stmt { id: ast::NodeId::root(), - kind: ast::StmtKind::Expr(ptr::P(body.clone())), + kind: ast::StmtKind::Expr(Box::new(body.clone())), span: body.span, }], id: ast::NodeId::root(), diff --git a/src/expr.rs b/src/expr.rs index 08aedff2b20..975f9be44e4 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -3,7 +3,7 @@ use std::cmp::min; use itertools::Itertools; use rustc_ast::token::{Delimiter, Lit, LitKind}; -use rustc_ast::{ForLoopKind, MatchKind, ast, ptr, token}; +use rustc_ast::{ForLoopKind, MatchKind, ast, token}; use rustc_span::{BytePos, Span}; use tracing::debug; @@ -1368,7 +1368,7 @@ fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option, callee: &str, - args: &[ptr::P], + args: &[Box], span: Span, shape: Shape, ) -> RewriteResult { @@ -1634,7 +1634,7 @@ fn struct_lit_can_be_aligned(fields: &[ast::ExprField], has_base: bool) -> bool fn rewrite_struct_lit<'a>( context: &RewriteContext<'_>, path: &ast::Path, - qself: &Option>, + qself: &Option>, fields: &'a [ast::ExprField], struct_rest: &ast::StructRest, attrs: &[ast::Attribute], diff --git a/src/items.rs b/src/items.rs index 7084639aca9..57d4142ebe4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -4,8 +4,8 @@ use std::borrow::Cow; use std::cmp::{Ordering, max, min}; use regex::Regex; +use rustc_ast::ast; use rustc_ast::visit; -use rustc_ast::{ast, ptr}; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, symbol}; use tracing::debug; @@ -725,9 +725,9 @@ impl<'a> FmtVisitor<'a> { .ok() } - fn visit_impl_items(&mut self, items: &[ptr::P]) { + fn visit_impl_items(&mut self, items: &[Box]) { if self.get_context().config.reorder_impl_items() { - type TyOpt = Option>; + type TyOpt = Option>; use crate::ast::AssocItemKind::*; let is_type = |ty: &TyOpt| opaque_ty(ty).is_none(); let is_opaque = |ty: &TyOpt| opaque_ty(ty).is_some(); @@ -934,7 +934,7 @@ pub(crate) fn format_impl( fn is_impl_single_line( context: &RewriteContext<'_>, - items: &[ptr::P], + items: &[Box], result: &str, where_clause_str: &str, item: &ast::Item, @@ -2024,7 +2024,7 @@ pub(crate) struct StaticParts<'a> { generics: Option<&'a ast::Generics>, ty: &'a ast::Ty, mutability: ast::Mutability, - expr_opt: Option<&'a ptr::P>, + expr_opt: Option<&'a Box>, defaultness: Option, span: Span, } diff --git a/src/macros.rs b/src/macros.rs index 0ff0aad7a2d..2e7ac90f596 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -12,9 +12,9 @@ use std::collections::HashMap; use std::panic::{AssertUnwindSafe, catch_unwind}; +use rustc_ast::ast; use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree}; -use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol}; use tracing::debug; @@ -53,10 +53,10 @@ pub(crate) enum MacroPosition { #[derive(Debug)] pub(crate) enum MacroArg { - Expr(ptr::P), - Ty(ptr::P), - Pat(ptr::P), - Item(ptr::P), + Expr(Box), + Ty(Box), + Pat(Box), + Item(Box), Keyword(Ident, Span), } diff --git a/src/matches.rs b/src/matches.rs index 8f62648e576..209cb2f9287 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -2,7 +2,7 @@ use std::iter::repeat; -use rustc_ast::{MatchKind, ast, ptr}; +use rustc_ast::{MatchKind, ast}; use rustc_span::{BytePos, Span}; use tracing::debug; @@ -394,7 +394,7 @@ fn flatten_arm_body<'a>( fn rewrite_match_body( context: &RewriteContext<'_>, - body: &ptr::P, + body: &Box, pats_str: &str, shape: Shape, has_guard: bool, @@ -569,7 +569,7 @@ fn rewrite_match_body( // The `if ...` guard on a match arm. fn rewrite_guard( context: &RewriteContext<'_>, - guard: &Option>, + guard: &Option>, shape: Shape, // The amount of space used up on this line for the pattern in // the arm (excludes offset). diff --git a/src/modules.rs b/src/modules.rs index 44c8123517c..3bc656b64b3 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -26,7 +26,7 @@ type FileModMap<'ast> = BTreeMap>; #[derive(Debug, Clone)] pub(crate) struct Module<'a> { ast_mod_kind: Option>, - pub(crate) items: Cow<'a, ThinVec>>, + pub(crate) items: Cow<'a, ThinVec>>, inner_attr: ast::AttrVec, pub(crate) span: Span, } @@ -35,7 +35,7 @@ impl<'a> Module<'a> { pub(crate) fn new( mod_span: Span, ast_mod_kind: Option>, - mod_items: Cow<'a, ThinVec>>, + mod_items: Cow<'a, ThinVec>>, mod_attrs: Cow<'a, ast::AttrVec>, ) -> Self { let inner_attr = mod_attrs @@ -170,7 +170,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { /// Visit modules defined inside macro calls. fn visit_mod_outside_ast( &mut self, - items: ThinVec>, + items: ThinVec>, ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(&item) { @@ -197,7 +197,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { /// Visit modules from AST. fn visit_mod_from_ast( &mut self, - items: &'ast [rustc_ast::ptr::P], + items: &'ast [Box], ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(item) { diff --git a/src/overflow.rs b/src/overflow.rs index 728adff2c7d..bb1ebc87f67 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -3,8 +3,8 @@ use std::cmp::min; use itertools::Itertools; +use rustc_ast::ast; use rustc_ast::token::Delimiter; -use rustc_ast::{ast, ptr}; use rustc_span::Span; use tracing::debug; @@ -219,7 +219,7 @@ pub(crate) trait IntoOverflowableItem<'a>: Rewrite + Spanned { fn into_overflowable_item(&'a self) -> OverflowableItem<'a>; } -impl<'a, T: 'a + IntoOverflowableItem<'a>> IntoOverflowableItem<'a> for ptr::P { +impl<'a, T: 'a + IntoOverflowableItem<'a>> IntoOverflowableItem<'a> for Box { fn into_overflowable_item(&'a self) -> OverflowableItem<'a> { (**self).into_overflowable_item() } diff --git a/src/parse/macros/lazy_static.rs b/src/parse/macros/lazy_static.rs index cbe81004e22..8611615d123 100644 --- a/src/parse/macros/lazy_static.rs +++ b/src/parse/macros/lazy_static.rs @@ -1,5 +1,4 @@ use rustc_ast::ast; -use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_parse::exp; @@ -10,7 +9,7 @@ use crate::rewrite::RewriteContext; pub(crate) fn parse_lazy_static( context: &RewriteContext<'_>, ts: TokenStream, -) -> Option, P)>> { +) -> Option, Box)>> { let mut result = vec![]; let mut parser = super::build_parser(context, ts); macro_rules! parse_or { diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index d7964484b26..724d7a09e4a 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -1,6 +1,6 @@ +use rustc_ast::ast; use rustc_ast::token::{Delimiter, NonterminalKind, NtExprKind::*, NtPatKind::*, TokenKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{ast, ptr}; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; use rustc_session::parse::ParseSess; @@ -49,26 +49,26 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { Expr, NonterminalKind::Expr(Expr), |parser: &mut Parser<'b>| parser.parse_expr(), - |x: ptr::P| Some(x) + |x: Box| Some(x) ); parse_macro_arg!( Ty, NonterminalKind::Ty, |parser: &mut Parser<'b>| parser.parse_ty(), - |x: ptr::P| Some(x) + |x: Box| Some(x) ); parse_macro_arg!( Pat, NonterminalKind::Pat(PatParam { inferred: false }), |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), - |x: ptr::P| Some(x) + |x: Box| Some(x) ); - // `parse_item` returns `Option>`. + // `parse_item` returns `Option>`. parse_macro_arg!( Item, NonterminalKind::Item, |parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No), - |x: Option>| x + |x: Option>| x ); None @@ -164,7 +164,7 @@ pub(crate) fn parse_macro_args( pub(crate) fn parse_expr( context: &RewriteContext<'_>, tokens: TokenStream, -) -> Option> { +) -> Option> { let mut parser = build_parser(context, tokens); parser.parse_expr().ok() } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index f357aed66c2..2ec8769c45f 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1,7 +1,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use std::path::{Path, PathBuf}; -use rustc_ast::{ast, attr, ptr}; +use rustc_ast::{ast, attr}; use rustc_errors::Diag; use rustc_parse::parser::Parser as RawParser; use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; @@ -102,7 +102,7 @@ impl<'a> Parser<'a> { psess: &'a ParseSess, path: &Path, span: Span, - ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { + ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); diff --git a/src/patterns.rs b/src/patterns.rs index cb3879f4be8..d212ecf392a 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -1,5 +1,4 @@ use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax}; -use rustc_ast::ptr; use rustc_span::{BytePos, Span}; use crate::comment::{FindUncommented, combine_strs_with_missing_comments}; @@ -77,7 +76,7 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool } pub(crate) struct RangeOperand<'a, T> { - pub operand: &'a Option>, + pub operand: &'a Option>, pub span: Span, } @@ -329,8 +328,8 @@ impl Rewrite for Pat { pub fn rewrite_range_pat( context: &RewriteContext<'_>, shape: Shape, - lhs: &Option>, - rhs: &Option>, + lhs: &Option>, + rhs: &Option>, end_kind: &rustc_span::source_map::Spanned, span: Span, ) -> RewriteResult { @@ -371,7 +370,7 @@ pub fn rewrite_range_pat( } fn rewrite_struct_pat( - qself: &Option>, + qself: &Option>, path: &ast::Path, fields: &[ast::PatField], ellipsis: bool, @@ -505,7 +504,7 @@ impl Rewrite for PatField { #[derive(Debug)] pub(crate) enum TuplePatField<'a> { - Pat(&'a ptr::P), + Pat(&'a Box), Dotdot(Span), } @@ -562,7 +561,7 @@ pub(crate) fn can_be_overflowed_pat( } fn rewrite_tuple_pat( - pats: &[ptr::P], + pats: &[Box], path_str: Option, span: Span, context: &RewriteContext<'_>, diff --git a/src/rewrite.rs b/src/rewrite.rs index 83020709797..f0accd62d1a 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -3,7 +3,6 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; -use rustc_ast::ptr; use rustc_span::Span; use thiserror::Error; @@ -24,7 +23,7 @@ pub(crate) trait Rewrite { } } -impl Rewrite for ptr::P { +impl Rewrite for Box { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { (**self).rewrite(context, shape) } diff --git a/src/spanned.rs b/src/spanned.rs index ac132999b62..020651e2daa 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -1,6 +1,6 @@ use std::cmp::max; -use rustc_ast::{ast, ptr}; +use rustc_ast::ast; use rustc_span::{Span, source_map}; use crate::macros::MacroArg; @@ -12,7 +12,7 @@ pub(crate) trait Spanned { fn span(&self) -> Span; } -impl Spanned for ptr::P { +impl Spanned for Box { fn span(&self) -> Span { (**self).span() } diff --git a/src/types.rs b/src/types.rs index 9ee10d86270..5dce9a0c8d0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,6 @@ use std::ops::Deref; use rustc_ast::ast::{self, FnRetTy, Mutability, Term}; -use rustc_ast::ptr; use rustc_span::{BytePos, Pos, Span, symbol::kw}; use tracing::debug; @@ -39,7 +38,7 @@ pub(crate) enum PathContext { pub(crate) fn rewrite_path( context: &RewriteContext<'_>, path_context: PathContext, - qself: &Option>, + qself: &Option>, path: &ast::Path, shape: Shape, ) -> RewriteResult { @@ -1340,7 +1339,7 @@ fn join_bounds_inner( } } -pub(crate) fn opaque_ty(ty: &Option>) -> Option<&ast::GenericBounds> { +pub(crate) fn opaque_ty(ty: &Option>) -> Option<&ast::GenericBounds> { ty.as_ref().and_then(|t| match &t.kind { ast::TyKind::ImplTrait(_, bounds) => Some(bounds), _ => None, diff --git a/src/utils.rs b/src/utils.rs index fcd475b1784..b9950e94d0c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; +use rustc_ast::YieldKind; use rustc_ast::ast::{ self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility, VisibilityKind, }; -use rustc_ast::{YieldKind, ptr}; use rustc_ast_pretty::pprust; use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol}; use unicode_width::UnicodeWidthStr; @@ -149,8 +149,8 @@ pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static } #[inline] -// Transform `Vec>` into `Vec<&T>` -pub(crate) fn ptr_vec_to_ref_vec(vec: &[ptr::P]) -> Vec<&T> { +// Transform `Vec>` into `Vec<&T>` +pub(crate) fn ptr_vec_to_ref_vec(vec: &[Box]) -> Vec<&T> { vec.iter().map(|x| &**x).collect::>() } diff --git a/src/visitor.rs b/src/visitor.rs index f6a9a3f2cd1..23d07c930d9 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -874,7 +874,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { !is_skip_attr(segments) } - fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P]) { + fn walk_mod_items(&mut self, items: &[Box]) { self.visit_items_with_reordering(&ptr_vec_to_ref_vec(items)); } From c9ee26ffdfeb427ee88e2df41644feec3b9fd8a9 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 21 Jul 2025 20:05:16 -0500 Subject: [PATCH 26/49] Extract ast TraitImplHeader --- src/items.rs | 51 +++++++++++++++-------------------- tests/source/negative-impl.rs | 4 --- tests/target/negative-impl.rs | 8 ------ 3 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/items.rs b/src/items.rs index 57d4142ebe4..10df6f96702 100644 --- a/src/items.rs +++ b/src/items.rs @@ -958,20 +958,19 @@ fn format_impl_ref_and_type( offset: Indent, ) -> Option { let ast::Impl { - safety, - polarity, - defaultness, - constness, - ref generics, - of_trait: ref trait_ref, - ref self_ty, - .. - } = *iimpl; + generics, + of_trait, + self_ty, + items: _, + } = iimpl; let mut result = String::with_capacity(128); result.push_str(&format_visibility(context, &item.vis)); - result.push_str(format_defaultness(defaultness)); - result.push_str(format_safety(safety)); + + if let Some(of_trait) = of_trait.as_deref() { + result.push_str(format_defaultness(of_trait.defaultness)); + result.push_str(format_safety(of_trait.safety)); + } let shape = if context.config.style_edition() >= StyleEdition::Edition2024 { Shape::indented(offset + last_line_width(&result), context.config) @@ -984,28 +983,24 @@ fn format_impl_ref_and_type( }; let generics_str = rewrite_generics(context, "impl", generics, shape).ok()?; result.push_str(&generics_str); - result.push_str(format_constness_right(constness)); - let polarity_str = match polarity { - ast::ImplPolarity::Negative(_) => "!", - ast::ImplPolarity::Positive => "", - }; - - let polarity_overhead; let trait_ref_overhead; - if let Some(ref trait_ref) = *trait_ref { + if let Some(of_trait) = of_trait.as_deref() { + result.push_str(format_constness_right(of_trait.constness)); + let polarity_str = match of_trait.polarity { + ast::ImplPolarity::Negative(_) => "!", + ast::ImplPolarity::Positive => "", + }; let result_len = last_line_width(&result); result.push_str(&rewrite_trait_ref( context, - trait_ref, + &of_trait.trait_ref, offset, polarity_str, result_len, )?); - polarity_overhead = 0; // already written trait_ref_overhead = " for".len(); } else { - polarity_overhead = polarity_str.len(); trait_ref_overhead = 0; } @@ -1020,17 +1015,15 @@ fn format_impl_ref_and_type( } else { 0 }; - let used_space = - last_line_width(&result) + polarity_overhead + trait_ref_overhead + curly_brace_overhead; + let used_space = last_line_width(&result) + trait_ref_overhead + curly_brace_overhead; // 1 = space before the type. let budget = context.budget(used_space + 1); if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) { if !self_ty_str.contains('\n') { - if trait_ref.is_some() { + if of_trait.is_some() { result.push_str(" for "); } else { result.push(' '); - result.push_str(polarity_str); } result.push_str(&self_ty_str); return Some(result); @@ -1042,12 +1035,10 @@ fn format_impl_ref_and_type( // Add indentation of one additional tab. let new_line_offset = offset.block_indent(context.config); result.push_str(&new_line_offset.to_string(context.config)); - if trait_ref.is_some() { + if of_trait.is_some() { result.push_str("for "); - } else { - result.push_str(polarity_str); } - let budget = context.budget(last_line_width(&result) + polarity_overhead); + let budget = context.budget(last_line_width(&result)); let type_offset = match context.config.indent_style() { IndentStyle::Visual => new_line_offset + trait_ref_overhead, IndentStyle::Block => new_line_offset, diff --git a/tests/source/negative-impl.rs b/tests/source/negative-impl.rs index da242d4f3dc..e8f9508e656 100644 --- a/tests/source/negative-impl.rs +++ b/tests/source/negative-impl.rs @@ -1,7 +1,3 @@ impl ! Display for JoinHandle { } -impl ! Box < JoinHandle > { } - impl ! std :: fmt :: Display for JoinHandle < T : std :: future :: Future + std :: marker :: Send + std :: marker :: Sync > { } - -impl ! JoinHandle < T : std :: future :: Future < Output > + std :: marker :: Send + std :: marker :: Sync + 'static > + 'static { } diff --git a/tests/target/negative-impl.rs b/tests/target/negative-impl.rs index 16ce7e26a99..bb53048dbc6 100644 --- a/tests/target/negative-impl.rs +++ b/tests/target/negative-impl.rs @@ -1,14 +1,6 @@ impl !Display for JoinHandle {} -impl !Box {} - impl !std::fmt::Display for JoinHandle { } - -impl - !JoinHandle + std::marker::Send + std::marker::Sync + 'static> - + 'static -{ -} From b63507db20c6801d00022bddf51afc91e1060a20 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 19 Aug 2025 15:06:48 +1000 Subject: [PATCH 27/49] Prevent impossible combinations in `ast::ModKind`. `ModKind::Loaded` has an `inline` field and a `had_parse_error` field. If the `inline` field is `Inline::Yes` then `had_parse_error` must be `Ok(())`. This commit moves the `had_parse_error` field into the `Inline::No` variant. This makes it impossible to create the nonsensical combination of `inline == Inline::Yes` and `had_parse_error = Err(_)`. --- src/items.rs | 2 +- src/modules.rs | 7 ++++--- src/visitor.rs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/items.rs b/src/items.rs index 10df6f96702..6555679c394 100644 --- a/src/items.rs +++ b/src/items.rs @@ -3600,7 +3600,7 @@ pub(crate) fn rewrite_extern_crate( pub(crate) fn is_mod_decl(item: &ast::Item) -> bool { !matches!( item.kind, - ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _)) + ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) ) } diff --git a/src/modules.rs b/src/modules.rs index 3bc656b64b3..af9feccb32e 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -316,11 +316,12 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { self.directory = directory; } match (sub_mod.ast_mod_kind, sub_mod.items) { - (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _, _))), _) => { + (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { self.visit_mod_from_ast(items) } - (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _, _))), _) - | (_, Cow::Owned(items)) => self.visit_mod_outside_ast(items), + (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => { + self.visit_mod_outside_ast(items) + } (_, _) => Ok(()), } } diff --git a/src/visitor.rs b/src/visitor.rs index 23d07c930d9..a3acbb218ff 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -942,7 +942,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let ident_str = rewrite_ident(&self.get_context(), ident).to_owned(); self.push_str(&ident_str); - if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans, _) = mod_kind { + if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind { let ast::ModSpans { inner_span, inject_use_span: _, From 366a08f08993d2642335149b00c8826720e50279 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 8 Aug 2025 16:31:53 -0500 Subject: [PATCH 28/49] test(rustfmt): Verify frontmatter is preserved This is to prove that the frontmatter is preserved. The choices in tests is intended for showing the different parts of the proposed Style Guide for frontmatters. --- tests/source/frontmatter_compact.rs | 8 ++++++++ tests/source/frontmatter_escaped.rs | 13 +++++++++++++ tests/source/frontmatter_spaced.rs | 16 ++++++++++++++++ tests/target/frontmatter_compact.rs | 8 ++++++++ tests/target/frontmatter_escaped.rs | 13 +++++++++++++ tests/target/frontmatter_spaced.rs | 16 ++++++++++++++++ 6 files changed, 74 insertions(+) create mode 100644 tests/source/frontmatter_compact.rs create mode 100644 tests/source/frontmatter_escaped.rs create mode 100644 tests/source/frontmatter_spaced.rs create mode 100644 tests/target/frontmatter_compact.rs create mode 100644 tests/target/frontmatter_escaped.rs create mode 100644 tests/target/frontmatter_spaced.rs diff --git a/tests/source/frontmatter_compact.rs b/tests/source/frontmatter_compact.rs new file mode 100644 index 00000000000..21d4c6f4b61 --- /dev/null +++ b/tests/source/frontmatter_compact.rs @@ -0,0 +1,8 @@ +#!/usr/bin/env cargo +---identifier +[dependencies] +regex = "1" +--- +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/source/frontmatter_escaped.rs b/tests/source/frontmatter_escaped.rs new file mode 100644 index 00000000000..0d026377566 --- /dev/null +++ b/tests/source/frontmatter_escaped.rs @@ -0,0 +1,13 @@ +#!/usr/bin/env cargo +------------ +package.description = """ +Header +----- + +Body +""" +------------ + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/source/frontmatter_spaced.rs b/tests/source/frontmatter_spaced.rs new file mode 100644 index 00000000000..ee0bb81705c --- /dev/null +++ b/tests/source/frontmatter_spaced.rs @@ -0,0 +1,16 @@ +#!/usr/bin/env cargo + + +--- identifier +[dependencies] +regex = "1" + +--- + + + + + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/target/frontmatter_compact.rs b/tests/target/frontmatter_compact.rs new file mode 100644 index 00000000000..21d4c6f4b61 --- /dev/null +++ b/tests/target/frontmatter_compact.rs @@ -0,0 +1,8 @@ +#!/usr/bin/env cargo +---identifier +[dependencies] +regex = "1" +--- +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/target/frontmatter_escaped.rs b/tests/target/frontmatter_escaped.rs new file mode 100644 index 00000000000..0d026377566 --- /dev/null +++ b/tests/target/frontmatter_escaped.rs @@ -0,0 +1,13 @@ +#!/usr/bin/env cargo +------------ +package.description = """ +Header +----- + +Body +""" +------------ + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/target/frontmatter_spaced.rs b/tests/target/frontmatter_spaced.rs new file mode 100644 index 00000000000..ee0bb81705c --- /dev/null +++ b/tests/target/frontmatter_spaced.rs @@ -0,0 +1,16 @@ +#!/usr/bin/env cargo + + +--- identifier +[dependencies] +regex = "1" + +--- + + + + + +#![feature(frontmatter)] + +fn main() {} From 671c0c9a9ad785e56a68f8d3f4c47997d096f80d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 21 Aug 2025 21:51:20 +1000 Subject: [PATCH 29/49] Remove `dirs-sys-0.4.1` dependency. By updating rustfmt to use `dirs-6.0.0`. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e497b792342..6392ffbe409 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ cargo_metadata = "0.18" clap = { version = "4.4.2", features = ["derive"] } clap-cargo = "0.12.0" diff = "0.1" -dirs = "5.0" +dirs = "6.0" getopts = "0.2" ignore = "0.4" itertools = "0.12" From 2890913f4e5fbe0055ede7064ec9d6ff78294bf2 Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 23 Aug 2025 11:37:53 +0200 Subject: [PATCH 30/49] add span to struct pattern rest (..) --- src/patterns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patterns.rs b/src/patterns.rs index d212ecf392a..848bd0766e7 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -303,7 +303,7 @@ impl Rewrite for Pat { qself, path, fields, - rest == ast::PatFieldsRest::Rest, + matches!(rest, ast::PatFieldsRest::Rest(_)), self.span, context, shape, From 086aa840db2649fa86a4496dc5d15467fb588cf3 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Mon, 1 Sep 2025 08:55:25 -0400 Subject: [PATCH 31/49] fix a constness ordering bug in rustfmt Normally, changes to rustfmt go into the separate repo. But, in this case, the bug is introduced in a local change and therefore isn't present in the rustfmt repo. --- src/items.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items.rs b/src/items.rs index 6555679c394..75e468b3525 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1175,8 +1175,8 @@ pub(crate) fn format_trait( let mut result = String::with_capacity(128); let header = format!( "{}{}{}{}trait ", - format_constness(constness), format_visibility(context, &item.vis), + format_constness(constness), format_safety(safety), format_auto(is_auto), ); From 288b931c202adfc483756333bd219aa5bd9beeb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 8 Sep 2025 19:25:22 +0200 Subject: [PATCH 32/49] Strip frontmatter in fewer places --- src/parse/parser.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 2ec8769c45f..63c6c8c99d0 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; use rustc_ast::{ast, attr}; use rustc_errors::Diag; +use rustc_parse::lexer::StripTokens; use rustc_parse::parser::Parser as RawParser; use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_span::{Span, sym}; @@ -64,11 +65,14 @@ impl<'a> ParserBuilder<'a> { input: Input, ) -> Result, Vec>> { match input { - Input::File(ref file) => new_parser_from_file(psess, file, None), + Input::File(ref file) => { + new_parser_from_file(psess, file, StripTokens::ShebangAndFrontmatter, None) + } Input::Text(text) => new_parser_from_source_str( psess, rustc_span::FileName::Custom("stdin".to_owned()), text, + StripTokens::ShebangAndFrontmatter, ), } } @@ -104,8 +108,12 @@ impl<'a> Parser<'a> { span: Span, ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = - unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); + let mut parser = unwrap_or_emit_fatal(new_parser_from_file( + psess.inner(), + path, + StripTokens::ShebangAndFrontmatter, + Some(span), + )); match parser.parse_mod(exp!(Eof)) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { From f30038006f6dfcc99a875c14552c56904e875e02 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 1 Aug 2025 21:55:11 +0300 Subject: [PATCH 33/49] resolve: Do not finalize shadowed bindings I.e. do not mark them as used, or non-speculative loaded, or similar. Previously they were sometimes finalized during early resolution, causing issues like https://github.com/rust-lang/rust/pull/144793#issuecomment-3168108005. --- src/config/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 6b63108c037..525953bf445 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -516,7 +516,6 @@ mod test { #[allow(dead_code)] mod mock { use super::super::*; - use crate::config_option_with_style_edition_default; use rustfmt_config_proc_macro::config_type; #[config_type] From de03b6f7b838527257c638678fbedec19b85d80e Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 4 Sep 2025 18:45:32 -0500 Subject: [PATCH 34/49] Remove boxes from ast Pat lists --- src/parse/macros/mod.rs | 2 +- src/patterns.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 724d7a09e4a..c063990dfa0 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -61,7 +61,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { Pat, NonterminalKind::Pat(PatParam { inferred: false }), |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), - |x: Box| Some(x) + |x: ast::Pat| Some(Box::new(x)) ); // `parse_item` returns `Option>`. parse_macro_arg!( diff --git a/src/patterns.rs b/src/patterns.rs index 848bd0766e7..fa9a3e33914 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -504,7 +504,7 @@ impl Rewrite for PatField { #[derive(Debug)] pub(crate) enum TuplePatField<'a> { - Pat(&'a Box), + Pat(&'a ast::Pat), Dotdot(Span), } @@ -561,7 +561,7 @@ pub(crate) fn can_be_overflowed_pat( } fn rewrite_tuple_pat( - pats: &[Box], + pats: &[ast::Pat], path_str: Option, span: Span, context: &RewriteContext<'_>, From ce8721ca80e6dae60949f943762c97cf3874391f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 24 Jan 2025 12:19:17 +0000 Subject: [PATCH 35/49] Add not-null pointer patterns to pattern types --- src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.rs b/src/types.rs index 5dce9a0c8d0..242d8c23113 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1099,7 +1099,7 @@ impl Rewrite for ast::TyPat { } Ok(s) } - ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), + ast::TyPatKind::NotNull | ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), } } } From 893f81d36c74f6fe61416965ef714a8cd106d3fb Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 15 Oct 2025 04:04:36 +0000 Subject: [PATCH 36/49] Retire ast::TyAliasWhereClauses. --- src/items.rs | 59 +++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/src/items.rs b/src/items.rs index 75e468b3525..a2e89c10a48 100644 --- a/src/items.rs +++ b/src/items.rs @@ -836,8 +836,7 @@ pub(crate) fn format_impl( let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1224,8 +1223,7 @@ pub(crate) fn format_trait( let option = WhereClauseOption::snuggled(&generics_str); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), where_on_new_line, @@ -1350,8 +1348,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let where_str = rewrite_where_clause( context, - &self.generics.where_clause.predicates, - self.generics.where_clause.span, + &self.generics.where_clause, context.config.brace_style(), shape, false, @@ -1621,8 +1618,7 @@ fn format_tuple_struct( let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1691,7 +1687,7 @@ struct TyAliasRewriteInfo<'c, 'g>( &'c RewriteContext<'c>, Indent, &'g ast::Generics, - ast::TyAliasWhereClauses, + &'g ast::WhereClause, symbol::Ident, Span, ); @@ -1712,13 +1708,13 @@ pub(crate) fn rewrite_type_alias<'a>( ref generics, ref bounds, ref ty, - where_clauses, + ref after_where_clause, } = *ty_alias_kind; let ty_opt = ty.as_ref(); let rhs_hi = ty .as_ref() - .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi()); - let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span); + .map_or(generics.where_clause.span.hi(), |ty| ty.span.hi()); + let rw_info = &TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span); let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. @@ -1762,11 +1758,7 @@ fn rewrite_ty( vis: &ast::Visibility, ) -> RewriteResult { let mut result = String::with_capacity(128); - let TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span) = *rw_info; - let (before_where_predicates, after_where_predicates) = generics - .where_clause - .predicates - .split_at(where_clauses.split); + let TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span) = *rw_info; result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1804,8 +1796,7 @@ fn rewrite_ty( } let before_where_clause_str = rewrite_where_clause( context, - before_where_predicates, - where_clauses.before.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, indent), false, @@ -1820,9 +1811,9 @@ fn rewrite_ty( // If there are any where clauses, add a newline before the assignment. // If there is a before where clause, do not indent, but if there is // only an after where clause, additionally indent the type. - if !before_where_predicates.is_empty() { + if !generics.where_clause.predicates.is_empty() { result.push_str(&indent.to_string_with_newline(context.config)); - } else if !after_where_predicates.is_empty() { + } else if !after_where_clause.predicates.is_empty() { result.push_str( &indent .block_indent(context.config) @@ -1835,7 +1826,7 @@ fn rewrite_ty( let comment_span = context .snippet_provider .opt_span_before(span, "=") - .map(|op_lo| mk_sp(where_clauses.before.span.hi(), op_lo)); + .map(|op_lo| mk_sp(generics.where_clause.span.hi(), op_lo)); let lhs = match comment_span { Some(comment_span) @@ -1846,7 +1837,7 @@ fn rewrite_ty( .unknown_error()?, ) => { - let comment_shape = if !before_where_predicates.is_empty() { + let comment_shape = if !generics.where_clause.predicates.is_empty() { Shape::indented(indent, context.config) } else { let shape = Shape::indented(indent, context.config); @@ -1869,7 +1860,7 @@ fn rewrite_ty( // 1 = `;` unless there's a trailing where clause let shape = Shape::indented(indent, context.config); - let shape = if after_where_predicates.is_empty() { + let shape = if after_where_clause.predicates.is_empty() { Shape::indented(indent, context.config) .sub_width(1) .max_width_error(shape.width, span)? @@ -1881,12 +1872,11 @@ fn rewrite_ty( result }; - if !after_where_predicates.is_empty() { + if !after_where_clause.predicates.is_empty() { let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); let after_where_clause_str = rewrite_where_clause( context, - after_where_predicates, - where_clauses.after.span, + &after_where_clause, context.config.brace_style(), Shape::indented(indent, context.config), false, @@ -2728,8 +2718,7 @@ fn rewrite_fn_base( } let where_clause_str = rewrite_where_clause( context, - &where_clause.predicates, - where_clause.span, + &where_clause, context.config.brace_style(), Shape::indented(indent, context.config), true, @@ -3158,8 +3147,7 @@ fn rewrite_bounds_on_where_clause( fn rewrite_where_clause( context: &RewriteContext<'_>, - predicates: &[ast::WherePredicate], - where_span: Span, + where_clause: &ast::WhereClause, brace_style: BraceStyle, shape: Shape, on_new_line: bool, @@ -3168,6 +3156,12 @@ fn rewrite_where_clause( span_end_before_where: BytePos, where_clause_option: WhereClauseOption, ) -> RewriteResult { + let ast::WhereClause { + ref predicates, + span: where_span, + has_where_token: _, + } = *where_clause; + if predicates.is_empty() { return Ok(String::new()); } @@ -3354,8 +3348,7 @@ fn format_generics( } let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, brace_style, Shape::legacy(budget, offset.block_only()), true, From cfdd64ae40593abef16c22e4807afcd9f3aa6163 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Jul 2025 10:07:35 +0000 Subject: [PATCH 37/49] Trait aliases are rare large ast nodes, box them --- src/visitor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/visitor.rs b/src/visitor.rs index a3acbb218ff..633a17a4010 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -497,14 +497,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent)); self.push_rewrite(item.span, rw); } - ast::ItemKind::TraitAlias(ident, ref generics, ref generic_bounds) => { + ast::ItemKind::TraitAlias(ref ta) => { let shape = Shape::indented(self.block_indent, self.config); let rw = format_trait_alias( &self.get_context(), - ident, + ta.ident, &item.vis, - generics, - generic_bounds, + &ta.generics, + &ta.bounds, shape, ); self.push_rewrite(item.span, rw); From 49e62021e161f6726617089b2202062c1add0852 Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 13 Apr 2025 22:57:37 +0800 Subject: [PATCH 38/49] Implement pattern matching for `&pin mut|const T` --- src/patterns.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/patterns.rs b/src/patterns.rs index fa9a3e33914..03752c371ae 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -134,7 +134,8 @@ impl Rewrite for Pat { let mut_prefix = format_mutability(mutability).trim(); let (ref_kw, mut_infix) = match by_ref { - ByRef::Yes(rmutbl) => ("ref", format_mutability(rmutbl).trim()), + // FIXME(pin_ergonomics): format the pinnedness + ByRef::Yes(_, rmutbl) => ("ref", format_mutability(rmutbl).trim()), ByRef::No => ("", ""), }; let id_str = rewrite_ident(context, ident); From 60fa6f3409ccde80aa556a2581a6614adc0fc363 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Jul 2025 08:11:23 +0000 Subject: [PATCH 39/49] Add more tests --- tests/source/trait.rs | 2 ++ tests/target/trait.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/source/trait.rs b/tests/source/trait.rs index b6db9e1590d..1970646f777 100644 --- a/tests/source/trait.rs +++ b/tests/source/trait.rs @@ -181,3 +181,5 @@ trait Visible { pub fn f(); pub fn g() {} } + +const trait Foomp = Hash; \ No newline at end of file diff --git a/tests/target/trait.rs b/tests/target/trait.rs index 7f067991b26..cc2b59dc616 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -218,3 +218,5 @@ trait Visible { pub fn f(); pub fn g() {} } + +trait Foomp = Hash; From 069aef54a47fa008b9086613ecf785e4c92ecde3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Jul 2025 14:29:01 +0000 Subject: [PATCH 40/49] Fix formatting of const trait aliases --- src/items.rs | 15 +++++++-------- src/visitor.rs | 9 +-------- tests/target/const_trait.rs | 5 +++++ tests/target/trait.rs | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) create mode 100644 tests/target/const_trait.rs diff --git a/src/items.rs b/src/items.rs index a2e89c10a48..ecaa4670f61 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1375,22 +1375,21 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { pub(crate) fn format_trait_alias( context: &RewriteContext<'_>, - ident: symbol::Ident, + ta: &ast::TraitAlias, vis: &ast::Visibility, - generics: &ast::Generics, - generic_bounds: &ast::GenericBounds, shape: Shape, ) -> Option { - let alias = rewrite_ident(context, ident); + let alias = rewrite_ident(context, ta.ident); // 6 = "trait ", 2 = " =" let g_shape = shape.offset_left(6)?.sub_width(2)?; - let generics_str = rewrite_generics(context, alias, generics, g_shape).ok()?; + let generics_str = rewrite_generics(context, alias, &ta.generics, g_shape).ok()?; let vis_str = format_visibility(context, vis); - let lhs = format!("{vis_str}trait {generics_str} ="); + let constness = format_constness(ta.constness); + let lhs = format!("{vis_str}{constness}trait {generics_str} ="); // 1 = ";" let trait_alias_bounds = TraitAliasBounds { - generic_bounds, - generics, + generic_bounds: &ta.bounds, + generics: &ta.generics, }; rewrite_assign_rhs( context, diff --git a/src/visitor.rs b/src/visitor.rs index 633a17a4010..c521b497a2d 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -499,14 +499,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } ast::ItemKind::TraitAlias(ref ta) => { let shape = Shape::indented(self.block_indent, self.config); - let rw = format_trait_alias( - &self.get_context(), - ta.ident, - &item.vis, - &ta.generics, - &ta.bounds, - shape, - ); + let rw = format_trait_alias(&self.get_context(), ta, &item.vis, shape); self.push_rewrite(item.span, rw); } ast::ItemKind::ExternCrate(..) => { diff --git a/tests/target/const_trait.rs b/tests/target/const_trait.rs new file mode 100644 index 00000000000..c4c88b17fc5 --- /dev/null +++ b/tests/target/const_trait.rs @@ -0,0 +1,5 @@ +#![feature(trait_alias, const_trait_impl)] + +const trait Bar {} + +const trait Foo = Bar; diff --git a/tests/target/trait.rs b/tests/target/trait.rs index cc2b59dc616..7a65b13d629 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -219,4 +219,4 @@ trait Visible { pub fn g() {} } -trait Foomp = Hash; +const trait Foomp = Hash; From eaaa7da5b87ab600a77983cfdc96fa2f0f41c31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 2 Nov 2025 11:03:31 +0100 Subject: [PATCH 41/49] Generalize branch references to HEAD --- Configurations.md | 2 +- Contributing.md | 2 +- src/closures.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Configurations.md b/Configurations.md index b1f54060392..dd5ce73df0f 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2422,7 +2422,7 @@ See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuri ## `single_line_let_else_max_width` Maximum line length for single line let-else statements. -See the [let-else statement section of the Rust Style Guide](https://github.com/rust-lang/rust/blob/master/src/doc/style-guide/src/statements.md#else-blocks-let-else-statements) for more details on when a let-else statement may be written on a single line. +See the [let-else statement section of the Rust Style Guide](https://github.com/rust-lang/rust/blob/HEAD/src/doc/style-guide/src/statements.md#else-blocks-let-else-statements) for more details on when a let-else statement may be written on a single line. A value of `0` (zero) means the divergent `else` block will always be formatted over multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`. diff --git a/Contributing.md b/Contributing.md index 85754a8658a..212c5d00683 100644 --- a/Contributing.md +++ b/Contributing.md @@ -157,7 +157,7 @@ format. There are different nodes for every kind of item and expression in Rust. For more details see the source code in the compiler - -[ast.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast/src/ast.rs) - and/or the +[ast.rs](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_ast/src/ast.rs) - and/or the [docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html). Many nodes in the AST (but not all, annoyingly) have a `Span`. A `Span` is a diff --git a/src/closures.rs b/src/closures.rs index bb10a7946b8..e219cacc155 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -480,7 +480,7 @@ fn is_block_closure_forced_inner(expr: &ast::Expr, style_edition: StyleEdition) /// if true {...} else {...} /// |x| 5 /// isn't parsed as (if true {...} else {...} | x) | 5 -// From https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/classify.rs. +// From https://github.com/rust-lang/rust/blob/HEAD/src/libsyntax/parse/classify.rs. fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { match e.kind { ast::ExprKind::If(..) From 70f61645c924bd34fd1b7c8200466ce1589765bf Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 3 Nov 2025 18:06:57 -0500 Subject: [PATCH 42/49] Fix rustfmt --- src/items.rs | 74 +++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/items.rs b/src/items.rs index ecaa4670f61..062e2e051b1 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2004,37 +2004,37 @@ pub(crate) struct StaticParts<'a> { generics: Option<&'a ast::Generics>, ty: &'a ast::Ty, mutability: ast::Mutability, - expr_opt: Option<&'a Box>, + expr_opt: Option<&'a ast::Expr>, defaultness: Option, span: Span, } impl<'a> StaticParts<'a> { pub(crate) fn from_item(item: &'a ast::Item) -> Self { - let (defaultness, prefix, safety, ident, ty, mutability, expr, generics) = match &item.kind - { - ast::ItemKind::Static(s) => ( - None, - "static", - s.safety, - s.ident, - &s.ty, - s.mutability, - &s.expr, - None, - ), - ast::ItemKind::Const(c) => ( - Some(c.defaultness), - "const", - ast::Safety::Default, - c.ident, - &c.ty, - ast::Mutability::Not, - &c.expr, - Some(&c.generics), - ), - _ => unreachable!(), - }; + let (defaultness, prefix, safety, ident, ty, mutability, expr_opt, generics) = + match &item.kind { + ast::ItemKind::Static(s) => ( + None, + "static", + s.safety, + s.ident, + &s.ty, + s.mutability, + s.expr.as_deref(), + None, + ), + ast::ItemKind::Const(c) => ( + Some(c.defaultness), + "const", + ast::Safety::Default, + c.ident, + &c.ty, + ast::Mutability::Not, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), + _ => unreachable!(), + }; StaticParts { prefix, safety, @@ -2043,7 +2043,7 @@ impl<'a> StaticParts<'a> { generics, ty, mutability, - expr_opt: expr.as_ref(), + expr_opt, defaultness, span: item.span, } @@ -2051,7 +2051,12 @@ impl<'a> StaticParts<'a> { pub(crate) fn from_trait_item(ti: &'a ast::AssocItem, ident: Ident) -> Self { let (defaultness, ty, expr_opt, generics) = match &ti.kind { - ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), + ast::AssocItemKind::Const(c) => ( + c.defaultness, + &c.ty, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), _ => unreachable!(), }; StaticParts { @@ -2062,15 +2067,20 @@ impl<'a> StaticParts<'a> { generics, ty, mutability: ast::Mutability::Not, - expr_opt: expr_opt.as_ref(), + expr_opt, defaultness: Some(defaultness), span: ti.span, } } pub(crate) fn from_impl_item(ii: &'a ast::AssocItem, ident: Ident) -> Self { - let (defaultness, ty, expr, generics) = match &ii.kind { - ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), + let (defaultness, ty, expr_opt, generics) = match &ii.kind { + ast::AssocItemKind::Const(c) => ( + c.defaultness, + &c.ty, + c.rhs.as_ref().map(|rhs| rhs.expr()), + Some(&c.generics), + ), _ => unreachable!(), }; StaticParts { @@ -2081,7 +2091,7 @@ impl<'a> StaticParts<'a> { generics, ty, mutability: ast::Mutability::Not, - expr_opt: expr.as_ref(), + expr_opt, defaultness: Some(defaultness), span: ii.span, } @@ -2144,7 +2154,7 @@ fn rewrite_static( rewrite_assign_rhs_with_comments( context, &lhs, - &**expr, + expr, Shape::legacy(remaining_width, offset.block_only()), &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, From 8f1be83bede415070854cb51b3a293e581e8d314 Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 2 Nov 2025 19:23:36 +0800 Subject: [PATCH 43/49] Implement `&pin` patterns and `ref pin` bindings --- src/patterns.rs | 69 +++++++++++++++++++++++++++++---------- src/utils.rs | 13 ++++++++ tests/source/pin_sugar.rs | 19 +++++++++++ tests/target/pin_sugar.rs | 8 +++++ 4 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/patterns.rs b/src/patterns.rs index 03752c371ae..285bc9a9e42 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -17,7 +17,9 @@ use crate::shape::Shape; use crate::source_map::SpanUtils; use crate::spanned::Spanned; use crate::types::{PathContext, rewrite_path}; -use crate::utils::{format_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident}; +use crate::utils::{ + format_mutability, format_pinnedness_and_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident, +}; /// Returns `true` if the given pattern is "short". /// A short pattern is defined by the following grammar: @@ -69,7 +71,7 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool } ast::PatKind::Box(ref p) | PatKind::Deref(ref p) - | ast::PatKind::Ref(ref p, _) + | ast::PatKind::Ref(ref p, _, _) | ast::PatKind::Paren(ref p) => is_short_pattern_inner(context, &*p), PatKind::Or(ref pats) => pats.iter().all(|p| is_short_pattern_inner(context, p)), } @@ -133,10 +135,13 @@ impl Rewrite for Pat { PatKind::Ident(BindingMode(by_ref, mutability), ident, ref sub_pat) => { let mut_prefix = format_mutability(mutability).trim(); - let (ref_kw, mut_infix) = match by_ref { - // FIXME(pin_ergonomics): format the pinnedness - ByRef::Yes(_, rmutbl) => ("ref", format_mutability(rmutbl).trim()), - ByRef::No => ("", ""), + let (ref_kw, pin_infix, mut_infix) = match by_ref { + ByRef::Yes(pinnedness, rmutbl) => { + let (pin_infix, mut_infix) = + format_pinnedness_and_mutability(pinnedness, rmutbl); + ("ref", pin_infix.trim(), mut_infix.trim()) + } + ByRef::No => ("", "", ""), }; let id_str = rewrite_ident(context, ident); let sub_pat = match *sub_pat { @@ -147,6 +152,7 @@ impl Rewrite for Pat { .checked_sub( mut_prefix.len() + ref_kw.len() + + pin_infix.len() + mut_infix.len() + id_str.len() + 2, @@ -193,18 +199,17 @@ impl Rewrite for Pat { (true, true) => (self.span.lo(), "".to_owned()), }; - // combine result of above and mut - let (second_lo, second) = match (first.is_empty(), mut_infix.is_empty()) { + // combine result of above and pin + let (second_lo, second) = match (first.is_empty(), pin_infix.is_empty()) { (false, false) => { let lo = context.snippet_provider.span_after(self.span, "ref"); - let end_span = mk_sp(first_lo, self.span.hi()); - let hi = context.snippet_provider.span_before(end_span, "mut"); + let hi = context.snippet_provider.span_before(self.span, "pin"); ( - context.snippet_provider.span_after(end_span, "mut"), + context.snippet_provider.span_after(self.span, "pin"), combine_strs_with_missing_comments( context, &first, - mut_infix, + pin_infix, mk_sp(lo, hi), shape, true, @@ -212,7 +217,33 @@ impl Rewrite for Pat { ) } (false, true) => (first_lo, first), - (true, false) => unreachable!("mut_infix necessarily follows a ref"), + (true, false) => unreachable!("pin_infix necessarily follows a ref"), + (true, true) => (self.span.lo(), "".to_owned()), + }; + + // combine result of above and const|mut + let (third_lo, third) = match (second.is_empty(), mut_infix.is_empty()) { + (false, false) => { + let lo = context.snippet_provider.span_after( + self.span, + if pin_infix.is_empty() { "ref" } else { "pin" }, + ); + let end_span = mk_sp(second_lo, self.span.hi()); + let hi = context.snippet_provider.span_before(end_span, mut_infix); + ( + context.snippet_provider.span_after(end_span, mut_infix), + combine_strs_with_missing_comments( + context, + &second, + mut_infix, + mk_sp(lo, hi), + shape, + true, + )?, + ) + } + (false, true) => (second_lo, second), + (true, false) => unreachable!("mut_infix necessarily follows a pin or ref"), (true, true) => (self.span.lo(), "".to_owned()), }; @@ -232,9 +263,9 @@ impl Rewrite for Pat { combine_strs_with_missing_comments( context, - &second, + &third, &next, - mk_sp(second_lo, ident.span.lo()), + mk_sp(third_lo, ident.span.lo()), shape, true, ) @@ -263,8 +294,10 @@ impl Rewrite for Pat { PatKind::Range(ref lhs, ref rhs, ref end_kind) => { rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) } - PatKind::Ref(ref pat, mutability) => { - let prefix = format!("&{}", format_mutability(mutability)); + PatKind::Ref(ref pat, pinnedness, mutability) => { + let (pin_prefix, mut_prefix) = + format_pinnedness_and_mutability(pinnedness, mutability); + let prefix = format!("&{}{}", pin_prefix, mut_prefix); rewrite_unary_prefix(context, &prefix, &**pat, shape) } PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape), @@ -551,7 +584,7 @@ pub(crate) fn can_be_overflowed_pat( | ast::PatKind::Tuple(..) | ast::PatKind::Struct(..) | ast::PatKind::TupleStruct(..) => context.use_block_indent() && len == 1, - ast::PatKind::Ref(ref p, _) | ast::PatKind::Box(ref p) => { + ast::PatKind::Ref(ref p, _, _) | ast::PatKind::Box(ref p) => { can_be_overflowed_pat(context, &TuplePatField::Pat(p), len) } ast::PatKind::Expr(ref expr) => can_be_overflowed_expr(context, expr, len), diff --git a/src/utils.rs b/src/utils.rs index b9950e94d0c..3a2975024a3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -132,6 +132,19 @@ pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str { } } +#[inline] +pub(crate) fn format_pinnedness_and_mutability( + pinnedness: ast::Pinnedness, + mutability: ast::Mutability, +) -> (&'static str, &'static str) { + match (pinnedness, mutability) { + (ast::Pinnedness::Pinned, ast::Mutability::Mut) => ("pin ", "mut "), + (ast::Pinnedness::Pinned, ast::Mutability::Not) => ("pin ", "const "), + (ast::Pinnedness::Not, ast::Mutability::Mut) => ("", "mut "), + (ast::Pinnedness::Not, ast::Mutability::Not) => ("", ""), + } +} + #[inline] pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> { match ext { diff --git a/tests/source/pin_sugar.rs b/tests/source/pin_sugar.rs index e5b47339b92..5f52e244926 100644 --- a/tests/source/pin_sugar.rs +++ b/tests/source/pin_sugar.rs @@ -28,3 +28,22 @@ fn borrows() { pin const foo; } + +fn patterns<'a>( + &pin mut x: &pin + mut + i32, + & + pin + const + y: & + 'a pin + const + i32, + ref pin mut z: i32, + mut + ref + pin + const + w: i32, +) {} diff --git a/tests/target/pin_sugar.rs b/tests/target/pin_sugar.rs index 09ad23a5807..f366ab4da95 100644 --- a/tests/target/pin_sugar.rs +++ b/tests/target/pin_sugar.rs @@ -23,3 +23,11 @@ fn borrows() { let x: Pin<&_> = &pin const foo; } + +fn patterns<'a>( + &pin mut x: &pin mut i32, + &pin const y: &'a pin const i32, + ref pin mut z: i32, + mut ref pin const w: i32, +) { +} From 6fe782d14adc6dce7c7d00071a13dd7d8a08eaf7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 31 Oct 2025 10:50:52 +0000 Subject: [PATCH 44/49] Give all impls a constness --- src/items.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/items.rs b/src/items.rs index 062e2e051b1..d1778f324c6 100644 --- a/src/items.rs +++ b/src/items.rs @@ -961,6 +961,7 @@ fn format_impl_ref_and_type( of_trait, self_ty, items: _, + constness, } = iimpl; let mut result = String::with_capacity(128); @@ -969,6 +970,8 @@ fn format_impl_ref_and_type( if let Some(of_trait) = of_trait.as_deref() { result.push_str(format_defaultness(of_trait.defaultness)); result.push_str(format_safety(of_trait.safety)); + } else { + result.push_str(format_constness_right(*constness)); } let shape = if context.config.style_edition() >= StyleEdition::Edition2024 { @@ -985,7 +988,7 @@ fn format_impl_ref_and_type( let trait_ref_overhead; if let Some(of_trait) = of_trait.as_deref() { - result.push_str(format_constness_right(of_trait.constness)); + result.push_str(format_constness_right(*constness)); let polarity_str = match of_trait.polarity { ast::ImplPolarity::Negative(_) => "!", ast::ImplPolarity::Positive => "", From e4f4af218062e2668b85bf8a9151f1bdfb24cc6e Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 25 Nov 2025 11:34:27 +0100 Subject: [PATCH 45/49] fix tooling --- src/types.rs | 10 +--------- tests/source/type.rs | 6 ------ tests/target/type.rs | 4 ---- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/types.rs b/src/types.rs index 242d8c23113..2d7bc59c627 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,8 +8,7 @@ use crate::comment::{combine_strs_with_missing_comments, contains_comment}; use crate::config::lists::*; use crate::config::{IndentStyle, StyleEdition, TypeDensity}; use crate::expr::{ - ExprType, RhsAssignKind, format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, - rewrite_unary_prefix, + ExprType, RhsAssignKind, format_expr, rewrite_assign_rhs, rewrite_tuple, rewrite_unary_prefix, }; use crate::lists::{ ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list, @@ -1031,13 +1030,6 @@ impl Rewrite for ast::Ty { } ast::TyKind::CVarArgs => Ok("...".to_owned()), ast::TyKind::Dummy | ast::TyKind::Err(_) => Ok(context.snippet(self.span).to_owned()), - ast::TyKind::Typeof(ref anon_const) => rewrite_call( - context, - "typeof", - &[anon_const.value.clone()], - self.span, - shape, - ), ast::TyKind::Pat(ref ty, ref pat) => { let ty = ty.rewrite_result(context, shape)?; let pat = pat.rewrite_result(context, shape)?; diff --git a/tests/source/type.rs b/tests/source/type.rs index 213fad7cb16..09ec22cf8d1 100644 --- a/tests/source/type.rs +++ b/tests/source/type.rs @@ -158,9 +158,3 @@ impl Foo { Self(t) } } - -// #4357 -type T = typeof( -1); -impl T for .. { -} diff --git a/tests/target/type.rs b/tests/target/type.rs index 93479f8b484..623192b72b8 100644 --- a/tests/target/type.rs +++ b/tests/target/type.rs @@ -167,7 +167,3 @@ impl Foo { Self(t) } } - -// #4357 -type T = typeof(1); -impl T for .. {} From 79e4f74153ca5696e5b1c13a5520b7b5bdcc54f1 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 7 Dec 2025 23:09:56 +0800 Subject: [PATCH 46/49] chore: bump rustfmt toolchain to nightly-2025-12-06 Bumping the toolchain version as part of a git subtree push. current toolchain (nightly-2025-04-02): - 1.88.0-nightly (e2014e876 2025-04-01) latest toolchain (nightly-2025-12-06): - 1.94.0-nightly (ba86c0460 2025-12-06) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 80851788276..f2ce790ea06 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-04-02" +channel = "nightly-2025-12-06" components = ["llvm-tools", "rustc-dev"] From 43282a4af5a70b0a8f389aecf39944e3c8eaa80f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 1 Jul 2025 23:43:29 -0400 Subject: [PATCH 47/49] Revert "defer changes for zero argument functions until style_edition=2027" This effectively reverts commit a7e0c15d264fcc655c3b249d924e0852009d93fc. This change made it into the 2024 style edition so we can't defer it to 2027. --- .../{style_edition_2015.rs => version_one.rs} | 0 .../{style_edition_2024.rs => version_two.rs} | 0 tests/source/long-fn-1/style_edition_2027.rs | 21 -------------- .../{style_edition_2015.rs => version_one.rs} | 0 .../{style_edition_2024.rs => version_two.rs} | 0 tests/target/issue-3278/style_edition_2024.rs | 8 ----- tests/target/issue-3278/style_edition_2027.rs | 8 ----- .../{style_edition_2015.rs => version_one.rs} | 0 .../issue-3278/version_two.rs} | 2 +- tests/target/long-fn-1/style_edition_2024.rs | 29 ------------------- .../{style_edition_2015.rs => version_one.rs} | 0 .../{style_edition_2027.rs => version_two.rs} | 2 +- 12 files changed, 2 insertions(+), 68 deletions(-) rename tests/source/issue-3278/{style_edition_2015.rs => version_one.rs} (100%) rename tests/source/issue-3278/{style_edition_2024.rs => version_two.rs} (100%) delete mode 100644 tests/source/long-fn-1/style_edition_2027.rs rename tests/source/long-fn-1/{style_edition_2015.rs => version_one.rs} (100%) rename tests/source/long-fn-1/{style_edition_2024.rs => version_two.rs} (100%) delete mode 100644 tests/target/issue-3278/style_edition_2024.rs delete mode 100644 tests/target/issue-3278/style_edition_2027.rs rename tests/target/issue-3278/{style_edition_2015.rs => version_one.rs} (100%) rename tests/{source/issue-3278/style_edition_2027.rs => target/issue-3278/version_two.rs} (82%) delete mode 100644 tests/target/long-fn-1/style_edition_2024.rs rename tests/target/long-fn-1/{style_edition_2015.rs => version_one.rs} (100%) rename tests/target/long-fn-1/{style_edition_2027.rs => version_two.rs} (95%) diff --git a/tests/source/issue-3278/style_edition_2015.rs b/tests/source/issue-3278/version_one.rs similarity index 100% rename from tests/source/issue-3278/style_edition_2015.rs rename to tests/source/issue-3278/version_one.rs diff --git a/tests/source/issue-3278/style_edition_2024.rs b/tests/source/issue-3278/version_two.rs similarity index 100% rename from tests/source/issue-3278/style_edition_2024.rs rename to tests/source/issue-3278/version_two.rs diff --git a/tests/source/long-fn-1/style_edition_2027.rs b/tests/source/long-fn-1/style_edition_2027.rs deleted file mode 100644 index ded5a38d179..00000000000 --- a/tests/source/long-fn-1/style_edition_2027.rs +++ /dev/null @@ -1,21 +0,0 @@ -// rustfmt-style_edition: 2027 -// Tests that a function which is almost short enough, but not quite, gets -// formatted correctly. - -impl Foo { - fn some_input(&mut self, input: Input, input_path: Option, ) -> (Input, Option) {} - - fn some_inpu(&mut self, input: Input, input_path: Option) -> (Input, Option) {} -} - -// #1843 -#[allow(non_snake_case)] -pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash() -> bool { - false -} - -// #3009 -impl Something { - fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine( -) -> Result< (), String > {} -} diff --git a/tests/source/long-fn-1/style_edition_2015.rs b/tests/source/long-fn-1/version_one.rs similarity index 100% rename from tests/source/long-fn-1/style_edition_2015.rs rename to tests/source/long-fn-1/version_one.rs diff --git a/tests/source/long-fn-1/style_edition_2024.rs b/tests/source/long-fn-1/version_two.rs similarity index 100% rename from tests/source/long-fn-1/style_edition_2024.rs rename to tests/source/long-fn-1/version_two.rs diff --git a/tests/target/issue-3278/style_edition_2024.rs b/tests/target/issue-3278/style_edition_2024.rs deleted file mode 100644 index 676db3b20f8..00000000000 --- a/tests/target/issue-3278/style_edition_2024.rs +++ /dev/null @@ -1,8 +0,0 @@ -// rustfmt-style_edition: 2024 - -pub fn parse_conditional<'a, I: 'a>( -) -> impl Parser + 'a -where - I: Stream, -{ -} diff --git a/tests/target/issue-3278/style_edition_2027.rs b/tests/target/issue-3278/style_edition_2027.rs deleted file mode 100644 index f33dffeb7f5..00000000000 --- a/tests/target/issue-3278/style_edition_2027.rs +++ /dev/null @@ -1,8 +0,0 @@ -// rustfmt-style_edition: 2027 - -pub fn parse_conditional<'a, I: 'a>() --> impl Parser + 'a -where - I: Stream, -{ -} diff --git a/tests/target/issue-3278/style_edition_2015.rs b/tests/target/issue-3278/version_one.rs similarity index 100% rename from tests/target/issue-3278/style_edition_2015.rs rename to tests/target/issue-3278/version_one.rs diff --git a/tests/source/issue-3278/style_edition_2027.rs b/tests/target/issue-3278/version_two.rs similarity index 82% rename from tests/source/issue-3278/style_edition_2027.rs rename to tests/target/issue-3278/version_two.rs index f33dffeb7f5..eb605e509f9 100644 --- a/tests/source/issue-3278/style_edition_2027.rs +++ b/tests/target/issue-3278/version_two.rs @@ -1,4 +1,4 @@ -// rustfmt-style_edition: 2027 +// rustfmt-style_edition: 2024 pub fn parse_conditional<'a, I: 'a>() -> impl Parser + 'a diff --git a/tests/target/long-fn-1/style_edition_2024.rs b/tests/target/long-fn-1/style_edition_2024.rs deleted file mode 100644 index f5edca5ee7d..00000000000 --- a/tests/target/long-fn-1/style_edition_2024.rs +++ /dev/null @@ -1,29 +0,0 @@ -// rustfmt-style_edition: 2024 -// Tests that a function which is almost short enough, but not quite, gets -// formatted correctly. - -impl Foo { - fn some_input( - &mut self, - input: Input, - input_path: Option, - ) -> (Input, Option) { - } - - fn some_inpu(&mut self, input: Input, input_path: Option) -> (Input, Option) { - } -} - -// #1843 -#[allow(non_snake_case)] -pub extern "C" fn Java_com_exonum_binding_storage_indices_ValueSetIndexProxy_nativeContainsByHash( -) -> bool { - false -} - -// #3009 -impl Something { - fn my_function_name_is_way_to_long_but_used_as_a_case_study_or_an_example_its_fine( - ) -> Result<(), String> { - } -} diff --git a/tests/target/long-fn-1/style_edition_2015.rs b/tests/target/long-fn-1/version_one.rs similarity index 100% rename from tests/target/long-fn-1/style_edition_2015.rs rename to tests/target/long-fn-1/version_one.rs diff --git a/tests/target/long-fn-1/style_edition_2027.rs b/tests/target/long-fn-1/version_two.rs similarity index 95% rename from tests/target/long-fn-1/style_edition_2027.rs rename to tests/target/long-fn-1/version_two.rs index 87361f0b96b..f6007398bcc 100644 --- a/tests/target/long-fn-1/style_edition_2027.rs +++ b/tests/target/long-fn-1/version_two.rs @@ -1,4 +1,4 @@ -// rustfmt-style_edition: 2027 +// rustfmt-style_edition: 2024 // Tests that a function which is almost short enough, but not quite, gets // formatted correctly. From 0a9652a17814f837cc5526a8d2e738dcb5e9760e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 1 Jul 2025 23:21:48 -0400 Subject: [PATCH 48/49] defer version sorted modules until style-edition 2027 We didn't get this change synced with r-l/rust before the release of the 2024 edition, so trying to do a subtree-sync with this mod sorting logic for `style-edition=2024` would be a breaking change. --- CHANGELOG.md | 2 +- src/reorder.rs | 6 +-- .../disabled_style_edition_2027.rs | 47 +++++++++++++++++++ .../enabled_style_edition_2027.rs | 47 +++++++++++++++++++ .../disabled_style_edition_2027.rs | 47 +++++++++++++++++++ .../enabled_style_edition_2024.rs | 38 +++++++-------- .../enabled_style_edition_2027.rs | 47 +++++++++++++++++++ 7 files changed, 211 insertions(+), 23 deletions(-) create mode 100644 tests/source/reorder_modules/disabled_style_edition_2027.rs create mode 100644 tests/source/reorder_modules/enabled_style_edition_2027.rs create mode 100644 tests/target/reorder_modules/disabled_style_edition_2027.rs create mode 100644 tests/target/reorder_modules/enabled_style_edition_2027.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 483a34826a7..e004bba0dc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ ### Changed - 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) -- Apply version sorting to module declarations when using `style_edition=2024` [#6368](https://github.com/rust-lang/rustfmt/pull/6368) +- Apply version sorting to module declarations when using `style_edition=2027` [#6368](https://github.com/rust-lang/rustfmt/pull/6368) and [#6594](https://github.com/rust-lang/rustfmt/pull/6594) - 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) - Correct version chunk splitting in the internal version sort algorithm [#6407](https://github.com/rust-lang/rustfmt/pull/6407) - 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) diff --git a/src/reorder.rs b/src/reorder.rs index e9d0fc059f8..6ef6e0bc969 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -29,7 +29,7 @@ fn compare_items(a: &ast::Item, b: &ast::Item, context: &RewriteContext<'_>) -> let style_edition = context.config.style_edition(); match (&a.kind, &b.kind) { (&ast::ItemKind::Mod(_, a_ident, _), &ast::ItemKind::Mod(_, b_ident, _)) => { - if style_edition <= StyleEdition::Edition2021 { + if style_edition <= StyleEdition::Edition2024 { a_ident.as_str().cmp(b_ident.as_str()) } else { version_sort(a_ident.as_str(), b_ident.as_str()) @@ -43,7 +43,7 @@ fn compare_items(a: &ast::Item, b: &ast::Item, context: &RewriteContext<'_>) -> // ^^^ Comparing this. let a_orig_name = a_name.unwrap_or(a_ident.name); let b_orig_name = b_name.unwrap_or(b_ident.name); - let result = if style_edition <= StyleEdition::Edition2021 { + let result = if style_edition <= StyleEdition::Edition2024 { a_orig_name.as_str().cmp(b_orig_name.as_str()) } else { version_sort(a_orig_name.as_str(), b_orig_name.as_str()) @@ -58,7 +58,7 @@ fn compare_items(a: &ast::Item, b: &ast::Item, context: &RewriteContext<'_>) -> (Some(..), None) => Ordering::Greater, (None, Some(..)) => Ordering::Less, (None, None) => Ordering::Equal, - (Some(..), Some(..)) if style_edition <= StyleEdition::Edition2021 => { + (Some(..), Some(..)) if style_edition <= StyleEdition::Edition2024 => { a_ident.as_str().cmp(b_ident.as_str()) } (Some(..), Some(..)) => version_sort(a_ident.as_str(), b_ident.as_str()), diff --git a/tests/source/reorder_modules/disabled_style_edition_2027.rs b/tests/source/reorder_modules/disabled_style_edition_2027.rs new file mode 100644 index 00000000000..f5f0cb6357f --- /dev/null +++ b/tests/source/reorder_modules/disabled_style_edition_2027.rs @@ -0,0 +1,47 @@ +// rustfmt-style_edition: 2027 +// rustfmt-reorder_modules: false + +mod x86; +mod v0s; +mod v001; +mod x87; +mod zyxw; +mod A2; +mod ZYXW; +mod w5s009t; +mod u8; +mod x86_128; +mod _ZYXW; +mod ZY_XW; +mod a1; +mod v01; +mod v0u; +mod x86_64; +mod ua; +mod x86_32; +mod v9; +mod v010; +mod u_zzz; +mod v0; +mod v00; +mod v009; +mod w005s09t; +mod u32; +mod v1; +mod v00t; +mod v09; +mod u256; +mod ZY_XW; +mod _abcd; +mod ABCD; +mod Z_YXW; +mod u64; +mod abcd; +mod ZYXW_; +mod u16; +mod uz; +mod v10; +mod x64; +mod u128; +mod usize; +mod v000; diff --git a/tests/source/reorder_modules/enabled_style_edition_2027.rs b/tests/source/reorder_modules/enabled_style_edition_2027.rs new file mode 100644 index 00000000000..46f6abe9312 --- /dev/null +++ b/tests/source/reorder_modules/enabled_style_edition_2027.rs @@ -0,0 +1,47 @@ +// rustfmt-style_edition: 2027 +// rustfmt-reorder_modules: true + +mod x86; +mod v0s; +mod v001; +mod x87; +mod zyxw; +mod A2; +mod ZYXW; +mod w5s009t; +mod u8; +mod x86_128; +mod _ZYXW; +mod ZY_XW; +mod a1; +mod v01; +mod v0u; +mod x86_64; +mod ua; +mod x86_32; +mod v9; +mod v010; +mod u_zzz; +mod v0; +mod v00; +mod v009; +mod w005s09t; +mod u32; +mod v1; +mod v00t; +mod v09; +mod u256; +mod ZY_XW; +mod _abcd; +mod ABCD; +mod Z_YXW; +mod u64; +mod abcd; +mod ZYXW_; +mod u16; +mod uz; +mod v10; +mod x64; +mod u128; +mod usize; +mod v000; diff --git a/tests/target/reorder_modules/disabled_style_edition_2027.rs b/tests/target/reorder_modules/disabled_style_edition_2027.rs new file mode 100644 index 00000000000..f5f0cb6357f --- /dev/null +++ b/tests/target/reorder_modules/disabled_style_edition_2027.rs @@ -0,0 +1,47 @@ +// rustfmt-style_edition: 2027 +// rustfmt-reorder_modules: false + +mod x86; +mod v0s; +mod v001; +mod x87; +mod zyxw; +mod A2; +mod ZYXW; +mod w5s009t; +mod u8; +mod x86_128; +mod _ZYXW; +mod ZY_XW; +mod a1; +mod v01; +mod v0u; +mod x86_64; +mod ua; +mod x86_32; +mod v9; +mod v010; +mod u_zzz; +mod v0; +mod v00; +mod v009; +mod w005s09t; +mod u32; +mod v1; +mod v00t; +mod v09; +mod u256; +mod ZY_XW; +mod _abcd; +mod ABCD; +mod Z_YXW; +mod u64; +mod abcd; +mod ZYXW_; +mod u16; +mod uz; +mod v10; +mod x64; +mod u128; +mod usize; +mod v000; diff --git a/tests/target/reorder_modules/enabled_style_edition_2024.rs b/tests/target/reorder_modules/enabled_style_edition_2024.rs index ad78762aa01..addc555aa0e 100644 --- a/tests/target/reorder_modules/enabled_style_edition_2024.rs +++ b/tests/target/reorder_modules/enabled_style_edition_2024.rs @@ -1,47 +1,47 @@ // rustfmt-style_edition: 2024 // rustfmt-reorder_modules: true -mod _ZYXW; -mod _abcd; mod A2; mod ABCD; -mod Z_YXW; -mod ZY_XW; -mod ZY_XW; mod ZYXW; mod ZYXW_; +mod ZY_XW; +mod ZY_XW; +mod Z_YXW; +mod _ZYXW; +mod _abcd; mod a1; mod abcd; -mod u_zzz; -mod u8; +mod u128; mod u16; +mod u256; mod u32; mod u64; -mod u128; -mod u256; +mod u8; +mod u_zzz; mod ua; mod usize; mod uz; -mod v000; -mod v00; mod v0; -mod v0s; -mod v00t; -mod v0u; +mod v00; +mod v000; mod v001; -mod v01; -mod v1; mod v009; -mod v09; -mod v9; +mod v00t; +mod v01; mod v010; +mod v09; +mod v0s; +mod v0u; +mod v1; mod v10; +mod v9; mod w005s09t; mod w5s009t; mod x64; mod x86; +mod x86_128; mod x86_32; mod x86_64; -mod x86_128; mod x87; mod zyxw; diff --git a/tests/target/reorder_modules/enabled_style_edition_2027.rs b/tests/target/reorder_modules/enabled_style_edition_2027.rs new file mode 100644 index 00000000000..44acabd75f5 --- /dev/null +++ b/tests/target/reorder_modules/enabled_style_edition_2027.rs @@ -0,0 +1,47 @@ +// rustfmt-style_edition: 2027 +// rustfmt-reorder_modules: true + +mod _ZYXW; +mod _abcd; +mod A2; +mod ABCD; +mod Z_YXW; +mod ZY_XW; +mod ZY_XW; +mod ZYXW; +mod ZYXW_; +mod a1; +mod abcd; +mod u_zzz; +mod u8; +mod u16; +mod u32; +mod u64; +mod u128; +mod u256; +mod ua; +mod usize; +mod uz; +mod v000; +mod v00; +mod v0; +mod v0s; +mod v00t; +mod v0u; +mod v001; +mod v01; +mod v1; +mod v009; +mod v09; +mod v9; +mod v010; +mod v10; +mod w005s09t; +mod w5s009t; +mod x64; +mod x86; +mod x86_32; +mod x86_64; +mod x86_128; +mod x87; +mod zyxw; From 74b465a8c8c99a128b15545887b0ca2442d999a8 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 7 Dec 2025 23:37:37 +0800 Subject: [PATCH 49/49] Fix broken test annotations for `tests/source/issue-6202/long_pat.rs` 1. The test annotations have the wrong syntax. 2. The test is missing a Rust language Edition (>= 2024) for if-let chains. Detected in a subtree sync attempt. --- tests/source/issue-6202/long_pat.rs | 9 +++++---- tests/target/issue-6202/long_pat.rs | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/source/issue-6202/long_pat.rs b/tests/source/issue-6202/long_pat.rs index a7f47f32cb2..4444a4a78cb 100644 --- a/tests/source/issue-6202/long_pat.rs +++ b/tests/source/issue-6202/long_pat.rs @@ -1,6 +1,7 @@ -// max_width = 120 -// error_on_line_overflow = true -// style_edition = "2027" +// rustfmt-max_width: 120 +// rustfmt-error_on_line_overflow: true +// rustfmt-style_edition: 2027 +// rustfmt-edition: 2024 impl EarlyLintPass for NeedlessContinue { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { @@ -11,4 +12,4 @@ impl EarlyLintPass for NeedlessContinue { check_final_block_stmt(cx, body, label, expr.span.ctxt()); } } -} \ No newline at end of file +} diff --git a/tests/target/issue-6202/long_pat.rs b/tests/target/issue-6202/long_pat.rs index fef118a9da2..1d2282626a2 100644 --- a/tests/target/issue-6202/long_pat.rs +++ b/tests/target/issue-6202/long_pat.rs @@ -1,6 +1,7 @@ -// max_width = 120 -// error_on_line_overflow = true -// style_edition = "2027" +// rustfmt-max_width: 120 +// rustfmt-error_on_line_overflow: true +// rustfmt-style_edition: 2027 +// rustfmt-edition: 2024 impl EarlyLintPass for NeedlessContinue { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {