about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-05-31 15:43:18 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2024-06-05 10:38:03 +1000
commitb9037339cbc636349b02088486effa21f9ab16aa (patch)
treee9831c4f2b34a5fcfd515679936bcb4878104301
parent264dbe4d8145c076557a95a93183b8c1d6e1f564 (diff)
downloadrust-b9037339cbc636349b02088486effa21f9ab16aa.tar.gz
rust-b9037339cbc636349b02088486effa21f9ab16aa.zip
Make top-level `rustc_parse` functions fallible.
Currently we have an awkward mix of fallible and infallible functions:
```
       new_parser_from_source_str
 maybe_new_parser_from_source_str
       new_parser_from_file
(maybe_new_parser_from_file)        // missing
      (new_parser_from_source_file) // missing
 maybe_new_parser_from_source_file
       source_str_to_stream
 maybe_source_file_to_stream
```
We could add the two missing functions, but instead this commit removes
of all the infallible ones and renames the fallible ones leaving us with
these which are all fallible:
```
new_parser_from_source_str
new_parser_from_file
new_parser_from_source_file
source_str_to_stream
source_file_to_stream
```
This requires making `unwrap_or_emit_fatal` public so callers of
formerly infallible functions can still work.

This does make some of the call sites slightly more verbose, but I think
it's worth it for the simpler API. Also, there are two `catch_unwind`
calls and one `catch_fatal_errors` call in this diff that become
removable thanks this change. (I will do that in a follow-up PR.)
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs4
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs6
-rw-r--r--compiler/rustc_expand/src/module.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs9
-rw-r--r--compiler/rustc_interface/src/interface.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs8
-rw-r--r--compiler/rustc_parse/src/lib.rs54
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs22
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs2
-rw-r--r--src/librustdoc/doctest.rs23
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs10
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs4
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs7
16 files changed, 105 insertions, 75 deletions
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index ada82e45712..e9b63b4abeb 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -4,16 +4,17 @@ use crate::errors;
 use rustc_ast::attr::mk_attr;
 use rustc_ast::token;
 use rustc_ast::{self as ast, AttrItem, AttrStyle};
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::FileName;
 
 pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
     for raw_attr in attrs {
-        let mut parser = rustc_parse::new_parser_from_source_str(
+        let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
             psess,
             FileName::cli_crate_attr_source_code(raw_attr),
             raw_attr.clone(),
-        );
+        ));
 
         let start_span = parser.token.span;
         let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 29e991525a9..dc1d82df0c3 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -12,8 +12,8 @@ use rustc_expand::base::{
 };
 use rustc_expand::module::DirOwnership;
 use rustc_lint_defs::BuiltinLintDiag;
-use rustc_parse::new_parser_from_file;
 use rustc_parse::parser::{ForceCollect, Parser};
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Symbol;
@@ -126,7 +126,7 @@ pub(crate) fn expand_include<'cx>(
             return ExpandResult::Ready(DummyResult::any(sp, guar));
         }
     };
-    let p = new_parser_from_file(cx.psess(), &file, Some(sp));
+    let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp)));
 
     // If in the included file we have e.g., `mod bar;`,
     // then the path of `bar.rs` should be relative to the directory of `file`.
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 236880420fc..93a65290602 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -32,7 +32,7 @@ use rustc_interface::{interface, Queries};
 use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
-use rustc_parse::{new_parser_from_file, new_parser_from_source_str};
+use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType};
 use rustc_session::getopts::{self, Matches};
@@ -1265,12 +1265,12 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
 }
 
 fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
-    let mut parser = match &sess.io.input {
+    let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
         Input::File(file) => new_parser_from_file(&sess.psess, file, None),
         Input::Str { name, input } => {
             new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
         }
-    };
+    });
     parser.parse_inner_attributes()
 }
 
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index c8983619e70..506bd445be3 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -5,8 +5,8 @@ use crate::errors::{
 use rustc_ast::ptr::P;
 use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
 use rustc_errors::{Diag, ErrorGuaranteed};
-use rustc_parse::new_parser_from_file;
 use rustc_parse::validate_attr;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
@@ -66,7 +66,8 @@ pub(crate) fn parse_external_mod(
         }
 
         // Actually parse the external file as a module.
-        let mut parser = new_parser_from_file(&sess.psess, &mp.file_path, Some(span));
+        let mut parser =
+            unwrap_or_emit_fatal(new_parser_from_file(&sess.psess, &mp.file_path, Some(span)));
         let (inner_attrs, items, inner_span) =
             parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
         attrs.extend(inner_attrs);
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 330a6c34770..93f8682090d 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -14,7 +14,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
 use rustc_parse::lexer::nfc_normalize;
 use rustc_parse::parser::Parser;
-use rustc_parse::source_str_to_stream;
+use rustc_parse::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::def_id::CrateNum;
 use rustc_span::symbol::{self, sym, Symbol};
@@ -467,7 +467,8 @@ impl server::FreeFunctions for Rustc<'_, '_> {
 
     fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
         let name = FileName::proc_macro_source_code(s);
-        let mut parser = rustc_parse::new_parser_from_source_str(self.psess(), name, s.to_owned());
+        let mut parser =
+            unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned()));
 
         let first_span = parser.token.span.data();
         let minus_present = parser.eat(&token::BinOp(token::Minus));
@@ -539,12 +540,12 @@ impl server::TokenStream for Rustc<'_, '_> {
     }
 
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        source_str_to_stream(
+        unwrap_or_emit_fatal(source_str_to_stream(
             self.psess(),
             FileName::proc_macro_source_code(src),
             src.to_string(),
             Some(self.call_site),
-        )
+        ))
     }
 
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 5254a6576f9..c95a10f4e8d 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,7 +14,7 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_middle::ty::CurrentGcx;
 use rustc_middle::util::Providers;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
 use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
@@ -67,7 +67,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
                 };
             }
 
-            match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+            match new_parser_from_source_str(&psess, filename, s.to_string()) {
                 Ok(mut parser) => match parser.parse_meta_item() {
                     Ok(meta_item) if parser.token == token::Eof => {
                         if meta_item.path.segments.len() != 1 {
@@ -166,7 +166,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
             error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
         };
 
-        let mut parser = match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+        let mut parser = match new_parser_from_source_str(&psess, filename, s.to_string()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index b3ed6622097..a342577cffb 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -19,7 +19,9 @@ use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
-use rustc_parse::{new_parser_from_file, new_parser_from_source_str, validate_attr};
+use rustc_parse::{
+    new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
+};
 use rustc_passes::{abi_test, hir_stats, layout_test};
 use rustc_resolve::Resolver;
 use rustc_session::code_stats::VTableSizeInfo;
@@ -43,12 +45,12 @@ use tracing::{info, instrument};
 
 pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
     let krate = sess.time("parse_crate", || {
-        let mut parser = match &sess.io.input {
+        let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
             Input::File(file) => new_parser_from_file(&sess.psess, file, None),
             Input::Str { input, name } => {
                 new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
             }
-        };
+        });
         parser.parse_crate_mod()
     })?;
 
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 8a061ce8f1b..b316327a262 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -35,7 +35,7 @@ mod errors;
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 // Unwrap the result if `Ok`, otherwise emit the diagnostics and abort.
-fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
+pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
     match expr {
         Ok(expr) => expr,
         Err(errs) => {
@@ -47,25 +47,28 @@ fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
     }
 }
 
-/// Creates a new parser from a source string.
-pub fn new_parser_from_source_str(psess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
-    unwrap_or_emit_fatal(maybe_new_parser_from_source_str(psess, name, source))
-}
-
-/// Creates a new parser from a source string. Returns any buffered errors from lexing the initial
-/// token stream; these must be consumed via `emit`, `cancel`, etc., otherwise a panic will occur
-/// when they are dropped.
-pub fn maybe_new_parser_from_source_str(
+/// Creates a new parser from a source string. On failure, the errors must be consumed via
+/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
+/// dropped.
+pub fn new_parser_from_source_str(
     psess: &ParseSess,
     name: FileName,
     source: String,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
-    maybe_new_parser_from_source_file(psess, psess.source_map().new_source_file(name, source))
+    let source_file = psess.source_map().new_source_file(name, source);
+    new_parser_from_source_file(psess, source_file)
 }
 
-/// Creates a new parser, aborting if the file doesn't exist. If a span is given, that is used on
-/// an error as the source of the problem.
-pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
+/// Creates a new parser from a filename. On failure, the errors must be consumed via
+/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
+/// dropped.
+///
+/// If a span is given, that is used on an error as the source of the problem.
+pub fn new_parser_from_file<'a>(
+    psess: &'a ParseSess,
+    path: &Path,
+    sp: Option<Span>,
+) -> Result<Parser<'a>, Vec<Diag<'a>>> {
     let source_file = psess.source_map().load_file(path).unwrap_or_else(|e| {
         let msg = format!("couldn't read {}: {}", path.display(), e);
         let mut err = psess.dcx.struct_fatal(msg);
@@ -74,23 +77,21 @@ pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Sp
         }
         err.emit();
     });
-
-    unwrap_or_emit_fatal(maybe_new_parser_from_source_file(psess, source_file))
+    new_parser_from_source_file(psess, source_file)
 }
 
 /// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
 /// the initial token stream.
-fn maybe_new_parser_from_source_file(
+fn new_parser_from_source_file(
     psess: &ParseSess,
     source_file: Lrc<SourceFile>,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let end_pos = source_file.end_position();
-    let stream = maybe_source_file_to_stream(psess, source_file, None)?;
+    let stream = source_file_to_stream(psess, source_file, None)?;
     let mut parser = Parser::new(psess, stream, None);
     if parser.token == token::Eof {
         parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt(), None);
     }
-
     Ok(parser)
 }
 
@@ -99,14 +100,14 @@ pub fn source_str_to_stream(
     name: FileName,
     source: String,
     override_span: Option<Span>,
-) -> TokenStream {
+) -> Result<TokenStream, Vec<Diag<'_>>> {
     let source_file = psess.source_map().new_source_file(name, source);
-    unwrap_or_emit_fatal(maybe_source_file_to_stream(psess, source_file, override_span))
+    source_file_to_stream(psess, source_file, override_span)
 }
 
 /// Given a source file, produces a sequence of token trees. Returns any buffered errors from
 /// parsing the token stream.
-fn maybe_source_file_to_stream<'psess>(
+fn source_file_to_stream<'psess>(
     psess: &'psess ParseSess,
     source_file: Lrc<SourceFile>,
     override_span: Option<Span>,
@@ -139,13 +140,18 @@ pub fn parse_in<'a, T>(
 pub fn fake_token_stream_for_item(psess: &ParseSess, item: &ast::Item) -> TokenStream {
     let source = pprust::item_to_string(item);
     let filename = FileName::macro_expansion_source_code(&source);
-    source_str_to_stream(psess, filename, source, Some(item.span))
+    unwrap_or_emit_fatal(source_str_to_stream(psess, filename, source, Some(item.span)))
 }
 
 pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> TokenStream {
     let source = pprust::crate_to_string_for_macros(krate);
     let filename = FileName::macro_expansion_source_code(&source);
-    source_str_to_stream(psess, filename, source, Some(krate.spans.inner_span))
+    unwrap_or_emit_fatal(source_str_to_stream(
+        psess,
+        filename,
+        source,
+        Some(krate.spans.inner_span),
+    ))
 }
 
 pub fn parse_cfg_attr(
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 2900d44089e..79a6cf1b541 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -1,5 +1,7 @@
 use crate::parser::ForceCollect;
-use crate::{new_parser_from_source_str, parser::Parser, source_str_to_stream};
+use crate::{
+    new_parser_from_source_str, parser::Parser, source_str_to_stream, unwrap_or_emit_fatal,
+};
 use ast::token::IdentIsRaw;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token};
@@ -29,7 +31,11 @@ fn psess() -> ParseSess {
 
 /// Map string to parser (via tts).
 fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
-    new_parser_from_source_str(psess, PathBuf::from("bogofile").into(), source_str)
+    unwrap_or_emit_fatal(new_parser_from_source_str(
+        psess,
+        PathBuf::from("bogofile").into(),
+        source_str,
+    ))
 }
 
 fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
@@ -82,7 +88,12 @@ where
 /// Maps a string to tts, using a made-up filename.
 pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
     let psess = psess();
-    source_str_to_stream(&psess, PathBuf::from("bogofile").into(), source_str, None)
+    unwrap_or_emit_fatal(source_str_to_stream(
+        &psess,
+        PathBuf::from("bogofile").into(),
+        source_str,
+        None,
+    ))
 }
 
 /// Parses a string, returns a crate.
@@ -1064,7 +1075,8 @@ fn parse_item_from_source_str(
     source: String,
     psess: &ParseSess,
 ) -> PResult<'_, Option<P<ast::Item>>> {
-    new_parser_from_source_str(psess, name, source).parse_item(ForceCollect::No)
+    unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
+        .parse_item(ForceCollect::No)
 }
 
 // Produces a `rustc_span::span`.
@@ -1345,7 +1357,7 @@ fn ttdelim_span() {
         source: String,
         psess: &ParseSess,
     ) -> PResult<'_, P<ast::Expr>> {
-        new_parser_from_source_str(psess, name, source).parse_expr()
+        unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
     }
 
     create_default_session_globals_then(|| {
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index 5ac1b742c38..995919f73f8 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -65,7 +65,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
     let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
     let file_name = source_map.span_to_filename(span);
     let mut parser =
-        match rustc_parse::maybe_new_parser_from_source_str(&psess, file_name, snippet.clone()) {
+        match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index a536a713921..0d4bad6921d 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -9,7 +9,7 @@ use rustc_interface::interface;
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::attr::InnerAttrPolicy;
 use rustc_resolve::rustdoc::span_of_fragments;
 use rustc_session::config::{self, CrateType, ErrorOutputType};
@@ -638,7 +638,7 @@ pub(crate) fn make_test(
             let mut found_extern_crate = crate_name.is_none();
             let mut found_macro = false;
 
-            let mut parser = match maybe_new_parser_from_source_str(&psess, filename, source) {
+            let mut parser = match new_parser_from_source_str(&psess, filename, source) {
                 Ok(p) => p,
                 Err(errs) => {
                     errs.into_iter().for_each(|err| err.cancel());
@@ -818,16 +818,15 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
 
             let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
             let psess = ParseSess::with_dcx(dcx, sm);
-            let mut parser =
-                match maybe_new_parser_from_source_str(&psess, filename, source.to_owned()) {
-                    Ok(p) => p,
-                    Err(errs) => {
-                        errs.into_iter().for_each(|err| err.cancel());
-                        // If there is an unclosed delimiter, an error will be returned by the
-                        // tokentrees.
-                        return false;
-                    }
-                };
+            let mut parser = match new_parser_from_source_str(&psess, filename, source.to_owned()) {
+                Ok(p) => p,
+                Err(errs) => {
+                    errs.into_iter().for_each(|err| err.cancel());
+                    // If there is an unclosed delimiter, an error will be returned by the
+                    // tokentrees.
+                    return false;
+                }
+            };
             // If a parsing error happened, it's very likely that the attribute is incomplete.
             if let Err(e) = parser.parse_attribute(InnerAttrPolicy::Permitted) {
                 e.cancel();
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 409546734cb..c185442fd55 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -5,7 +5,7 @@ use rustc_errors::{
     translation::{to_fluent_args, Translate},
     Applicability, DiagCtxt, DiagInner, LazyFallbackBundle,
 };
-use rustc_parse::source_str_to_stream;
+use rustc_parse::{source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, Transparency};
@@ -51,8 +51,13 @@ fn check_rust_syntax(
     let span = DUMMY_SP.apply_mark(expn_id.to_expn_id(), Transparency::Transparent);
 
     let is_empty = rustc_driver::catch_fatal_errors(|| {
-        source_str_to_stream(&psess, FileName::Custom(String::from("doctest")), source, Some(span))
-            .is_empty()
+        unwrap_or_emit_fatal(source_str_to_stream(
+            &psess,
+            FileName::Custom(String::from("doctest")),
+            source,
+            Some(span),
+        ))
+        .is_empty()
     })
     .unwrap_or(false);
     let buffer = buffer.borrow();
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index 651f2ebaee6..c3e3c0431e6 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{Diag, DiagCtxt};
 use rustc_lint::LateContext;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -50,7 +50,7 @@ pub fn check(
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
                 let psess = ParseSess::with_dcx(dcx, sm);
 
-                let mut parser = match maybe_new_parser_from_source_str(&psess, filename, code) {
+                let mut parser = match new_parser_from_source_str(&psess, filename, code) {
                     Ok(p) => p,
                     Err(errs) => {
                         errs.into_iter().for_each(Diag::cancel);
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 5dcdca1d953..7adf339b453 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -4,7 +4,8 @@ use std::path::{Path, PathBuf};
 use rustc_ast::token::TokenKind;
 use rustc_ast::{ast, attr, ptr};
 use rustc_errors::Diag;
-use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
+use rustc_parse::parser::Parser as RawParser;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_span::{sym, Span};
 use thin_vec::ThinVec;
 
@@ -68,10 +69,10 @@ impl<'a> ParserBuilder<'a> {
     ) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diag<'a>>>> {
         match input {
             Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
-                new_parser_from_file(psess, file, None)
+                unwrap_or_emit_fatal(new_parser_from_file(psess, file, None))
             }))
             .map_err(|_| None),
-            Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
+            Input::Text(text) => rustc_parse::new_parser_from_source_str(
                 psess,
                 rustc_span::FileName::Custom("stdin".to_owned()),
                 text,
@@ -111,7 +112,8 @@ impl<'a> Parser<'a> {
         span: Span,
     ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
-            let mut parser = new_parser_from_file(psess.inner(), path, Some(span));
+            let mut parser =
+                unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
             match parser.parse_mod(&TokenKind::Eof) {
                 Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
                 Err(e) => {
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index ef70e64ed7e..99cb5fc5aa1 100644
--- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -16,7 +16,7 @@ extern crate rustc_span;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
 
-use rustc_parse::new_parser_from_file;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use std::path::Path;
 
@@ -34,6 +34,6 @@ fn parse() {
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
-    let mut parser = new_parser_from_file(&psess, &path, None);
+    let mut parser = unwrap_or_emit_fatal(new_parser_from_file(&psess, &path, None));
     let _ = parser.parse_crate_mod();
 }
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 2b1fec94387..762ad0b79ec 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -36,7 +36,7 @@ use rustc_ast::mut_visit::{visit_clobber, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust;
-use rustc_parse::new_parser_from_source_str;
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
@@ -46,8 +46,9 @@ use thin_vec::{thin_vec, ThinVec};
 fn parse_expr(psess: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p =
-        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string);
+    let mut p = unwrap_or_emit_fatal(
+        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string)
+    );
     p.parse_expr().map_err(|e| e.cancel()).ok()
 }