Rollup merge of #119841 - nnethercote:rm-DiagnosticBuilder-buffer, r=oli-obk
Remove `DiagnosticBuilder::buffer` `DiagnosticBuilder::buffer` doesn't do much, and part of what it does (for `-Ztreat-err-as-bug`) it shouldn't. This PR strips it back, replaces its uses, and finally removes it, making a few cleanups in the vicinity along the way. r? ``@oli-obk``
This commit is contained in:
commit
f5387a1c38
20 changed files with 119 additions and 159 deletions
|
@ -2399,10 +2399,10 @@ mod error {
|
||||||
/// and we want only the best of those errors.
|
/// and we want only the best of those errors.
|
||||||
///
|
///
|
||||||
/// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
|
/// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
|
||||||
/// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of the
|
/// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of
|
||||||
/// `Place` of the previous most diagnostic. This happens instead of buffering the error. Once
|
/// the `Place` of the previous most diagnostic. This happens instead of buffering the
|
||||||
/// all move errors have been reported, any diagnostics in this map are added to the buffer
|
/// error. Once all move errors have been reported, any diagnostics in this map are added
|
||||||
/// to be emitted.
|
/// to the buffer to be emitted.
|
||||||
///
|
///
|
||||||
/// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary
|
/// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary
|
||||||
/// when errors in the map are being re-added to the error buffer so that errors with the
|
/// when errors in the map are being re-added to the error buffer so that errors with the
|
||||||
|
@ -2410,7 +2410,8 @@ mod error {
|
||||||
buffered_move_errors:
|
buffered_move_errors:
|
||||||
BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)>,
|
BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)>,
|
||||||
buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx>, usize)>,
|
buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx>, usize)>,
|
||||||
/// Diagnostics to be reported buffer.
|
/// Buffer of diagnostics to be reported. Uses `Diagnostic` rather than `DiagnosticBuilder`
|
||||||
|
/// because it has a mixture of error diagnostics and non-error diagnostics.
|
||||||
buffered: Vec<Diagnostic>,
|
buffered: Vec<Diagnostic>,
|
||||||
/// Set to Some if we emit an error during borrowck
|
/// Set to Some if we emit an error during borrowck
|
||||||
tainted_by_errors: Option<ErrorGuaranteed>,
|
tainted_by_errors: Option<ErrorGuaranteed>,
|
||||||
|
@ -2434,11 +2435,11 @@ mod error {
|
||||||
"diagnostic buffered but not emitted",
|
"diagnostic buffered but not emitted",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
t.buffer(&mut self.buffered);
|
self.buffered.push(t.into_diagnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
|
pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
|
||||||
t.buffer(&mut self.buffered);
|
self.buffered.push(t.into_diagnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
|
pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
|
||||||
|
@ -2486,13 +2487,13 @@ mod error {
|
||||||
// Buffer any move errors that we collected and de-duplicated.
|
// Buffer any move errors that we collected and de-duplicated.
|
||||||
for (_, (_, diag)) in std::mem::take(&mut self.errors.buffered_move_errors) {
|
for (_, (_, diag)) in std::mem::take(&mut self.errors.buffered_move_errors) {
|
||||||
// We have already set tainted for this error, so just buffer it.
|
// We have already set tainted for this error, so just buffer it.
|
||||||
diag.buffer(&mut self.errors.buffered);
|
self.errors.buffered.push(diag.into_diagnostic());
|
||||||
}
|
}
|
||||||
for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) {
|
for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) {
|
||||||
if count > 10 {
|
if count > 10 {
|
||||||
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
|
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
|
||||||
}
|
}
|
||||||
diag.buffer(&mut self.errors.buffered);
|
self.errors.buffered.push(diag.into_diagnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.errors.buffered.is_empty() {
|
if !self.errors.buffered.is_empty() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
|
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
|
||||||
|
|
||||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
|
@ -214,7 +214,7 @@ pub struct Checker<'mir, 'tcx> {
|
||||||
local_has_storage_dead: Option<BitSet<Local>>,
|
local_has_storage_dead: Option<BitSet<Local>>,
|
||||||
|
|
||||||
error_emitted: Option<ErrorGuaranteed>,
|
error_emitted: Option<ErrorGuaranteed>,
|
||||||
secondary_errors: Vec<Diagnostic>,
|
secondary_errors: Vec<DiagnosticBuilder<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> Deref for Checker<'mir, 'tcx> {
|
impl<'mir, 'tcx> Deref for Checker<'mir, 'tcx> {
|
||||||
|
@ -272,14 +272,17 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got through const-checking without emitting any "primary" errors, emit any
|
// If we got through const-checking without emitting any "primary" errors, emit any
|
||||||
// "secondary" errors if they occurred.
|
// "secondary" errors if they occurred. Otherwise, cancel the "secondary" errors.
|
||||||
let secondary_errors = mem::take(&mut self.secondary_errors);
|
let secondary_errors = mem::take(&mut self.secondary_errors);
|
||||||
if self.error_emitted.is_none() {
|
if self.error_emitted.is_none() {
|
||||||
for error in secondary_errors {
|
for error in secondary_errors {
|
||||||
self.tcx.dcx().emit_diagnostic(error);
|
error.emit();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert!(self.tcx.dcx().has_errors().is_some());
|
assert!(self.tcx.dcx().has_errors().is_some());
|
||||||
|
for error in secondary_errors {
|
||||||
|
error.cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +350,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||||
self.error_emitted = Some(reported);
|
self.error_emitted = Some(reported);
|
||||||
}
|
}
|
||||||
|
|
||||||
ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors),
|
ops::DiagnosticImportance::Secondary => self.secondary_errors.push(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,35 +255,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||||
/// Stashes diagnostic for possible later improvement in a different,
|
/// Stashes diagnostic for possible later improvement in a different,
|
||||||
/// later stage of the compiler. The diagnostic can be accessed with
|
/// later stage of the compiler. The diagnostic can be accessed with
|
||||||
/// the provided `span` and `key` through [`DiagCtxt::steal_diagnostic()`].
|
/// the provided `span` and `key` through [`DiagCtxt::steal_diagnostic()`].
|
||||||
///
|
|
||||||
/// As with `buffer`, this is unless the dcx has disabled such buffering.
|
|
||||||
pub fn stash(self, span: Span, key: StashKey) {
|
pub fn stash(self, span: Span, key: StashKey) {
|
||||||
if let Some((diag, dcx)) = self.into_diagnostic() {
|
self.dcx.stash_diagnostic(span, key, self.into_diagnostic());
|
||||||
dcx.stash_diagnostic(span, key, diag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the builder to a `Diagnostic` for later emission,
|
/// Converts the builder to a `Diagnostic` for later emission.
|
||||||
/// unless dcx has disabled such buffering.
|
pub fn into_diagnostic(mut self) -> Diagnostic {
|
||||||
fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> {
|
self.take_diag()
|
||||||
if self.dcx.inner.lock().flags.treat_err_as_bug.is_some() {
|
|
||||||
self.emit();
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let diag = self.take_diag();
|
|
||||||
|
|
||||||
// Logging here is useful to help track down where in logs an error was
|
|
||||||
// actually emitted.
|
|
||||||
debug!("buffer: diag={:?}", diag);
|
|
||||||
|
|
||||||
Some((diag, self.dcx))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Buffers the diagnostic for later emission,
|
|
||||||
/// unless dcx has disabled such buffering.
|
|
||||||
pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) {
|
|
||||||
buffered_diagnostics.extend(self.into_diagnostic().map(|(diag, _)| diag));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delay emission of this diagnostic as a bug.
|
/// Delay emission of this diagnostic as a bug.
|
||||||
|
|
|
@ -981,6 +981,10 @@ impl DiagCtxt {
|
||||||
|
|
||||||
inner.emit_stashed_diagnostics();
|
inner.emit_stashed_diagnostics();
|
||||||
|
|
||||||
|
if inner.treat_err_as_bug() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let warnings = match inner.deduplicated_warn_count {
|
let warnings = match inner.deduplicated_warn_count {
|
||||||
0 => Cow::from(""),
|
0 => Cow::from(""),
|
||||||
1 => Cow::from("1 warning emitted"),
|
1 => Cow::from("1 warning emitted"),
|
||||||
|
@ -991,9 +995,6 @@ impl DiagCtxt {
|
||||||
1 => Cow::from("aborting due to 1 previous error"),
|
1 => Cow::from("aborting due to 1 previous error"),
|
||||||
count => Cow::from(format!("aborting due to {count} previous errors")),
|
count => Cow::from(format!("aborting due to {count} previous errors")),
|
||||||
};
|
};
|
||||||
if inner.treat_err_as_bug() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match (errors.len(), warnings.len()) {
|
match (errors.len(), warnings.len()) {
|
||||||
(0, 0) => return,
|
(0, 0) => return,
|
||||||
|
@ -1168,7 +1169,8 @@ impl DiagCtxt {
|
||||||
let mut inner = self.inner.borrow_mut();
|
let mut inner = self.inner.borrow_mut();
|
||||||
|
|
||||||
if loud && lint_level.is_error() {
|
if loud && lint_level.is_error() {
|
||||||
inner.bump_err_count();
|
inner.err_count += 1;
|
||||||
|
inner.panic_if_treat_err_as_bug();
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.emitter.emit_unused_externs(lint_level, unused_externs)
|
inner.emitter.emit_unused_externs(lint_level, unused_externs)
|
||||||
|
@ -1255,7 +1257,7 @@ impl DiagCtxtInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
|
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
|
||||||
if matches!(diagnostic.level, Error | Fatal) && self.treat_err_as_bug() {
|
if matches!(diagnostic.level, Error | Fatal) && self.treat_next_err_as_bug() {
|
||||||
diagnostic.level = Bug;
|
diagnostic.level = Bug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1353,10 +1355,11 @@ impl DiagCtxtInner {
|
||||||
}
|
}
|
||||||
if diagnostic.is_error() {
|
if diagnostic.is_error() {
|
||||||
if diagnostic.is_lint {
|
if diagnostic.is_lint {
|
||||||
self.bump_lint_err_count();
|
self.lint_err_count += 1;
|
||||||
} else {
|
} else {
|
||||||
self.bump_err_count();
|
self.err_count += 1;
|
||||||
}
|
}
|
||||||
|
self.panic_if_treat_err_as_bug();
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
{
|
{
|
||||||
|
@ -1447,16 +1450,6 @@ impl DiagCtxtInner {
|
||||||
panic::panic_any(DelayedBugPanic);
|
panic::panic_any(DelayedBugPanic);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bump_lint_err_count(&mut self) {
|
|
||||||
self.lint_err_count += 1;
|
|
||||||
self.panic_if_treat_err_as_bug();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bump_err_count(&mut self) {
|
|
||||||
self.err_count += 1;
|
|
||||||
self.panic_if_treat_err_as_bug();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn panic_if_treat_err_as_bug(&self) {
|
fn panic_if_treat_err_as_bug(&self) {
|
||||||
if self.treat_err_as_bug() {
|
if self.treat_err_as_bug() {
|
||||||
match (
|
match (
|
||||||
|
|
|
@ -498,14 +498,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
// order when emitting them.
|
// order when emitting them.
|
||||||
let err =
|
let err =
|
||||||
self.tcx().dcx().struct_span_err(span, format!("user args: {user_args:?}"));
|
self.tcx().dcx().struct_span_err(span, format!("user args: {user_args:?}"));
|
||||||
err.buffer(&mut errors_buffer);
|
errors_buffer.push(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errors_buffer.is_empty() {
|
if !errors_buffer.is_empty() {
|
||||||
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
|
errors_buffer.sort_by_key(|diag| diag.span.primary_span());
|
||||||
for diag in errors_buffer {
|
for err in errors_buffer {
|
||||||
self.tcx().dcx().emit_diagnostic(diag);
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
expected_error();
|
Err(errs) => {
|
||||||
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
|
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};
|
||||||
|
@ -42,12 +42,12 @@ pub struct UnmatchedDelim {
|
||||||
pub candidate_span: Option<Span>,
|
pub candidate_span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_token_trees<'a>(
|
pub(crate) fn parse_token_trees<'sess, 'src>(
|
||||||
sess: &'a ParseSess,
|
sess: &'sess ParseSess,
|
||||||
mut src: &'a 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<'a>(
|
||||||
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)
|
||||||
|
@ -90,16 +90,16 @@ pub(crate) fn parse_token_trees<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StringReader<'a> {
|
struct StringReader<'sess, 'src> {
|
||||||
sess: &'a ParseSess,
|
sess: &'sess ParseSess,
|
||||||
/// Initial position, read-only.
|
/// Initial position, read-only.
|
||||||
start_pos: BytePos,
|
start_pos: BytePos,
|
||||||
/// The absolute offset within the source_map of the current character.
|
/// The absolute offset within the source_map of the current character.
|
||||||
pos: BytePos,
|
pos: BytePos,
|
||||||
/// Source text to tokenize.
|
/// Source text to tokenize.
|
||||||
src: &'a str,
|
src: &'src str,
|
||||||
/// Cursor for getting lexer tokens.
|
/// Cursor for getting lexer tokens.
|
||||||
cursor: Cursor<'a>,
|
cursor: Cursor<'src>,
|
||||||
override_span: Option<Span>,
|
override_span: Option<Span>,
|
||||||
/// When a "unknown start of token: \u{a0}" has already been emitted earlier
|
/// When a "unknown start of token: \u{a0}" has already been emitted earlier
|
||||||
/// in this file, it's safe to treat further occurrences of the non-breaking
|
/// in this file, it's safe to treat further occurrences of the non-breaking
|
||||||
|
@ -107,8 +107,8 @@ struct StringReader<'a> {
|
||||||
nbsp_is_whitespace: bool,
|
nbsp_is_whitespace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StringReader<'a> {
|
impl<'sess, 'src> StringReader<'sess, 'src> {
|
||||||
pub fn dcx(&self) -> &'a DiagCtxt {
|
pub fn dcx(&self) -> &'sess DiagCtxt {
|
||||||
&self.sess.dcx
|
&self.sess.dcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ impl<'a> StringReader<'a> {
|
||||||
|
|
||||||
/// Slice of the source text from `start` up to but excluding `self.pos`,
|
/// Slice of the source text from `start` up to but excluding `self.pos`,
|
||||||
/// meaning the slice does not include the character `self.ch`.
|
/// meaning the slice does not include the character `self.ch`.
|
||||||
fn str_from(&self, start: BytePos) -> &'a str {
|
fn str_from(&self, start: BytePos) -> &'src str {
|
||||||
self.str_from_to(start, self.pos)
|
self.str_from_to(start, self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,12 +537,12 @@ impl<'a> StringReader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slice of the source text spanning from `start` up to but excluding `end`.
|
/// Slice of the source text spanning from `start` up to but excluding `end`.
|
||||||
fn str_from_to(&self, start: BytePos, end: BytePos) -> &'a str {
|
fn str_from_to(&self, start: BytePos, end: BytePos) -> &'src str {
|
||||||
&self.src[self.src_index(start)..self.src_index(end)]
|
&self.src[self.src_index(start)..self.src_index(end)]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slice of the source text spanning from `start` until the end
|
/// Slice of the source text spanning from `start` until the end
|
||||||
fn str_from_to_end(&self, start: BytePos) -> &'a str {
|
fn str_from_to_end(&self, start: BytePos) -> &'src str {
|
||||||
&self.src[self.src_index(start)..]
|
&self.src[self.src_index(start)..]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,18 @@ use rustc_ast_pretty::pprust::token_to_string;
|
||||||
use rustc_errors::{Applicability, PErr};
|
use rustc_errors::{Applicability, PErr};
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
|
|
||||||
pub(super) struct TokenTreesReader<'a> {
|
pub(super) struct TokenTreesReader<'sess, 'src> {
|
||||||
string_reader: StringReader<'a>,
|
string_reader: StringReader<'sess, 'src>,
|
||||||
/// The "next" token, which has been obtained from the `StringReader` but
|
/// The "next" token, which has been obtained from the `StringReader` but
|
||||||
/// not yet handled by the `TokenTreesReader`.
|
/// not yet handled by the `TokenTreesReader`.
|
||||||
token: Token,
|
token: Token,
|
||||||
diag_info: TokenTreeDiagInfo,
|
diag_info: TokenTreeDiagInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TokenTreesReader<'a> {
|
impl<'sess, 'src> TokenTreesReader<'sess, 'src> {
|
||||||
pub(super) fn parse_all_token_trees(
|
pub(super) fn parse_all_token_trees(
|
||||||
string_reader: StringReader<'a>,
|
string_reader: StringReader<'sess, 'src>,
|
||||||
) -> (TokenStream, Result<(), Vec<PErr<'a>>>, Vec<UnmatchedDelim>) {
|
) -> (TokenStream, Result<(), Vec<PErr<'sess>>>, Vec<UnmatchedDelim>) {
|
||||||
let mut tt_reader = TokenTreesReader {
|
let mut tt_reader = TokenTreesReader {
|
||||||
string_reader,
|
string_reader,
|
||||||
token: Token::dummy(),
|
token: Token::dummy(),
|
||||||
|
@ -35,7 +35,7 @@ impl<'a> TokenTreesReader<'a> {
|
||||||
fn parse_token_trees(
|
fn parse_token_trees(
|
||||||
&mut self,
|
&mut self,
|
||||||
is_delimited: bool,
|
is_delimited: bool,
|
||||||
) -> (Spacing, TokenStream, Result<(), Vec<PErr<'a>>>) {
|
) -> (Spacing, TokenStream, Result<(), Vec<PErr<'sess>>>) {
|
||||||
// Move past the opening delimiter.
|
// Move past the opening delimiter.
|
||||||
let (_, open_spacing) = self.bump(false);
|
let (_, open_spacing) = self.bump(false);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ impl<'a> TokenTreesReader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eof_err(&mut self) -> PErr<'a> {
|
fn eof_err(&mut self) -> PErr<'sess> {
|
||||||
let msg = "this file contains an unclosed delimiter";
|
let msg = "this file contains an unclosed delimiter";
|
||||||
let mut err = self.string_reader.sess.dcx.struct_span_err(self.token.span, msg);
|
let mut err = self.string_reader.sess.dcx.struct_span_err(self.token.span, msg);
|
||||||
for &(_, sp) in &self.diag_info.open_braces {
|
for &(_, sp) in &self.diag_info.open_braces {
|
||||||
|
@ -99,7 +99,7 @@ impl<'a> TokenTreesReader<'a> {
|
||||||
fn parse_token_tree_open_delim(
|
fn parse_token_tree_open_delim(
|
||||||
&mut self,
|
&mut self,
|
||||||
open_delim: Delimiter,
|
open_delim: Delimiter,
|
||||||
) -> Result<TokenTree, Vec<PErr<'a>>> {
|
) -> Result<TokenTree, Vec<PErr<'sess>>> {
|
||||||
// The span for beginning of the delimited section
|
// The span for beginning of the delimited section
|
||||||
let pre_span = self.token.span;
|
let pre_span = self.token.span;
|
||||||
|
|
||||||
|
@ -229,7 +229,11 @@ impl<'a> TokenTreesReader<'a> {
|
||||||
(this_tok, this_spacing)
|
(this_tok, this_spacing)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unclosed_delim_err(&mut self, tts: TokenStream, mut errs: Vec<PErr<'a>>) -> Vec<PErr<'a>> {
|
fn unclosed_delim_err(
|
||||||
|
&mut self,
|
||||||
|
tts: TokenStream,
|
||||||
|
mut errs: Vec<PErr<'sess>>,
|
||||||
|
) -> Vec<PErr<'sess>> {
|
||||||
// If there are unclosed delims, see if there are diff markers and if so, point them
|
// If there are unclosed delims, see if there are diff markers and if so, point them
|
||||||
// out instead of complaining about the unclosed delims.
|
// out instead of complaining about the unclosed delims.
|
||||||
let mut parser = crate::stream_to_parser(self.string_reader.sess, tts, None);
|
let mut parser = crate::stream_to_parser(self.string_reader.sess, tts, None);
|
||||||
|
@ -285,7 +289,7 @@ impl<'a> TokenTreesReader<'a> {
|
||||||
return errs;
|
return errs;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'a> {
|
fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'sess> {
|
||||||
// An unexpected closing delimiter (i.e., there is no
|
// An unexpected closing delimiter (i.e., there is no
|
||||||
// matching opening delimiter).
|
// matching opening delimiter).
|
||||||
let token_str = token_to_string(&self.token);
|
let token_str = token_to_string(&self.token);
|
||||||
|
|
|
@ -337,7 +337,7 @@ const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(super) fn check_for_substitution(
|
pub(super) fn check_for_substitution(
|
||||||
reader: &StringReader<'_>,
|
reader: &StringReader<'_, '_>,
|
||||||
pos: BytePos,
|
pos: BytePos,
|
||||||
ch: char,
|
ch: char,
|
||||||
count: usize,
|
count: usize,
|
||||||
|
|
|
@ -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, FatalError, Level, 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,36 +99,41 @@ 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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new parser, handling errors as appropriate if the file doesn't exist.
|
/// Creates a new parser, aborting if the file doesn't exist. If a span is given, that is used on
|
||||||
/// If a span is given, that is used on an error as the source of the problem.
|
/// an error as the source of the problem.
|
||||||
pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
|
pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
|
||||||
source_file_to_parser(sess, file_to_source_file(sess, path, sp))
|
let source_file = sess.source_map().load_file(path).unwrap_or_else(|e| {
|
||||||
|
let msg = format!("couldn't read {}: {}", path.display(), e);
|
||||||
|
let mut err = sess.dcx.struct_fatal(msg);
|
||||||
|
if let Some(sp) = sp {
|
||||||
|
err.span(sp);
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
});
|
||||||
|
|
||||||
|
panictry_buffer!(maybe_source_file_to_parser(sess, source_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a session and a `source_file`, returns a parser.
|
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
|
||||||
fn source_file_to_parser(sess: &ParseSess, source_file: Lrc<SourceFile>) -> Parser<'_> {
|
/// the initial token stream.
|
||||||
panictry_buffer!(&sess.dcx, maybe_source_file_to_parser(sess, source_file))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing the
|
|
||||||
/// initial token stream.
|
|
||||||
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);
|
||||||
|
@ -142,52 +146,22 @@ fn maybe_source_file_to_parser(
|
||||||
|
|
||||||
// Base abstractions
|
// Base abstractions
|
||||||
|
|
||||||
/// Given a session and a path and an optional span (for error reporting),
|
|
||||||
/// add the path to the session's source_map and return the new source_file or
|
|
||||||
/// error when a file can't be read.
|
|
||||||
fn try_file_to_source_file(
|
|
||||||
sess: &ParseSess,
|
|
||||||
path: &Path,
|
|
||||||
spanopt: Option<Span>,
|
|
||||||
) -> Result<Lrc<SourceFile>, Diagnostic> {
|
|
||||||
sess.source_map().load_file(path).map_err(|e| {
|
|
||||||
let msg = format!("couldn't read {}: {}", path.display(), e);
|
|
||||||
let mut diag = Diagnostic::new(Level::Fatal, msg);
|
|
||||||
if let Some(sp) = spanopt {
|
|
||||||
diag.span(sp);
|
|
||||||
}
|
|
||||||
diag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a session and a path and an optional span (for error reporting),
|
|
||||||
/// adds the path to the session's `source_map` and returns the new `source_file`.
|
|
||||||
fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> {
|
|
||||||
match try_file_to_source_file(sess, path, spanopt) {
|
|
||||||
Ok(source_file) => source_file,
|
|
||||||
Err(d) => {
|
|
||||||
sess.dcx.emit_diagnostic(d);
|
|
||||||
FatalError.raise();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a `source_file`, produces a sequence of token trees.
|
/// Given a `source_file`, produces a sequence of token trees.
|
||||||
pub fn source_file_to_stream(
|
pub fn source_file_to_stream(
|
||||||
sess: &ParseSess,
|
sess: &ParseSess,
|
||||||
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.
|
||||||
pub 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: expected one of `->`, `where`, or `{`, found `<eof>`
|
error: internal compiler error: expected one of `->`, `where`, or `{`, found `<eof>`
|
||||||
--> $DIR/ice-bug-report-url.rs:14:10
|
--> $DIR/ice-bug-report-url.rs:14:10
|
||||||
|
|
|
|
||||||
LL | fn wrong()
|
LL | fn wrong()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0080]: evaluation of constant value failed
|
error: internal compiler error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const-eval-query-stack.rs:16:16
|
--> $DIR/const-eval-query-stack.rs:16:16
|
||||||
|
|
|
|
||||||
LL | const X: i32 = 1 / 0;
|
LL | const X: i32 = 1 / 0;
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: unconstrained opaque type
|
||||||
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
error: internal compiler error[E0792]: expected generic lifetime parameter, found `'_`
|
||||||
--> $DIR/issue-86800.rs:39:5
|
--> $DIR/issue-86800.rs:39:5
|
||||||
|
|
|
|
||||||
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0425]: cannot find value `missing_ident` in this scope
|
error: internal compiler error[E0425]: cannot find value `missing_ident` in this scope
|
||||||
--> $DIR/default-backtrace-ice.rs:21:13
|
--> $DIR/default-backtrace-ice.rs:21:13
|
||||||
|
|
|
|
||||||
LL | fn main() { missing_ident; }
|
LL | fn main() { missing_ident; }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0080]: could not evaluate static initializer
|
error: internal compiler error[E0080]: could not evaluate static initializer
|
||||||
--> $DIR/err.rs:11:21
|
--> $DIR/err.rs:11:21
|
||||||
|
|
|
|
||||||
LL | pub static C: u32 = 0 - 1;
|
LL | pub static C: u32 = 0 - 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue