Auto merge of #103042 - davidtwco:translation-distributed-ftl, r=oli-obk

errors: generate typed identifiers in each crate

Instead of loading the Fluent resources for every crate in `rustc_error_messages`, each crate generates typed identifiers for its own diagnostics and creates a static which are pulled together in the `rustc_driver` crate and provided to the diagnostic emitter.

There are advantages and disadvantages to this change..

#### Advantages
- Changing a diagnostic now only recompiles the crate for that diagnostic and those crates that depend on it, rather than `rustc_error_messages` and all crates thereafter.
- This approach can be used to support first-party crates that want to supply translatable diagnostics (e.g. `rust-lang/thorin` in https://github.com/rust-lang/rust/pull/102612#discussion_r985372582, cc `@JhonnyBillM)`
- We can extend this a little so that tools built using rustc internals (like clippy or rustdoc) can add their own diagnostic resources (much more easily than those resources needing to be available to `rustc_error_messages`)

#### Disadvantages
- Crates can only refer to the diagnostic messages defined in the current crate (or those from dependencies), rather than all diagnostic messages.
- `rustc_driver` (or some other crate we create for this purpose) has to directly depend on *everything* that has error messages.
  - It already transitively depended on all these crates.

#### Pending work
- [x] I don't know how to make `rustc_codegen_gcc`'s translated diagnostics work with this approach - because `rustc_driver` can't depend on that crate and so can't get its resources to provide to the diagnostic emission. I don't really know how the alternative codegen backends are actually wired up to the compiler at all.
- [x] Update `triagebot.toml` to track the moved FTL files.

r? `@compiler-errors`
cc #100717
This commit is contained in:
bors 2023-02-22 15:14:22 +00:00
commit b869e84e58
156 changed files with 1786 additions and 1454 deletions

View File

@ -3930,26 +3930,47 @@ version = "0.0.0"
dependencies = [
"libc",
"rustc_ast",
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr",
"rustc_borrowck",
"rustc_builtin_macros",
"rustc_codegen_ssa",
"rustc_const_eval",
"rustc_data_structures",
"rustc_error_codes",
"rustc_error_messages",
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_hir",
"rustc_hir_analysis",
"rustc_hir_pretty",
"rustc_hir_typeck",
"rustc_incremental",
"rustc_infer",
"rustc_interface",
"rustc_lint",
"rustc_log",
"rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_mir_build",
"rustc_mir_dataflow",
"rustc_monomorphize",
"rustc_parse",
"rustc_passes",
"rustc_plugin_impl",
"rustc_privacy",
"rustc_query_system",
"rustc_resolve",
"rustc_session",
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
"rustc_trait_selection",
"rustc_ty_utils",
"serde_json",
"tracing",
"winapi",

View File

@ -339,7 +339,7 @@ pub struct InclusiveRangeWithNoEnd {
#[derive(Diagnostic, Clone, Copy)]
#[diag(ast_lowering_trait_fn_async, code = "E0706")]
#[note]
#[note(note2)]
#[note(ast_lowering_note2)]
pub struct TraitFnAsync {
#[primary_span]
pub fn_span: Span,

View File

@ -52,15 +52,20 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey};
use rustc_errors::{
DiagnosticArgFromDisplay, DiagnosticMessage, Handler, StashKey, SubdiagnosticMessage,
};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_hir::definitions::DefPathData;
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_macros::fluent_messages;
use rustc_middle::{
span_bug,
ty::{ResolverAstLowering, TyCtxt},
};
use rustc_session::parse::feature_err;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DesugaringKind;
@ -87,6 +92,8 @@ mod lifetime_collector;
mod pat;
mod path;
fluent_messages! { "../locales/en-US.ftl" }
struct LoweringContext<'a, 'hir> {
tcx: TyCtxt<'hir>,
resolver: &'a mut ResolverAstLowering,

View File

@ -13,7 +13,7 @@ use rustc_ast::walk_list;
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
use rustc_macros::Subdiagnostic;
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
@ -30,6 +30,7 @@ use std::ops::{Deref, DerefMut};
use thin_vec::thin_vec;
use crate::errors::*;
use crate::fluent_generated as fluent;
const MORE_EXTERN: &str =
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
@ -1723,12 +1724,12 @@ pub(crate) enum ForbiddenLetReason {
/// `let` is not valid and the source environment is not important
GenericForbidden,
/// A let chain with the `||` operator
#[note(not_supported_or)]
#[note(ast_passes_not_supported_or)]
NotSupportedOr(#[primary_span] Span),
/// A let chain with invalid parentheses
///
/// For example, `let 1 = 1 && (expr && expr)` is allowed
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
#[note(not_supported_parentheses)]
#[note(ast_passes_not_supported_parentheses)]
NotSupportedParentheses(#[primary_span] Span),
}

View File

@ -50,7 +50,7 @@ pub struct InvalidLabel {
pub struct InvalidVisibility {
#[primary_span]
pub span: Span,
#[label(implied)]
#[label(ast_passes_implied)]
pub implied: Option<Span>,
#[subdiagnostic]
pub note: Option<InvalidVisibilityNote>,
@ -58,9 +58,9 @@ pub struct InvalidVisibility {
#[derive(Subdiagnostic)]
pub enum InvalidVisibilityNote {
#[note(individual_impl_items)]
#[note(ast_passes_individual_impl_items)]
IndividualImplItems,
#[note(individual_foreign_items)]
#[note(ast_passes_individual_foreign_items)]
IndividualForeignItems,
}

View File

@ -157,7 +157,7 @@ impl<'a> PostExpansionVisitor<'a> {
&self.sess.parse_sess,
sym::non_lifetime_binders,
non_lt_param_spans,
rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param,
crate::fluent_generated::ast_passes_forbidden_non_lifetime_param,
)
.emit();
}

View File

@ -11,8 +11,13 @@
#![feature(let_chains)]
#![recursion_limit = "256"]
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
pub mod ast_validation;
mod errors;
pub mod feature_gate;
pub mod node_count;
pub mod show_span;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -11,6 +11,9 @@
#[macro_use]
extern crate rustc_macros;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
mod builtin;
mod session_diagnostics;
@ -22,3 +25,5 @@ pub use StabilityLevel::*;
pub use rustc_ast::attr::*;
pub(crate) use rustc_ast::HashStableContext;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -2,11 +2,12 @@ use std::num::IntErrorKind;
use rustc_ast as ast;
use rustc_errors::{
error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
};
use rustc_macros::Diagnostic;
use rustc_span::{Span, Symbol};
use crate::fluent_generated as fluent;
use crate::UnsupportedLiteralReason;
#[derive(Diagnostic)]
@ -59,7 +60,7 @@ impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> {
);
diag.set_arg("item", self.item);
diag.set_arg("expected", expected.join(", "));
diag.span_label(self.span, fluent::label);
diag.span_label(self.span, fluent::attr_label);
diag
}
}
@ -99,31 +100,31 @@ pub(crate) struct InvalidIssueString {
// translatable.
#[derive(Subdiagnostic)]
pub(crate) enum InvalidIssueStringCause {
#[label(must_not_be_zero)]
#[label(attr_must_not_be_zero)]
MustNotBeZero {
#[primary_span]
span: Span,
},
#[label(empty)]
#[label(attr_empty)]
Empty {
#[primary_span]
span: Span,
},
#[label(invalid_digit)]
#[label(attr_invalid_digit)]
InvalidDigit {
#[primary_span]
span: Span,
},
#[label(pos_overflow)]
#[label(attr_pos_overflow)]
PosOverflow {
#[primary_span]
span: Span,
},
#[label(neg_overflow)]
#[label(attr_neg_overflow)]
NegOverflow {
#[primary_span]
span: Span,
@ -275,7 +276,7 @@ pub(crate) struct IncorrectReprFormatGeneric<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum IncorrectReprFormatGenericCause<'a> {
#[suggestion(suggestion, code = "{name}({int})", applicability = "machine-applicable")]
#[suggestion(attr_suggestion, code = "{name}({int})", applicability = "machine-applicable")]
Int {
#[primary_span]
span: Span,
@ -287,7 +288,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
int: u128,
},
#[suggestion(suggestion, code = "{name}({symbol})", applicability = "machine-applicable")]
#[suggestion(attr_suggestion, code = "{name}({symbol})", applicability = "machine-applicable")]
Symbol {
#[primary_span]
span: Span,

View File

@ -20,7 +20,7 @@ extern crate tracing;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::{Diagnostic, DiagnosticBuilder};
use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet;
@ -28,6 +28,7 @@ use rustc_index::vec::IndexVec;
use rustc_infer::infer::{
DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
};
use rustc_macros::fluent_messages;
use rustc_middle::mir::{
traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand,
Place, PlaceElem, PlaceRef, VarDebugInfoContents,
@ -99,6 +100,8 @@ use places_conflict::{places_conflict, PlaceConflictBias};
use region_infer::RegionInferenceContext;
use renumber::RegionCtxt;
fluent_messages! { "../locales/en-US.ftl" }
// FIXME(eddyb) perhaps move this somewhere more centrally.
#[derive(Debug)]
struct Upvar<'tcx> {

View File

@ -55,7 +55,7 @@ pub(crate) struct VarNeedNotMut {
#[derive(Diagnostic)]
#[diag(borrowck_var_cannot_escape_closure)]
#[note]
#[note(cannot_escape)]
#[note(borrowck_cannot_escape)]
pub(crate) struct FnMutError {
#[primary_span]
pub span: Span,
@ -223,7 +223,7 @@ pub(crate) struct MoveBorrow<'a> {
pub borrow_place: &'a str,
pub value_place: &'a str,
#[primary_span]
#[label(move_label)]
#[label(borrowck_move_label)]
pub span: Span,
#[label]
pub borrow_span: Span,

View File

@ -21,8 +21,10 @@ extern crate tracing;
use crate::deriving::*;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro;
use rustc_macros::fluent_messages;
use rustc_span::symbol::sym;
mod alloc_error_handler;
@ -54,6 +56,8 @@ pub mod proc_macro_harness;
pub mod standard_library_imports;
pub mod test_harness;
fluent_messages! { "../locales/en-US.ftl" }
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
macro register_bang($($name:ident: $f:expr,)*) {

View File

@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend {
}
impl CodegenBackend for CraneliftCodegenBackend {
fn locale_resource(&self) -> &'static str {
// FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated
""
}
fn init(&self, sess: &Session) {
use rustc_session::config::Lto;
match sess.lto() {

View File

@ -73,7 +73,8 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorGuaranteed, Handler};
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::TyCtxt;
@ -84,6 +85,8 @@ use rustc_span::Symbol;
use rustc_span::fatal_error::FatalError;
use tempfile::TempDir;
fluent_messages! { "../locales/en-US.ftl" }
pub struct PrintOnPanic<F: Fn() -> String>(pub F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
@ -100,6 +103,10 @@ pub struct GccCodegenBackend {
}
impl CodegenBackend for GccCodegenBackend {
fn locale_resource(&self) -> &'static str {
crate::DEFAULT_LOCALE_RESOURCE
}
fn init(&self, sess: &Session) {
if sess.lto() != Lto::No {
sess.emit_warning(LTONotSupported {});

View File

@ -2,9 +2,10 @@ use std::borrow::Cow;
use std::ffi::CString;
use std::path::Path;
use crate::fluent_generated as fluent;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{
fluent, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic,
DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;
@ -27,9 +28,9 @@ pub(crate) struct UnknownCTargetFeature<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum PossibleFeature<'a> {
#[help(possible_feature)]
#[help(codegen_llvm_possible_feature)]
Some { rust_feature: &'a str },
#[help(consider_filing_feature_request)]
#[help(codegen_llvm_consider_filing_feature_request)]
None,
}

View File

@ -34,7 +34,8 @@ use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorGuaranteed, FatalError, Handler};
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::query::Providers;
@ -83,6 +84,8 @@ mod type_of;
mod va_arg;
mod value;
fluent_messages! { "../locales/en-US.ftl" }
#[derive(Clone)]
pub struct LlvmCodegenBackend(());
@ -246,6 +249,10 @@ impl LlvmCodegenBackend {
}
impl CodegenBackend for LlvmCodegenBackend {
fn locale_resource(&self) -> &'static str {
crate::DEFAULT_LOCALE_RESOURCE
}
fn init(&self, sess: &Session) {
llvm_util::init(sess); // Make sure llvm is inited
}

View File

@ -1,8 +1,9 @@
//! Errors emitted by codegen_ssa
use crate::back::command::Command;
use crate::fluent_generated as fluent;
use rustc_errors::{
fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
IntoDiagnosticArg,
};
use rustc_macros::Diagnostic;
@ -388,7 +389,7 @@ pub struct LinkerNotFound {
#[derive(Diagnostic)]
#[diag(codegen_ssa_unable_to_exe_linker)]
#[note]
#[note(command_note)]
#[note(codegen_ssa_command_note)]
pub struct UnableToExeLinker {
pub linker_path: PathBuf,
pub error: Error,

View File

@ -25,7 +25,9 @@ extern crate rustc_middle;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir::def_id::CrateNum;
use rustc_macros::fluent_messages;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
@ -54,6 +56,8 @@ pub mod mono_item;
pub mod target_features;
pub mod traits;
fluent_messages! { "../locales/en-US.ftl" }
pub struct ModuleCodegen<M> {
/// The name of the module. When the crate may be saved between
/// compilations, incremental compilation requires that name be

View File

@ -57,6 +57,10 @@ impl<'tcx, T> Backend<'tcx> for T where
}
pub trait CodegenBackend {
/// Locale resources for diagnostic messages - a string the content of the Fluent resource.
/// Called before `init` so that all other functions are able to emit translatable diagnostics.
fn locale_resource(&self) -> &'static str;
fn init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {

View File

@ -9,12 +9,12 @@ pub(crate) struct UnstableInStable {
#[primary_span]
pub span: Span,
#[suggestion(
unstable_sugg,
const_eval_unstable_sugg,
code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
applicability = "has-placeholders"
)]
#[suggestion(
bypass_sugg,
const_eval_bypass_sugg,
code = "#[rustc_allow_const_fn_unstable({gate})]\n",
applicability = "has-placeholders"
)]
@ -35,15 +35,15 @@ pub(crate) struct StaticAccessErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
#[note(teach_note)]
#[help(teach_help)]
#[note(const_eval_teach_note)]
#[help(const_eval_teach_help)]
pub teach: Option<()>,
}
#[derive(Diagnostic)]
#[diag(const_eval_raw_ptr_to_int)]
#[note]
#[note(note2)]
#[note(const_eval_note2)]
pub(crate) struct RawPtrToIntErr {
#[primary_span]
pub span: Span,
@ -118,7 +118,7 @@ pub(crate) struct UnallowedMutableRefs {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
#[note(teach_note)]
#[note(const_eval_teach_note)]
pub teach: Option<()>,
}
@ -128,7 +128,7 @@ pub(crate) struct UnallowedMutableRefsRaw {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
#[note(teach_note)]
#[note(const_eval_teach_note)]
pub teach: Option<()>,
}
#[derive(Diagnostic)]
@ -163,7 +163,7 @@ pub(crate) struct UnallowedHeapAllocations {
#[label]
pub span: Span,
pub kind: ConstContext,
#[note(teach_note)]
#[note(const_eval_teach_note)]
pub teach: Option<()>,
}
@ -184,7 +184,7 @@ pub(crate) struct InteriorMutableDataRefer {
#[help]
pub opt_help: Option<()>,
pub kind: ConstContext,
#[note(teach_note)]
#[note(const_eval_teach_note)]
pub teach: Option<()>,
}

View File

@ -34,10 +34,14 @@ pub mod interpret;
pub mod transform;
pub mod util;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
use rustc_middle::ty;
use rustc_middle::ty::query::Providers;
use rustc_target::abi::InitKind;
fluent_messages! { "../locales/en-US.ftl" }
pub fn provide(providers: &mut Providers) {
const_eval::provide(providers);
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;

View File

@ -9,6 +9,27 @@ edition = "2021"
tracing = { version = "0.1.35" }
serde_json = "1.0.59"
rustc_log = { path = "../rustc_log" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_attr = { path = "../rustc_attr" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_const_eval = { path = "../rustc_const_eval" }
rustc_error_messages = { path = "../rustc_error_messages" }
rustc_expand = { path = "../rustc_expand" }
rustc_hir_typeck = { path = "../rustc_hir_typeck" }
rustc_incremental = { path = "../rustc_incremental" }
rustc_infer = { path = "../rustc_infer" }
rustc_mir_build = { path = "../rustc_mir_build" }
rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
rustc_monomorphize = { path = "../rustc_monomorphize" }
rustc_passes = { path = "../rustc_passes" }
rustc_privacy = { path = "../rustc_privacy" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_resolve = { path = "../rustc_resolve" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
rustc_middle = { path = "../rustc_middle" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_target = { path = "../rustc_target" }

View File

@ -23,11 +23,14 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::SeqCst;
use rustc_errors::registry::{InvalidErrorCode, Registry};
use rustc_errors::{ErrorGuaranteed, PResult, TerminalUrl};
use rustc_errors::{
DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl,
};
use rustc_feature::find_gated_cfg;
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
use rustc_interface::{interface, Queries};
use rustc_lint::LintStore;
use rustc_macros::fluent_messages;
use rustc_metadata::locator;
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths};
@ -61,6 +64,44 @@ use crate::session_diagnostics::{
RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead,
};
fluent_messages! { "../locales/en-US.ftl" }
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
// tidy-alphabetical-start
crate::DEFAULT_LOCALE_RESOURCE,
rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE,
rustc_ast_passes::DEFAULT_LOCALE_RESOURCE,
rustc_attr::DEFAULT_LOCALE_RESOURCE,
rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE,
rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE,
rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
rustc_error_messages::DEFAULT_LOCALE_RESOURCE,
rustc_expand::DEFAULT_LOCALE_RESOURCE,
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE,
rustc_incremental::DEFAULT_LOCALE_RESOURCE,
rustc_infer::DEFAULT_LOCALE_RESOURCE,
rustc_interface::DEFAULT_LOCALE_RESOURCE,
rustc_lint::DEFAULT_LOCALE_RESOURCE,
rustc_metadata::DEFAULT_LOCALE_RESOURCE,
rustc_middle::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE,
rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
rustc_plugin_impl::DEFAULT_LOCALE_RESOURCE,
rustc_privacy::DEFAULT_LOCALE_RESOURCE,
rustc_query_system::DEFAULT_LOCALE_RESOURCE,
rustc_resolve::DEFAULT_LOCALE_RESOURCE,
rustc_session::DEFAULT_LOCALE_RESOURCE,
rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE,
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
rustc_ty_utils::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
];
/// Exit status code used for successful compilation and help output.
pub const EXIT_SUCCESS: i32 = 0;
@ -218,6 +259,7 @@ fn run_compiler(
output_file: ofile,
output_dir: odir,
file_loader,
locale_resources: DEFAULT_LOCALE_RESOURCES,
lint_caps: Default::default(),
parse_sess_created: None,
register_lints: None,
@ -1162,7 +1204,7 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
/// hook.
pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
let fallback_bundle =
rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
rustc_errors::ColorConfig::Auto,
None,

View File

@ -0,0 +1 @@
# satisfy tidy lint by having a line in this file

View File

@ -1,13 +0,0 @@
errors_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
errors_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
errors_target_missing_alignment = missing alignment for `{$cause}` in "data-layout"
errors_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err}
errors_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
errors_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
errors_target_invalid_bits_size = {$err}

View File

@ -34,47 +34,7 @@ use intl_memoizer::IntlLangMemoizer;
pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue};
pub use unic_langid::{langid, LanguageIdentifier};
// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
fluent_messages! {
// tidy-alphabetical-start
ast_lowering => "../locales/en-US/ast_lowering.ftl",
ast_passes => "../locales/en-US/ast_passes.ftl",
attr => "../locales/en-US/attr.ftl",
borrowck => "../locales/en-US/borrowck.ftl",
builtin_macros => "../locales/en-US/builtin_macros.ftl",
codegen_gcc => "../locales/en-US/codegen_gcc.ftl",
codegen_llvm => "../locales/en-US/codegen_llvm.ftl",
codegen_ssa => "../locales/en-US/codegen_ssa.ftl",
compiletest => "../locales/en-US/compiletest.ftl",
const_eval => "../locales/en-US/const_eval.ftl",
driver => "../locales/en-US/driver.ftl",
errors => "../locales/en-US/errors.ftl",
expand => "../locales/en-US/expand.ftl",
hir_analysis => "../locales/en-US/hir_analysis.ftl",
hir_typeck => "../locales/en-US/hir_typeck.ftl",
incremental => "../locales/en-US/incremental.ftl",
infer => "../locales/en-US/infer.ftl",
interface => "../locales/en-US/interface.ftl",
lint => "../locales/en-US/lint.ftl",
metadata => "../locales/en-US/metadata.ftl",
middle => "../locales/en-US/middle.ftl",
mir_build => "../locales/en-US/mir_build.ftl",
mir_dataflow => "../locales/en-US/mir_dataflow.ftl",
monomorphize => "../locales/en-US/monomorphize.ftl",
parse => "../locales/en-US/parse.ftl",
passes => "../locales/en-US/passes.ftl",
plugin_impl => "../locales/en-US/plugin_impl.ftl",
privacy => "../locales/en-US/privacy.ftl",
query_system => "../locales/en-US/query_system.ftl",
resolve => "../locales/en-US/resolve.ftl",
session => "../locales/en-US/session.ftl",
symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
trait_selection => "../locales/en-US/trait_selection.ftl",
ty_utils => "../locales/en-US/ty_utils.ftl",
// tidy-alphabetical-end
}
pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
fluent_messages! { "../locales/en-US.ftl" }
pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>;
@ -263,7 +223,7 @@ pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBund
/// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
#[instrument(level = "trace")]
pub fn fallback_fluent_bundle(
resources: &'static [&'static str],
resources: Vec<&'static str>,
with_directionality_markers: bool,
) -> LazyFallbackBundle {
Lrc::new(Lazy::new(move || {

View File

@ -0,0 +1,19 @@
errors_target_invalid_address_space =
invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
errors_target_invalid_bits =
invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
errors_target_missing_alignment =
missing alignment for `{$cause}` in "data-layout"
errors_target_invalid_alignment =
invalid alignment for `{$cause}` in "data-layout": {$err}
errors_target_inconsistent_architecture =
inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
errors_target_inconsistent_pointer_width =
inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
errors_target_invalid_bits_size = {$err}

View File

@ -1,6 +1,5 @@
use crate::{
fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
};
use crate::fluent_generated as fluent;
use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_hir as hir;

View File

@ -46,7 +46,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
let fallback_bundle =
crate::fallback_fluent_bundle(rustc_error_messages::DEFAULT_LOCALE_RESOURCES, false);
crate::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
let output = Arc::new(Mutex::new(Vec::new()));
let je = JsonEmitter::new(

View File

@ -36,11 +36,11 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
pub use rustc_error_messages::{
fallback_fluent_bundle, fluent, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
DEFAULT_LOCALE_RESOURCES,
};
pub use rustc_lint_defs::{pluralize, Applicability};
use rustc_macros::fluent_messages;
use rustc_span::source_map::SourceMap;
use rustc_span::HashStableContext;
use rustc_span::{Loc, Span};
@ -76,6 +76,8 @@ pub use snippet::Style;
pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>;
pub type PResult<'a, T> = Result<T, PErr<'a>>;
fluent_messages! { "../locales/en-US.ftl" }
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
// (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.)
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]

View File

@ -4,6 +4,7 @@ use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
use rustc_data_structures::sync::Lrc;
use rustc_error_messages::FluentArgs;
use std::borrow::Cow;
use std::env;
use std::error::Report;
/// Convert diagnostic arguments (a rustc internal type that exists to implement
@ -94,8 +95,16 @@ pub trait Translate {
// The primary bundle was present and translation succeeded
Some(Ok(t)) => t,
// Always yeet out for errors on debug
Some(Err(primary)) if cfg!(debug_assertions) => do yeet primary,
// Always yeet out for errors on debug (unless
// `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows
// local runs of the test suites, of builds with debug assertions, to test the
// behaviour in a normal build).
Some(Err(primary))
if cfg!(debug_assertions)
&& env::var("RUSTC_TRANSLATION_NO_DEBUG_ASSERT").is_err() =>
{
do yeet primary
}
// If `translate_with_bundle` returns `Err` with the primary bundle, this is likely
// just that the primary bundle doesn't contain the message being translated or

View File

@ -65,7 +65,7 @@ pub(crate) struct MacroConstStability {
#[primary_span]
#[label]
pub span: Span,
#[label(label2)]
#[label(expand_label2)]
pub head_span: Span,
}
@ -75,7 +75,7 @@ pub(crate) struct MacroBodyStability {
#[primary_span]
#[label]
pub span: Span,
#[label(label2)]
#[label(expand_label2)]
pub head_span: Span,
}
@ -188,7 +188,7 @@ pub(crate) struct FeatureRemoved<'a> {
}
#[derive(Subdiagnostic)]
#[note(reason)]
#[note(expand_reason)]
pub(crate) struct FeatureRemovedReason<'a> {
pub reason: &'a str,
}
@ -223,12 +223,12 @@ pub(crate) struct MalformedFeatureAttribute {
#[derive(Subdiagnostic)]
pub(crate) enum MalformedFeatureAttributeHelp {
#[label(expected)]
#[label(expand_expected)]
Label {
#[primary_span]
span: Span,
},
#[suggestion(expected, code = "{suggestion}", applicability = "maybe-incorrect")]
#[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")]
Suggestion {
#[primary_span]
span: Span,
@ -306,7 +306,7 @@ pub(crate) struct IncompleteParse<'a> {
pub kind_name: &'a str,
#[suggestion(
suggestion_add_semi,
expand_suggestion_add_semi,
style = "verbose",
code = ";",
applicability = "maybe-incorrect"
@ -340,7 +340,7 @@ pub(crate) struct ModuleInBlock {
}
#[derive(Subdiagnostic)]
#[note(note)]
#[note(expand_note)]
pub(crate) struct ModuleInBlockName {
#[primary_span]
pub span: Span,

View File

@ -20,6 +20,9 @@ extern crate tracing;
extern crate proc_macro as pm;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
mod placeholders;
mod proc_macro_server;
@ -60,3 +63,5 @@ mod tokenstream {
mod mut_visit {
mod tests;
}
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -18,7 +18,10 @@ use rustc_span::{BytePos, FileName, Pos, Span};
use std::path::PathBuf;
fn sess() -> ParseSess {
ParseSess::new(FilePathMapping::empty())
ParseSess::new(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty(),
)
}
/// Parses an item.

View File

@ -34,7 +34,10 @@ where
/// Maps a string to tts, using a made-up filename.
pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
let ps = ParseSess::new(FilePathMapping::empty());
let ps = ParseSess::new(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty(),
);
source_file_to_stream(
&ps,
ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str),
@ -45,7 +48,10 @@ pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
/// Parses a string, returns a crate.
pub(crate) fn string_to_crate(source_str: String) -> ast::Crate {
let ps = ParseSess::new(FilePathMapping::empty());
let ps = ParseSess::new(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty(),
);
with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod())
}
@ -127,8 +133,10 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
create_default_session_if_not_set_then(|_| {
let output = Arc::new(Mutex::new(Vec::new()));
let fallback_bundle =
rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
false,
);
let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());

View File

@ -33,20 +33,7 @@ hir_analysis_field_already_declared =
.label = field already declared
.previous_decl_label = `{$field_name}` first declared here
hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
hir_analysis_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
hir_analysis_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
hir_analysis_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
hir_analysis_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
@ -68,6 +55,25 @@ hir_analysis_value_of_associated_struct_already_specified =
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
hir_analysis_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
hir_analysis_unused_extern_crate =
unused extern crate
.suggestion = remove it
hir_analysis_extern_crate_not_idiomatic =
`extern crate` is not idiomatic in the new edition
.suggestion = convert it to a `{$msg_code}`
hir_analysis_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_analysis_missing_type_params =
the type {$parameterCount ->
[one] parameter
@ -90,20 +96,16 @@ hir_analysis_missing_type_params =
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
hir_analysis_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
hir_analysis_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
hir_analysis_unused_extern_crate =
unused extern crate
.suggestion = remove it
hir_analysis_extern_crate_not_idiomatic =
`extern crate` is not idiomatic in the new edition
.suggestion = convert it to a `{$msg_code}`
hir_analysis_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
hir_analysis_const_impl_for_non_const_trait =
const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]`

View File

@ -1,7 +1,10 @@
//! Errors emitted by `rustc_hir_analysis`.
use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
use rustc_errors::{IntoDiagnostic, MultiSpan};
use crate::fluent_generated as fluent;
use rustc_errors::{
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
MultiSpan,
};
use rustc_macros::{Diagnostic, LintDiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span, Symbol};
@ -41,11 +44,11 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
#[primary_span]
#[label]
pub span: Span,
#[label(generics_label)]
#[label(hir_analysis_generics_label)]
pub generics_span: Option<Span>,
#[label(where_label)]
#[label(hir_analysis_where_label)]
pub where_span: Option<Span>,
#[label(bounds_label)]
#[label(hir_analysis_bounds_label)]
pub bounds_span: Vec<Span>,
pub item_kind: &'static str,
pub ident: Ident,
@ -57,7 +60,7 @@ pub struct AsyncTraitImplShouldBeAsync {
#[primary_span]
// #[label]
pub span: Span,
#[label(trait_item_label)]
#[label(hir_analysis_trait_item_label)]
pub trait_item_span: Option<Span>,
pub method_name: Symbol,
}
@ -77,7 +80,7 @@ pub struct FieldAlreadyDeclared {
#[primary_span]
#[label]
pub span: Span,
#[label(previous_decl_label)]
#[label(hir_analysis_previous_decl_label)]
pub prev_span: Span,
}
@ -109,7 +112,7 @@ pub struct CopyImplOnNonAdt {
pub struct TraitObjectDeclaredWithNoTraits {
#[primary_span]
pub span: Span,
#[label(alias_span)]
#[label(hir_analysis_alias_span)]
pub trait_alias_span: Option<Span>,
}
@ -145,7 +148,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified {
#[primary_span]
#[label]
pub span: Span,
#[label(previous_bound_label)]
#[label(hir_analysis_previous_bound_label)]
pub prev_span: Span,
pub item_name: Ident,
pub def_path: String,
@ -175,7 +178,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut err = handler.struct_span_err_with_code(
self.span,
rustc_errors::fluent::hir_analysis_missing_type_params,
fluent::hir_analysis_missing_type_params,
error_code!(E0393),
);
err.set_arg("parameterCount", self.missing_type_params.len());
@ -188,7 +191,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
.join(", "),
);
err.span_label(self.def_span, rustc_errors::fluent::label);
err.span_label(self.def_span, fluent::hir_analysis_label);
let mut suggested = false;
// Don't suggest setting the type params if there are some already: the order is
@ -203,7 +206,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
// least we can clue them to the correct syntax `Iterator<Type>`.
err.span_suggestion(
self.span,
rustc_errors::fluent::suggestion,
fluent::hir_analysis_suggestion,
format!(
"{}<{}>",
snippet,
@ -219,10 +222,10 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
}
}
if !suggested {
err.span_label(self.span, rustc_errors::fluent::no_suggestion_label);
err.span_label(self.span, fluent::hir_analysis_no_suggestion_label);
}
err.note(rustc_errors::fluent::note);
err.note(fluent::hir_analysis_note);
err
}
}
@ -274,7 +277,7 @@ pub struct ConstImplForNonConstTrait {
pub local_trait_span: Option<Span>,
#[note]
pub marking: (),
#[note(adding)]
#[note(hir_analysis_adding)]
pub adding: (),
}

View File

@ -99,9 +99,11 @@ pub mod structured_errors;
mod variance;
use rustc_errors::{struct_span_err, ErrorGuaranteed};
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
use rustc_macros::fluent_messages;
use rustc_middle::middle;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -118,6 +120,8 @@ use std::ops::Not;
use astconv::AstConv;
use bounds::Bounds;
fluent_messages! { "../locales/en-US.ftl" }
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention";
const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";

View File

@ -1,17 +1,26 @@
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
hir_typeck_fru_expr = this expression does not end in a comma...
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
hir_typeck_fru_suggestion =
to set the remaining fields{$expr ->
[NONE]{""}
*[other] {" "}from `{$expr}`
}, separate the last named field with a comma
hir_typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
.previous_use_label = first use of `{$ident}`
hir_typeck_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
hir_typeck_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
hir_typeck_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
hir_typeck_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
hir_typeck_return_stmt_outside_of_fn_body =
return statement outside of function body
.encl_body_label = the return is part of this body...
@ -26,9 +35,6 @@ hir_typeck_struct_expr_non_exhaustive =
hir_typeck_method_call_on_unknown_type =
the type of this value must be known to call a method on a raw pointer on it
hir_typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
hir_typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
@ -44,9 +50,6 @@ hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on
hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
hir_typeck_op_trait_generic_params =
`{$method_name}` must not have any generic parameters
hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item
hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count}
@ -63,3 +66,14 @@ 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
hir_typeck_convert_to_str = try converting the passed type into a `&str`
hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
hir_typeck_fru_expr = this expression does not end in a comma...
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
hir_typeck_fru_suggestion =
to set the remaining fields{$expr ->
[NONE]{""}
*[other] {" "}from `{$expr}`
}, separate the last named field with a comma

View File

@ -1,4 +1,5 @@
//! Errors emitted by `rustc_hir_typeck`.
use crate::fluent_generated as fluent;
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
@ -14,7 +15,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
#[primary_span]
#[label]
pub span: Span,
#[label(previous_use_label)]
#[label(hir_typeck_previous_use_label)]
pub prev_span: Span,
pub ident: Ident,
}
@ -24,9 +25,9 @@ pub struct FieldMultiplySpecifiedInInitializer {
pub struct ReturnStmtOutsideOfFnBody {
#[primary_span]
pub span: Span,
#[label(encl_body_label)]
#[label(hir_typeck_encl_body_label)]
pub encl_body_span: Option<Span>,
#[label(encl_fn_label)]
#[label(hir_typeck_encl_fn_label)]
pub encl_fn_span: Option<Span>,
}
@ -157,20 +158,17 @@ impl AddToDiagnostic for TypeMismatchFruTypo {
// Only explain that `a ..b` is a range if it's split up
if self.expr_span.between(self.fru_span).is_empty() {
diag.span_note(
self.expr_span.to(self.fru_span),
rustc_errors::fluent::hir_typeck_fru_note,
);
diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note);
} else {
let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr);
multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2);
diag.span_note(multispan, fluent::hir_typeck_fru_note);
}
diag.span_suggestion(
self.expr_span.shrink_to_hi(),
rustc_errors::fluent::hir_typeck_fru_suggestion,
fluent::hir_typeck_fru_suggestion,
", ",
Applicability::MaybeIncorrect,
);

View File

@ -1,9 +1,10 @@
use super::FnCtxt;
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
use crate::fluent_generated as fluent;
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_errors::{fluent, Applicability, Diagnostic, MultiSpan};
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
use rustc_hir::lang_items::LangItem;

View File

@ -53,7 +53,10 @@ use crate::check::check_fn;
use crate::coercion::DynamicCoerceMany;
use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan};
use rustc_errors::{
struct_span_err, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
SubdiagnosticMessage,
};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor;
@ -61,6 +64,7 @@ use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::check_abi;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_macros::fluent_messages;
use rustc_middle::traits;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -69,6 +73,8 @@ use rustc_session::Session;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
fluent_messages! { "../locales/en-US.ftl" }
#[macro_export]
macro_rules! type_error_struct {
($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({

View File

@ -31,3 +31,8 @@ pub use persist::save_dep_graph;
pub use persist::save_work_product_index;
pub use persist::LoadResult;
pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -1,6 +1,6 @@
use hir::GenericParamKind;
use rustc_errors::{
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
};
use rustc_hir as hir;
@ -12,9 +12,10 @@ use rustc_span::symbol::kw;
use rustc_span::Symbol;
use rustc_span::{symbol::Ident, BytePos, Span};
use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted;
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{
need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
nice_region_error::placeholder_error::Highlighted,
ObligationCauseAsDiagArg,
};
@ -26,9 +27,9 @@ pub struct OpaqueHiddenTypeDiag {
#[primary_span]
#[label]
pub span: Span,
#[note(opaque_type)]
#[note(infer_opaque_type)]
pub opaque_type: Span,
#[note(hidden_type)]
#[note(infer_hidden_type)]
pub hidden_type: Span,
}
@ -768,11 +769,11 @@ impl<'tcx> ActualImplExplNotes<'tcx> {
pub struct TraitPlaceholderMismatch<'tcx> {
#[primary_span]
pub span: Span,
#[label(label_satisfy)]
#[label(infer_label_satisfy)]
pub satisfy_span: Option<Span>,
#[label(label_where)]
#[label(infer_label_where)]
pub where_span: Option<Span>,
#[label(label_dup)]
#[label(infer_label_dup)]
pub dup_span: Option<Span>,
pub def_id: String,
pub trait_def_id: String,
@ -808,11 +809,11 @@ pub struct RelationshipHelp;
#[diag(infer_trait_impl_diff)]
pub struct TraitImplDiff {
#[primary_span]
#[label(found)]
#[label(infer_found)]
pub sp: Span,
#[label(expected)]
#[label(infer_expected)]
pub trait_sp: Span,
#[note(expected_found)]
#[note(infer_expected_found)]
pub note: (),
#[subdiagnostic]
pub param_help: ConsiderBorrowingParamHelp,
@ -852,10 +853,10 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion {
#[derive(Diagnostic)]
#[diag(infer_but_calling_introduces, code = "E0772")]
pub struct ButCallingIntroduces {
#[label(label1)]
#[label(infer_label1)]
pub param_ty_span: Span,
#[primary_span]
#[label(label2)]
#[label(infer_label2)]
pub cause_span: Span,
pub has_param_name: bool,
@ -913,15 +914,15 @@ impl AddToDiagnostic for MoreTargeted {
pub struct ButNeedsToSatisfy {
#[primary_span]
pub sp: Span,
#[label(influencer)]
#[label(infer_influencer)]
pub influencer_point: Span,
#[label(used_here)]
#[label(infer_used_here)]
pub spans: Vec<Span>,
#[label(require)]
#[label(infer_require)]
pub require_span_as_label: Option<Span>,
#[note(require)]
#[note(infer_require)]
pub require_span_as_note: Option<Span>,
#[note(introduced_by_bound)]
#[note(infer_introduced_by_bound)]
pub bound: Option<Span>,
#[subdiagnostic]

View File

@ -1,7 +1,6 @@
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::nice_region_error::find_anon_type;
use rustc_errors::{
self, fluent, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage,
};
use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{symbol::kw, Span};

View File

@ -2,10 +2,11 @@ use crate::errors::{
note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
};
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
use crate::infer::{self, SubregionOrigin};
use rustc_errors::{
fluent, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::ObligationCauseCode;

View File

@ -33,6 +33,11 @@ extern crate tracing;
#[macro_use]
extern crate rustc_middle;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
mod errors;
pub mod infer;
pub mod traits;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -222,6 +222,7 @@ pub struct Config {
pub output_dir: Option<PathBuf>,
pub output_file: Option<PathBuf>,
pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
pub locale_resources: &'static [&'static str],
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
@ -267,6 +268,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
config.opts,
config.crate_cfg,
config.crate_check_cfg,
config.locale_resources,
config.file_loader,
CompilerIO {
input: config.input,

View File

@ -12,6 +12,9 @@
#[macro_use]
extern crate tracing;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
mod callbacks;
mod errors;
pub mod interface;
@ -27,3 +30,5 @@ pub use queries::Queries;
#[cfg(test)]
mod tests;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -50,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
output_file: None,
temps_dir,
};
let sess = build_session(sessopts, io, None, registry, Default::default(), None, None);
let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None);
(sess, cfg)
}

View File

@ -59,6 +59,7 @@ pub fn create_session(
sopts: config::Options,
cfg: FxHashSet<(String, Option<String>)>,
check_cfg: CheckCfg,
locale_resources: &'static [&'static str],
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
io: CompilerIO,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
@ -89,11 +90,15 @@ pub fn create_session(
}
};
let mut locale_resources = Vec::from(locale_resources);
locale_resources.push(codegen_backend.locale_resource());
let mut sess = session::build_session(
sopts,
io,
bundle,
descriptions,
locale_resources,
lint_caps,
file_loader,
target_override,

View File

@ -1,5 +1,7 @@
use crate::lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub};
use crate::{LateContext, LateLintPass, LintContext};
use crate::{
lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub},
LateContext, LateLintPass, LintContext,
};
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_middle::ty::adjustment::{Adjust, Adjustment};

View File

@ -20,6 +20,7 @@
//! If you define a new `LateLintPass`, you will also need to add it to the
//! `late_lint_methods!` invocation in `lib.rs`.
use crate::fluent_generated as fluent;
use crate::{
errors::BuiltinEllpisisInclusiveRangePatterns,
lints::{
@ -50,7 +51,7 @@ use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust::{self, expr_to_string};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{fluent, Applicability, DecorateLint, MultiSpan};
use rustc_errors::{Applicability, DecorateLint, MultiSpan};
use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};

View File

@ -1,6 +1,6 @@
use crate::fluent_generated as fluent;
use rustc_errors::{
fluent, AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic,
SubdiagnosticMessage,
AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic, SubdiagnosticMessage,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_session::lint::Level;
@ -116,7 +116,7 @@ impl IntoDiagnostic<'_> for CheckNameUnknown {
let mut diag = handler.struct_err(fluent::lint_check_name_unknown);
diag.code(rustc_errors::error_code!(E0602));
if let Some(suggestion) = self.suggestion {
diag.help(fluent::help);
diag.help(fluent::lint_help);
diag.set_arg("suggestion", suggestion);
}
diag.set_arg("lint_name", self.lint_name);

View File

@ -1,13 +1,16 @@
use crate::context::{CheckLintNameResult, LintStore};
use crate::late::unerased_lint_store;
use crate::lints::{
DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint,
RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
use crate::{
context::{CheckLintNameResult, LintStore},
fluent_generated as fluent,
late::unerased_lint_store,
lints::{
DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint,
RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
},
};
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{fluent, DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::HirId;
@ -983,7 +986,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
fluent::lint_unknown_gated_lint,
|lint| {
lint.set_arg("name", lint_id.lint.name_lower());
lint.note(fluent::note);
lint.note(fluent::lint_note);
add_feature_diagnostics(lint, &self.sess.parse_sess, feature);
lint
},

View File

@ -80,8 +80,10 @@ mod unused;
pub use array_into_iter::ARRAY_INTO_ITER;
use rustc_ast as ast;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_macros::fluent_messages;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
@ -122,6 +124,8 @@ pub use rustc_session::lint::Level::{self, *};
pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId};
pub use rustc_session::lint::{LintArray, LintPass};
fluent_messages! { "../locales/en-US.ftl" }
pub fn provide(providers: &mut Providers) {
levels::provide(providers);
expect::provide(providers);

View File

@ -2,9 +2,10 @@
#![allow(rustc::diagnostic_outside_of_impl)]
use std::num::NonZeroU32;
use crate::fluent_generated as fluent;
use rustc_errors::{
fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage,
DiagnosticStyledString, SuggestionStyle,
AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString,
SuggestionStyle,
};
use rustc_hir::def_id::DefId;
use rustc_macros::{LintDiagnostic, Subdiagnostic};
@ -23,7 +24,7 @@ use crate::{
#[diag(lint_array_into_iter)]
pub struct ArrayIntoIterDiag<'a> {
pub target: &'a str,
#[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
#[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
pub suggestion: Span,
#[subdiagnostic]
pub sub: Option<ArrayIntoIterDiagSub>,
@ -31,12 +32,15 @@ pub struct ArrayIntoIterDiag<'a> {
#[derive(Subdiagnostic)]
pub enum ArrayIntoIterDiagSub {
#[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
#[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
RemoveIntoIter {
#[primary_span]
span: Span,
},
#[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")]
#[multipart_suggestion(
lint_use_explicit_into_iter_suggestion,
applicability = "maybe-incorrect"
)]
UseExplicitIntoIter {
#[suggestion_part(code = "IntoIterator::into_iter(")]
start_span: Span,
@ -163,13 +167,13 @@ pub struct BuiltinDeprecatedAttrLink<'a> {
#[derive(Subdiagnostic)]
pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
#[suggestion(msg_suggestion, code = "", applicability = "machine-applicable")]
#[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")]
Msg {
#[primary_span]
suggestion: Span,
msg: &'a str,
},
#[suggestion(default_suggestion, code = "", applicability = "machine-applicable")]
#[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")]
Default {
#[primary_span]
suggestion: Span,
@ -201,9 +205,9 @@ pub struct BuiltinUnusedDocComment<'a> {
#[derive(Subdiagnostic)]
pub enum BuiltinUnusedDocCommentSub {
#[help(plain_help)]
#[help(lint_plain_help)]
PlainHelp,
#[help(block_help)]
#[help(lint_block_help)]
BlockHelp,
}
@ -242,7 +246,7 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
self,
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.span_label(self.label, fluent::label);
diag.span_label(self.label, fluent::lint_label);
rustc_session::parse::add_feature_diagnostics(
diag,
&self.parse_sess,
@ -337,7 +341,7 @@ impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
) -> rustc_errors::SubdiagnosticMessage,
{
diag.multipart_suggestion(
fluent::suggestion,
fluent::lint_suggestion,
self.suggestions,
Applicability::MachineApplicable,
);
@ -388,7 +392,7 @@ pub struct BuiltinExplicitOutlives {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion)]
#[multipart_suggestion(lint_suggestion)]
pub struct BuiltinExplicitOutlivesSuggestion {
#[suggestion_part(code = "")]
pub spans: Vec<Span>,
@ -407,11 +411,11 @@ pub struct BuiltinIncompleteFeatures {
}
#[derive(Subdiagnostic)]
#[help(help)]
#[help(lint_help)]
pub struct BuiltinIncompleteFeaturesHelp;
#[derive(Subdiagnostic)]
#[note(note)]
#[note(lint_note)]
pub struct BuiltinIncompleteFeaturesNote {
pub n: NonZeroU32,
}
@ -482,9 +486,9 @@ pub enum BuiltinClashingExtern<'a> {
SameName {
this: Symbol,
orig: Symbol,
#[label(previous_decl_label)]
#[label(lint_previous_decl_label)]
previous_decl_label: Span,
#[label(mismatch_label)]
#[label(lint_mismatch_label)]
mismatch_label: Span,
#[subdiagnostic]
sub: BuiltinClashingExternSub<'a>,
@ -493,9 +497,9 @@ pub enum BuiltinClashingExtern<'a> {
DiffName {
this: Symbol,
orig: Symbol,
#[label(previous_decl_label)]
#[label(lint_previous_decl_label)]
previous_decl_label: Span,
#[label(mismatch_label)]
#[label(lint_mismatch_label)]
mismatch_label: Span,
#[subdiagnostic]
sub: BuiltinClashingExternSub<'a>,
@ -571,7 +575,7 @@ pub struct SupertraitAsDerefTarget<'a> {
}
#[derive(Subdiagnostic)]
#[label(label)]
#[label(lint_label)]
pub struct SupertraitAsDerefTargetLabel {
#[primary_span]
pub label: Span,
@ -604,7 +608,7 @@ pub struct Expectation {
}
#[derive(Subdiagnostic)]
#[note(rationale)]
#[note(lint_rationale)]
pub struct ExpectationNote {
pub rationale: Symbol,
}
@ -625,13 +629,13 @@ pub struct ForLoopsOverFalliblesDiag<'a> {
#[derive(Subdiagnostic)]
pub enum ForLoopsOverFalliblesLoopSub<'a> {
#[suggestion(remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
#[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
RemoveNext {
#[primary_span]
suggestion: Span,
recv_snip: String,
},
#[multipart_suggestion(use_while_let, applicability = "maybe-incorrect")]
#[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")]
UseWhileLet {
#[suggestion_part(code = "while let {var}(")]
start_span: Span,
@ -642,14 +646,14 @@ pub enum ForLoopsOverFalliblesLoopSub<'a> {
}
#[derive(Subdiagnostic)]
#[suggestion(use_question_mark, code = "?", applicability = "maybe-incorrect")]
#[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")]
pub struct ForLoopsOverFalliblesQuestionMark {
#[primary_span]
pub suggestion: Span,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
pub struct ForLoopsOverFalliblesSuggestion<'a> {
pub var: &'a str,
#[suggestion_part(code = "if let {var}(")]
@ -708,13 +712,13 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
match self {
HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
diag.multipart_suggestion_with_style(
fluent::suggestion_remove,
fluent::lint_suggestion_remove,
spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
Applicability::MachineApplicable,
SuggestionStyle::HideCodeAlways,
);
diag.multipart_suggestion(
fluent::suggestion_escape,
fluent::lint_suggestion_escape,
spans
.into_iter()
.map(|(c, span)| {
@ -737,8 +741,8 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
.collect::<Vec<String>>()
.join(", "),
);
diag.note(fluent::suggestion_remove);
diag.note(fluent::no_suggestion_note_escape);
diag.note(fluent::lint_suggestion_remove);
diag.note(fluent::lint_no_suggestion_note_escape);
}
}
}
@ -883,7 +887,7 @@ pub struct RenamedOrRemovedLint<'a> {
}
#[derive(Subdiagnostic)]
#[suggestion(suggestion, code = "{replace}", applicability = "machine-applicable")]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
pub struct RenamedOrRemovedLintSuggestion<'a> {
#[primary_span]
pub suggestion: Span,
@ -899,7 +903,7 @@ pub struct UnknownLint {
}
#[derive(Subdiagnostic)]
#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
pub struct UnknownLintSuggestion {
#[primary_span]
pub suggestion: Span,
@ -919,9 +923,9 @@ pub struct IgnoredUnlessCrateSpecified<'a> {
#[note]
#[help]
pub struct CStringPtr {
#[label(as_ptr_label)]
#[label(lint_as_ptr_label)]
pub as_ptr: Span,
#[label(unwrap_label)]
#[label(lint_unwrap_label)]
pub unwrap: Span,
}
@ -952,7 +956,7 @@ pub struct ConfusableIdentifierPair {
#[derive(LintDiagnostic)]
#[diag(lint_mixed_script_confusables)]
#[note(includes_note)]
#[note(lint_includes_note)]
#[note]
pub struct MixedScriptConfusables {
pub set: String,
@ -972,17 +976,17 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.set_arg("count", self.count);
diag.note(fluent::note);
diag.note(fluent::lint_note);
if let Some(span) = self.suggestion {
diag.span_suggestion(
span.shrink_to_hi(),
fluent::add_args_suggestion,
fluent::lint_add_args_suggestion,
", ...",
Applicability::HasPlaceholders,
);
diag.span_suggestion(
span.shrink_to_lo(),
fluent::add_fmt_suggestion,
fluent::lint_add_fmt_suggestion,
"\"{}\", ",
Applicability::MachineApplicable,
);
@ -1016,12 +1020,12 @@ pub struct NonCamelCaseType<'a> {
#[derive(Subdiagnostic)]
pub enum NonCamelCaseTypeSub {
#[label(label)]
#[label(lint_label)]
Label {
#[primary_span]
span: Span,
},
#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
Suggestion {
#[primary_span]
span: Span,
@ -1057,15 +1061,15 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub {
{
match self {
NonSnakeCaseDiagSub::Label { span } => {
diag.span_label(span, fluent::label);
diag.span_label(span, fluent::lint_label);
}
NonSnakeCaseDiagSub::Help => {
diag.help(fluent::help);
diag.help(fluent::lint_help);
}
NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
diag.span_suggestion(
span,
fluent::convert_suggestion,
fluent::lint_convert_suggestion,
suggestion,
Applicability::MaybeIncorrect,
);
@ -1073,16 +1077,16 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub {
NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
diag.span_suggestion(
span,
fluent::rename_or_convert_suggestion,
fluent::lint_rename_or_convert_suggestion,
suggestion,
Applicability::MaybeIncorrect,
);
}
NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
diag.note(fluent::cannot_convert_note);
diag.note(fluent::lint_cannot_convert_note);
diag.span_suggestion(
span,
fluent::rename_suggestion,
fluent::lint_rename_suggestion,
"",
Applicability::MaybeIncorrect,
);
@ -1102,12 +1106,12 @@ pub struct NonUpperCaseGlobal<'a> {
#[derive(Subdiagnostic)]
pub enum NonUpperCaseGlobalSub {
#[label(label)]
#[label(lint_label)]
Label {
#[primary_span]
span: Span,
},
#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
Suggestion {
#[primary_span]
span: Span,
@ -1225,11 +1229,11 @@ impl AddToDiagnostic for OverflowingBinHexSign {
{
match self {
OverflowingBinHexSign::Positive => {
diag.note(fluent::positive_note);
diag.note(fluent::lint_positive_note);
}
OverflowingBinHexSign::Negative => {
diag.note(fluent::negative_note);
diag.note(fluent::negative_becomes_note);
diag.note(fluent::lint_negative_note);
diag.note(fluent::lint_negative_becomes_note);
}
}
}
@ -1238,7 +1242,7 @@ impl AddToDiagnostic for OverflowingBinHexSign {
#[derive(Subdiagnostic)]
pub enum OverflowingBinHexSub<'a> {
#[suggestion(
suggestion,
lint_suggestion,
code = "{sans_suffix}{suggestion_ty}",
applicability = "machine-applicable"
)]
@ -1248,7 +1252,7 @@ pub enum OverflowingBinHexSub<'a> {
suggestion_ty: &'a str,
sans_suffix: &'a str,
},
#[help(help)]
#[help(lint_help)]
Help { suggestion_ty: &'a str },
}
@ -1265,7 +1269,7 @@ pub struct OverflowingInt<'a> {
}
#[derive(Subdiagnostic)]
#[help(help)]
#[help(lint_help)]
pub struct OverflowingIntHelp<'a> {
pub suggestion_ty: &'a str,
}
@ -1317,13 +1321,13 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.set_arg("ty", self.ty);
diag.set_arg("desc", self.desc);
diag.span_label(self.label, fluent::label);
diag.span_label(self.label, fluent::lint_label);
if let Some(help) = self.help {
diag.help(help);
}
diag.note(self.note);
if let Some(note) = self.span_note {
diag.span_note(note, fluent::note);
diag.span_note(note, fluent::lint_note);
}
diag
}
@ -1416,7 +1420,7 @@ pub struct UnusedDef<'a, 'b> {
#[derive(Subdiagnostic)]
pub enum UnusedDefSuggestion {
#[suggestion(
suggestion,
lint_suggestion,
style = "verbose",
code = "let _ = ",
applicability = "machine-applicable"
@ -1460,13 +1464,13 @@ pub struct PathStatementDrop {
#[derive(Subdiagnostic)]
pub enum PathStatementDropSub {
#[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
#[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
Suggestion {
#[primary_span]
span: Span,
snippet: String,
},
#[help(help)]
#[help(lint_help)]
Help {
#[primary_span]
span: Span,
@ -1487,7 +1491,7 @@ pub struct UnusedDelim<'a> {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
pub struct UnusedDelimSuggestion {
#[suggestion_part(code = "{start_replace}")]
pub start_span: Span,

View File

@ -1,7 +1,7 @@
use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
use crate::{LateContext, LateLintPass, LintContext};
use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext};
use rustc_ast as ast;
use rustc_errors::{fluent, Applicability};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::lint::in_external_macro;
@ -122,18 +122,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
#[allow(rustc::diagnostic_outside_of_impl)]
cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| {
lint.set_arg("name", symbol);
lint.note(fluent::note);
lint.note(fluent::more_info_note);
lint.note(fluent::lint_note);
lint.note(fluent::lint_more_info_note);
if !is_arg_inside_call(arg_span, span) {
// No clue where this argument is coming from.
return lint;
}
if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
// A case of `panic!(format!(..))`.
lint.note(fluent::supports_fmt_note);
lint.note(fluent::lint_supports_fmt_note);
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
lint.multipart_suggestion(
fluent::supports_fmt_suggestion,
fluent::lint_supports_fmt_suggestion,
vec![
(arg_span.until(open.shrink_to_hi()), "".into()),
(close.until(arg_span.shrink_to_hi()), "".into()),
@ -179,7 +179,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
if suggest_display {
lint.span_suggestion_verbose(
arg_span.shrink_to_lo(),
fluent::display_suggestion,
fluent::lint_display_suggestion,
"\"{}\", ",
fmt_applicability,
);
@ -187,7 +187,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
lint.set_arg("ty", ty);
lint.span_suggestion_verbose(
arg_span.shrink_to_lo(),
fluent::debug_suggestion,
fluent::lint_debug_suggestion,
"\"{:?}\", ",
fmt_applicability,
);
@ -197,7 +197,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
if let Some((open, close, del)) = find_delimiters(cx, span) {
lint.set_arg("already_suggested", suggest_display || suggest_debug);
lint.multipart_suggestion(
fluent::panic_suggestion,
fluent::lint_panic_suggestion,
if del == '(' {
vec![(span.until(open), "std::panic::panic_any".into())]
} else {

View File

@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
struct OpaqueHiddenInferredBoundLint<'tcx> {
ty: Ty<'tcx>,
proj_ty: Ty<'tcx>,
#[label(specifically)]
#[label(lint_specifically)]
assoc_pred_span: Span,
#[subdiagnostic]
add_bound: Option<AddBound<'tcx>>,

View File

@ -1,14 +1,17 @@
use crate::lints::{
AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt,
RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
use crate::{
fluent_generated as fluent,
lints::{
AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral,
OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
},
};
use crate::{LateContext, LateLintPass, LintContext};
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{fluent, DiagnosticMessage};
use rustc_errors::DiagnosticMessage;
use rustc_hir as hir;
use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};

View File

@ -57,7 +57,7 @@ impl<'a> DiagnosticDerive<'a> {
}
Some(slug) => {
quote! {
let mut #diag = #handler.struct_diagnostic(rustc_errors::fluent::#slug);
let mut #diag = #handler.struct_diagnostic(crate::fluent_generated::#slug);
}
}
};
@ -149,7 +149,7 @@ impl<'a> LintDiagnosticDerive<'a> {
}
Some(slug) => {
quote! {
rustc_errors::fluent::#slug.into()
crate::fluent_generated::#slug.into()
}
}
}

View File

@ -452,7 +452,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
Ok(quote! {
#diag.span_suggestions_with_style(
#span_field,
rustc_errors::fluent::#slug,
crate::fluent_generated::#slug,
#code_field,
#applicability,
#style
@ -476,7 +476,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
quote! {
#diag.#fn_name(
#field_binding,
rustc_errors::fluent::#fluent_attr_identifier
crate::fluent_generated::#fluent_attr_identifier
);
}
}
@ -486,7 +486,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
let diag = &self.parent.diag;
quote! {
#diag.#kind(rustc_errors::fluent::#fluent_attr_identifier);
#diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
}
}

View File

@ -19,52 +19,9 @@ use std::{
io::Read,
path::{Path, PathBuf},
};
use syn::{
parse::{Parse, ParseStream},
parse_macro_input,
punctuated::Punctuated,
token, Ident, LitStr, Result,
};
use syn::{parse_macro_input, Ident, LitStr};
use unic_langid::langid;
struct Resource {
krate: Ident,
#[allow(dead_code)]
fat_arrow_token: token::FatArrow,
resource_path: LitStr,
}
impl Parse for Resource {
fn parse(input: ParseStream<'_>) -> Result<Self> {
Ok(Resource {
krate: input.parse()?,
fat_arrow_token: input.parse()?,
resource_path: input.parse()?,
})
}
}
struct Resources(Punctuated<Resource, token::Comma>);
impl Parse for Resources {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let mut resources = Punctuated::new();
loop {
if input.is_empty() || input.peek(token::Brace) {
break;
}
let value = input.parse()?;
resources.push_value(value);
if !input.peek(token::Comma) {
break;
}
let punct = input.parse()?;
resources.push_punct(punct);
}
Ok(Resources(resources))
}
}
/// Helper function for returning an absolute path for macro-invocation relative file paths.
///
/// If the input is already absolute, then the input is returned. If the input is not absolute,
@ -84,241 +41,16 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
}
}
/// See [rustc_macros::fluent_messages].
pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let resources = parse_macro_input!(input as Resources);
// Cannot iterate over individual messages in a bundle, so do that using the
// `FluentResource` instead. Construct a bundle anyway to find out if there are conflicting
// messages in the resources.
let mut bundle = FluentBundle::new(vec![langid!("en-US")]);
// Map of Fluent identifiers to the `Span` of the resource that defined them, used for better
// diagnostics.
let mut previous_defns = HashMap::new();
// Set of Fluent attribute names already output, to avoid duplicate type errors - any given
// constant created for a given attribute is the same.
let mut previous_attrs = HashSet::new();
let mut includes = TokenStream::new();
let mut generated = TokenStream::new();
for res in resources.0 {
let krate_span = res.krate.span().unwrap();
let path_span = res.resource_path.span().unwrap();
let relative_ftl_path = res.resource_path.value();
let absolute_ftl_path =
invocation_relative_path_to_absolute(krate_span, &relative_ftl_path);
// As this macro also outputs an `include_str!` for this file, the macro will always be
// re-executed when the file changes.
let mut resource_file = match File::open(absolute_ftl_path) {
Ok(resource_file) => resource_file,
Err(e) => {
Diagnostic::spanned(path_span, Level::Error, "could not open Fluent resource")
.note(e.to_string())
.emit();
continue;
}
};
let mut resource_contents = String::new();
if let Err(e) = resource_file.read_to_string(&mut resource_contents) {
Diagnostic::spanned(path_span, Level::Error, "could not read Fluent resource")
.note(e.to_string())
.emit();
continue;
}
let resource = match FluentResource::try_new(resource_contents) {
Ok(resource) => resource,
Err((this, errs)) => {
Diagnostic::spanned(path_span, Level::Error, "could not parse Fluent resource")
.help("see additional errors emitted")
.emit();
for ParserError { pos, slice: _, kind } in errs {
let mut err = kind.to_string();
// Entirely unnecessary string modification so that the error message starts
// with a lowercase as rustc errors do.
err.replace_range(
0..1,
&err.chars().next().unwrap().to_lowercase().to_string(),
);
let line_starts: Vec<usize> = std::iter::once(0)
.chain(
this.source()
.char_indices()
.filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')),
)
.collect();
let line_start = line_starts
.iter()
.enumerate()
.map(|(line, idx)| (line + 1, idx))
.filter(|(_, idx)| **idx <= pos.start)
.last()
.unwrap()
.0;
let snippet = Snippet {
title: Some(Annotation {
label: Some(&err),
id: None,
annotation_type: AnnotationType::Error,
}),
footer: vec![],
slices: vec![Slice {
source: this.source(),
line_start,
origin: Some(&relative_ftl_path),
fold: true,
annotations: vec![SourceAnnotation {
label: "",
annotation_type: AnnotationType::Error,
range: (pos.start, pos.end - 1),
}],
}],
opt: Default::default(),
};
let dl = DisplayList::from(snippet);
eprintln!("{dl}\n");
}
continue;
}
};
let mut constants = TokenStream::new();
let mut messagerefs = Vec::new();
for entry in resource.entries() {
let span = res.krate.span();
if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) =
entry
{
let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
if name.contains('-') {
Diagnostic::spanned(
path_span,
Level::Error,
format!("name `{name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}
if let Some(Pattern { elements }) = value {
for elt in elements {
if let PatternElement::Placeable {
expression:
Expression::Inline(InlineExpression::MessageReference { id, .. }),
} = elt
{
messagerefs.push((id.name, *name));
}
}
}
// Require that the message name starts with the crate name
// `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
// `const_eval_baz` (in `const_eval.ftl`)
// `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
// The last case we error about above, but we want to fall back gracefully
// so that only the error is being emitted and not also one about the macro
// failing.
let crate_prefix = format!("{}_", res.krate);
let snake_name = name.replace('-', "_");
if !snake_name.starts_with(&crate_prefix) {
Diagnostic::spanned(
path_span,
Level::Error,
format!("name `{name}` does not start with the crate name"),
)
.help(format!(
"prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"
))
.emit();
};
let snake_name = Ident::new(&snake_name, span);
constants.extend(quote! {
pub const #snake_name: crate::DiagnosticMessage =
crate::DiagnosticMessage::FluentIdentifier(
std::borrow::Cow::Borrowed(#name),
None
);
});
for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
let snake_name = Ident::new(&attr_name.replace('-', "_"), span);
if !previous_attrs.insert(snake_name.clone()) {
continue;
}
if attr_name.contains('-') {
Diagnostic::spanned(
path_span,
Level::Error,
format!("attribute `{attr_name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}
constants.extend(quote! {
pub const #snake_name: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(
std::borrow::Cow::Borrowed(#attr_name)
);
});
}
}
}
for (mref, name) in messagerefs.into_iter() {
if !previous_defns.contains_key(mref) {
Diagnostic::spanned(
path_span,
Level::Error,
format!("referenced message `{mref}` does not exist (in message `{name}`)"),
)
.help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
.emit();
}
}
if let Err(errs) = bundle.add_resource(resource) {
for e in errs {
match e {
FluentError::Overriding { kind, id } => {
Diagnostic::spanned(
path_span,
Level::Error,
format!("overrides existing {kind}: `{id}`"),
)
.span_help(previous_defns[&id], "previously defined in this resource")
.emit();
}
FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(),
}
}
}
includes.extend(quote! { include_str!(#relative_ftl_path), });
generated.extend(constants);
}
/// Tokens to be returned when the macro cannot proceed.
fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
quote! {
pub static DEFAULT_LOCALE_RESOURCE: &'static str = "";
#[allow(non_upper_case_globals)]
#[doc(hidden)]
pub mod fluent_generated {
pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
#includes
];
#generated
pub(crate) mod fluent_generated {
pub mod #crate_name {
}
pub mod _subdiag {
pub const help: crate::SubdiagnosticMessage =
@ -336,3 +68,262 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
}
.into()
}
/// See [rustc_macros::fluent_messages].
pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let crate_name = std::env::var("CARGO_PKG_NAME")
// If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use
// `no_crate`.
.unwrap_or_else(|_| "no_crate".to_string())
.replace("rustc_", "");
// Cannot iterate over individual messages in a bundle, so do that using the
// `FluentResource` instead. Construct a bundle anyway to find out if there are conflicting
// messages in the resources.
let mut bundle = FluentBundle::new(vec![langid!("en-US")]);
// Set of Fluent attribute names already output, to avoid duplicate type errors - any given
// constant created for a given attribute is the same.
let mut previous_attrs = HashSet::new();
let resource_str = parse_macro_input!(input as LitStr);
let resource_span = resource_str.span().unwrap();
let relative_ftl_path = resource_str.value();
let absolute_ftl_path = invocation_relative_path_to_absolute(resource_span, &relative_ftl_path);
let crate_name = Ident::new(&crate_name, resource_str.span());
// As this macro also outputs an `include_str!` for this file, the macro will always be
// re-executed when the file changes.
let mut resource_file = match File::open(absolute_ftl_path) {
Ok(resource_file) => resource_file,
Err(e) => {
Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource")
.note(e.to_string())
.emit();
return failed(&crate_name);
}
};
let mut resource_contents = String::new();
if let Err(e) = resource_file.read_to_string(&mut resource_contents) {
Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource")
.note(e.to_string())
.emit();
return failed(&crate_name);
}
let resource = match FluentResource::try_new(resource_contents) {
Ok(resource) => resource,
Err((this, errs)) => {
Diagnostic::spanned(resource_span, Level::Error, "could not parse Fluent resource")
.help("see additional errors emitted")
.emit();
for ParserError { pos, slice: _, kind } in errs {
let mut err = kind.to_string();
// Entirely unnecessary string modification so that the error message starts
// with a lowercase as rustc errors do.
err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string());
let line_starts: Vec<usize> = std::iter::once(0)
.chain(
this.source()
.char_indices()
.filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')),
)
.collect();
let line_start = line_starts
.iter()
.enumerate()
.map(|(line, idx)| (line + 1, idx))
.filter(|(_, idx)| **idx <= pos.start)
.last()
.unwrap()
.0;
let snippet = Snippet {
title: Some(Annotation {
label: Some(&err),
id: None,
annotation_type: AnnotationType::Error,
}),
footer: vec![],
slices: vec![Slice {
source: this.source(),
line_start,
origin: Some(&relative_ftl_path),
fold: true,
annotations: vec![SourceAnnotation {
label: "",
annotation_type: AnnotationType::Error,
range: (pos.start, pos.end - 1),
}],
}],
opt: Default::default(),
};
let dl = DisplayList::from(snippet);
eprintln!("{dl}\n");
}
return failed(&crate_name);
}
};
let mut constants = TokenStream::new();
let mut previous_defns = HashMap::new();
let mut message_refs = Vec::new();
for entry in resource.entries() {
if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = entry {
let _ = previous_defns.entry(name.to_string()).or_insert(resource_span);
if name.contains('-') {
Diagnostic::spanned(
resource_span,
Level::Error,
format!("name `{name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}
if let Some(Pattern { elements }) = value {
for elt in elements {
if let PatternElement::Placeable {
expression:
Expression::Inline(InlineExpression::MessageReference { id, .. }),
} = elt
{
message_refs.push((id.name, *name));
}
}
}
// `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
// `const_eval_baz` => `baz` (in `const_eval.ftl`)
// `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
// The last case we error about above, but we want to fall back gracefully
// so that only the error is being emitted and not also one about the macro
// failing.
let crate_prefix = format!("{crate_name}_");
let snake_name = name.replace('-', "_");
if !snake_name.starts_with(&crate_prefix) {
Diagnostic::spanned(
resource_span,
Level::Error,
format!("name `{name}` does not start with the crate name"),
)
.help(format!(
"prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"
))
.emit();
};
let snake_name = Ident::new(&snake_name, resource_str.span());
if !previous_attrs.insert(snake_name.clone()) {
continue;
}
let msg = format!("Constant referring to Fluent message `{name}` from `{crate_name}`");
constants.extend(quote! {
#[doc = #msg]
pub const #snake_name: crate::DiagnosticMessage =
crate::DiagnosticMessage::FluentIdentifier(
std::borrow::Cow::Borrowed(#name),
None
);
});
for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
let snake_name = Ident::new(
&format!("{}{}", &crate_prefix, &attr_name.replace('-', "_")),
resource_str.span(),
);
if !previous_attrs.insert(snake_name.clone()) {
continue;
}
if attr_name.contains('-') {
Diagnostic::spanned(
resource_span,
Level::Error,
format!("attribute `{attr_name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}
let msg = format!(
"Constant referring to Fluent message `{name}.{attr_name}` from `{crate_name}`"
);
constants.extend(quote! {
#[doc = #msg]
pub const #snake_name: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(
std::borrow::Cow::Borrowed(#attr_name)
);
});
}
}
}
for (mref, name) in message_refs.into_iter() {
if !previous_defns.contains_key(mref) {
Diagnostic::spanned(
resource_span,
Level::Error,
format!("referenced message `{mref}` does not exist (in message `{name}`)"),
)
.help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
.emit();
}
}
if let Err(errs) = bundle.add_resource(resource) {
for e in errs {
match e {
FluentError::Overriding { kind, id } => {
Diagnostic::spanned(
resource_span,
Level::Error,
format!("overrides existing {kind}: `{id}`"),
)
.emit();
}
FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(),
}
}
}
quote! {
/// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro,
/// imported by `rustc_driver` to include all crates' resources in one bundle.
pub static DEFAULT_LOCALE_RESOURCE: &'static str = include_str!(#relative_ftl_path);
#[allow(non_upper_case_globals)]
#[doc(hidden)]
/// Auto-generated constants for type-checked references to Fluent messages.
pub(crate) mod fluent_generated {
#constants
/// Constants expected to exist by the diagnostic derive macros to use as default Fluent
/// identifiers for different subdiagnostic kinds.
pub mod _subdiag {
/// Default for `#[help]`
pub const help: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
/// Default for `#[note]`
pub const note: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
/// Default for `#[warn]`
pub const warn: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
/// Default for `#[label]`
pub const label: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
/// Default for `#[suggestion]`
pub const suggestion: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
}
}
}
.into()
}

View File

@ -512,7 +512,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
let mut calls = TokenStream::new();
for (kind, slug) in kind_slugs {
let message = format_ident!("__message");
calls.extend(quote! { let #message = #f(#diag, rustc_errors::fluent::#slug.into()); });
calls.extend(
quote! { let #message = #f(#diag, crate::fluent_generated::#slug.into()); },
);
let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
let call = match kind {

View File

@ -61,9 +61,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// For example, given the following invocation of the macro..
///
/// ```ignore (rust)
/// fluent_messages! {
/// typeck => "./typeck.ftl",
/// }
/// fluent_messages! { "./typeck.ftl" }
/// ```
/// ..where `typeck.ftl` has the following contents..
///
@ -77,9 +75,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// will generate the following code:
///
/// ```ignore (rust)
/// pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
/// include_str!("./typeck.ftl"),
/// ];
/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl");
///
/// mod fluent_generated {
/// mod typeck {

View File

@ -9,6 +9,7 @@ use rustc_session::config;
use rustc_span::{sym, Span, Symbol};
use rustc_target::spec::{PanicStrategy, TargetTriple};
use crate::fluent_generated as fluent;
use crate::locator::CrateFlavor;
#[derive(Diagnostic)]
@ -491,7 +492,7 @@ impl IntoDiagnostic<'_> for MultipleCandidates {
self,
handler: &'_ rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(rustc_errors::fluent::metadata_multiple_candidates);
let mut diag = handler.struct_err(fluent::metadata_multiple_candidates);
diag.set_arg("crate_name", self.crate_name);
diag.set_arg("flavor", self.flavor);
diag.code(error_code!(E0464));
@ -590,7 +591,7 @@ impl IntoDiagnostic<'_> for InvalidMetadataFiles {
self,
handler: &'_ rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(rustc_errors::fluent::metadata_invalid_meta_files);
let mut diag = handler.struct_err(fluent::metadata_invalid_meta_files);
diag.set_arg("crate_name", self.crate_name);
diag.set_arg("add_info", self.add_info);
diag.code(error_code!(E0786));
@ -619,7 +620,7 @@ impl IntoDiagnostic<'_> for CannotFindCrate {
self,
handler: &'_ rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(rustc_errors::fluent::metadata_cannot_find_crate);
let mut diag = handler.struct_err(fluent::metadata_cannot_find_crate);
diag.set_arg("crate_name", self.crate_name);
diag.set_arg("current_crate", self.current_crate);
diag.set_arg("add_info", self.add_info);
@ -630,32 +631,32 @@ impl IntoDiagnostic<'_> for CannotFindCrate {
&& self.locator_triple != TargetTriple::from_triple(config::host_triple())
{
if self.missing_core {
diag.note(rustc_errors::fluent::metadata_target_not_installed);
diag.note(fluent::metadata_target_not_installed);
} else {
diag.note(rustc_errors::fluent::metadata_target_no_std_support);
diag.note(fluent::metadata_target_no_std_support);
}
// NOTE: this suggests using rustup, even though the user may not have it installed.
// That's because they could choose to install it; or this may give them a hint which
// target they need to install from their distro.
if self.missing_core {
diag.help(rustc_errors::fluent::metadata_consider_downloading_target);
diag.help(fluent::metadata_consider_downloading_target);
}
// Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
// NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
// If it's not a dummy, that means someone added `extern crate std` explicitly and
// `#![no_std]` won't help.
if !self.missing_core && self.span.is_dummy() {
diag.note(rustc_errors::fluent::metadata_std_required);
diag.note(fluent::metadata_std_required);
}
if self.is_nightly_build {
diag.help(rustc_errors::fluent::metadata_consider_building_std);
diag.help(fluent::metadata_consider_building_std);
}
} else if self.crate_name == self.profiler_runtime {
diag.note(rustc_errors::fluent::metadata_compiler_missing_profiler);
diag.note(fluent::metadata_compiler_missing_profiler);
} else if self.crate_name.as_str().starts_with("rustc_") {
diag.help(rustc_errors::fluent::metadata_install_missing_components);
diag.help(fluent::metadata_install_missing_components);
}
diag.span_label(self.span, rustc_errors::fluent::metadata_cant_find_crate);
diag.span_label(self.span, fluent::metadata_cant_find_crate);
diag
}
}

View File

@ -30,6 +30,8 @@ extern crate rustc_data_structures;
extern crate tracing;
pub use rmeta::{provide, provide_extern};
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
mod dependency_format;
mod foreign_modules;
@ -44,3 +46,5 @@ pub mod locator;
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
pub use native_libs::find_native_static_library;
pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -73,6 +73,9 @@ extern crate tracing;
#[macro_use]
extern crate smallvec;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
#[cfg(test)]
mod tests;
@ -105,3 +108,5 @@ pub mod util {
// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
fluent_messages! { "../locales/en-US.ftl" }

View File

@ -612,3 +612,11 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
c.try_super_fold_with(self)
}
}
#[derive(Diagnostic)]
#[diag(middle_const_not_used_in_type_alias)]
pub(super) struct ConstNotUsedTraitAlias {
pub ct: String,
#[primary_span]
pub span: Span,
}

View File

@ -1,3 +1,4 @@
use crate::fluent_generated as fluent;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitable};
@ -182,16 +183,16 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> {
match self {
LayoutError::Unknown(ty) => {
diag.set_arg("ty", ty);
diag.set_primary_message(rustc_errors::fluent::middle_unknown_layout);
diag.set_primary_message(fluent::middle_unknown_layout);
}
LayoutError::SizeOverflow(ty) => {
diag.set_arg("ty", ty);
diag.set_primary_message(rustc_errors::fluent::middle_values_too_big);
diag.set_primary_message(fluent::middle_values_too_big);
}
LayoutError::NormalizationFailure(ty, e) => {
diag.set_arg("ty", ty);
diag.set_arg("failure_ty", e.get_type_for_failure());
diag.set_primary_message(rustc_errors::fluent::middle_cannot_be_normalized);
diag.set_primary_message(fluent::middle_cannot_be_normalized);
}
}
diag

View File

@ -1,9 +1,10 @@
use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
use crate::thir::pattern::MatchCheckCtxt;
use rustc_errors::Handler;
use crate::{
fluent_generated as fluent,
thir::pattern::{deconstruct_pat::DeconstructedPat, MatchCheckCtxt},
};
use rustc_errors::{
error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
};
use rustc_hir::def::Res;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@ -358,7 +359,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_span_err_with_code(
self.span,
rustc_errors::fluent::mir_build_non_exhaustive_patterns_type_not_empty,
fluent::mir_build_non_exhaustive_patterns_type_not_empty,
error_code!(E0004),
);
@ -380,7 +381,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
let mut span: MultiSpan = def_span.into();
span.push_span_label(def_span, "");
diag.span_note(span, rustc_errors::fluent::def_note);
diag.span_note(span, fluent::mir_build_def_note);
}
let is_variant_list_non_exhaustive = match self.ty.kind() {
@ -391,14 +392,14 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
};
if is_variant_list_non_exhaustive {
diag.note(rustc_errors::fluent::non_exhaustive_type_note);
diag.note(fluent::mir_build_non_exhaustive_type_note);
} else {
diag.note(rustc_errors::fluent::type_note);
diag.note(fluent::mir_build_type_note);
}
if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) {
diag.note(rustc_errors::fluent::reference_note);
diag.note(fluent::mir_build_reference_note);
}
}
@ -424,12 +425,12 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
if let Some((span, sugg)) = suggestion {
diag.span_suggestion_verbose(
span,
rustc_errors::fluent::suggestion,
fluent::mir_build_suggestion,
sugg,
Applicability::HasPlaceholders,
);
} else {
diag.help(rustc_errors::fluent::help);
diag.help(fluent::mir_build_help);
}
diag
@ -469,7 +470,7 @@ pub struct NonConstPath {
pub struct UnreachablePattern {
#[label]
pub span: Option<Span>,
#[label(catchall_label)]
#[label(mir_build_catchall_label)]
pub catchall: Option<Span>,
}
@ -493,7 +494,7 @@ pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
#[primary_span]
#[label]
pub span: Span,
#[note(teach_note)]
#[note(mir_build_teach_note)]
pub teach: Option<()>,
}
@ -585,9 +586,9 @@ pub struct BorrowOfMovedValue<'tcx> {
#[primary_span]
pub span: Span,
#[label]
#[label(occurs_because_label)]
#[label(mir_build_occurs_because_label)]
pub binding_span: Span,
#[label(value_borrowed_label)]
#[label(mir_build_value_borrowed_label)]
pub conflicts_ref: Vec<Span>,
pub name: Ident,
pub ty: Ty<'tcx>,
@ -708,7 +709,7 @@ pub struct NontrivialStructuralMatch<'tcx> {
#[diag(mir_build_overlapping_range_endpoints)]
#[note]
pub struct OverlappingRangeEndpoints<'tcx> {
#[label(range)]
#[label(mir_build_range)]
pub range: Span,
#[subdiagnostic]
pub overlap: Vec<Overlap<'tcx>>,
@ -788,7 +789,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
pub interpreted_as_const: Option<InterpretedAsConst>,
#[subdiagnostic]
pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
#[note(pattern_ty)]
#[note(mir_build_pattern_ty)]
pub _p: (),
pub pattern_ty: Ty<'tcx>,
#[subdiagnostic]
@ -823,10 +824,10 @@ impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
let mut spans = MultiSpan::from(self.adt_def_span);
for Variant { span } in self.variants {
spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
spans.push_span_label(span, fluent::mir_build_variant_defined_here);
}
diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
diag.span_note(spans, fluent::mir_build_adt_defined_here);
}
}

View File

@ -25,6 +25,11 @@ pub mod thir;
use rustc_middle::ty::query::Providers;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
fluent_messages! { "../locales/en-US.ftl" }
pub fn provide(providers: &mut Providers) {
providers.check_match = thir::pattern::check_match;
providers.lit_to_const = thir::constant::lit_to_const;

View File

@ -16,7 +16,9 @@ extern crate tracing;
extern crate rustc_middle;
use rustc_ast::MetaItem;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir::def_id::DefId;
use rustc_macros::fluent_messages;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
@ -44,6 +46,8 @@ pub mod storage;
pub mod un_derefer;
pub mod value_analysis;
fluent_messages! { "../locales/en-US.ftl" }
pub(crate) mod indexes {
pub(crate) use super::move_paths::MovePathIndex;
}

View File

@ -1,5 +1,6 @@
use std::path::PathBuf;
use crate::fluent_generated as fluent;
use rustc_errors::ErrorGuaranteed;
use rustc_errors::IntoDiagnostic;
use rustc_macros::{Diagnostic, LintDiagnostic};
@ -44,7 +45,7 @@ impl IntoDiagnostic<'_> for UnusedGenericParamsHint {
self,
handler: &'_ rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(rustc_errors::fluent::monomorphize_unused_generic_params);
let mut diag = handler.struct_err(fluent::monomorphize_unused_generic_params);
diag.set_span(self.span);
for (span, name) in self.param_spans.into_iter().zip(self.param_names) {
// FIXME: I can figure out how to do a label with a fluent string with a fixed message,

View File

@ -9,7 +9,9 @@ extern crate tracing;
#[macro_use]
extern crate rustc_middle;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir::lang_items::LangItem;
use rustc_macros::fluent_messages;
use rustc_middle::traits;
use rustc_middle::ty::adjustment::CustomCoerceUnsized;
use rustc_middle::ty::query::{Providers, TyCtxtAt};
@ -21,6 +23,8 @@ mod partitioning;
mod polymorphize;
mod util;
fluent_messages! { "../locales/en-US.ftl" }
fn custom_coerce_unsize_info<'tcx>(
tcx: TyCtxtAt<'tcx>,
source_ty: Ty<'tcx>,

View File

@ -93,6 +93,26 @@ parse_do_catch_syntax_removed = found removed `do catch` syntax
parse_float_literal_requires_integer_part = float literals must have an integer part
.suggestion = must have an integer part
parse_invalid_int_literal_width = invalid width `{$width}` for integer literal
.help = valid widths are 8, 16, 32, 64 and 128
parse_invalid_num_literal_base_prefix = invalid base prefix for number literal
.note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
.suggestion = try making the prefix lowercase
parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal
.label = invalid suffix `{$suffix}`
.help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
parse_invalid_float_literal_width = invalid width `{$width}` for float literal
.help = valid widths are 32 and 64
parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
.label = invalid suffix `{$suffix}`
.help = valid suffixes are `f32` and `f64`
parse_int_literal_too_large = integer literal is too large
parse_missing_semicolon_before_array = expected `;`, found `[`
.suggestion = consider adding `;` here
@ -219,6 +239,14 @@ parse_struct_literal_not_allowed_here = struct literals are not allowed here
parse_invalid_interpolated_expression = invalid interpolated expression
parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
parse_octal_float_literal_not_supported = octal float literal is not supported
parse_binary_float_literal_not_supported = binary float literal is not supported
parse_not_supported = not supported
parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid
.label = invalid suffix `{$suffix}`
parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
.label = invalid suffix `{$suffix}`
.tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases

View File

@ -2,13 +2,14 @@ use std::borrow::Cow;
use rustc_ast::token::Token;
use rustc_ast::{Path, Visibility};
use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
use rustc_errors::{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};
use crate::fluent_generated as fluent;
use crate::parser::TokenDescription;
#[derive(Diagnostic)]
@ -78,7 +79,7 @@ pub(crate) struct IncorrectSemicolon<'a> {
#[diag(parse_incorrect_use_of_await)]
pub(crate) struct IncorrectUseOfAwait {
#[primary_span]
#[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")]
#[suggestion(parse_parentheses_suggestion, code = "", applicability = "machine-applicable")]
pub span: Span,
}
@ -87,7 +88,7 @@ pub(crate) struct IncorrectUseOfAwait {
pub(crate) struct IncorrectAwait {
#[primary_span]
pub span: Span,
#[suggestion(postfix_suggestion, code = "{expr}.await{question_mark}")]
#[suggestion(parse_postfix_suggestion, code = "{expr}.await{question_mark}")]
pub sugg_span: (Span, Applicability),
pub expr: String,
pub question_mark: &'static str,
@ -140,7 +141,7 @@ pub(crate) struct InvalidComparisonOperator {
#[derive(Subdiagnostic)]
pub(crate) enum InvalidComparisonOperatorSub {
#[suggestion(
use_instead,
parse_use_instead,
style = "short",
applicability = "machine-applicable",
code = "{correct}"
@ -151,7 +152,7 @@ pub(crate) enum InvalidComparisonOperatorSub {
invalid: String,
correct: String,
},
#[label(spaceship_operator_invalid)]
#[label(parse_spaceship_operator_invalid)]
Spaceship(#[primary_span] Span),
}
@ -169,14 +170,14 @@ pub(crate) struct InvalidLogicalOperator {
#[derive(Subdiagnostic)]
pub(crate) enum InvalidLogicalOperatorSub {
#[suggestion(
use_amp_amp_for_conjunction,
parse_use_amp_amp_for_conjunction,
style = "short",
applicability = "machine-applicable",
code = "&&"
)]
Conjunction(#[primary_span] Span),
#[suggestion(
use_pipe_pipe_for_disjunction,
parse_use_pipe_pipe_for_disjunction,
style = "short",
applicability = "machine-applicable",
code = "||"
@ -262,14 +263,14 @@ pub(crate) struct UnexpectedTokenAfterLabel {
#[primary_span]
#[label(parse_unexpected_token_after_label)]
pub span: Span,
#[suggestion(suggestion_remove_label, style = "verbose", code = "")]
#[suggestion(parse_suggestion_remove_label, style = "verbose", code = "")]
pub remove_label: Option<Span>,
#[subdiagnostic]
pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion_enclose_in_block, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion_enclose_in_block, applicability = "machine-applicable")]
pub(crate) struct UnexpectedTokenAfterLabelSugg {
#[suggestion_part(code = "{{ ")]
pub left: Span,
@ -347,9 +348,9 @@ pub(crate) struct IfExpressionMissingThenBlock {
#[derive(Subdiagnostic)]
pub(crate) enum IfExpressionMissingThenBlockSub {
#[help(condition_possibly_unfinished)]
#[help(parse_condition_possibly_unfinished)]
UnfinishedCondition(#[primary_span] Span),
#[help(add_then_block)]
#[help(parse_add_then_block)]
AddThenBlock(#[primary_span] Span),
}
@ -364,9 +365,9 @@ pub(crate) struct IfExpressionLetSomeSub {
#[diag(parse_if_expression_missing_condition)]
pub(crate) struct IfExpressionMissingCondition {
#[primary_span]
#[label(condition_label)]
#[label(parse_condition_label)]
pub if_span: Span,
#[label(block_label)]
#[label(parse_block_label)]
pub block_span: Span,
}
@ -404,10 +405,10 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse {
#[primary_span]
pub last: Span,
#[label(branch_label)]
#[label(parse_branch_label)]
pub branch_span: Span,
#[label(ctx_label)]
#[label(parse_ctx_label)]
pub ctx_span: Span,
pub ctx: String,
@ -427,9 +428,14 @@ pub(crate) struct MissingInInForLoop {
#[derive(Subdiagnostic)]
pub(crate) enum MissingInInForLoopSub {
// Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
#[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
#[suggestion(
parse_use_in_not_of,
style = "short",
applicability = "maybe-incorrect",
code = "in"
)]
InNotOf(#[primary_span] Span),
#[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
#[suggestion(parse_add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
AddIn(#[primary_span] Span),
}
@ -484,8 +490,8 @@ pub(crate) struct EqFieldInit {
#[diag(parse_dotdotdot)]
pub(crate) struct DotDotDot {
#[primary_span]
#[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
#[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
#[suggestion(parse_suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
#[suggestion(parse_suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
pub span: Span,
}
@ -525,10 +531,10 @@ pub(crate) struct UseEmptyBlockNotSemi {
#[diag(parse_comparison_interpreted_as_generic)]
pub(crate) struct ComparisonInterpretedAsGeneric {
#[primary_span]
#[label(label_comparison)]
#[label(parse_label_comparison)]
pub comparison: Span,
pub r#type: Path,
#[label(label_args)]
#[label(parse_label_args)]
pub args: Span,
#[subdiagnostic]
pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
@ -538,17 +544,17 @@ pub(crate) struct ComparisonInterpretedAsGeneric {
#[diag(parse_shift_interpreted_as_generic)]
pub(crate) struct ShiftInterpretedAsGeneric {
#[primary_span]
#[label(label_comparison)]
#[label(parse_label_comparison)]
pub shift: Span,
pub r#type: Path,
#[label(label_args)]
#[label(parse_label_args)]
pub args: Span,
#[subdiagnostic]
pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
#[suggestion_part(code = "(")]
pub left: Span,
@ -574,7 +580,7 @@ pub(crate) struct LeadingPlusNotSupported {
#[label]
pub span: Span,
#[suggestion(
suggestion_remove_plus,
parse_suggestion_remove_plus,
style = "verbose",
code = "",
applicability = "machine-applicable"
@ -597,7 +603,7 @@ pub(crate) struct ParenthesesWithStructFields {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
#[multipart_suggestion(parse_suggestion_braces_for_struct, applicability = "maybe-incorrect")]
pub(crate) struct BracesForStructLiteral {
#[suggestion_part(code = " {{ ")]
pub first: Span,
@ -606,7 +612,7 @@ pub(crate) struct BracesForStructLiteral {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
#[multipart_suggestion(parse_suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
pub(crate) struct NoFieldsForFnCall {
#[suggestion_part(code = "")]
pub fields: Vec<Span>,
@ -643,7 +649,7 @@ pub(crate) struct ArrayBracketsInsteadOfSpaces {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
#[suggestion_part(code = "[")]
pub left: Span,
@ -655,9 +661,9 @@ pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
#[diag(parse_match_arm_body_without_braces)]
pub(crate) struct MatchArmBodyWithoutBraces {
#[primary_span]
#[label(label_statements)]
#[label(parse_label_statements)]
pub statements: Span,
#[label(label_arrow)]
#[label(parse_label_arrow)]
pub arrow: Span,
pub num_statements: usize,
#[subdiagnostic]
@ -670,7 +676,7 @@ pub(crate) struct MatchArmBodyWithoutBraces {
pub(crate) struct InclusiveRangeExtraEquals {
#[primary_span]
#[suggestion(
suggestion_remove_eq,
parse_suggestion_remove_eq,
style = "short",
code = "..=",
applicability = "maybe-incorrect"
@ -695,7 +701,7 @@ pub(crate) struct InclusiveRangeMatchArrow {
pub(crate) struct InclusiveRangeNoEnd {
#[primary_span]
#[suggestion(
suggestion_open_range,
parse_suggestion_open_range,
code = "..",
applicability = "machine-applicable",
style = "short"
@ -705,7 +711,7 @@ pub(crate) struct InclusiveRangeNoEnd {
#[derive(Subdiagnostic)]
pub(crate) enum MatchArmBodyWithoutBracesSugg {
#[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion_add_braces, applicability = "machine-applicable")]
AddBraces {
#[suggestion_part(code = "{{ ")]
left: Span,
@ -713,7 +719,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg {
right: Span,
},
#[suggestion(
suggestion_use_comma_not_semicolon,
parse_suggestion_use_comma_not_semicolon,
code = ",",
applicability = "machine-applicable"
)]
@ -733,7 +739,7 @@ pub(crate) struct StructLiteralNotAllowedHere {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct StructLiteralNotAllowedHereSugg {
#[suggestion_part(code = "(")]
pub left: Span,
@ -755,9 +761,9 @@ pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
#[label]
pub span: Span,
pub suffix: Symbol,
#[help(tuple_exception_line_1)]
#[help(tuple_exception_line_2)]
#[help(tuple_exception_line_3)]
#[help(parse_tuple_exception_line_1)]
#[help(parse_tuple_exception_line_2)]
#[help(parse_tuple_exception_line_3)]
pub exception: Option<()>,
}
@ -775,11 +781,11 @@ pub(crate) struct MismatchedClosingDelimiter {
#[primary_span]
pub spans: Vec<Span>,
pub delimiter: String,
#[label(label_unmatched)]
#[label(parse_label_unmatched)]
pub unmatched: Span,
#[label(label_opening_candidate)]
#[label(parse_label_opening_candidate)]
pub opening_candidate: Option<Span>,
#[label(label_unclosed)]
#[label(parse_label_unclosed)]
pub unclosed: Option<Span>,
}
@ -930,7 +936,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
self,
handler: &'a rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'a, G> {
let token_descr = super::parser::TokenDescription::from_token(&self.token);
let token_descr = TokenDescription::from_token(&self.token);
let mut diag = handler.struct_diagnostic(match token_descr {
Some(TokenDescription::ReservedIdentifier) => {
@ -976,7 +982,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
self,
handler: &'a rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'a, G> {
let token_descr = super::parser::TokenDescription::from_token(&self.token);
let token_descr = TokenDescription::from_token(&self.token);
let mut diag = handler.struct_diagnostic(match token_descr {
Some(TokenDescription::ReservedIdentifier) => {
@ -1025,7 +1031,7 @@ pub(crate) struct StructLiteralBodyWithoutPath {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "has-placeholders")]
#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")]
pub(crate) struct StructLiteralBodyWithoutPathSugg {
#[suggestion_part(code = "{{ SomeStruct ")]
pub before: Span,
@ -1043,7 +1049,7 @@ pub(crate) struct StructLiteralNeedingParens {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct StructLiteralNeedingParensSugg {
#[suggestion_part(code = "(")]
pub before: Span,
@ -1070,7 +1076,7 @@ pub(crate) struct GenericParamsWithoutAngleBrackets {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
#[suggestion_part(code = "<")]
pub left: Span,
@ -1091,7 +1097,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained {
)]
pub suggest_turbofish: Option<Span>,
#[help(parse_sugg_turbofish_syntax)]
#[help(sugg_parentheses_for_function_args)]
#[help(parse_sugg_parentheses_for_function_args)]
pub help_turbofish: Option<()>,
#[subdiagnostic]
pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
@ -1100,7 +1106,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained {
#[derive(Subdiagnostic)]
pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
#[suggestion(
sugg_split_comparison,
parse_sugg_split_comparison,
style = "verbose",
code = " && {middle_term}",
applicability = "maybe-incorrect"
@ -1110,7 +1116,7 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
span: Span,
middle_term: String,
},
#[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
#[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")]
Parenthesize {
#[suggestion_part(code = "(")]
left: Span,
@ -1130,7 +1136,7 @@ pub(crate) struct QuestionMarkInType {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct QuestionMarkInTypeSugg {
#[suggestion_part(code = "Option<")]
pub left: Span,
@ -1148,7 +1154,7 @@ pub(crate) struct ParenthesesInForHead {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct ParenthesesInForHeadSugg {
#[suggestion_part(code = "{left_snippet}")]
pub left: Span,
@ -1208,7 +1214,7 @@ pub(crate) struct ConstGenericWithoutBraces {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct ConstGenericWithoutBracesSugg {
#[suggestion_part(code = "{{ ")]
pub left: Span,
@ -1228,7 +1234,7 @@ pub(crate) struct UnexpectedConstParamDeclaration {
#[derive(Subdiagnostic)]
pub(crate) enum UnexpectedConstParamDeclarationSugg {
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
AddParam {
#[suggestion_part(code = "<{snippet}>")]
impl_generics: Span,
@ -1237,7 +1243,7 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg {
snippet: String,
ident: String,
},
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
AppendParam {
#[suggestion_part(code = ", {snippet}")]
impl_generics_end: Span,
@ -1284,7 +1290,7 @@ pub(crate) struct FnPtrWithGenerics {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct FnPtrWithGenericsSugg {
#[suggestion_part(code = "{snippet}")]
pub left: Span,
@ -1325,16 +1331,16 @@ pub(crate) struct WhereClauseBeforeTupleStructBody {
#[primary_span]
#[label]
pub span: Span,
#[label(name_label)]
#[label(parse_name_label)]
pub name: Span,
#[label(body_label)]
#[label(parse_body_label)]
pub body: Span,
#[subdiagnostic]
pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
#[suggestion_part(code = "{snippet}")]
pub left: Span,
@ -1429,13 +1435,13 @@ pub(crate) enum MissingKeywordForItemDefinition {
#[derive(Subdiagnostic)]
pub(crate) enum AmbiguousMissingKwForItemSub {
#[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
#[suggestion(parse_suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
SuggestMacro {
#[primary_span]
span: Span,
snippet: String,
},
#[help(help)]
#[help(parse_help)]
HelpMacro,
}
@ -1443,9 +1449,9 @@ pub(crate) enum AmbiguousMissingKwForItemSub {
#[diag(parse_missing_trait_in_trait_impl)]
pub(crate) struct MissingTraitInTraitImpl {
#[primary_span]
#[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
#[suggestion(parse_suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
pub span: Span,
#[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
#[suggestion(parse_suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
pub for_span: Span,
}
@ -1505,7 +1511,7 @@ pub(crate) struct ExternCrateNameWithDashes {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
pub(crate) struct ExternCrateNameWithDashesSugg {
#[suggestion_part(code = "_")]
pub dashes: Vec<Span>,
@ -1726,10 +1732,15 @@ pub struct UnknownPrefix<'a> {
#[derive(Subdiagnostic)]
pub enum UnknownPrefixSugg {
#[suggestion(suggestion_br, code = "br", applicability = "maybe-incorrect", style = "verbose")]
#[suggestion(
parse_suggestion_br,
code = "br",
applicability = "maybe-incorrect",
style = "verbose"
)]
UseBr(#[primary_span] Span),
#[suggestion(
suggestion_whitespace,
parse_suggestion_whitespace,
code = " ",
applicability = "maybe-incorrect",
style = "verbose"
@ -1761,7 +1772,7 @@ pub struct UnknownTokenStart {
#[derive(Subdiagnostic)]
pub enum TokenSubstitution {
#[suggestion(sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
#[suggestion(parse_sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
DirectedQuotes {
#[primary_span]
span: Span,
@ -1769,7 +1780,7 @@ pub enum TokenSubstitution {
ascii_str: &'static str,
ascii_name: &'static str,
},
#[suggestion(sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
#[suggestion(parse_sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
Other {
#[primary_span]
span: Span,
@ -1782,13 +1793,13 @@ pub enum TokenSubstitution {
}
#[derive(Subdiagnostic)]
#[note(note_repeats)]
#[note(parse_note_repeats)]
pub struct UnknownTokenRepeat {
pub repeats: usize,
}
#[derive(Subdiagnostic)]
#[help(help_null)]
#[help(parse_help_null)]
pub struct UnknownTokenNull;
#[derive(Diagnostic)]
@ -1805,7 +1816,7 @@ pub enum UnescapeError {
EscapeOnlyChar {
#[primary_span]
span: Span,
#[suggestion(escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
#[suggestion(parse_escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
char_span: Span,
escaped_sugg: String,
escaped_msg: String,
@ -1814,7 +1825,7 @@ pub enum UnescapeError {
#[diag(parse_bare_cr)]
BareCr {
#[primary_span]
#[suggestion(escape, applicability = "machine-applicable", code = "\\r")]
#[suggestion(parse_escape, applicability = "machine-applicable", code = "\\r")]
span: Span,
double_quotes: bool,
},
@ -1854,7 +1865,12 @@ pub enum UnescapeError {
#[primary_span]
#[label]
Span,
#[suggestion(terminate, code = "}}", applicability = "maybe-incorrect", style = "verbose")]
#[suggestion(
parse_terminate,
code = "}}",
applicability = "maybe-incorrect",
style = "verbose"
)]
Span,
),
#[diag(parse_no_brace_unicode_escape)]
@ -1918,20 +1934,24 @@ pub enum UnescapeError {
#[derive(Subdiagnostic)]
pub enum MoreThanOneCharSugg {
#[suggestion(consider_normalized, code = "{normalized}", applicability = "machine-applicable")]
#[suggestion(
parse_consider_normalized,
code = "{normalized}",
applicability = "machine-applicable"
)]
NormalizedForm {
#[primary_span]
span: Span,
ch: String,
normalized: String,
},
#[suggestion(remove_non, code = "{ch}", applicability = "maybe-incorrect")]
#[suggestion(parse_remove_non, code = "{ch}", applicability = "maybe-incorrect")]
RemoveNonPrinting {
#[primary_span]
span: Span,
ch: String,
},
#[suggestion(use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
#[suggestion(parse_use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
Quotes {
#[primary_span]
span: Span,
@ -1942,7 +1962,7 @@ pub enum MoreThanOneCharSugg {
#[derive(Subdiagnostic)]
pub enum MoreThanOneCharNote {
#[note(followed_by)]
#[note(parse_followed_by)]
AllCombining {
#[primary_span]
span: Span,
@ -1950,7 +1970,7 @@ pub enum MoreThanOneCharNote {
len: usize,
escaped_marks: String,
},
#[note(non_printing)]
#[note(parse_non_printing)]
NonPrinting {
#[primary_span]
span: Span,
@ -1960,13 +1980,13 @@ pub enum MoreThanOneCharNote {
#[derive(Subdiagnostic)]
pub enum NoBraceUnicodeSub {
#[suggestion(use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
#[suggestion(parse_use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
Suggestion {
#[primary_span]
span: Span,
suggestion: String,
},
#[help(format_of_unicode)]
#[help(parse_format_of_unicode)]
Help,
}
@ -2042,9 +2062,9 @@ pub(crate) struct PatternOnWrongSideOfAt {
#[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
pub whole_span: Span,
pub whole_pat: String,
#[label(label_pattern)]
#[label(parse_label_pattern)]
pub pattern: Span,
#[label(label_binding)]
#[label(parse_label_binding)]
pub binding: Span,
}
@ -2054,9 +2074,9 @@ pub(crate) struct PatternOnWrongSideOfAt {
pub(crate) struct ExpectedBindingLeftOfAt {
#[primary_span]
pub whole_span: Span,
#[label(label_lhs)]
#[label(parse_label_lhs)]
pub lhs: Span,
#[label(label_rhs)]
#[label(parse_label_rhs)]
pub rhs: Span,
}
@ -2236,7 +2256,7 @@ pub(crate) struct NegativeBoundsNotSupported {
#[derive(Subdiagnostic)]
#[suggestion(
suggestion,
parse_suggestion,
style = "tool-only",
code = "{fixed}",
applicability = "machine-applicable"

View File

@ -19,6 +19,8 @@ use rustc_ast::{AttrItem, Attribute, MetaItem};
use rustc_ast_pretty::pprust;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult};
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_macros::fluent_messages;
use rustc_session::parse::ParseSess;
use rustc_span::{FileName, SourceFile, Span};
@ -34,6 +36,8 @@ pub mod validate_attr;
mod errors;
fluent_messages! { "../locales/en-US.ftl" }
// A bunch of utility functions of the form `parse_<thing>_from_<source>`
// where <thing> includes crate, expr, item, stmt, tts, and one that
// uses a HOF to parse anything, and <source> includes file and

View File

@ -1,10 +1,11 @@
use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
use crate::fluent_generated as fluent;
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::token::{self, Delimiter, Nonterminal};
use rustc_errors::{error_code, fluent, Diagnostic, IntoDiagnostic, PResult};
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
use rustc_span::{sym, BytePos, Span};
use std::convert::TryInto;
use thin_vec::ThinVec;
@ -68,10 +69,10 @@ impl<'a> Parser<'a> {
token::CommentKind::Block => OuterAttributeType::DocBlockComment,
},
) {
err.note(fluent::note);
err.note(fluent::parse_note);
err.span_suggestion_verbose(
replacement_span,
fluent::suggestion,
fluent::parse_suggestion,
"",
rustc_errors::Applicability::MachineApplicable,
);
@ -175,10 +176,10 @@ impl<'a> Parser<'a> {
Ok(Some(item)) => {
// FIXME(#100717)
err.set_arg("item", item.kind.descr());
err.span_label(item.span, fluent::label_does_not_annotate_this);
err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
err.span_suggestion_verbose(
replacement_span,
fluent::sugg_change_inner_to_outer,
fluent::parse_sugg_change_inner_to_outer,
match attr_type {
OuterAttributeType::Attribute => "",
OuterAttributeType::DocBlockComment => "*",
@ -204,8 +205,8 @@ impl<'a> Parser<'a> {
attr_sp,
fluent::parse_inner_attr_not_permitted_after_outer_doc_comment,
);
diag.span_label(attr_sp, fluent::label_attr)
.span_label(prev_doc_comment_span, fluent::label_prev_doc_comment);
diag.span_label(attr_sp, fluent::parse_label_attr)
.span_label(prev_doc_comment_span, fluent::parse_label_prev_doc_comment);
diag
}
Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => {
@ -213,8 +214,8 @@ impl<'a> Parser<'a> {
attr_sp,
fluent::parse_inner_attr_not_permitted_after_outer_attr,
);
diag.span_label(attr_sp, fluent::label_attr)
.span_label(prev_outer_attr_sp, fluent::label_prev_attr);
diag.span_label(attr_sp, fluent::parse_label_attr)
.span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr);
diag
}
Some(InnerAttrForbiddenReason::InCodeBlock) | None => {

View File

@ -18,6 +18,7 @@ use crate::errors::{
UseEqInstead,
};
use crate::fluent_generated as fluent;
use crate::lexer::UnmatchedBrace;
use crate::parser;
use rustc_ast as ast;
@ -32,10 +33,9 @@ use rustc_ast::{
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, FatalError, Handler, MultiSpan,
PResult,
pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
};
use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident};

Some files were not shown because too many files have changed in this diff Show More