makepad/libs/relax/compiler/tests/fullcheck_std_gaps.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

233 lines
7.8 KiB
Rust

extern crate core;
use std::ffi::{OsStr, OsString};
use std::iter::FusedIterator;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
fn assert_exact<I: ExactSizeIterator>(iter: &I, len: usize) {
assert_eq!(iter.len(), len);
assert_eq!(iter.size_hint(), (len, Some(len)));
}
fn assert_exhausted<I: ExactSizeIterator + DoubleEndedIterator + FusedIterator>(iter: &mut I) {
assert_exact(iter, 0);
assert!(iter.next().is_none());
assert!(iter.next_back().is_none());
assert!(iter.next().is_none());
assert_exact(iter, 0);
}
#[test]
fn ascii_escape_all_bytes() {
for byte in 0u16..=255 {
let byte = byte as u8;
let expected = match byte {
b'\t' => String::from("\\t"),
b'\r' => String::from("\\r"),
b'\n' => String::from("\\n"),
b'\'' => String::from("\\'"),
b'"' => String::from("\\\""),
b'\\' => String::from("\\\\"),
0x20..=0x7e => (byte as char).to_string(),
_ => format!("\\x{:02x}", byte),
};
let escaped: std::ascii::EscapeDefault = std::ascii::escape_default(byte);
let core_escaped: core::ascii::EscapeDefault = core::ascii::escape_default(byte);
assert_exact(&escaped, expected.len());
assert_eq!(escaped.to_string(), expected);
assert_eq!(escaped.clone().collect::<Vec<u8>>(), expected.as_bytes());
assert_eq!(core_escaped.collect::<Vec<u8>>(), expected.as_bytes());
assert_eq!(format!("b'{}'", escaped), format!("b'{}'", expected));
assert_eq!(format!("{:?}", escaped), "EscapeDefault { .. }");
}
}
#[test]
fn ascii_escape_remaining_display_and_ends() {
let mut escaped = std::ascii::escape_default(0x9d);
assert_eq!(escaped.next(), Some(b'\\'));
assert_eq!(escaped.next_back(), Some(b'd'));
assert_exact(&escaped, 2);
assert_eq!(escaped.to_string(), "x9");
assert_eq!(escaped.clone().rev().collect::<Vec<u8>>(), b"9x");
assert_eq!(escaped.nth(1), Some(b'9'));
assert_exhausted(&mut escaped);
assert_eq!(escaped.to_string(), "");
let mut escaped = std::ascii::escape_default(b'\n');
assert_eq!(escaped.nth_back(usize::MAX), None);
assert_exhausted(&mut escaped);
}
#[cfg(unix)]
#[test]
fn unix_parent_id_matches_getppid() {
unsafe extern "C" {
fn getppid() -> std::os::raw::c_int;
}
let parent_id: fn() -> u32 = std::os::unix::process::parent_id;
assert_eq!(parent_id(), unsafe { getppid() as u32 });
}
#[test]
fn option_iterators() {
let mut value = Some(17);
assert_eq!(value.iter().len(), 1);
let mut iter = value.iter();
assert_exact(&iter, 1);
assert_eq!(iter.next_back(), Some(&17));
assert_exhausted(&mut iter);
let mut iter = value.iter();
assert_eq!(iter.next(), Some(&17));
assert_exhausted(&mut iter);
let mut iter = value.iter_mut();
assert_exact(&iter, 1);
*iter.next_back().unwrap() += 1;
assert_exhausted(&mut iter);
let mut iter = value.into_iter();
assert_exact(&iter, 1);
assert_eq!(iter.next_back(), Some(18));
assert_exhausted(&mut iter);
let mut empty: Option<i32> = None;
assert_exhausted(&mut empty.iter());
assert_exhausted(&mut empty.iter_mut());
assert_exhausted(&mut empty.into_iter());
}
#[test]
fn result_iterators() {
let mut value: Result<i32, ()> = Ok(21);
let mut iter = value.iter();
assert_exact(&iter, 1);
assert_eq!(iter.next_back(), Some(&21));
assert_exhausted(&mut iter);
let mut iter = value.iter_mut();
assert_exact(&iter, 1);
*iter.next_back().unwrap() += 1;
assert_exhausted(&mut iter);
let mut iter = value.into_iter();
assert_exact(&iter, 1);
assert_eq!(iter.next_back(), Some(22));
assert_exhausted(&mut iter);
let mut empty: Result<i32, ()> = Err(());
assert_exhausted(&mut empty.iter());
assert_exhausted(&mut empty.iter_mut());
assert_exhausted(&mut empty.into_iter());
}
#[test]
fn other_exact_size_iterators() {
let calls = std::cell::Cell::new(0);
let mut once = std::iter::once_with(|| {
calls.set(calls.get() + 1);
7
});
assert_exact(&once, 1);
assert_eq!(calls.get(), 0);
assert_eq!(once.next_back(), Some(7));
assert_exhausted(&mut once);
assert_eq!(calls.get(), 1);
let mut inspected = (0..3).inspect(|_| calls.set(calls.get() + 1));
assert_exact(&inspected, 3);
assert_eq!(calls.get(), 1);
assert_eq!(inspected.next(), Some(0));
assert_eq!(inspected.next_back(), Some(2));
assert_exact(&inspected, 1);
assert_eq!(inspected.next(), Some(1));
assert_exhausted(&mut inspected);
assert_eq!(calls.get(), 4);
let mut map = std::collections::BTreeMap::new();
map.insert(1, 10);
map.insert(2, 20);
let mut keys = map.clone().into_keys();
assert_exact(&keys, 2);
assert_eq!(keys.next_back(), Some(2));
assert_exact(&keys, 1);
assert_eq!(keys.next(), Some(1));
assert_exhausted(&mut keys);
let mut values = map.into_values();
assert_exact(&values, 2);
assert_eq!(values.next(), Some(10));
assert_exact(&values, 1);
assert_eq!(values.next_back(), Some(20));
assert_exhausted(&mut values);
}
fn arc_raw_roundtrip<T: ?Sized>(value: Arc<T>) -> Arc<T> {
let raw = Arc::into_raw(value.clone());
unsafe {
Arc::increment_strong_count(raw);
assert_eq!(Arc::strong_count(&value), 3);
Arc::decrement_strong_count(raw);
let restored = Arc::from_raw(raw);
assert!(Arc::ptr_eq(&value, &restored));
assert_eq!(Arc::strong_count(&restored), 2);
restored
}
}
fn rc_raw_roundtrip<T: ?Sized>(value: Rc<T>) -> Rc<T> {
let raw = Rc::into_raw(value.clone());
unsafe {
Rc::increment_strong_count(raw);
assert_eq!(Rc::strong_count(&value), 3);
Rc::decrement_strong_count(raw);
let restored = Rc::from_raw(raw);
assert!(Rc::ptr_eq(&value, &restored));
assert_eq!(Rc::strong_count(&restored), 2);
restored
}
}
fn check_shared_path(path: &Path) {
let arc = arc_raw_roundtrip(Arc::<Path>::from(path));
let rc = rc_raw_roundtrip(Rc::<Path>::from(path));
assert_eq!(&*arc, path);
assert_eq!(&*rc, path);
assert_eq!(Arc::strong_count(&arc), 1);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(&*Arc::<Path>::from(PathBuf::from(path)), path);
assert_eq!(&*Rc::<Path>::from(PathBuf::from(path)), path);
let os = path.as_os_str();
assert_eq!(&*arc_raw_roundtrip(Arc::<OsStr>::from(os)), os);
assert_eq!(&*rc_raw_roundtrip(Rc::<OsStr>::from(os)), os);
assert_eq!(&*Arc::<OsStr>::from(OsString::from(os)), os);
assert_eq!(&*Rc::<OsStr>::from(OsString::from(os)), os);
}
#[test]
fn shared_unsized_paths_and_raw_pointers() {
check_shared_path(Path::new("dir/café.txt"));
check_shared_path(Path::new(""));
assert_eq!(&*arc_raw_roundtrip(Arc::<str>::from("abc")), "abc");
assert_eq!(&*rc_raw_roundtrip(Rc::<str>::from("abc")), "abc");
assert_eq!(&*arc_raw_roundtrip(Arc::<[u8]>::from(&b"abc"[..])), b"abc");
assert_eq!(&*rc_raw_roundtrip(Rc::<[u8]>::from(&b"abc"[..])), b"abc");
}
#[cfg(unix)]
#[test]
fn shared_paths_preserve_non_utf8_bytes() {
use std::os::unix::ffi::OsStrExt;
check_shared_path(Path::new(OsStr::from_bytes(b"dir/\xff\0")));
}
#[test]
fn float_next_up_down() {
assert_eq!(1.0f32.next_down(), f32::from_bits(1.0f32.to_bits() - 1));
assert_eq!(1.0f32.next_up(), f32::from_bits(1.0f32.to_bits() + 1));
assert_eq!(0.0f32.next_up(), f32::from_bits(1));
assert_eq!(0.0f32.next_down(), -f32::from_bits(1));
assert_eq!((-1.0f64).next_up(), f64::from_bits((-1.0f64).to_bits() - 1));
assert_eq!(f64::INFINITY.next_up(), f64::INFINITY);
assert_eq!(f64::NEG_INFINITY.next_down(), f64::NEG_INFINITY);
assert!(f32::NAN.next_up().is_nan());
}