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`.
This commit is contained in:
Nicholas Nethercote 2024-01-03 12:17:35 +11:00
parent ca2fc426a9
commit b1b9278851
86 changed files with 329 additions and 312 deletions

View File

@ -23,7 +23,7 @@ macro_rules! gate {
($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{ ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain) feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain)
.help($help) .help_mv($help)
.emit(); .emit();
} }
}}; }};

View File

@ -348,7 +348,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty); let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
let named_key = self.regioncx.name_regions(self.infcx.tcx, key); let named_key = self.regioncx.name_regions(self.infcx.tcx, key);
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
let mut diag = unexpected_hidden_region_diagnostic( let diag = unexpected_hidden_region_diagnostic(
self.infcx.tcx, self.infcx.tcx,
span, span,
named_ty, named_ty,

View File

@ -421,7 +421,7 @@ fn check_opaque_type_parameter_valid(
return Err(tcx return Err(tcx
.dcx() .dcx()
.struct_span_err(span, "non-defining opaque type use in defining scope") .struct_span_err(span, "non-defining opaque type use in defining scope")
.span_note(spans, format!("{descr} used multiple times")) .span_note_mv(spans, format!("{descr} used multiple times"))
.emit()); .emit());
} }
} }

View File

@ -458,7 +458,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
match expr_to_spanned_string(ecx, template_expr, msg) { match expr_to_spanned_string(ecx, template_expr, msg) {
Ok(template_part) => template_part, Ok(template_part) => template_part,
Err(err) => { Err(err) => {
if let Some((mut err, _)) = err { if let Some((err, _)) = err {
err.emit(); err.emit();
} }
return None; return None;
@ -747,7 +747,7 @@ pub(super) fn expand_asm<'cx>(
}; };
MacEager::expr(expr) MacEager::expr(expr)
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
DummyResult::any(sp) DummyResult::any(sp)
} }
@ -779,7 +779,7 @@ pub(super) fn expand_global_asm<'cx>(
DummyResult::any(sp) DummyResult::any(sp)
} }
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
DummyResult::any(sp) DummyResult::any(sp)
} }

View File

@ -22,7 +22,7 @@ pub fn expand_assert<'cx>(
) -> Box<dyn MacResult + 'cx> { ) -> Box<dyn MacResult + 'cx> {
let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) { let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) {
Ok(assert) => assert, Ok(assert) => assert,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(span); return DummyResult::any(span);
} }

View File

@ -28,7 +28,7 @@ pub fn expand_cfg(
); );
MacEager::expr(cx.expr_bool(sp, matches_cfg)) MacEager::expr(cx.expr_bool(sp, matches_cfg))
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
DummyResult::any(sp) DummyResult::any(sp)
} }

View File

@ -200,7 +200,7 @@ impl CfgEval<'_, '_> {
parser.capture_cfg = true; parser.capture_cfg = true;
match parse_annotatable_with(&mut parser) { match parse_annotatable_with(&mut parser) {
Ok(a) => annotatable = a, Ok(a) => annotatable = a,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return Some(annotatable); return Some(annotatable);
} }

View File

@ -18,7 +18,7 @@ pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String])
let start_span = parser.token.span; let start_span = parser.token.span;
let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) { let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
Ok(ai) => ai, Ok(ai) => ai,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
continue; continue;
} }

View File

@ -99,7 +99,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<
} }
match p.expect(&token::Comma) { match p.expect(&token::Comma) {
Err(mut err) => { Err(err) => {
match token::TokenKind::Comma.similar_tokens() { match token::TokenKind::Comma.similar_tokens() {
Some(tks) if tks.contains(&p.token.kind) => { Some(tks) if tks.contains(&p.token.kind) => {
// If a similar token is found, then it may be a typo. We // If a similar token is found, then it may be a typo. We
@ -630,8 +630,7 @@ fn report_missing_placeholders(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !placeholders.is_empty() { if !placeholders.is_empty() {
if let Some(mut new_diag) = report_redundant_format_arguments(ecx, args, used, placeholders) if let Some(new_diag) = report_redundant_format_arguments(ecx, args, used, placeholders) {
{
diag.cancel(); diag.cancel();
new_diag.emit(); new_diag.emit();
return; return;
@ -976,7 +975,7 @@ fn expand_format_args_impl<'cx>(
MacEager::expr(DummyResult::raw_expr(sp, true)) MacEager::expr(DummyResult::raw_expr(sp, true))
} }
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
DummyResult::any(sp) DummyResult::any(sp)
} }

View File

@ -194,7 +194,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
self.dcx self.dcx
.struct_span_err(attr.span, msg) .struct_span_err(attr.span, msg)
.span_label(prev_attr.span, "previous attribute here") .span_label_mv(prev_attr.span, "previous attribute here")
.emit(); .emit();
return; return;

View File

@ -109,7 +109,7 @@ pub fn expand_include<'cx>(
// The file will be added to the code map by the parser // The file will be added to the code map by the parser
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) { let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
Ok(f) => f, Ok(f) => f,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(sp); return DummyResult::any(sp);
} }
@ -146,7 +146,7 @@ pub fn expand_include<'cx>(
let mut ret = SmallVec::new(); let mut ret = SmallVec::new();
loop { loop {
match self.p.parse_item(ForceCollect::No) { match self.p.parse_item(ForceCollect::No) {
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
break; break;
} }
@ -181,7 +181,7 @@ pub fn expand_include_str(
}; };
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) { let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
Ok(f) => f, Ok(f) => f,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(sp); return DummyResult::any(sp);
} }
@ -215,7 +215,7 @@ pub fn expand_include_bytes(
}; };
let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) { let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
Ok(f) => f, Ok(f) => f,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(sp); return DummyResult::any(sp);
} }

View File

@ -409,8 +409,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
), ),
); );
} }
err.span_label(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions") err.span_label_mv(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions")
.span_suggestion(attr_sp, .span_suggestion_mv(attr_sp,
"replace with conditional compilation to make the item only exist when tests are being run", "replace with conditional compilation to make the item only exist when tests are being run",
"#[cfg(test)]", "#[cfg(test)]",
Applicability::MaybeIncorrect) Applicability::MaybeIncorrect)
@ -480,7 +480,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
"argument must be of the form: \ "argument must be of the form: \
`expected = \"error message\"`", `expected = \"error message\"`",
) )
.note( .note_mv(
"errors in this attribute were erroneously \ "errors in this attribute were erroneously \
allowed and will become a hard error in a \ allowed and will become a hard error in a \
future release", future release",

View File

@ -12,7 +12,7 @@ pub fn expand_type_ascribe(
) -> Box<dyn base::MacResult + 'static> { ) -> Box<dyn base::MacResult + 'static> {
let (expr, ty) = match parse_ascribe(cx, tts) { let (expr, ty) = match parse_ascribe(cx, tts) {
Ok(parsed) => parsed, Ok(parsed) => parsed,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(span); return DummyResult::any(span);
} }

View File

@ -477,7 +477,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
InlineAttr::Never InlineAttr::Never
} else { } else {
struct_span_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") struct_span_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
.help("valid inline arguments are `always` and `never`") .help_mv("valid inline arguments are `always` and `never`")
.emit(); .emit();
InlineAttr::None InlineAttr::None
@ -662,7 +662,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal); let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
tcx.dcx() tcx.dcx()
.struct_span_err(attr.span, msg) .struct_span_err(attr.span, msg)
.note("the value may not exceed `u16::MAX`") .note_mv("the value may not exceed `u16::MAX`")
.emit(); .emit();
None None
} }

View File

@ -27,7 +27,7 @@ pub fn from_target_feature(
let code = "enable = \"..\""; let code = "enable = \"..\"";
tcx.dcx() tcx.dcx()
.struct_span_err(span, msg) .struct_span_err(span, msg)
.span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders) .span_suggestion_mv(span, "must be of the form", code, Applicability::HasPlaceholders)
.emit(); .emit();
}; };
let rust_features = tcx.features(); let rust_features = tcx.features();

View File

@ -338,7 +338,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
return; return;
} }
let mut err = op.build_error(self.ccx, span); let err = op.build_error(self.ccx, span);
assert!(err.is_error()); assert!(err.is_error());
match op.importance() { match op.importance() {

View File

@ -716,7 +716,7 @@ fn print_crate_info(
let result = parse_crate_attrs(sess); let result = parse_crate_attrs(sess);
match result { match result {
Ok(attrs) => Some(attrs), Ok(attrs) => Some(attrs),
Err(mut parse_error) => { Err(parse_error) => {
parse_error.emit(); parse_error.emit();
return Compilation::Stop; return Compilation::Stop;
} }

View File

@ -198,23 +198,34 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
} }
} }
/// In general, the `DiagnosticBuilder` uses deref to allow access to /// `DiagnosticBuilder` impls `DerefMut`, which allows access to the fields and
/// the fields and methods of the embedded `diagnostic` in a /// methods of the embedded `Diagnostic`. However, that doesn't allow method
/// transparent way. *However,* many of the methods are intended to /// chaining at the `DiagnosticBuilder` level. Each use of this macro defines
/// be used in a chained way, and hence ought to return `self`. In /// two builder methods at that level, both of which wrap the equivalent method
/// that case, we can't just naively forward to the method on the /// in `Diagnostic`.
/// `diagnostic`, because the return type would be a `&Diagnostic` /// - A `&mut self -> &mut Self` method, with the same name as the underlying
/// instead of a `&DiagnosticBuilder<'a>`. This `forward!` macro makes /// `Diagnostic` method. It is mostly to modify existing diagnostics, either
/// it easy to declare such methods on the builder. /// in a standalone fashion, e.g. `err.code(code)`, or in a chained fashion
/// to make multiple modifications, e.g. `err.code(code).span(span)`.
/// - A `self -> Self` method, with `_mv` suffix added (short for "move").
/// It is mostly used in a chained fashion when producing a new diagnostic,
/// e.g. `let err = struct_err(msg).code_mv(code)`, or when emitting a new
/// diagnostic , e.g. `struct_err(msg).code_mv(code).emit()`.
///
/// Although the latter method can be used to modify an existing diagnostic,
/// e.g. `err = err.code_mv(code)`, this should be avoided because the former
/// method give shorter code, e.g. `err.code(code)`.
macro_rules! forward { macro_rules! forward {
// Forward pattern for &mut self -> &mut Self
( (
$(#[$attrs:meta])* ($n:ident, $n_mv:ident)($($name:ident: $ty:ty),* $(,)?)
pub fn $n:ident(&mut self $(, $name:ident: $ty:ty)* $(,)?) -> &mut Self
) => { ) => {
$(#[$attrs])*
#[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")]
pub fn $n(&mut self $(, $name: $ty)*) -> &mut Self { pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
self.diagnostic.$n($($name),*);
self
}
#[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")]
pub fn $n_mv(mut self, $($name: $ty),*) -> Self {
self.diagnostic.$n($($name),*); self.diagnostic.$n($($name),*);
self self
} }
@ -254,11 +265,15 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
} }
} }
/// Emit the diagnostic. Does not consume `self`, which may be surprising, /// Emit and consume the diagnostic.
/// but there are various places that rely on continuing to use `self`
/// after calling `emit`.
#[track_caller] #[track_caller]
pub fn emit(&mut self) -> G::EmitResult { pub fn emit(mut self) -> G::EmitResult {
G::emit_producing_guarantee(&mut self)
}
/// Emit the diagnostic without consuming it. `emit` should be preferred.
#[track_caller]
pub fn emit_without_consuming(&mut self) -> G::EmitResult {
G::emit_producing_guarantee(self) G::emit_producing_guarantee(self)
} }
@ -267,7 +282,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// ///
/// See `emit` and `delay_as_bug` for details. /// See `emit` and `delay_as_bug` for details.
#[track_caller] #[track_caller]
pub fn emit_unless(&mut self, delay: bool) -> G::EmitResult { pub fn emit_unless(mut self, delay: bool) -> G::EmitResult {
if delay { if delay {
self.downgrade_to_delayed_bug(); self.downgrade_to_delayed_bug();
} }
@ -354,142 +369,142 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// In the meantime, though, callsites are required to deal with the "bug" /// In the meantime, though, callsites are required to deal with the "bug"
/// locally in whichever way makes the most sense. /// locally in whichever way makes the most sense.
#[track_caller] #[track_caller]
pub fn delay_as_bug(&mut self) -> G::EmitResult { pub fn delay_as_bug(mut self) -> G::EmitResult {
self.downgrade_to_delayed_bug(); self.downgrade_to_delayed_bug();
self.emit() self.emit()
} }
forward!(pub fn span_label( /// Non-consuming variant of `delay_as_bug`.
&mut self, #[track_caller]
pub fn delay_as_bug_without_consuming(&mut self) -> G::EmitResult {
self.downgrade_to_delayed_bug();
self.emit_without_consuming()
}
forward!((span_label, span_label_mv)(
span: Span, span: Span,
label: impl Into<SubdiagnosticMessage> label: impl Into<SubdiagnosticMessage>,
) -> &mut Self); ));
forward!(pub fn span_labels( forward!((span_labels, span_labels_mv)(
&mut self,
spans: impl IntoIterator<Item = Span>, spans: impl IntoIterator<Item = Span>,
label: &str, label: &str,
) -> &mut Self); ));
forward!(pub fn note_expected_found( forward!((note_expected_found, note_expected_found_mv)(
&mut self,
expected_label: &dyn fmt::Display, expected_label: &dyn fmt::Display,
expected: DiagnosticStyledString, expected: DiagnosticStyledString,
found_label: &dyn fmt::Display, found_label: &dyn fmt::Display,
found: DiagnosticStyledString, found: DiagnosticStyledString,
) -> &mut Self); ));
forward!(pub fn note_expected_found_extra( forward!((note_expected_found_extra, note_expected_found_extra_mv)(
&mut self,
expected_label: &dyn fmt::Display, expected_label: &dyn fmt::Display,
expected: DiagnosticStyledString, expected: DiagnosticStyledString,
found_label: &dyn fmt::Display, found_label: &dyn fmt::Display,
found: DiagnosticStyledString, found: DiagnosticStyledString,
expected_extra: &dyn fmt::Display, expected_extra: &dyn fmt::Display,
found_extra: &dyn fmt::Display, found_extra: &dyn fmt::Display,
) -> &mut Self); ));
forward!(pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self); forward!((note, note_mv)(
forward!(pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self); msg: impl Into<SubdiagnosticMessage>,
forward!(pub fn span_note( ));
&mut self, forward!((note_once, note_once_mv)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_note, span_note_mv)(
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self); ));
forward!(pub fn span_note_once( forward!((span_note_once, span_note_once_mv)(
&mut self,
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self); ));
forward!(pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self); forward!((warn, warn_mv)(
forward!(pub fn span_warn( msg: impl Into<SubdiagnosticMessage>,
&mut self, ));
forward!((span_warn, span_warn_mv)(
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self); ));
forward!(pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self); forward!((help, help_mv)(
forward!(pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self); msg: impl Into<SubdiagnosticMessage>,
forward!(pub fn span_help( ));
&mut self, forward!((help_once, help_once_mv)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_help, span_help_once_mv)(
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self); ));
forward!(pub fn is_lint(&mut self) -> &mut Self); forward!((multipart_suggestion, multipart_suggestion_mv)(
forward!(pub fn disable_suggestions(&mut self) -> &mut Self);
forward!(pub fn multipart_suggestion(
&mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>, suggestion: Vec<(Span, String)>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn multipart_suggestion_verbose( forward!((multipart_suggestion_verbose, multipart_suggestion_verbose_mv)(
&mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>, suggestion: Vec<(Span, String)>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn tool_only_multipart_suggestion( forward!((tool_only_multipart_suggestion, tool_only_multipart_suggestion_mv)(
&mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>, suggestion: Vec<(Span, String)>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn span_suggestion( forward!((span_suggestion, span_suggestion_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString, suggestion: impl ToString,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn span_suggestions( forward!((span_suggestions, span_suggestions_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestions: impl IntoIterator<Item = String>, suggestions: impl IntoIterator<Item = String>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn multipart_suggestions( forward!((multipart_suggestions, multipart_suggestions_mv)(
&mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestions: impl IntoIterator<Item = Vec<(Span, String)>>, suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn span_suggestion_short( forward!((span_suggestion_short, span_suggestion_short_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString, suggestion: impl ToString,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn span_suggestion_verbose( forward!((span_suggestion_verbose, span_suggestion_verbose_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString, suggestion: impl ToString,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn span_suggestion_hidden( forward!((span_suggestion_hidden, span_suggestion_hidden_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString, suggestion: impl ToString,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn tool_only_span_suggestion( forward!((tool_only_span_suggestion, tool_only_span_suggestion_mv)(
&mut self,
sp: Span, sp: Span,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString, suggestion: impl ToString,
applicability: Applicability, applicability: Applicability,
) -> &mut Self); ));
forward!(pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self); forward!((primary_message, primary_message_mv)(
forward!(pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self); msg: impl Into<DiagnosticMessage>,
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self); ));
forward!(pub fn arg( forward!((span, span_mv)(
&mut self, sp: impl Into<MultiSpan>,
name: impl Into<Cow<'static, str>>, ));
arg: impl IntoDiagnosticArg, forward!((code, code_mv)(
) -> &mut Self); s: DiagnosticId,
forward!(pub fn subdiagnostic( ));
&mut self, forward!((arg, arg_mv)(
subdiagnostic: impl crate::AddToDiagnostic name: impl Into<Cow<'static, str>>, arg: impl IntoDiagnosticArg,
) -> &mut Self); ));
forward!((subdiagnostic, subdiagnostic_mv)(
subdiagnostic: impl crate::AddToDiagnostic,
));
} }
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {

View File

@ -1232,7 +1232,7 @@ pub fn expr_to_string(
) -> Option<(Symbol, ast::StrStyle)> { ) -> Option<(Symbol, ast::StrStyle)> {
expr_to_spanned_string(cx, expr, err_msg) expr_to_spanned_string(cx, expr, err_msg)
.map_err(|err| { .map_err(|err| {
err.map(|(mut err, _)| { err.map(|(err, _)| {
err.emit(); err.emit();
}) })
}) })
@ -1254,7 +1254,7 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str
pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> { pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
match p.parse_expr() { match p.parse_expr() {
Ok(e) => return Some(e), Ok(e) => return Some(e),
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
} }
} }

View File

@ -362,7 +362,7 @@ impl<'a> StripUnconfigured<'a> {
pub(crate) fn cfg_true(&self, attr: &Attribute) -> (bool, Option<MetaItem>) { pub(crate) fn cfg_true(&self, attr: &Attribute) -> (bool, Option<MetaItem>) {
let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) { let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) {
Ok(meta_item) => meta_item, Ok(meta_item) => meta_item,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return (true, None); return (true, None);
} }

View File

@ -735,7 +735,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fragment_kind.expect_from_annotatables(items) fragment_kind.expect_from_annotatables(items)
} }
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
fragment_kind.dummy(span) fragment_kind.dummy(span)
} }

View File

@ -679,8 +679,8 @@ impl TtParser {
// We use the span of the metavariable declaration to determine any // We use the span of the metavariable declaration to determine any
// edition-specific matching behavior for non-terminals. // edition-specific matching behavior for non-terminals.
let nt = match parser.to_mut().parse_nonterminal(kind) { let nt = match parser.to_mut().parse_nonterminal(kind) {
Err(mut err) => { Err(err) => {
let guarantee = err.span_label( let guarantee = err.span_label_mv(
span, span,
format!( format!(
"while parsing argument for this `{kind}` macro fragment" "while parsing argument for this `{kind}` macro fragment"

View File

@ -215,7 +215,7 @@ fn expand_macro<'cx>(
// rhs has holes ( `$id` and `$(...)` that need filled) // rhs has holes ( `$id` and `$(...)` that need filled)
let tts = match transcribe(cx, &named_matches, rhs, rhs_span, transparency) { let tts = match transcribe(cx, &named_matches, rhs, rhs_span, transparency) {
Ok(tts) => tts, Ok(tts) => tts,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return DummyResult::any(arm_span); return DummyResult::any(arm_span);
} }

View File

@ -86,7 +86,7 @@ pub(super) fn parse(
); );
sess.dcx sess.dcx
.struct_span_err(span, msg) .struct_span_err(span, msg)
.help(VALID_FRAGMENT_NAMES_MSG) .help_mv(VALID_FRAGMENT_NAMES_MSG)
.emit(); .emit();
token::NonterminalKind::Ident token::NonterminalKind::Ident
}, },
@ -175,7 +175,7 @@ fn parse_tree<'a>(
// of a meta-variable expression (e.g. `${count(ident)}`). // of a meta-variable expression (e.g. `${count(ident)}`).
// Try to parse the meta-variable expression. // Try to parse the meta-variable expression.
match MetaVarExpr::parse(tts, delim_span.entire(), sess) { match MetaVarExpr::parse(tts, delim_span.entire(), sess) {
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
// Returns early the same read `$` to avoid spanning // Returns early the same read `$` to avoid spanning
// unrelated diagnostics that could be performed afterwards // unrelated diagnostics that could be performed afterwards

View File

@ -282,7 +282,7 @@ impl ModError<'_> {
secondary_path: secondary_path.display().to_string(), secondary_path: secondary_path.display().to_string(),
}) })
} }
ModError::ParserError(mut err) => err.emit(), ModError::ParserError(err) => err.emit(),
} }
} }
} }

View File

@ -171,7 +171,7 @@ impl MultiItemModifier for DeriveProcMacro {
items.push(Annotatable::Item(item)); items.push(Annotatable::Item(item));
} }
} }
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
break; break;
} }

View File

@ -537,7 +537,7 @@ impl server::TokenStream for Rustc<'_, '_> {
} }
expr expr
}; };
let expr = expr.map_err(|mut err| { let expr = expr.map_err(|err| {
err.emit(); err.emit();
})?; })?;

View File

@ -305,7 +305,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
binding.span, binding.span,
format!("{} `{}` is private", assoc_item.kind, binding.item_name), format!("{} `{}` is private", assoc_item.kind, binding.item_name),
) )
.span_label(binding.span, format!("private {}", assoc_item.kind)) .span_label_mv(binding.span, format!("private {}", assoc_item.kind))
.emit(); .emit();
} }
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);

View File

@ -58,13 +58,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if !trait_def.paren_sugar { if !trait_def.paren_sugar {
if trait_segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar { if trait_segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar {
// For now, require that parenthetical notation be used only with `Fn()` etc. // For now, require that parenthetical notation be used only with `Fn()` etc.
let mut err = feature_err( feature_err(
&self.tcx().sess.parse_sess, &self.tcx().sess.parse_sess,
sym::unboxed_closures, sym::unboxed_closures,
span, span,
"parenthetical notation is only stable when used with `Fn`-family traits", "parenthetical notation is only stable when used with `Fn`-family traits",
); )
err.emit(); .emit();
} }
return; return;

View File

@ -70,7 +70,7 @@ fn generic_arg_mismatch_err(
Res::Err => { Res::Err => {
add_braces_suggestion(arg, &mut err); add_braces_suggestion(arg, &mut err);
return err return err
.primary_message("unresolved item provided when a constant was expected") .primary_message_mv("unresolved item provided when a constant was expected")
.emit(); .emit();
} }
Res::Def(DefKind::TyParam, src_def_id) => { Res::Def(DefKind::TyParam, src_def_id) => {

View File

@ -1648,8 +1648,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let def_span = tcx.def_span(item); let def_span = tcx.def_span(item);
tcx.dcx() tcx.dcx()
.struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624)) .struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624))
.span_label(span, format!("private {kind}")) .span_label_mv(span, format!("private {kind}"))
.span_label(def_span, format!("{kind} defined here")) .span_label_mv(def_span, format!("{kind} defined here"))
.emit(); .emit();
} }
tcx.check_stability(item, Some(block), span, None); tcx.check_stability(item, Some(block), span, None);

View File

@ -375,7 +375,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ast_region_to_region(lifetime, None) self.ast_region_to_region(lifetime, None)
} else { } else {
self.re_infer(None, span).unwrap_or_else(|| { self.re_infer(None, span).unwrap_or_else(|| {
let mut err = struct_span_err!( let err = struct_span_err!(
tcx.dcx(), tcx.dcx(),
span, span,
E0228, E0228,

View File

@ -550,8 +550,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
E0044, E0044,
"foreign items may not have {kinds} parameters", "foreign items may not have {kinds} parameters",
) )
.span_label(item.span, format!("can't have {kinds} parameters")) .span_label_mv(item.span, format!("can't have {kinds} parameters"))
.help( .help_mv(
// FIXME: once we start storing spans for type arguments, turn this // FIXME: once we start storing spans for type arguments, turn this
// into a suggestion. // into a suggestion.
format!( format!(
@ -788,7 +788,7 @@ fn check_impl_items_against_trait<'tcx>(
}; };
tcx.dcx() tcx.dcx()
.struct_span_err(tcx.def_span(def_id), msg) .struct_span_err(tcx.def_span(def_id), msg)
.note(format!( .note_mv(format!(
"specialization behaves in inconsistent and \ "specialization behaves in inconsistent and \
surprising ways with {feature}, \ surprising ways with {feature}, \
and for now is disallowed" and for now is disallowed"
@ -830,7 +830,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
let e = fields[FieldIdx::from_u32(0)].ty(tcx, args); let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
if !fields.iter().all(|f| f.ty(tcx, args) == e) { if !fields.iter().all(|f| f.ty(tcx, args) == e) {
struct_span_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous") struct_span_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type") .span_label_mv(sp, "SIMD elements must have the same type")
.emit(); .emit();
return; return;
} }
@ -1107,7 +1107,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
E0084, E0084,
"unsupported representation for zero-variant enum" "unsupported representation for zero-variant enum"
) )
.span_label(tcx.def_span(def_id), "zero-variant enum") .span_label_mv(tcx.def_span(def_id), "zero-variant enum")
.emit(); .emit();
} }
} }
@ -1140,7 +1140,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var)); let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var));
if disr_non_unit || (disr_units && has_non_units) { if disr_non_unit || (disr_units && has_non_units) {
let mut err = struct_span_err!( let err = struct_span_err!(
tcx.dcx(), tcx.dcx(),
tcx.def_span(def_id), tcx.def_span(def_id),
E0732, E0732,
@ -1249,7 +1249,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
} }
} }
if let Some(mut e) = error { if let Some(e) = error {
e.emit(); e.emit();
} }
@ -1294,7 +1294,7 @@ pub(super) fn check_type_params_are_used<'tcx>(
{ {
let span = tcx.def_span(param.def_id); let span = tcx.def_span(param.def_id);
struct_span_err!(tcx.dcx(), span, E0091, "type parameter `{}` is unused", param.name,) struct_span_err!(tcx.dcx(), span, E0091, "type parameter `{}` is unused", param.name,)
.span_label(span, "unused type parameter") .span_label_mv(span, "unused type parameter")
.emit(); .emit();
} }
} }
@ -1302,9 +1302,9 @@ pub(super) fn check_type_params_are_used<'tcx>(
fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed { fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
struct_span_err!(tcx.dcx(), span, E0733, "recursion in an `async fn` requires boxing") struct_span_err!(tcx.dcx(), span, E0733, "recursion in an `async fn` requires boxing")
.span_label(span, "recursive `async fn`") .span_label_mv(span, "recursive `async fn`")
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") .note_mv("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
.note( .note_mv(
"consider using the `async_recursion` crate: https://crates.io/crates/async_recursion", "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
) )
.emit() .emit()

View File

@ -934,12 +934,12 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
return_span, return_span,
"return type captures more lifetimes than trait definition", "return type captures more lifetimes than trait definition",
) )
.span_label(self.tcx.def_span(def_id), "this lifetime was captured") .span_label_mv(self.tcx.def_span(def_id), "this lifetime was captured")
.span_note( .span_note_mv(
self.tcx.def_span(self.def_id), self.tcx.def_span(self.def_id),
"hidden type must only reference lifetimes captured by this impl trait", "hidden type must only reference lifetimes captured by this impl trait",
) )
.note(format!("hidden type inferred to be `{}`", self.ty)) .note_mv(format!("hidden type inferred to be `{}`", self.ty))
.emit() .emit()
} }
_ => { _ => {

View File

@ -161,7 +161,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
"`Drop` impl requires `{root_predicate}` \ "`Drop` impl requires `{root_predicate}` \
but the {self_descr} it is implemented for does not", but the {self_descr} it is implemented for does not",
) )
.span_note(item_span, "the implementor must specify the same requirement") .span_note_mv(item_span, "the implementor must specify the same requirement")
.emit(), .emit(),
); );
} }
@ -193,7 +193,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
"`Drop` impl requires `{outlives}` \ "`Drop` impl requires `{outlives}` \
but the {self_descr} it is implemented for does not", but the {self_descr} it is implemented for does not",
) )
.span_note(item_span, "the implementor must specify the same requirement") .span_note_mv(item_span, "the implementor must specify the same requirement")
.emit(), .emit(),
); );
} }

View File

@ -30,7 +30,7 @@ fn equate_intrinsic_type<'tcx>(
} }
_ => { _ => {
struct_span_err!(tcx.dcx(), it.span, E0622, "intrinsic must be a function") struct_span_err!(tcx.dcx(), it.span, E0622, "intrinsic must be a function")
.span_label(it.span, "expected a function") .span_label_mv(it.span, "expected a function")
.emit(); .emit();
return; return;
} }

View File

@ -838,8 +838,8 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
trait_should_be_self, trait_should_be_self,
"associated item referring to unboxed trait object for its own trait", "associated item referring to unboxed trait object for its own trait",
) )
.span_label(trait_name.span, "in this trait") .span_label_mv(trait_name.span, "in this trait")
.multipart_suggestion( .multipart_suggestion_mv(
"you might have meant to use `Self` to refer to the implementing type", "you might have meant to use `Self` to refer to the implementing type",
sugg, sugg,
Applicability::MachineApplicable, Applicability::MachineApplicable,
@ -1599,7 +1599,7 @@ fn check_method_receiver<'tcx>(
the `arbitrary_self_types` feature", the `arbitrary_self_types` feature",
), ),
) )
.help(HELP_FOR_SELF_TYPE) .help_mv(HELP_FOR_SELF_TYPE)
.emit() .emit()
} else { } else {
// Report error; would not have worked with `arbitrary_self_types`. // Report error; would not have worked with `arbitrary_self_types`.
@ -1612,8 +1612,8 @@ fn check_method_receiver<'tcx>(
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed { fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
struct_span_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}") struct_span_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}")
.note("type of `self` must be `Self` or a type that dereferences to it") .note_mv("type of `self` must be `Self` or a type that dereferences to it")
.help(HELP_FOR_SELF_TYPE) .help_mv(HELP_FOR_SELF_TYPE)
.emit() .emit()
} }

View File

@ -181,7 +181,7 @@ fn check_object_overlap<'tcx>(
trait_ref.self_ty(), trait_ref.self_ty(),
tcx.def_path_str(trait_def_id) tcx.def_path_str(trait_def_id)
) )
.span_label( .span_label_mv(
span, span,
format!( format!(
"`{}` automatically implements trait `{}`", "`{}` automatically implements trait `{}`",

View File

@ -25,7 +25,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"implementing the trait `{}` is not unsafe", "implementing the trait `{}` is not unsafe",
trait_ref.print_trait_sugared() trait_ref.print_trait_sugared()
) )
.span_suggestion_verbose( .span_suggestion_verbose_mv(
item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)), item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)),
"remove `unsafe` from this trait implementation", "remove `unsafe` from this trait implementation",
"", "",
@ -42,13 +42,13 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"the trait `{}` requires an `unsafe impl` declaration", "the trait `{}` requires an `unsafe impl` declaration",
trait_ref.print_trait_sugared() trait_ref.print_trait_sugared()
) )
.note(format!( .note_mv(format!(
"the trait `{}` enforces invariants that the compiler can't check. \ "the trait `{}` enforces invariants that the compiler can't check. \
Review the trait documentation and make sure this implementation \ Review the trait documentation and make sure this implementation \
upholds those invariants before adding the `unsafe` keyword", upholds those invariants before adding the `unsafe` keyword",
trait_ref.print_trait_sugared() trait_ref.print_trait_sugared()
)) ))
.span_suggestion_verbose( .span_suggestion_verbose_mv(
item.span.shrink_to_lo(), item.span.shrink_to_lo(),
"add `unsafe` to this trait implementation", "add `unsafe` to this trait implementation",
"unsafe ", "unsafe ",
@ -65,13 +65,13 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"requires an `unsafe impl` declaration due to `#[{}]` attribute", "requires an `unsafe impl` declaration due to `#[{}]` attribute",
attr_name attr_name
) )
.note(format!( .note_mv(format!(
"the trait `{}` enforces invariants that the compiler can't check. \ "the trait `{}` enforces invariants that the compiler can't check. \
Review the trait documentation and make sure this implementation \ Review the trait documentation and make sure this implementation \
upholds those invariants before adding the `unsafe` keyword", upholds those invariants before adding the `unsafe` keyword",
trait_ref.print_trait_sugared() trait_ref.print_trait_sugared()
)) ))
.span_suggestion_verbose( .span_suggestion_verbose_mv(
item.span.shrink_to_lo(), item.span.shrink_to_lo(),
"add `unsafe` to this trait implementation", "add `unsafe` to this trait implementation",
"unsafe ", "unsafe ",

View File

@ -2114,7 +2114,7 @@ pub fn deny_non_region_late_bound(
hir::GenericParamKind::Lifetime { .. } => continue, hir::GenericParamKind::Lifetime { .. } => continue,
}; };
let mut diag = tcx.dcx().struct_span_err( let diag = tcx.dcx().struct_span_err(
param.span, param.span,
format!("late-bound {what} parameter not allowed on {where_}"), format!("late-bound {what} parameter not allowed on {where_}"),
); );

View File

@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
callee_expr.span, callee_expr.span,
format!("evaluate({predicate:?}) = {result:?}"), format!("evaluate({predicate:?}) = {result:?}"),
) )
.span_label(predicate_span, "predicate") .span_label_mv(predicate_span, "predicate")
.emit(); .emit();
} }
} }

View File

@ -269,7 +269,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
} }
CastError::NeedViaInt => { CastError::NeedViaInt => {
make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx)
.help("cast through an integer first") .help_mv("cast through an integer first")
.emit(); .emit();
} }
CastError::IllegalCast => { CastError::IllegalCast => {
@ -277,7 +277,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
} }
CastError::DifferingKinds => { CastError::DifferingKinds => {
make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx)
.note("vtable kinds may not match") .note_mv("vtable kinds may not match")
.emit(); .emit();
} }
CastError::CastToBool => { CastError::CastToBool => {
@ -512,7 +512,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
self.cast_ty, self.cast_ty,
fcx, fcx,
) )
.note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate") .note_mv("cannot cast an enum with a non-exhaustive variant when it's defined in another crate")
.emit(); .emit();
} }
} }

View File

@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Requires that the two types unify, and prints an error message if /// Requires that the two types unify, and prints an error message if
/// they don't. /// they don't.
pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
if let Some(mut e) = self.demand_suptype_diag(sp, expected, actual) { if let Some(e) = self.demand_suptype_diag(sp, expected, actual) {
e.emit(); e.emit();
} }
} }
@ -189,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
if let Some(mut err) = self.demand_eqtype_diag(sp, expected, actual) { if let Some(err) = self.demand_eqtype_diag(sp, expected, actual) {
err.emit(); err.emit();
} }
} }
@ -228,7 +228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let (ty, err) = let (ty, err) =
self.demand_coerce_diag(expr, checked_ty, expected, expected_ty_expr, allow_two_phase); self.demand_coerce_diag(expr, checked_ty, expected, expected_ty_expr, allow_two_phase);
if let Some(mut err) = err { if let Some(err) = err {
err.emit(); err.emit();
} }
ty ty

View File

@ -1338,7 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
Err(error) => { Err(error) => {
if segment.ident.name != kw::Empty { if segment.ident.name != kw::Empty {
if let Some(mut err) = self.report_method_error( if let Some(err) = self.report_method_error(
span, span,
rcvr_t, rcvr_t,
segment.ident, segment.ident,
@ -2011,7 +2011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
!= range_def_id != range_def_id
{ {
// Suppress any range expr type mismatches // Suppress any range expr type mismatches
if let Some(mut diag) = if let Some(diag) =
self.dcx().steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo) self.dcx().steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo)
{ {
diag.delay_as_bug(); diag.delay_as_bug();

View File

@ -845,7 +845,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.and_then(|r| { .and_then(|r| {
// lint bare trait if the method is found in the trait // lint bare trait if the method is found in the trait
if span.edition().at_least_rust_2021() if span.edition().at_least_rust_2021()
&& let Some(mut diag) = && let Some(diag) =
self.dcx().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) self.dcx().steal_diagnostic(qself.span, StashKey::TraitMissingMethod)
{ {
diag.emit(); diag.emit();
@ -877,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// emit or cancel the diagnostic for bare traits // emit or cancel the diagnostic for bare traits
if span.edition().at_least_rust_2021() if span.edition().at_least_rust_2021()
&& let Some(mut diag) = && let Some(diag) =
self.dcx().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) self.dcx().steal_diagnostic(qself.span, StashKey::TraitMissingMethod)
{ {
if trait_missing_method { if trait_missing_method {
@ -889,7 +889,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
if item_name.name != kw::Empty { if item_name.name != kw::Empty {
if let Some(mut e) = self.report_method_error( if let Some(e) = self.report_method_error(
span, span,
ty.normalized, ty.normalized,
item_name, item_name,

View File

@ -1384,7 +1384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"expected struct, variant or union type, found {}", "expected struct, variant or union type, found {}",
ty.normalized.sort_string(self.tcx) ty.normalized.sort_string(self.tcx)
) )
.span_label(path_span, "not a struct") .span_label_mv(path_span, "not a struct")
.emit(), .emit(),
}) })
} }
@ -1459,8 +1459,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let previous_diverges = self.diverges.get(); let previous_diverges = self.diverges.get();
let else_ty = self.check_block_with_expected(blk, NoExpectation); let else_ty = self.check_block_with_expected(blk, NoExpectation);
let cause = self.cause(blk.span, ObligationCauseCode::LetElse); let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
if let Some(mut err) = if let Some(err) = self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty)
self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty)
{ {
err.emit(); err.emit();
} }

View File

@ -74,9 +74,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& size_to == Pointer(dl.instruction_address_space).size(&tcx) && size_to == Pointer(dl.instruction_address_space).size(&tcx)
{ {
struct_span_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") struct_span_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type")
.note(format!("source type: {from}")) .note_mv(format!("source type: {from}"))
.note(format!("target type: {to}")) .note_mv(format!("target type: {to}"))
.help("cast with `as` to a pointer instead") .help_mv("cast with `as` to a pointer instead")
.emit(); .emit();
return; return;
} }
@ -125,9 +125,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from)))
.note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); .note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to)));
if let Err(LayoutError::ReferencesError(_)) = sk_from { if let Err(LayoutError::ReferencesError(_)) = sk_from {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} else if let Err(LayoutError::ReferencesError(_)) = sk_to { } else if let Err(LayoutError::ReferencesError(_)) = sk_to {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
} }
err.emit(); err.emit();

View File

@ -366,7 +366,7 @@ fn report_unexpected_variant_res(
_ => res.descr(), _ => res.descr(),
}; };
let path_str = rustc_hir_pretty::qpath_to_string(qpath); let path_str = rustc_hir_pretty::qpath_to_string(qpath);
let mut err = tcx.dcx().struct_span_err_with_code( let err = tcx.dcx().struct_span_err_with_code(
span, span,
format!("expected {expected}, found {res_descr} `{path_str}`"), format!("expected {expected}, found {res_descr} `{path_str}`"),
DiagnosticId::Error(err_code.into()), DiagnosticId::Error(err_code.into()),
@ -374,10 +374,10 @@ fn report_unexpected_variant_res(
match res { match res {
Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => { Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => {
let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html"; let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
err.span_label(span, "`fn` calls are not allowed in patterns"); err.span_label_mv(span, "`fn` calls are not allowed in patterns")
err.help(format!("for more information, visit {patterns_url}")) .help_mv(format!("for more information, visit {patterns_url}"))
} }
_ => err.span_label(span, format!("not a {expected}")), _ => err.span_label_mv(span, format!("not a {expected}")),
} }
.emit() .emit()
} }

View File

@ -385,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::ExprKind::Assign(..) = expr.kind && let hir::ExprKind::Assign(..) = expr.kind
{ {
// We defer to the later error produced by `check_lhs_assignable`. // We defer to the later error produced by `check_lhs_assignable`.
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
let suggest_deref_binop = let suggest_deref_binop =

View File

@ -117,7 +117,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
actual: Ty<'tcx>, actual: Ty<'tcx>,
ti: TopInfo<'tcx>, ti: TopInfo<'tcx>,
) { ) {
if let Some(mut err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) { if let Some(err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) {
err.emit(); err.emit();
} }
} }
@ -441,7 +441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// //
// then that's equivalent to there existing a LUB. // then that's equivalent to there existing a LUB.
let cause = self.pattern_cause(ti, span); let cause = self.pattern_cause(ti, span);
if let Some(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { if let Some(err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) {
err.emit_unless( err.emit_unless(
ti.span ti.span
.filter(|&s| { .filter(|&s| {
@ -1103,7 +1103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type-check the tuple struct pattern against the expected type. // Type-check the tuple struct pattern against the expected type.
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti); let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
let had_err = if let Some(mut err) = diag { let had_err = if let Some(err) = diag {
err.emit(); err.emit();
true true
} else { } else {
@ -1329,9 +1329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter);
let pat_ty = Ty::new_tup(tcx, element_tys); let pat_ty = Ty::new_tup(tcx, element_tys);
if let Some(mut err) = if let Some(err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, pat_info.top_info) {
self.demand_eqtype_pat_diag(span, expected, pat_ty, pat_info.top_info)
{
let reported = err.emit(); let reported = err.emit();
// Walk subpatterns with an expected type of `err` in this case to silence // Walk subpatterns with an expected type of `err` in this case to silence
// further errors being emitted when using the bindings. #50333 // further errors being emitted when using the bindings. #50333
@ -1469,8 +1467,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
match (inexistent_fields_err, unmentioned_err) { match (inexistent_fields_err, unmentioned_err) {
(Some(mut i), Some(mut u)) => { (Some(i), Some(u)) => {
if let Some(mut e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { if let Some(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) {
// We don't want to show the nonexistent fields error when this was // We don't want to show the nonexistent fields error when this was
// `Foo { a, b }` when it should have been `Foo(a, b)`. // `Foo { a, b }` when it should have been `Foo(a, b)`.
i.delay_as_bug(); i.delay_as_bug();
@ -1481,19 +1479,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
u.emit(); u.emit();
} }
} }
(None, Some(mut u)) => { (None, Some(u)) => {
if let Some(mut e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { if let Some(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) {
u.delay_as_bug(); u.delay_as_bug();
e.emit(); e.emit();
} else { } else {
u.emit(); u.emit();
} }
} }
(Some(mut err), None) => { (Some(err), None) => {
err.emit(); err.emit();
} }
(None, None) (None, None)
if let Some(mut err) = if let Some(err) =
self.error_tuple_variant_index_shorthand(variant, pat, fields) => self.error_tuple_variant_index_shorthand(variant, pat, fields) =>
{ {
err.emit(); err.emit();
@ -1571,8 +1569,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"field `{}` bound multiple times in the pattern", "field `{}` bound multiple times in the pattern",
ident ident
) )
.span_label(span, format!("multiple uses of `{ident}` in pattern")) .span_label_mv(span, format!("multiple uses of `{ident}` in pattern"))
.span_label(other_field, format!("first use of `{ident}`")) .span_label_mv(other_field, format!("first use of `{ident}`"))
.emit() .emit()
} }
@ -2237,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pluralize!(min_len), pluralize!(min_len),
size, size,
) )
.span_label(span, format!("expected {} element{}", size, pluralize!(size))) .span_label_mv(span, format!("expected {} element{}", size, pluralize!(size)))
.emit() .emit()
} }
@ -2256,7 +2254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pluralize!(min_len), pluralize!(min_len),
size, size,
) )
.span_label( .span_label_mv(
span, span,
format!("pattern cannot match array of {} element{}", size, pluralize!(size),), format!("pattern cannot match array of {} element{}", size, pluralize!(size),),
) )

View File

@ -361,7 +361,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
); );
} }
ty::ReError(_) => { ty::ReError(_) => {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
_ => { _ => {
// Ugh. This is a painful case: the hidden region is not one // Ugh. This is a painful case: the hidden region is not one

View File

@ -60,7 +60,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
pub fn try_report(&self) -> Option<ErrorGuaranteed> { pub fn try_report(&self) -> Option<ErrorGuaranteed> {
self.try_report_from_nll() self.try_report_from_nll()
.map(|mut diag| diag.emit()) .map(|diag| diag.emit())
.or_else(|| self.try_report_impl_not_conforming_to_trait()) .or_else(|| self.try_report_impl_not_conforming_to_trait())
.or_else(|| self.try_report_anon_anon_conflict()) .or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_static_impl_trait()) .or_else(|| self.try_report_static_impl_trait())

View File

@ -281,7 +281,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
}; };
if sub.is_error() || sup.is_error() { if sub.is_error() || sup.is_error() {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
err err
} }

View File

@ -108,7 +108,7 @@ impl<'tcx> Queries<'tcx> {
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> { pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
self.parse.compute(|| { self.parse.compute(|| {
passes::parse(&self.compiler.sess).map_err(|mut parse_error| parse_error.emit()) passes::parse(&self.compiler.sess).map_err(|parse_error| parse_error.emit())
}) })
} }

View File

@ -132,7 +132,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
.tcx .tcx
.dcx() .dcx()
.struct_span_err(self.span, "non-defining opaque type use in defining scope") .struct_span_err(self.span, "non-defining opaque type use in defining scope")
.span_label( .span_label_mv(
self.span, self.span,
format!( format!(
"lifetime `{r}` is part of concrete type but not used in \ "lifetime `{r}` is part of concrete type but not used in \

View File

@ -369,7 +369,7 @@ impl<'tcx> TyCtxt<'tcx> {
if let Some((old_item_id, _)) = dtor_candidate { if let Some((old_item_id, _)) = dtor_candidate {
self.dcx() self.dcx()
.struct_span_err(self.def_span(item_id), "multiple drop impls found") .struct_span_err(self.def_span(item_id), "multiple drop impls found")
.span_note(self.def_span(old_item_id), "other impl here") .span_note_mv(self.def_span(old_item_id), "other impl here")
.delay_as_bug(); .delay_as_bug();
} }

View File

@ -278,7 +278,7 @@ impl<'a> TokenTreesReader<'a> {
} }
if !diff_errs.is_empty() { if !diff_errs.is_empty() {
errs.iter_mut().for_each(|err| { errs.iter_mut().for_each(|err| {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
}); });
return diff_errs; return diff_errs;
} }

View File

@ -245,9 +245,9 @@ pub fn parse_cfg_attr(
crate::validate_attr::check_cfg_attr_bad_delim(parse_sess, dspan, delim); crate::validate_attr::check_cfg_attr_bad_delim(parse_sess, dspan, delim);
match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
Ok(r) => return Some(r), Ok(r) => return Some(r),
Err(mut e) => { Err(e) => {
e.help(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`")) e.help_mv(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`"))
.note(CFG_ATTR_NOTE_REF) .note_mv(CFG_ATTR_NOTE_REF)
.emit(); .emit();
} }
} }

View File

@ -896,7 +896,7 @@ impl<'a> Parser<'a> {
let struct_expr = snapshot.parse_expr_struct(None, path, false); let struct_expr = snapshot.parse_expr_struct(None, path, false);
let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No); let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
return Some(match (struct_expr, block_tail) { return Some(match (struct_expr, block_tail) {
(Ok(expr), Err(mut err)) => { (Ok(expr), Err(err)) => {
// We have encountered the following: // We have encountered the following:
// fn foo() -> Foo { // fn foo() -> Foo {
// field: value, // field: value,
@ -1218,7 +1218,7 @@ impl<'a> Parser<'a> {
"::", "::",
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
) )
.emit(); .emit_without_consuming();
match self.parse_expr() { match self.parse_expr() {
Ok(_) => { Ok(_) => {
*expr = self.mk_expr_err(expr.span.to(self.prev_token.span)); *expr = self.mk_expr_err(expr.span.to(self.prev_token.span));
@ -2045,7 +2045,7 @@ impl<'a> Parser<'a> {
) -> P<Expr> { ) -> P<Expr> {
match result { match result {
Ok(x) => x, Ok(x) => x,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
// Recover from parse error, callers expect the closing delim to be consumed. // Recover from parse error, callers expect the closing delim to be consumed.
self.consume_block(delim, ConsumeClosingDelim::Yes); self.consume_block(delim, ConsumeClosingDelim::Yes);
@ -2470,7 +2470,7 @@ impl<'a> Parser<'a> {
return Ok(true); // Continue return Ok(true); // Continue
} }
} }
Err(mut err) => { Err(err) => {
args.push(arg); args.push(arg);
// We will emit a more generic error later. // We will emit a more generic error later.
err.delay_as_bug(); err.delay_as_bug();
@ -2946,7 +2946,7 @@ impl<'a> Parser<'a> {
} }
pub fn recover_diff_marker(&mut self) { pub fn recover_diff_marker(&mut self) {
if let Err(mut err) = self.err_diff_marker() { if let Err(err) = self.err_diff_marker() {
err.emit(); err.emit();
FatalError.raise(); FatalError.raise();
} }

View File

@ -127,7 +127,7 @@ impl<'a> Parser<'a> {
fn parse_expr_catch_underscore(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>> { fn parse_expr_catch_underscore(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>> {
match self.parse_expr_res(restrictions, None) { match self.parse_expr_res(restrictions, None) {
Ok(expr) => Ok(expr), Ok(expr) => Ok(expr),
Err(mut err) => match self.token.ident() { Err(err) => match self.token.ident() {
Some((Ident { name: kw::Underscore, .. }, false)) Some((Ident { name: kw::Underscore, .. }, false))
if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) => if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) =>
{ {
@ -1333,12 +1333,12 @@ impl<'a> Parser<'a> {
.collect(), .collect(),
}, },
}); });
replacement_err.emit(); replacement_err.emit_without_consuming();
let old_err = mem::replace(err, replacement_err); let old_err = mem::replace(err, replacement_err);
old_err.cancel(); old_err.cancel();
} else { } else {
err.emit(); err.emit_without_consuming();
} }
return Some(self.mk_expr_err(span)); return Some(self.mk_expr_err(span));
} }
@ -1756,9 +1756,8 @@ impl<'a> Parser<'a> {
mk_lit_char: impl FnOnce(Symbol, Span) -> L, mk_lit_char: impl FnOnce(Symbol, Span) -> L,
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>, err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>,
) -> L { ) -> L {
if let Some(mut diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) if let Some(diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) {
{ diag.span_suggestion_verbose_mv(
diag.span_suggestion_verbose(
lifetime.span.shrink_to_hi(), lifetime.span.shrink_to_hi(),
"add `'` to close the char literal", "add `'` to close the char literal",
"'", "'",
@ -1767,7 +1766,7 @@ impl<'a> Parser<'a> {
.emit(); .emit();
} else { } else {
err(self) err(self)
.span_suggestion_verbose( .span_suggestion_verbose_mv(
lifetime.span.shrink_to_hi(), lifetime.span.shrink_to_hi(),
"add `'` to close the char literal", "add `'` to close the char literal",
"'", "'",
@ -2903,7 +2902,7 @@ impl<'a> Parser<'a> {
while self.token != token::CloseDelim(Delimiter::Brace) { while self.token != token::CloseDelim(Delimiter::Brace) {
match self.parse_arm() { match self.parse_arm() {
Ok(arm) => arms.push(arm), Ok(arm) => arms.push(arm),
Err(mut e) => { Err(e) => {
// Recover by skipping to the end of the block. // Recover by skipping to the end of the block.
e.emit(); e.emit();
self.recover_stmt(); self.recover_stmt();
@ -3437,7 +3436,7 @@ impl<'a> Parser<'a> {
} }
match self.parse_expr() { match self.parse_expr() {
Ok(e) => base = ast::StructRest::Base(e), Ok(e) => base = ast::StructRest::Base(e),
Err(mut e) if recover => { Err(e) if recover => {
e.emit(); e.emit();
self.recover_stmt(); self.recover_stmt();
} }

View File

@ -77,7 +77,7 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }
err.emit(); err.emit_without_consuming();
return Err(err); return Err(err);
} }
} }

View File

@ -739,11 +739,14 @@ impl<'a> Parser<'a> {
break; break;
} }
Ok(Some(item)) => items.extend(item), Ok(Some(item)) => items.extend(item),
Err(mut err) => { Err(err) => {
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
err.span_label(open_brace_span, "while parsing this item list starting here") err.span_label_mv(
.span_label(self.prev_token.span, "the item list ends here") open_brace_span,
.emit(); "while parsing this item list starting here",
)
.span_label_mv(self.prev_token.span, "the item list ends here")
.emit();
break; break;
} }
} }
@ -762,8 +765,8 @@ impl<'a> Parser<'a> {
E0584, E0584,
"found a documentation comment that doesn't document anything", "found a documentation comment that doesn't document anything",
) )
.span_label(self.token.span, "this doc comment doesn't document anything") .span_label_mv(self.token.span, "this doc comment doesn't document anything")
.help( .help_mv(
"doc comments must come before what they document, if a comment was \ "doc comments must come before what they document, if a comment was \
intended use `//`", intended use `//`",
) )
@ -1106,7 +1109,7 @@ impl<'a> Parser<'a> {
&& self.token.is_keyword(kw::Unsafe) && self.token.is_keyword(kw::Unsafe)
&& self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace)) && self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace))
{ {
let mut err = self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err(); let err = self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err();
err.emit(); err.emit();
unsafety = Unsafe::Yes(self.token.span); unsafety = Unsafe::Yes(self.token.span);
self.eat_keyword(kw::Unsafe); self.eat_keyword(kw::Unsafe);
@ -1198,7 +1201,7 @@ impl<'a> Parser<'a> {
defaultness: Defaultness, defaultness: Defaultness,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemInfo> {
let impl_span = self.token.span; let impl_span = self.token.span;
let mut err = self.expected_ident_found_err(); let err = self.expected_ident_found_err();
// Only try to recover if this is implementing a trait for a type // Only try to recover if this is implementing a trait for a type
let mut impl_info = match self.parse_item_impl(attrs, defaultness) { let mut impl_info = match self.parse_item_impl(attrs, defaultness) {
@ -1216,7 +1219,7 @@ impl<'a> Parser<'a> {
let before_trait = trai.path.span.shrink_to_lo(); let before_trait = trai.path.span.shrink_to_lo();
let const_up_to_impl = const_span.with_hi(impl_span.lo()); let const_up_to_impl = const_span.with_hi(impl_span.lo());
err.multipart_suggestion( err.multipart_suggestion_mv(
"you might have meant to write a const trait impl", "you might have meant to write a const trait impl",
vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())], vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
@ -1454,8 +1457,8 @@ impl<'a> Parser<'a> {
let ident = this.parse_field_ident("enum", vlo)?; let ident = this.parse_field_ident("enum", vlo)?;
if this.token == token::Not { if this.token == token::Not {
if let Err(mut err) = this.unexpected::<()>() { if let Err(err) = this.unexpected::<()>() {
err.note(fluent::parse_macro_expands_to_enum_variant).emit(); err.note_mv(fluent::parse_macro_expands_to_enum_variant).emit();
} }
this.bump(); this.bump();
@ -1811,7 +1814,7 @@ impl<'a> Parser<'a> {
// `check_trailing_angle_brackets` already emitted a nicer error // `check_trailing_angle_brackets` already emitted a nicer error
// NOTE(eddyb) this was `.cancel()`, but `err` // NOTE(eddyb) this was `.cancel()`, but `err`
// gets returned, so we can't fully defuse it. // gets returned, so we can't fully defuse it.
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
} }
} }
@ -1828,7 +1831,7 @@ impl<'a> Parser<'a> {
",", ",",
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
err.emit(); err.emit_without_consuming();
recovered = true; recovered = true;
} }
@ -1846,7 +1849,7 @@ impl<'a> Parser<'a> {
} }
fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> { fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
if let Err(mut err) = self.expect(&token::Colon) { if let Err(err) = self.expect(&token::Colon) {
let sm = self.sess.source_map(); let sm = self.sess.source_map();
let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start()); let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start());
let semi_typo = self.token.kind == token::Semi let semi_typo = self.token.kind == token::Semi
@ -1862,7 +1865,7 @@ impl<'a> Parser<'a> {
if eq_typo || semi_typo { if eq_typo || semi_typo {
self.bump(); self.bump();
// Gracefully handle small typos. // Gracefully handle small typos.
err.span_suggestion_short( err.span_suggestion_short_mv(
self.prev_token.span, self.prev_token.span,
"field names and their types are separated with `:`", "field names and their types are separated with `:`",
":", ":",
@ -2598,7 +2601,7 @@ impl<'a> Parser<'a> {
let (mut params, _) = self.parse_paren_comma_seq(|p| { let (mut params, _) = self.parse_paren_comma_seq(|p| {
p.recover_diff_marker(); p.recover_diff_marker();
let snapshot = p.create_snapshot_for_diagnostic(); let snapshot = p.create_snapshot_for_diagnostic();
let param = p.parse_param_general(req_name, first_param).or_else(|mut e| { let param = p.parse_param_general(req_name, first_param).or_else(|e| {
e.emit(); e.emit();
let lo = p.prev_token.span; let lo = p.prev_token.span;
p.restore_snapshot(snapshot); p.restore_snapshot(snapshot);

View File

@ -499,7 +499,7 @@ impl<'a> Parser<'a> {
let (ident, is_raw) = self.ident_or_err(recover)?; let (ident, is_raw) = self.ident_or_err(recover)?;
if !is_raw && ident.is_reserved() { if !is_raw && ident.is_reserved() {
let mut err = self.expected_ident_found_err(); let err = self.expected_ident_found_err();
if recover { if recover {
err.emit(); err.emit();
} else { } else {
@ -847,7 +847,7 @@ impl<'a> Parser<'a> {
pprust::token_to_string(&self.prev_token) pprust::token_to_string(&self.prev_token)
); );
expect_err expect_err
.span_suggestion_verbose( .span_suggestion_verbose_mv(
self.prev_token.span.shrink_to_hi().until(self.token.span), self.prev_token.span.shrink_to_hi().until(self.token.span),
msg, msg,
" @ ", " @ ",
@ -863,7 +863,7 @@ impl<'a> Parser<'a> {
// Parsed successfully, therefore most probably the code only // Parsed successfully, therefore most probably the code only
// misses a separator. // misses a separator.
expect_err expect_err
.span_suggestion_short( .span_suggestion_short_mv(
sp, sp,
format!("missing `{token_str}`"), format!("missing `{token_str}`"),
token_str, token_str,

View File

@ -144,7 +144,7 @@ impl<'a> Parser<'a> {
// Parse the first pattern (`p_0`). // Parse the first pattern (`p_0`).
let mut first_pat = match self.parse_pat_no_top_alt(expected, syntax_loc) { let mut first_pat = match self.parse_pat_no_top_alt(expected, syntax_loc) {
Ok(pat) => pat, Ok(pat) => pat,
Err(mut err) Err(err)
if self.token.is_reserved_ident() if self.token.is_reserved_ident()
&& !self.token.is_keyword(kw::In) && !self.token.is_keyword(kw::In)
&& !self.token.is_keyword(kw::If) => && !self.token.is_keyword(kw::If) =>
@ -251,7 +251,7 @@ impl<'a> Parser<'a> {
} }
}); });
if trailing_vert { if trailing_vert {
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} }
err.emit(); err.emit();
} }
@ -1028,7 +1028,7 @@ impl<'a> Parser<'a> {
let attrs = match self.parse_outer_attributes() { let attrs = match self.parse_outer_attributes() {
Ok(attrs) => attrs, Ok(attrs) => attrs,
Err(err) => { Err(err) => {
if let Some(mut delayed) = delayed_err { if let Some(delayed) = delayed_err {
delayed.emit(); delayed.emit();
} }
return Err(err); return Err(err);
@ -1040,7 +1040,7 @@ impl<'a> Parser<'a> {
if !ate_comma { if !ate_comma {
let mut err = let mut err =
self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span }); self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span });
if let Some(mut delayed) = delayed_err { if let Some(delayed) = delayed_err {
delayed.emit(); delayed.emit();
} }
self.recover_misplaced_pattern_modifiers(&fields, &mut err); self.recover_misplaced_pattern_modifiers(&fields, &mut err);
@ -1113,14 +1113,14 @@ impl<'a> Parser<'a> {
// This way we avoid "pattern missing fields" errors afterwards. // This way we avoid "pattern missing fields" errors afterwards.
// We delay this error until the end in order to have a span for a // We delay this error until the end in order to have a span for a
// suggested fix. // suggested fix.
if let Some(mut delayed_err) = delayed_err { if let Some(delayed_err) = delayed_err {
delayed_err.emit(); delayed_err.emit();
return Err(err); return Err(err);
} else { } else {
delayed_err = Some(err); delayed_err = Some(err);
} }
} else { } else {
if let Some(mut err) = delayed_err { if let Some(err) = delayed_err {
err.emit(); err.emit();
} }
return Err(err); return Err(err);
@ -1132,7 +1132,7 @@ impl<'a> Parser<'a> {
let field = match this.parse_pat_field(lo, attrs) { let field = match this.parse_pat_field(lo, attrs) {
Ok(field) => Ok(field), Ok(field) => Ok(field),
Err(err) => { Err(err) => {
if let Some(mut delayed_err) = delayed_err.take() { if let Some(delayed_err) = delayed_err.take() {
delayed_err.emit(); delayed_err.emit();
} }
return Err(err); return Err(err);

View File

@ -128,7 +128,7 @@ impl<'a> Parser<'a> {
self.prev_token.span, self.prev_token.span,
"found single colon before projection in qualified path", "found single colon before projection in qualified path",
) )
.span_suggestion( .span_suggestion_mv(
self.prev_token.span, self.prev_token.span,
"use double colon", "use double colon",
"::", "::",
@ -493,7 +493,7 @@ impl<'a> Parser<'a> {
self.angle_bracket_nesting -= 1; self.angle_bracket_nesting -= 1;
Ok(args) Ok(args)
} }
Err(mut e) if self.angle_bracket_nesting > 10 => { Err(e) if self.angle_bracket_nesting > 10 => {
self.angle_bracket_nesting -= 1; self.angle_bracket_nesting -= 1;
// When encountering severely malformed code where there are several levels of // When encountering severely malformed code where there are several levels of
// nested unclosed angle args (`f::<f::<f::<f::<...`), we avoid severe O(n^2) // nested unclosed angle args (`f::<f::<f::<f::<...`), we avoid severe O(n^2)

View File

@ -32,7 +32,7 @@ impl<'a> Parser<'a> {
/// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
// Public for rustfmt usage. // Public for rustfmt usage.
pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Stmt>> { pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Stmt>> {
Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|mut e| { Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| {
e.emit(); e.emit();
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
None None
@ -663,7 +663,7 @@ impl<'a> Parser<'a> {
match expect_result { match expect_result {
// Recover from parser, skip type error to avoid extra errors. // Recover from parser, skip type error to avoid extra errors.
Ok(true) => true, Ok(true) => true,
Err(mut e) => { Err(e) => {
if self.recover_colon_as_semi() { if self.recover_colon_as_semi() {
// recover_colon_as_semi has already emitted a nicer error. // recover_colon_as_semi has already emitted a nicer error.
e.delay_as_bug(); e.delay_as_bug();
@ -716,7 +716,7 @@ impl<'a> Parser<'a> {
_ => {} _ => {}
} }
if let Err(mut e) = if let Err(e) =
self.check_mistyped_turbofish_with_multiple_type_params(e, expr) self.check_mistyped_turbofish_with_multiple_type_params(e, expr)
{ {
if recover.no() { if recover.no() {

View File

@ -300,7 +300,7 @@ impl<'a> Parser<'a> {
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
let kind = let kind =
self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?; self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?;
let mut err = self.dcx().create_err(errors::TransposeDynOrImpl { let err = self.dcx().create_err(errors::TransposeDynOrImpl {
span: kw.span, span: kw.span,
kw: kw.name.as_str(), kw: kw.name.as_str(),
sugg: errors::TransposeDynOrImplSugg { sugg: errors::TransposeDynOrImplSugg {
@ -487,7 +487,7 @@ impl<'a> Parser<'a> {
fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> { fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
let elt_ty = match self.parse_ty() { let elt_ty = match self.parse_ty() {
Ok(ty) => ty, Ok(ty) => ty,
Err(mut err) Err(err)
if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket)) if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket))
| self.look_ahead(1, |t| t.kind == token::Semi) => | self.look_ahead(1, |t| t.kind == token::Semi) =>
{ {
@ -1109,20 +1109,19 @@ impl<'a> Parser<'a> {
lifetime_defs.append(&mut generic_params); lifetime_defs.append(&mut generic_params);
let generic_args_span = generic_args.span(); let generic_args_span = generic_args.span();
let mut err = self
.dcx()
.struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters");
let snippet = format!( let snippet = format!(
"for<{}> ", "for<{}> ",
lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(), lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::<String>(),
); );
let before_fn_path = fn_path.span.shrink_to_lo(); let before_fn_path = fn_path.span.shrink_to_lo();
err.multipart_suggestion( self.dcx()
"consider using a higher-ranked trait bound instead", .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters")
vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)], .multipart_suggestion_mv(
Applicability::MaybeIncorrect, "consider using a higher-ranked trait bound instead",
) vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)],
.emit(); Applicability::MaybeIncorrect,
)
.emit();
Ok(()) Ok(())
} }

View File

@ -29,7 +29,7 @@ pub fn check_attr(sess: &ParseSess, attr: &Attribute) {
_ if let AttrArgs::Eq(..) = attr.get_normal_item().args => { _ if let AttrArgs::Eq(..) = attr.get_normal_item().args => {
// All key-value attributes are restricted to meta-item syntax. // All key-value attributes are restricted to meta-item syntax.
parse_meta(sess, attr) parse_meta(sess, attr)
.map_err(|mut err| { .map_err(|err| {
err.emit(); err.emit();
}) })
.ok(); .ok();
@ -139,7 +139,7 @@ pub fn check_builtin_attribute(
) { ) {
match parse_meta(sess, attr) { match parse_meta(sess, attr) {
Ok(meta) => check_builtin_meta_item(sess, &meta, attr.style, name, template), Ok(meta) => check_builtin_meta_item(sess, &meta, attr.style, name, template),
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
} }
} }
@ -208,7 +208,7 @@ fn emit_malformed_attribute(
} else { } else {
sess.dcx sess.dcx
.struct_span_err(span, error_msg) .struct_span_err(span, error_msg)
.span_suggestions( .span_suggestions_mv(
span, span,
if suggestions.len() == 1 { if suggestions.len() == 1 {
"must be of the form" "must be of the form"

View File

@ -48,7 +48,7 @@ impl DebuggerVisualizerCollector<'_> {
let file = let file =
match resolve_path(&self.sess.parse_sess, visualizer_path.as_str(), attr.span) { match resolve_path(&self.sess.parse_sess, visualizer_path.as_str(), attr.span) {
Ok(file) => file, Ok(file) => file,
Err(mut err) => { Err(err) => {
err.emit(); err.emit();
return; return;
} }

View File

@ -1040,7 +1040,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> {
// This error is redundant, we will have already emitted a // This error is redundant, we will have already emitted a
// suggestion to use the label when `segment` wasn't found // suggestion to use the label when `segment` wasn't found
// (hence the `Res::Err` check). // (hence the `Res::Err` check).
diag.delay_as_bug(); diag.delay_as_bug_without_consuming();
} }
_ => { _ => {
diag.span_suggestion( diag.span_suggestion(

View File

@ -124,7 +124,7 @@ fn handle_cycle_error<Q, Qcx>(
query: Q, query: Q,
qcx: Qcx, qcx: Qcx,
cycle_error: &CycleError, cycle_error: &CycleError,
mut error: DiagnosticBuilder<'_>, error: DiagnosticBuilder<'_>,
) -> Q::Value ) -> Q::Value
where where
Q: QueryConfig<Qcx>, Q: QueryConfig<Qcx>,

View File

@ -818,7 +818,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r self.r
.dcx() .dcx()
.struct_span_err(item.span, "`extern crate self;` requires renaming") .struct_span_err(item.span, "`extern crate self;` requires renaming")
.span_suggestion( .span_suggestion_mv(
item.span, item.span,
"rename the `self` crate to be able to import it", "rename the `self` crate to be able to import it",
"extern crate self as name;", "extern crate self as name;",
@ -999,7 +999,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let msg = format!("`{name}` is already in scope"); let msg = format!("`{name}` is already in scope");
let note = let note =
"macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
self.r.dcx().struct_span_err(span, msg).note(note).emit(); self.r.dcx().struct_span_err(span, msg).note_mv(note).emit();
} }
} }
@ -1110,10 +1110,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`"; let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`";
let mut err = self.r.dcx().struct_span_warn(attr.span, msg); let mut err = self.r.dcx().struct_span_warn(attr.span, msg);
if let ast::AttrStyle::Inner = attr.style { if let ast::AttrStyle::Inner = attr.style {
err.help("try an outer attribute: `#[macro_use]`").emit(); err.help("try an outer attribute: `#[macro_use]`");
} else {
err.emit();
} }
err.emit();
} else if !attr.has_name(sym::macro_use) { } else if !attr.has_name(sym::macro_use) {
continue; continue;
} }

View File

@ -1233,7 +1233,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
); );
} else { } else {
if ns == TypeNS { if ns == TypeNS {
let mut err = if crate_private_reexport { let err = if crate_private_reexport {
self.dcx().create_err(CannotBeReexportedCratePublicNS { self.dcx().create_err(CannotBeReexportedCratePublicNS {
span: import.span, span: import.span,
ident, ident,

View File

@ -2600,7 +2600,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
E0637, E0637,
"`'_` cannot be used here" "`'_` cannot be used here"
) )
.span_label(param.ident.span, "`'_` is a reserved lifetime name") .span_label_mv(param.ident.span, "`'_` is a reserved lifetime name")
.emit(); .emit();
// Record lifetime res, so lowering knows there is something fishy. // Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_param(param.id, LifetimeRes::Error); self.record_lifetime_param(param.id, LifetimeRes::Error);
@ -2615,7 +2615,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
"invalid lifetime parameter name: `{}`", "invalid lifetime parameter name: `{}`",
param.ident, param.ident,
) )
.span_label(param.ident.span, "'static is a reserved lifetime name") .span_label_mv(param.ident.span, "'static is a reserved lifetime name")
.emit(); .emit();
// Record lifetime res, so lowering knows there is something fishy. // Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_param(param.id, LifetimeRes::Error); self.record_lifetime_param(param.id, LifetimeRes::Error);

View File

@ -128,7 +128,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
let msg = format!("{} `{}` was already registered", "tool", ident); let msg = format!("{} `{}` was already registered", "tool", ident);
tcx.dcx() tcx.dcx()
.struct_span_err(ident.span, msg) .struct_span_err(ident.span, msg)
.span_label(old_ident.span, "already registered here") .span_label_mv(old_ident.span, "already registered here")
.emit(); .emit();
} }
} }
@ -137,7 +137,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
let span = nested_meta.span(); let span = nested_meta.span();
tcx.dcx() tcx.dcx()
.struct_span_err(span, msg) .struct_span_err(span, msg)
.span_label(span, "not an identifier") .span_label_mv(span, "not an identifier")
.emit(); .emit();
} }
} }
@ -955,7 +955,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
E0773, E0773,
"attempted to define built-in macro more than once" "attempted to define built-in macro more than once"
) )
.span_note(span, "previously defined here") .span_note_mv(span, "previously defined here")
.emit(); .emit();
} }
} }

View File

@ -1491,7 +1491,10 @@ impl EarlyDiagCtxt {
jobserver::initialize_checked(|err| { jobserver::initialize_checked(|err| {
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
self.dcx.struct_warn(err).note("the build environment is likely misconfigured").emit() self.dcx
.struct_warn(err)
.note_mv("the build environment is likely misconfigured")
.emit()
}); });
} }
} }

View File

@ -122,8 +122,8 @@ pub fn is_const_evaluatable<'tcx>(
if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span },
"failed to evaluate generic const expression", "failed to evaluate generic const expression",
) )
.note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") .note_mv("the crate this constant originates from uses `#![feature(generic_const_exprs)]`")
.span_suggestion_verbose( .span_suggestion_verbose_mv(
rustc_span::DUMMY_SP, rustc_span::DUMMY_SP,
"consider enabling this feature", "consider enabling this feature",
"#![feature(generic_const_exprs)]\n", "#![feature(generic_const_exprs)]\n",

View File

@ -2088,7 +2088,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let ty = self.resolve_vars_if_possible(returned_ty); let ty = self.resolve_vars_if_possible(returned_ty);
if ty.references_error() { if ty.references_error() {
// don't print out the [type error] here // don't print out the [type error] here
err.delay_as_bug(); err.delay_as_bug_without_consuming();
} else { } else {
err.span_label(expr.span, format!("this returned value is of type `{ty}`")); err.span_label(expr.span, format!("this returned value is of type `{ty}`"));
} }

View File

@ -969,7 +969,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.tcx().def_span(impl_def_id), self.tcx().def_span(impl_def_id),
"multiple drop impls found", "multiple drop impls found",
) )
.span_note(self.tcx().def_span(old_impl_def_id), "other impl here") .span_note_mv(
self.tcx().def_span(old_impl_def_id),
"other impl here",
)
.delay_as_bug(); .delay_as_bug();
} }

View File

@ -345,7 +345,7 @@ fn report_negative_positive_conflict<'tcx>(
positive_impl_def_id: DefId, positive_impl_def_id: DefId,
sg: &mut specialization_graph::Graph, sg: &mut specialization_graph::Graph,
) { ) {
let mut err = tcx.dcx().create_err(NegativePositiveConflict { let err = tcx.dcx().create_err(NegativePositiveConflict {
impl_span: tcx.def_span(local_impl_def_id), impl_span: tcx.def_span(local_impl_def_id),
trait_desc: overlap.trait_ref, trait_desc: overlap.trait_ref,
self_ty: overlap.self_ty, self_ty: overlap.self_ty,

View File

@ -3001,7 +3001,7 @@ fn clean_use_statement_inner<'tcx>(
E0780, E0780,
"anonymous imports cannot be inlined" "anonymous imports cannot be inlined"
) )
.span_label(import.span, "anonymous import") .span_label_mv(import.span, "anonymous import")
.emit(); .emit();
} }

View File

@ -577,13 +577,13 @@ impl Options {
{ {
if !theme_file.is_file() { if !theme_file.is_file() {
dcx.struct_err(format!("invalid argument: \"{theme_s}\"")) dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
.help("arguments to --theme must be files") .help_mv("arguments to --theme must be files")
.emit(); .emit();
return Err(1); return Err(1);
} }
if theme_file.extension() != Some(OsStr::new("css")) { if theme_file.extension() != Some(OsStr::new("css")) {
dcx.struct_err(format!("invalid argument: \"{theme_s}\"")) dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
.help("arguments to --theme must have a .css extension") .help_mv("arguments to --theme must have a .css extension")
.emit(); .emit();
return Err(1); return Err(1);
} }
@ -595,8 +595,8 @@ impl Options {
dcx.struct_warn(format!( dcx.struct_warn(format!(
"theme file \"{theme_s}\" is missing CSS rules from the default theme", "theme file \"{theme_s}\" is missing CSS rules from the default theme",
)) ))
.warn("the theme may appear incorrect when loaded") .warn_mv("the theme may appear incorrect when loaded")
.help(format!( .help_mv(format!(
"to see what rules are missing, call `rustdoc --check-theme \"{theme_s}\"`", "to see what rules are missing, call `rustdoc --check-theme \"{theme_s}\"`",
)) ))
.emit(); .emit();
@ -809,7 +809,7 @@ fn check_deprecated_options(matches: &getopts::Matches, dcx: &rustc_errors::Diag
for &flag in deprecated_flags.iter() { for &flag in deprecated_flags.iter() {
if matches.opt_present(flag) { if matches.opt_present(flag) {
dcx.struct_warn(format!("the `{flag}` flag is deprecated")) dcx.struct_warn(format!("the `{flag}` flag is deprecated"))
.note( .note_mv(
"see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
for more information", for more information",
) )

View File

@ -1228,7 +1228,7 @@ impl LinkCollector<'_, '_> {
span, span,
"linking to associated items of raw pointers is experimental", "linking to associated items of raw pointers is experimental",
) )
.note("rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does") .note_mv("rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does")
.emit(); .emit();
} }

View File

@ -109,7 +109,7 @@ impl Msrv {
if let Some(duplicate) = msrv_attrs.last() { if let Some(duplicate) = msrv_attrs.last() {
sess.dcx() sess.dcx()
.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
.span_note(msrv_attr.span, "first definition found here") .span_note_mv(msrv_attr.span, "first definition found here")
.emit(); .emit();
} }

View File

@ -136,7 +136,7 @@ pub fn get_unique_attr<'a>(
if let Some(duplicate) = unique_attr { if let Some(duplicate) = unique_attr {
sess.dcx() sess.dcx()
.struct_span_err(attr.span, format!("`{name}` is defined multiple times")) .struct_span_err(attr.span, format!("`{name}` is defined multiple times"))
.span_note(duplicate.span, "first definition found here") .span_note_mv(duplicate.span, "first definition found here")
.emit(); .emit();
} else { } else {
unique_attr = Some(attr); unique_attr = Some(attr);

View File

@ -114,7 +114,7 @@ impl<'a> Parser<'a> {
let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
match parser.parse_mod(&TokenKind::Eof) { match parser.parse_mod(&TokenKind::Eof) {
Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
Err(mut e) => { Err(e) => {
e.emit(); e.emit();
if sess.can_reset_errors() { if sess.can_reset_errors() {
sess.reset_errors(); sess.reset_errors();
@ -165,7 +165,7 @@ impl<'a> Parser<'a> {
match catch_unwind(move || parser.parse_crate_mod()) { match catch_unwind(move || parser.parse_crate_mod()) {
Ok(Ok(k)) => Ok(k), Ok(Ok(k)) => Ok(k),
Ok(Err(mut db)) => { Ok(Err(db)) => {
db.emit(); db.emit();
Err(ParserError::ParseError) Err(ParserError::ParseError)
} }