Rollup merge of #95512 - davidtwco:diagnostic-translation, r=oli-obk
diagnostics: translation infrastructure An implementation of the infrastructure required to have translatable diagnostic messages. - Introduces a `DiagnosticMessage` type which can represent both the current non-translatable messages and identifiers for [Fluent](https://projectfluent.org/). - Modifies current diagnostic API so that existing calls still work but `DiagnosticMessage`s can be provided too. - Adds support for always loading a "fallback bundle" containing the English diagnostic messages, which are used when a `DiagnosticMessage::FluentIdentifier` is used in a diagnostic being emitted. - Adds support for loading a "primary bundle" which contains the user's preferred language translation, and is used preferentially when it contains a diagnostic message being emitted. Primary bundles are loaded either from the path provided to `-Ztranslate-alternate-ftl` (for testing), or from the sysroot at `$sysroot/locale/$locale/*.ftl` given a locale with `-Ztranslate-lang` (which is parsed as a language identifier). - Adds "diagnostic args" which enable normally-interpolated variables to be made available as variables for Fluent messages to use. - Updates `#[derive(SessionDiagnostic)]` so that it can only be used for translatable diagnostics and update the handful of diagnostics which used the derive to be translatable. For example, the following diagnostic... ```rust #[derive(SessionDiagnostic)] #[error = "E0195"] pub struct LifetimesOrBoundsMismatchOnTrait { #[message = "lifetime parameters or bounds on {item_kind} `{ident}` do not match the trait declaration"] #[label = "lifetimes do not match {item_kind} in trait"] pub span: Span, #[label = "lifetimes in impl do not match this {item_kind} in trait"] pub generics_span: Option<Span>, pub item_kind: &'static str, pub ident: Ident, } ``` ...becomes... ```rust #[derive(SessionDiagnostic)] #[error(code = "E0195", slug = "typeck-lifetimes-or-bounds-mismatch-on-trait")] pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, #[label = "generics-label"] pub generics_span: Option<Span>, pub item_kind: &'static str, pub ident: Ident, } ``` ```fluent typeck-lifetimes-or-bounds-mismatch-on-trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait .generics-label = lifetimes in impl do not match this {$item_kind} in trait ``` r? `@estebank` cc `@oli-obk` `@Manishearth`
This commit is contained in:
commit
d4730244d7
101 changed files with 2916 additions and 1076 deletions
|
@ -32,10 +32,10 @@ use rustc_ast::node_id::NodeMap;
|
|||
use rustc_ast::visit::{self, Visitor};
|
||||
use rustc_ast_lowering::ResolverAstLowering;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::pluralize;
|
||||
use rustc_errors::{pluralize, MultiSpan};
|
||||
use rustc_session::lint::builtin::{MACRO_USE_EXTERN_CRATE, UNUSED_IMPORTS};
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
struct UnusedImport<'a> {
|
||||
use_tree: &'a ast::UseTree,
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_ast::{self as ast, Path};
|
|||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{
|
||||
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
use rustc_feature::BUILTIN_ATTRIBUTES;
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
|
@ -18,7 +18,7 @@ use rustc_span::hygiene::MacroKind;
|
|||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, MultiSpan, Span};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::imports::{Import, ImportKind, ImportResolver};
|
||||
|
@ -1341,7 +1341,7 @@ impl<'a> Resolver<'a> {
|
|||
let def_span = self.session.source_map().guess_head_span(binding.span);
|
||||
let mut note_span = MultiSpan::from_span(def_span);
|
||||
if !first && binding.vis.is_public() {
|
||||
note_span.push_span_label(def_span, "consider importing it directly".into());
|
||||
note_span.push_span_label(def_span, "consider importing it directly");
|
||||
}
|
||||
err.span_note(note_span, &msg);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin
|
|||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
|
||||
use rustc_hir::def::{self, PartialRes};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::metadata::ModChild;
|
||||
|
@ -23,7 +23,7 @@ use rustc_session::lint::BuiltinLintDiagnostics;
|
|||
use rustc_span::hygiene::LocalExpnId;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
use rustc_span::Span;
|
||||
|
||||
use tracing::*;
|
||||
|
||||
|
@ -739,7 +739,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||
|
||||
if let Some((_, UnresolvedImportError { note, .. })) = errors.iter().last() {
|
||||
for message in note {
|
||||
diag.note(&message);
|
||||
diag.note(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ use rustc_ast_pretty::pprust::path_segment_to_string;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{
|
||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
MultiSpan,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
|
@ -25,7 +26,7 @@ use rustc_span::edition::Edition;
|
|||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
@ -1106,7 +1107,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
.collect();
|
||||
|
||||
if non_visible_spans.len() > 0 {
|
||||
let mut m: rustc_span::MultiSpan = non_visible_spans.clone().into();
|
||||
let mut m: MultiSpan = non_visible_spans.clone().into();
|
||||
non_visible_spans
|
||||
.into_iter()
|
||||
.for_each(|s| m.push_span_label(s, "private field".to_string()));
|
||||
|
@ -1139,7 +1140,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&"use this syntax instead",
|
||||
"use this syntax instead",
|
||||
path_str.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue