From ae760e695c605598b9563503a4f6a6618d64d5af Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Wed, 29 Nov 2023 15:39:20 -0500 Subject: [PATCH 01/66] Address unused tuple struct fields in rustfmt --- src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr.rs b/src/expr.rs index 7808f891336..8dead8f078d 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1947,7 +1947,7 @@ fn rewrite_unary_op( } pub(crate) enum RhsAssignKind<'ast> { - Expr(&'ast ast::ExprKind, Span), + Expr(&'ast ast::ExprKind, #[allow(unused_tuple_struct_fields)] Span), Bounds, Ty, } From 4a1b4182feaf284d26511fc3dae8fefc7a2efd04 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 30 Nov 2023 08:22:31 -0500 Subject: [PATCH 02/66] Rename `unused_tuple_struct_fields` in rustfmt Otherwise tests fail due to unknown lint and dead code warnings. --- src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr.rs b/src/expr.rs index 8dead8f078d..4b86c2acdc5 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1947,7 +1947,7 @@ fn rewrite_unary_op( } pub(crate) enum RhsAssignKind<'ast> { - Expr(&'ast ast::ExprKind, #[allow(unused_tuple_struct_fields)] Span), + Expr(&'ast ast::ExprKind, #[allow(dead_code)] Span), Bounds, Ty, } From 840824f3bb52a10c6ef1626505be5149708c4163 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 10:02:40 +1100 Subject: [PATCH 03/66] Rename `EmitterWriter` as `HumanEmitter`. For consistency with other `Emitter` impls, such as `JsonEmitter`, `SilentEmitter`, `SharedEmitter`, etc. --- 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 8303c03e1eb..2663f16b8e8 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -2,7 +2,7 @@ use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; -use rustc_errors::emitter::{DynEmitter, Emitter, EmitterWriter}; +use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ColorConfig, DiagCtxt, Diagnostic, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; @@ -139,7 +139,7 @@ fn default_dcx( rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false, ); - Box::new(EmitterWriter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) + Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) }; DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, From 141b31a23f4832017e6f5ce1f58ccc1e19868e12 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 3 Jan 2024 12:17:35 +1100 Subject: [PATCH 04/66] Make `DiagnosticBuilder::emit` consuming. This works for most of its call sites. This is nice, because `emit` very much makes sense as a consuming operation -- indeed, `DiagnosticBuilderState` exists to ensure no diagnostic is emitted twice, but it uses runtime checks. For the small number of call sites where a consuming emit doesn't work, the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will be removed in subsequent commits.) Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes consuming, while `delay_as_bug_without_consuming` is added (which will also be removed in subsequent commits.) All this requires significant changes to `DiagnosticBuilder`'s chaining methods. Currently `DiagnosticBuilder` method chaining uses a non-consuming `&mut self -> &mut Self` style, which allows chaining to be used when the chain ends in `emit()`, like so: ``` struct_err(msg).span(span).emit(); ``` But it doesn't work when producing a `DiagnosticBuilder` value, requiring this: ``` let mut err = self.struct_err(msg); err.span(span); err ``` This style of chaining won't work with consuming `emit` though. For that, we need to use to a `self -> Self` style. That also would allow `DiagnosticBuilder` production to be chained, e.g.: ``` self.struct_err(msg).span(span) ``` However, removing the `&mut self -> &mut Self` style would require that individual modifications of a `DiagnosticBuilder` go from this: ``` err.span(span); ``` to this: ``` err = err.span(span); ``` There are *many* such places. I have a high tolerance for tedious refactorings, but even I gave up after a long time trying to convert them all. Instead, this commit has it both ways: the existing `&mut self -> Self` chaining methods are kept, and new `self -> Self` chaining methods are added, all of which have a `_mv` suffix (short for "move"). Changes to the existing `forward!` macro lets this happen with very little additional boilerplate code. I chose to add the suffix to the new chaining methods rather than the existing ones, because the number of changes required is much smaller that way. This doubled chainging is a bit clumsy, but I think it is worthwhile because it allows a *lot* of good things to subsequently happen. In this commit, there are many `mut` qualifiers removed in places where diagnostics are emitted without being modified. In subsequent commits: - chaining can be used more, making the code more concise; - more use of chaining also permits the removal of redundant diagnostic APIs like `struct_err_with_code`, which can be replaced easily with `struct_err` + `code_mv`; - `emit_without_diagnostic` can be removed, which simplifies a lot of machinery, removing the need for `DiagnosticBuilderState`. --- src/parse/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 6bc53159b38..7045a7dd9ce 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -114,7 +114,7 @@ impl<'a> Parser<'a> { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), - Err(mut e) => { + Err(e) => { e.emit(); if sess.can_reset_errors() { sess.reset_errors(); @@ -165,7 +165,7 @@ impl<'a> Parser<'a> { match catch_unwind(move || parser.parse_crate_mod()) { Ok(Ok(k)) => Ok(k), - Ok(Err(mut db)) => { + Ok(Err(db)) => { db.emit(); Err(ParserError::ParseError) } From 192c4a0cf40adc752daa4fa37ca85300fbe70ab4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 9 Jan 2024 12:28:45 +1100 Subject: [PATCH 05/66] Change how `force-warn` lint diagnostics are recorded. `is_force_warn` is only possible for diagnostics with `Level::Warning`, but it is currently stored in `Diagnostic::code`, which every diagnostic has. This commit: - removes the boolean `DiagnosticId::Lint::is_force_warn` field; - adds a `ForceWarning` variant to `Level`. Benefits: - The common `Level::Warning` case now has no arguments, replacing lots of `Warning(None)` occurrences. - `rustc_session::lint::Level` and `rustc_errors::Level` are more similar, both having `ForceWarning` and `Warning`. --- src/parse/session.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 2663f16b8e8..f4fb5073dfd 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -446,7 +446,7 @@ mod tests { Some(ignore_list), ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(span)); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); emitter.emit_diagnostic(&non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); assert_eq!(can_reset_errors.load(Ordering::Acquire), true); @@ -470,7 +470,7 @@ mod tests { None, ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(span)); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); emitter.emit_diagnostic(&non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); @@ -507,8 +507,8 @@ mod tests { ); let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22))); - let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(bar_span)); - let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(foo_span)); + let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); + let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); emitter.emit_diagnostic(&bar_diagnostic); emitter.emit_diagnostic(&foo_diagnostic); From 381ef817b72ce951fb4e28f26a94c1fd7e5c9635 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 11 Jan 2024 14:22:44 +1100 Subject: [PATCH 06/66] Stop using `DiagnosticBuilder::buffer` in the parser. One consequence is that errors returned by `maybe_new_parser_from_source_str` now must be consumed, so a bunch of places that previously ignored those errors now cancel them. (Most of them explicitly dropped the errors before. I guess that was to indicate "we are explicitly ignoring these", though I'm not 100% sure.) --- src/parse/parser.rs | 4 ++-- src/parse/session.rs | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 7045a7dd9ce..31226cf8c30 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; -use rustc_errors::Diagnostic; +use rustc_errors::DiagnosticBuilder; use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; use rustc_span::{sym, Span}; use thin_vec::ThinVec; @@ -65,7 +65,7 @@ impl<'a> ParserBuilder<'a> { fn parser( sess: &'a rustc_session::parse::ParseSess, input: Input, - ) -> Result, Option>> { + ) -> Result, Option>>> { match input { Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { new_parser_from_file(sess, file, None) diff --git a/src/parse/session.rs b/src/parse/session.rs index f4fb5073dfd..6dc3eac44d4 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -4,7 +4,9 @@ use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; -use rustc_errors::{ColorConfig, DiagCtxt, Diagnostic, Level as DiagnosticLevel}; +use rustc_errors::{ + ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel, +}; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ source_map::{FilePathMapping, SourceMap}, @@ -283,9 +285,9 @@ impl ParseSess { // Methods that should be restricted within the parse module. impl ParseSess { - pub(super) fn emit_diagnostics(&self, diagnostics: Vec) { + pub(super) fn emit_diagnostics(&self, diagnostics: Vec>) { for diagnostic in diagnostics { - self.parse_sess.dcx.emit_diagnostic(diagnostic); + diagnostic.emit(); } } From 6078b96b236dbe40f0a0018a3432dea786e43071 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Sun, 26 Nov 2023 15:57:31 +0300 Subject: [PATCH 07/66] Delegation implementation: step 1 --- src/items.rs | 6 +++++- src/visitor.rs | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/items.rs b/src/items.rs index 6fb69d6b883..b57be8c1054 100644 --- a/src/items.rs +++ b/src/items.rs @@ -728,7 +728,9 @@ impl<'a> FmtVisitor<'a> { (Const(..), Const(..)) | (MacCall(..), MacCall(..)) => { a.ident.as_str().cmp(b.ident.as_str()) } - (Fn(..), Fn(..)) => a.span.lo().cmp(&b.span.lo()), + (Fn(..), Fn(..)) | (Delegation(..), Delegation(..)) => { + a.span.lo().cmp(&b.span.lo()) + } (Type(ty), _) if is_type(&ty.ty) => Ordering::Less, (_, Type(ty)) if is_type(&ty.ty) => Ordering::Greater, (Type(..), _) => Ordering::Less, @@ -737,6 +739,8 @@ impl<'a> FmtVisitor<'a> { (_, Const(..)) => Ordering::Greater, (MacCall(..), _) => Ordering::Less, (_, MacCall(..)) => Ordering::Greater, + (Delegation(..), _) => Ordering::Less, + (_, Delegation(..)) => Ordering::Greater, }); let mut prev_kind = None; for (buf, item) in buffer { diff --git a/src/visitor.rs b/src/visitor.rs index f4d84d1381f..bc5accefd92 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -592,6 +592,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ); self.push_rewrite(item.span, rewrite); } + ast::ItemKind::Delegation(..) => { + // TODO: rewrite delegation items once syntax is established. + // For now, leave the contents of the Span unformatted. + self.push_rewrite(item.span, None) + } }; } self.skip_context = skip_context_saved; From 255d2cf8f18e710375ff75f27562b500477c0201 Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Wed, 17 Jan 2024 03:14:16 +0100 Subject: [PATCH 08/66] Add `PatKind::Err` --- src/patterns.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/patterns.rs b/src/patterns.rs index 0fa6edaa5d7..7f576279432 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -40,9 +40,11 @@ pub(crate) fn is_short_pattern(pat: &ast::Pat, pat_str: &str) -> bool { fn is_short_pattern_inner(pat: &ast::Pat) -> bool { match pat.kind { - ast::PatKind::Rest | ast::PatKind::Never | ast::PatKind::Wild | ast::PatKind::Lit(_) => { - true - } + ast::PatKind::Rest + | ast::PatKind::Never + | ast::PatKind::Wild + | ast::PatKind::Err(_) + | ast::PatKind::Lit(_) => true, ast::PatKind::Ident(_, _, ref pat) => pat.is_none(), ast::PatKind::Struct(..) | ast::PatKind::MacCall(..) @@ -274,6 +276,7 @@ impl Rewrite for Pat { PatKind::Paren(ref pat) => pat .rewrite(context, shape.offset_left(1)?.sub_width(1)?) .map(|inner_pat| format!("({})", inner_pat)), + PatKind::Err(_) => None, } } } From b92320c39b9a0217342d566e56114b80312371c1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 22 Jan 2024 01:18:16 +0000 Subject: [PATCH 09/66] Check that a token can begin a nonterminal kind before parsing it as a macro arg in rustfmt --- src/parse/macros/mod.rs | 41 +++++++++++++---------- tests/source/macros/rewrite-const-item.rs | 1 + tests/target/macros/rewrite-const-item.rs | 3 ++ 3 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 tests/source/macros/rewrite-const-item.rs create mode 100644 tests/target/macros/rewrite-const-item.rs diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 2dd2622174f..36e3972a463 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -1,7 +1,7 @@ use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; -use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_parse::parser::{ForceCollect, Parser, Recovery}; use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; use rustc_session::parse::ParseSess; use rustc_span::symbol::{self, kw}; @@ -24,45 +24,52 @@ fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { macro_rules! parse_macro_arg { - ($macro_arg:ident, $parser:expr, $f:expr) => { + ($macro_arg:ident, $can_begin:expr, $try_parse:expr, $then:expr) => { let mut cloned_parser = (*parser).clone(); - match $parser(&mut cloned_parser) { - Ok(x) => { - if parser.sess.dcx.has_errors().is_some() { + if $can_begin(&mut cloned_parser) { + match $try_parse(&mut cloned_parser) { + Ok(x) => { + if parser.sess.dcx.has_errors().is_some() { + parser.sess.dcx.reset_err_count(); + } else { + // Parsing succeeded. + *parser = cloned_parser; + return Some(MacroArg::$macro_arg($then(x)?)); + } + } + Err(e) => { + e.cancel(); parser.sess.dcx.reset_err_count(); - } else { - // Parsing succeeded. - *parser = cloned_parser; - return Some(MacroArg::$macro_arg($f(x)?)); } } - Err(e) => { - e.cancel(); - parser.sess.dcx.reset_err_count(); - } } }; } parse_macro_arg!( Expr, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_expr(), + |parser: &mut Parser<'b>| parser.token.can_begin_expr(), + |parser: &mut Parser<'b>| parser.parse_expr(), |x: ptr::P| Some(x) ); parse_macro_arg!( Ty, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_ty(), + |parser: &mut Parser<'b>| parser.token.can_begin_type(), + |parser: &mut Parser<'b>| parser.parse_ty(), |x: ptr::P| Some(x) ); parse_macro_arg!( Pat, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_pat_no_top_alt(None, None), + // FIXME: This isn't right + |_| true, + |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), |x: ptr::P| Some(x) ); // `parse_item` returns `Option>`. parse_macro_arg!( Item, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_item(ForceCollect::No), + |_| true, + |parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No), |x: Option>| x ); diff --git a/tests/source/macros/rewrite-const-item.rs b/tests/source/macros/rewrite-const-item.rs new file mode 100644 index 00000000000..3db2c26ab5a --- /dev/null +++ b/tests/source/macros/rewrite-const-item.rs @@ -0,0 +1 @@ +m!(const N: usize = 0;); diff --git a/tests/target/macros/rewrite-const-item.rs b/tests/target/macros/rewrite-const-item.rs new file mode 100644 index 00000000000..f7ebaf78277 --- /dev/null +++ b/tests/target/macros/rewrite-const-item.rs @@ -0,0 +1,3 @@ +m!( + const N: usize = 0; +); From f8847ff3ecd37e3facb438e2b8784a8124f97454 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 22 Jan 2024 00:56:58 +0000 Subject: [PATCH 10/66] Do not eagerly recover malformed AST in rustfmt --- src/parse/macros/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 36e3972a463..c6ee96ebb8a 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -15,7 +15,7 @@ pub(crate) mod cfg_if; pub(crate) mod lazy_static; fn build_stream_parser<'a>(sess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> { - stream_to_parser(sess, tokens, MACRO_ARGUMENTS) + stream_to_parser(sess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden) } fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { From a0958082b36bd47ee5a71cad32f41b2906db46b8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 22 Jan 2024 01:55:49 +0000 Subject: [PATCH 11/66] Actually, just use nonterminal_may_begin_with --- src/parse/macros/mod.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index c6ee96ebb8a..a9f9ea1826a 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; @@ -24,9 +24,9 @@ fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { macro_rules! parse_macro_arg { - ($macro_arg:ident, $can_begin:expr, $try_parse:expr, $then:expr) => { + ($macro_arg:ident, $nt_kind:expr, $try_parse:expr, $then:expr) => { let mut cloned_parser = (*parser).clone(); - if $can_begin(&mut cloned_parser) { + if Parser::nonterminal_may_begin_with($nt_kind, &cloned_parser.token) { match $try_parse(&mut cloned_parser) { Ok(x) => { if parser.sess.dcx.has_errors().is_some() { @@ -48,27 +48,26 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { parse_macro_arg!( Expr, - |parser: &mut Parser<'b>| parser.token.can_begin_expr(), + NonterminalKind::Expr, |parser: &mut Parser<'b>| parser.parse_expr(), |x: ptr::P| Some(x) ); parse_macro_arg!( Ty, - |parser: &mut Parser<'b>| parser.token.can_begin_type(), + NonterminalKind::Ty, |parser: &mut Parser<'b>| parser.parse_ty(), |x: ptr::P| Some(x) ); parse_macro_arg!( Pat, - // FIXME: This isn't right - |_| true, + NonterminalKind::PatParam { inferred: false }, |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), |x: ptr::P| Some(x) ); // `parse_item` returns `Option>`. parse_macro_arg!( Item, - |_| true, + NonterminalKind::Item, |parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No), |x: Option>| x ); From 18f51f79f31a022257c0c1fe7501d4af141d3bad Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 2 Feb 2024 15:44:22 +1100 Subject: [PATCH 12/66] Make `Emitter::emit_diagnostic` consuming. All the other `emit`/`emit_diagnostic` methods were recently made consuming (e.g. #119606), but this one wasn't. But it makes sense to. Much of this is straightforward, and lots of `clone` calls are avoided. There are a couple of tricky bits. - `Emitter::primary_span_formatted` no longer takes a `Diagnostic` and returns a pair. Instead it takes the two fields from `Diagnostic` that it used (`span` and `suggestions`) as `&mut`, and modifies them. This is necessary to avoid the cloning of `diag.children` in two emitters. - `from_errors_diagnostic` is rearranged so various uses of `diag` occur before the consuming `emit_diagnostic` call. --- src/parse/session.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 6dc3eac44d4..f0af401d3da 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -47,7 +47,7 @@ impl Emitter for SilentEmitter { None } - fn emit_diagnostic(&mut self, _db: &Diagnostic) {} + fn emit_diagnostic(&mut self, _db: Diagnostic) {} } fn silent_emitter() -> Box { @@ -64,7 +64,7 @@ struct SilentOnIgnoredFilesEmitter { } impl SilentOnIgnoredFilesEmitter { - fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) { + fn handle_non_ignoreable_error(&mut self, db: Diagnostic) { self.has_non_ignorable_parser_errors = true; self.can_reset.store(false, Ordering::Release); self.emitter.emit_diagnostic(db); @@ -86,7 +86,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter { None } - fn emit_diagnostic(&mut self, db: &Diagnostic) { + fn emit_diagnostic(&mut self, db: Diagnostic) { if db.level() == DiagnosticLevel::Fatal { return self.handle_non_ignoreable_error(db); } @@ -365,7 +365,7 @@ mod tests { None } - fn emit_diagnostic(&mut self, _db: &Diagnostic) { + fn emit_diagnostic(&mut self, _db: Diagnostic) { self.num_emitted_errors.fetch_add(1, Ordering::Release); } } @@ -424,7 +424,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span)); - emitter.emit_diagnostic(&fatal_diagnostic); + emitter.emit_diagnostic(fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } @@ -449,7 +449,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(&non_fatal_diagnostic); + emitter.emit_diagnostic(non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); assert_eq!(can_reset_errors.load(Ordering::Acquire), true); } @@ -473,7 +473,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(&non_fatal_diagnostic); + emitter.emit_diagnostic(non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } @@ -512,9 +512,9 @@ mod tests { let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); - emitter.emit_diagnostic(&bar_diagnostic); - emitter.emit_diagnostic(&foo_diagnostic); - emitter.emit_diagnostic(&fatal_diagnostic); + emitter.emit_diagnostic(bar_diagnostic); + emitter.emit_diagnostic(foo_diagnostic); + emitter.emit_diagnostic(fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } From 88c5838c062eaa1521e0bf088088da4842711284 Mon Sep 17 00:00:00 2001 From: Frank King Date: Thu, 4 Jan 2024 21:53:06 +0800 Subject: [PATCH 13/66] Lower anonymous structs or unions to HIR --- src/types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.rs b/src/types.rs index cd2582e66be..aaef80f4aef 100644 --- a/src/types.rs +++ b/src/types.rs @@ -806,8 +806,8 @@ impl Rewrite for ast::Ty { ast::TyKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1) } - ast::TyKind::AnonStruct(_) => Some(context.snippet(self.span).to_owned()), - ast::TyKind::AnonUnion(_) => Some(context.snippet(self.span).to_owned()), + ast::TyKind::AnonStruct(..) => Some(context.snippet(self.span).to_owned()), + ast::TyKind::AnonUnion(..) => Some(context.snippet(self.span).to_owned()), ast::TyKind::Path(ref q_self, ref path) => { rewrite_path(context, PathContext::Type, q_self, path, shape) } From 16250ea7ba73f858a6ee08374848fbea615ea6c3 Mon Sep 17 00:00:00 2001 From: Frank King Date: Sat, 6 Jan 2024 15:52:22 +0800 Subject: [PATCH 14/66] Add rustfmt test from #117942 --- tests/target/anonymous-types.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/target/anonymous-types.rs b/tests/target/anonymous-types.rs index 8e08c314ed1..e8c2d83878c 100644 --- a/tests/target/anonymous-types.rs +++ b/tests/target/anonymous-types.rs @@ -16,4 +16,16 @@ struct Foo { e: f32, } +// Test for https://github.com/rust-lang/rust/issues/117942 +struct Foo { + _: union { + #[rustfmt::skip] + f: String, + }, + #[rustfmt::skip] + _: struct { + g: i32, + }, +} + fn main() {} From bed388348bbb5df299c5b5bd08a39d9e556a53ad Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 13 Feb 2024 16:05:41 +0000 Subject: [PATCH 15/66] Format async bounds in rustfmt --- src/types.rs | 19 +++++++++++++++---- tests/target/asyncness.rs | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 tests/target/asyncness.rs diff --git a/src/types.rs b/src/types.rs index cd2582e66be..f4ca18919db 100644 --- a/src/types.rs +++ b/src/types.rs @@ -537,18 +537,29 @@ impl Rewrite for ast::Lifetime { impl Rewrite for ast::GenericBound { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match *self { - ast::GenericBound::Trait(ref poly_trait_ref, modifiers) => { + ast::GenericBound::Trait( + ref poly_trait_ref, + ast::TraitBoundModifiers { + constness, + asyncness, + polarity, + }, + ) => { let snippet = context.snippet(self.span()); let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); - let mut constness = modifiers.constness.as_str().to_string(); + let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); } - let polarity = modifiers.polarity.as_str(); + let mut asyncness = asyncness.as_str().to_string(); + if !asyncness.is_empty() { + asyncness.push(' '); + } + let polarity = polarity.as_str(); let shape = shape.offset_left(constness.len() + polarity.len())?; poly_trait_ref .rewrite(context, shape) - .map(|s| format!("{constness}{polarity}{s}")) + .map(|s| format!("{constness}{asyncness}{polarity}{s}")) .map(|s| if has_paren { format!("({})", s) } else { s }) } ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape), diff --git a/tests/target/asyncness.rs b/tests/target/asyncness.rs new file mode 100644 index 00000000000..d91ac960499 --- /dev/null +++ b/tests/target/asyncness.rs @@ -0,0 +1,3 @@ +// rustfmt-edition: 2018 + +fn foo() -> impl async Fn() {} From 6674be96570d63b460c36869d6edd5d590356290 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 14 Feb 2024 14:50:49 +1100 Subject: [PATCH 16/66] Add an `ErrorGuaranteed` to `ast::TyKind::Err`. This makes it more like `hir::TyKind::Err`, and avoids a `span_delayed_bug` call in `LoweringContext::lower_ty_direct`. It also requires adding `ast::TyKind::Dummy`, now that `ast::TyKind::Err` can't be used for that purpose in the absence of an error emission. There are a couple of cases that aren't as neat as I would have liked, marked with `FIXME` comments. --- src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.rs b/src/types.rs index 4cd8e6a703e..7f220a456a8 100644 --- a/src/types.rs +++ b/src/types.rs @@ -859,7 +859,7 @@ impl Rewrite for ast::Ty { }) } ast::TyKind::CVarArgs => Some("...".to_owned()), - ast::TyKind::Err => Some(context.snippet(self.span).to_owned()), + ast::TyKind::Dummy | ast::TyKind::Err(_) => Some(context.snippet(self.span).to_owned()), ast::TyKind::Typeof(ref anon_const) => rewrite_call( context, "typeof", From aba5f546de28a10f6c374c90200f6142d47a8e38 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 14 Feb 2024 14:17:27 +0000 Subject: [PATCH 17/66] errors: only eagerly translate subdiagnostics Subdiagnostics don't need to be lazily translated, they can always be eagerly translated. Eager translation is slightly more complex as we need to have a `DiagCtxt` available to perform the translation, which involves slightly more threading of that context. This slight increase in complexity should enable later simplifications - like passing `DiagCtxt` into `AddToDiagnostic` and moving Fluent messages into the diagnostic structs rather than having them in separate files (working on that was what led to this change). Signed-off-by: David Wood --- src/parse/session.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/parse/session.rs b/src/parse/session.rs index f0af401d3da..cff025cf2ab 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; @@ -40,6 +41,16 @@ impl Translate for SilentEmitter { fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { panic!("silent emitter attempted to translate a diagnostic"); } + + // Override `translate_message` for the silent emitter because eager translation of + // subdiagnostics result in a call to this. + fn translate_message<'a>( + &'a self, + message: &'a rustc_errors::DiagnosticMessage, + _: &'a rustc_errors::translation::FluentArgs<'_>, + ) -> Result, rustc_errors::error::TranslateError<'_>> { + rustc_errors::emitter::silent_translate(message) + } } impl Emitter for SilentEmitter { From 263910118cb0f2d890a74c62a8e51dda47e13cbc Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 27 Jan 2024 17:39:16 +0100 Subject: [PATCH 18/66] Allow newly added non_local_definitions in rustfmt --- src/source_file.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/source_file.rs b/src/source_file.rs index 958f9b0154f..512a8593c27 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -66,6 +66,7 @@ where } } + #[cfg_attr(not(bootstrap), allow(non_local_definitions))] impl From<&FileName> for rustc_span::FileName { fn from(filename: &FileName) -> rustc_span::FileName { match filename { From ce71137b96e32ad7d198d3a073aff722917c4fd0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 23 Feb 2024 13:20:33 +1100 Subject: [PATCH 19/66] Explicitly call `emit_stashed_diagnostics`. Commit 72b172b in #121206 changed things so that `emit_stashed_diagnostics` is only called from `run_compiler`. But rustfmt doesn't use `run_compiler`, so it needs to call `emit_stashed_diagnostics` itself to avoid an abort in `DiagCtxtInner::drop` when stashed diagnostics occur. Fixes #121450. --- src/parse/parser.rs | 18 +++++++++++++----- src/test/parser.rs | 7 +++++++ tests/parser/stashed-diag.rs | 3 +++ 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 tests/parser/stashed-diag.rs diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 31226cf8c30..cca14353b5c 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -163,13 +163,21 @@ impl<'a> Parser<'a> { fn parse_crate_mod(&mut self) -> Result { let mut parser = AssertUnwindSafe(&mut self.parser); - match catch_unwind(move || parser.parse_crate_mod()) { - Ok(Ok(k)) => Ok(k), - Ok(Err(db)) => { + // rustfmt doesn't use `run_compiler` like other tools, so it must emit + // any stashed diagnostics itself, otherwise the `DiagCtxt` will assert + // when dropped. The final result here combines the parsing result and + // the `emit_stashed_diagnostics` result. + let parse_res = catch_unwind(move || parser.parse_crate_mod()); + let stashed_res = self.parser.dcx().emit_stashed_diagnostics(); + let err = Err(ParserError::ParsePanicError); + match (parse_res, stashed_res) { + (Ok(Ok(k)), None) => Ok(k), + (Ok(Ok(_)), Some(_guar)) => err, + (Ok(Err(db)), _) => { db.emit(); - Err(ParserError::ParseError) + err } - Err(_) => Err(ParserError::ParsePanicError), + (Err(_), _) => err, } } } diff --git a/src/test/parser.rs b/src/test/parser.rs index ae4a4f94d92..da2a2ba62e0 100644 --- a/src/test/parser.rs +++ b/src/test/parser.rs @@ -55,3 +55,10 @@ fn crate_parsing_errors_on_unclosed_delims() { let filename = "tests/parser/unclosed-delims/issue_4466.rs"; assert_parser_error(filename); } + +#[test] +fn crate_parsing_stashed_diag() { + // See also https://github.com/rust-lang/rust/issues/121450 + let filename = "tests/parser/stashed-diag.rs"; + assert_parser_error(filename); +} diff --git a/tests/parser/stashed-diag.rs b/tests/parser/stashed-diag.rs new file mode 100644 index 00000000000..3b0b543e610 --- /dev/null +++ b/tests/parser/stashed-diag.rs @@ -0,0 +1,3 @@ +#![u={static N;}] + +fn main() {} From 7d82dd0d31b426afaf88d307cc3fb7deddb44552 Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:22:09 +0100 Subject: [PATCH 20/66] Add `ast::ExprKind::Dummy` --- src/expr.rs | 2 +- src/utils.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/expr.rs b/src/expr.rs index 4b86c2acdc5..d46d7c53bdb 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -404,7 +404,7 @@ pub(crate) fn format_expr( // These do not occur in the AST because macros aren't expanded. unreachable!() } - ast::ExprKind::Err => None, + ast::ExprKind::Err | ast::ExprKind::Dummy => None, }; expr_rw diff --git a/src/utils.rs b/src/utils.rs index 642b6603b1e..b6b37e492e9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -497,6 +497,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Break(..) | ast::ExprKind::Cast(..) | ast::ExprKind::Continue(..) + | ast::ExprKind::Dummy | ast::ExprKind::Err | ast::ExprKind::Field(..) | ast::ExprKind::IncludedBytes(..) From 1bbfb76993eafc9828af62588f13fe68eaeb4e1a Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:22:11 +0100 Subject: [PATCH 21/66] Add `ErrorGuaranteed` to `ast::ExprKind::Err` --- src/expr.rs | 2 +- src/utils.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index d46d7c53bdb..c500b30b998 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -404,7 +404,7 @@ pub(crate) fn format_expr( // These do not occur in the AST because macros aren't expanded. unreachable!() } - ast::ExprKind::Err | ast::ExprKind::Dummy => None, + ast::ExprKind::Err(_) | ast::ExprKind::Dummy => None, }; expr_rw diff --git a/src/utils.rs b/src/utils.rs index b6b37e492e9..d4218cff75a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -498,7 +498,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Cast(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Dummy - | ast::ExprKind::Err + | ast::ExprKind::Err(_) | ast::ExprKind::Field(..) | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::InlineAsm(..) From 90af751966bc170a96860aea6186f1cc7f08217a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 26 Feb 2024 09:24:03 +1100 Subject: [PATCH 22/66] Move `emit_stashed_diagnostic` call in rustfmt. This call was added to `parse_crate_mod` in #121487, to fix a case where a stashed diagnostic wasn't emitted. But there is another path where a stashed diagnostic might fail to be emitted if there's a parse error, if the `build` call in `parse_crate_inner` fails before `parse_crate_mod` is reached. So this commit moves the `emit_stashed_diagnostic` call outwards, from `parse_crate_mod` to `format_project`, just after the `Parser::parse_crate` call. This should be far out enough to catch any parsing errors. Fixes #121517. --- src/formatting.rs | 22 ++++++++++++++++------ src/parse/parser.rs | 16 ++++------------ src/parse/session.rs | 6 +++++- src/test/parser.rs | 7 +++++++ tests/parser/stashed-diag2.rs | 3 +++ 5 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 tests/parser/stashed-diag2.rs diff --git a/src/formatting.rs b/src/formatting.rs index cd57a025b67..323ae83fe6e 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -109,7 +109,7 @@ fn format_project( let main_file = input.file_name(); let input_is_stdin = main_file == FileName::Stdin; - let parse_session = ParseSess::new(config)?; + let mut parse_session = ParseSess::new(config)?; if config.skip_children() && parse_session.ignore_file(&main_file) { return Ok(FormatReport::new()); } @@ -117,11 +117,21 @@ fn format_project( // Parse the crate. let mut report = FormatReport::new(); let directory_ownership = input.to_directory_ownership(); - let krate = match Parser::parse_crate(input, &parse_session) { - Ok(krate) => krate, - // Surface parse error via Session (errors are merged there from report) - Err(e) => { - let forbid_verbose = input_is_stdin || e != ParserError::ParsePanicError; + + // rustfmt doesn't use `run_compiler` like other tools, so it must emit any + // stashed diagnostics itself, otherwise the `DiagCtxt` will assert when + // dropped. The final result here combines the parsing result and the + // `emit_stashed_diagnostics` result. + let parse_res = Parser::parse_crate(input, &parse_session); + let stashed_res = parse_session.emit_stashed_diagnostics(); + let krate = match (parse_res, stashed_res) { + (Ok(krate), None) => krate, + (parse_res, _) => { + // Surface parse error via Session (errors are merged there from report). + let forbid_verbose = match parse_res { + Err(e) if e != ParserError::ParsePanicError => true, + _ => input_is_stdin, + }; should_emit_verbose(forbid_verbose, config, || { eprintln!("The Rust parser panicked"); }); diff --git a/src/parse/parser.rs b/src/parse/parser.rs index cca14353b5c..3269fe7c7c7 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -162,22 +162,14 @@ impl<'a> Parser<'a> { fn parse_crate_mod(&mut self) -> Result { let mut parser = AssertUnwindSafe(&mut self.parser); - - // rustfmt doesn't use `run_compiler` like other tools, so it must emit - // any stashed diagnostics itself, otherwise the `DiagCtxt` will assert - // when dropped. The final result here combines the parsing result and - // the `emit_stashed_diagnostics` result. - let parse_res = catch_unwind(move || parser.parse_crate_mod()); - let stashed_res = self.parser.dcx().emit_stashed_diagnostics(); let err = Err(ParserError::ParsePanicError); - match (parse_res, stashed_res) { - (Ok(Ok(k)), None) => Ok(k), - (Ok(Ok(_)), Some(_guar)) => err, - (Ok(Err(db)), _) => { + match catch_unwind(move || parser.parse_crate_mod()) { + Ok(Ok(k)) => Ok(k), + Ok(Err(db)) => { db.emit(); err } - (Err(_), _) => err, + Err(_) => err, } } } diff --git a/src/parse/session.rs b/src/parse/session.rs index cff025cf2ab..decd3b167e0 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -6,7 +6,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ - ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel, + ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel, }; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ @@ -230,6 +230,10 @@ impl ParseSess { self.ignore_path_set.as_ref().is_match(path) } + pub(crate) fn emit_stashed_diagnostics(&mut self) -> Option { + self.parse_sess.dcx.emit_stashed_diagnostics() + } + pub(crate) fn set_silent_emitter(&mut self) { self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter()); } diff --git a/src/test/parser.rs b/src/test/parser.rs index da2a2ba62e0..d951c8469e6 100644 --- a/src/test/parser.rs +++ b/src/test/parser.rs @@ -62,3 +62,10 @@ fn crate_parsing_stashed_diag() { let filename = "tests/parser/stashed-diag.rs"; assert_parser_error(filename); } + +#[test] +fn crate_parsing_stashed_diag2() { + // See also https://github.com/rust-lang/rust/issues/121517 + let filename = "tests/parser/stashed-diag2.rs"; + assert_parser_error(filename); +} diff --git a/tests/parser/stashed-diag2.rs b/tests/parser/stashed-diag2.rs new file mode 100644 index 00000000000..579a69def16 --- /dev/null +++ b/tests/parser/stashed-diag2.rs @@ -0,0 +1,3 @@ +trait Trait<'1> { s> {} + +fn main() {} From d84567c0ffab10a14f6b6ff11b8ee7235a5e25ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 22 Feb 2024 18:32:06 +1100 Subject: [PATCH 23/66] Rename `Diagnostic` as `DiagInner`. I started by changing it to `DiagData`, but that didn't feel right. `DiagInner` felt much better. --- src/parse/session.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index decd3b167e0..272cc86f783 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -6,7 +6,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ - ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel, + ColorConfig, DiagCtxt, DiagInner, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel, }; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ @@ -58,7 +58,7 @@ impl Emitter for SilentEmitter { None } - fn emit_diagnostic(&mut self, _db: Diagnostic) {} + fn emit_diagnostic(&mut self, _diag: DiagInner) {} } fn silent_emitter() -> Box { @@ -75,10 +75,10 @@ struct SilentOnIgnoredFilesEmitter { } impl SilentOnIgnoredFilesEmitter { - fn handle_non_ignoreable_error(&mut self, db: Diagnostic) { + fn handle_non_ignoreable_error(&mut self, diag: DiagInner) { self.has_non_ignorable_parser_errors = true; self.can_reset.store(false, Ordering::Release); - self.emitter.emit_diagnostic(db); + self.emitter.emit_diagnostic(diag); } } @@ -97,11 +97,11 @@ impl Emitter for SilentOnIgnoredFilesEmitter { None } - fn emit_diagnostic(&mut self, db: Diagnostic) { - if db.level() == DiagnosticLevel::Fatal { - return self.handle_non_ignoreable_error(db); + fn emit_diagnostic(&mut self, diag: DiagInner) { + if diag.level() == DiagnosticLevel::Fatal { + return self.handle_non_ignoreable_error(diag); } - if let Some(primary_span) = &db.span.primary_span() { + if let Some(primary_span) = &diag.span.primary_span() { let file_name = self.source_map.span_to_filename(*primary_span); if let rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(ref path)) = file_name @@ -117,7 +117,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } }; } - self.handle_non_ignoreable_error(db); + self.handle_non_ignoreable_error(diag); } } @@ -380,13 +380,13 @@ mod tests { None } - fn emit_diagnostic(&mut self, _db: Diagnostic) { + fn emit_diagnostic(&mut self, _diag: DiagInner) { self.num_emitted_errors.fetch_add(1, Ordering::Release); } } - fn build_diagnostic(level: DiagnosticLevel, span: Option) -> Diagnostic { - let mut diag = Diagnostic::new(level, ""); + fn build_diagnostic(level: DiagnosticLevel, span: Option) -> DiagInner { + let mut diag = DiagInner::new(level, ""); diag.messages.clear(); if let Some(span) = span { diag.span = span; From 4026fd735c31f02fa8c2cd326459fb9851e354c9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 23 Feb 2024 10:20:45 +1100 Subject: [PATCH 24/66] Rename `DiagnosticBuilder` as `Diag`. Much better! Note that this involves renaming (and updating the value of) `DIAGNOSTIC_BUILDER` in clippy. --- src/parse/parser.rs | 4 ++-- src/parse/session.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 3269fe7c7c7..19b0dada08f 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; -use rustc_errors::DiagnosticBuilder; +use rustc_errors::Diag; use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; use rustc_span::{sym, Span}; use thin_vec::ThinVec; @@ -65,7 +65,7 @@ impl<'a> ParserBuilder<'a> { fn parser( sess: &'a rustc_session::parse::ParseSess, input: Input, - ) -> Result, Option>>> { + ) -> Result, Option>>> { match input { Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { new_parser_from_file(sess, file, None) diff --git a/src/parse/session.rs b/src/parse/session.rs index 272cc86f783..e33f1ca755c 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -6,7 +6,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ - ColorConfig, DiagCtxt, DiagInner, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel, + ColorConfig, Diag, DiagCtxt, DiagInner, ErrorGuaranteed, Level as DiagnosticLevel, }; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ @@ -300,7 +300,7 @@ impl ParseSess { // Methods that should be restricted within the parse module. impl ParseSess { - pub(super) fn emit_diagnostics(&self, diagnostics: Vec>) { + pub(super) fn emit_diagnostics(&self, diagnostics: Vec>) { for diagnostic in diagnostics { diagnostic.emit(); } From 45aad179050756e040bbfae1d2742d796b74aa95 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 28 Feb 2024 11:00:27 +1100 Subject: [PATCH 25/66] Reinstate `emit_stashed_diagnostics` in `DiagCtxtInner::drop`. I removed it in #121206 because I thought thought it wasn't necessary. But then I had to add an `emit_stashed_diagnostics` call elsewhere in rustfmt to avoid the assertion failure (which took two attempts to get right, #121487 and #121615), and now there's an assertion failure in clippy as well (https://github.com/rust-lang/rust-clippy/issues/12364). So this commit just reinstates the call in `DiagCtxtInner::drop`. It also reverts the rustfmt changes from #121487 and #121615, though it keeps the tests added for those PRs. --- src/formatting.rs | 21 ++++++--------------- src/parse/session.rs | 8 +------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/formatting.rs b/src/formatting.rs index 323ae83fe6e..1c64921b1a6 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -109,7 +109,7 @@ fn format_project( let main_file = input.file_name(); let input_is_stdin = main_file == FileName::Stdin; - let mut parse_session = ParseSess::new(config)?; + let parse_session = ParseSess::new(config)?; if config.skip_children() && parse_session.ignore_file(&main_file) { return Ok(FormatReport::new()); } @@ -118,20 +118,11 @@ fn format_project( let mut report = FormatReport::new(); let directory_ownership = input.to_directory_ownership(); - // rustfmt doesn't use `run_compiler` like other tools, so it must emit any - // stashed diagnostics itself, otherwise the `DiagCtxt` will assert when - // dropped. The final result here combines the parsing result and the - // `emit_stashed_diagnostics` result. - let parse_res = Parser::parse_crate(input, &parse_session); - let stashed_res = parse_session.emit_stashed_diagnostics(); - let krate = match (parse_res, stashed_res) { - (Ok(krate), None) => krate, - (parse_res, _) => { - // Surface parse error via Session (errors are merged there from report). - let forbid_verbose = match parse_res { - Err(e) if e != ParserError::ParsePanicError => true, - _ => input_is_stdin, - }; + let krate = match Parser::parse_crate(input, &parse_session) { + Ok(krate) => krate, + // Surface parse error via Session (errors are merged there from report) + Err(e) => { + let forbid_verbose = input_is_stdin || e != ParserError::ParsePanicError; should_emit_verbose(forbid_verbose, config, || { eprintln!("The Rust parser panicked"); }); diff --git a/src/parse/session.rs b/src/parse/session.rs index e33f1ca755c..f5defe63c13 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -5,9 +5,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; -use rustc_errors::{ - ColorConfig, Diag, DiagCtxt, DiagInner, ErrorGuaranteed, Level as DiagnosticLevel, -}; +use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{ source_map::{FilePathMapping, SourceMap}, @@ -230,10 +228,6 @@ impl ParseSess { self.ignore_path_set.as_ref().is_match(path) } - pub(crate) fn emit_stashed_diagnostics(&mut self) -> Option { - self.parse_sess.dcx.emit_stashed_diagnostics() - } - pub(crate) fn set_silent_emitter(&mut self) { self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter()); } From 0811e8f8777391375d2410a716d0659c44fb7a10 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 11:50:32 +1100 Subject: [PATCH 26/66] Rename `DiagCtxt::with_emitter` as `DiagCtxt::new`. Because it's now the only constructor. --- 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 e33f1ca755c..ad36e022b8d 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -154,7 +154,7 @@ fn default_dcx( ); Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) }; - DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter { + DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, source_map, emitter, @@ -235,7 +235,7 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter()); + self.parse_sess.dcx = DiagCtxt::new(silent_emitter()); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { From 9c85ae873cb959965d2ccfa3fb49fd121cfe12b8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 15:37:38 +1100 Subject: [PATCH 27/66] Inline and remove `HumanEmitter::stderr`. Because `HumanEmitter::new` is enough, in conjunction with the (renamed) `stderr_destination` function. --- src/parse/session.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index ad36e022b8d..7e6517a66dd 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -3,7 +3,7 @@ use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; -use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; +use rustc_errors::emitter::{stderr_destination, DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ ColorConfig, Diag, DiagCtxt, DiagInner, ErrorGuaranteed, Level as DiagnosticLevel, @@ -152,7 +152,10 @@ fn default_dcx( rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false, ); - Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) + Box::new( + HumanEmitter::new(stderr_destination(emit_color), fallback_bundle) + .sm(Some(source_map.clone())), + ) }; DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, From fc64cbdbe7dd07b021f9a2989c29cfb9ddab419a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 19 Feb 2024 14:25:33 +0100 Subject: [PATCH 28/66] AST: Refactor type alias where clauses --- src/items.rs | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/items.rs b/src/items.rs index b57be8c1054..f6f51fbd8ea 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1651,8 +1651,7 @@ struct TyAliasRewriteInfo<'c, 'g>( &'c RewriteContext<'c>, Indent, &'g ast::Generics, - (ast::TyAliasWhereClause, ast::TyAliasWhereClause), - usize, + ast::TyAliasWhereClauses, symbol::Ident, Span, ); @@ -1672,7 +1671,6 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( ref bounds, ref ty, where_clauses, - where_predicates_split, } = *ty_alias_kind; let ty_opt = ty.as_ref(); let (ident, vis) = match visitor_kind { @@ -1680,15 +1678,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), ForeignItem(i) => (i.ident, &i.vis), }; - let rw_info = &TyAliasRewriteInfo( - context, - indent, - generics, - where_clauses, - where_predicates_split, - ident, - span, - ); + let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, 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. @@ -1724,19 +1714,11 @@ fn rewrite_ty( vis: &ast::Visibility, ) -> Option { let mut result = String::with_capacity(128); - let TyAliasRewriteInfo( - context, - indent, - generics, - where_clauses, - where_predicates_split, - ident, - span, - ) = *rw_info; + 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_predicates_split); + .split_at(where_clauses.split); if !after_where_predicates.is_empty() { return None; } @@ -1771,7 +1753,7 @@ fn rewrite_ty( let where_clause_str = rewrite_where_clause( context, before_where_predicates, - where_clauses.0.1, + where_clauses.before.span, context.config.brace_style(), Shape::legacy(where_budget, indent), false, @@ -1795,7 +1777,7 @@ fn rewrite_ty( let comment_span = context .snippet_provider .opt_span_before(span, "=") - .map(|op_lo| mk_sp(where_clauses.0.1.hi(), op_lo)); + .map(|op_lo| mk_sp(where_clauses.before.span.hi(), op_lo)); let lhs = match comment_span { Some(comment_span) From 0b56261cef11fbc5ef97b0ccc9e322c06ce095e6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 20 Dec 2023 15:05:30 +1100 Subject: [PATCH 29/66] Tweak `parse_asm_args`. It doesn't need a `Parser` and a `ParseSess`, because the former contains the latter. --- src/parse/macros/asm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse/macros/asm.rs b/src/parse/macros/asm.rs index 01edfab3654..6373d0251f8 100644 --- a/src/parse/macros/asm.rs +++ b/src/parse/macros/asm.rs @@ -7,5 +7,5 @@ use crate::rewrite::RewriteContext; 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, context.parse_sess.inner(), mac.span(), false).ok() + parse_asm_args(&mut parser, mac.span(), false).ok() } From 78c99ebfeac04a0d4ab188a2cabddc5c775e6af2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Mar 2024 16:31:49 +1100 Subject: [PATCH 30/66] Rename all `ParseSess` variables/fields/lifetimes as `psess`. Existing names for values of this type are `sess`, `parse_sess`, `parse_session`, and `ps`. `sess` is particularly annoying because that's also used for `Session` values, which are often co-located, and it can be difficult to know which type a value named `sess` refers to. (That annoyance is the main motivation for this change.) `psess` is nice and short, which is good for a name used this much. The commit also renames some `parse_sess_created` values as `psess_created`. --- src/comment.rs | 4 +-- src/formatting.rs | 53 ++++++++++++++------------------- src/macros.rs | 4 +-- src/missed_spans.rs | 6 ++-- src/modules.rs | 30 +++++++++---------- src/modules/visitor.rs | 8 ++--- src/parse/macros/cfg_if.rs | 10 +++---- src/parse/macros/lazy_static.rs | 6 ++-- src/parse/macros/mod.rs | 12 ++++---- src/parse/parser.rs | 46 ++++++++++++++-------------- src/parse/session.rs | 40 ++++++++++++------------- src/reorder.rs | 4 +-- src/rewrite.rs | 2 +- src/source_file.rs | 4 +-- src/utils.rs | 2 +- src/visitor.rs | 36 ++++++++++------------ 16 files changed, 126 insertions(+), 141 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index f7cd7cefb3d..7d1b0384431 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -1721,10 +1721,10 @@ pub(crate) fn recover_comment_removed( // We missed some comments. Warn and keep the original text. if context.config.error_on_unformatted() { context.report.append( - context.parse_sess.span_to_filename(span), + context.psess.span_to_filename(span), vec![FormattingError::from_span( span, - context.parse_sess, + context.psess, ErrorKind::LostComment, )], ); diff --git a/src/formatting.rs b/src/formatting.rs index 1c64921b1a6..3bcb4d15184 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -79,7 +79,7 @@ fn should_skip_module( // FIXME(calebcartwright) - we need to determine how we'll handle the // `format_generated_files` option with stdin based input. if !input_is_stdin && !config.format_generated_files() { - let source_file = context.parse_session.span_to_file_contents(module.span); + let source_file = context.psess.span_to_file_contents(module.span); let src = source_file.src.as_ref().expect("SourceFile without src"); if is_generated_file(src) { @@ -109,8 +109,8 @@ fn format_project( let main_file = input.file_name(); let input_is_stdin = main_file == FileName::Stdin; - let parse_session = ParseSess::new(config)?; - if config.skip_children() && parse_session.ignore_file(&main_file) { + let psess = ParseSess::new(config)?; + if config.skip_children() && psess.ignore_file(&main_file) { return Ok(FormatReport::new()); } @@ -118,7 +118,7 @@ fn format_project( let mut report = FormatReport::new(); let directory_ownership = input.to_directory_ownership(); - let krate = match Parser::parse_crate(input, &parse_session) { + let krate = match Parser::parse_crate(input, &psess) { Ok(krate) => krate, // Surface parse error via Session (errors are merged there from report) Err(e) => { @@ -131,9 +131,9 @@ fn format_project( } }; - let mut context = FormatContext::new(&krate, report, parse_session, config, handler); + let mut context = FormatContext::new(&krate, report, psess, config, handler); let files = modules::ModResolver::new( - &context.parse_session, + &context.psess, directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaBlock), !input_is_stdin && !config.skip_children(), ) @@ -148,16 +148,11 @@ fn format_project( timer = timer.done_parsing(); // Suppress error output if we have to do any further parsing. - context.parse_session.set_silent_emitter(); + context.psess.set_silent_emitter(); for (path, module) in files { if input_is_stdin && contains_skip(module.attrs()) { - return echo_back_stdin( - context - .parse_session - .snippet_provider(module.span) - .entire_snippet(), - ); + return echo_back_stdin(context.psess.snippet_provider(module.span).entire_snippet()); } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); context.format_file(path, &module, is_macro_def)?; @@ -179,7 +174,7 @@ fn format_project( struct FormatContext<'a, T: FormatHandler> { krate: &'a ast::Crate, report: FormatReport, - parse_session: ParseSess, + psess: ParseSess, config: &'a Config, handler: &'a mut T, } @@ -188,21 +183,21 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { fn new( krate: &'a ast::Crate, report: FormatReport, - parse_session: ParseSess, + psess: ParseSess, config: &'a Config, handler: &'a mut T, ) -> Self { FormatContext { krate, report, - parse_session, + psess, config, handler, } } fn ignore_file(&self, path: &FileName) -> bool { - self.parse_session.ignore_file(path) + self.psess.ignore_file(path) } // Formats a single file/module. @@ -212,9 +207,9 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { module: &Module<'_>, is_macro_def: bool, ) -> Result<(), ErrorKind> { - let snippet_provider = self.parse_session.snippet_provider(module.span); - let mut visitor = FmtVisitor::from_parse_sess( - &self.parse_session, + let snippet_provider = self.psess.snippet_provider(module.span); + let mut visitor = FmtVisitor::from_psess( + &self.psess, self.config, &snippet_provider, self.report.clone(), @@ -257,7 +252,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { .add_non_formatted_ranges(visitor.skipped_range.borrow().clone()); self.handler.handle_formatted_file( - &self.parse_session, + &self.psess, path, visitor.buffer.to_owned(), &mut self.report, @@ -269,7 +264,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { trait FormatHandler { fn handle_formatted_file( &mut self, - parse_session: &ParseSess, + psess: &ParseSess, path: FileName, result: String, report: &mut FormatReport, @@ -280,14 +275,14 @@ impl<'b, T: Write + 'b> FormatHandler for Session<'b, T> { // Called for each formatted file. fn handle_formatted_file( &mut self, - parse_session: &ParseSess, + psess: &ParseSess, path: FileName, result: String, report: &mut FormatReport, ) -> Result<(), ErrorKind> { if let Some(ref mut out) = self.out { match source_file::write_file( - Some(parse_session), + Some(psess), &path, &result, out, @@ -318,17 +313,13 @@ pub(crate) struct FormattingError { } impl FormattingError { - pub(crate) fn from_span( - span: Span, - parse_sess: &ParseSess, - kind: ErrorKind, - ) -> FormattingError { + pub(crate) fn from_span(span: Span, psess: &ParseSess, kind: ErrorKind) -> FormattingError { FormattingError { - line: parse_sess.line_of_byte_pos(span.lo()), + line: psess.line_of_byte_pos(span.lo()), is_comment: kind.is_comment(), kind, is_string: false, - line_buffer: parse_sess.span_to_first_line_string(span), + line_buffer: psess.span_to_first_line_string(span), } } diff --git a/src/macros.rs b/src/macros.rs index b4c58d2fefb..8d77d2b3254 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -136,8 +136,8 @@ fn return_macro_parse_failure_fallback( } context.skipped_range.borrow_mut().push(( - context.parse_sess.line_of_byte_pos(span.lo()), - context.parse_sess.line_of_byte_pos(span.hi()), + context.psess.line_of_byte_pos(span.lo()), + context.psess.line_of_byte_pos(span.hi()), )); // Return the snippet unmodified if the macro is not block-like diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 28edcb784b4..b1a7769c21b 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -91,7 +91,7 @@ impl<'a> FmtVisitor<'a> { assert!( start < end, "Request to format inverted span: {}", - self.parse_sess.span_to_debug_info(mk_sp(start, end)), + self.psess.span_to_debug_info(mk_sp(start, end)), ); self.last_pos = end; @@ -166,8 +166,8 @@ impl<'a> FmtVisitor<'a> { // Trim whitespace from the right hand side of each line. // Annoyingly, the library functions for splitting by lines etc. are not // quite right, so we must do it ourselves. - let line = self.parse_sess.line_of_byte_pos(span.lo()); - let file_name = &self.parse_sess.span_to_filename(span); + let line = self.psess.line_of_byte_pos(span.lo()); + let file_name = &self.psess.span_to_filename(span); let mut status = SnippetStatus::new(line); let snippet = &*transform_missing_snippet(self.config, old_snippet); diff --git a/src/modules.rs b/src/modules.rs index af9a154a6ae..0590f28ee05 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -57,8 +57,8 @@ impl<'a> Module<'a> { } /// Maps each module to the corresponding file. -pub(crate) struct ModResolver<'ast, 'sess> { - parse_sess: &'sess ParseSess, +pub(crate) struct ModResolver<'ast, 'psess> { + psess: &'psess ParseSess, directory: Directory, file_map: FileModMap<'ast>, recursive: bool, @@ -99,10 +99,10 @@ enum SubModKind<'a, 'ast> { Internal(&'a ast::Item), } -impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { +impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { /// Creates a new `ModResolver`. pub(crate) fn new( - parse_sess: &'sess ParseSess, + psess: &'psess ParseSess, directory_ownership: DirectoryOwnership, recursive: bool, ) -> Self { @@ -112,7 +112,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { ownership: directory_ownership, }, file_map: BTreeMap::new(), - parse_sess, + psess, recursive, } } @@ -122,7 +122,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { mut self, krate: &'ast ast::Crate, ) -> Result, ModuleResolutionError> { - let root_filename = self.parse_sess.span_to_filename(krate.spans.inner_span); + let root_filename = self.psess.span_to_filename(krate.spans.inner_span); self.directory.path = match root_filename { FileName::Real(ref p) => p.parent().unwrap_or(Path::new("")).to_path_buf(), _ => PathBuf::new(), @@ -133,7 +133,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { self.visit_mod_from_ast(&krate.items)?; } - let snippet_provider = self.parse_sess.snippet_provider(krate.spans.inner_span); + let snippet_provider = self.psess.snippet_provider(krate.spans.inner_span); self.file_map.insert( root_filename, @@ -149,7 +149,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { /// Visit `cfg_if` macro and look for module declarations. fn visit_cfg_if(&mut self, item: Cow<'ast, ast::Item>) -> Result<(), ModuleResolutionError> { - let mut visitor = visitor::CfgIfVisitor::new(self.parse_sess); + let mut visitor = visitor::CfgIfVisitor::new(self.psess); visitor.visit_item(&item); for module_item in visitor.mods() { if let ast::ItemKind::Mod(_, ref sub_mod_kind) = module_item.item.kind { @@ -338,10 +338,10 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { DirectoryOwnership::UnownedViaBlock => None, }; if let Some(path) = Parser::submod_path_from_attr(attrs, &self.directory.path) { - if self.parse_sess.is_file_parsed(&path) { + if self.psess.is_file_parsed(&path) { return Ok(None); } - return match Parser::parse_file_as_module(self.parse_sess, &path, sub_mod.span) { + return match Parser::parse_file_as_module(self.psess, &path, sub_mod.span) { Ok((ref attrs, _, _)) if contains_skip(attrs) => Ok(None), Ok((attrs, items, span)) => Ok(Some(SubModKind::External( path, @@ -368,7 +368,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { let mut mods_outside_ast = self.find_mods_outside_of_ast(attrs, sub_mod); match self - .parse_sess + .psess .default_submod_path(mod_name, relative, &self.directory.path) { Ok(ModulePathSuccess { @@ -380,7 +380,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { let should_insert = !mods_outside_ast .iter() .any(|(outside_path, _, _)| outside_path == &file_path); - if self.parse_sess.is_file_parsed(&file_path) { + if self.psess.is_file_parsed(&file_path) { if outside_mods_empty { return Ok(None); } else { @@ -390,7 +390,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { return Ok(Some(SubModKind::MultiExternal(mods_outside_ast))); } } - match Parser::parse_file_as_module(self.parse_sess, &file_path, sub_mod.span) { + match Parser::parse_file_as_module(self.psess, &file_path, sub_mod.span) { Ok((ref attrs, _, _)) if contains_skip(attrs) => Ok(None), Ok((attrs, items, span)) if outside_mods_empty => { Ok(Some(SubModKind::External( @@ -517,7 +517,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { if !actual_path.exists() { continue; } - if self.parse_sess.is_file_parsed(&actual_path) { + if self.psess.is_file_parsed(&actual_path) { // If the specified file is already parsed, then we just use that. result.push(( actual_path, @@ -527,7 +527,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { continue; } let (attrs, items, span) = - match Parser::parse_file_as_module(self.parse_sess, &actual_path, sub_mod.span) { + match Parser::parse_file_as_module(self.psess, &actual_path, sub_mod.span) { Ok((ref attrs, _, _)) if contains_skip(attrs) => continue, Ok(m) => m, Err(..) => continue, diff --git a/src/modules/visitor.rs b/src/modules/visitor.rs index 48431693332..3e05b6d0c5d 100644 --- a/src/modules/visitor.rs +++ b/src/modules/visitor.rs @@ -12,15 +12,15 @@ pub(crate) struct ModItem { /// Traverse `cfg_if!` macro and fetch modules. pub(crate) struct CfgIfVisitor<'a> { - parse_sess: &'a ParseSess, + psess: &'a ParseSess, mods: Vec, } impl<'a> CfgIfVisitor<'a> { - pub(crate) fn new(parse_sess: &'a ParseSess) -> CfgIfVisitor<'a> { + pub(crate) fn new(psess: &'a ParseSess) -> CfgIfVisitor<'a> { CfgIfVisitor { mods: vec![], - parse_sess, + psess, } } @@ -62,7 +62,7 @@ impl<'a, 'ast: 'a> CfgIfVisitor<'a> { } }; - let items = parse_cfg_if(self.parse_sess, mac)?; + let items = parse_cfg_if(self.psess, mac)?; self.mods .append(&mut items.into_iter().map(|item| ModItem { item }).collect()); diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index bafef7b0f46..5fc988e4319 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -9,10 +9,10 @@ use crate::parse::macros::build_stream_parser; use crate::parse::session::ParseSess; pub(crate) fn parse_cfg_if<'a>( - sess: &'a ParseSess, + psess: &'a ParseSess, mac: &'a ast::MacCall, ) -> Result, &'static str> { - match catch_unwind(AssertUnwindSafe(|| parse_cfg_if_inner(sess, mac))) { + match catch_unwind(AssertUnwindSafe(|| parse_cfg_if_inner(psess, mac))) { Ok(Ok(items)) => Ok(items), Ok(err @ Err(_)) => err, Err(..) => Err("failed to parse cfg_if!"), @@ -20,11 +20,11 @@ pub(crate) fn parse_cfg_if<'a>( } fn parse_cfg_if_inner<'a>( - sess: &'a ParseSess, + psess: &'a ParseSess, mac: &'a ast::MacCall, ) -> Result, &'static str> { let ts = mac.args.tokens.clone(); - let mut parser = build_stream_parser(sess.inner(), ts); + let mut parser = build_stream_parser(psess.inner(), ts); let mut items = vec![]; let mut process_if_cfg = true; @@ -67,7 +67,7 @@ fn parse_cfg_if_inner<'a>( Ok(None) => continue, Err(err) => { err.cancel(); - parser.sess.dcx.reset_err_count(); + parser.psess.dcx.reset_err_count(); return Err( "Expected item inside cfg_if block, but failed to parse it as an item", ); diff --git a/src/parse/macros/lazy_static.rs b/src/parse/macros/lazy_static.rs index 8b1dc6694d6..badd9569950 100644 --- a/src/parse/macros/lazy_static.rs +++ b/src/parse/macros/lazy_static.rs @@ -16,8 +16,8 @@ pub(crate) fn parse_lazy_static( ($method:ident $(,)* $($arg:expr),* $(,)*) => { match parser.$method($($arg,)*) { Ok(val) => { - if parser.sess.dcx.has_errors().is_some() { - parser.sess.dcx.reset_err_count(); + if parser.psess.dcx.has_errors().is_some() { + parser.psess.dcx.reset_err_count(); return None; } else { val @@ -25,7 +25,7 @@ pub(crate) fn parse_lazy_static( } Err(err) => { err.cancel(); - parser.sess.dcx.reset_err_count(); + parser.psess.dcx.reset_err_count(); return None; } } diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index a9f9ea1826a..3cf133c647c 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -14,12 +14,12 @@ pub(crate) mod asm; pub(crate) mod cfg_if; pub(crate) mod lazy_static; -fn build_stream_parser<'a>(sess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> { - stream_to_parser(sess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden) +fn build_stream_parser<'a>(psess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> { + stream_to_parser(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden) } fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { - build_stream_parser(context.parse_sess.inner(), tokens) + build_stream_parser(context.psess.inner(), tokens) } fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { @@ -29,8 +29,8 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { if Parser::nonterminal_may_begin_with($nt_kind, &cloned_parser.token) { match $try_parse(&mut cloned_parser) { Ok(x) => { - if parser.sess.dcx.has_errors().is_some() { - parser.sess.dcx.reset_err_count(); + if parser.psess.dcx.has_errors().is_some() { + parser.psess.dcx.reset_err_count(); } else { // Parsing succeeded. *parser = cloned_parser; @@ -39,7 +39,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { } Err(e) => { e.cancel(); - parser.sess.dcx.reset_err_count(); + parser.psess.dcx.reset_err_count(); } } } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 19b0dada08f..5dcdca1d953 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -29,7 +29,7 @@ pub(crate) struct Parser<'a> { /// A builder for the `Parser`. #[derive(Default)] pub(crate) struct ParserBuilder<'a> { - sess: Option<&'a ParseSess>, + psess: Option<&'a ParseSess>, input: Option, } @@ -39,20 +39,20 @@ impl<'a> ParserBuilder<'a> { self } - pub(crate) fn sess(mut self, sess: &'a ParseSess) -> ParserBuilder<'a> { - self.sess = Some(sess); + pub(crate) fn psess(mut self, psess: &'a ParseSess) -> ParserBuilder<'a> { + self.psess = Some(psess); self } pub(crate) fn build(self) -> Result, ParserError> { - let sess = self.sess.ok_or(ParserError::NoParseSess)?; + let psess = self.psess.ok_or(ParserError::NoParseSess)?; let input = self.input.ok_or(ParserError::NoInput)?; - let parser = match Self::parser(sess.inner(), input) { + let parser = match Self::parser(psess.inner(), input) { Ok(p) => p, Err(db) => { if let Some(diagnostics) = db { - sess.emit_diagnostics(diagnostics); + psess.emit_diagnostics(diagnostics); return Err(ParserError::ParserCreationError); } return Err(ParserError::ParsePanicError); @@ -63,16 +63,16 @@ impl<'a> ParserBuilder<'a> { } fn parser( - sess: &'a rustc_session::parse::ParseSess, + psess: &'a rustc_session::parse::ParseSess, input: Input, ) -> Result, Option>>> { match input { Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { - new_parser_from_file(sess, file, None) + new_parser_from_file(psess, file, None) })) .map_err(|_| None), Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str( - sess, + psess, rustc_span::FileName::Custom("stdin".to_owned()), text, ) @@ -106,27 +106,27 @@ impl<'a> Parser<'a> { } pub(crate) fn parse_file_as_module( - sess: &'a ParseSess, + psess: &'a ParseSess, path: &Path, span: Span, ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); + let mut parser = new_parser_from_file(psess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { e.emit(); - if sess.can_reset_errors() { - sess.reset_errors(); + if psess.can_reset_errors() { + psess.reset_errors(); } None } } })); match result { - Ok(Some(m)) if !sess.has_errors() => Ok(m), - Ok(Some(m)) if sess.can_reset_errors() => { - sess.reset_errors(); + Ok(Some(m)) if !psess.has_errors() => Ok(m), + Ok(Some(m)) if psess.can_reset_errors() => { + psess.reset_errors(); Ok(m) } Ok(_) => Err(ParserError::ParseError), @@ -137,25 +137,25 @@ impl<'a> Parser<'a> { pub(crate) fn parse_crate( input: Input, - sess: &'a ParseSess, + psess: &'a ParseSess, ) -> Result { - let krate = Parser::parse_crate_inner(input, sess)?; - if !sess.has_errors() { + let krate = Parser::parse_crate_inner(input, psess)?; + if !psess.has_errors() { return Ok(krate); } - if sess.can_reset_errors() { - sess.reset_errors(); + if psess.can_reset_errors() { + psess.reset_errors(); return Ok(krate); } Err(ParserError::ParseError) } - fn parse_crate_inner(input: Input, sess: &'a ParseSess) -> Result { + fn parse_crate_inner(input: Input, psess: &'a ParseSess) -> Result { ParserBuilder::default() .input(input) - .sess(sess) + .psess(psess) .build()? .parse_crate_mod() } diff --git a/src/parse/session.rs b/src/parse/session.rs index d6386a9504d..356410f5596 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -23,7 +23,7 @@ use crate::{Config, ErrorKind, FileName}; /// ParseSess holds structs necessary for constructing a parser. pub(crate) struct ParseSess { - parse_sess: RawParseSess, + raw_psess: RawParseSess, ignore_path_set: Lrc, can_reset_errors: Lrc, } @@ -180,10 +180,10 @@ impl ParseSess { config.hide_parse_errors(), config.color(), ); - let parse_sess = RawParseSess::with_dcx(dcx, source_map); + let raw_psess = RawParseSess::with_dcx(dcx, source_map); Ok(ParseSess { - parse_sess, + raw_psess, ignore_path_set, can_reset_errors, }) @@ -202,14 +202,14 @@ impl ParseSess { relative: Option, dir_path: &Path, ) -> Result> { - rustc_expand::module::default_submod_path(&self.parse_sess, id, relative, dir_path).or_else( + rustc_expand::module::default_submod_path(&self.raw_psess, id, relative, dir_path).or_else( |e| { // If resloving a module relative to {dir_path}/{symbol} fails because a file // could not be found, then try to resolve the module relative to {dir_path}. // If we still can't find the module after searching for it in {dir_path}, // surface the original error. if matches!(e, ModError::FileNotFound(..)) && relative.is_some() { - rustc_expand::module::default_submod_path(&self.parse_sess, id, None, dir_path) + rustc_expand::module::default_submod_path(&self.raw_psess, id, None, dir_path) .map_err(|_| e) } else { Err(e) @@ -219,7 +219,7 @@ impl ParseSess { } pub(crate) fn is_file_parsed(&self, path: &Path) -> bool { - self.parse_sess + self.raw_psess .source_map() .get_source_file(&rustc_span::FileName::Real( rustc_span::RealFileName::LocalPath(path.to_path_buf()), @@ -232,21 +232,21 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.parse_sess.dcx = DiagCtxt::new(silent_emitter()); + self.raw_psess.dcx = DiagCtxt::new(silent_emitter()); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { - self.parse_sess.source_map().span_to_filename(span).into() + self.raw_psess.source_map().span_to_filename(span).into() } pub(crate) fn span_to_file_contents(&self, span: Span) -> Lrc { - self.parse_sess + self.raw_psess .source_map() .lookup_source_file(span.data().lo) } pub(crate) fn span_to_first_line_string(&self, span: Span) -> String { - let file_lines = self.parse_sess.source_map().span_to_lines(span).ok(); + let file_lines = self.raw_psess.source_map().span_to_lines(span).ok(); match file_lines { Some(fl) => fl @@ -258,7 +258,7 @@ impl ParseSess { } pub(crate) fn line_of_byte_pos(&self, pos: BytePos) -> usize { - self.parse_sess.source_map().lookup_char_pos(pos).line + self.raw_psess.source_map().lookup_char_pos(pos).line } // TODO(calebcartwright): Preemptive, currently unused addition @@ -271,15 +271,15 @@ impl ParseSess { } pub(crate) fn span_to_debug_info(&self, span: Span) -> String { - self.parse_sess.source_map().span_to_diagnostic_string(span) + self.raw_psess.source_map().span_to_diagnostic_string(span) } pub(crate) fn inner(&self) -> &RawParseSess { - &self.parse_sess + &self.raw_psess } pub(crate) fn snippet_provider(&self, span: Span) -> SnippetProvider { - let source_file = self.parse_sess.source_map().lookup_char_pos(span.lo()).file; + let source_file = self.raw_psess.source_map().lookup_char_pos(span.lo()).file; SnippetProvider::new( source_file.start_pos, source_file.end_position(), @@ -288,7 +288,7 @@ impl ParseSess { } pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option> { - self.parse_sess + self.raw_psess .source_map() .get_source_file(&file_name.into()) .and_then(|source_file| source_file.src.clone()) @@ -308,23 +308,23 @@ impl ParseSess { } pub(super) fn has_errors(&self) -> bool { - self.parse_sess.dcx.has_errors().is_some() + self.raw_psess.dcx.has_errors().is_some() } pub(super) fn reset_errors(&self) { - self.parse_sess.dcx.reset_err_count(); + self.raw_psess.dcx.reset_err_count(); } } impl LineRangeUtils for ParseSess { fn lookup_line_range(&self, span: Span) -> LineRange { let snippet = self - .parse_sess + .raw_psess .source_map() .span_to_snippet(span) .unwrap_or_default(); - let lo = self.parse_sess.source_map().lookup_line(span.lo()).unwrap(); - let hi = self.parse_sess.source_map().lookup_line(span.hi()).unwrap(); + let lo = self.raw_psess.source_map().lookup_line(span.lo()).unwrap(); + let hi = self.raw_psess.source_map().lookup_line(span.hi()).unwrap(); debug_assert_eq!( lo.sf.name, hi.sf.name, diff --git a/src/reorder.rs b/src/reorder.rs index 3e14f9f1272..fdbed939af5 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -263,13 +263,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { item_kind: ReorderableItemKind, in_group: bool, ) -> usize { - let mut last = self.parse_sess.lookup_line_range(items[0].span()); + let mut last = self.psess.lookup_line_range(items[0].span()); let item_length = items .iter() .take_while(|ppi| { item_kind.is_same_item_kind(&***ppi) && (!in_group || { - let current = self.parse_sess.lookup_line_range(ppi.span()); + let current = self.psess.lookup_line_range(ppi.span()); let in_same_group = current.lo < last.hi + 2; last = current; in_same_group diff --git a/src/rewrite.rs b/src/rewrite.rs index 4a3bd129d16..e2498a3500a 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -26,7 +26,7 @@ impl Rewrite for ptr::P { #[derive(Clone)] pub(crate) struct RewriteContext<'a> { - pub(crate) parse_sess: &'a ParseSess, + pub(crate) psess: &'a ParseSess, pub(crate) config: &'a Config, pub(crate) inside_macro: Rc>, // Force block indent style even if we are using visual indent style. diff --git a/src/source_file.rs b/src/source_file.rs index 512a8593c27..6376bc49b69 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -49,7 +49,7 @@ where } pub(crate) fn write_file( - parse_sess: Option<&ParseSess>, + psess: Option<&ParseSess>, filename: &FileName, formatted_text: &str, out: &mut T, @@ -90,7 +90,7 @@ where let original_text = if newline_style != NewlineStyle::Auto && *filename != FileName::Stdin { Lrc::new(fs::read_to_string(ensure_real_path(filename))?) } else { - match parse_sess.and_then(|sess| sess.get_original_snippet(filename)) { + match psess.and_then(|psess| psess.get_original_snippet(filename)) { Some(ori) => ori, None => Lrc::new(fs::read_to_string(ensure_real_path(filename))?), } diff --git a/src/utils.rs b/src/utils.rs index d4218cff75a..b91d9b47cb6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -362,7 +362,7 @@ macro_rules! out_of_file_lines_range { && !$self .config .file_lines() - .intersects(&$self.parse_sess.lookup_line_range($span)) + .intersects(&$self.psess.lookup_line_range($span)) }; } diff --git a/src/visitor.rs b/src/visitor.rs index bc5accefd92..47f772b485d 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -71,7 +71,7 @@ impl SnippetProvider { pub(crate) struct FmtVisitor<'a> { parent_context: Option<&'a RewriteContext<'a>>, - pub(crate) parse_sess: &'a ParseSess, + pub(crate) psess: &'a ParseSess, pub(crate) buffer: String, pub(crate) last_pos: BytePos, // FIXME: use an RAII util or closure for indenting @@ -113,10 +113,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } fn visit_stmt(&mut self, stmt: &Stmt<'_>, include_empty_semi: bool) { - debug!( - "visit_stmt: {}", - self.parse_sess.span_to_debug_info(stmt.span()) - ); + debug!("visit_stmt: {}", self.psess.span_to_debug_info(stmt.span())); if stmt.is_empty() { // If the statement is empty, just skip over it. Before that, make sure any comment @@ -217,10 +214,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { inner_attrs: Option<&[ast::Attribute]>, has_braces: bool, ) { - debug!( - "visit_block: {}", - self.parse_sess.span_to_debug_info(b.span), - ); + debug!("visit_block: {}", self.psess.span_to_debug_info(b.span)); // Check if this block has braces. let brace_compensation = BytePos(if has_braces { 1 } else { 0 }); @@ -744,10 +738,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // do not take into account the lines with attributes as part of the skipped range let attrs_end = attrs .iter() - .map(|attr| self.parse_sess.line_of_byte_pos(attr.span.hi())) + .map(|attr| self.psess.line_of_byte_pos(attr.span.hi())) .max() .unwrap_or(1); - let first_line = self.parse_sess.line_of_byte_pos(main_span.lo()); + let first_line = self.psess.line_of_byte_pos(main_span.lo()); // Statement can start after some newlines and/or spaces // or it can be on the same line as the last attribute. // So here we need to take a minimum between the two. @@ -758,8 +752,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } pub(crate) fn from_context(ctx: &'a RewriteContext<'_>) -> FmtVisitor<'a> { - let mut visitor = FmtVisitor::from_parse_sess( - ctx.parse_sess, + let mut visitor = FmtVisitor::from_psess( + ctx.psess, ctx.config, ctx.snippet_provider, ctx.report.clone(), @@ -769,8 +763,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { visitor } - pub(crate) fn from_parse_sess( - parse_session: &'a ParseSess, + pub(crate) fn from_psess( + psess: &'a ParseSess, config: &'a Config, snippet_provider: &'a SnippetProvider, report: FormatReport, @@ -786,7 +780,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { skip_context.macros.extend(macro_names); FmtVisitor { parent_context: None, - parse_sess: parse_session, + psess, buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2), last_pos: BytePos(0), block_indent: Indent::empty(), @@ -814,12 +808,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { pub(crate) fn visit_attrs(&mut self, attrs: &[ast::Attribute], style: ast::AttrStyle) -> bool { for attr in attrs { if attr.has_name(depr_skip_annotation()) { - let file_name = self.parse_sess.span_to_filename(attr.span); + let file_name = self.psess.span_to_filename(attr.span); self.report.append( file_name, vec![FormattingError::from_span( attr.span, - self.parse_sess, + self.psess, ErrorKind::DeprecatedAttr, )], ); @@ -828,12 +822,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::AttrKind::Normal(ref normal) if self.is_unknown_rustfmt_attr(&normal.item.path.segments) => { - let file_name = self.parse_sess.span_to_filename(attr.span); + let file_name = self.psess.span_to_filename(attr.span); self.report.append( file_name, vec![FormattingError::from_span( attr.span, - self.parse_sess, + self.psess, ErrorKind::BadAttr, )], ); @@ -1007,7 +1001,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { pub(crate) fn get_context(&self) -> RewriteContext<'_> { RewriteContext { - parse_sess: self.parse_sess, + psess: self.psess, config: self.config, inside_macro: Rc::new(Cell::new(false)), use_block: Cell::new(false), From fe9ceab35631f03cb3af853986288ab0dc9f41e7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 11:58:51 +1100 Subject: [PATCH 31/66] Rename `DiagnosticMessage` as `DiagMessage`. --- src/parse/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 356410f5596..11af9860513 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -44,7 +44,7 @@ impl Translate for SilentEmitter { // subdiagnostics result in a call to this. fn translate_message<'a>( &'a self, - message: &'a rustc_errors::DiagnosticMessage, + message: &'a rustc_errors::DiagMessage, _: &'a rustc_errors::translation::FluentArgs<'_>, ) -> Result, rustc_errors::error::TranslateError<'_>> { rustc_errors::emitter::silent_translate(message) From 124808b5828cd9ee0a17a46c706c3cd55705336c Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 19 Feb 2024 15:07:08 +0000 Subject: [PATCH 32/66] errors: share `SilentEmitter` between rustc and rustfmt Signed-off-by: David Wood --- src/parse/session.rs | 73 +++++++++++++------------------------- tests/rustfmt/main.rs | 2 +- tests/target/issue_6082.rs | 5 +++ 3 files changed, 31 insertions(+), 49 deletions(-) create mode 100644 tests/target/issue_6082.rs diff --git a/src/parse/session.rs b/src/parse/session.rs index 11af9860513..60a89a57536 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -1,9 +1,8 @@ -use std::borrow::Cow; use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; -use rustc_errors::emitter::{stderr_destination, DynEmitter, Emitter, HumanEmitter}; +use rustc_errors::emitter::{stderr_destination, DynEmitter, Emitter, HumanEmitter, SilentEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; @@ -28,41 +27,6 @@ pub(crate) struct ParseSess { can_reset_errors: Lrc, } -/// Emitter which discards every error. -struct SilentEmitter; - -impl Translate for SilentEmitter { - fn fluent_bundle(&self) -> Option<&Lrc> { - None - } - - fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { - panic!("silent emitter attempted to translate a diagnostic"); - } - - // Override `translate_message` for the silent emitter because eager translation of - // subdiagnostics result in a call to this. - fn translate_message<'a>( - &'a self, - message: &'a rustc_errors::DiagMessage, - _: &'a rustc_errors::translation::FluentArgs<'_>, - ) -> Result, rustc_errors::error::TranslateError<'_>> { - rustc_errors::emitter::silent_translate(message) - } -} - -impl Emitter for SilentEmitter { - fn source_map(&self) -> Option<&Lrc> { - None - } - - fn emit_diagnostic(&mut self, _diag: DiagInner) {} -} - -fn silent_emitter() -> Box { - Box::new(SilentEmitter {}) -} - /// Emit errors against every files expect ones specified in the `ignore_path_set`. struct SilentOnIgnoredFilesEmitter { ignore_path_set: IntoDynSyncSend>, @@ -143,17 +107,23 @@ fn default_dcx( ColorConfig::Never }; - let emitter = if hide_parse_errors { - silent_emitter() + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); + let emitter = Box::new( + HumanEmitter::new(stderr_destination(emit_color), fallback_bundle.clone()) + .sm(Some(source_map.clone())), + ); + + let emitter: Box = if hide_parse_errors { + Box::new(SilentEmitter { + fallback_bundle, + fatal_dcx: DiagCtxt::new(emitter), + fatal_note: None, + }) } else { - let fallback_bundle = rustc_errors::fallback_fluent_bundle( - rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), - false, - ); - Box::new( - HumanEmitter::new(stderr_destination(emit_color), fallback_bundle) - .sm(Some(source_map.clone())), - ) + emitter }; DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, @@ -232,7 +202,14 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.raw_psess.dcx = DiagCtxt::new(silent_emitter()); + // Ideally this invocation wouldn't be necessary and the fallback bundle in + // `self.parse_sess.dcx` could be used, but the lock in `DiagCtxt` prevents this. + // See `::fallback_fluent_bundle`. + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); + self.raw_psess.dcx.make_silent(fallback_bundle, None); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 7dcf7c8416e..e66fad1e7fa 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -176,7 +176,7 @@ fn rustfmt_emits_error_on_line_overflow_true() { #[test] #[allow(non_snake_case)] fn dont_emit_ICE() { - let files = ["tests/target/issue_5728.rs", "tests/target/issue_5729.rs"]; + let files = ["tests/target/issue_5728.rs", "tests/target/issue_5729.rs", "tests/target/issue_6082.rs"]; for file in files { let args = [file]; diff --git a/tests/target/issue_6082.rs b/tests/target/issue_6082.rs new file mode 100644 index 00000000000..58e512c710e --- /dev/null +++ b/tests/target/issue_6082.rs @@ -0,0 +1,5 @@ +macro_rules! test { + ($T:ident, $b:lifetime) => { + Box<$T<$b>> + }; +} From 677c1d805906bcd21f0dd48d044fee9323db7e74 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 Feb 2024 14:12:50 +1100 Subject: [PATCH 33/66] Rewrite the `untranslatable_diagnostic` lint. Currently it only checks calls to functions marked with `#[rustc_lint_diagnostics]`. This commit changes it to check calls to any function with an `impl Into<{D,Subd}iagMessage>` parameter. This greatly improves its coverage and doesn't rely on people remembering to add `#[rustc_lint_diagnostics]`. The commit also adds `#[allow(rustc::untranslatable_diagnostic)`] attributes to places that need it that are caught by the improved lint. These places that might be easy to convert to translatable diagnostics. Finally, it also: - Expands and corrects some comments. - Does some minor formatting improvements. - Adds missing `DecorateLint` cases to `tests/ui-fulldeps/internal-lints/diagnostics.rs`. --- src/parse/session.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parse/session.rs b/src/parse/session.rs index 11af9860513..cf8120e9b09 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -383,6 +383,7 @@ mod tests { } fn build_diagnostic(level: DiagnosticLevel, span: Option) -> DiagInner { + #[allow(rustc::untranslatable_diagnostic)] // no translation needed for empty string let mut diag = DiagInner::new(level, ""); diag.messages.clear(); if let Some(span) = span { From f3892a06cc385a1d8c36f611680a866567b59a0e Mon Sep 17 00:00:00 2001 From: Ross Smyth Date: Sat, 17 Feb 2024 12:43:54 -0500 Subject: [PATCH 34/66] Add MatchKind member to the Match expr for pretty printing & fmt --- src/expr.rs | 8 ++++---- src/matches.rs | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index c500b30b998..e04290ce87c 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::{ast, ptr, token, ForLoopKind}; +use rustc_ast::{ast, MatchKind, ptr, token, ForLoopKind}; use rustc_span::{BytePos, Span}; use crate::chains::rewrite_chain; @@ -170,8 +170,8 @@ pub(crate) fn format_expr( } } } - ast::ExprKind::Match(ref cond, ref arms) => { - rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs) + ast::ExprKind::Match(ref cond, ref arms, kind) => { + rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs, kind) } ast::ExprKind::Path(ref qself, ref path) => { rewrite_path(context, PathContext::Expr, qself, path, shape) @@ -625,7 +625,7 @@ pub(crate) fn rewrite_cond( shape: Shape, ) -> Option { match expr.kind { - ast::ExprKind::Match(ref cond, _) => { + ast::ExprKind::Match(ref cond, _, MatchKind::Prefix) => { // `match `cond` {` let cond_shape = match context.config.indent_style() { IndentStyle::Visual => shape.shrink_left(6).and_then(|s| s.sub_width(2))?, diff --git a/src/matches.rs b/src/matches.rs index 5a00984d4c0..63e3162be2c 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -2,7 +2,7 @@ use std::iter::repeat; -use rustc_ast::{ast, ptr}; +use rustc_ast::{ast, MatchKind, ptr}; use rustc_span::{BytePos, Span}; use crate::comment::{combine_strs_with_missing_comments, rewrite_comment}; @@ -72,6 +72,8 @@ pub(crate) fn rewrite_match( shape: Shape, span: Span, attrs: &[ast::Attribute], + // TODO: Use this + _: MatchKind, ) -> Option { // Do not take the rhs overhead from the upper expressions into account // when rewriting match condition. From 1709dd59bd3aa5f9778ef9c03e8792fb8199a313 Mon Sep 17 00:00:00 2001 From: Ross Smyth Date: Sat, 17 Feb 2024 14:01:02 -0500 Subject: [PATCH 35/66] Add basic rustfmt implementation & test --- src/expr.rs | 2 +- src/matches.rs | 35 +++++++++++++++++--------- tests/source/postfix-match/pf-match.rs | 20 +++++++++++++++ tests/target/postfix-match/pf-match.rs | 20 +++++++++++++++ 4 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 tests/source/postfix-match/pf-match.rs create mode 100644 tests/target/postfix-match/pf-match.rs diff --git a/src/expr.rs b/src/expr.rs index e04290ce87c..053afcc52d4 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::{ast, MatchKind, ptr, token, ForLoopKind}; +use rustc_ast::{ast, ptr, token, ForLoopKind, MatchKind}; use rustc_span::{BytePos, Span}; use crate::chains::rewrite_chain; diff --git a/src/matches.rs b/src/matches.rs index 63e3162be2c..e68903c8715 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -2,7 +2,7 @@ use std::iter::repeat; -use rustc_ast::{ast, MatchKind, ptr}; +use rustc_ast::{ast, ptr, MatchKind}; use rustc_span::{BytePos, Span}; use crate::comment::{combine_strs_with_missing_comments, rewrite_comment}; @@ -72,8 +72,7 @@ pub(crate) fn rewrite_match( shape: Shape, span: Span, attrs: &[ast::Attribute], - // TODO: Use this - _: MatchKind, + match_kind: MatchKind, ) -> Option { // Do not take the rhs overhead from the upper expressions into account // when rewriting match condition. @@ -133,15 +132,27 @@ pub(crate) fn rewrite_match( } } else { let span_after_cond = mk_sp(cond.span.hi(), span.hi()); - Some(format!( - "match {}{}{{\n{}{}{}\n{}}}", - cond_str, - block_sep, - inner_attrs_str, - nested_indent_str, - rewrite_match_arms(context, arms, shape, span_after_cond, open_brace_pos)?, - shape.indent.to_string(context.config), - )) + + match match_kind { + MatchKind::Prefix => Some(format!( + "match {}{}{{\n{}{}{}\n{}}}", + cond_str, + block_sep, + inner_attrs_str, + nested_indent_str, + rewrite_match_arms(context, arms, shape, span_after_cond, open_brace_pos)?, + shape.indent.to_string(context.config), + )), + MatchKind::Postfix => Some(format!( + "{}.match{}{{\n{}{}{}\n{}}}", + cond_str, + block_sep, + inner_attrs_str, + nested_indent_str, + rewrite_match_arms(context, arms, shape, span_after_cond, open_brace_pos)?, + shape.indent.to_string(context.config), + )), + } } } diff --git a/tests/source/postfix-match/pf-match.rs b/tests/source/postfix-match/pf-match.rs new file mode 100644 index 00000000000..b2366723631 --- /dev/null +++ b/tests/source/postfix-match/pf-match.rs @@ -0,0 +1,20 @@ +#![feature(postfix_match)] + +fn main() { + let val = Some(42); + + val.match { + Some(_) => 2, + _ => 1 + }; + + Some(2).match { + Some(_) => true, + None => false + }.match { + false => "ferris is cute", + true => "I turn cats in to petted cats", + }.match { + _ => (), + } +} \ No newline at end of file diff --git a/tests/target/postfix-match/pf-match.rs b/tests/target/postfix-match/pf-match.rs new file mode 100644 index 00000000000..f439f272623 --- /dev/null +++ b/tests/target/postfix-match/pf-match.rs @@ -0,0 +1,20 @@ +#![feature(postfix_match)] + +fn main() { + let val = Some(42); + + val.match { + Some(_) => 2, + _ => 1, + }; + + Some(2).match { + Some(_) => true, + None => false, + }.match { + false => "ferris is cute", + true => "I turn cats in to petted cats", + }.match { + _ => (), + } +} From fe0415e17a6cda89ab7a8afa3cfe1dfc298e3ded Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 14 Mar 2024 11:25:05 +0100 Subject: [PATCH 36/66] Rename `ast::StmtKind::Local` into `ast::StmtKind::Let` --- src/attr.rs | 2 +- src/spanned.rs | 2 +- src/stmt.rs | 2 +- src/visitor.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/attr.rs b/src/attr.rs index 4d83547d664..83f59837d44 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -26,7 +26,7 @@ pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] { pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span { match stmt.kind { - ast::StmtKind::Local(ref local) => local.span, + ast::StmtKind::Let(ref local) => local.span, ast::StmtKind::Item(ref item) => item.span, ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span, ast::StmtKind::MacCall(ref mac_stmt) => mac_stmt.mac.span(), diff --git a/src/spanned.rs b/src/spanned.rs index 5960b144499..4aaf7fdb27f 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -61,7 +61,7 @@ implement_spanned!(ast::Local); impl Spanned for ast::Stmt { fn span(&self) -> Span { match self.kind { - ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()), + ast::StmtKind::Let(ref local) => mk_sp(local.span().lo(), self.span.hi()), ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()), ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => { mk_sp(expr.span().lo(), self.span.hi()) diff --git a/src/stmt.rs b/src/stmt.rs index e3fe4ebca11..73a9cce416c 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -115,7 +115,7 @@ fn format_stmt( skip_out_of_file_lines_range!(context, stmt.span()); let result = match stmt.kind { - ast::StmtKind::Local(ref local) => local.rewrite(context, shape), + ast::StmtKind::Let(ref local) => local.rewrite(context, shape), ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => { let suffix = if semicolon_for_stmt(context, stmt, is_last_expr) { ";" diff --git a/src/visitor.rs b/src/visitor.rs index 47f772b485d..6209b37004b 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -150,7 +150,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.visit_item(item); self.last_pos = stmt.span().hi(); } - ast::StmtKind::Local(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => { + ast::StmtKind::Let(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => { let attrs = get_attrs_from_stmt(stmt.as_ast_node()); if contains_skip(attrs) { self.push_skipped_with_span( From 911f6a438f1e6e6b1e80b56be638e6c193ec93ef Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 19 Mar 2024 12:58:23 -0400 Subject: [PATCH 37/66] conditionally ignore fatal diagnostic in the SilentEmitter This change is primarily meant to allow rustfmt to ignore all diagnostics when using the `SilentEmitter`. Back in PR 121301 the `SilentEmitter` was shared between rustc and rustfmt. This changed rustfmt's behavior from ignoring all diagnostic to emitting fatal diagnostics. These changes allow rustfmt to maintain it's previous behaviour when using the SilentEmitter, while allowing rustc code to still emit fatal diagnostics. --- src/parse/session.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index cb46e65999d..1a39d212386 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -121,6 +121,7 @@ fn default_dcx( fallback_bundle, fatal_dcx: DiagCtxt::new(emitter), fatal_note: None, + emit_fatal_diagnostic: false, }) } else { emitter @@ -209,7 +210,7 @@ impl ParseSess { rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false, ); - self.raw_psess.dcx.make_silent(fallback_bundle, None); + self.raw_psess.dcx.make_silent(fallback_bundle, None, false); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { From 8f62a2dedbbb2d694afcf810e38661902c88938a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 19 Mar 2024 09:34:31 -0400 Subject: [PATCH 38/66] step cfgs --- src/source_file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_file.rs b/src/source_file.rs index 6376bc49b69..2b43ec94b6b 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -66,7 +66,7 @@ where } } - #[cfg_attr(not(bootstrap), allow(non_local_definitions))] + #[allow(non_local_definitions)] impl From<&FileName> for rustc_span::FileName { fn from(filename: &FileName) -> rustc_span::FileName { match filename { From f670f3b5e05a3126fe4cf5b4b75c97658c062357 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 20 Mar 2024 16:53:50 -0400 Subject: [PATCH 39/66] Implement macro-based deref!() syntax for deref patterns Stop using `box PAT` syntax for deref patterns, as it's misleading and also causes their semantics being tangled up. --- src/patterns.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/patterns.rs b/src/patterns.rs index 7f576279432..47b48468a24 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -55,9 +55,10 @@ fn is_short_pattern_inner(pat: &ast::Pat) -> bool { ast::PatKind::TupleStruct(_, ref path, ref subpats) => { path.segments.len() <= 1 && subpats.len() <= 1 } - ast::PatKind::Box(ref p) | ast::PatKind::Ref(ref p, _) | ast::PatKind::Paren(ref p) => { - is_short_pattern_inner(&*p) - } + ast::PatKind::Box(ref p) + | PatKind::Deref(ref p) + | ast::PatKind::Ref(ref p, _) + | ast::PatKind::Paren(ref p) => is_short_pattern_inner(&*p), PatKind::Or(ref pats) => pats.iter().all(|p| is_short_pattern_inner(p)), } } @@ -277,6 +278,7 @@ impl Rewrite for Pat { .rewrite(context, shape.offset_left(1)?.sub_width(1)?) .map(|inner_pat| format!("({})", inner_pat)), PatKind::Err(_) => None, + PatKind::Deref(_) => None, } } } From 645b94c1555e2ede79095a0385c6ad24ae7e5419 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 23 Mar 2024 21:04:45 -0400 Subject: [PATCH 40/66] Implement `mut ref`/`mut ref mut` --- src/patterns.rs | 91 +++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/src/patterns.rs b/src/patterns.rs index 47b48468a24..820eccb2dc2 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -107,18 +107,19 @@ impl Rewrite for Pat { } PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape), PatKind::Ident(BindingAnnotation(by_ref, mutability), ident, ref sub_pat) => { - let prefix = match by_ref { - ByRef::Yes => "ref", - ByRef::No => "", + let mut_prefix = format_mutability(mutability).trim(); + + let (ref_kw, mut_infix) = match by_ref { + ByRef::Yes(rmutbl) => ("ref", format_mutability(rmutbl).trim()), + ByRef::No => ("", ""), }; - let mut_infix = format_mutability(mutability).trim(); let id_str = rewrite_ident(context, ident); let sub_pat = match *sub_pat { Some(ref p) => { // 2 - `@ `. - let width = shape - .width - .checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 2)?; + let width = shape.width.checked_sub( + mut_prefix.len() + ref_kw.len() + mut_infix.len() + id_str.len() + 2, + )?; let lo = context.snippet_provider.span_after(self.span, "@"); combine_strs_with_missing_comments( context, @@ -132,33 +133,55 @@ impl Rewrite for Pat { None => "".to_owned(), }; - // combine prefix and mut - let (first_lo, first) = if !prefix.is_empty() && !mut_infix.is_empty() { - let hi = context.snippet_provider.span_before(self.span, "mut"); - let lo = context.snippet_provider.span_after(self.span, "ref"); - ( + // combine prefix and ref + let (first_lo, first) = match (mut_prefix.is_empty(), ref_kw.is_empty()) { + (false, false) => { + let lo = context.snippet_provider.span_after(self.span, "mut"); + let hi = context.snippet_provider.span_before(self.span, "ref"); + ( + context.snippet_provider.span_after(self.span, "ref"), + combine_strs_with_missing_comments( + context, + mut_prefix, + ref_kw, + mk_sp(lo, hi), + shape, + true, + )?, + ) + } + (false, true) => ( context.snippet_provider.span_after(self.span, "mut"), - combine_strs_with_missing_comments( - context, - prefix, - mut_infix, - mk_sp(lo, hi), - shape, - true, - )?, - ) - } else if !prefix.is_empty() { - ( + mut_prefix.to_owned(), + ), + (true, false) => ( context.snippet_provider.span_after(self.span, "ref"), - prefix.to_owned(), - ) - } else if !mut_infix.is_empty() { - ( - context.snippet_provider.span_after(self.span, "mut"), - mut_infix.to_owned(), - ) - } else { - (self.span.lo(), "".to_owned()) + ref_kw.to_owned(), + ), + (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()) { + (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"); + ( + context.snippet_provider.span_after(end_span, "mut"), + combine_strs_with_missing_comments( + context, + &first, + mut_infix, + mk_sp(lo, hi), + shape, + true, + )?, + ) + } + (false, true) => (first_lo, first), + (true, false) => unreachable!("mut_infix necessarily follows a ref"), + (true, true) => (self.span.lo(), "".to_owned()), }; let next = if !sub_pat.is_empty() { @@ -177,9 +200,9 @@ impl Rewrite for Pat { combine_strs_with_missing_comments( context, - &first, + &second, &next, - mk_sp(first_lo, ident.span.lo()), + mk_sp(second_lo, ident.span.lo()), shape, true, ) From 31a4eae7eac98b29cfe938b48498b24c71ddc925 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 27 Mar 2024 16:35:40 -0400 Subject: [PATCH 41/66] Add rustfmt test for mut ref mut --- tests/source/mut_ref.rs | 10 ++++++++++ tests/target/mut_ref.rs | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/source/mut_ref.rs create mode 100644 tests/target/mut_ref.rs diff --git a/tests/source/mut_ref.rs b/tests/source/mut_ref.rs new file mode 100644 index 00000000000..18ff33a99ce --- /dev/null +++ b/tests/source/mut_ref.rs @@ -0,0 +1,10 @@ +#![feature(mut_ref)] +fn mut_ref() { + if let Some(mut /*a*/ ref /*def*/ mut /*abc*/ state)= /*abc*/foo{ + println!( +"asdfasdfasdf"); } + +if let Some(mut /*a*/ ref /*def*/ /*mut*/ state)= /*abc*/foo{ + println!( +"asdfasdfasdf"); } +} diff --git a/tests/target/mut_ref.rs b/tests/target/mut_ref.rs new file mode 100644 index 00000000000..16035243791 --- /dev/null +++ b/tests/target/mut_ref.rs @@ -0,0 +1,10 @@ +#![feature(mut_ref)] +fn mut_ref() { + if let Some(mut /*a*/ ref /*def*/ mut /*abc*/ state) = /*abc*/ foo { + println!("asdfasdfasdf"); + } + + if let Some(mut /*a*/ ref /*def*/ /*mut*/ state) = /*abc*/ foo { + println!("asdfasdfasdf"); + } +} From fd204262e543d31189aa3e8db593974b978181ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 4 Apr 2024 19:03:32 +0200 Subject: [PATCH 42/66] Rename ModSep to PathSep --- src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.rs b/src/macros.rs index 8d77d2b3254..6b24b1aec5d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1091,7 +1091,7 @@ fn next_space(tok: &TokenKind) -> SpaceState { | TokenKind::DotDotEq | TokenKind::Question => SpaceState::Punctuation, - TokenKind::ModSep + TokenKind::PathSep | TokenKind::Pound | TokenKind::Dollar | TokenKind::OpenDelim(_) From 7af33b30768a7ab0df2b285b225233d5fb565c5c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 30 Jan 2023 09:50:16 +0000 Subject: [PATCH 43/66] Add pattern types to ast --- src/types.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types.rs b/src/types.rs index 7f220a456a8..10a87f6e698 100644 --- a/src/types.rs +++ b/src/types.rs @@ -867,6 +867,11 @@ impl Rewrite for ast::Ty { self.span, shape, ), + ast::TyKind::Pat(ref ty, ref pat) => { + let ty = ty.rewrite(context, shape)?; + let pat = pat.rewrite(context, shape)?; + Some(format!("{ty} is {pat}")) + } } } } From afa482ef2499a2501ce64c437912d197f8ab9f13 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 2 Apr 2024 00:26:10 +0200 Subject: [PATCH 44/66] store the span of the nested part of the use tree in the ast --- src/imports.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/imports.rs b/src/imports.rs index 09f6e752338..2da746295fc 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -458,7 +458,9 @@ impl UseTree { version, }); } - UseTreeKind::Nested(ref list) => { + UseTreeKind::Nested { + items: ref list, .. + } => { // Extract comments between nested use items. // This needs to be done before sorting use items. let items = itemize_list( From 9400b9952ef66554e938477d429eab55deea043b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 20:52:56 -0400 Subject: [PATCH 45/66] Rustfmt, clippy --- src/types.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/types.rs b/src/types.rs index 10a87f6e698..fe2d28ae1b9 100644 --- a/src/types.rs +++ b/src/types.rs @@ -843,7 +843,11 @@ impl Rewrite for ast::Ty { rewrite_macro(mac, None, context, shape, MacroPosition::Expression) } ast::TyKind::ImplicitSelf => Some(String::from("")), - ast::TyKind::ImplTrait(_, ref it) => { + ast::TyKind::ImplTrait(_, ref it, ref captures) => { + // FIXME(precise_capturing): Implement formatting. + if captures.is_some() { + return None; + } // Empty trait is not a parser error. if it.is_empty() { return Some("impl".to_owned()); @@ -1106,7 +1110,8 @@ fn join_bounds_inner( 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), + // FIXME(precise_capturing): Implement support here + ast::TyKind::ImplTrait(_, bounds, _) => Some(bounds), _ => None, }) } From 932f3ab7625fc65b733f04f49d60f6c27644fdee Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 16 Apr 2024 19:23:30 -0400 Subject: [PATCH 46/66] Rename `BindingAnnotation` to `BindingMode` --- src/patterns.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/patterns.rs b/src/patterns.rs index 820eccb2dc2..d8cb26a20f1 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -1,6 +1,4 @@ -use rustc_ast::ast::{ - self, BindingAnnotation, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax, -}; +use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax}; use rustc_ast::ptr; use rustc_span::{BytePos, Span}; @@ -106,7 +104,7 @@ impl Rewrite for Pat { write_list(&items, &fmt) } PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape), - PatKind::Ident(BindingAnnotation(by_ref, mutability), ident, ref sub_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 { From 966dd60251152809b82050ae04fdc18a0ac909c6 Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Wed, 17 Apr 2024 23:40:03 +0200 Subject: [PATCH 47/66] Disallow ambiguous attributes on expressions --- tests/source/attrib.rs | 4 ++-- tests/target/attrib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/source/attrib.rs b/tests/source/attrib.rs index d45fba55224..fc13cd02b03 100644 --- a/tests/source/attrib.rs +++ b/tests/source/attrib.rs @@ -214,8 +214,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo ; - #[must_use] - foo = false ; + (#[must_use] + foo) = false ; } // #3509 diff --git a/tests/target/attrib.rs b/tests/target/attrib.rs index 7e61f68d76a..7b3309676de 100644 --- a/tests/target/attrib.rs +++ b/tests/target/attrib.rs @@ -248,8 +248,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo; - #[must_use] - foo = false; + (#[must_use] + foo) = false; } // #3509 From 20e40d5efedebd13edcbf059441a1684029fc5e1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 11 Apr 2024 13:15:34 +0000 Subject: [PATCH 48/66] Error on using `yield` without also using `#[coroutine]` on the closure And suggest adding the `#[coroutine]` to the closure --- tests/source/immovable_coroutines.rs | 3 ++- tests/target/immovable_coroutines.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/source/immovable_coroutines.rs b/tests/source/immovable_coroutines.rs index 3b94af0c96c..539049577a0 100644 --- a/tests/source/immovable_coroutines.rs +++ b/tests/source/immovable_coroutines.rs @@ -1,7 +1,8 @@ #![feature(coroutines)] unsafe fn foo() { - let mut ga = static || { + let mut ga = #[coroutine] + static || { yield 1; }; } diff --git a/tests/target/immovable_coroutines.rs b/tests/target/immovable_coroutines.rs index f52cfa00f97..539049577a0 100644 --- a/tests/target/immovable_coroutines.rs +++ b/tests/target/immovable_coroutines.rs @@ -1,7 +1,8 @@ #![feature(coroutines)] unsafe fn foo() { - let mut ga = static || { + let mut ga = #[coroutine] + static || { yield 1; }; } From e606bb626ec2a30e10015006ea36443f65b12dd9 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 14:13:08 +0100 Subject: [PATCH 49/66] Remove direct dependencies on lazy_static, once_cell and byteorder The functionality of all three crates is now available in the standard library. --- Cargo.toml | 1 - src/comment.rs | 20 ++++++-------------- src/lib.rs | 10 +++++++--- src/test/configuration_snippet.rs | 22 +++++++--------------- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 032b9b54810..b18c80654a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,6 @@ dirs = "4.0" getopts = "0.2" ignore = "0.4" itertools = "0.11" -lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" diff --git a/src/comment.rs b/src/comment.rs index 7d1b0384431..099e12f86dd 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,8 +3,6 @@ use std::{borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; -use lazy_static::lazy_static; -use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -17,17 +15,6 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; -lazy_static! { - /// A regex matching reference doc links. - /// - /// ```markdown - /// /// An [example]. - /// /// - /// /// [example]: this::is::a::link - /// ``` - static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); -} - fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -980,11 +967,16 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. + // The regex is indended to capture text such as the below. + // + // /// An [example]. + // /// + // /// [example]: this::is::a::link s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") - || REFERENCE_LINK_URL.is_match(s) + || static_regex!(r"^\[.+\]\s?:").is_match(s) } /// Returns true if the given string may be part of a Markdown table. diff --git a/src/lib.rs b/src/lib.rs index 877d057a34b..e07720f30ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,6 @@ #![allow(clippy::match_like_matches_macro)] #![allow(unreachable_pub)] -#[cfg(test)] -#[macro_use] -extern crate lazy_static; #[macro_use] extern crate tracing; @@ -62,6 +59,13 @@ pub use crate::rustfmt_diff::{ModifiedChunk, ModifiedLines}; #[macro_use] mod utils; +macro_rules! static_regex { + ($re:literal) => {{ + static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); + RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) + }}; +} + mod attr; mod chains; mod closures; diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index 80b61c88a00..a195b306da3 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -24,19 +24,6 @@ impl ConfigurationSection { fn get_section>( file: &mut Enumerate, ) -> Option { - lazy_static! { - static ref CONFIG_NAME_REGEX: regex::Regex = - regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); - // Configuration values, which will be passed to `from_str`: - // - // - must be prefixed with `####` - // - must be wrapped in backticks - // - may by wrapped in double quotes (which will be stripped) - static ref CONFIG_VALUE_REGEX: regex::Regex = - regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) - .expect("failed creating configuration value pattern"); - } - loop { match file.next() { Some((i, line)) => { @@ -53,9 +40,14 @@ impl ConfigurationSection { let start_line = (i + 2) as u32; return Some(ConfigurationSection::CodeBlock((block, start_line))); - } else if let Some(c) = CONFIG_NAME_REGEX.captures(&line) { + } else if let Some(c) = static_regex!(r"^## `([^`]+)`").captures(&line) { return Some(ConfigurationSection::ConfigName(String::from(&c[1]))); - } else if let Some(c) = CONFIG_VALUE_REGEX.captures(&line) { + } else if let Some(c) = static_regex!(r#"^#### `"?([^`]+?)"?`"#).captures(&line) { + // Configuration values, which will be passed to `from_str` + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) return Some(ConfigurationSection::ConfigValue(String::from(&c[1]))); } } From 997d5f2bec55c711fd9aeaac7bc5d7b65144dbcf Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 21:38:55 +0100 Subject: [PATCH 50/66] Move rustfmt changes out Now in https://github.com/rust-lang/rustfmt/pull/6154 --- Cargo.toml | 1 + src/comment.rs | 20 ++++++++++++++------ src/lib.rs | 10 +++------- src/test/configuration_snippet.rs | 22 +++++++++++++++------- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b18c80654a0..032b9b54810 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ dirs = "4.0" getopts = "0.2" ignore = "0.4" itertools = "0.11" +lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" diff --git a/src/comment.rs b/src/comment.rs index 099e12f86dd..7d1b0384431 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,6 +3,8 @@ use std::{borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; +use lazy_static::lazy_static; +use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -15,6 +17,17 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; +lazy_static! { + /// A regex matching reference doc links. + /// + /// ```markdown + /// /// An [example]. + /// /// + /// /// [example]: this::is::a::link + /// ``` + static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); +} + fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -967,16 +980,11 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. - // The regex is indended to capture text such as the below. - // - // /// An [example]. - // /// - // /// [example]: this::is::a::link s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") - || static_regex!(r"^\[.+\]\s?:").is_match(s) + || REFERENCE_LINK_URL.is_match(s) } /// Returns true if the given string may be part of a Markdown table. diff --git a/src/lib.rs b/src/lib.rs index e07720f30ca..877d057a34b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,9 @@ #![allow(clippy::match_like_matches_macro)] #![allow(unreachable_pub)] +#[cfg(test)] +#[macro_use] +extern crate lazy_static; #[macro_use] extern crate tracing; @@ -59,13 +62,6 @@ pub use crate::rustfmt_diff::{ModifiedChunk, ModifiedLines}; #[macro_use] mod utils; -macro_rules! static_regex { - ($re:literal) => {{ - static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); - RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) - }}; -} - mod attr; mod chains; mod closures; diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index a195b306da3..80b61c88a00 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -24,6 +24,19 @@ impl ConfigurationSection { fn get_section>( file: &mut Enumerate, ) -> Option { + lazy_static! { + static ref CONFIG_NAME_REGEX: regex::Regex = + regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); + // Configuration values, which will be passed to `from_str`: + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) + static ref CONFIG_VALUE_REGEX: regex::Regex = + regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) + .expect("failed creating configuration value pattern"); + } + loop { match file.next() { Some((i, line)) => { @@ -40,14 +53,9 @@ impl ConfigurationSection { let start_line = (i + 2) as u32; return Some(ConfigurationSection::CodeBlock((block, start_line))); - } else if let Some(c) = static_regex!(r"^## `([^`]+)`").captures(&line) { + } else if let Some(c) = CONFIG_NAME_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigName(String::from(&c[1]))); - } else if let Some(c) = static_regex!(r#"^#### `"?([^`]+?)"?`"#).captures(&line) { - // Configuration values, which will be passed to `from_str` - // - // - must be prefixed with `####` - // - must be wrapped in backticks - // - may by wrapped in double quotes (which will be stripped) + } else if let Some(c) = CONFIG_VALUE_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigValue(String::from(&c[1]))); } } From fafa690716ca2a6495e53fb3317ace76fc98061f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 29 Apr 2024 11:27:14 -0300 Subject: [PATCH 51/66] Add StaticForeignItem and use it on ForeignItemKind --- src/items.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items.rs b/src/items.rs index f6f51fbd8ea..e196d1817f3 100644 --- a/src/items.rs +++ b/src/items.rs @@ -3325,11 +3325,11 @@ impl Rewrite for ast::ForeignItem { .map(|(s, _, _)| format!("{};", s)) } } - ast::ForeignItemKind::Static(ref ty, mutability, _) => { + ast::ForeignItemKind::Static(ref static_foreign_item) => { // FIXME(#21): we're dropping potential comments in between the // function kw here. let vis = format_visibility(context, &self.vis); - let mut_str = format_mutability(mutability); + let mut_str = format_mutability(static_foreign_item.mutability); let prefix = format!( "{}static {}{}:", vis, @@ -3340,7 +3340,7 @@ impl Rewrite for ast::ForeignItem { rewrite_assign_rhs( context, prefix, - &**ty, + &static_foreign_item.ty, &RhsAssignKind::Ty, shape.sub_width(1)?, ) From 05a2db7624bfdb8fcd0541acbda04671bf742c2d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 15 Mar 2024 14:21:03 +0300 Subject: [PATCH 52/66] delegation: Implement list delegation ```rust reuse prefix::{a, b, c} ``` --- 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 e196d1817f3..90e9e58ef9c 100644 --- a/src/items.rs +++ b/src/items.rs @@ -739,8 +739,8 @@ impl<'a> FmtVisitor<'a> { (_, Const(..)) => Ordering::Greater, (MacCall(..), _) => Ordering::Less, (_, MacCall(..)) => Ordering::Greater, - (Delegation(..), _) => Ordering::Less, - (_, Delegation(..)) => Ordering::Greater, + (Delegation(..), _) | (DelegationMac(..), _) => Ordering::Less, + (_, Delegation(..)) | (_, DelegationMac(..)) => Ordering::Greater, }); let mut prev_kind = None; for (buf, item) in buffer { diff --git a/src/visitor.rs b/src/visitor.rs index 6209b37004b..e1c7dc35087 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -586,7 +586,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ); self.push_rewrite(item.span, rewrite); } - ast::ItemKind::Delegation(..) => { + ast::ItemKind::Delegation(..) | ast::ItemKind::DelegationMac(..) => { // TODO: rewrite delegation items once syntax is established. // For now, leave the contents of the Span unformatted. self.push_rewrite(item.span, None) From 97bdbd96f17c1dbff17331c96e1ac1fbdf4bb405 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 17 May 2024 14:17:48 -0300 Subject: [PATCH 53/66] Rename Unsafe to Safety --- src/items.rs | 22 +++++++++++----------- src/types.rs | 2 +- src/utils.rs | 6 +++--- src/visitor.rs | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/items.rs b/src/items.rs index 90e9e58ef9c..e869787b394 100644 --- a/src/items.rs +++ b/src/items.rs @@ -247,7 +247,7 @@ fn allow_single_line_let_else_block(result: &str, block: &ast::Block) -> bool { #[allow(dead_code)] #[derive(Debug)] struct Item<'a> { - unsafety: ast::Unsafe, + safety: ast::Safety, abi: Cow<'static, str>, vis: Option<&'a ast::Visibility>, body: Vec>, @@ -257,7 +257,7 @@ struct Item<'a> { impl<'a> Item<'a> { fn from_foreign_mod(fm: &'a ast::ForeignMod, span: Span, config: &Config) -> Item<'a> { Item { - unsafety: fm.unsafety, + safety: fm.safety, abi: format_extern( ast::Extern::from_abi(fm.abi, DUMMY_SP), config.force_explicit_abi(), @@ -290,7 +290,7 @@ pub(crate) struct FnSig<'a> { coroutine_kind: Cow<'a, Option>, constness: ast::Const, defaultness: ast::Defaultness, - unsafety: ast::Unsafe, + safety: ast::Safety, visibility: &'a ast::Visibility, } @@ -301,7 +301,7 @@ impl<'a> FnSig<'a> { visibility: &'a ast::Visibility, ) -> FnSig<'a> { FnSig { - unsafety: method_sig.header.unsafety, + safety: method_sig.header.safety, coroutine_kind: Cow::Borrowed(&method_sig.header.coroutine_kind), constness: method_sig.header.constness, defaultness: ast::Defaultness::Final, @@ -330,7 +330,7 @@ impl<'a> FnSig<'a> { constness: fn_sig.header.constness, coroutine_kind: Cow::Borrowed(&fn_sig.header.coroutine_kind), defaultness, - unsafety: fn_sig.header.unsafety, + safety: fn_sig.header.safety, visibility: vis, }, _ => unreachable!(), @@ -345,7 +345,7 @@ impl<'a> FnSig<'a> { result.push_str(format_constness(self.constness)); self.coroutine_kind .map(|coroutine_kind| result.push_str(format_coro(&coroutine_kind))); - result.push_str(format_unsafety(self.unsafety)); + result.push_str(format_safety(self.safety)); result.push_str(&format_extern( self.ext, context.config.force_explicit_abi(), @@ -356,7 +356,7 @@ impl<'a> FnSig<'a> { impl<'a> FmtVisitor<'a> { fn format_item(&mut self, item: &Item<'_>) { - self.buffer.push_str(format_unsafety(item.unsafety)); + self.buffer.push_str(format_safety(item.safety)); self.buffer.push_str(&item.abi); let snippet = self.snippet(item.span); @@ -924,7 +924,7 @@ fn format_impl_ref_and_type( offset: Indent, ) -> Option { let ast::Impl { - unsafety, + safety, polarity, defaultness, constness, @@ -937,7 +937,7 @@ fn format_impl_ref_and_type( result.push_str(&format_visibility(context, &item.vis)); result.push_str(format_defaultness(defaultness)); - result.push_str(format_unsafety(unsafety)); + result.push_str(format_safety(safety)); let shape = if context.config.version() == Version::Two { Shape::indented(offset + last_line_width(&result), context.config) @@ -1137,7 +1137,7 @@ pub(crate) fn format_trait( }; let ast::Trait { is_auto, - unsafety, + safety, ref generics, ref bounds, ref items, @@ -1147,7 +1147,7 @@ pub(crate) fn format_trait( let header = format!( "{}{}{}trait ", format_visibility(context, &item.vis), - format_unsafety(unsafety), + format_safety(safety), format_auto(is_auto), ); result.push_str(&header); diff --git a/src/types.rs b/src/types.rs index fe2d28ae1b9..75dea90d994 100644 --- a/src/types.rs +++ b/src/types.rs @@ -899,7 +899,7 @@ fn rewrite_bare_fn( result.push_str("> "); } - result.push_str(crate::utils::format_unsafety(bare_fn.unsafety)); + result.push_str(crate::utils::format_safety(bare_fn.safety)); result.push_str(&format_extern( bare_fn.ext, diff --git a/src/utils.rs b/src/utils.rs index b91d9b47cb6..09e1dbde1d0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -108,10 +108,10 @@ pub(crate) fn format_defaultness(defaultness: ast::Defaultness) -> &'static str } #[inline] -pub(crate) fn format_unsafety(unsafety: ast::Unsafe) -> &'static str { +pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str { match unsafety { - ast::Unsafe::Yes(..) => "unsafe ", - ast::Unsafe::No => "", + ast::Safety::Unsafe(..) => "unsafe ", + ast::Safety::Default => "", } } diff --git a/src/visitor.rs b/src/visitor.rs index e1c7dc35087..7a0c68c214c 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -24,7 +24,7 @@ use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; use crate::stmt::Stmt; use crate::utils::{ - self, contains_skip, count_newlines, depr_skip_annotation, format_unsafety, inner_attributes, + self, contains_skip, count_newlines, depr_skip_annotation, format_safety, inner_attributes, last_line_width, mk_sp, ptr_vec_to_ref_vec, rewrite_ident, starts_with_newline, stmt_expr, }; use crate::{ErrorKind, FormatReport, FormattingError}; @@ -517,9 +517,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.visit_enum(item.ident, &item.vis, def, generics, item.span); self.last_pos = source!(self, item.span).hi(); } - ast::ItemKind::Mod(unsafety, ref mod_kind) => { + ast::ItemKind::Mod(safety, ref mod_kind) => { self.format_missing_with_indent(source!(self, item.span).lo()); - self.format_mod(mod_kind, unsafety, &item.vis, item.span, item.ident, attrs); + self.format_mod(mod_kind, safety, &item.vis, item.span, item.ident, attrs); } ast::ItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(item.ident), MacroPosition::Item); @@ -913,7 +913,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { fn format_mod( &mut self, mod_kind: &ast::ModKind, - unsafety: ast::Unsafe, + safety: ast::Safety, vis: &ast::Visibility, s: Span, ident: symbol::Ident, @@ -921,7 +921,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ) { let vis_str = utils::format_visibility(&self.get_context(), vis); self.push_str(&*vis_str); - self.push_str(format_unsafety(unsafety)); + self.push_str(format_safety(safety)); self.push_str("mod "); // Calling `to_owned()` to work around borrow checker. let ident_str = rewrite_ident(&self.get_context(), ident).to_owned(); From a2c6f80a45f84c20ec839e7842214938df5c6f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 27 May 2024 23:53:46 +0200 Subject: [PATCH 54/66] Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup --- src/types.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/types.rs b/src/types.rs index 75dea90d994..7d14d9e727a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -140,7 +140,7 @@ pub(crate) enum SegmentParam<'a> { Const(&'a ast::AnonConst), LifeTime(&'a ast::Lifetime), Type(&'a ast::Ty), - Binding(&'a ast::AssocConstraint), + Binding(&'a ast::AssocItemConstraint), } impl<'a> SegmentParam<'a> { @@ -175,9 +175,9 @@ impl<'a> Rewrite for SegmentParam<'a> { } } -impl Rewrite for ast::AssocConstraint { +impl Rewrite for ast::AssocItemConstraint { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - use ast::AssocConstraintKind::{Bound, Equality}; + use ast::AssocItemConstraintKind::{Bound, Equality}; let mut result = String::with_capacity(128); result.push_str(rewrite_ident(context, self.ident)); @@ -205,14 +205,14 @@ impl Rewrite for ast::AssocConstraint { } } -impl Rewrite for ast::AssocConstraintKind { +impl Rewrite for ast::AssocItemConstraintKind { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match self { - ast::AssocConstraintKind::Equality { term } => match term { + ast::AssocItemConstraintKind::Equality { term } => match term { Term::Ty(ty) => ty.rewrite(context, shape), Term::Const(c) => c.rewrite(context, shape), }, - ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), + ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), } } } From 6478d9e59cef8b8341c63b48d493fb57d166caca Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 23 May 2024 10:01:05 -0300 Subject: [PATCH 55/66] Handle safety keyword for extern block inner items --- src/utils.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils.rs b/src/utils.rs index 09e1dbde1d0..fd59aedadfe 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -111,6 +111,7 @@ pub(crate) fn format_defaultness(defaultness: ast::Defaultness) -> &'static str pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str { match unsafety { ast::Safety::Unsafe(..) => "unsafe ", + ast::Safety::Safe(..) => "safe ", ast::Safety::Default => "", } } From eeefcd66cb1b74e9e71048a04df549246b61380f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 31 May 2024 13:32:54 +1000 Subject: [PATCH 56/66] Remove `stream_to_parser`. It's a zero-value wrapper of `Parser::new`. --- src/parse/macros/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 3cf133c647c..cbcc0b2d636 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -2,7 +2,7 @@ use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; -use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; +use rustc_parse::MACRO_ARGUMENTS; use rustc_session::parse::ParseSess; use rustc_span::symbol::{self, kw}; use rustc_span::Symbol; @@ -15,7 +15,7 @@ pub(crate) mod cfg_if; pub(crate) mod lazy_static; fn build_stream_parser<'a>(psess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> { - stream_to_parser(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden) + Parser::new(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden) } fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { From 5962aa96f1aad5c30e19119c6da0ea19e0588ea5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 31 May 2024 15:43:18 +1000 Subject: [PATCH 57/66] Make top-level `rustc_parse` functions fallible. Currently we have an awkward mix of fallible and infallible functions: ``` new_parser_from_source_str maybe_new_parser_from_source_str new_parser_from_file (maybe_new_parser_from_file) // missing (new_parser_from_source_file) // missing maybe_new_parser_from_source_file source_str_to_stream maybe_source_file_to_stream ``` We could add the two missing functions, but instead this commit removes of all the infallible ones and renames the fallible ones leaving us with these which are all fallible: ``` new_parser_from_source_str new_parser_from_file new_parser_from_source_file source_str_to_stream source_file_to_stream ``` This requires making `unwrap_or_emit_fatal` public so callers of formerly infallible functions can still work. This does make some of the call sites slightly more verbose, but I think it's worth it for the simpler API. Also, there are two `catch_unwind` calls and one `catch_fatal_errors` call in this diff that become removable thanks this change. (I will do that in a follow-up PR.) --- src/parse/parser.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 5dcdca1d953..7adf339b453 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -4,7 +4,8 @@ use std::path::{Path, PathBuf}; use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; use rustc_errors::Diag; -use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; +use rustc_parse::parser::Parser as RawParser; +use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal}; use rustc_span::{sym, Span}; use thin_vec::ThinVec; @@ -68,10 +69,10 @@ impl<'a> ParserBuilder<'a> { ) -> Result, Option>>> { match input { Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { - new_parser_from_file(psess, file, None) + unwrap_or_emit_fatal(new_parser_from_file(psess, file, None)) })) .map_err(|_| None), - Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str( + Input::Text(text) => rustc_parse::new_parser_from_source_str( psess, rustc_span::FileName::Custom("stdin".to_owned()), text, @@ -111,7 +112,8 @@ impl<'a> Parser<'a> { span: Span, ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = new_parser_from_file(psess.inner(), path, Some(span)); + let mut parser = + unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); match parser.parse_mod(&TokenKind::Eof) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { From ecb2dd151c4d78fa9231f66e9c90dfef90dab4cc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Jun 2024 14:32:03 +1000 Subject: [PATCH 58/66] rustfmt: Remove an unnecessary `catch_unwind` use. The `Input::File` and `Input::Text` cases should be very similar. However, currently the `Input::File` case uses `catch_unwind` because, until recently (#125815) there was a fallible version of `new_parser_from_source_str` but only an infallible version of `new_parser_from_file`. This difference wasn't fundamental, just an overlooked gap in the API of `rustc_parse`. Both of those operations are now fallible, so the `Input::File` and `Input::Text` cases can made more similar, with no need for `catch_unwind`. This also lets us simplify an `Option>` to `Vec`. --- src/parse/parser.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 7adf339b453..6051241309d 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -5,7 +5,7 @@ use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; use rustc_errors::Diag; use rustc_parse::parser::Parser as RawParser; -use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal}; +use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_span::{sym, Span}; use thin_vec::ThinVec; @@ -51,12 +51,9 @@ impl<'a> ParserBuilder<'a> { let parser = match Self::parser(psess.inner(), input) { Ok(p) => p, - Err(db) => { - if let Some(diagnostics) = db { - psess.emit_diagnostics(diagnostics); - return Err(ParserError::ParserCreationError); - } - return Err(ParserError::ParsePanicError); + Err(diagnostics) => { + psess.emit_diagnostics(diagnostics); + return Err(ParserError::ParserCreationError); } }; @@ -66,18 +63,14 @@ impl<'a> ParserBuilder<'a> { fn parser( psess: &'a rustc_session::parse::ParseSess, input: Input, - ) -> Result, Option>>> { + ) -> Result, Vec>> { match input { - Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { - unwrap_or_emit_fatal(new_parser_from_file(psess, file, None)) - })) - .map_err(|_| None), - Input::Text(text) => rustc_parse::new_parser_from_source_str( + Input::File(ref file) => new_parser_from_file(psess, file, None), + Input::Text(text) => new_parser_from_source_str( psess, rustc_span::FileName::Custom("stdin".to_owned()), text, - ) - .map_err(Some), + ), } } } From 783a411f671e1c9aa580b33b0288d9c16e094a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 6 Jun 2024 20:39:54 +0000 Subject: [PATCH 59/66] Revert "Rollup merge of #124099 - voidc:disallow-ambiguous-expr-attrs, r=davidtwco" This reverts commit 57dad1d75e562ff73051c1c43b07eaf65c7dbd74, reversing changes made to 36316df9fe6c3e246153fe6e78967643cf08c148. --- tests/source/attrib.rs | 4 ++-- tests/target/attrib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/source/attrib.rs b/tests/source/attrib.rs index fc13cd02b03..d45fba55224 100644 --- a/tests/source/attrib.rs +++ b/tests/source/attrib.rs @@ -214,8 +214,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo ; - (#[must_use] - foo) = false ; + #[must_use] + foo = false ; } // #3509 diff --git a/tests/target/attrib.rs b/tests/target/attrib.rs index 7b3309676de..7e61f68d76a 100644 --- a/tests/target/attrib.rs +++ b/tests/target/attrib.rs @@ -248,8 +248,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo; - (#[must_use] - foo) = false; + #[must_use] + foo = false; } // #3509 From afa731e42f0011ff8e9d16233c466ecee78651b6 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 12 Jun 2024 22:38:19 -0400 Subject: [PATCH 60/66] bump toolchain to nightly-2024-06-13 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index aa35a7f12d5..25e3961d32a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-12-28" +channel = "nightly-2024-06-13" components = ["llvm-tools", "rustc-dev"] From 2db10950fe407ae5cf561fbb30a31e120a58b1ee Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 6 Jun 2024 23:10:29 -0400 Subject: [PATCH 61/66] allow dead code for `StyleEditionDefault` We need to allow `StyleEditionDefault` because it will be used to implement `style_edition`, but that work is currently ongoing. --- src/config/style_edition.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config/style_edition.rs b/src/config/style_edition.rs index 4dd5f0164fa..7b3ea3bc119 100644 --- a/src/config/style_edition.rs +++ b/src/config/style_edition.rs @@ -1,6 +1,7 @@ use crate::config::StyleEdition; /// Defines the default value for the given style edition +#[allow(dead_code)] pub(crate) trait StyleEditionDefault { type ConfigType; fn style_edition_default(style_edition: StyleEdition) -> Self::ConfigType; From acc687735a48b4a1158e621b1bf5a2bcd2c437ea Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 6 Jun 2024 23:13:48 -0400 Subject: [PATCH 62/66] Bumped bytecount 0.6.4 -> 0.6.8 fixes compilation issues with the `generic-simd` feature --- CHANGELOG.md | 4 ++++ Cargo.lock | 33 ++------------------------------- Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5897b1fb378..6d1701f90d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## [Unreleased] - Updating `dirs 4.0.0 -> 5.0.1` and `cargo_metadata 0.15.4 -> 0.18.0` [#6033] (https://github.com/rust-lang/rustfmt/issues/6033) +- Bumped bytecount `0.6.4` -> `0.6.8` to fix compilation issues with the `generic-simd` feature. See [bytecount#92] and [bytecount#93] + +[bytecount#92]: https://github.com/llogiq/bytecount/pull/92 +[bytecount#93]: https://github.com/llogiq/bytecount/pull/93 ## [1.7.0] 2023-10-22 diff --git a/Cargo.lock b/Cargo.lock index b5032945e7e..3d0233f4cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,12 +98,9 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.4" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7" -dependencies = [ - "packed_simd", -] +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "camino" @@ -369,12 +366,6 @@ version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - [[package]] name = "log" version = "0.4.16" @@ -409,16 +400,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", - "libm", -] - [[package]] name = "once_cell" version = "1.17.1" @@ -437,16 +418,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "packed_simd" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d" -dependencies = [ - "cfg-if", - "num-traits", -] - [[package]] name = "pin-project-lite" version = "0.2.9" diff --git a/Cargo.toml b/Cargo.toml index c98200c23d4..5cd9193166c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ generic-simd = ["bytecount/generic-simd"] [dependencies] annotate-snippets = { version = "0.9", features = ["color"] } anyhow = "1.0" -bytecount = "0.6.4" +bytecount = "0.6.8" cargo_metadata = "0.18" clap = { version = "4.4.2", features = ["derive"] } clap-cargo = "0.12.0" From 8c4c336e37dd2125a23532111b11f6551205825e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 19 Apr 2024 23:46:37 -0400 Subject: [PATCH 63/66] remove archived `error-chain` crate from integration tests Can't run `cargo test --all` for `error-chain` anymore. The tests don't compile because of `#[deny(invalid_doc_attributes)]`. Here's the error message: ``` error: this attribute can only be applied at the crate level --> tests/tests.rs:508:7 | 508 | #[doc(test)] | ^^^^ | = note: read for more information = note: `#[deny(invalid_doc_attributes)]` on by default help: to apply to the crate, use an inner attribute | 508 | #![doc(test)] | + ``` --- .github/workflows/integration.yml | 1 - ci/integration.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 314ce0e84c6..f0dd0cf73bb 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -19,7 +19,6 @@ jobs: matrix: integration: [ bitflags, - error-chain, log, mdbook, packed_simd, diff --git a/ci/integration.sh b/ci/integration.sh index 19d502bc5c7..ea96e4be130 100755 --- a/ci/integration.sh +++ b/ci/integration.sh @@ -104,7 +104,7 @@ case ${INTEGRATION} in check_fmt_with_all_tests cd - ;; - error-chain | tempdir) + tempdir) git clone --depth=1 https://github.com/rust-lang-deprecated/${INTEGRATION}.git cd ${INTEGRATION} show_head From 8e80f8aa3a2395d2bab4c4f62957fedf97da35b2 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 6 May 2024 13:26:54 -0400 Subject: [PATCH 64/66] don't apply formatting to builtin type ascription syntax The syntax changed from `expr: ty` -> `builtin # type_ascribe(expr, ty)` For now, rustfmt will just emit the contents of the span. --- CHANGELOG.md | 7 +++++++ src/expr.rs | 9 +-------- tests/target/issue_6159.rs | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 tests/target/issue_6159.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d1701f90d7..fdb671ad4c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ [bytecount#92]: https://github.com/llogiq/bytecount/pull/92 [bytecount#93]: https://github.com/llogiq/bytecount/pull/93 +- Output correct syntax for type ascription builtin [#6159](https://github.com/rust-lang/rustfmt/issues/6159) + ```rust + fn main() { + builtin # type_ascribe(10, usize) + } + ``` + ## [1.7.0] 2023-10-22 ### Fixed diff --git a/src/expr.rs b/src/expr.rs index f2fb2b4a83a..8266f95fd70 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -263,14 +263,6 @@ pub(crate) fn format_expr( shape, SeparatorPlace::Front, ), - ast::ExprKind::Type(ref expr, ref ty) => rewrite_pair( - &**expr, - &**ty, - PairParts::infix(": "), - context, - shape, - SeparatorPlace::Back, - ), ast::ExprKind::Index(ref expr, ref index, _) => { rewrite_index(&**expr, &**index, context, shape) } @@ -412,6 +404,7 @@ pub(crate) fn format_expr( } ast::ExprKind::Underscore => Some("_".to_owned()), ast::ExprKind::FormatArgs(..) + | ast::ExprKind::Type(..) | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::OffsetOf(..) => { // These don't normally occur in the AST because macros aren't expanded. However, diff --git a/tests/target/issue_6159.rs b/tests/target/issue_6159.rs new file mode 100644 index 00000000000..49fd539d3ef --- /dev/null +++ b/tests/target/issue_6159.rs @@ -0,0 +1,3 @@ +fn main() { + builtin # type_ascribe(10, usize) +} From 8abbcad9384ff9004d3da315e0c7392a0d2241fa Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 12 Jun 2024 23:53:53 -0400 Subject: [PATCH 65/66] format #![feature(unsafe_attributes)] Our diff-check job was failing in part due to removing `unsafe` from any `#[unsafe(attributes)]`. To prevent that I added a quick implementation for this. --- src/attr.rs | 16 +++++++++++---- tests/target/unsafe_attributes.rs | 34 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/target/unsafe_attributes.rs diff --git a/src/attr.rs b/src/attr.rs index 83f59837d44..433b9256202 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -353,10 +353,18 @@ impl Rewrite for ast::Attribute { // 1 = `[` let shape = shape.offset_left(prefix.len() + 1)?; - Some( - meta.rewrite(context, shape) - .map_or_else(|| snippet.to_owned(), |rw| format!("{}[{}]", prefix, rw)), - ) + Some(meta.rewrite(context, shape).map_or_else( + || snippet.to_owned(), + |rw| match &self.kind { + ast::AttrKind::Normal(normal_attr) => match normal_attr.item.unsafety { + // For #![feature(unsafe_attributes)] + // See https://github.com/rust-lang/rust/issues/123757 + ast::Safety::Unsafe(_) => format!("{}[unsafe({})]", prefix, rw), + _ => format!("{}[{}]", prefix, rw), + }, + _ => format!("{}[{}]", prefix, rw), + }, + )) } else { Some(snippet.to_owned()) } diff --git a/tests/target/unsafe_attributes.rs b/tests/target/unsafe_attributes.rs new file mode 100644 index 00000000000..a05bedc751a --- /dev/null +++ b/tests/target/unsafe_attributes.rs @@ -0,0 +1,34 @@ +#![feature(unsafe_attributes)] +// https://github.com/rust-lang/rust/issues/123757 +// +#![simple_ident] +#![simple::path] +#![simple_ident_expr = ""] +#![simple::path::Expr = ""] +#![simple_ident_tt(a b c)] +#![simple_ident_tt[a b c]] +#![simple_ident_tt{a b c}] +#![simple::path::tt(a b c)] +#![simple::path::tt[a b c]] +#![simple::path::tt{a b c}] +#![unsafe(simple_ident)] +#![unsafe(simple::path)] +#![unsafe(simple_ident_expr = "")] +#![unsafe(simple::path::Expr = "")] +#![unsafe(simple_ident_tt(a b c))] +#![unsafe(simple_ident_tt[a b c])] +#![unsafe(simple_ident_tt{a b c})] +#![unsafe(simple::path::tt(a b c))] +#![unsafe(simple::path::tt[a b c])] +#![unsafe(simple::path::tt{a b c})] +// I don't think `safe` attributes are a thing, but adding these formatting cases here just in case +#![safe(simple_ident)] +#![safe(simple::path)] +#![safe(simple_ident_expr = "")] +#![safe(simple::path::Expr = "")] +#![safe(simple_ident_tt(a b c))] +#![safe(simple_ident_tt[a b c])] +#![safe(simple_ident_tt{a b c})] +#![safe(simple::path::tt(a b c))] +#![safe(simple::path::tt[a b c])] +#![safe(simple::path::tt{a b c})] From 30eb54b5cafd78eca990bc8067e6cf18b2712b7c Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 13 Jun 2024 00:43:21 -0400 Subject: [PATCH 66/66] Add `config_proc_macro` to system tests Also formats unforamatted files in the crate. --- config_proc_macro/src/attrs.rs | 6 +++++- src/test/mod.rs | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/config_proc_macro/src/attrs.rs b/config_proc_macro/src/attrs.rs index d8de9aae088..e7534b813d7 100644 --- a/config_proc_macro/src/attrs.rs +++ b/config_proc_macro/src/attrs.rs @@ -68,7 +68,11 @@ fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option { match &attr.meta { syn::Meta::NameValue(syn::MetaNameValue { path, - value: syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit_str), .. }), + value: + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit_str), + .. + }), .. }) if path.is_ident(name) => Some(lit_str.value()), _ => None, diff --git a/src/test/mod.rs b/src/test/mod.rs index d567a1b8e4e..7c563801c32 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -391,12 +391,24 @@ fn self_tests() { files.push(path); } // for crates that need to be included but lies outside src - let external_crates = vec!["check_diff"]; + let external_crates = vec!["check_diff", "config_proc_macro"]; for external_crate in external_crates { let mut path = PathBuf::from(external_crate); path.push("src"); - path.push("main.rs"); - files.push(path); + let directory = fs::read_dir(&path).unwrap(); + let search_files = directory.filter_map(|file| { + file.ok().and_then(|f| { + let name = f.file_name(); + if matches!(name.as_os_str().to_str(), Some("main.rs" | "lib.rs")) { + Some(f.path()) + } else { + None + } + }) + }); + for file in search_files { + files.push(file); + } } files.push(PathBuf::from("src/lib.rs"));