|
1 | 1 | #![feature(test)] // compiletest_rs requires this attribute |
2 | 2 | #![feature(once_cell)] |
| 3 | +#![feature(try_blocks)] |
3 | 4 |
|
4 | 5 | use compiletest_rs as compiletest; |
5 | 6 | use compiletest_rs::common::Mode as TestMode; |
@@ -45,48 +46,49 @@ fn third_party_crates() -> String { |
45 | 46 | "syn", |
46 | 47 | ]; |
47 | 48 | let dep_dir = cargo::TARGET_LIB.join("deps"); |
48 | | - let mut crates: HashMap<&str, PathBuf> = HashMap::with_capacity(CRATES.len()); |
49 | | - for entry in fs::read_dir(dep_dir).unwrap() { |
50 | | - let path = match entry { |
51 | | - Ok(entry) => entry.path(), |
52 | | - Err(_) => continue, |
53 | | - }; |
54 | | - if let Some(name) = path.file_name().and_then(OsStr::to_str) { |
55 | | - for dep in CRATES { |
56 | | - if name.starts_with(&format!("lib{}-", dep)) |
57 | | - && name.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rlib")) == Some(true) |
58 | | - { |
59 | | - if let Some(old) = crates.insert(dep, path.clone()) { |
60 | | - // Check which action should be done in order to remove compiled deps. |
61 | | - // If pre-installed version of compiler is used, `cargo clean` will do. |
62 | | - // Otherwise (for bootstrapped compiler), the dependencies directory |
63 | | - // must be removed manually. |
64 | | - let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { |
65 | | - "remove the stageN-tools directory" |
66 | | - } else { |
67 | | - "run `cargo clean`" |
68 | | - }; |
69 | | - |
70 | | - panic!( |
71 | | - "\n---------------------------------------------------\n\n \ |
72 | | - Found multiple rlibs for crate `{}`: `{:?}` and `{:?}`.\n \ |
73 | | - Probably, you need to {} before running tests again.\n \ |
74 | | - \nFor details on that error see https://github.com/rust-lang/rust-clippy/issues/7343 \ |
75 | | - \n---------------------------------------------------\n", |
76 | | - dep, old, path, suggested_action |
77 | | - ); |
78 | | - } |
79 | | - break; |
80 | | - } |
81 | | - } |
| 49 | + let mut crates: HashMap<&str, Vec<PathBuf>> = HashMap::with_capacity(CRATES.len()); |
| 50 | + let mut flags = String::new(); |
| 51 | + for entry in fs::read_dir(dep_dir).unwrap().flatten() { |
| 52 | + let path = entry.path(); |
| 53 | + if let Some(name) = try { |
| 54 | + let name = path.file_name()?.to_str()?; |
| 55 | + let (name, _) = name.strip_suffix(".rlib")?.strip_prefix("lib")?.split_once('-')?; |
| 56 | + CRATES.iter().copied().find(|&c| c == name)? |
| 57 | + } { |
| 58 | + flags += &format!(" --extern {}={}", name, path.display()); |
| 59 | + crates.entry(name).or_default().push(path.clone()); |
82 | 60 | } |
83 | 61 | } |
| 62 | + crates.retain(|_, paths| paths.len() > 1); |
| 63 | + if !crates.is_empty() { |
| 64 | + let crate_names = crates.keys().map(|s| format!("`{}`", s)).collect::<Vec<_>>().join(", "); |
| 65 | + // add backslashes for an easy copy-paste `rm` command |
| 66 | + let paths = crates |
| 67 | + .into_values() |
| 68 | + .flatten() |
| 69 | + .map(|p| strip_current_dir(&p).display().to_string()) |
| 70 | + .collect::<Vec<_>>() |
| 71 | + .join(" \\\n"); |
| 72 | + // Check which action should be done in order to remove compiled deps. |
| 73 | + // If pre-installed version of compiler is used, `cargo clean` will do. |
| 74 | + // Otherwise (for bootstrapped compiler), the dependencies directory |
| 75 | + // must be removed manually. |
| 76 | + let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { |
| 77 | + "removing the stageN-tools directory" |
| 78 | + } else { |
| 79 | + "running `cargo clean`" |
| 80 | + }; |
84 | 81 |
|
85 | | - let v: Vec<_> = crates |
86 | | - .into_iter() |
87 | | - .map(|(dep, path)| format!("--extern {}={}", dep, path.display())) |
88 | | - .collect(); |
89 | | - v.join(" ") |
| 82 | + panic!( |
| 83 | + "\n----------------------------------------------------------------------\n\ |
| 84 | + ERROR: Found multiple rlibs for crates: {}\n\ |
| 85 | + Try {} or remove the following files:\n\n{}\n\n\ |
| 86 | + For details on this error see https://github.com/rust-lang/rust-clippy/issues/7343\n\ |
| 87 | + ----------------------------------------------------------------------\n", |
| 88 | + crate_names, suggested_action, paths |
| 89 | + ); |
| 90 | + } |
| 91 | + flags |
90 | 92 | } |
91 | 93 |
|
92 | 94 | fn default_config() -> compiletest::Config { |
@@ -313,3 +315,12 @@ impl Drop for VarGuard { |
313 | 315 | } |
314 | 316 | } |
315 | 317 | } |
| 318 | + |
| 319 | +fn strip_current_dir(path: &Path) -> &Path { |
| 320 | + if let Ok(curr) = env::current_dir() { |
| 321 | + if let Ok(stripped) = path.strip_prefix(curr) { |
| 322 | + return stripped; |
| 323 | + } |
| 324 | + } |
| 325 | + path |
| 326 | +} |
0 commit comments