Use AddToDiagnostic for "use latest edition" help
This commit is contained in:
parent
0e36e7cebe
commit
fc0ba2c8b6
@ -555,18 +555,6 @@ impl Diagnostic {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Help the user upgrade to the latest edition.
|
|
||||||
/// This is factored out to make sure it does the right thing with `Cargo.toml`.
|
|
||||||
pub fn help_use_latest_edition(&mut self) -> &mut Self {
|
|
||||||
if std::env::var_os("CARGO").is_some() {
|
|
||||||
self.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
|
|
||||||
} else {
|
|
||||||
self.help(&format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION));
|
|
||||||
}
|
|
||||||
self.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disallow attaching suggestions this diagnostic.
|
/// Disallow attaching suggestions this diagnostic.
|
||||||
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
|
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
|
||||||
/// (before and after the call to `disable_suggestions`) will be ignored.
|
/// (before and after the call to `disable_suggestions`) will be ignored.
|
||||||
@ -1083,3 +1071,39 @@ impl PartialEq for Diagnostic {
|
|||||||
self.keys() == other.keys()
|
self.keys() == other.keys()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum HelpUseLatestEdition {
|
||||||
|
Cargo,
|
||||||
|
Standalone,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HelpUseLatestEdition {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
if std::env::var_os("CARGO").is_some() { Self::Cargo } else { Self::Standalone }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddToDiagnostic for HelpUseLatestEdition {
|
||||||
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
|
||||||
|
where
|
||||||
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||||
|
{
|
||||||
|
let msg = f(
|
||||||
|
diag,
|
||||||
|
match self {
|
||||||
|
Self::Cargo => {
|
||||||
|
format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)
|
||||||
|
}
|
||||||
|
Self::Standalone => {
|
||||||
|
format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
diag.help(msg);
|
||||||
|
|
||||||
|
let msg =
|
||||||
|
f(diag, "for more on editions, read https://doc.rust-lang.org/edition-guide".into());
|
||||||
|
diag.note(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -669,7 +669,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||||||
sp: impl Into<MultiSpan>,
|
sp: impl Into<MultiSpan>,
|
||||||
msg: impl Into<SubdiagnosticMessage>,
|
msg: impl Into<SubdiagnosticMessage>,
|
||||||
) -> &mut Self);
|
) -> &mut Self);
|
||||||
forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
|
|
||||||
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
|
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
|
||||||
|
|
||||||
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);
|
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);
|
||||||
|
@ -378,7 +378,7 @@ pub struct DelayedBugPanic;
|
|||||||
|
|
||||||
pub use diagnostic::{
|
pub use diagnostic::{
|
||||||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
||||||
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
|
DiagnosticStyledString, HelpUseLatestEdition, IntoDiagnosticArg, SubDiagnostic,
|
||||||
};
|
};
|
||||||
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
|
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
|
||||||
pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};
|
pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};
|
||||||
|
@ -23,8 +23,8 @@ use rustc_ast as ast;
|
|||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
|
pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
|
||||||
ErrorGuaranteed, StashKey,
|
DiagnosticId, ErrorGuaranteed, HelpUseLatestEdition, StashKey,
|
||||||
};
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
@ -2433,7 +2433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We know by construction that `<expr>.await` is either on Rust 2015
|
// We know by construction that `<expr>.await` is either on Rust 2015
|
||||||
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
|
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
|
||||||
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
|
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
|
||||||
err.help_use_latest_edition();
|
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -39,8 +39,8 @@ use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, R
|
|||||||
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
|
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||||
StashKey,
|
HelpUseLatestEdition, IntoDiagnostic, PResult, StashKey,
|
||||||
};
|
};
|
||||||
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
|
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
|
||||||
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
|
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
|
||||||
@ -2927,7 +2927,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut async_block_err = |e: &mut Diagnostic, span: Span| {
|
let mut async_block_err = |e: &mut Diagnostic, span: Span| {
|
||||||
recover_async = true;
|
recover_async = true;
|
||||||
e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
|
e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
|
||||||
e.help_use_latest_edition();
|
HelpUseLatestEdition::new().add_to_diagnostic(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
while self.token != token::CloseDelim(close_delim) {
|
while self.token != token::CloseDelim(close_delim) {
|
||||||
|
@ -16,7 +16,10 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
|
|||||||
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||||
use rustc_ast::{MacCall, MacDelimiter};
|
use rustc_ast::{MacCall, MacDelimiter};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
|
use rustc_errors::{
|
||||||
|
struct_span_err, AddToDiagnostic, Applicability, HelpUseLatestEdition, IntoDiagnostic, PResult,
|
||||||
|
StashKey,
|
||||||
|
};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::lev_distance::lev_distance;
|
use rustc_span::lev_distance::lev_distance;
|
||||||
use rustc_span::source_map::{self, Span};
|
use rustc_span::source_map::{self, Span};
|
||||||
@ -2445,10 +2448,12 @@ impl<'a> Parser<'a> {
|
|||||||
fn ban_async_in_2015(&self, span: Span) {
|
fn ban_async_in_2015(&self, span: Span) {
|
||||||
if span.rust_2015() {
|
if span.rust_2015() {
|
||||||
let diag = self.diagnostic();
|
let diag = self.diagnostic();
|
||||||
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
|
|
||||||
.span_label(span, "to use `async fn`, switch to Rust 2018 or later")
|
let mut e =
|
||||||
.help_use_latest_edition()
|
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015");
|
||||||
.emit();
|
e.span_label(span, "to use `async fn`, switch to Rust 2018 or later");
|
||||||
|
HelpUseLatestEdition::new().add_to_diagnostic(&mut e);
|
||||||
|
e.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user