Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/parsers/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1849,7 +1849,12 @@ mod tests {
out.push('\n');
}

writeln!(out, "bool={:?}", Expr::get_boolean(&root, b"private")).unwrap();
writeln!(
out,
"bool={:?}",
root.get(b"private").and_then(|e| e.as_bool())
)
.unwrap();
writeln!(out, "num={:?}", root.get_number(b"count").map(|(n, _)| n)).unwrap();
writeln!(
out,
Expand Down
21 changes: 21 additions & 0 deletions src/parsers/native_test_shims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,24 @@ unsafe extern "C" fn highway_index_of_any_char(
};
t.iter().position(|c| cs.contains(c)).unwrap_or(text_len)
}

#[unsafe(no_mangle)]
unsafe extern "C" fn highway_memmem(
haystack: *const u8,
haystack_len: usize,
needle: *const u8,
needle_len: usize,
) -> *const u8 {
// SAFETY: caller contract of `bun_highway::memmem` guarantees both
// (ptr, len) pairs describe valid readable ranges.
let (h, n) = unsafe {
(
core::slice::from_raw_parts(haystack, haystack_len),
core::slice::from_raw_parts(needle, needle_len),
)
};
h.windows(n.len())
.position(|w| w == n)
// SAFETY: `i < haystack_len`, so `haystack.add(i)` stays in bounds.
.map_or(core::ptr::null(), |i| unsafe { haystack.add(i) })
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
16 changes: 8 additions & 8 deletions src/sys/file.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! `bun.sys.File` — high-level file handle.
//!
//! Owns the descriptor; closes it on Drop (skipping `Fd::INVALID` and stdio
//! so `File::stdin()`/`stdout()`/`stderr()` and default-constructed handles
//! are safe to drop). Use [`File::into_raw`] to hand the fd off,
//! [`File::borrow`] for a non-owning `&File` view of someone else's fd.
//! Owns the descriptor; closes it on Drop (skipping `Fd::INVALID` and stdio,
//! so stdio-wrapping and default-constructed handles are safe to drop). Use
//! [`File::into_raw`] to hand the fd off, [`File::borrow`] for a non-owning
//! `&File` view of someone else's fd.
//! All methods preserve OS errno via [`crate::Maybe`].
#![allow(clippy::module_inception)]

Expand Down Expand Up @@ -486,13 +486,13 @@ pub(crate) mod tests {
#[test]
fn dropping_stdio_is_safe() {
let _g = FD_TEST_LOCK.lock();
// `File::stdin()` / `stdout()` / `stderr()` wrap process-shared
// descriptors that the caller does not own. Dropping the wrapper must
// not tear down the test harness's output.
// A `File` wrapping a stdio descriptor must not close it on Drop: the
// caller does not own that fd. Dropping the wrapper must not tear down
// the test harness's output.
for _ in 0..16 {
let _ = File::stdin();
let _ = File::stdout();
let _ = File::stderr();
let _ = File::from_fd(Fd::stderr());
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
assert!(fstat(Fd::stdout()).is_ok());
}
Expand Down
50 changes: 50 additions & 0 deletions test/internal/rust-tests-compile.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Verifies that the `#[cfg(test)]` code in a fixed set of Rust crates compiles.
//
// `bun bd`, `rust:check`, and `rust:clippy` all build with the default cfg only,
// so a workspace-wide refactor that removes a symbol whose sole caller sits
// behind `#[cfg(test)]` is invisible to every other CI lane. That is exactly how
// #35002 broke `cargo test -p bun_parsers` (removed `Expr::get_boolean`) and
// `cargo test -p bun_sys` (removed `File::stderr`).
//
// This does not try to link or run the unit tests (linking needs the C/C++ dep
// archive assembled by `scripts/bench-json-rust.sh`); `cargo check --tests` is
// enough to catch the class of breakage above and is fast on a warm build tree.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
import { expect, test } from "bun:test";
import { existsSync } from "node:fs";
import { join } from "node:path";

const repo = join(import.meta.dir, "..", "..");

// Crates whose `#[cfg(test)]` modules are worth guarding here. Keep this list
// small: each entry costs a `cargo check` of its dependency closure.
const CRATES = ["bun_parsers", "bun_sys"];

const cargo = Bun.which("cargo");
// `cargo check` needs a resolvable workspace: the codegen dir from
// `bun bd` / `bun run build --configure-only`, and vendor/lolhtml (a path dep
// in the root Cargo.toml). Test-only lanes run a prebuilt binary and have
// neither; see scripts/rust-miri.ts for the same prerequisite check.
const workspaceReady =
existsSync(join(repo, "build", "debug", "codegen", "build_options.rs")) &&
existsSync(join(repo, "vendor", "lolhtml", "Cargo.toml"));

test.skipIf(!cargo || !workspaceReady)(
`cargo check --tests compiles: ${CRATES.join(", ")}`,
async () => {
await using proc = Bun.spawn({
cmd: [cargo!, "check", ...CRATES.flatMap(c => ["-p", c]), "--tests", "--keep-going", "--message-format=short"],
cwd: repo,
env: { ...process.env, CARGO_TERM_COLOR: "never" },
stdout: "ignore",
stderr: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
const errors = stderr
.split("\n")
.filter(l => /^error(\[|:)|: error[[:]/.test(l))
.join("\n");
expect(errors).toBe("");
expect(exitCode).toBe(0);
},
120_000,
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Loading