Rust Compiler Contribution
To gain more experience in software-engineering I was playing around with the thought to contribute to open-source software. Since I started reading “Programming Rust” by O’Reilly to get started with a low-level language, I got also interested in understanding what happens under the hood when we execute or compile a program.
Therefore, I thought it might be a good idea to look into the Rust Programming language itself. Coincidentally, I found this video from Esteban Kuber, which ultimately made sure to check out the Rust compiler.
I started reading through the Rust compiler guide and followed all instructions. Everything worked out the first time till I ran the first tests.
After executing the tests on the standard library with the following command: python ./x.py test --stage 0 library/std
one test case failed.
I wondered if the reason was that I ran the tests with the stage 0
compiler but since every other test case succeeded I got skeptical and checked out the error message:
failures:
---- fs::tests::read_link stdout ----
thread 'fs::tests::read_link' panicked at 'fs::read_link(r"C:\Documents and Settings\") failed with:
The system cannot find the file specified. (os error 2)', library\std\src\fs\tests.rs:839:20
The source code of the corresponding test case looks like this:
fn read_link() {
if cfg!(windows) {
// directory symlink
assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData"));
// junction
assert_eq!(check!(fs::read_link(r"C:\Users\Default User")), Path::new(r"C:\Users\Default"));
// junction with special permissions
assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")), Path::new(r"C:\Users"));
}
let tmpdir = tmpdir();
let link = tmpdir.join("link");
if !got_symlink_permission(&tmpdir) {
return;
};
check!(symlink_file(&"foo", &link));
assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
}
From the error message it gets pretty clear that we are failing at the following line:
assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")), Path::new(r"C:\Users"));
First, I thought that there might be a problem with my Windows installation since my PC was pretty new, and I freshly installed Windows 11. I asked for help in the Rust Zulip and also their discord server but it seemed that my Windows 11 installation was correct. However, even on Zulip or on discord nobody directly knew that the problem was a bit of both, the formulation of the test case and how Windows names important folders.
Through testing, googling, and chatting with other rustaceans we could trace down the problem that if you install Windows in a foreign (non-English) language, some folders like the Documents and Settings folder will be installed with names in the corresponding installation language. It does not even matter if you change the system language to English. The Documents and Settings folder will remain in the installation language.
But since my impression was, that Rust gets more popular and therefore more people will probably start contributing to the compiler, especially people from non-English countries, the test case should eventually be changed. The test case itself works correctly, but I think before other developers have this problem as well we could eventually make a quality of life change to the test case. Therefore, I created an issue on GitHub and after exchanging with other contributors we found a solution to make this test case suitable for everyone.
To be safe, we agreed that we would always execute the whole test during CI (continuous integration), therefore we check if the environment variable CI
is set.
If the variable is not set, e.g. we execute the test locally on our machine and do not provide it, then we check if the folder Documents and Settings exists,
and if so, we execute the whole test, and otherwise we skip the following assert:
assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")), Path::new(r"C:\Users"));
In the end, the final change looks like that:
#[test]
fn read_link() {
if cfg!(windows) {
// directory symlink
assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData"));
// junction
assert_eq!(check!(fs::read_link(r"C:\Users\Default User")), Path::new(r"C:\Users\Default"));
// junction with special permissions
// Since not all localized windows versions contain the folder "Documents and Settings" in english,
// we will briefly check, if it exists and otherwise skip the test. Except during CI we will always execute the test.
if Path::new(r"C:\Documents and Settings\").exists() || env::var_os("CI").is_some() {
assert_eq!(
check!(fs::read_link(r"C:\Documents and Settings\")),
Path::new(r"C:\Users")
);
}
}
let tmpdir = tmpdir();
let link = tmpdir.join("link");
if !got_symlink_permission(&tmpdir) {
return;
};
check!(symlink_file(&"foo", &link));
assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
}
You can find the pull request here.