diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_succinct_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_succinct_zkvm_elf.rs index db1a61c69688a..8343f4d606f22 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_succinct_zkvm_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_succinct_zkvm_elf.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { description: Some("Succinct's zero-knowledge Virtual Machine (RV32IM ISA)".into()), tier: Some(3), host_tools: Some(false), - std: None, + std: Some(true), }, pointer_width: 32, arch: "riscv32".into(), diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml index 6f43ac4809a32..883b3ea294966 100644 --- a/library/panic_abort/Cargo.toml +++ b/library/panic_abort/Cargo.toml @@ -19,3 +19,10 @@ compiler_builtins = "0.1.0" [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] libc = { version = "0.2", default-features = false } + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = [ + 'cfg(bootstrap)', + 'cfg(target_os, values("succinct-zkvm"))' +] diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index b2ad0f4ac3d04..0b5b9231b2117 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -20,7 +20,7 @@ #[cfg(target_os = "android")] mod android; -#[cfg(target_os = "zkvm")] +#[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] mod zkvm; use core::any::Any; @@ -40,7 +40,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 { unsafe { android::android_set_abort_message(_payload); } - #[cfg(target_os = "zkvm")] + #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] unsafe { zkvm::zkvm_set_abort_message(_payload); } diff --git a/library/panic_abort/src/zkvm.rs b/library/panic_abort/src/zkvm.rs index 7b1e89c6a8e63..6ae619b83e13a 100644 --- a/library/panic_abort/src/zkvm.rs +++ b/library/panic_abort/src/zkvm.rs @@ -1,8 +1,7 @@ use alloc::string::String; use core::panic::PanicPayload; -// Forward the abort message to zkVM's sys_panic. This is implemented by RISC Zero's -// platform crate which exposes system calls specifically for the zkVM. +/// Note this function works with both `zkvm` and `succinct-zkvm`. pub(crate) unsafe fn zkvm_set_abort_message(payload: &mut dyn PanicPayload) { let payload = payload.get(); let msg = match payload.downcast_ref::<&'static str>() { diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 9d9601b79a7ed..67951295fb658 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -163,4 +163,6 @@ check-cfg = [ # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg 'cfg(feature, values(any()))', + 'cfg(target_os, values("succinct-zkvm"))' ] + diff --git a/library/std/build.rs b/library/std/build.rs index a0cfbc4685ee5..2693143e01e0d 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -60,9 +60,9 @@ fn main() { || target_os == "uefi" || target_os == "teeos" || target_os == "zkvm" + || target_os == "succinct-zkvm" || target_os == "rtems" || target_os == "nuttx" - // See src/bootstrap/src/core/build_steps/synthetic_targets.rs || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() { diff --git a/library/std/src/random.rs b/library/std/src/random.rs index 45f51dd37b041..a9905e3a79649 100644 --- a/library/std/src/random.rs +++ b/library/std/src/random.rs @@ -48,6 +48,7 @@ use crate::sys::random as sys; /// VxWorks | `randABytes` after waiting for `randSecure` to become ready /// WASI | [`random_get`](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-random_getbuf-pointeru8-buf_len-size---result-errno) /// ZKVM | `sys_rand` +/// SUCCINCT-ZKVM | `sys_rand` /// /// Note that the sources used might change over time. /// diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 8489e17c971d9..abd4ca5ca26cf 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -7,7 +7,7 @@ use crate::ptr; // add fast paths for low alignment values. #[allow(dead_code)] const MIN_ALIGN: usize = if cfg!(any( - all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")), + all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm", target_os = "succinct-zkvm")), all(target_arch = "xtensa", target_os = "espidf"), )) { // The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment. @@ -89,7 +89,7 @@ cfg_if::cfg_if! { mod wasm; } else if #[cfg(target_os = "xous")] { mod xous; - } else if #[cfg(target_os = "zkvm")] { + } else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] { mod zkvm; } } diff --git a/library/std/src/sys/alloc/zkvm.rs b/library/std/src/sys/alloc/zkvm.rs index a600cfa2220dd..92ebd9ae97566 100644 --- a/library/std/src/sys/alloc/zkvm.rs +++ b/library/std/src/sys/alloc/zkvm.rs @@ -1,6 +1,7 @@ use crate::alloc::{GlobalAlloc, Layout, System}; use crate::sys::pal::abi; +/// Note this allocator works with both `zkvm` and `succinct-zkvm`. #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index fbefc62ac88eb..b2e4775e02869 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -64,6 +64,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "zkvm")] { mod zkvm; pub use self::zkvm::*; + } else if #[cfg(target_os = "succinct-zkvm")] { + mod succinct_zkvm; + pub use self::succinct_zkvm::*; } else { mod unsupported; pub use self::unsupported::*; diff --git a/library/std/src/sys/pal/succint-zkvm/abi.rs b/library/std/src/sys/pal/succint-zkvm/abi.rs new file mode 100644 index 0000000000000..22980bbbab61a --- /dev/null +++ b/library/std/src/sys/pal/succint-zkvm/abi.rs @@ -0,0 +1,35 @@ +//! ABI definitions for symbols exported by <_>-zkvm targets. +//! +//! Ideally, these should be the minimum viable symbols to support the std-lib. + +#![allow(dead_code)] +pub const DIGEST_WORDS: usize = 8; + +/// Standard IO file descriptors for use with sys_read and sys_write. +pub mod fileno { + pub const STDIN: u32 = 0; + pub const STDOUT: u32 = 1; + pub const STDERR: u32 = 2; +} + +unsafe extern "C" { + pub fn sys_halt(); + pub fn sys_rand(recv_buf: *mut u8, words: usize); + pub fn sys_panic(msg_ptr: *const u8, len: usize) -> !; + pub fn sys_write(fd: u32, write_buf: *const u8, nbytes: usize); + pub fn sys_getenv( + recv_buf: *mut u32, + words: usize, + varname: *const u8, + varname_len: usize, + ) -> usize; + pub fn sys_argv(out_words: *mut u32, out_nwords: usize, arg_index: usize) -> usize; + pub fn sys_alloc_aligned(nwords: usize, align: usize) -> *mut u8; +} + +// Note: sys_read is not implemented for succinct-zkvm. +// However, it is a function used in the standard library, so we need to +// implement it. +pub unsafe extern "C" fn sys_read(_: u32, _: *mut u8, _: usize) -> usize { + panic!("sys_read not implemented for succinct"); +} diff --git a/library/std/src/sys/pal/succint-zkvm/args.rs b/library/std/src/sys/pal/succint-zkvm/args.rs new file mode 100644 index 0000000000000..a23c4c6f8a8a4 --- /dev/null +++ b/library/std/src/sys/pal/succint-zkvm/args.rs @@ -0,0 +1,61 @@ +use crate::ffi::OsString; +use crate::fmt; + +pub struct Args { + i_forward: usize, + i_back: usize, + count: usize, +} + +pub fn args() -> Args { + panic!("args not implemented for succinct"); +} + +impl Args { + #[cfg(target_os = "succinct-zkvm")] + fn argv(_: usize) -> OsString { + panic!("argv not implemented for succinct"); + } +} + +impl fmt::Debug for Args { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().finish() + } +} + +impl Iterator for Args { + type Item = OsString; + + fn next(&mut self) -> Option { + if self.i_forward >= self.count - self.i_back { + None + } else { + let arg = Self::argv(self.i_forward); + self.i_forward += 1; + Some(arg) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.count, Some(self.count)) + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + self.count + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + if self.i_back >= self.count - self.i_forward { + None + } else { + let arg = Self::argv(self.count - 1 - self.i_back); + self.i_back += 1; + Some(arg) + } + } +} diff --git a/library/std/src/sys/pal/succint-zkvm/env.rs b/library/std/src/sys/pal/succint-zkvm/env.rs new file mode 100644 index 0000000000000..b85153642b1c9 --- /dev/null +++ b/library/std/src/sys/pal/succint-zkvm/env.rs @@ -0,0 +1,9 @@ +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = ""; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ".elf"; + pub const DLL_EXTENSION: &str = "elf"; + pub const EXE_SUFFIX: &str = ".elf"; + pub const EXE_EXTENSION: &str = "elf"; +} diff --git a/library/std/src/sys/pal/succint-zkvm/mod.rs b/library/std/src/sys/pal/succint-zkvm/mod.rs new file mode 100644 index 0000000000000..f282df9b38af4 --- /dev/null +++ b/library/std/src/sys/pal/succint-zkvm/mod.rs @@ -0,0 +1,53 @@ +//! System bindings for the succinct-zkvm platform +//! +//! This module contains the facade (aka platform-specific) implementations of +//! OS level functionality for succinct-zkvm. +//! +//! This is all super highly experimental and not actually intended for +//! wide/production use yet, it's still all in the experimental category. This +//! will likely change over time. +#![forbid(unsafe_op_in_unsafe_fn)] + +pub mod abi; +#[path = "../succinct-zkvm/args.rs"] +pub mod args; +pub mod env; +pub mod os; +#[path = "../unsupported/pipe.rs"] +pub mod pipe; +#[path = "../unsupported/process.rs"] +pub mod process; +#[path = "../unsupported/thread.rs"] +pub mod thread; +#[path = "../unsupported/time.rs"] +pub mod time; + +use crate::io as std_io; + +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() {} + +pub fn unsupported() -> std_io::Result { + Err(unsupported_err()) +} + +pub fn unsupported_err() -> std_io::Error { + std_io::Error::UNSUPPORTED_PLATFORM +} + +pub fn is_interrupted(_code: i32) -> bool { + false +} + +pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { + crate::io::ErrorKind::Uncategorized +} + +pub fn abort_internal() -> ! { + core::intrinsics::abort(); +} diff --git a/library/std/src/sys/pal/succint-zkvm/os.rs b/library/std/src/sys/pal/succint-zkvm/os.rs new file mode 100644 index 0000000000000..1cd71551dd750 --- /dev/null +++ b/library/std/src/sys/pal/succint-zkvm/os.rs @@ -0,0 +1,118 @@ +use super::unsupported; +use crate::error::Error as StdError; +use crate::ffi::{OsStr, OsString}; +use crate::marker::PhantomData; +use crate::path::{self, PathBuf}; +use crate::{fmt, io}; + +pub fn errno() -> i32 { + 0 +} + +pub fn error_string(_errno: i32) -> String { + "operation successful".to_string() +} + +pub fn getcwd() -> io::Result { + unsupported() +} + +pub fn chdir(_: &path::Path) -> io::Result<()> { + unsupported() +} + +pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); + +pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { + panic!("unsupported") +} + +impl<'a> Iterator for SplitPaths<'a> { + type Item = PathBuf; + fn next(&mut self) -> Option { + self.0 + } +} + +#[derive(Debug)] +pub struct JoinPathsError; + +pub fn join_paths(_paths: I) -> Result +where + I: Iterator, + T: AsRef, +{ + Err(JoinPathsError) +} + +impl fmt::Display for JoinPathsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + "not supported on this platform yet".fmt(f) + } +} + +impl StdError for JoinPathsError { + #[allow(deprecated)] + fn description(&self) -> &str { + "not supported on this platform yet" + } +} + +pub fn current_exe() -> io::Result { + unsupported() +} + +pub struct Env(!); + +impl Iterator for Env { + type Item = (OsString, OsString); + fn next(&mut self) -> Option<(OsString, OsString)> { + self.0 + } +} + +pub fn env() -> Env { + panic!("not supported on this platform") +} + +impl Env { + pub fn str_debug(&self) -> impl fmt::Debug + '_ { + let Self(inner) = self; + match *inner {} + } +} + +impl fmt::Debug for Env { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(inner) = self; + match *inner {} + } +} + +pub fn getenv(_: &OsStr) -> Option { + panic!("getenv not implemented for succinct"); +} + +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) +} + +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) +} + +pub fn temp_dir() -> PathBuf { + panic!("no filesystem on this platform") +} + +pub fn home_dir() -> Option { + None +} + +pub fn exit(_code: i32) -> ! { + crate::intrinsics::abort() +} + +pub fn getpid() -> u32 { + panic!("no pids on this platform") +} diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 870039602bcf0..236a3a89252a3 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -72,9 +72,12 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "wasi")] { mod wasi; pub use wasi::fill_bytes; - } else if #[cfg(target_os = "zkvm")] { + } else if #[cfg(any(target_os = "zkvm", target_os = "succinct-zkvm"))] { mod zkvm; pub use zkvm::fill_bytes; + } else if #[cfg(target_os = "succinct-zkvm")] { + mod succinct_zkvm; + pub use succinct_zkvm::fill_bytes; } else if #[cfg(any( all(target_family = "wasm", target_os = "unknown"), target_os = "xous", diff --git a/library/std/src/sys/random/succinct_zkvm.rs b/library/std/src/sys/random/succinct_zkvm.rs new file mode 100644 index 0000000000000..3852bd158600d --- /dev/null +++ b/library/std/src/sys/random/succinct_zkvm.rs @@ -0,0 +1,5 @@ +use crate::sys::pal::abi; + +pub fn fill_bytes(bytes: &mut [u8]) { + unsafe { abi::sys_rand(bytes.as_mut_ptr(), bytes.len()) }; +} \ No newline at end of file diff --git a/library/std/src/sys/random/zkvm.rs b/library/std/src/sys/random/zkvm.rs index 3011942f6b26b..0a6bac8d13ca6 100644 --- a/library/std/src/sys/random/zkvm.rs +++ b/library/std/src/sys/random/zkvm.rs @@ -1,5 +1,6 @@ use crate::sys::pal::abi; +#[cfg(target_vendor = "risc0")] pub fn fill_bytes(bytes: &mut [u8]) { let (pre, words, post) = unsafe { bytes.align_to_mut::() }; if !words.is_empty() { @@ -19,3 +20,8 @@ pub fn fill_bytes(bytes: &mut [u8]) { pre.copy_from_slice(&buf[..pre.len()]); post.copy_from_slice(&buf[pre.len()..pre.len() + post.len()]); } + +#[cfg(target_vendor = "succinct")] +pub fn fill_bytes(bytes: &mut [u8]) { + unsafe { abi::sys_rand(bytes.as_mut_ptr(), bytes.len()) }; +} \ No newline at end of file diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index 336d4c8527db3..774a7cf6fe6e4 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -34,6 +34,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "zkvm")] { mod zkvm; pub use zkvm::*; + } else if #[cfg(target_os = "succinct-zkvm")] { + mod succinct_zkvm; + pub use succinct_zkvm::*; } else { mod unsupported; pub use unsupported::*; diff --git a/library/std/src/sys/stdio/succinct_zkvm.rs b/library/std/src/sys/stdio/succinct_zkvm.rs new file mode 100644 index 0000000000000..f31c6c26e87cd --- /dev/null +++ b/library/std/src/sys/stdio/succinct_zkvm.rs @@ -0,0 +1,72 @@ +use crate::io::{self, BorrowedCursor}; +use crate::sys::pal::abi::{self, fileno}; + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub const fn new() -> Stdin { + Stdin + } +} + +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + Ok(unsafe { abi::sys_read(fileno::STDIN, buf.as_mut_ptr(), buf.len()) }) + } + + fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { + unsafe { + let n = abi::sys_read(fileno::STDIN, buf.as_mut().as_mut_ptr().cast(), buf.capacity()); + buf.advance_unchecked(n); + } + Ok(()) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + unsafe { abi::sys_write(fileno::STDOUT, buf.as_ptr(), buf.len()) } + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub const fn new() -> Stderr { + Stderr + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + unsafe { abi::sys_write(fileno::STDERR, buf.as_ptr(), buf.len()) } + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; + +pub fn is_ebadf(_err: &io::Error) -> bool { + true +} + +pub fn panic_output() -> Option { + Some(Stderr::new()) +} diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 1ff13154b7b3c..ccc627e99ddb2 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -29,6 +29,7 @@ cfg_if::cfg_if! { target_os = "uefi", target_os = "zkvm", target_os = "trusty", + target_os = "succinct-zkvm", ))] { mod statik; pub use statik::{EagerStorage, LazyStorage, thread_local_inner}; @@ -93,6 +94,7 @@ pub(crate) mod guard { target_os = "uefi", target_os = "zkvm", target_os = "trusty", + target_os = "succinct-zkvm", ))] { pub(crate) fn enable() { // FIXME: Right now there is no concept of "thread exit" on diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 2a32a7dd76eed..74787910bf71a 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -12,3 +12,9 @@ core = { path = "../core", public = true } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] libc = { version = "0.2.150", default-features = false } + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = [ + 'cfg(target_os, values("succinct-zkvm"))' +] \ No newline at end of file diff --git a/library/test/src/console.rs b/library/test/src/console.rs index 8f29f1dada528..f75f677740522 100644 --- a/library/test/src/console.rs +++ b/library/test/src/console.rs @@ -317,7 +317,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu // - It's currently not supported for wasm targets without Emscripten nor WASI. // - It's currently not supported for zkvm targets. let is_instant_unsupported = - (cfg!(target_family = "wasm") && cfg!(target_os = "unknown")) || cfg!(target_os = "zkvm"); + (cfg!(target_family = "wasm") && cfg!(target_os = "unknown")) || cfg!(target_os = "zkvm") || cfg!(target_os = "succinct-zkvm"); let start_time = (!is_instant_unsupported).then(Instant::now); run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 7ada3f269a002..03a69cea46f4e 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -555,7 +555,7 @@ pub fn run_test( // Emscripten can catch panics but other wasm targets cannot let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No - && (cfg!(target_family = "wasm") || cfg!(target_os = "zkvm")) + && (cfg!(target_family = "wasm") || cfg!(target_os = "zkvm") || cfg!(target_os = "succinct-zkvm")) && !cfg!(target_os = "emscripten"); if force_ignore || desc.ignore || ignore_because_no_process_support { @@ -604,7 +604,9 @@ pub fn run_test( // level. let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm") - && !cfg!(target_os = "zkvm"); + && !cfg!(target_os = "zkvm") + && !cfg!(target_os = "succinct-zkvm"); + if supports_threads { let cfg = thread::Builder::new().name(name.as_slice().to_owned()); let mut runtest = Arc::new(Mutex::new(Some(runtest))); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 88139b662a8d2..aadc96a794cc1 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -35,7 +35,7 @@ pub struct Finder { const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "wasm32-wali-linux-musl", - "riscv32im-succinct-zkvm-elf" + "riscv32im-succinct-zkvm-elf", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM