diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index af4f13a7..35d8fcb7 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -955,11 +955,21 @@ impl Build { } else { let output_path = if let Some(ref path) = self.output { let path = Path::new(path); - if path.is_absolute() { + let full_path = if path.is_absolute() { path.to_path_buf() } else { current_dir.join(path) - } + }; + let parent_path = full_path + .parent() + .context("Output path must have a parent")?; + let name = full_path + .file_name() + .context("Ouput path must have a filename")?; + fs::create_dir_all(parent_path).context("Failed to create output path")?; + let mut canon_path = parent_path.canonicalize().context("Invalid output path")?; + canon_path.push(name); + canon_path } else { let file_name = grammar_path .file_stem() diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index a6f10d54..11c8b673 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1098,11 +1098,11 @@ impl Loader { // Ensure the dynamic library exists before trying to load it. This can // happen in race conditions where we couldn't acquire the lock because - // another process was compiling but it still haven't finished by the + // another process was compiling but it still hasn't finished by the // time we reach this point, so the output file still doesn't exist. // - // Instead of complaining about library load failure in `load_language`, - // inform the user about the precise issue. + // Instead of allowing the `load_language` call below to fail, return a + // clearer error to the user here. if !output_path.exists() { let msg = format!( "Dynamic library `{}` not found after build attempt. \ @@ -1110,10 +1110,10 @@ impl Loader { output_path.display() ); - return Err(LoaderError::IO(IoError::new( + Err(LoaderError::IO(IoError::new( std::io::Error::new(std::io::ErrorKind::NotFound, msg), Some(output_path.as_path()), - ))); + )))?; } Self::load_language(&output_path, &language_fn_name)