Auto merge of #135818 - jieyouxu:migrate-translation, r=compiler-errors · rust-lang/rust@4a5f1cc (original) (raw)

``

1

`+

//! Smoke test for the rustc diagnostics translation infrastructure.

`

``

2

`+

//!

`

``

3

`+

//! # References

`

``

4

`+

//!

`

``

5

`+

//! - Current tracking issue: https://github.com/rust-lang/rust/issues/132181.

`

``

6

`+

//! - Old tracking issue: https://github.com/rust-lang/rust/issues/100717

`

``

7

`+

//! - Initial translation infra implementation: https://github.com/rust-lang/rust/pull/95512.

`

``

8

+

``

9

`+

// This test uses symbolic links to stub out a fake sysroot to save testing time.

`

``

10

`+

//@ needs-symlink

`

``

11

`+

//@ needs-subprocess

`

``

12

+

``

13

`+

#![deny(warnings)]

`

``

14

+

``

15

`+

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

`

``

16

+

``

17

`+

use run_make_support::rustc::sysroot;

`

``

18

`+

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

`

``

19

+

``

20

`+

fn main() {

`

``

21

`+

builtin_fallback_bundle();

`

``

22

`+

additional_primary_bundle();

`

``

23

`+

missing_slug_prefers_fallback_bundle();

`

``

24

`+

broken_primary_bundle_prefers_fallback_bundle();

`

``

25

`+

locale_sysroot();

`

``

26

`+

missing_sysroot();

`

``

27

`+

file_sysroot();

`

``

28

`+

}

`

``

29

+

``

30

`+

/// Check that the test works normally, using the built-in fallback bundle.

`

``

31

`+

fn builtin_fallback_bundle() {

`

``

32

`+

rustc().input("test.rs").run_fail().assert_stderr_contains("struct literal body without path");

`

``

33

`+

}

`

``

34

+

``

35

`+

/// Check that a primary bundle can be loaded and will be preferentially used where possible.

`

``

36

`+

fn additional_primary_bundle() {

`

``

37

`+

rustc()

`

``

38

`+

.input("test.rs")

`

``

39

`+

.arg("-Ztranslate-additional-ftl=working.ftl")

`

``

40

`+

.run_fail()

`

``

41

`+

.assert_stderr_contains("this is a test message");

`

``

42

`+

}

`

``

43

+

``

44

`+

/// Check that a primary bundle without the desired message will use the fallback bundle.

`

``

45

`+

fn missing_slug_prefers_fallback_bundle() {

`

``

46

`+

rustc()

`

``

47

`+

.input("test.rs")

`

``

48

`+

.arg("-Ztranslate-additional-ftl=missing.ftl")

`

``

49

`+

.run_fail()

`

``

50

`+

.assert_stderr_contains("struct literal body without path");

`

``

51

`+

}

`

``

52

+

``

53

`+

/// Check that a primary bundle with a broken message (e.g. an interpolated variable is not

`

``

54

`+

/// provided) will use the fallback bundle.

`

``

55

`+

fn broken_primary_bundle_prefers_fallback_bundle() {

`

``

56

`+

// FIXME(#135817): as of the rmake.rs port, the compiler actually ICEs on the additional

`

``

57

`` +

// broken.ftl, even though the original intention seems to be that it should gracefully

``

``

58

`` +

// failover to the fallback bundle. On aarch64-apple-darwin, somehow it doesn't ICE.

``

``

59

+

``

60

`+

rustc()

`

``

61

`+

.env("RUSTC_ICE", "0") // disable ICE dump file, not needed

`

``

62

`+

.input("test.rs")

`

``

63

`+

.arg("-Ztranslate-additional-ftl=broken.ftl")

`

``

64

`+

.run_fail();

`

``

65

`+

}

`

``

66

+

``

67

`+

#[track_caller]

`

``

68

`+

fn shallow_symlink_dir_entries(src_dir: &Path, dst_dir: &Path) {

`

``

69

`+

for entry in rfs::read_dir(src_dir) {

`

``

70

`+

let entry = entry.unwrap();

`

``

71

`+

let src_entry_path = entry.path();

`

``

72

`+

let src_filename = src_entry_path.file_name().unwrap();

`

``

73

`+

let meta = rfs::symlink_metadata(&src_entry_path);

`

``

74

`+

if meta.is_symlink() || meta.is_file() {

`

``

75

`+

rfs::symlink_file(&src_entry_path, dst_dir.join(src_filename));

`

``

76

`+

} else if meta.is_dir() {

`

``

77

`+

rfs::symlink_dir(&src_entry_path, dst_dir.join(src_filename));

`

``

78

`+

} else {

`

``

79

`+

unreachable!()

`

``

80

`+

}

`

``

81

`+

}

`

``

82

`+

}

`

``

83

+

``

84

`+

#[track_caller]

`

``

85

`+

fn shallow_symlink_dir_entries_materialize_single_dir(

`

``

86

`+

src_dir: &Path,

`

``

87

`+

dst_dir: &Path,

`

``

88

`+

dir_filename: &str,

`

``

89

`+

) {

`

``

90

`+

shallow_symlink_dir_entries(src_dir, dst_dir);

`

``

91

+

``

92

`+

let dst_symlink_meta = rfs::symlink_metadata(dst_dir.join(dir_filename));

`

``

93

+

``

94

`+

if dst_symlink_meta.is_file() || dst_symlink_meta.is_dir() {

`

``

95

`+

unreachable!();

`

``

96

`+

}

`

``

97

+

``

98

`+

#[cfg(windows)]

`

``

99

`+

{

`

``

100

`+

use std::os::windows::fs::FileTypeExt as _;

`

``

101

`+

if dst_symlink_meta.file_type().is_symlink_file() {

`

``

102

`+

rfs::remove_file(dst_dir.join(dir_filename));

`

``

103

`+

} else if dst_symlink_meta.file_type().is_symlink_dir() {

`

``

104

`+

rfs::remove_dir(dst_dir.join(dir_filename));

`

``

105

`+

} else {

`

``

106

`+

unreachable!();

`

``

107

`+

}

`

``

108

`+

}

`

``

109

`+

#[cfg(not(windows))]

`

``

110

`+

{

`

``

111

`+

rfs::remove_file(dst_dir.join(dir_filename));

`

``

112

`+

}

`

``

113

+

``

114

`+

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

`

``

115

`+

}

`

``

116

+

``

117

`+

#[track_caller]

`

``

118

`+

fn setup_fakeroot_parents() -> PathBuf {

`

``

119

`+

let sysroot = sysroot();

`

``

120

`+

let fakeroot = cwd().join("fakeroot");

`

``

121

`+

rfs::create_dir_all(&fakeroot);

`

``

122

`+

shallow_symlink_dir_entries_materialize_single_dir(&sysroot, &fakeroot, "lib");

`

``

123

`+

shallow_symlink_dir_entries_materialize_single_dir(

`

``

124

`+

&sysroot.join("lib"),

`

``

125

`+

&fakeroot.join("lib"),

`

``

126

`+

"rustlib",

`

``

127

`+

);

`

``

128

`+

shallow_symlink_dir_entries_materialize_single_dir(

`

``

129

`+

&sysroot.join("lib").join("rustlib"),

`

``

130

`+

&fakeroot.join("lib").join("rustlib"),

`

``

131

`+

"src",

`

``

132

`+

);

`

``

133

`+

shallow_symlink_dir_entries(

`

``

134

`+

&sysroot.join("lib").join("rustlib").join("src"),

`

``

135

`+

&fakeroot.join("lib").join("rustlib").join("src"),

`

``

136

`+

);

`

``

137

`+

fakeroot

`

``

138

`+

}

`

``

139

+

``

140

`+

/// Check that a locale can be loaded from the sysroot given a language identifier by making a local

`

``

141

`+

/// copy of the sysroot and adding the custom locale to it.

`

``

142

`+

fn locale_sysroot() {

`

``

143

`+

run_in_tmpdir(|| {

`

``

144

`+

let fakeroot = setup_fakeroot_parents();

`

``

145

+

``

146

`+

// When download-rustc is enabled, real sysroot will have a share directory. Delete the link

`

``

147

`+

// to it.

`

``

148

`+

let _ = std::fs::remove_file(fakeroot.join("share"));

`

``

149

+

``

150

`+

let fake_locale_path = fakeroot.join("share").join("locale").join("zh-CN");

`

``

151

`+

rfs::create_dir_all(&fake_locale_path);

`

``

152

`+

rfs::symlink_file(

`

``

153

`+

cwd().join("working.ftl"),

`

``

154

`+

fake_locale_path.join("basic-translation.ftl"),

`

``

155

`+

);

`

``

156

+

``

157

`+

rustc()

`

``

158

`+

.env("RUSTC_ICE", "0")

`

``

159

`+

.input("test.rs")

`

``

160

`+

.sysroot(&fakeroot)

`

``

161

`+

.arg("-Ztranslate-lang=zh-CN")

`

``

162

`+

.run_fail()

`

``

163

`+

.assert_stderr_contains("this is a test message");

`

``

164

`+

});

`

``

165

`+

}

`

``

166

+

``

167

`+

/// Check that the compiler errors out when the sysroot requested cannot be found. This test might

`

``

168

`+

/// start failing if there actually exists a Klingon translation of rustc's error messages.

`

``

169

`+

fn missing_sysroot() {

`

``

170

`+

run_in_tmpdir(|| {

`

``

171

`+

rustc()

`

``

172

`+

.input("test.rs")

`

``

173

`+

.arg("-Ztranslate-lang=tlh")

`

``

174

`+

.run_fail()

`

``

175

`+

.assert_stderr_contains("missing locale directory");

`

``

176

`+

});

`

``

177

`+

}

`

``

178

+

``

179

`+

/// Check that the compiler errors out when the directory for the locale in the sysroot is actually

`

``

180

`+

/// a file.

`

``

181

`+

fn file_sysroot() {

`

``

182

`+

run_in_tmpdir(|| {

`

``

183

`+

let fakeroot = setup_fakeroot_parents();

`

``

184

`+

rfs::create_dir_all(fakeroot.join("share").join("locale"));

`

``

185

`+

rfs::write(fakeroot.join("share").join("locale").join("zh-CN"), b"not a dir");

`

``

186

+

``

187

`+

rustc()

`

``

188

`+

.input("test.rs")

`

``

189

`+

.sysroot(&fakeroot)

`

``

190

`+

.arg("-Ztranslate-lang=zh-CN")

`

``

191

`+

.run_fail()

`

``

192

`+

.assert_stderr_contains("is not a directory");

`

``

193

`+

});

`

``

194

`+

}

`