|
| 1 | +//! Regression test for rust-lang/rust#70924. Check that if we add the `rust-src` component in |
| 2 | +//! between two incremental compiles, that the compiler doesn't ICE on the second invocation. |
| 3 | +//! |
| 4 | +//! This test uses symbolic links to save testing time. |
| 5 | +//! |
| 6 | +//! The way this test works is that, for every prefix in `root/lib/rustlib/src`, link all of prefix |
| 7 | +//! parent content, then remove the prefix, then loop on the next prefix. This way, we basically |
| 8 | +//! create a copy of the context around `root/lib/rustlib/src`, and can freely add/remove the src |
| 9 | +//! component itself. |
| 10 | +
|
| 11 | +//@ ignore-cross-compile |
| 12 | +// Reason: test needs to run. |
| 13 | + |
| 14 | +//@ needs-symlink |
| 15 | +// Reason: test needs symlink to create stub directories and files. |
| 16 | + |
| 17 | +use std::path::Path; |
| 18 | + |
| 19 | +use run_make_support::rfs::read_dir_entries; |
| 20 | +use run_make_support::{bare_rustc, path, rfs, run}; |
| 21 | + |
| 22 | +#[derive(Debug, Copy, Clone)] |
| 23 | +struct Symlink<'a, 'b> { |
| 24 | + src_dir: &'a Path, |
| 25 | + dst_dir: &'b Path, |
| 26 | +} |
| 27 | + |
| 28 | +fn shallow_symlink_dir<'a, 'b>(Symlink { src_dir, dst_dir }: Symlink<'a, 'b>) { |
| 29 | + eprintln!( |
| 30 | + "shallow_symlink_dir: src_dir={} -> dst_dir={}", |
| 31 | + src_dir.display(), |
| 32 | + dst_dir.display() |
| 33 | + ); |
| 34 | + |
| 35 | + read_dir_entries(src_dir, |src_path| { |
| 36 | + let src_metadata = rfs::symlink_metadata(src_path); |
| 37 | + let filename = src_path.file_name().unwrap(); |
| 38 | + if src_metadata.is_dir() { |
| 39 | + rfs::symlink_dir(src_path, dst_dir.join(filename)); |
| 40 | + } else if src_metadata.is_file() { |
| 41 | + rfs::symlink_file(src_path, dst_dir.join(filename)); |
| 42 | + } else if src_metadata.is_symlink() { |
| 43 | + rfs::copy_symlink(src_path, dst_dir.join(filename)); |
| 44 | + } |
| 45 | + }); |
| 46 | +} |
| 47 | + |
| 48 | +fn recreate_dir(path: &Path) { |
| 49 | + rfs::recursive_remove(path); |
| 50 | + rfs::create_dir(path); |
| 51 | +} |
| 52 | + |
| 53 | +fn main() { |
| 54 | + let sysroot = bare_rustc().print("sysroot").run().stdout_utf8(); |
| 55 | + let sysroot = sysroot.trim(); |
| 56 | + let sysroot = path(sysroot); |
| 57 | + |
| 58 | + let incr = path("incr"); |
| 59 | + |
| 60 | + let fakeroot = path("fakeroot"); |
| 61 | + rfs::create_dir(&fakeroot); |
| 62 | + |
| 63 | + shallow_symlink_dir(Symlink { src_dir: &sysroot, dst_dir: &fakeroot }); |
| 64 | + recreate_dir(&fakeroot.join("lib")); |
| 65 | + |
| 66 | + shallow_symlink_dir(Symlink { src_dir: &sysroot.join("lib"), dst_dir: &fakeroot.join("lib") }); |
| 67 | + recreate_dir(&fakeroot.join("lib").join("rustlib")); |
| 68 | + |
| 69 | + shallow_symlink_dir(Symlink { |
| 70 | + src_dir: &sysroot.join("lib").join("rustlib"), |
| 71 | + dst_dir: &fakeroot.join("lib").join("rustlib"), |
| 72 | + }); |
| 73 | + recreate_dir(&fakeroot.join("lib").join("rustlib").join("src")); |
| 74 | + |
| 75 | + shallow_symlink_dir(Symlink { |
| 76 | + src_dir: &sysroot.join("lib").join("rustlib").join("src"), |
| 77 | + dst_dir: &fakeroot.join("lib").join("rustlib").join("src"), |
| 78 | + }); |
| 79 | + |
| 80 | + rfs::recursive_remove(&fakeroot.join("lib").join("rustlib").join("src").join("rust")); |
| 81 | + |
| 82 | + let run_incr_rustc = || { |
| 83 | + bare_rustc() |
| 84 | + .sysroot(&fakeroot) |
| 85 | + .arg("-C") |
| 86 | + .arg(format!("incremental={}", incr.to_str().unwrap())) |
| 87 | + .input("main.rs") |
| 88 | + .run(); |
| 89 | + }; |
| 90 | + |
| 91 | + // Run rustc w/ incremental once... |
| 92 | + run_incr_rustc(); |
| 93 | + |
| 94 | + // NOTE: the Makefile version of this used `$SYSROOT/lib/rustlib/src/rust/src/libstd/lib.rs`, |
| 95 | + // but that actually got moved around and reorganized over the years. As of Dec 2024, the |
| 96 | + // rust-src component is more like (specific for our purposes): |
| 97 | + // |
| 98 | + // ``` |
| 99 | + // $SYSROOT/lib/rustlib/src/rust/ |
| 100 | + // library/std/src/lib.rs |
| 101 | + // src/ |
| 102 | + // ``` |
| 103 | + rfs::create_dir_all( |
| 104 | + &fakeroot |
| 105 | + .join("lib") |
| 106 | + .join("rustlib") |
| 107 | + .join("src") |
| 108 | + .join("rust") |
| 109 | + .join("library") |
| 110 | + .join("std") |
| 111 | + .join("src"), |
| 112 | + ); |
| 113 | + rfs::write( |
| 114 | + &fakeroot |
| 115 | + .join("lib") |
| 116 | + .join("rustlib") |
| 117 | + .join("src") |
| 118 | + .join("rust") |
| 119 | + .join("library") |
| 120 | + .join("std") |
| 121 | + .join("src") |
| 122 | + .join("lib.rs"), |
| 123 | + b"", |
| 124 | + ); |
| 125 | + |
| 126 | + // ... and a second time. |
| 127 | + run_incr_rustc(); |
| 128 | + |
| 129 | + // Basic sanity check that the compiled binary can run. |
| 130 | + run("main"); |
| 131 | +} |
0 commit comments