Skip to content

Commit

Permalink
Rollup merge of rust-lang#135818 - jieyouxu:migrate-translation, r=co…
Browse files Browse the repository at this point in the history
…mpiler-errors

tests: Port `translation` to rmake.rs

Part of rust-lang#121876.

This PR partially supersedes rust-lang#129011 and is co-authored with `@Oneirical.`

## Summary

This PR ports `tests/run-make/translation` to rmake.rs. Notable changes from the Makefile version include:

- We now actually fail if the rustc invocations fail... The Makefile did not have `SHELL=/bin/bash -o pipefail`, so all the piped rustc invocations to grep vacuously succeeded, even if the broken ftl test case actually regressed over time and ICEs on current master.
    - That test case is converted to assert it ICEs with a FIXME backlinking to rust-lang#135817.
- The test coverage is expanded to not ignore windows. Instead, the test now uses symlink capability detection to gate test execution.
- Added some backlinks to relevant tracking issues and the initial translation infra implementation PR.

## Review advice

Best reviewed commit-by-commit.

r? compiler
  • Loading branch information
jieyouxu authored Jan 22, 2025
2 parents e9943e8 + 139c5ae commit 315ad11
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 80 deletions.
10 changes: 9 additions & 1 deletion src/tools/run-make-support/src/external_deps/rustc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ffi::{OsStr, OsString};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::str::FromStr as _;

use crate::command::Command;
use crate::env::env_var;
Expand Down Expand Up @@ -390,3 +391,10 @@ impl Rustc {
self
}
}

/// Query the sysroot path corresponding `rustc --print=sysroot`.
#[track_caller]
pub fn sysroot() -> PathBuf {
let path = rustc().print("sysroot").run().stdout_utf8();
PathBuf::from_str(path.trim()).unwrap()
}
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
run-make/jobserver-error/Makefile
run-make/split-debuginfo/Makefile
run-make/symbol-mangling-hashed/Makefile
run-make/translation/Makefile
78 changes: 0 additions & 78 deletions tests/run-make/translation/Makefile

This file was deleted.

179 changes: 179 additions & 0 deletions tests/run-make/translation/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
//! Smoke test for the rustc diagnostics translation infrastructure.
//!
//! # References
//!
//! - Current tracking issue: <https://github.com/rust-lang/rust/issues/132181>.
//! - Old tracking issue: <https://github.com/rust-lang/rust/issues/100717>
//! - Initial translation infra implementation: <https://github.com/rust-lang/rust/pull/95512>.
// This test uses symbolic links to stub out a fake sysroot to save testing time.
//@ needs-symlink

#![deny(warnings)]

use std::path::{Path, PathBuf};

use run_make_support::rustc::sysroot;
use run_make_support::{cwd, rfs, run_in_tmpdir, rustc};

fn main() {
builtin_fallback_bundle();
additional_primary_bundle();
missing_slug_prefers_fallback_bundle();
broken_primary_bundle_prefers_fallback_bundle();
locale_sysroot();
missing_sysroot();
file_sysroot();
}

/// Check that the test works normally, using the built-in fallback bundle.
fn builtin_fallback_bundle() {
rustc().input("test.rs").run_fail().assert_stderr_contains("struct literal body without path");
}

/// Check that a primary bundle can be loaded and will be preferentially used where possible.
fn additional_primary_bundle() {
rustc()
.input("test.rs")
.arg("-Ztranslate-additional-ftl=working.ftl")
.run_fail()
.assert_stderr_contains("this is a test message");
}

/// Check that a primary bundle without the desired message will use the fallback bundle.
fn missing_slug_prefers_fallback_bundle() {
rustc()
.input("test.rs")
.arg("-Ztranslate-additional-ftl=missing.ftl")
.run_fail()
.assert_stderr_contains("struct literal body without path");
}

/// Check that a primary bundle with a broken message (e.g. an interpolated variable is not
/// provided) will use the fallback bundle.
fn broken_primary_bundle_prefers_fallback_bundle() {
// FIXME(#135817): as of the rmake.rs port, the compiler actually ICEs on the additional
// `broken.ftl`, even though the original intention seems to be that it should gracefully
// failover to the fallback bundle.

rustc()
.env("RUSTC_ICE", "0") // disable ICE dump file, not needed
.input("test.rs")
.arg("-Ztranslate-additional-ftl=broken.ftl")
.run_fail()
.assert_exit_code(101);
}

#[track_caller]
fn shallow_symlink_dir_entries(src_dir: &Path, dst_dir: &Path) {
for entry in rfs::read_dir(src_dir) {
let entry = entry.unwrap();
let src_entry_path = entry.path();
let src_filename = src_entry_path.file_name().unwrap();
let meta = rfs::symlink_metadata(&src_entry_path);

if meta.is_symlink() || meta.is_file() {
rfs::symlink_file(&src_entry_path, dst_dir.join(src_filename));
} else if meta.is_dir() {
rfs::symlink_dir(&src_entry_path, dst_dir.join(src_filename));
} else {
unreachable!()
}
}
}

#[track_caller]
fn shallow_symlink_dir_entries_materialize_single_dir(
src_dir: &Path,
dst_dir: &Path,
dir_filename: &str,
) {
shallow_symlink_dir_entries(src_dir, dst_dir);

// On Windows, this would be a symlink-to-dir, so we have to remove with `remove_dir` instead.
#[cfg(windows)]
rfs::remove_dir(dst_dir.join(dir_filename));
#[cfg(not(windows))]
rfs::remove_file(dst_dir.join(dir_filename));

rfs::create_dir_all(dst_dir.join(dir_filename));
}

#[track_caller]
fn setup_fakeroot_parents() -> PathBuf {
let sysroot = sysroot();
let fakeroot = cwd().join("fakeroot");
rfs::create_dir_all(&fakeroot);
shallow_symlink_dir_entries_materialize_single_dir(&sysroot, &fakeroot, "lib");
shallow_symlink_dir_entries_materialize_single_dir(
&sysroot.join("lib"),
&fakeroot.join("lib"),
"rustlib",
);
shallow_symlink_dir_entries_materialize_single_dir(
&sysroot.join("lib").join("rustlib"),
&fakeroot.join("lib").join("rustlib"),
"src",
);
shallow_symlink_dir_entries(
&sysroot.join("lib").join("rustlib").join("src"),
&fakeroot.join("lib").join("rustlib").join("src"),
);
fakeroot
}

/// Check that a locale can be loaded from the sysroot given a language identifier by making a local
/// copy of the sysroot and adding the custom locale to it.
fn locale_sysroot() {
run_in_tmpdir(|| {
let fakeroot = setup_fakeroot_parents();

// When download-rustc is enabled, real sysroot will have a share directory. Delete the link
// to it.
let _ = std::fs::remove_file(fakeroot.join("share"));

let fake_locale_path = fakeroot.join("share").join("locale").join("zh-CN");
rfs::create_dir_all(&fake_locale_path);
rfs::symlink_file(
cwd().join("working.ftl"),
fake_locale_path.join("basic-translation.ftl"),
);

rustc()
.env("RUSTC_ICE", "0")
.input("test.rs")
.sysroot(&fakeroot)
.arg("-Ztranslate-lang=zh-CN")
.run_fail()
.assert_stderr_contains("this is a test message");
});
}

/// Check that the compiler errors out when the sysroot requested cannot be found. This test might
/// start failing if there actually exists a Klingon translation of rustc's error messages.
fn missing_sysroot() {
run_in_tmpdir(|| {
rustc()
.input("test.rs")
.arg("-Ztranslate-lang=tlh")
.run_fail()
.assert_stderr_contains("missing locale directory");
});
}

/// Check that the compiler errors out when the directory for the locale in the sysroot is actually
/// a file.
fn file_sysroot() {
run_in_tmpdir(|| {
let fakeroot = setup_fakeroot_parents();
rfs::create_dir_all(fakeroot.join("share").join("locale"));
rfs::write(fakeroot.join("share").join("locale").join("zh-CN"), b"not a dir");

rustc()
.input("test.rs")
.sysroot(&fakeroot)
.arg("-Ztranslate-lang=zh-CN")
.run_fail()
.assert_stderr_contains("is not a directory");
});
}

0 comments on commit 315ad11

Please sign in to comment.