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.)
This commit is contained in:
parent
d02150fd45
commit
6656413a5c
@ -82,7 +82,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
|
|||||||
Ok(..) => {}
|
Ok(..) => {}
|
||||||
Err(err) => err.cancel(),
|
Err(err) => err.cancel(),
|
||||||
},
|
},
|
||||||
Err(errs) => drop(errs),
|
Err(errs) => errs.into_iter().for_each(|err| err.cancel()),
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user tried to use a key="value" flag, but is missing the quotes, provide
|
// If the user tried to use a key="value" flag, but is missing the quotes, provide
|
||||||
@ -129,9 +129,12 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
|
|||||||
error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
|
error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(mut parser) = maybe_new_parser_from_source_str(&sess, filename, s.to_string())
|
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
|
||||||
else {
|
Ok(parser) => parser,
|
||||||
|
Err(errs) => {
|
||||||
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
expected_error();
|
expected_error();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let meta_item = match parser.parse_meta_item() {
|
let meta_item = match parser.parse_meta_item() {
|
||||||
|
@ -7,7 +7,7 @@ use rustc_ast::ast::{self, AttrStyle};
|
|||||||
use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::util::unicode::contains_text_flow_control_chars;
|
use rustc_ast::util::unicode::contains_text_flow_control_chars;
|
||||||
use rustc_errors::{error_code, Applicability, DiagCtxt, Diagnostic, StashKey};
|
use rustc_errors::{error_code, Applicability, DiagCtxt, DiagnosticBuilder, StashKey};
|
||||||
use rustc_lexer::unescape::{self, EscapeError, Mode};
|
use rustc_lexer::unescape::{self, EscapeError, Mode};
|
||||||
use rustc_lexer::{Base, DocStyle, RawStrError};
|
use rustc_lexer::{Base, DocStyle, RawStrError};
|
||||||
use rustc_lexer::{Cursor, LiteralKind};
|
use rustc_lexer::{Cursor, LiteralKind};
|
||||||
@ -47,7 +47,7 @@ pub(crate) fn parse_token_trees<'sess, 'src>(
|
|||||||
mut src: &'src str,
|
mut src: &'src str,
|
||||||
mut start_pos: BytePos,
|
mut start_pos: BytePos,
|
||||||
override_span: Option<Span>,
|
override_span: Option<Span>,
|
||||||
) -> Result<TokenStream, Vec<Diagnostic>> {
|
) -> Result<TokenStream, Vec<DiagnosticBuilder<'sess>>> {
|
||||||
// Skip `#!`, if present.
|
// Skip `#!`, if present.
|
||||||
if let Some(shebang_len) = rustc_lexer::strip_shebang(src) {
|
if let Some(shebang_len) = rustc_lexer::strip_shebang(src) {
|
||||||
src = &src[shebang_len..];
|
src = &src[shebang_len..];
|
||||||
@ -76,13 +76,13 @@ pub(crate) fn parse_token_trees<'sess, 'src>(
|
|||||||
let mut buffer = Vec::with_capacity(1);
|
let mut buffer = Vec::with_capacity(1);
|
||||||
for unmatched in unmatched_delims {
|
for unmatched in unmatched_delims {
|
||||||
if let Some(err) = make_unclosed_delims_error(unmatched, sess) {
|
if let Some(err) = make_unclosed_delims_error(unmatched, sess) {
|
||||||
err.buffer(&mut buffer);
|
buffer.push(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Err(errs) = res {
|
if let Err(errs) = res {
|
||||||
// Add unclosing delimiter or diff marker errors
|
// Add unclosing delimiter or diff marker errors
|
||||||
for err in errs {
|
for err in errs {
|
||||||
err.buffer(&mut buffer);
|
buffer.push(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(buffer)
|
Err(buffer)
|
||||||
|
@ -19,7 +19,7 @@ use rustc_ast::tokenstream::TokenStream;
|
|||||||
use rustc_ast::{AttrItem, Attribute, MetaItem};
|
use rustc_ast::{AttrItem, Attribute, MetaItem};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Diagnostic, PResult};
|
use rustc_errors::{DiagnosticBuilder, FatalError, PResult};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::{FileName, SourceFile, Span};
|
use rustc_span::{FileName, SourceFile, Span};
|
||||||
|
|
||||||
@ -45,14 +45,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
|||||||
/// A variant of 'panictry!' that works on a `Vec<Diagnostic>` instead of a single
|
/// A variant of 'panictry!' that works on a `Vec<Diagnostic>` instead of a single
|
||||||
/// `DiagnosticBuilder`.
|
/// `DiagnosticBuilder`.
|
||||||
macro_rules! panictry_buffer {
|
macro_rules! panictry_buffer {
|
||||||
($handler:expr, $e:expr) => {{
|
($e:expr) => {{
|
||||||
use rustc_errors::FatalError;
|
|
||||||
use std::result::Result::{Err, Ok};
|
use std::result::Result::{Err, Ok};
|
||||||
match $e {
|
match $e {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
for e in errs {
|
for e in errs {
|
||||||
$handler.emit_diagnostic(e);
|
e.emit();
|
||||||
}
|
}
|
||||||
FatalError.raise()
|
FatalError.raise()
|
||||||
}
|
}
|
||||||
@ -100,16 +99,17 @@ pub fn parse_stream_from_source_str(
|
|||||||
|
|
||||||
/// Creates a new parser from a source string.
|
/// Creates a new parser from a source string.
|
||||||
pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
|
pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
|
||||||
panictry_buffer!(&sess.dcx, maybe_new_parser_from_source_str(sess, name, source))
|
panictry_buffer!(maybe_new_parser_from_source_str(sess, name, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new parser from a source string. Returns any buffered errors from lexing the initial
|
/// Creates a new parser from a source string. Returns any buffered errors from lexing the initial
|
||||||
/// token stream.
|
/// 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(
|
pub fn maybe_new_parser_from_source_str(
|
||||||
sess: &ParseSess,
|
sess: &ParseSess,
|
||||||
name: FileName,
|
name: FileName,
|
||||||
source: String,
|
source: String,
|
||||||
) -> Result<Parser<'_>, Vec<Diagnostic>> {
|
) -> Result<Parser<'_>, Vec<DiagnosticBuilder<'_>>> {
|
||||||
maybe_source_file_to_parser(sess, sess.source_map().new_source_file(name, source))
|
maybe_source_file_to_parser(sess, sess.source_map().new_source_file(name, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Spa
|
|||||||
err.emit();
|
err.emit();
|
||||||
});
|
});
|
||||||
|
|
||||||
panictry_buffer!(&sess.dcx, maybe_source_file_to_parser(sess, source_file))
|
panictry_buffer!(maybe_source_file_to_parser(sess, source_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
|
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
|
||||||
@ -133,7 +133,7 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Spa
|
|||||||
fn maybe_source_file_to_parser(
|
fn maybe_source_file_to_parser(
|
||||||
sess: &ParseSess,
|
sess: &ParseSess,
|
||||||
source_file: Lrc<SourceFile>,
|
source_file: Lrc<SourceFile>,
|
||||||
) -> Result<Parser<'_>, Vec<Diagnostic>> {
|
) -> Result<Parser<'_>, Vec<DiagnosticBuilder<'_>>> {
|
||||||
let end_pos = source_file.end_position();
|
let end_pos = source_file.end_position();
|
||||||
let stream = maybe_file_to_stream(sess, source_file, None)?;
|
let stream = maybe_file_to_stream(sess, source_file, None)?;
|
||||||
let mut parser = stream_to_parser(sess, stream, None);
|
let mut parser = stream_to_parser(sess, stream, None);
|
||||||
@ -152,16 +152,16 @@ pub fn source_file_to_stream(
|
|||||||
source_file: Lrc<SourceFile>,
|
source_file: Lrc<SourceFile>,
|
||||||
override_span: Option<Span>,
|
override_span: Option<Span>,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
panictry_buffer!(&sess.dcx, maybe_file_to_stream(sess, source_file, override_span))
|
panictry_buffer!(maybe_file_to_stream(sess, source_file, override_span))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a source file, produces a sequence of token trees. Returns any buffered errors from
|
/// Given a source file, produces a sequence of token trees. Returns any buffered errors from
|
||||||
/// parsing the token stream.
|
/// parsing the token stream.
|
||||||
fn maybe_file_to_stream(
|
fn maybe_file_to_stream<'sess>(
|
||||||
sess: &ParseSess,
|
sess: &'sess ParseSess,
|
||||||
source_file: Lrc<SourceFile>,
|
source_file: Lrc<SourceFile>,
|
||||||
override_span: Option<Span>,
|
override_span: Option<Span>,
|
||||||
) -> Result<TokenStream, Vec<Diagnostic>> {
|
) -> Result<TokenStream, Vec<DiagnosticBuilder<'sess>>> {
|
||||||
let src = source_file.src.as_ref().unwrap_or_else(|| {
|
let src = source_file.src.as_ref().unwrap_or_else(|| {
|
||||||
sess.dcx.bug(format!(
|
sess.dcx.bug(format!(
|
||||||
"cannot lex `source_file` without source: {}",
|
"cannot lex `source_file` without source: {}",
|
||||||
|
@ -69,8 +69,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
|
|||||||
let mut parser =
|
let mut parser =
|
||||||
match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
|
match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
|
||||||
Ok(parser) => parser,
|
Ok(parser) => parser,
|
||||||
Err(diagnostics) => {
|
Err(errs) => {
|
||||||
drop(diagnostics);
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -589,7 +589,7 @@ pub(crate) fn make_test(
|
|||||||
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
|
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
drop(errs);
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
return (found_main, found_extern_crate, found_macro);
|
return (found_main, found_extern_crate, found_macro);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -759,8 +759,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
|
|||||||
let mut parser =
|
let mut parser =
|
||||||
match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) {
|
match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(_) => {
|
Err(errs) => {
|
||||||
// If there is an unclosed delimiter, an error will be returned by the tokentrees.
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
|
// If there is an unclosed delimiter, an error will be returned by the
|
||||||
|
// tokentrees.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -53,7 +53,7 @@ pub fn check(
|
|||||||
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
|
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
drop(errs);
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
return (false, test_attr_spans);
|
return (false, test_attr_spans);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
|
|||||||
|
|
||||||
use rustc_ast::token::TokenKind;
|
use rustc_ast::token::TokenKind;
|
||||||
use rustc_ast::{ast, attr, ptr};
|
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_parse::{new_parser_from_file, parser::Parser as RawParser};
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
use thin_vec::ThinVec;
|
use thin_vec::ThinVec;
|
||||||
@ -65,7 +65,7 @@ impl<'a> ParserBuilder<'a> {
|
|||||||
fn parser(
|
fn parser(
|
||||||
sess: &'a rustc_session::parse::ParseSess,
|
sess: &'a rustc_session::parse::ParseSess,
|
||||||
input: Input,
|
input: Input,
|
||||||
) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diagnostic>>> {
|
) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<DiagnosticBuilder<'a>>>> {
|
||||||
match input {
|
match input {
|
||||||
Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
|
Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
|
||||||
new_parser_from_file(sess, file, None)
|
new_parser_from_file(sess, file, None)
|
||||||
|
@ -4,7 +4,9 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
||||||
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
|
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
|
||||||
use rustc_errors::translation::Translate;
|
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_session::parse::ParseSess as RawParseSess;
|
||||||
use rustc_span::{
|
use rustc_span::{
|
||||||
source_map::{FilePathMapping, SourceMap},
|
source_map::{FilePathMapping, SourceMap},
|
||||||
@ -283,9 +285,9 @@ impl ParseSess {
|
|||||||
|
|
||||||
// Methods that should be restricted within the parse module.
|
// Methods that should be restricted within the parse module.
|
||||||
impl ParseSess {
|
impl ParseSess {
|
||||||
pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) {
|
pub(super) fn emit_diagnostics(&self, diagnostics: Vec<DiagnosticBuilder<'_>>) {
|
||||||
for diagnostic in diagnostics {
|
for diagnostic in diagnostics {
|
||||||
self.parse_sess.dcx.emit_diagnostic(diagnostic);
|
diagnostic.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user