various: translation resources from cg backend

Extend `CodegenBackend` trait with a function returning the translation
resources from the codegen backend, which can be added to the complete
list of resources provided to the emitter.

Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
David Wood 2022-10-17 14:11:26 +01:00
parent a8e37507f4
commit 26255186e2
23 changed files with 86 additions and 48 deletions

View File

@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend {
} }
impl CodegenBackend for 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) { fn init(&self, sess: &Session) {
use rustc_session::config::Lto; use rustc_session::config::Lto;
match sess.lto() { match sess.lto() {

View File

@ -103,6 +103,10 @@ pub struct GccCodegenBackend {
} }
impl CodegenBackend for GccCodegenBackend { impl CodegenBackend for GccCodegenBackend {
fn locale_resource(&self) -> &'static str {
crate::DEFAULT_LOCALE_RESOURCE
}
fn init(&self, sess: &Session) { fn init(&self, sess: &Session) {
if sess.lto() != Lto::No { if sess.lto() != Lto::No {
sess.emit_warning(LTONotSupported {}); sess.emit_warning(LTONotSupported {});

View File

@ -249,6 +249,10 @@ impl LlvmCodegenBackend {
} }
impl CodegenBackend for LlvmCodegenBackend { impl CodegenBackend for LlvmCodegenBackend {
fn locale_resource(&self) -> &'static str {
crate::DEFAULT_LOCALE_RESOURCE
}
fn init(&self, sess: &Session) { fn init(&self, sess: &Session) {
llvm_util::init(sess); // Make sure llvm is inited llvm_util::init(sess); // Make sure llvm is inited
} }

View File

@ -57,6 +57,10 @@ impl<'tcx, T> Backend<'tcx> for T where
} }
pub trait CodegenBackend { 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 init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {} fn print(&self, _req: PrintRequest, _sess: &Session) {}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> { fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {

View File

@ -362,7 +362,7 @@ fn run_compiler(
} }
// Make sure name resolution and macro expansion is run. // Make sure name resolution and macro expansion is run.
queries.global_ctxt()?; queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(()));
if callbacks.after_expansion(compiler, queries) == Compilation::Stop { if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
return early_exit(); return early_exit();
@ -1204,7 +1204,7 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
/// hook. /// hook.
pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
let fallback_bundle = let fallback_bundle =
rustc_errors::fallback_fluent_bundle(crate::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( let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
rustc_errors::ColorConfig::Auto, rustc_errors::ColorConfig::Auto,
None, None,

View File

@ -223,7 +223,7 @@ pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBund
/// Return the default `FluentBundle` with standard "en-US" diagnostic messages. /// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
#[instrument(level = "trace")] #[instrument(level = "trace")]
pub fn fallback_fluent_bundle( pub fn fallback_fluent_bundle(
resources: &'static [&'static str], resources: Vec<&'static str>,
with_directionality_markers: bool, with_directionality_markers: bool,
) -> LazyFallbackBundle { ) -> LazyFallbackBundle {
Lrc::new(Lazy::new(move || { Lrc::new(Lazy::new(move || {

View File

@ -42,11 +42,11 @@ impl<T: Write> Write for Shared<T> {
/// Test the span yields correct positions in JSON. /// Test the span yields correct positions in JSON.
fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
static TEST_LOCALE_RESOURCES: &[&str] = &[crate::DEFAULT_LOCALE_RESOURCE];
rustc_span::create_default_session_globals_then(|| { rustc_span::create_default_session_globals_then(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned()); sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
let fallback_bundle = crate::fallback_fluent_bundle(TEST_LOCALE_RESOURCES, false); let fallback_bundle =
crate::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
let output = Arc::new(Mutex::new(Vec::new())); let output = Arc::new(Mutex::new(Vec::new()));
let je = JsonEmitter::new( let je = JsonEmitter::new(

View File

@ -17,11 +17,11 @@ use rustc_span::{BytePos, FileName, Pos, Span};
use std::path::PathBuf; use std::path::PathBuf;
static TEST_LOCALE_RESOURCES: &[&str] =
&[crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE];
fn sess() -> ParseSess { fn sess() -> ParseSess {
ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()) ParseSess::new(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty(),
)
} }
/// Parses an item. /// Parses an item.

View File

@ -34,7 +34,10 @@ where
/// Maps a string to tts, using a made-up filename. /// Maps a string to tts, using a made-up filename.
pub(crate) fn string_to_stream(source_str: String) -> TokenStream { pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
let ps = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); let ps = ParseSess::new(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty(),
);
source_file_to_stream( source_file_to_stream(
&ps, &ps,
ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str), 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. /// Parses a string, returns a crate.
pub(crate) fn string_to_crate(source_str: String) -> ast::Crate { pub(crate) fn string_to_crate(source_str: String) -> ast::Crate {
let ps = ParseSess::new(TEST_LOCALE_RESOURCES, 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()) with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod())
} }
@ -123,14 +129,14 @@ impl<T: Write> Write for Shared<T> {
} }
} }
static TEST_LOCALE_RESOURCES: &[&str] =
&[crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE];
fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) { fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
create_default_session_if_not_set_then(|_| { create_default_session_if_not_set_then(|_| {
let output = Arc::new(Mutex::new(Vec::new())); let output = Arc::new(Mutex::new(Vec::new()));
let fallback_bundle = rustc_errors::fallback_fluent_bundle(TEST_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())); 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()); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());

View File

@ -50,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
output_file: None, output_file: None,
temps_dir, 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) (sess, cfg)
} }

View File

@ -90,6 +90,9 @@ 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( let mut sess = session::build_session(
sopts, sopts,
io, io,

View File

@ -226,10 +226,7 @@ pub struct ParseSess {
impl ParseSess { impl ParseSess {
/// Used for testing. /// Used for testing.
pub fn new( pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self {
locale_resources: &'static [&'static str],
file_path_mapping: FilePathMapping,
) -> Self {
let fallback_bundle = fallback_fluent_bundle(locale_resources, false); let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
let sm = Lrc::new(SourceMap::new(file_path_mapping)); let sm = Lrc::new(SourceMap::new(file_path_mapping));
let handler = Handler::with_tty_emitter( let handler = Handler::with_tty_emitter(
@ -268,7 +265,7 @@ impl ParseSess {
} }
pub fn with_silent_emitter(fatal_note: Option<String>) -> Self { pub fn with_silent_emitter(fatal_note: Option<String>) -> Self {
let fallback_bundle = fallback_fluent_bundle(&[], false); let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let fatal_handler = let fatal_handler =
Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle); Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle);

View File

@ -1341,7 +1341,7 @@ pub fn build_session(
io: CompilerIO, io: CompilerIO,
bundle: Option<Lrc<rustc_errors::FluentBundle>>, bundle: Option<Lrc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry, registry: rustc_errors::registry::Registry,
fluent_resources: &'static [&'static str], fluent_resources: Vec<&'static str>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>, driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>, target_override: Option<Target>,
@ -1630,13 +1630,11 @@ pub enum IncrCompSession {
InvalidBecauseOfErrors { session_directory: PathBuf }, InvalidBecauseOfErrors { session_directory: PathBuf },
} }
// FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will need
// to reference every crate that might emit an early error for translation to work.
static EARLY_ERROR_LOCALE_RESOURCE: &'static [&'static str] =
&[rustc_errors::DEFAULT_LOCALE_RESOURCE];
fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler { fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
let fallback_bundle = fallback_fluent_bundle(EARLY_ERROR_LOCALE_RESOURCE, false); // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will
// need to reference every crate that might emit an early error for translation to work.
let fallback_bundle =
fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false);
let emitter: Box<dyn Emitter + sync::Send> = match output { let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(kind) => { config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip(); let (short, color_config) = kind.unzip();

View File

@ -63,7 +63,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
let snippet = source_map.span_to_snippet(span).ok()?; let snippet = source_map.span_to_snippet(span).ok()?;
// Create a Parser. // Create a Parser.
let sess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES, FilePathMapping::empty()); let sess =
ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), FilePathMapping::empty());
let file_name = source_map.span_to_filename(span); let file_name = source_map.span_to_filename(span);
let mut parser = let mut parser =
match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) { match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {

View File

@ -115,8 +115,10 @@ pub(crate) fn new_handler(
diagnostic_width: Option<usize>, diagnostic_width: Option<usize>,
unstable_opts: &UnstableOptions, unstable_opts: &UnstableOptions,
) -> rustc_errors::Handler { ) -> rustc_errors::Handler {
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
let emitter: Box<dyn Emitter + sync::Send> = match error_format { let emitter: Box<dyn Emitter + sync::Send> = match error_format {
ErrorOutputType::HumanReadable(kind) => { ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip(); let (short, color_config) = kind.unzip();

View File

@ -546,8 +546,10 @@ pub(crate) fn make_test(
// Any errors in parsing should also appear when the doctest is compiled for real, so just // Any errors in parsing should also appear when the doctest is compiled for real, so just
// send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
supports_color = EmitterWriter::stderr( supports_color = EmitterWriter::stderr(
ColorConfig::Auto, ColorConfig::Auto,
None, None,
@ -742,8 +744,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
// Any errors in parsing should also appear when the doctest is compiled for real, so just // Any errors in parsing should also appear when the doctest is compiled for real, so just
// send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
let emitter = EmitterWriter::new( let emitter = EmitterWriter::new(
Box::new(io::sink()), Box::new(io::sink()),

View File

@ -33,8 +33,10 @@ fn check_rust_syntax(
code_block: RustCodeBlock, code_block: RustCodeBlock,
) { ) {
let buffer = Lrc::new(Lock::new(Buffer::default())); let buffer = Lrc::new(Lock::new(Buffer::default()));
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));

View File

@ -704,8 +704,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
let filename = FileName::anon_source_code(&code); let filename = FileName::anon_source_code(&code);
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false
);
let emitter = EmitterWriter::new( let emitter = EmitterWriter::new(
Box::new(io::sink()), Box::new(io::sink()),
None, None,

View File

@ -209,7 +209,10 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
// Separate the output with an empty line // Separate the output with an empty line
eprintln!(); eprintln!();
let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false
);
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
rustc_errors::ColorConfig::Auto, rustc_errors::ColorConfig::Auto,
None, None,

View File

@ -123,8 +123,10 @@ fn default_handler(
let emitter = if hide_parse_errors { let emitter = if hide_parse_errors {
silent_emitter() silent_emitter()
} else { } else {
let fallback_bundle = let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
Box::new(EmitterWriter::stderr( Box::new(EmitterWriter::stderr(
color_cfg, color_cfg,
Some(source_map.clone()), Some(source_map.clone()),

View File

@ -27,6 +27,8 @@ use std::any::Any;
struct TheBackend; struct TheBackend;
impl CodegenBackend for TheBackend { impl CodegenBackend for TheBackend {
fn locale_resource(&self) -> &'static str { "" }
fn codegen_crate<'a, 'tcx>( fn codegen_crate<'a, 'tcx>(
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View File

@ -30,10 +30,11 @@ pub fn main() {
assert_eq!(gravy::foo(), 10); assert_eq!(gravy::foo(), 10);
} }
static TEST_LOCALE_RESOURCES: &[&str] = &[rustc_parse::DEFAULT_LOCALE_RESOURCE];
fn parse() { fn parse() {
let parse_session = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); let parse_session = ParseSess::new(
vec![rustc_parse::DEFAULT_LOCALE_RESOURCE],
FilePathMapping::empty()
);
let path = Path::new(file!()); let path = Path::new(file!());
let path = path.canonicalize().unwrap(); let path = path.canonicalize().unwrap();

View File

@ -219,10 +219,8 @@ fn main() {
rustc_span::create_default_session_globals_then(|| run()); rustc_span::create_default_session_globals_then(|| run());
} }
static TEST_LOCALE_RESOURCES: &[&str] = &[rustc_parse::DEFAULT_LOCALE_RESOURCE];
fn run() { fn run() {
let ps = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); let ps = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], FilePathMapping::empty());
iter_exprs(2, &mut |mut e| { iter_exprs(2, &mut |mut e| {
// If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,