Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
cc
Probably a duplicate of , and hopefully will be fixed by .
no, I checked, while is fixed, this one isn't :(

Discussion:
let main_file = input.file_name(); let input_is_stdin = main_file == FileName::Stdin; <del> let parse_session = ParseSess::new(config)?; </del> <ins> let mut parse_session = ParseSess::new(config)?; </ins> if config.skip_children() && parse_session.ignore_file(&main_file) { return Ok(FormatReport::new()); }

// Parse the crate. let mut report = FormatReport::new(); let directory_ownership = input.to_directory_ownership(); <del> 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; </del> <ins> // 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, }; </ins> should_emit_verbose(forbid_verbose, config, || { eprintln!("The Rust parser panicked"); });

fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> { let mut parser = AssertUnwindSafe(&mut self.parser); <del> // 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(); </del> let err = Err(ParserError::ParsePanicError); <del> match (parse_res, stashed_res) { (Ok(Ok(k)), None) => Ok(k), (Ok(Ok(_)), Some(_guar)) => err, (Ok(Err(db)), _) => { </del> <ins> match catch_unwind(move || parser.parse_crate_mod()) { Ok(Ok(k)) => Ok(k), Ok(Err(db)) => { </ins> db.emit(); err } <del> (Err(_), _) => err, </del> <ins> Err(_) => err, </ins> } } }

use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ <del> ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel, </del> <ins> ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel, </ins> }; use rustc_session::parse::ParseSess as RawParseSess; use rustc_span::{

self.ignore_path_set.as_ref().is_match(path) } <ins> pub(crate) fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> { self.parse_sess.dcx.emit_stashed_diagnostics() } </ins> pub(crate) fn set_silent_emitter(&mut self) { self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter()); }

let filename = "tests/parser/stashed-diag.rs"; assert_parser_error(filename); } <ins> #[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); } </ins>

<ins> trait Trait<'1> { s> {} fn main() {} </ins>