diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl index ca72b7faa9289..0f13d29d0fcb6 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl @@ -57,3 +57,7 @@ hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` la hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect .suggestion = change the type from `{$found_ty}` to `{$expected_ty}` + +hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` +hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` +hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_error_messages/locales/en-US/parse.ftl index 91902081d9045..21cf4bd789c7e 100644 --- a/compiler/rustc_error_messages/locales/en-US/parse.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parse.ftl @@ -574,3 +574,7 @@ parse_negative_bounds_not_supported = negative bounds are not supported [one] remove the bound *[other] remove the bounds } + +parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` +parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` +parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 632f819e58433..9ed8ab67431c0 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_error_messages::fluent_value_from_str_list_sep_by_and; use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; -use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; use std::borrow::Cow; @@ -1071,39 +1070,3 @@ impl PartialEq for Diagnostic { 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(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); - } -} diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 05cfebbfe8aca..ec04e865d53b1 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -378,7 +378,7 @@ pub struct DelayedBugPanic; pub use diagnostic::{ AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, - DiagnosticStyledString, HelpUseLatestEdition, IntoDiagnosticArg, SubDiagnostic, + DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, }; pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted}; pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList}; diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 5b4fd5e4a5283..2c8979402b654 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -2,7 +2,11 @@ use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; -use rustc_span::{symbol::Ident, Span}; +use rustc_span::{ + edition::{Edition, LATEST_STABLE_EDITION}, + symbol::Ident, + Span, +}; #[derive(Diagnostic)] #[diag(hir_typeck_field_multiply_specified_in_initializer, code = "E0062")] @@ -205,3 +209,24 @@ pub struct LangStartIncorrectRetTy<'tcx> { pub expected_ty: Ty<'tcx>, pub found_ty: Ty<'tcx>, } + +#[derive(Subdiagnostic)] +pub enum HelpUseLatestEdition { + #[help(hir_typeck_help_set_edition_cargo)] + #[note(hir_typeck_note_edition_guide)] + Cargo { edition: Edition }, + #[help(hir_typeck_help_set_edition_standalone)] + #[note(hir_typeck_note_edition_guide)] + Standalone { edition: Edition }, +} + +impl HelpUseLatestEdition { + pub fn new() -> Self { + let edition = LATEST_STABLE_EDITION; + if std::env::var_os("CARGO").is_some() { + Self::Cargo { edition } + } else { + Self::Standalone { edition } + } + } +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 3054e1c8ac211..3561992e86ab4 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -8,7 +8,7 @@ use crate::coercion::DynamicCoerceMany; use crate::errors::TypeMismatchFruTypo; use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive}; use crate::errors::{ - FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, + FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition, YieldExprOutsideOfGenerator, }; use crate::fatally_break_rust; @@ -24,7 +24,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, - DiagnosticId, ErrorGuaranteed, HelpUseLatestEdition, StashKey, + DiagnosticId, ErrorGuaranteed, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 5a7e28ce5232a..145611923ff16 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1,10 +1,9 @@ use rustc_ast::token::Token; use rustc_ast::{Path, Visibility}; -use rustc_errors::{ - fluent, AddToDiagnostic, Applicability, EmissionGuarantee, HelpUseLatestEdition, IntoDiagnostic, -}; +use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; +use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; @@ -1916,3 +1915,24 @@ pub(crate) struct NegativeBoundsNotSupportedSugg { pub num_bounds: usize, pub fixed: String, } + +#[derive(Subdiagnostic)] +pub enum HelpUseLatestEdition { + #[help(parse_help_set_edition_cargo)] + #[note(parse_note_edition_guide)] + Cargo { edition: Edition }, + #[help(parse_help_set_edition_standalone)] + #[note(parse_note_edition_guide)] + Standalone { edition: Edition }, +} + +impl HelpUseLatestEdition { + pub fn new() -> Self { + let edition = LATEST_STABLE_EDITION; + if std::env::var_os("CARGO").is_some() { + Self::Cargo { edition } + } else { + Self::Standalone { edition } + } + } +} diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5f5117d6833f8..b7a023868fced 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -11,15 +11,16 @@ use crate::errors::{ ComparisonInterpretedAsGeneric, ComparisonOrShiftInterpretedAsGenericSugg, DoCatchSyntaxRemoved, DotDotDot, EqFieldInit, ExpectedElseBlock, ExpectedEqForLetExpr, ExpectedExpressionFoundLet, FieldExpressionWithGeneric, FloatLiteralRequiresIntegerPart, - FoundExprWouldBeStmt, IfExpressionLetSomeSub, IfExpressionMissingCondition, - IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, InvalidBlockMacroSegment, - InvalidComparisonOperator, InvalidComparisonOperatorSub, InvalidInterpolatedExpression, - InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, InvalidLogicalOperatorSub, - LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression, - MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces, - MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, MissingDotDot, MissingInInForLoop, - MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, NotAsNegationOperator, - NotAsNegationOperatorSub, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields, + FoundExprWouldBeStmt, HelpUseLatestEdition, IfExpressionLetSomeSub, + IfExpressionMissingCondition, IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, + InvalidBlockMacroSegment, InvalidComparisonOperator, InvalidComparisonOperatorSub, + InvalidInterpolatedExpression, InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, + InvalidLogicalOperatorSub, LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator, + LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel, + MatchArmBodyWithoutBraces, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, + MissingDotDot, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, + NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub, + OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf, UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses, @@ -39,8 +40,8 @@ use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, R use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind}; use rustc_ast_pretty::pprust; use rustc_errors::{ - AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, - HelpUseLatestEdition, IntoDiagnostic, PResult, StashKey, + AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, + PResult, StashKey, }; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e401570912fb1..81fd084ccb38e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -3,7 +3,7 @@ use crate::errors::{ BoundsNotAllowedOnTraitAliases, ConstGlobalCannotBeMutable, ConstLetMutuallyExclusive, DefaultNotFollowedByItem, DocCommentDoesNotDocumentAnything, EnumStructMutuallyExclusive, ExpectedTraitInTraitImplFoundType, ExternCrateNameWithDashes, ExternCrateNameWithDashesSugg, - ExternItemCannotBeConst, MissingConstType, MissingForInTraitImpl, + ExternItemCannotBeConst, HelpUseLatestEdition, MissingConstType, MissingForInTraitImpl, MissingKeywordForItemDefinition, MissingTraitInTraitImpl, SelfArgumentPointer, TraitAliasCannotBeAuto, TraitAliasCannotBeUnsafe, UnexpectedTokenAfterStructName, UseEmptyBlockNotSemi, VisibilityNotFollowedByItem, @@ -26,8 +26,8 @@ use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, Visibility use rustc_ast::{MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; use rustc_errors::{ - struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, HelpUseLatestEdition, - IntoDiagnostic, PResult, StashKey, + struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult, + StashKey, }; use rustc_span::edition::Edition; use rustc_span::lev_distance::lev_distance;