Skip to content

Commit fc0ba2c

Browse files
committed
Use AddToDiagnostic for "use latest edition" help
1 parent 0e36e7c commit fc0ba2c

File tree

6 files changed

+53
-25
lines changed

6 files changed

+53
-25
lines changed

compiler/rustc_errors/src/diagnostic.rs

+36-12
Original file line numberDiff line numberDiff line change
@@ -555,18 +555,6 @@ impl Diagnostic {
555555
self
556556
}
557557

558-
/// Help the user upgrade to the latest edition.
559-
/// This is factored out to make sure it does the right thing with `Cargo.toml`.
560-
pub fn help_use_latest_edition(&mut self) -> &mut Self {
561-
if std::env::var_os("CARGO").is_some() {
562-
self.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
563-
} else {
564-
self.help(&format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION));
565-
}
566-
self.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
567-
self
568-
}
569-
570558
/// Disallow attaching suggestions this diagnostic.
571559
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
572560
/// (before and after the call to `disable_suggestions`) will be ignored.
@@ -1083,3 +1071,39 @@ impl PartialEq for Diagnostic {
10831071
self.keys() == other.keys()
10841072
}
10851073
}
1074+
1075+
pub enum HelpUseLatestEdition {
1076+
Cargo,
1077+
Standalone,
1078+
}
1079+
1080+
impl HelpUseLatestEdition {
1081+
pub fn new() -> Self {
1082+
if std::env::var_os("CARGO").is_some() { Self::Cargo } else { Self::Standalone }
1083+
}
1084+
}
1085+
1086+
impl AddToDiagnostic for HelpUseLatestEdition {
1087+
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
1088+
where
1089+
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
1090+
{
1091+
let msg = f(
1092+
diag,
1093+
match self {
1094+
Self::Cargo => {
1095+
format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)
1096+
}
1097+
Self::Standalone => {
1098+
format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION)
1099+
}
1100+
}
1101+
.into(),
1102+
);
1103+
diag.help(msg);
1104+
1105+
let msg =
1106+
f(diag, "for more on editions, read https://doc.rust-lang.org/edition-guide".into());
1107+
diag.note(msg);
1108+
}
1109+
}

compiler/rustc_errors/src/diagnostic_builder.rs

-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
669669
sp: impl Into<MultiSpan>,
670670
msg: impl Into<SubdiagnosticMessage>,
671671
) -> &mut Self);
672-
forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
673672
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
674673

675674
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);

compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub struct DelayedBugPanic;
378378

379379
pub use diagnostic::{
380380
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
381-
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
381+
DiagnosticStyledString, HelpUseLatestEdition, IntoDiagnosticArg, SubDiagnostic,
382382
};
383383
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
384384
pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};

compiler/rustc_hir_typeck/src/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use rustc_ast as ast;
2323
use rustc_data_structures::fx::FxHashMap;
2424
use rustc_data_structures::stack::ensure_sufficient_stack;
2525
use rustc_errors::{
26-
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
27-
ErrorGuaranteed, StashKey,
26+
pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
27+
DiagnosticId, ErrorGuaranteed, HelpUseLatestEdition, StashKey,
2828
};
2929
use rustc_hir as hir;
3030
use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -2433,7 +2433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24332433
// We know by construction that `<expr>.await` is either on Rust 2015
24342434
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
24352435
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
2436-
err.help_use_latest_edition();
2436+
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
24372437
}
24382438

24392439
err.emit();

compiler/rustc_parse/src/parser/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, R
3939
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
4040
use rustc_ast_pretty::pprust;
4141
use rustc_errors::{
42-
Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
43-
StashKey,
42+
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
43+
HelpUseLatestEdition, IntoDiagnostic, PResult, StashKey,
4444
};
4545
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
4646
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
@@ -2927,7 +2927,7 @@ impl<'a> Parser<'a> {
29272927
let mut async_block_err = |e: &mut Diagnostic, span: Span| {
29282928
recover_async = true;
29292929
e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
2930-
e.help_use_latest_edition();
2930+
HelpUseLatestEdition::new().add_to_diagnostic(e);
29312931
};
29322932

29332933
while self.token != token::CloseDelim(close_delim) {

compiler/rustc_parse/src/parser/item.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
1616
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
1717
use rustc_ast::{MacCall, MacDelimiter};
1818
use rustc_ast_pretty::pprust;
19-
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
19+
use rustc_errors::{
20+
struct_span_err, AddToDiagnostic, Applicability, HelpUseLatestEdition, IntoDiagnostic, PResult,
21+
StashKey,
22+
};
2023
use rustc_span::edition::Edition;
2124
use rustc_span::lev_distance::lev_distance;
2225
use rustc_span::source_map::{self, Span};
@@ -2445,10 +2448,12 @@ impl<'a> Parser<'a> {
24452448
fn ban_async_in_2015(&self, span: Span) {
24462449
if span.rust_2015() {
24472450
let diag = self.diagnostic();
2448-
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
2449-
.span_label(span, "to use `async fn`, switch to Rust 2018 or later")
2450-
.help_use_latest_edition()
2451-
.emit();
2451+
2452+
let mut e =
2453+
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015");
2454+
e.span_label(span, "to use `async fn`, switch to Rust 2018 or later");
2455+
HelpUseLatestEdition::new().add_to_diagnostic(&mut e);
2456+
e.emit();
24522457
}
24532458
}
24542459

0 commit comments

Comments
 (0)