Skip to content

Commit 58edd7f

Browse files
committed
Use AddToDiagnostic for "use latest edition" help
1 parent 3e2ae86 commit 58edd7f

File tree

6 files changed

+53
-25
lines changed

6 files changed

+53
-25
lines changed

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 36 additions & 12 deletions
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.
@@ -1064,3 +1052,39 @@ impl PartialEq for Diagnostic {
10641052
self.keys() == other.keys()
10651053
}
10661054
}
1055+
1056+
pub enum HelpUseLatestEdition {
1057+
Cargo,
1058+
Standalone,
1059+
}
1060+
1061+
impl HelpUseLatestEdition {
1062+
pub fn new() -> Self {
1063+
if std::env::var_os("CARGO").is_some() { Self::Cargo } else { Self::Standalone }
1064+
}
1065+
}
1066+
1067+
impl AddToDiagnostic for HelpUseLatestEdition {
1068+
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
1069+
where
1070+
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
1071+
{
1072+
let msg = f(
1073+
diag,
1074+
match self {
1075+
Self::Cargo => {
1076+
format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)
1077+
}
1078+
Self::Standalone => {
1079+
format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION)
1080+
}
1081+
}
1082+
.into(),
1083+
);
1084+
diag.help(msg);
1085+
1086+
let msg =
1087+
f(diag, "for more on editions, read https://doc.rust-lang.org/edition-guide".into());
1088+
diag.note(msg);
1089+
}
1090+
}

compiler/rustc_errors/src/diagnostic_builder.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
616616
sp: impl Into<MultiSpan>,
617617
msg: impl Into<SubdiagnosticMessage>,
618618
) -> &mut Self);
619-
forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
620619
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
621620

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

compiler/rustc_errors/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ pub struct GoodPathBug;
370370

371371
pub use diagnostic::{
372372
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
373-
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
373+
DiagnosticStyledString, HelpUseLatestEdition, IntoDiagnosticArg, SubDiagnostic,
374374
};
375375
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
376376
pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 3 additions & 3 deletions
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};
@@ -2415,7 +2415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24152415
// We know by construction that `<expr>.await` is either on Rust 2015
24162416
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
24172417
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
2418-
err.help_use_latest_edition();
2418+
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
24192419
}
24202420

24212421
err.emit();

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 3 additions & 3 deletions
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;
@@ -2874,7 +2874,7 @@ impl<'a> Parser<'a> {
28742874
let mut async_block_err = |e: &mut Diagnostic, span: Span| {
28752875
recover_async = true;
28762876
e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
2877-
e.help_use_latest_edition();
2877+
HelpUseLatestEdition::new().add_to_diagnostic(e);
28782878
};
28792879

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

compiler/rustc_parse/src/parser/item.rs

Lines changed: 10 additions & 5 deletions
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};
@@ -2436,10 +2439,12 @@ impl<'a> Parser<'a> {
24362439
fn ban_async_in_2015(&self, span: Span) {
24372440
if span.rust_2015() {
24382441
let diag = self.diagnostic();
2439-
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
2440-
.span_label(span, "to use `async fn`, switch to Rust 2018 or later")
2441-
.help_use_latest_edition()
2442-
.emit();
2442+
2443+
let mut e =
2444+
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015");
2445+
e.span_label(span, "to use `async fn`, switch to Rust 2018 or later");
2446+
HelpUseLatestEdition::new().add_to_diagnostic(&mut e);
2447+
e.emit();
24432448
}
24442449
}
24452450

0 commit comments

Comments
 (0)