From ae760e695c605598b9563503a4f6a6618d64d5af Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Wed, 29 Nov 2023 15:39:20 -0500 Subject: [PATCH 01/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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/46] 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 6e4105f7e97a1aae9543204d41afd4b7c11b60d4 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 7 Apr 2024 22:10:47 -0400 Subject: [PATCH 42/46] fix dead code and redundant import warnings We need to allow `StyleEditionDefault` because it will be used to implement `style_edition`, and we didn't need to explicitly import it for tests since it's already imported by `use super::*;`. --- src/config/style_edition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/style_edition.rs b/src/config/style_edition.rs index 4dd5f0164fa..96e979443ae 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; @@ -39,7 +40,6 @@ macro_rules! style_edition_default { #[cfg(test)] mod test { use super::*; - use crate::config::StyleEdition; #[test] fn test_impl_default_style_edition_struct_for_all_editions() { From 9ede6261417bd77ce88676884b1e223d61760d4e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 7 Apr 2024 22:14:08 -0400 Subject: [PATCH 43/46] bump rust toolchain to nightly-2024-04-08 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index aa35a7f12d5..3c1fa544c64 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-12-28" +channel = "nightly-2024-04-08" components = ["llvm-tools", "rustc-dev"] From 732855d1b36688d942c33c17bac93c4ee7a7d852 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 19 Apr 2024 21:28:18 -0400 Subject: [PATCH 44/46] Bumped bytecount `0.6.4` -> `0.6.8` fixes compilation issues with the `generic-simd` feature --- CHANGELOG.md | 5 +++++ Cargo.lock | 33 ++------------------------------- Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5897b1fb378..22af34cdde2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ ## [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 7465a4f9521..90f74607daa 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 bcd3b420acb..af1a6c3f56a 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 919fb28407fc226de806fea8364deef0117a0aeb Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 19 Apr 2024 23:46:37 -0400 Subject: [PATCH 45/46] 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 35ad744be140f2d4c3c0c22eb986efe2303cf8f2 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 6 May 2024 13:26:54 -0400 Subject: [PATCH 46/46] 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 | 6 ++++++ src/expr.rs | 9 +-------- tests/target/issue_6159.rs | 3 +++ 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 tests/target/issue_6159.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 22af34cdde2..fdb671ad4c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ [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 diff --git a/src/expr.rs b/src/expr.rs index 4f7b88da6b2..7af3acc6708 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -253,14 +253,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) } @@ -402,6 +394,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) +}