Change:
This might not be a valid request (I have to tell it what to test), but surely it shouldn't just result in such an obscure panic. Cc
you don't have dir ?
it doesn't exists until fetching the submodule
Seems like I don't have that submodule checked out; I don't work on the book so it's not needed (and I keep the checked-out submodules to a minimum to avoid having to update them all the time).
I reproduced it in local, without in and don't update submodule manually, will fail like this.
I can fix it tomorrow, feel free to work on it if you want to fix it earlier.
by the way, do you know why we use those for here?
Not particularly, I am not so familiar with the compiletest code. Probably we panic there so the compiletest runner process can handle(being able to understand compiletest was failed) that.
The fix shouldn't make any changes on the compiletest side. We just need to avoid using submodules(if doesn't exists) instead of assuming that they exist.
Yes, that's another issue, I just met it today.

Discussion:
use crate::compile; use crate::config::{Config, TargetSelection}; use crate::tool::{self, prepare_tool_cargo, SourceType, Tool}; <del> use crate::util::{symlink_dir, t, up_to_date}; </del> <ins> use crate::util::{dir_is_empty, symlink_dir, t, up_to_date}; </ins> use crate::Mode; macro_rules! submodule_helper {

let compiler = self.compiler; let target = self.target; <ins> let absolute_path = builder.src.join(&relative_path); let redirect_path = absolute_path.join("redirects"); if !absolute_path.exists() || !redirect_path.exists() || dir_is_empty(&absolute_path) || dir_is_empty(&redirect_path) { eprintln!("Please checkout submodule: {}", relative_path.display()); crate::exit!(1); } </ins> // build book builder.ensure(RustbookSrc { target, name: INTERNER.intern_str("book"), <del> src: INTERNER.intern_path(builder.src.join(&relative_path)), </del> <ins> src: INTERNER.intern_path(absolute_path.clone()), </ins> parent: Some(self), });

builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(format!("book/{}", edition)), <del> src: INTERNER.intern_path(builder.src.join(&relative_path).join(edition)), </del> <ins> src: INTERNER.intern_path(absolute_path.join(edition)), </ins> // There should only be one book that is marked as the parent for each target, so // treat the other editions as not having a parent. parent: Option::<Self>::None,

// build the redirect pages let _guard = builder.msg_doc(compiler, "book redirect pages", target); <del> for file in t!(fs::read_dir(builder.src.join(&relative_path).join("redirects"))) { </del> <ins> for file in t!(fs::read_dir(redirect_path)) { </ins> let file = t!(file); let path = file.path(); let path = path.to_str().unwrap();

use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{ <del> exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, </del> <ins> dir_is_empty, exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, </ins> }; mod bolt;

/// /// `relative_path` should be relative to the root of the git repository, not an absolute path. pub(crate) fn update_submodule(&self, relative_path: &Path) { <del> fn dir_is_empty(dir: &Path) -> bool { t!(std::fs::read_dir(dir)).next().is_none() } </del> if !self.config.submodules(&self.rust_info()) { return; }

}); if is_windows { windows } else { other } } <ins> pub fn dir_is_empty(dir: &Path) -> bool { t!(std::fs::read_dir(dir)).next().is_none() } </ins>