From b1b9278851a9512a0c934c12f9c1800169c336f7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 3 Jan 2024 12:17:35 +1100 Subject: 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`. --- compiler/rustc_parse/src/parser/diagnostics.rs | 10 ++++---- compiler/rustc_parse/src/parser/expr.rs | 17 ++++++------- compiler/rustc_parse/src/parser/generics.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 35 ++++++++++++++------------ compiler/rustc_parse/src/parser/mod.rs | 6 ++--- compiler/rustc_parse/src/parser/pat.rs | 14 +++++------ compiler/rustc_parse/src/parser/path.rs | 4 +-- compiler/rustc_parse/src/parser/stmt.rs | 6 ++--- compiler/rustc_parse/src/parser/ty.rs | 21 ++++++++-------- 9 files changed, 58 insertions(+), 57 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index aed5e11133b..02eab2bac58 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -896,7 +896,7 @@ impl<'a> Parser<'a> { let struct_expr = snapshot.parse_expr_struct(None, path, false); let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No); return Some(match (struct_expr, block_tail) { - (Ok(expr), Err(mut err)) => { + (Ok(expr), Err(err)) => { // We have encountered the following: // fn foo() -> Foo { // field: value, @@ -1218,7 +1218,7 @@ impl<'a> Parser<'a> { "::", Applicability::MaybeIncorrect, ) - .emit(); + .emit_without_consuming(); match self.parse_expr() { Ok(_) => { *expr = self.mk_expr_err(expr.span.to(self.prev_token.span)); @@ -2045,7 +2045,7 @@ impl<'a> Parser<'a> { ) -> P { match result { Ok(x) => x, - Err(mut err) => { + Err(err) => { err.emit(); // Recover from parse error, callers expect the closing delim to be consumed. self.consume_block(delim, ConsumeClosingDelim::Yes); @@ -2470,7 +2470,7 @@ impl<'a> Parser<'a> { return Ok(true); // Continue } } - Err(mut err) => { + Err(err) => { args.push(arg); // We will emit a more generic error later. err.delay_as_bug(); @@ -2946,7 +2946,7 @@ impl<'a> Parser<'a> { } 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(); FatalError.raise(); } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 880743ddd3c..697c44a9f3e 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -127,7 +127,7 @@ impl<'a> Parser<'a> { fn parse_expr_catch_underscore(&mut self, restrictions: Restrictions) -> PResult<'a, P> { match self.parse_expr_res(restrictions, None) { Ok(expr) => Ok(expr), - Err(mut err) => match self.token.ident() { + Err(err) => match self.token.ident() { Some((Ident { name: kw::Underscore, .. }, false)) if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) => { @@ -1333,12 +1333,12 @@ impl<'a> Parser<'a> { .collect(), }, }); - replacement_err.emit(); + replacement_err.emit_without_consuming(); let old_err = mem::replace(err, replacement_err); old_err.cancel(); } else { - err.emit(); + err.emit_without_consuming(); } return Some(self.mk_expr_err(span)); } @@ -1756,9 +1756,8 @@ impl<'a> Parser<'a> { mk_lit_char: impl FnOnce(Symbol, Span) -> L, err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>, ) -> L { - if let Some(mut diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) - { - diag.span_suggestion_verbose( + if let Some(diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) { + diag.span_suggestion_verbose_mv( lifetime.span.shrink_to_hi(), "add `'` to close the char literal", "'", @@ -1767,7 +1766,7 @@ impl<'a> Parser<'a> { .emit(); } else { err(self) - .span_suggestion_verbose( + .span_suggestion_verbose_mv( lifetime.span.shrink_to_hi(), "add `'` to close the char literal", "'", @@ -2903,7 +2902,7 @@ impl<'a> Parser<'a> { while self.token != token::CloseDelim(Delimiter::Brace) { match self.parse_arm() { Ok(arm) => arms.push(arm), - Err(mut e) => { + Err(e) => { // Recover by skipping to the end of the block. e.emit(); self.recover_stmt(); @@ -3437,7 +3436,7 @@ impl<'a> Parser<'a> { } match self.parse_expr() { Ok(e) => base = ast::StructRest::Base(e), - Err(mut e) if recover => { + Err(e) if recover => { e.emit(); self.recover_stmt(); } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 7e243c1c32a..2a8e220181a 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -77,7 +77,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.emit(); + err.emit_without_consuming(); return Err(err); } } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2ce27ff66e1..45aafbd0fdf 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -739,11 +739,14 @@ impl<'a> Parser<'a> { break; } Ok(Some(item)) => items.extend(item), - Err(mut err) => { + Err(err) => { self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); - err.span_label(open_brace_span, "while parsing this item list starting here") - .span_label(self.prev_token.span, "the item list ends here") - .emit(); + err.span_label_mv( + open_brace_span, + "while parsing this item list starting here", + ) + .span_label_mv(self.prev_token.span, "the item list ends here") + .emit(); break; } } @@ -762,8 +765,8 @@ impl<'a> Parser<'a> { E0584, "found a documentation comment that doesn't document anything", ) - .span_label(self.token.span, "this doc comment doesn't document anything") - .help( + .span_label_mv(self.token.span, "this doc comment doesn't document anything") + .help_mv( "doc comments must come before what they document, if a comment was \ intended use `//`", ) @@ -1106,7 +1109,7 @@ impl<'a> Parser<'a> { && self.token.is_keyword(kw::Unsafe) && 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(); unsafety = Unsafe::Yes(self.token.span); self.eat_keyword(kw::Unsafe); @@ -1198,7 +1201,7 @@ impl<'a> Parser<'a> { defaultness: Defaultness, ) -> PResult<'a, ItemInfo> { 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 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 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", vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())], Applicability::MaybeIncorrect, @@ -1454,8 +1457,8 @@ impl<'a> Parser<'a> { let ident = this.parse_field_ident("enum", vlo)?; if this.token == token::Not { - if let Err(mut err) = this.unexpected::<()>() { - err.note(fluent::parse_macro_expands_to_enum_variant).emit(); + if let Err(err) = this.unexpected::<()>() { + err.note_mv(fluent::parse_macro_expands_to_enum_variant).emit(); } this.bump(); @@ -1811,7 +1814,7 @@ impl<'a> Parser<'a> { // `check_trailing_angle_brackets` already emitted a nicer error // NOTE(eddyb) this was `.cancel()`, but `err` // 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, ); - err.emit(); + err.emit_without_consuming(); recovered = true; } @@ -1846,7 +1849,7 @@ impl<'a> Parser<'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 eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start()); let semi_typo = self.token.kind == token::Semi @@ -1862,7 +1865,7 @@ impl<'a> Parser<'a> { if eq_typo || semi_typo { self.bump(); // Gracefully handle small typos. - err.span_suggestion_short( + err.span_suggestion_short_mv( self.prev_token.span, "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| { p.recover_diff_marker(); 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(); let lo = p.prev_token.span; p.restore_snapshot(snapshot); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index b201d36455e..c13adfb0532 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -499,7 +499,7 @@ impl<'a> Parser<'a> { let (ident, is_raw) = self.ident_or_err(recover)?; if !is_raw && ident.is_reserved() { - let mut err = self.expected_ident_found_err(); + let err = self.expected_ident_found_err(); if recover { err.emit(); } else { @@ -847,7 +847,7 @@ impl<'a> Parser<'a> { pprust::token_to_string(&self.prev_token) ); expect_err - .span_suggestion_verbose( + .span_suggestion_verbose_mv( self.prev_token.span.shrink_to_hi().until(self.token.span), msg, " @ ", @@ -863,7 +863,7 @@ impl<'a> Parser<'a> { // Parsed successfully, therefore most probably the code only // misses a separator. expect_err - .span_suggestion_short( + .span_suggestion_short_mv( sp, format!("missing `{token_str}`"), token_str, diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 7d17b1d4c4d..e9b68a129ef 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -144,7 +144,7 @@ impl<'a> Parser<'a> { // Parse the first pattern (`p_0`). let mut first_pat = match self.parse_pat_no_top_alt(expected, syntax_loc) { Ok(pat) => pat, - Err(mut err) + Err(err) if self.token.is_reserved_ident() && !self.token.is_keyword(kw::In) && !self.token.is_keyword(kw::If) => @@ -251,7 +251,7 @@ impl<'a> Parser<'a> { } }); if trailing_vert { - err.delay_as_bug(); + err.delay_as_bug_without_consuming(); } err.emit(); } @@ -1028,7 +1028,7 @@ impl<'a> Parser<'a> { let attrs = match self.parse_outer_attributes() { Ok(attrs) => attrs, Err(err) => { - if let Some(mut delayed) = delayed_err { + if let Some(delayed) = delayed_err { delayed.emit(); } return Err(err); @@ -1040,7 +1040,7 @@ impl<'a> Parser<'a> { if !ate_comma { let mut err = self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span }); - if let Some(mut delayed) = delayed_err { + if let Some(delayed) = delayed_err { delayed.emit(); } 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. // We delay this error until the end in order to have a span for a // suggested fix. - if let Some(mut delayed_err) = delayed_err { + if let Some(delayed_err) = delayed_err { delayed_err.emit(); return Err(err); } else { delayed_err = Some(err); } } else { - if let Some(mut err) = delayed_err { + if let Some(err) = delayed_err { err.emit(); } return Err(err); @@ -1132,7 +1132,7 @@ impl<'a> Parser<'a> { let field = match this.parse_pat_field(lo, attrs) { Ok(field) => Ok(field), Err(err) => { - if let Some(mut delayed_err) = delayed_err.take() { + if let Some(delayed_err) = delayed_err.take() { delayed_err.emit(); } return Err(err); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 4253c0ae421..5ad17a30980 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -128,7 +128,7 @@ impl<'a> Parser<'a> { self.prev_token.span, "found single colon before projection in qualified path", ) - .span_suggestion( + .span_suggestion_mv( self.prev_token.span, "use double colon", "::", @@ -493,7 +493,7 @@ impl<'a> Parser<'a> { self.angle_bracket_nesting -= 1; Ok(args) } - Err(mut e) if self.angle_bracket_nesting > 10 => { + Err(e) if self.angle_bracket_nesting > 10 => { self.angle_bracket_nesting -= 1; // When encountering severely malformed code where there are several levels of // nested unclosed angle args (`f:: Parser<'a> { /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. // Public for rustfmt usage. pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> { - 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(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); None @@ -663,7 +663,7 @@ impl<'a> Parser<'a> { match expect_result { // Recover from parser, skip type error to avoid extra errors. Ok(true) => true, - Err(mut e) => { + Err(e) => { if self.recover_colon_as_semi() { // recover_colon_as_semi has already emitted a nicer error. 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) { if recover.no() { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 4be2c662d03..61d72857c36 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -300,7 +300,7 @@ impl<'a> Parser<'a> { let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); let kind = 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, kw: kw.name.as_str(), sugg: errors::TransposeDynOrImplSugg { @@ -487,7 +487,7 @@ impl<'a> Parser<'a> { fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> { let elt_ty = match self.parse_ty() { Ok(ty) => ty, - Err(mut err) + Err(err) if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket)) | self.look_ahead(1, |t| t.kind == token::Semi) => { @@ -1109,20 +1109,19 @@ impl<'a> Parser<'a> { lifetime_defs.append(&mut generic_params); 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!( "for<{}> ", lifetimes.iter().map(|lt| lt.ident.as_str()).intersperse(", ").collect::(), ); let before_fn_path = fn_path.span.shrink_to_lo(); - err.multipart_suggestion( - "consider using a higher-ranked trait bound instead", - vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)], - Applicability::MaybeIncorrect, - ) - .emit(); + self.dcx() + .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters") + .multipart_suggestion_mv( + "consider using a higher-ranked trait bound instead", + vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)], + Applicability::MaybeIncorrect, + ) + .emit(); Ok(()) } -- cgit 1.4.1-3-g733a5 From 589591efde6c54baa8b7932ec3be6f45dc9d781f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 3 Jan 2024 16:00:29 +1100 Subject: Use chaining in `DiagnosticBuilder` construction. To avoid the use of a mutable local variable, and because it reads more nicely. --- compiler/rustc_attr/src/session_diagnostics.rs | 13 +- compiler/rustc_borrowck/src/borrowck_errors.rs | 70 ++++---- .../src/diagnostics/conflict_errors.rs | 15 +- .../rustc_borrowck/src/diagnostics/move_errors.rs | 31 ++-- compiler/rustc_builtin_macros/src/errors.rs | 17 +- compiler/rustc_codegen_llvm/src/errors.rs | 14 +- compiler/rustc_codegen_ssa/src/errors.rs | 180 +++++++-------------- compiler/rustc_errors/src/diagnostic_builder.rs | 4 +- compiler/rustc_errors/src/diagnostic_impls.rs | 63 +++----- compiler/rustc_errors/src/lib.rs | 40 ++--- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 6 +- compiler/rustc_hir_typeck/src/expr.rs | 8 +- .../rustc_infer/src/infer/error_reporting/note.rs | 5 +- compiler/rustc_parse/src/lexer/mod.rs | 6 +- compiler/rustc_parse/src/parser/attr.rs | 27 ++-- compiler/rustc_parse/src/parser/item.rs | 22 ++- compiler/rustc_parse/src/parser/pat.rs | 7 +- compiler/rustc_resolve/src/diagnostics.rs | 9 +- compiler/rustc_resolve/src/late/diagnostics.rs | 16 +- compiler/rustc_session/src/errors.rs | 7 +- compiler/rustc_symbol_mangling/src/errors.rs | 4 +- .../traits/error_reporting/type_err_ctxt_ext.rs | 28 ++-- 22 files changed, 223 insertions(+), 369 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index fdb5d66bf62..5f61a56c189 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -54,13 +54,12 @@ pub(crate) struct UnknownMetaItem<'a> { impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> { fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); - let mut diag = DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item); - diag.span(self.span); - diag.code(error_code!(E0541)); - diag.arg("item", self.item); - diag.arg("expected", expected.join(", ")); - diag.span_label(self.span, fluent::attr_label); - diag + DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item) + .span_mv(self.span) + .code_mv(error_code!(E0541)) + .arg_mv("item", self.item) + .arg_mv("expected", expected.join(", ")) + .span_label_mv(self.span, fluent::attr_label) } } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 900b7891019..a9fc0a6f415 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -31,17 +31,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, borrow_desc: &str, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0503, "cannot use {} because it was mutably borrowed", desc, - ); - - err.span_label(borrow_span, format!("{borrow_desc} is borrowed here")); - err.span_label(span, format!("use of borrowed {borrow_desc}")); - err + ) + .span_label_mv(borrow_span, format!("{borrow_desc} is borrowed here")) + .span_label_mv(span, format!("use of borrowed {borrow_desc}")) } pub(crate) fn cannot_mutably_borrow_multiply( @@ -238,17 +236,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, desc: &str, ) -> DiagnosticBuilder<'cx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0506, "cannot assign to {} because it is borrowed", desc, - ); - - err.span_label(borrow_span, format!("{desc} is borrowed here")); - err.span_label(span, format!("{desc} is assigned to here but it was already borrowed")); - err + ) + .span_label_mv(borrow_span, format!("{desc} is borrowed here")) + .span_label_mv(span, format!("{desc} is assigned to here but it was already borrowed")) } pub(crate) fn cannot_reassign_immutable( @@ -287,16 +283,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { (&ty::Slice(_), _) => "slice", _ => span_bug!(move_from_span, "this path should not cause illegal move"), }; - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), move_from_span, E0508, "cannot move out of type `{}`, a non-copy {}", ty, type_name, - ); - err.span_label(move_from_span, "cannot move out of here"); - err + ) + .span_label_mv(move_from_span, "cannot move out of here") } pub(crate) fn cannot_move_out_of_interior_of_drop( @@ -304,15 +299,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, container_ty: Ty<'_>, ) -> DiagnosticBuilder<'cx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), move_from_span, E0509, "cannot move out of type `{}`, which implements the `Drop` trait", container_ty, - ); - err.span_label(move_from_span, "cannot move out of here"); - err + ) + .span_label_mv(move_from_span, "cannot move out of here") } pub(crate) fn cannot_act_on_moved_value( @@ -352,7 +346,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { immutable_section: &str, action: &str, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), mutate_span, E0510, @@ -360,10 +354,9 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { action, immutable_place, immutable_section, - ); - err.span_label(mutate_span, format!("cannot {action}")); - err.span_label(immutable_span, format!("value is immutable in {immutable_section}")); - err + ) + .span_label_mv(mutate_span, format!("cannot {action}")) + .span_label_mv(immutable_span, format!("value is immutable in {immutable_section}")) } pub(crate) fn cannot_borrow_across_coroutine_yield( @@ -372,14 +365,13 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { yield_span: Span, ) -> DiagnosticBuilder<'tcx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0626, "borrow may still be in use when {coroutine_kind:#} yields", - ); - err.span_label(yield_span, "possible yield occurs here"); - err + ) + .span_label_mv(yield_span, "possible yield occurs here") } pub(crate) fn cannot_borrow_across_destructor( @@ -409,7 +401,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { reference_desc: &str, path_desc: &str, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0515, @@ -417,14 +409,11 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { RETURN = return_kind, REFERENCE = reference_desc, LOCAL = path_desc, - ); - - err.span_label( + ) + .span_label_mv( span, format!("{return_kind}s a {reference_desc} data owned by the current function"), - ); - - err + ) } pub(crate) fn cannot_capture_in_long_lived_closure( @@ -435,16 +424,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { capture_span: Span, scope: &str, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), closure_span, E0373, "{closure_kind} may outlive the current {scope}, but it borrows {borrowed_path}, \ which is owned by the current {scope}", - ); - err.span_label(capture_span, format!("{borrowed_path} is borrowed here")) - .span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")); - err + ) + .span_label_mv(capture_span, format!("{borrowed_path} is borrowed here")) + .span_label_mv(closure_span, format!("may outlive borrowed value {borrowed_path}")) } pub(crate) fn thread_local_value_does_not_live_long_enough( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 9ce753134fb..5baa108ed3c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2218,15 +2218,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { drop_span, borrow_span ); - let mut err = self.thread_local_value_does_not_live_long_enough(borrow_span); - - err.span_label( - borrow_span, - "thread-local variables cannot be borrowed beyond the end of the function", - ); - err.span_label(drop_span, "end of enclosing function is here"); - - err + self.thread_local_value_does_not_live_long_enough(borrow_span) + .span_label_mv( + borrow_span, + "thread-local variables cannot be borrowed beyond the end of the function", + ) + .span_label_mv(drop_span, "end of enclosing function is here") } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index f3b21d22c1a..50dde5ce636 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -329,15 +329,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let PlaceRef { local, projection: [] } = deref_base { let decl = &self.body.local_decls[local]; if decl.is_ref_for_guard() { - let mut err = self.cannot_move_out_of( - span, - &format!("`{}` in pattern guard", self.local_names[local].unwrap()), - ); - err.note( - "variables bound in patterns cannot be moved from \ + return self + .cannot_move_out_of( + span, + &format!("`{}` in pattern guard", self.local_names[local].unwrap()), + ) + .note_mv( + "variables bound in patterns cannot be moved from \ until after the end of the pattern guard", - ); - return err; + ); } else if decl.is_ref_to_static() { return self.report_cannot_move_from_static(move_place, span); } @@ -381,15 +381,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { closure_kind_ty, closure_kind, place_description, ); - let mut diag = self.cannot_move_out_of(span, &place_description); - - diag.span_label(upvar_span, "captured outer variable"); - diag.span_label( - self.infcx.tcx.def_span(def_id), - format!("captured by this `{closure_kind}` closure"), - ); - - diag + self.cannot_move_out_of(span, &place_description) + .span_label_mv(upvar_span, "captured outer variable") + .span_label_mv( + self.infcx.tcx.def_span(def_id), + format!("captured by this `{closure_kind}` closure"), + ) } _ => { let source = self.borrowed_content_source(deref_base); diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index f9ddffcc155..13e5a40ca9e 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -803,24 +803,23 @@ pub(crate) struct AsmClobberNoReg { impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for AsmClobberNoReg { fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { - let mut diag = DiagnosticBuilder::new( - dcx, - level, - crate::fluent_generated::builtin_macros_asm_clobber_no_reg, - ); - diag.span(self.spans.clone()); // eager translation as `span_labels` takes `AsRef` let lbl1 = dcx.eagerly_translate_to_string( crate::fluent_generated::builtin_macros_asm_clobber_abi, [].into_iter(), ); - diag.span_labels(self.clobbers, &lbl1); let lbl2 = dcx.eagerly_translate_to_string( crate::fluent_generated::builtin_macros_asm_clobber_outputs, [].into_iter(), ); - diag.span_labels(self.spans, &lbl2); - diag + DiagnosticBuilder::new( + dcx, + level, + crate::fluent_generated::builtin_macros_asm_clobber_no_reg, + ) + .span_mv(self.spans.clone()) + .span_labels_mv(self.clobbers, &lbl1) + .span_labels_mv(self.spans, &lbl2) } } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 422e8edff5f..6e2c0dc21ad 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -105,10 +105,8 @@ impl IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_ let (message, _) = diag.messages().first().expect("`LlvmError` with no message"); let message = dcx.eagerly_translate_to_string(message.clone(), diag.args()); - let mut diag = - DiagnosticBuilder::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config); - diag.arg("error", message); - diag + DiagnosticBuilder::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config) + .arg_mv("error", message) } } @@ -204,10 +202,10 @@ impl IntoDiagnostic<'_, G> for WithLlvmError<'_> { PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err, ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err, }; - let mut diag = self.0.into_diagnostic(dcx, level); - diag.primary_message(msg_with_llvm_err); - diag.arg("llvm_err", self.1); - diag + self.0 + .into_diagnostic(dcx, level) + .primary_message_mv(msg_with_llvm_err) + .arg_mv("llvm_err", self.1) } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index c1086bebb8d..7e3b69fa52f 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -212,192 +212,124 @@ pub struct ThorinErrorWrapper(pub thorin::Error); impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { let build = |msg| DiagnosticBuilder::new(dcx, level, msg); - let mut diag; match self.0 { - thorin::Error::ReadInput(_) => { - diag = build(fluent::codegen_ssa_thorin_read_input_failure); - diag - } + thorin::Error::ReadInput(_) => build(fluent::codegen_ssa_thorin_read_input_failure), thorin::Error::ParseFileKind(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_input_file_kind); - diag + build(fluent::codegen_ssa_thorin_parse_input_file_kind) } thorin::Error::ParseObjectFile(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_input_object_file); - diag + build(fluent::codegen_ssa_thorin_parse_input_object_file) } thorin::Error::ParseArchiveFile(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_input_archive_file); - diag + build(fluent::codegen_ssa_thorin_parse_input_archive_file) } thorin::Error::ParseArchiveMember(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_archive_member); - diag - } - thorin::Error::InvalidInputKind => { - diag = build(fluent::codegen_ssa_thorin_invalid_input_kind); - diag - } - thorin::Error::DecompressData(_) => { - diag = build(fluent::codegen_ssa_thorin_decompress_data); - diag + build(fluent::codegen_ssa_thorin_parse_archive_member) } + thorin::Error::InvalidInputKind => build(fluent::codegen_ssa_thorin_invalid_input_kind), + thorin::Error::DecompressData(_) => build(fluent::codegen_ssa_thorin_decompress_data), thorin::Error::NamelessSection(_, offset) => { - diag = build(fluent::codegen_ssa_thorin_section_without_name); - diag.arg("offset", format!("0x{offset:08x}")); - diag + build(fluent::codegen_ssa_thorin_section_without_name) + .arg_mv("offset", format!("0x{offset:08x}")) } thorin::Error::RelocationWithInvalidSymbol(section, offset) => { - diag = build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol); - diag.arg("section", section); - diag.arg("offset", format!("0x{offset:08x}")); - diag + build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol) + .arg_mv("section", section) + .arg_mv("offset", format!("0x{offset:08x}")) } thorin::Error::MultipleRelocations(section, offset) => { - diag = build(fluent::codegen_ssa_thorin_multiple_relocations); - diag.arg("section", section); - diag.arg("offset", format!("0x{offset:08x}")); - diag + build(fluent::codegen_ssa_thorin_multiple_relocations) + .arg_mv("section", section) + .arg_mv("offset", format!("0x{offset:08x}")) } thorin::Error::UnsupportedRelocation(section, offset) => { - diag = build(fluent::codegen_ssa_thorin_unsupported_relocation); - diag.arg("section", section); - diag.arg("offset", format!("0x{offset:08x}")); - diag - } - thorin::Error::MissingDwoName(id) => { - diag = build(fluent::codegen_ssa_thorin_missing_dwo_name); - diag.arg("id", format!("0x{id:08x}")); - diag + build(fluent::codegen_ssa_thorin_unsupported_relocation) + .arg_mv("section", section) + .arg_mv("offset", format!("0x{offset:08x}")) } + thorin::Error::MissingDwoName(id) => build(fluent::codegen_ssa_thorin_missing_dwo_name) + .arg_mv("id", format!("0x{id:08x}")), thorin::Error::NoCompilationUnits => { - diag = build(fluent::codegen_ssa_thorin_no_compilation_units); - diag - } - thorin::Error::NoDie => { - diag = build(fluent::codegen_ssa_thorin_no_die); - diag + build(fluent::codegen_ssa_thorin_no_compilation_units) } + thorin::Error::NoDie => build(fluent::codegen_ssa_thorin_no_die), thorin::Error::TopLevelDieNotUnit => { - diag = build(fluent::codegen_ssa_thorin_top_level_die_not_unit); - diag + build(fluent::codegen_ssa_thorin_top_level_die_not_unit) } thorin::Error::MissingRequiredSection(section) => { - diag = build(fluent::codegen_ssa_thorin_missing_required_section); - diag.arg("section", section); - diag + build(fluent::codegen_ssa_thorin_missing_required_section) + .arg_mv("section", section) } thorin::Error::ParseUnitAbbreviations(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_unit_abbreviations); - diag + build(fluent::codegen_ssa_thorin_parse_unit_abbreviations) } thorin::Error::ParseUnitAttribute(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_unit_attribute); - diag + build(fluent::codegen_ssa_thorin_parse_unit_attribute) } thorin::Error::ParseUnitHeader(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_unit_header); - diag - } - thorin::Error::ParseUnit(_) => { - diag = build(fluent::codegen_ssa_thorin_parse_unit); - diag + build(fluent::codegen_ssa_thorin_parse_unit_header) } + thorin::Error::ParseUnit(_) => build(fluent::codegen_ssa_thorin_parse_unit), thorin::Error::IncompatibleIndexVersion(section, format, actual) => { - diag = build(fluent::codegen_ssa_thorin_incompatible_index_version); - diag.arg("section", section); - diag.arg("actual", actual); - diag.arg("format", format); - diag + build(fluent::codegen_ssa_thorin_incompatible_index_version) + .arg_mv("section", section) + .arg_mv("actual", actual) + .arg_mv("format", format) } thorin::Error::OffsetAtIndex(_, index) => { - diag = build(fluent::codegen_ssa_thorin_offset_at_index); - diag.arg("index", index); - diag + build(fluent::codegen_ssa_thorin_offset_at_index).arg_mv("index", index) } thorin::Error::StrAtOffset(_, offset) => { - diag = build(fluent::codegen_ssa_thorin_str_at_offset); - diag.arg("offset", format!("0x{offset:08x}")); - diag + build(fluent::codegen_ssa_thorin_str_at_offset) + .arg_mv("offset", format!("0x{offset:08x}")) } thorin::Error::ParseIndex(_, section) => { - diag = build(fluent::codegen_ssa_thorin_parse_index); - diag.arg("section", section); - diag + build(fluent::codegen_ssa_thorin_parse_index).arg_mv("section", section) } thorin::Error::UnitNotInIndex(unit) => { - diag = build(fluent::codegen_ssa_thorin_unit_not_in_index); - diag.arg("unit", format!("0x{unit:08x}")); - diag + build(fluent::codegen_ssa_thorin_unit_not_in_index) + .arg_mv("unit", format!("0x{unit:08x}")) } thorin::Error::RowNotInIndex(_, row) => { - diag = build(fluent::codegen_ssa_thorin_row_not_in_index); - diag.arg("row", row); - diag - } - thorin::Error::SectionNotInRow => { - diag = build(fluent::codegen_ssa_thorin_section_not_in_row); - diag + build(fluent::codegen_ssa_thorin_row_not_in_index).arg_mv("row", row) } + thorin::Error::SectionNotInRow => build(fluent::codegen_ssa_thorin_section_not_in_row), thorin::Error::EmptyUnit(unit) => { - diag = build(fluent::codegen_ssa_thorin_empty_unit); - diag.arg("unit", format!("0x{unit:08x}")); - diag + build(fluent::codegen_ssa_thorin_empty_unit).arg_mv("unit", format!("0x{unit:08x}")) } thorin::Error::MultipleDebugInfoSection => { - diag = build(fluent::codegen_ssa_thorin_multiple_debug_info_section); - diag + build(fluent::codegen_ssa_thorin_multiple_debug_info_section) } thorin::Error::MultipleDebugTypesSection => { - diag = build(fluent::codegen_ssa_thorin_multiple_debug_types_section); - diag - } - thorin::Error::NotSplitUnit => { - diag = build(fluent::codegen_ssa_thorin_not_split_unit); - diag - } - thorin::Error::DuplicateUnit(unit) => { - diag = build(fluent::codegen_ssa_thorin_duplicate_unit); - diag.arg("unit", format!("0x{unit:08x}")); - diag + build(fluent::codegen_ssa_thorin_multiple_debug_types_section) } + thorin::Error::NotSplitUnit => build(fluent::codegen_ssa_thorin_not_split_unit), + thorin::Error::DuplicateUnit(unit) => build(fluent::codegen_ssa_thorin_duplicate_unit) + .arg_mv("unit", format!("0x{unit:08x}")), thorin::Error::MissingReferencedUnit(unit) => { - diag = build(fluent::codegen_ssa_thorin_missing_referenced_unit); - diag.arg("unit", format!("0x{unit:08x}")); - diag + build(fluent::codegen_ssa_thorin_missing_referenced_unit) + .arg_mv("unit", format!("0x{unit:08x}")) } thorin::Error::NoOutputObjectCreated => { - diag = build(fluent::codegen_ssa_thorin_not_output_object_created); - diag + build(fluent::codegen_ssa_thorin_not_output_object_created) } thorin::Error::MixedInputEncodings => { - diag = build(fluent::codegen_ssa_thorin_mixed_input_encodings); - diag + build(fluent::codegen_ssa_thorin_mixed_input_encodings) } thorin::Error::Io(e) => { - diag = build(fluent::codegen_ssa_thorin_io); - diag.arg("error", format!("{e}")); - diag + build(fluent::codegen_ssa_thorin_io).arg_mv("error", format!("{e}")) } thorin::Error::ObjectRead(e) => { - diag = build(fluent::codegen_ssa_thorin_object_read); - diag.arg("error", format!("{e}")); - diag + build(fluent::codegen_ssa_thorin_object_read).arg_mv("error", format!("{e}")) } thorin::Error::ObjectWrite(e) => { - diag = build(fluent::codegen_ssa_thorin_object_write); - diag.arg("error", format!("{e}")); - diag + build(fluent::codegen_ssa_thorin_object_write).arg_mv("error", format!("{e}")) } thorin::Error::GimliRead(e) => { - diag = build(fluent::codegen_ssa_thorin_gimli_read); - diag.arg("error", format!("{e}")); - diag + build(fluent::codegen_ssa_thorin_gimli_read).arg_mv("error", format!("{e}")) } thorin::Error::GimliWrite(e) => { - diag = build(fluent::codegen_ssa_thorin_gimli_write); - diag.arg("error", format!("{e}")); - diag + build(fluent::codegen_ssa_thorin_gimli_write).arg_mv("error", format!("{e}")) } _ => unimplemented!("Untranslated thorin error"), } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index e41acd6447b..b3f8a6c2440 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -30,9 +30,7 @@ where G: EmissionGuarantee, { fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { - let mut diag = self.node.into_diagnostic(dcx, level); - diag.span(self.span); - diag + self.node.into_diagnostic(dcx, level).span_mv(self.span) } } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index de27c6e910b..58d4d2caf2e 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -249,60 +249,43 @@ impl IntoDiagnosticArg for hir::def::Res { impl IntoDiagnostic<'_, G> for TargetDataLayoutErrors<'_> { fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { - let mut diag; match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { - diag = - DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_address_space); - diag.arg("addr_space", addr_space); - diag.arg("cause", cause); - diag.arg("err", err); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_address_space) + .arg_mv("addr_space", addr_space) + .arg_mv("cause", cause) + .arg_mv("err", err) } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { - diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits); - diag.arg("kind", kind); - diag.arg("bit", bit); - diag.arg("cause", cause); - diag.arg("err", err); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits) + .arg_mv("kind", kind) + .arg_mv("bit", bit) + .arg_mv("cause", cause) + .arg_mv("err", err) } TargetDataLayoutErrors::MissingAlignment { cause } => { - diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_missing_alignment); - diag.arg("cause", cause); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_missing_alignment) + .arg_mv("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_alignment); - diag.arg("cause", cause); - diag.arg("err_kind", err.diag_ident()); - diag.arg("align", err.align()); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_alignment) + .arg_mv("cause", cause) + .arg_mv("err_kind", err.diag_ident()) + .arg_mv("align", err.align()) } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { - diag = DiagnosticBuilder::new( - dcx, - level, - fluent::errors_target_inconsistent_architecture, - ); - diag.arg("dl", dl); - diag.arg("target", target); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_architecture) + .arg_mv("dl", dl) + .arg_mv("target", target) } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { - diag = DiagnosticBuilder::new( - dcx, - level, - fluent::errors_target_inconsistent_pointer_width, - ); - diag.arg("pointer_size", pointer_size); - diag.arg("target", target); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_pointer_width) + .arg_mv("pointer_size", pointer_size) + .arg_mv("target", target) } TargetDataLayoutErrors::InvalidBitsSize { err } => { - diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits_size); - diag.arg("err", err); - diag + DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits_size) + .arg_mv("err", err) } } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e07a9509383..a63c32566ca 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -729,9 +729,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, ()> { - let mut result = self.struct_warn(msg); - result.span(span); - result + self.struct_warn(msg).span_mv(span) } /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. @@ -744,9 +742,7 @@ impl DiagCtxt { msg: impl Into, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ()> { - let mut result = self.struct_span_warn(span, msg); - result.code(code); - result + self.struct_span_warn(span, msg).code_mv(code) } /// Construct a builder at the `Warning` level with the `msg`. @@ -786,9 +782,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_> { - let mut result = self.struct_err(msg); - result.span(span); - result + self.struct_err(msg).span_mv(span) } /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. @@ -800,9 +794,7 @@ impl DiagCtxt { msg: impl Into, code: DiagnosticId, ) -> DiagnosticBuilder<'_> { - let mut result = self.struct_span_err(span, msg); - result.code(code); - result + self.struct_span_err(span, msg).code_mv(code) } /// Construct a builder at the `Error` level with the `msg`. @@ -821,9 +813,7 @@ impl DiagCtxt { msg: impl Into, code: DiagnosticId, ) -> DiagnosticBuilder<'_> { - let mut result = self.struct_err(msg); - result.code(code); - result + self.struct_err(msg).code_mv(code) } /// Construct a builder at the `Warn` level with the `msg` and the `code`. @@ -834,9 +824,7 @@ impl DiagCtxt { msg: impl Into, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ()> { - let mut result = self.struct_warn(msg); - result.code(code); - result + self.struct_warn(msg).code_mv(code) } /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. @@ -847,9 +835,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, FatalAbort> { - let mut result = self.struct_fatal(msg); - result.span(span); - result + self.struct_fatal(msg).span_mv(span) } /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. @@ -861,9 +847,7 @@ impl DiagCtxt { msg: impl Into, code: DiagnosticId, ) -> DiagnosticBuilder<'_, FatalAbort> { - let mut result = self.struct_span_fatal(span, msg); - result.code(code); - result + self.struct_span_fatal(span, msg).code_mv(code) } /// Construct a builder at the `Fatal` level with the `msg`. @@ -904,9 +888,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, BugAbort> { - let mut result = self.struct_bug(msg); - result.span(span); - result + self.struct_bug(msg).span_mv(span) } #[rustc_lint_diagnostics] @@ -1021,9 +1003,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, ()> { - let mut db = DiagnosticBuilder::new(self, Note, msg); - db.span(span); - db + DiagnosticBuilder::new(self, Note, msg).span_mv(span) } #[rustc_lint_diagnostics] diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c53ff565550..4bac124b58b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1921,10 +1921,8 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error } fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> { - let mut err = - struct_span_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used"); - err.span_label(span, "unused parameter"); - err + struct_span_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used") + .span_label_mv(span, "unused parameter") } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 69a65e8b750..da9d41a7d72 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2836,15 +2836,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn private_field_err(&self, field: Ident, base_did: DefId) -> DiagnosticBuilder<'_> { let struct_path = self.tcx().def_path_str(base_did); let kind_name = self.tcx().def_descr(base_did); - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), field.span, E0616, "field `{field}` of {kind_name} `{struct_path}` is private", - ); - err.span_label(field.span, "private field"); - - err + ) + .span_label_mv(field.span, "private field") } pub(crate) fn get_field_candidates_considering_privacy( diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e9fa39ad08a..c09646b491c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -367,9 +367,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &trace.cause.code().peel_derives() { let span = *span; - let mut err = self.report_concrete_failure(placeholder_origin, sub, sup); - err.span_note(span, "the lifetime requirement is introduced here"); - err + self.report_concrete_failure(placeholder_origin, sub, sup) + .span_note_mv(span, "the lifetime requirement is introduced here") } else { unreachable!( "control flow ensures we have a `BindingObligation` or `ExprBindingObligation` here..." diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 4819ed6021d..bc42b1b3ef8 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -249,9 +249,9 @@ impl<'a> StringReader<'a> { let lifetime_name = self.str_from(start); if starts_with_number { let span = self.mk_sp(start, self.pos); - let mut diag = self.dcx().struct_err("lifetimes cannot start with a number"); - diag.span(span); - diag.stash(span, StashKey::LifetimeIsChar); + self.dcx().struct_err("lifetimes cannot start with a number") + .span_mv(span) + .stash(span, StashKey::LifetimeIsChar); } let ident = Symbol::intern(lifetime_name); token::Lifetime(ident) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index c8629069968..1f8c368b2a9 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -200,23 +200,22 @@ impl<'a> Parser<'a> { if let InnerAttrPolicy::Forbidden(reason) = policy { let mut diag = match reason.as_ref().copied() { Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => { - let mut diag = self.dcx().struct_span_err( - attr_sp, - fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, - ); - diag.span_label(attr_sp, fluent::parse_label_attr) - .span_label(prev_doc_comment_span, fluent::parse_label_prev_doc_comment); - diag + self.dcx() + .struct_span_err( + attr_sp, + fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, + ) + .span_label_mv(attr_sp, fluent::parse_label_attr) + .span_label_mv(prev_doc_comment_span, fluent::parse_label_prev_doc_comment) } - Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => { - let mut diag = self.dcx().struct_span_err( + Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => self + .dcx() + .struct_span_err( attr_sp, fluent::parse_inner_attr_not_permitted_after_outer_attr, - ); - diag.span_label(attr_sp, fluent::parse_label_attr) - .span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr); - diag - } + ) + .span_label_mv(attr_sp, fluent::parse_label_attr) + .span_label_mv(prev_outer_attr_sp, fluent::parse_label_prev_attr), Some(InnerAttrForbiddenReason::InCodeBlock) | None => { self.dcx().struct_span_err(attr_sp, fluent::parse_inner_attr_not_permitted) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 45aafbd0fdf..2694dd3c9c6 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1941,15 +1941,14 @@ impl<'a> Parser<'a> { Case::Insensitive, ) { Ok(_) => { - let mut err = self.dcx().struct_span_err( + self.dcx().struct_span_err( lo.to(self.prev_token.span), format!("functions are not allowed in {adt_ty} definitions"), - ); - err.help( + ) + .help_mv( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", - ); - err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); - err + ) + .help_mv("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information") } Err(err) => { err.cancel(); @@ -1959,14 +1958,13 @@ impl<'a> Parser<'a> { } } else if self.eat_keyword(kw::Struct) { match self.parse_item_struct() { - Ok((ident, _)) => { - let mut err = self.dcx().struct_span_err( + Ok((ident, _)) => self + .dcx() + .struct_span_err( lo.with_hi(ident.span.hi()), format!("structs are not allowed in {adt_ty} definitions"), - ); - err.help("consider creating a new `struct` definition instead of nesting"); - err - } + ) + .help_mv("consider creating a new `struct` definition instead of nesting"), Err(err) => { err.cancel(); self.restore_snapshot(snapshot); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index e9b68a129ef..a6804b99204 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -460,9 +460,10 @@ impl<'a> Parser<'a> { super::token_descr(&self_.token) ); - let mut err = self_.dcx().struct_span_err(self_.token.span, msg); - err.span_label(self_.token.span, format!("expected {expected}")); - err + self_ + .dcx() + .struct_span_err(self_.token.span, msg) + .span_label_mv(self_.token.span, format!("expected {expected}")) }); PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit))) } else { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index c1cb20f6bb0..977a7e796e7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -944,16 +944,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { trait_item_span, trait_path, } => { - let mut err = self.dcx().struct_span_err_with_code( + self.dcx().struct_span_err_with_code( span, format!( "item `{name}` is an associated {kind}, which doesn't match its trait `{trait_path}`", ), code, - ); - err.span_label(span, "does not match trait"); - err.span_label(trait_item_span, "item in trait"); - err + ) + .span_label_mv(span, "does not match trait") + .span_label_mv(trait_item_span, "item in trait") } ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self .dcx() diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 821aafe2fed..43608da8ab2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2603,25 +2603,23 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ) { debug_assert_ne!(lifetime_ref.ident.name, kw::UnderscoreLifetime); let mut err = if let Some(outer) = outer_lifetime_ref { - let mut err = struct_span_err!( + struct_span_err!( self.r.dcx(), lifetime_ref.ident.span, E0401, "can't use generic parameters from outer item", - ); - err.span_label(lifetime_ref.ident.span, "use of generic parameter from outer item"); - err.span_label(outer.span, "lifetime parameter from outer item"); - err + ) + .span_label_mv(lifetime_ref.ident.span, "use of generic parameter from outer item") + .span_label_mv(outer.span, "lifetime parameter from outer item") } else { - let mut err = struct_span_err!( + struct_span_err!( self.r.dcx(), lifetime_ref.ident.span, E0261, "use of undeclared lifetime name `{}`", lifetime_ref.ident - ); - err.span_label(lifetime_ref.ident.span, "undeclared lifetime"); - err + ) + .span_label_mv(lifetime_ref.ident.span, "undeclared lifetime") }; self.suggest_introducing_lifetime( &mut err, diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 758c3122404..8baa5d892a5 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -18,10 +18,9 @@ pub struct FeatureGateError { impl<'a> IntoDiagnostic<'a> for FeatureGateError { #[track_caller] fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> { - let mut diag = DiagnosticBuilder::new(dcx, level, self.explain); - diag.span(self.span); - diag.code(error_code!(E0658)); - diag + DiagnosticBuilder::new(dcx, level, self.explain) + .span_mv(self.span) + .code_mv(error_code!(E0658)) } } diff --git a/compiler/rustc_symbol_mangling/src/errors.rs b/compiler/rustc_symbol_mangling/src/errors.rs index 0fa59d2ddfb..746783ab7e3 100644 --- a/compiler/rustc_symbol_mangling/src/errors.rs +++ b/compiler/rustc_symbol_mangling/src/errors.rs @@ -18,9 +18,7 @@ impl IntoDiagnostic<'_, G> for TestOutput { let TestOutput { span, kind, content } = self; #[allow(rustc::untranslatable_diagnostic)] - let mut diag = DiagnosticBuilder::new(dcx, level, format!("{kind}({content})")); - diag.span(span); - diag + DiagnosticBuilder::new(dcx, level, format!("{kind}({content})")).span_mv(span) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index efc75ee538e..6bf1307b37f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2654,26 +2654,24 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .chain(Some(data.term.into_arg())) .find(|g| g.has_non_region_infer()); if let Some(subst) = subst { - let mut err = self.emit_inference_failure_err( + self.emit_inference_failure_err( obligation.cause.body_id, span, subst, ErrorCode::E0284, true, - ); - err.note(format!("cannot satisfy `{predicate}`")); - err + ) + .note_mv(format!("cannot satisfy `{predicate}`")) } else { // If we can't find a substitution, just print a generic error - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, - ); - err.span_label(span, format!("cannot satisfy `{predicate}`")); - err + ) + .span_label_mv(span, format!("cannot satisfy `{predicate}`")) } } @@ -2693,30 +2691,28 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err } else { // If we can't find a substitution, just print a generic error - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, - ); - err.span_label(span, format!("cannot satisfy `{predicate}`")); - err + ) + .span_label_mv(span, format!("cannot satisfy `{predicate}`")) } } _ => { if self.dcx().has_errors().is_some() || self.tainted_by_errors().is_some() { return; } - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, - ); - err.span_label(span, format!("cannot satisfy `{predicate}`")); - err + ) + .span_label_mv(span, format!("cannot satisfy `{predicate}`")) } }; self.note_obligation_cause(&mut err, obligation); -- cgit 1.4.1-3-g733a5 From bd4e623485f383b478fae662a767a3129bb4b989 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 3 Jan 2024 17:03:10 +1100 Subject: Use chaining for `DiagnosticBuilder` construction and `emit`. To avoid the use of a mutable local variable, and because it reads more nicely. --- compiler/rustc_builtin_macros/src/asm.rs | 15 +++-- compiler/rustc_codegen_cranelift/src/driver/jit.rs | 7 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 8 +-- .../rustc_hir_analysis/src/astconv/generics.rs | 6 +- .../src/astconv/object_safety.rs | 10 +-- compiler/rustc_hir_analysis/src/check/check.rs | 6 +- .../rustc_hir_analysis/src/check/intrinsicck.rs | 74 ++++++++++++---------- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 53 ++++++++-------- .../src/coherence/inherent_impls_overlap.rs | 11 ++-- .../src/collect/resolve_bound_vars.rs | 8 +-- compiler/rustc_hir_typeck/src/expr.rs | 33 +++++----- compiler/rustc_hir_typeck/src/pat.rs | 10 +-- compiler/rustc_hir_typeck/src/place_op.rs | 12 ++-- compiler/rustc_middle/src/lint.rs | 1 - compiler/rustc_middle/src/values.rs | 10 +-- compiler/rustc_parse/src/parser/diagnostics.rs | 19 +++--- compiler/rustc_parse/src/parser/generics.rs | 23 +++---- compiler/rustc_parse/src/parser/item.rs | 3 +- compiler/rustc_resolve/src/late/diagnostics.rs | 25 ++++---- compiler/rustc_resolve/src/macros.rs | 9 ++- .../traits/error_reporting/type_err_ctxt_ext.rs | 21 +++--- src/librustdoc/core.rs | 12 ++-- 22 files changed, 193 insertions(+), 183 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index ac90f4d4084..d0e13fa3c0f 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -693,13 +693,14 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option {} 1 => { let (sp, msg) = unused_operands.into_iter().next().unwrap(); - let mut err = ecx.dcx().struct_span_err(sp, msg); - err.span_label(sp, msg); - err.help(format!( - "if this argument is intentionally unused, \ - consider using it in an asm comment: `\"/*{help_str} */\"`" - )); - err.emit(); + ecx.dcx() + .struct_span_err(sp, msg) + .span_label_mv(sp, msg) + .help_mv(format!( + "if this argument is intentionally unused, \ + consider using it in an asm comment: `\"/*{help_str} */\"`" + )) + .emit(); } _ => { let mut err = ecx.dcx().struct_span_err( diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index a8d8fb189e2..50d9f287e74 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -321,9 +321,10 @@ fn dep_symbol_lookup_fn( Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { let name = crate_info.crate_name[&cnum]; - let mut err = sess.dcx().struct_err(format!("Can't load static lib {}", name)); - err.note("rustc_codegen_cranelift can only load dylibs in JIT mode."); - err.emit(); + sess.dcx() + .struct_err(format!("Can't load static lib {}", name)) + .note("rustc_codegen_cranelift can only load dylibs in JIT mode.") + .emit(); } Linkage::Dynamic => { dylib_paths.push(src.dylib.as_ref().unwrap().0.clone()); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index a1ec191f105..f53067d194a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -303,14 +303,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // This exception needs to be kept in sync with allowing // `#[target_feature]` on `main` and `start`. } else if !tcx.features().target_feature_11 { - let mut err = feature_err( + feature_err( &tcx.sess.parse_sess, sym::target_feature_11, attr.span, "`#[target_feature(..)]` can only be applied to `unsafe` functions", - ); - err.span_label(tcx.def_span(did), "not an `unsafe` function"); - err.emit(); + ) + .span_label_mv(tcx.def_span(did), "not an `unsafe` function") + .emit(); } else { check_target_feature_trait_unsafe(tcx, did, attr.span); } diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 257b108471f..adc6a9de808 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -650,9 +650,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( if position == GenericArgPosition::Value && args.num_lifetime_params() != param_counts.lifetimes { - let mut err = struct_span_err!(tcx.dcx(), span, E0794, "{}", msg); - err.span_note(span_late, note); - err.emit(); + struct_span_err!(tcx.dcx(), span, E0794, "{}", msg) + .span_note_mv(span_late, note) + .emit(); } else { let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note); diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index ff84a982495..703e0bdc40e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -290,19 +290,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if references_self { let def_id = i.bottom().0.def_id(); - let mut err = struct_span_err!( + struct_span_err!( tcx.dcx(), i.bottom().1, E0038, "the {} `{}` cannot be made into an object", tcx.def_descr(def_id), tcx.item_name(def_id), - ); - err.note( + ) + .note_mv( rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![]) .error_msg(), - ); - err.emit(); + ) + .emit(); } ty::ExistentialTraitRef { def_id: trait_ref.def_id, args } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 544e06879f6..4b26a469eb5 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1140,13 +1140,13 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var)); if disr_non_unit || (disr_units && has_non_units) { - let err = struct_span_err!( + struct_span_err!( tcx.dcx(), tcx.def_span(def_id), E0732, "`#[repr(inttype)]` must be specified" - ); - err.emit(); + ) + .emit(); } } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index ac18e6de0ba..1979f52eda9 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -153,12 +153,14 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { }; let Some(asm_ty) = asm_ty else { let msg = format!("cannot use value of type `{ty}` for inline assembly"); - let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); - err.note( - "only integers, floats, SIMD vectors, pointers and function pointers \ - can be used as arguments for inline assembly", - ); - err.emit(); + self.tcx + .dcx() + .struct_span_err(expr.span, msg) + .note_mv( + "only integers, floats, SIMD vectors, pointers and function pointers \ + can be used as arguments for inline assembly", + ) + .emit(); return None; }; @@ -166,9 +168,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // possibly fail is for SIMD types which don't #[derive(Copy)]. if !ty.is_copy_modulo_regions(self.tcx, self.param_env) { let msg = "arguments for inline assembly must be copyable"; - let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); - err.note(format!("`{ty}` does not implement the Copy trait")); - err.emit(); + self.tcx + .dcx() + .struct_span_err(expr.span, msg) + .note_mv(format!("`{ty}` does not implement the Copy trait")) + .emit(); } // Ideally we wouldn't need to do this, but LLVM's register allocator @@ -183,16 +187,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some((in_expr, Some(in_asm_ty))) = tied_input { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; - let mut err = self.tcx.dcx().struct_span_err(vec![in_expr.span, expr.span], msg); - let in_expr_ty = (self.get_operand_ty)(in_expr); - err.span_label(in_expr.span, format!("type `{in_expr_ty}`")); - err.span_label(expr.span, format!("type `{ty}`")); - err.note( - "asm inout arguments must have the same type, \ + self.tcx + .dcx() + .struct_span_err(vec![in_expr.span, expr.span], msg) + .span_label_mv(in_expr.span, format!("type `{in_expr_ty}`")) + .span_label_mv(expr.span, format!("type `{ty}`")) + .note_mv( + "asm inout arguments must have the same type, \ unless they are both pointers or integers of the same size", - ); - err.emit(); + ) + .emit(); } // All of the later checks have already been done on the input, so @@ -234,13 +239,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some(feature) = feature { if !target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); - let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); - err.note(format!( - "this is required to use type `{}` with register class `{}`", - ty, - reg_class.name(), - )); - err.emit(); + self.tcx + .dcx() + .struct_span_err(expr.span, msg) + .note_mv(format!( + "this is required to use type `{}` with register class `{}`", + ty, + reg_class.name(), + )) + .emit(); return Some(asm_ty); } } @@ -449,14 +456,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Never | ty::Error(_) => {} ty::FnDef(..) => {} _ => { - let mut err = - self.tcx.dcx().struct_span_err(*op_sp, "invalid `sym` operand"); - err.span_label( - self.tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ); - err.help("`sym` operands must refer to either a function or a static"); - err.emit(); + self.tcx + .dcx() + .struct_span_err(*op_sp, "invalid `sym` operand") + .span_label_mv( + self.tcx.def_span(anon_const.def_id), + format!("is {} `{}`", ty.kind().article(), ty), + ) + .help_mv( + "`sym` operands must refer to either a function or a static", + ) + .emit(); } }; } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4bac124b58b..67ec2c3e5ea 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -197,11 +197,12 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() let mut res = Ok(()); if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) { let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span); - let mut err = - tcx.dcx().struct_span_err(sp, "impls of auto traits cannot be default"); - err.span_labels(impl_.defaultness_span, "default because of this"); - err.span_label(sp, "auto trait"); - res = Err(err.emit()); + res = Err(tcx + .dcx() + .struct_span_err(sp, "impls of auto traits cannot be default") + .span_labels_mv(impl_.defaultness_span, "default because of this") + .span_label_mv(sp, "auto trait") + .emit()); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. match tcx.impl_polarity(def_id) { @@ -489,35 +490,33 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { if !unsatisfied_bounds.is_empty() { let plural = pluralize!(unsatisfied_bounds.len()); - let mut err = tcx.dcx().struct_span_err( - gat_item_hir.span, - format!("missing required bound{} on `{}`", plural, gat_item_hir.ident), - ); - let suggestion = format!( "{} {}", gat_item_hir.generics.add_where_or_trailing_comma(), unsatisfied_bounds.join(", "), ); - err.span_suggestion( - gat_item_hir.generics.tail_span_for_predicate_suggestion(), - format!("add the required where clause{plural}"), - suggestion, - Applicability::MachineApplicable, - ); - let bound = if unsatisfied_bounds.len() > 1 { "these bounds are" } else { "this bound is" }; - err.note(format!( - "{bound} currently required to ensure that impls have maximum flexibility" - )); - err.note( - "we are soliciting feedback, see issue #87479 \ + tcx.dcx() + .struct_span_err( + gat_item_hir.span, + format!("missing required bound{} on `{}`", plural, gat_item_hir.ident), + ) + .span_suggestion_mv( + gat_item_hir.generics.tail_span_for_predicate_suggestion(), + format!("add the required where clause{plural}"), + suggestion, + Applicability::MachineApplicable, + ) + .note_mv(format!( + "{bound} currently required to ensure that impls have maximum flexibility" + )) + .note_mv( + "we are soliciting feedback, see issue #87479 \ \ for more information", - ); - - err.emit(); + ) + .emit(); } } } @@ -938,8 +937,8 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), }; if may_suggest_feature && tcx.sess.is_nightly_build() { diag.help( - "add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types", - ); + "add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types", + ); } Err(diag.emit()) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index ec15aa65e7a..8f54bf00528 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -70,17 +70,16 @@ impl<'tcx> InherentOverlapChecker<'tcx> { match seen_items.entry(norm_ident) { Entry::Occupied(entry) => { let former = entry.get(); - let mut err = struct_span_err!( + struct_span_err!( self.tcx.dcx(), span, E0592, "duplicate definitions with name `{}`", ident, - ); - err.span_label(span, format!("duplicate definitions for `{ident}`")); - err.span_label(*former, format!("other definition for `{ident}`")); - - err.emit(); + ) + .span_label_mv(span, format!("duplicate definitions for `{ident}`")) + .span_label_mv(*former, format!("other definition for `{ident}`")) + .emit(); } Entry::Vacant(entry) => { entry.insert(span); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c033cec3155..61bb4235139 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -750,12 +750,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { kind: hir::ItemKind::OpaqueTy { .. }, .. }) = self.tcx.hir_node(parent_id) { - let mut err = self.tcx.dcx().struct_span_err( + self.tcx.dcx().struct_span_err( lifetime.ident.span, "higher kinded lifetime bounds on nested opaque types are not supported yet", - ); - err.span_note(self.tcx.def_span(def_id), "lifetime declared here"); - err.emit(); + ) + .span_note_mv(self.tcx.def_span(def_id), "lifetime declared here") + .emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index da9d41a7d72..c7163913517 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3183,9 +3183,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized(ty, expr.span, traits::InlineAsmSized); if !is_input && !expr.is_syntactic_place_expr() { - let mut err = self.dcx().struct_span_err(expr.span, "invalid asm output"); - err.span_label(expr.span, "cannot assign to this expression"); - err.emit(); + self.dcx() + .struct_span_err(expr.span, "invalid asm output") + .span_label_mv(expr.span, "cannot assign to this expression") + .emit(); } // If this is an input value, we require its type to be fully resolved @@ -3278,27 +3279,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter_enumerated() .find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident) else { - let mut err = type_error_struct!( + type_error_struct!( self.dcx(), ident.span, container, E0599, "no variant named `{ident}` found for enum `{container}`", - ); - err.span_label(field.span, "variant not found"); - err.emit(); + ) + .span_label_mv(field.span, "variant not found") + .emit(); break; }; let Some(&subfield) = fields.next() else { - let mut err = type_error_struct!( + type_error_struct!( self.dcx(), ident.span, container, E0795, "`{ident}` is an enum variant; expected field at end of `offset_of`", - ); - err.span_label(field.span, "enum variant"); - err.emit(); + ) + .span_label_mv(field.span, "enum variant") + .emit(); break; }; let (subident, sub_def_scope) = @@ -3309,16 +3310,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter_enumerated() .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) else { - let mut err = type_error_struct!( + type_error_struct!( self.dcx(), ident.span, container, E0609, "no field named `{subfield}` on enum variant `{container}::{ident}`", - ); - err.span_label(field.span, "this enum variant..."); - err.span_label(subident.span, "...does not have this field"); - err.emit(); + ) + .span_label_mv(field.span, "this enum variant...") + .span_label_mv(subident.span, "...does not have this field") + .emit(); break; }; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 022213abd67..4ac85cce292 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1541,19 +1541,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sp_comma = sm.end_point(pat.span.with_hi(sp_brace.hi())); let sugg = if no_fields || sp_brace != sp_comma { ".. }" } else { ", .. }" }; - let mut err = struct_span_err!( + struct_span_err!( self.dcx(), pat.span, E0638, "`..` required with {descr} marked as non-exhaustive", - ); - err.span_suggestion_verbose( + ) + .span_suggestion_verbose_mv( sp_comma, "add `..` at the end of the field list to ignore all other fields", sugg, Applicability::MachineApplicable, - ); - err.emit(); + ) + .emit(); } fn error_field_already_bound( diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index c3bcdcfa5cd..3825c513ef3 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -332,15 +332,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if inside_union && source.ty_adt_def().is_some_and(|adt| adt.is_manually_drop()) { - let mut err = self.dcx().struct_span_err( + self.dcx().struct_span_err( expr.span, "not automatically applying `DerefMut` on `ManuallyDrop` union field", - ); - err.help( + ) + .help_mv( "writing to this reference calls the destructor for the old value", - ); - err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor"); - err.emit(); + ) + .help_mv("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor") + .emit(); } } source = adjustment.target; diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index d45ec8e4646..212e831e106 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -357,7 +357,6 @@ pub fn struct_lint_level( if let Level::Expect(_) = level { let name = lint.name_lower(); err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn: false }); - decorate(&mut err); err.emit(); return; diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index b4e45ad5685..b3c05a36a13 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -190,7 +190,7 @@ pub fn recursive_type_error( } s }; - let mut err = struct_span_err!( + struct_span_err!( tcx.dcx(), err_span, E0072, @@ -198,13 +198,13 @@ pub fn recursive_type_error( pluralize!(cycle_len), items_list, pluralize!("has", cycle_len), - ); - err.multipart_suggestion( + ) + .multipart_suggestion_mv( "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle", suggestion, Applicability::HasPlaceholders, - ); - err.emit(); + ) + .emit(); } fn find_item_ty_spans( diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 02eab2bac58..66d80fa3c52 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2848,15 +2848,16 @@ impl<'a> Parser<'a> { let label = self.eat_label().expect("just checked if a label exists"); self.bump(); // eat `:` let span = label.ident.span.to(self.prev_token.span); - let mut err = self.dcx().struct_span_err(span, "block label not supported here"); - err.span_label(span, "not supported here"); - err.tool_only_span_suggestion( - label.ident.span.until(self.token.span), - "remove this block label", - "", - Applicability::MachineApplicable, - ); - err.emit(); + self.dcx() + .struct_span_err(span, "block label not supported here") + .span_label_mv(span, "not supported here") + .tool_only_span_suggestion_mv( + label.ident.span.until(self.token.span), + "remove this block label", + "", + Applicability::MachineApplicable, + ) + .emit(); true } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 2a8e220181a..7ff72eb5fb3 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -141,17 +141,18 @@ impl<'a> Parser<'a> { // Parse optional const generics default value. let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None }; - let mut err = self.dcx().struct_span_err( - mistyped_const_ident.span, - format!("`const` keyword was mistyped as `{}`", mistyped_const_ident.as_str()), - ); - err.span_suggestion_verbose( - mistyped_const_ident.span, - "use the `const` keyword", - kw::Const.as_str(), - Applicability::MachineApplicable, - ); - err.emit(); + self.dcx() + .struct_span_err( + mistyped_const_ident.span, + format!("`const` keyword was mistyped as `{}`", mistyped_const_ident.as_str()), + ) + .span_suggestion_verbose_mv( + mistyped_const_ident.span, + "use the `const` keyword", + kw::Const.as_str(), + Applicability::MachineApplicable, + ) + .emit(); Ok(GenericParam { ident, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2694dd3c9c6..381ea21a244 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1109,8 +1109,7 @@ impl<'a> Parser<'a> { && self.token.is_keyword(kw::Unsafe) && self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace)) { - let err = self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err(); - err.emit(); + self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err().emit(); unsafety = Unsafe::Yes(self.token.span); self.eat_keyword(kw::Unsafe); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 43608da8ab2..70519af16c5 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3282,16 +3282,16 @@ fn mk_where_bound_predicate( /// Report lifetime/lifetime shadowing as an error. pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) { - let mut err = struct_span_err!( + struct_span_err!( sess.dcx(), shadower.span, E0496, "lifetime name `{}` shadows a lifetime name that is already in scope", orig.name, - ); - err.span_label(orig.span, "first declared here"); - err.span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name)); - err.emit(); + ) + .span_label_mv(orig.span, "first declared here") + .span_label_mv(shadower.span, format!("lifetime `{}` already in scope", orig.name)) + .emit(); } struct LifetimeFinder<'ast> { @@ -3317,11 +3317,12 @@ impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> { pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) { let name = shadower.name; let shadower = shadower.span; - let mut err = sess.dcx().struct_span_warn( - shadower, - format!("label name `{name}` shadows a label name that is already in scope"), - ); - err.span_label(orig, "first declared here"); - err.span_label(shadower, format!("label `{name}` already in scope")); - err.emit(); + sess.dcx() + .struct_span_warn( + shadower, + format!("label name `{name}` shadows a label name that is already in scope"), + ) + .span_label_mv(orig, "first declared here") + .span_label_mv(shadower, format!("label `{name}` already in scope")) + .emit(); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 32aed6611cf..fc55481cb01 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -576,10 +576,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.add_as_non_derive = Some(AddAsNonDerive { macro_path: &path_str }); } - let mut err = self.dcx().create_err(err); - err.span_label(path.span, format!("not {article} {expected}")); - - err.emit(); + self.dcx() + .create_err(err) + .span_label_mv(path.span, format!("not {article} {expected}")) + .emit(); return Ok((self.dummy_ext(kind), Res::Err)); } @@ -830,7 +830,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { expected, ident, }); - self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident, krate); err.emit(); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 6bf1307b37f..51119c3560e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3544,17 +3544,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span: Span, ) -> Option> { if !self.tcx.features().generic_const_exprs { - let mut err = self - .dcx() - .struct_span_err(span, "constant expression depends on a generic parameter"); - // FIXME(const_generics): we should suggest to the user how they can resolve this - // issue. However, this is currently not actually possible - // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). - // - // Note that with `feature(generic_const_exprs)` this case should not - // be reachable. - err.note("this may fail depending on what value the parameter takes"); - err.emit(); + self.dcx() + .struct_span_err(span, "constant expression depends on a generic parameter") + // FIXME(const_generics): we should suggest to the user how they can resolve this + // issue. However, this is currently not actually possible + // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). + // + // Note that with `feature(generic_const_exprs)` this case should not + // be reachable. + .note_mv("this may fail depending on what value the parameter takes") + .emit(); return None; } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 359d5ec485e..40ea4346f93 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -495,16 +495,16 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { .intersperse("::") .collect::() ); - let mut err = rustc_errors::struct_span_err!( + rustc_errors::struct_span_err!( self.tcx.dcx(), path.span, E0433, "failed to resolve: {label}", - ); - err.span_label(path.span, label); - err.note("this error was originally ignored because you are running `rustdoc`"); - err.note("try running again with `rustc` or `cargo check` and you may get a more detailed error"); - err.emit(); + ) + .span_label_mv(path.span, label) + .note_mv("this error was originally ignored because you are running `rustdoc`") + .note_mv("try running again with `rustc` or `cargo check` and you may get a more detailed error") + .emit(); } // We could have an outer resolution that succeeded, // but with generic parameters that failed. -- cgit 1.4.1-3-g733a5 From 6682f243dcb9babd67525bbf9798dca302f60588 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 3 Jan 2024 21:50:36 +1100 Subject: Remove all eight `DiagnosticBuilder::*_with_code` methods. These all have relatively low use, and can be perfectly emulated with a simpler construction method combined with `code` or `code_mv`. --- compiler/rustc_errors/src/diagnostic_builder.rs | 4 +- compiler/rustc_errors/src/lib.rs | 92 ---------------------- compiler/rustc_hir_analysis/src/astconv/mod.rs | 3 +- .../src/check/compare_impl_item.rs | 4 +- .../wrong_number_of_generic_args.rs | 3 +- compiler/rustc_hir_typeck/src/expr.rs | 8 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 29 +++---- compiler/rustc_hir_typeck/src/lib.rs | 9 +-- .../rustc_infer/src/infer/error_reporting/mod.rs | 18 ++--- compiler/rustc_parse/src/lexer/mod.rs | 73 ++++++++--------- compiler/rustc_parse/src/parser/attr.rs | 9 +-- compiler/rustc_resolve/src/diagnostics.rs | 4 +- compiler/rustc_resolve/src/late/diagnostics.rs | 4 +- .../traits/error_reporting/type_err_ctxt_ext.rs | 4 +- 14 files changed, 84 insertions(+), 180 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index b3f8a6c2440..dcbf60e4847 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -538,11 +538,11 @@ impl Drop for DiagnosticBuilder<'_, G> { #[macro_export] macro_rules! struct_span_err { ($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({ - $dcx.struct_span_err_with_code( + $dcx.struct_span_err( $span, format!($($message)*), - $crate::error_code!($code), ) + .code_mv($crate::error_code!($code)) }) } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index a63c32566ca..4710722c771 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -732,19 +732,6 @@ impl DiagCtxt { self.struct_warn(msg).span_mv(span) } - /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. - /// Also include a code. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_warn_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_, ()> { - self.struct_span_warn(span, msg).code_mv(code) - } - /// Construct a builder at the `Warning` level with the `msg`. /// /// Attempting to `.emit()` the builder will only emit if either: @@ -785,18 +772,6 @@ impl DiagCtxt { self.struct_err(msg).span_mv(span) } - /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_err_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { - self.struct_span_err(span, msg).code_mv(code) - } - /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] @@ -805,28 +780,6 @@ impl DiagCtxt { DiagnosticBuilder::new(self, Error, msg) } - /// Construct a builder at the `Error` level with the `msg` and the `code`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_err_with_code( - &self, - msg: impl Into, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { - self.struct_err(msg).code_mv(code) - } - - /// Construct a builder at the `Warn` level with the `msg` and the `code`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_warn_with_code( - &self, - msg: impl Into, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_, ()> { - self.struct_warn(msg).code_mv(code) - } - /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] #[track_caller] @@ -838,18 +791,6 @@ impl DiagCtxt { self.struct_fatal(msg).span_mv(span) } - /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_fatal_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_, FatalAbort> { - self.struct_span_fatal(span, msg).code_mv(code) - } - /// Construct a builder at the `Fatal` level with the `msg`. #[rustc_lint_diagnostics] #[track_caller] @@ -897,17 +838,6 @@ impl DiagCtxt { self.struct_span_fatal(span, msg).emit() } - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_fatal_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) -> ! { - self.struct_span_fatal_with_code(span, msg, code).emit() - } - #[rustc_lint_diagnostics] #[track_caller] pub fn span_err( @@ -918,34 +848,12 @@ impl DiagCtxt { self.struct_span_err(span, msg).emit() } - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_err_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) -> ErrorGuaranteed { - self.struct_span_err_with_code(span, msg, code).emit() - } - #[rustc_lint_diagnostics] #[track_caller] pub fn span_warn(&self, span: impl Into, msg: impl Into) { self.struct_span_warn(span, msg).emit() } - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_warn_with_code( - &self, - span: impl Into, - msg: impl Into, - code: DiagnosticId, - ) { - self.struct_span_warn_with_code(span, msg, code).emit() - } - pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.struct_span_bug(span, msg).emit() } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 0a924aa3536..eb6a5cc5b21 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1647,7 +1647,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let msg = format!("{kind} `{name}` is private"); let def_span = tcx.def_span(item); tcx.dcx() - .struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624)) + .struct_span_err(span, msg) + .code_mv(rustc_errors::error_code!(E0624)) .span_label_mv(span, format!("private {kind}")) .span_label_mv(def_span, format!("{kind} defined here")) .emit(); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index f5323fd3bb8..46b5c1a94de 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1371,7 +1371,7 @@ fn compare_number_of_generics<'tcx>( let spans = arg_spans(impl_.kind, impl_item.generics); let span = spans.first().copied(); - let mut err = tcx.dcx().struct_span_err_with_code( + let mut err = tcx.dcx().struct_span_err( spans, format!( "{} `{}` has {} {kind} parameter{} but its trait \ @@ -1384,8 +1384,8 @@ fn compare_number_of_generics<'tcx>( pluralize!(trait_count), kind = kind, ), - DiagnosticId::Error("E0049".into()), ); + err.code(DiagnosticId::Error("E0049".into())); let msg = format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),); diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index ae68a8bf281..04c42b4b2e6 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -523,8 +523,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> { let span = self.path_segment.ident.span; let msg = self.create_error_message(); - - self.tcx.dcx().struct_span_err_with_code(span, msg, self.code()) + self.tcx.dcx().struct_span_err(span, msg).code_mv(self.code()) } /// Builds the `expected 1 type argument / supplied 2 type arguments` message. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c7163913517..7617f03fcf2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -940,12 +940,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - // FIXME: Make this use Diagnostic once error codes can be dynamically set. - let mut err = self.dcx().struct_span_err_with_code( - op_span, - "invalid left-hand side of assignment", - DiagnosticId::Error(err_code.into()), - ); + let mut err = self.dcx().struct_span_err(op_span, "invalid left-hand side of assignment"); + err.code(DiagnosticId::Error(err_code.into())); err.span_label(lhs.span, "cannot assign to this expression"); self.comes_from_while_condition(lhs.hir_id, |expr| { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9b891691161..da6f2042c11 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -664,7 +664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("arguments to this {call_name} are incorrect"), ); } else { - err = tcx.dcx().struct_span_err_with_code( + err = tcx.dcx().struct_span_err( full_call_span, format!( "{call_name} takes {}{} but {} {} supplied", @@ -676,8 +676,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { potentially_plural_count(provided_args.len(), "argument"), pluralize!("was", provided_args.len()) ), - DiagnosticId::Error(err_code.to_owned()), ); + err.code(DiagnosticId::Error(err_code.to_owned())); err.multipart_suggestion_verbose( "wrap these arguments in parentheses to construct a tuple", vec![ @@ -815,18 +815,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_name, ) } else { - tcx.dcx().struct_span_err_with_code( - full_call_span, - format!( - "this {} takes {}{} but {} {} supplied", - call_name, - if c_variadic { "at least " } else { "" }, - potentially_plural_count(formal_and_expected_inputs.len(), "argument"), - potentially_plural_count(provided_args.len(), "argument"), - pluralize!("was", provided_args.len()) - ), - DiagnosticId::Error(err_code.to_owned()), - ) + tcx.dcx() + .struct_span_err( + full_call_span, + format!( + "this {} takes {}{} but {} {} supplied", + call_name, + if c_variadic { "at least " } else { "" }, + potentially_plural_count(formal_and_expected_inputs.len(), "argument"), + potentially_plural_count(provided_args.len(), "argument"), + pluralize!("was", provided_args.len()) + ), + ) + .code_mv(DiagnosticId::Error(err_code.to_owned())) }; // As we encounter issues, keep track of what we want to provide for the suggestion diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index c3332a49306..ffae08d0f27 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -366,11 +366,10 @@ fn report_unexpected_variant_res( _ => res.descr(), }; let path_str = rustc_hir_pretty::qpath_to_string(qpath); - let err = tcx.dcx().struct_span_err_with_code( - span, - format!("expected {expected}, found {res_descr} `{path_str}`"), - DiagnosticId::Error(err_code.into()), - ); + let err = tcx + .dcx() + .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`")) + .code_mv(DiagnosticId::Error(err_code.into())); match res { Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => { let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html"; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f88fd617c13..5dd4f959beb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2356,15 +2356,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }, }; - let mut err = self.tcx.dcx().struct_span_err_with_code( - span, - format!("{labeled_user_string} may not live long enough"), - match sub.kind() { - ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309), - ty::ReStatic => error_code!(E0310), - _ => error_code!(E0311), - }, - ); + let mut err = self + .tcx + .dcx() + .struct_span_err(span, format!("{labeled_user_string} may not live long enough")); + err.code(match sub.kind() { + ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309), + ty::ReStatic => error_code!(E0310), + _ => error_code!(E0311), + }); '_explain: { let (description, span) = match sub.kind() { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index bc42b1b3ef8..d08f31e69d8 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -395,51 +395,58 @@ impl<'a> StringReader<'a> { match kind { rustc_lexer::LiteralKind::Char { terminated } => { if !terminated { - self.dcx().span_fatal_with_code( - self.mk_sp(start, end), - "unterminated character literal", - error_code!(E0762), - ) + self.dcx() + .struct_span_fatal(self.mk_sp(start, end), "unterminated character literal") + .code_mv(error_code!(E0762)) + .emit() } self.cook_quoted(token::Char, Mode::Char, start, end, 1, 1) // ' ' } rustc_lexer::LiteralKind::Byte { terminated } => { if !terminated { - self.dcx().span_fatal_with_code( - self.mk_sp(start + BytePos(1), end), - "unterminated byte constant", - error_code!(E0763), - ) + self.dcx() + .struct_span_fatal( + self.mk_sp(start + BytePos(1), end), + "unterminated byte constant", + ) + .code_mv(error_code!(E0763)) + .emit() } self.cook_quoted(token::Byte, Mode::Byte, start, end, 2, 1) // b' ' } rustc_lexer::LiteralKind::Str { terminated } => { if !terminated { - self.dcx().span_fatal_with_code( - self.mk_sp(start, end), - "unterminated double quote string", - error_code!(E0765), - ) + self.dcx() + .struct_span_fatal( + self.mk_sp(start, end), + "unterminated double quote string", + ) + .code_mv(error_code!(E0765)) + .emit() } self.cook_quoted(token::Str, Mode::Str, start, end, 1, 1) // " " } rustc_lexer::LiteralKind::ByteStr { terminated } => { if !terminated { - self.dcx().span_fatal_with_code( - self.mk_sp(start + BytePos(1), end), - "unterminated double quote byte string", - error_code!(E0766), - ) + self.dcx() + .struct_span_fatal( + self.mk_sp(start + BytePos(1), end), + "unterminated double quote byte string", + ) + .code_mv(error_code!(E0766)) + .emit() } self.cook_quoted(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" " } rustc_lexer::LiteralKind::CStr { terminated } => { if !terminated { - self.dcx().span_fatal_with_code( - self.mk_sp(start + BytePos(1), end), - "unterminated C string", - error_code!(E0767), - ) + self.dcx() + .struct_span_fatal( + self.mk_sp(start + BytePos(1), end), + "unterminated C string", + ) + .code_mv(error_code!(E0767)) + .emit() } self.cook_c_string(token::CStr, Mode::CStr, start, end, 2, 1) // c" " } @@ -573,12 +580,9 @@ impl<'a> StringReader<'a> { possible_offset: Option, found_terminators: u32, ) -> ! { - let mut err = self.dcx().struct_span_fatal_with_code( - self.mk_sp(start, start), - "unterminated raw string", - error_code!(E0748), - ); - + let mut err = + self.dcx().struct_span_fatal(self.mk_sp(start, start), "unterminated raw string"); + err.code(error_code!(E0748)); err.span_label(self.mk_sp(start, start), "unterminated raw string"); if n_hashes > 0 { @@ -609,11 +613,8 @@ impl<'a> StringReader<'a> { None => "unterminated block comment", }; let last_bpos = self.pos; - let mut err = self.dcx().struct_span_fatal_with_code( - self.mk_sp(start, last_bpos), - msg, - error_code!(E0758), - ); + let mut err = self.dcx().struct_span_fatal(self.mk_sp(start, last_bpos), msg); + err.code(error_code!(E0758)); let mut nested_block_comment_open_idxs = vec![]; let mut last_nested_block_comment_idxs = None; let mut content_chars = self.str_from(start).char_indices().peekable(); diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 1f8c368b2a9..cec657f7b67 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -55,11 +55,10 @@ impl<'a> Parser<'a> { } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind { if attr_style != ast::AttrStyle::Outer { let span = self.token.span; - let mut err = self.dcx().struct_span_err_with_code( - span, - fluent::parse_inner_doc_comment_not_permitted, - error_code!(E0753), - ); + let mut err = self + .dcx() + .struct_span_err(span, fluent::parse_inner_doc_comment_not_permitted); + err.code(error_code!(E0753)); if let Some(replacement_span) = self.annotate_following_item_if_applicable( &mut err, span, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 977a7e796e7..57f23200e79 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -944,13 +944,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { trait_item_span, trait_path, } => { - self.dcx().struct_span_err_with_code( + self.dcx().struct_span_err( span, format!( "item `{name}` is an associated {kind}, which doesn't match its trait `{trait_path}`", ), - code, ) + .code_mv(code) .span_label_mv(span, "does not match trait") .span_label_mv(trait_item_span, "item in trait") } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 70519af16c5..a36d1377ab5 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -429,8 +429,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let base_error = self.make_base_error(path, span, source, res); let code = source.error_code(res.is_some()); - let mut err = - self.r.dcx().struct_span_err_with_code(base_error.span, base_error.msg.clone(), code); + let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone()); + err.code(code); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 51119c3560e..b05895e4b9a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2525,14 +2525,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Replace the more general E0283 with a more specific error err.cancel(); - err = self.dcx().struct_span_err_with_code( + err = self.dcx().struct_span_err( span, format!( "cannot {verb} associated {noun} on trait without specifying the \ corresponding `impl` type", ), - rustc_errors::error_code!(E0790), ); + err.code(rustc_errors::error_code!(E0790)); if let Some(local_def_id) = data.trait_ref.def_id.as_local() && let Some(hir::Node::Item(hir::Item { -- cgit 1.4.1-3-g733a5 From 1881055000485527e3ad69e2bc6c9fa247e3f06f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 09:55:07 +1100 Subject: Remove a `DiagnosticBuilder::emit_without_consuming` call. In this parsing recovery function, we only need to emit the previously obtained error message and mark `expr` as erroneous in the case where we actually recover. --- compiler/rustc_parse/src/parser/diagnostics.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 66d80fa3c52..b05940f3569 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1212,29 +1212,32 @@ impl<'a> Parser<'a> { match x { Ok((_, _, false)) => { if self.eat(&token::Gt) { + // We made sense of it. Improve the error message. e.span_suggestion_verbose( binop.span.shrink_to_lo(), fluent::parse_sugg_turbofish_syntax, "::", Applicability::MaybeIncorrect, - ) - .emit_without_consuming(); + ); match self.parse_expr() { Ok(_) => { + // The subsequent expression is valid. Mark + // `expr` as erroneous and emit `e` now, but + // return `Ok` so parsing can continue. + e.emit(); *expr = self.mk_expr_err(expr.span.to(self.prev_token.span)); return Ok(()); } Err(err) => { - *expr = self.mk_expr_err(expr.span); err.cancel(); } } } } + Ok((_, _, true)) => {} Err(err) => { err.cancel(); } - _ => {} } } Err(e) -- cgit 1.4.1-3-g733a5 From 3ce34f42e160d7e63132c7e3994861bb876eb943 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 10:42:31 +1100 Subject: Remove a second `DiagnosticBuilder::emit_without_consuming` call. Instead of taking `seq` as a mutable reference, `maybe_recover_struct_lit_bad_delims` now consumes `seq` on the recovery path, and returns `seq` unchanged on the non-recovery path. The commit also combines an `if` and a `match` to merge two identical paths. Also change `recover_seq_parse_error` so it receives a `PErr` instead of a `PResult`, because all the call sites now handle the `Ok`/`Err` distinction themselves. --- compiler/rustc_parse/src/parser/diagnostics.rs | 17 +++------ compiler/rustc_parse/src/parser/expr.rs | 52 ++++++++++++-------------- 2 files changed, 30 insertions(+), 39 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b05940f3569..776d0ace875 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -35,7 +35,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, FatalError, - PResult, + PErr, PResult, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -2044,17 +2044,12 @@ impl<'a> Parser<'a> { &mut self, delim: Delimiter, lo: Span, - result: PResult<'a, P>, + err: PErr<'a>, ) -> P { - match result { - Ok(x) => x, - Err(err) => { - err.emit(); - // Recover from parse error, callers expect the closing delim to be consumed. - self.consume_block(delim, ConsumeClosingDelim::Yes); - self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err) - } - } + err.emit(); + // Recover from parse error, callers expect the closing delim to be consumed. + self.consume_block(delim, ConsumeClosingDelim::Yes); + self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err) } /// Eats tokens until we can be relatively sure we reached the end of the diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 697c44a9f3e..db777266b59 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1272,15 +1272,13 @@ impl<'a> Parser<'a> { }; let open_paren = self.token.span; - let mut seq = self + let seq = self .parse_expr_paren_seq() .map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args))); - if let Some(expr) = - self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot) - { - return expr; + match self.maybe_recover_struct_lit_bad_delims(lo, open_paren, seq, snapshot) { + Ok(expr) => expr, + Err(err) => self.recover_seq_parse_error(Delimiter::Parenthesis, lo, err), } - self.recover_seq_parse_error(Delimiter::Parenthesis, lo, seq) } /// If we encounter a parser state that looks like the user has written a `struct` literal with @@ -1290,14 +1288,11 @@ impl<'a> Parser<'a> { &mut self, lo: Span, open_paren: Span, - seq: &mut PResult<'a, P>, + seq: PResult<'a, P>, snapshot: Option<(SnapshotParser<'a>, ExprKind)>, - ) -> Option> { - if !self.may_recover() { - return None; - } - match (seq.as_mut(), snapshot) { - (Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => { + ) -> PResult<'a, P> { + match (self.may_recover(), seq, snapshot) { + (true, Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => { snapshot.bump(); // `(` match snapshot.parse_struct_fields(path.clone(), false, Delimiter::Parenthesis) { Ok((fields, ..)) @@ -1315,11 +1310,13 @@ impl<'a> Parser<'a> { if !fields.is_empty() && // `token.kind` should not be compared here. // This is because the `snapshot.token.kind` is treated as the same as - // that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different. + // that of the open delim in `TokenTreesReader::parse_token_tree`, even + // if they are different. self.span_to_snippet(close_paren).is_ok_and(|snippet| snippet == ")") { - let mut replacement_err = - self.dcx().create_err(errors::ParenthesesWithStructFields { + err.cancel(); + self.dcx() + .create_err(errors::ParenthesesWithStructFields { span, r#type: path, braces_for_struct: errors::BracesForStructLiteral { @@ -1332,23 +1329,22 @@ impl<'a> Parser<'a> { .map(|field| field.span.until(field.expr.span)) .collect(), }, - }); - replacement_err.emit_without_consuming(); - - let old_err = mem::replace(err, replacement_err); - old_err.cancel(); + }) + .emit(); } else { - err.emit_without_consuming(); + err.emit(); } - return Some(self.mk_expr_err(span)); + Ok(self.mk_expr_err(span)) + } + Ok(_) => Err(err), + Err(err2) => { + err2.cancel(); + Err(err) } - Ok(_) => {} - Err(err) => err.cancel(), } } - _ => {} + (_, seq, _) => seq, } - None } /// Parse an indexing expression `expr[...]`. @@ -1552,7 +1548,7 @@ impl<'a> Parser<'a> { ) { Ok(x) => x, Err(err) => { - return Ok(self.recover_seq_parse_error(Delimiter::Parenthesis, lo, Err(err))); + return Ok(self.recover_seq_parse_error(Delimiter::Parenthesis, lo, err)); } }; let kind = if es.len() == 1 && !trailing_comma { -- cgit 1.4.1-3-g733a5 From 1b6c8e7533ae387ed320fc55a45dee95acc311ee Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 10:55:45 +1100 Subject: Remove a third `DiagnosticBuilder::emit_without_consuming` call. It's not clear why this was here, because the created error is returned as a normal error anyway. Nor is it clear why removing the call works. The change doesn't affect any tests; `tests/ui/parser/issues/issue-102182-impl-trait-recover.rs` looks like the only test that could have been affected. --- compiler/rustc_parse/src/parser/generics.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 7ff72eb5fb3..66aa8cbcda4 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -77,7 +77,6 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.emit_without_consuming(); return Err(err); } } -- cgit 1.4.1-3-g733a5 From c733a0216d55977e51a26ead6f2446668f006e02 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 11:10:18 +1100 Subject: Remove a fourth `DiagnosticBuilder::emit_without_consuming` call. The old code was very hard to understand, involving an `emit_without_consuming` call *and* a `delay_as_bug_without_consuming` call. With slight changes both calls can be avoided. Not creating the error until later is crucial, as is the early return in the `if recovered` block. It took me some time to come up with this reworking -- it went through intermediate states much further from the original code than this final version -- and it's isn't obvious at a glance that it is equivalent. But I think it is, and the unchanged test behaviour is good supporting evidence. The commit also changes `check_trailing_angle_brackets` to return `Option`. This provides a stricter proof that it emitted an error message than asserting `dcx.has_errors().is_some()`, which would succeed if any error had previously been emitted anywhere. --- compiler/rustc_parse/src/parser/diagnostics.rs | 17 ++++++------- compiler/rustc_parse/src/parser/item.rs | 35 ++++++++++---------------- 2 files changed, 21 insertions(+), 31 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 776d0ace875..a9cf26d991c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -34,8 +34,8 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, FatalError, - PErr, PResult, + pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, + ErrorGuaranteed, FatalError, PErr, PResult, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -1049,9 +1049,9 @@ impl<'a> Parser<'a> { &mut self, segment: &PathSegment, end: &[&TokenKind], - ) -> bool { + ) -> Option { if !self.may_recover() { - return false; + return None; } // This function is intended to be invoked after parsing a path segment where there are two @@ -1086,7 +1086,7 @@ impl<'a> Parser<'a> { parsed_angle_bracket_args, ); if !parsed_angle_bracket_args { - return false; + return None; } // Keep the span at the start so we can highlight the sequence of `>` characters to be @@ -1124,7 +1124,7 @@ impl<'a> Parser<'a> { number_of_gt, number_of_shr, ); if number_of_gt < 1 && number_of_shr < 1 { - return false; + return None; } // Finally, double check that we have our end token as otherwise this is the @@ -1139,10 +1139,9 @@ impl<'a> Parser<'a> { let span = lo.until(self.token.span); let num_extra_brackets = number_of_gt + number_of_shr * 2; - self.dcx().emit_err(UnmatchedAngleBrackets { span, num_extra_brackets }); - return true; + return Some(self.dcx().emit_err(UnmatchedAngleBrackets { span, num_extra_brackets })); } - false + None } /// Check if a method call with an intended turbofish has been written without surrounding diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 381ea21a244..fed3c83a81d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1793,52 +1793,43 @@ impl<'a> Parser<'a> { } _ => { let sp = self.prev_token.span.shrink_to_hi(); - let mut err = self.dcx().struct_span_err( - sp, - format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), - ); + let msg = + format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)); // Try to recover extra trailing angle brackets - let mut recovered = false; if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind { if let Some(last_segment) = segments.last() { - recovered = self.check_trailing_angle_brackets( + let guar = self.check_trailing_angle_brackets( last_segment, &[&token::Comma, &token::CloseDelim(Delimiter::Brace)], ); - if recovered { + if let Some(_guar) = guar { // Handle a case like `Vec>,` where we can continue parsing fields // after the comma self.eat(&token::Comma); - // `check_trailing_angle_brackets` already emitted a nicer error - // NOTE(eddyb) this was `.cancel()`, but `err` - // gets returned, so we can't fully defuse it. - err.delay_as_bug_without_consuming(); + + // `check_trailing_angle_brackets` already emitted a nicer error, as + // proven by the presence of `_guar`. We can continue parsing. + return Ok(a_var); } } } + let mut err = self.dcx().struct_span_err(sp, msg); + if self.token.is_ident() || (self.token.kind == TokenKind::Pound && (self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Bracket)))) { - // This is likely another field, TokenKind::Pound is used for `#[..]` attribute for next field, - // emit the diagnostic and keep going + // This is likely another field, TokenKind::Pound is used for `#[..]` + // attribute for next field. Emit the diagnostic and continue parsing. err.span_suggestion( sp, "try adding a comma", ",", Applicability::MachineApplicable, ); - err.emit_without_consuming(); - recovered = true; - } - - if recovered { - // Make sure an error was emitted (either by recovering an angle bracket, - // or by finding an identifier as the next token), since we're - // going to continue parsing - assert!(self.dcx().has_errors().is_some()); + err.emit(); } else { return Err(err); } -- cgit 1.4.1-3-g733a5 From 4752a923af2a0e26b2da0861e4a8f1f6c35b6d56 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 5 Jan 2024 16:38:04 +1100 Subject: Remove `DiagnosticBuilder::delay_as_bug_without_consuming`. The existing uses are replaced in one of three ways. - In a function that also has calls to `emit`, just rearrange the code so that exactly one of `delay_as_bug` or `emit` is called on every path. - In a function returning a `DiagnosticBuilder`, use `downgrade_to_delayed_bug`. That's good enough because it will get emitted later anyway. - In `unclosed_delim_err`, one set of errors is being replaced with another set, so just cancel the original errors. --- compiler/rustc_errors/src/diagnostic_builder.rs | 7 ------- compiler/rustc_hir_typeck/src/intrinsicck.rs | 8 +++++--- compiler/rustc_hir_typeck/src/op.rs | 2 +- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/error_reporting/note.rs | 2 +- compiler/rustc_parse/src/lexer/mod.rs | 2 +- compiler/rustc_parse/src/lexer/tokentrees.rs | 6 +++--- compiler/rustc_parse/src/parser/pat.rs | 7 ++++--- compiler/rustc_passes/src/errors.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- 10 files changed, 18 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index eb081df040a..6fd485e00ad 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -366,13 +366,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { self.emit() } - /// Non-consuming variant of `delay_as_bug`. - #[track_caller] - pub fn delay_as_bug_without_consuming(&mut self) -> G::EmitResult { - self.downgrade_to_delayed_bug(); - G::emit_producing_guarantee(self) - } - forward!((span_label, span_label_mv)( span: Span, label: impl Into, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index a18f486b0d2..8bffd2dfc70 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -121,15 +121,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if from == to { err.note(format!("`{from}` does not have a fixed size")); + err.emit(); } else { err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) .note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); if let Err(LayoutError::ReferencesError(_)) = sk_from { - err.delay_as_bug_without_consuming(); + err.delay_as_bug(); } else if let Err(LayoutError::ReferencesError(_)) = sk_to { - err.delay_as_bug_without_consuming(); + err.delay_as_bug(); + } else { + err.emit(); } } - err.emit(); } } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 59cf0d8c8ed..3b5226c6414 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -385,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::ExprKind::Assign(..) = expr.kind { // We defer to the later error produced by `check_lhs_assignable`. - err.delay_as_bug_without_consuming(); + err.downgrade_to_delayed_bug(); } let suggest_deref_binop = diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 5dd4f959beb..b1c360b61cb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -361,7 +361,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( ); } ty::ReError(_) => { - err.delay_as_bug_without_consuming(); + err.downgrade_to_delayed_bug(); } _ => { // Ugh. This is a painful case: the hidden region is not one diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index c09646b491c..77a0accf80b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -281,7 +281,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }; if sub.is_error() || sup.is_error() { - err.delay_as_bug_without_consuming(); + err.downgrade_to_delayed_bug(); } err } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index d08f31e69d8..a45bc581240 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -67,7 +67,7 @@ pub(crate) fn parse_token_trees<'a>( let (stream, res, unmatched_delims) = tokentrees::TokenTreesReader::parse_all_token_trees(string_reader); match res { - Ok(_open_spacing) if unmatched_delims.is_empty() => Ok(stream), + Ok(()) if unmatched_delims.is_empty() => Ok(stream), _ => { // Return error if there are unmatched delimiters or unclosed delimiters. // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 72f76cd8975..64b3928689a 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -277,9 +277,9 @@ impl<'a> TokenTreesReader<'a> { parser.bump(); } if !diff_errs.is_empty() { - errs.iter_mut().for_each(|err| { - err.delay_as_bug_without_consuming(); - }); + for err in errs { + err.cancel(); + } return diff_errs; } return errs; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index a6804b99204..00dc307ab60 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -242,7 +242,7 @@ impl<'a> Parser<'a> { Some(TopLevelOrPatternNotAllowedSugg::WrapInParens { span, pat }) }; - let mut err = self.dcx().create_err(match syntax_loc { + let err = self.dcx().create_err(match syntax_loc { PatternLocation::LetBinding => { TopLevelOrPatternNotAllowed::LetBinding { span, sub } } @@ -251,9 +251,10 @@ impl<'a> Parser<'a> { } }); if trailing_vert { - err.delay_as_bug_without_consuming(); + err.delay_as_bug(); + } else { + err.emit(); } - err.emit(); } Ok((pat, colon)) diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 44c71dfa8d0..d934e959a41 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1040,7 +1040,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> { // This error is redundant, we will have already emitted a // suggestion to use the label when `segment` wasn't found // (hence the `Res::Err` check). - diag.delay_as_bug_without_consuming(); + diag.downgrade_to_delayed_bug(); } _ => { diag.span_suggestion( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fb1df4e4e76..4a6ef27e7ba 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2088,7 +2088,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let ty = self.resolve_vars_if_possible(returned_ty); if ty.references_error() { // don't print out the [type error] here - err.delay_as_bug_without_consuming(); + err.downgrade_to_delayed_bug(); } else { err.span_label(expr.span, format!("this returned value is of type `{ty}`")); } -- cgit 1.4.1-3-g733a5