Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ edit = { path = "./crates/edit" }
lsh = { path = "./crates/lsh" }
stdext = { path = "./crates/stdext" }
unicode-gen = { path = "./crates/unicode-gen" }

[workspace.lints.clippy]
ptr_as_ptr = "warn"
3 changes: 3 additions & 0 deletions crates/edit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ features = [
[dev-dependencies]
criterion = { version = "0.8", features = ["html_reports"] }
zstd = { version = "0.13", default-features = false }

[lints]
workspace = true
4 changes: 2 additions & 2 deletions crates/edit/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::cmp::Ordering;
use std::io::{self, Read};
use std::mem::MaybeUninit;
use std::{fmt, slice};
use std::{fmt, ptr, slice};

pub const KILO: usize = 1000;
pub const MEGA: usize = 1000 * 1000;
Expand Down Expand Up @@ -59,7 +59,7 @@ impl Point {
pub const MAX: Self = Self { x: CoordType::MAX, y: CoordType::MAX };

pub fn as_array(&mut self) -> &mut [CoordType; 2] {
unsafe { &mut *(self as *mut Self as *mut [CoordType; 2]) }
unsafe { &mut *ptr::from_mut(self).cast() }
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/edit/src/icu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::cmp::Ordering;
use std::ffi::{CStr, c_char};
use std::mem::MaybeUninit;
use std::ops::Range;
use std::ptr::{null, null_mut};
use std::ptr::{self, null, null_mut};
use std::sync::OnceLock;
use std::{fmt, mem};

Expand Down Expand Up @@ -348,15 +348,15 @@ impl Text {

let ut = unsafe { &mut *ptr };
ut.p_funcs = &FUNCS;
ut.context = tb as *const TextBuffer as *mut _;
ut.context = ptr::from_ref(tb).cast_mut().cast();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lhecker e.g. this is more readable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"from_ref cast mut cast" is not as readable to me as "as text buffer as whatever", personally. It'd be great to hear the opinion of others but I doubt anyone just randomly shows up haha. (I mean people that aren't too opinionated on Rust-correctness, otherwise that'd be unfair.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being explicit when casting mutability makes the intent clearer and, in my opinion, improves readability.

In the case of .cast_mut(), this looks like a potentially suspicious operation, so I looked into this instance further. It seems the context field may be incorrectly typed, as the corresponding C definition uses const void *, while the Rust definition uses *mut c_void:

pub context: *mut c_void,

https://github.com/unicode-org/icu/blob/bbb41e0bc320e2d5515d337c0cd9e9703a1942ee/icu4c/source/common/unicode/utext.h#L1443

@xtqqczze xtqqczze Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ut.a = -1;

Ok(Self(ut))
}
}

fn text_buffer_from_utext<'a>(ut: &icu_ffi::UText) -> &'a TextBuffer {
unsafe { &*(ut.context as *const TextBuffer) }
unsafe { &*(ut.context.cast()) }
}

fn double_cache_from_utext<'a>(ut: &icu_ffi::UText) -> &'a mut DoubleCache {
Expand Down
30 changes: 15 additions & 15 deletions crates/edit/src/simd/lines_bwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ unsafe fn lines_bwd_avx2(
while end.offset_from_unsigned(beg) >= 128 {
let chunk_start = end.sub(128);

let v1 = _mm256_loadu_si256(chunk_start.add(0) as *const _);
let v2 = _mm256_loadu_si256(chunk_start.add(32) as *const _);
let v3 = _mm256_loadu_si256(chunk_start.add(64) as *const _);
let v4 = _mm256_loadu_si256(chunk_start.add(96) as *const _);
let v1 = _mm256_loadu_si256(chunk_start.add(0).cast());
let v2 = _mm256_loadu_si256(chunk_start.add(32).cast());
let v3 = _mm256_loadu_si256(chunk_start.add(64).cast());
let v4 = _mm256_loadu_si256(chunk_start.add(96).cast());

let mut sum = _mm256_setzero_si256();
sum = _mm256_sub_epi8(sum, _mm256_cmpeq_epi8(v1, lf));
Expand All @@ -142,7 +142,7 @@ unsafe fn lines_bwd_avx2(

while end.offset_from_unsigned(beg) >= 32 {
let chunk_start = end.sub(32);
let v = _mm256_loadu_si256(chunk_start as *const _);
let v = _mm256_loadu_si256(chunk_start.cast());
let c = _mm256_cmpeq_epi8(v, lf);

let ones = _mm256_and_si256(c, _mm256_set1_epi8(0x01));
Expand Down Expand Up @@ -216,10 +216,10 @@ unsafe fn lines_bwd_lasx(
while end.offset_from_unsigned(beg) >= 128 {
let chunk_start = end.sub(128);

let v1 = lasx_xvld::<0>(chunk_start as *const _);
let v2 = lasx_xvld::<32>(chunk_start as *const _);
let v3 = lasx_xvld::<64>(chunk_start as *const _);
let v4 = lasx_xvld::<96>(chunk_start as *const _);
let v1 = lasx_xvld::<0>(chunk_start.cast());
let v2 = lasx_xvld::<32>(chunk_start.cast());
let v3 = lasx_xvld::<64>(chunk_start.cast());
let v4 = lasx_xvld::<96>(chunk_start.cast());

let mut sum = lasx_xvneg_b(lasx_xvseqi_b::<LF>(v1));
sum = lasx_xvsub_b(sum, lasx_xvseqi_b::<LF>(v2));
Expand All @@ -238,7 +238,7 @@ unsafe fn lines_bwd_lasx(

while end.offset_from_unsigned(beg) >= 32 {
let chunk_start = end.sub(32);
let v = lasx_xvld::<0>(chunk_start as *const _);
let v = lasx_xvld::<0>(chunk_start.cast());
let c = lasx_xvseqi_b::<LF>(v);

let ones = lasx_xvandi_b::<1>(c);
Expand Down Expand Up @@ -289,10 +289,10 @@ unsafe fn lines_bwd_lsx(
while end.offset_from_unsigned(beg) >= 64 {
let chunk_start = end.sub(64);

let v1 = lsx_vld::<0>(chunk_start as *const _);
let v2 = lsx_vld::<16>(chunk_start as *const _);
let v3 = lsx_vld::<32>(chunk_start as *const _);
let v4 = lsx_vld::<48>(chunk_start as *const _);
let v1 = lsx_vld::<0>(chunk_start.cast());
let v2 = lsx_vld::<16>(chunk_start.cast());
let v3 = lsx_vld::<32>(chunk_start.cast());
let v4 = lsx_vld::<48>(chunk_start.cast());

let mut sum = lsx_vneg_b(lsx_vseqi_b::<LF>(v1));
sum = lsx_vsub_b(sum, lsx_vseqi_b::<LF>(v2));
Expand All @@ -311,7 +311,7 @@ unsafe fn lines_bwd_lsx(

while end.offset_from_unsigned(beg) >= 16 {
let chunk_start = end.sub(16);
let v = lsx_vld::<0>(chunk_start as *const _);
let v = lsx_vld::<0>(chunk_start.cast());
let c = lsx_vseqi_b::<LF>(v);

let ones = lsx_vandi_b::<1>(c);
Expand Down
30 changes: 15 additions & 15 deletions crates/edit/src/simd/lines_fwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ unsafe fn lines_fwd_avx2(
// Unrolling the loop by 4x speeds things up by >3x.
// It allows us to accumulate matches before doing a single `vpsadbw`.
while end.offset_from_unsigned(beg) >= 128 {
let v1 = _mm256_loadu_si256(beg.add(0) as *const _);
let v2 = _mm256_loadu_si256(beg.add(32) as *const _);
let v3 = _mm256_loadu_si256(beg.add(64) as *const _);
let v4 = _mm256_loadu_si256(beg.add(96) as *const _);
let v1 = _mm256_loadu_si256(beg.add(0).cast());
let v2 = _mm256_loadu_si256(beg.add(32).cast());
let v3 = _mm256_loadu_si256(beg.add(64).cast());
let v4 = _mm256_loadu_si256(beg.add(96).cast());

// `vpcmpeqb` leaves each comparison result byte as 0 or -1 (0xff).
// This allows us to accumulate the comparisons by subtracting them.
Expand All @@ -145,7 +145,7 @@ unsafe fn lines_fwd_avx2(
}

while end.offset_from_unsigned(beg) >= 32 {
let v = _mm256_loadu_si256(beg as *const _);
let v = _mm256_loadu_si256(beg.cast());
let c = _mm256_cmpeq_epi8(v, lf);

// If you ask an LLM, the best way to do this is
Expand Down Expand Up @@ -221,10 +221,10 @@ unsafe fn lines_fwd_lasx(

if line < line_stop {
while end.offset_from_unsigned(beg) >= 128 {
let v1 = lasx_xvld::<0>(beg as *const _);
let v2 = lasx_xvld::<32>(beg as *const _);
let v3 = lasx_xvld::<64>(beg as *const _);
let v4 = lasx_xvld::<96>(beg as *const _);
let v1 = lasx_xvld::<0>(beg.cast());
let v2 = lasx_xvld::<32>(beg.cast());
let v3 = lasx_xvld::<64>(beg.cast());
let v4 = lasx_xvld::<96>(beg.cast());

let mut sum = lasx_xvneg_b(lasx_xvseqi_b::<LF>(v1));
sum = lasx_xvsub_b(sum, lasx_xvseqi_b::<LF>(v2));
Expand All @@ -242,7 +242,7 @@ unsafe fn lines_fwd_lasx(
}

while end.offset_from_unsigned(beg) >= 32 {
let v = lasx_xvld::<0>(beg as *const _);
let v = lasx_xvld::<0>(beg.cast());
let c = lasx_xvseqi_b::<LF>(v);

let ones = lasx_xvandi_b::<1>(c);
Expand Down Expand Up @@ -292,10 +292,10 @@ unsafe fn lines_fwd_lsx(

if line < line_stop {
while end.offset_from_unsigned(beg) >= 64 {
let v1 = lsx_vld::<0>(beg as *const _);
let v2 = lsx_vld::<16>(beg as *const _);
let v3 = lsx_vld::<32>(beg as *const _);
let v4 = lsx_vld::<48>(beg as *const _);
let v1 = lsx_vld::<0>(beg.cast());
let v2 = lsx_vld::<16>(beg.cast());
let v3 = lsx_vld::<32>(beg.cast());
let v4 = lsx_vld::<48>(beg.cast());

let mut sum = lsx_vneg_b(lsx_vseqi_b::<LF>(v1));
sum = lsx_vsub_b(sum, lsx_vseqi_b::<LF>(v2));
Expand All @@ -313,7 +313,7 @@ unsafe fn lines_fwd_lsx(
}

while end.offset_from_unsigned(beg) >= 16 {
let v = lsx_vld::<0>(beg as *const _);
let v = lsx_vld::<0>(beg.cast());
let c = lsx_vseqi_b::<LF>(v);

let ones = lsx_vandi_b::<1>(c);
Expand Down
6 changes: 3 additions & 3 deletions crates/edit/src/simd/memchr2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ unsafe fn memchr2_avx2(needle1: u8, needle2: u8, mut beg: *const u8, end: *const
let mut remaining = end.offset_from_unsigned(beg);

while remaining >= 32 {
let v = _mm256_loadu_si256(beg as *const _);
let v = _mm256_loadu_si256(beg.cast());
let a = _mm256_cmpeq_epi8(v, n1);
let b = _mm256_cmpeq_epi8(v, n2);
let c = _mm256_or_si256(a, b);
Expand Down Expand Up @@ -134,7 +134,7 @@ unsafe fn memchr2_lasx(needle1: u8, needle2: u8, mut beg: *const u8, end: *const
}

while end.offset_from_unsigned(beg) >= 32 {
let v = lasx_xvld::<0>(beg as *const _);
let v = lasx_xvld::<0>(beg.cast());
let a = lasx_xvseq_b(v, n1);
let b = lasx_xvseq_b(v, n2);
let c = lasx_xvor_v(a, b);
Expand Down Expand Up @@ -169,7 +169,7 @@ unsafe fn memchr2_lsx(needle1: u8, needle2: u8, mut beg: *const u8, end: *const
}

while end.offset_from_unsigned(beg) >= 16 {
let v = lsx_vld::<0>(beg as *const _);
let v = lsx_vld::<0>(beg.cast());
let a = lsx_vseq_b(v, n1);
let b = lsx_vseq_b(v, n2);
let c = lsx_vor_v(a, b);
Expand Down
2 changes: 1 addition & 1 deletion crates/edit/src/sys/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ where
res.push_str(arena, name);
res.push_str(arena, suffix);
res.push(arena, '\0');
res.as_ptr() as *const c_char
res.as_ptr().cast()
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/edit/src/sys/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ pub fn read_stdin(arena: &Arena, mut timeout: time::Duration) -> Option<BString<
0,
utf16_buf[0].as_ptr(),
utf16_buf_len as i32,
spare.as_mut_ptr() as *mut _,
spare.as_mut_ptr().cast(),
spare.len() as i32,
null(),
null_mut(),
Expand Down Expand Up @@ -488,7 +488,7 @@ fn file_id_from_handle(file: &File) -> io::Result<FileId> {
check_bool_return(FileSystem::GetFileInformationByHandleEx(
file.as_raw_handle(),
FileSystem::FileIdInfo,
info.as_mut_ptr() as *mut _,
info.as_mut_ptr().cast(),
mem::size_of::<FileSystem::FILE_ID_INFO>() as u32,
))?;
Ok(FileId::Id(info.assume_init()))
Expand Down Expand Up @@ -538,7 +538,7 @@ unsafe fn load_library(name: *const u16) -> io::Result<NonNull<c_void>> {
// It'd be nice to constrain T to std::marker::FnPtr, but that's unstable.
pub unsafe fn get_proc_address<T>(handle: NonNull<c_void>, name: *const c_char) -> io::Result<T> {
unsafe {
let ptr = LibraryLoader::GetProcAddress(handle.as_ptr(), name as *const u8);
let ptr = LibraryLoader::GetProcAddress(handle.as_ptr(), name.cast());
if let Some(ptr) = ptr { Ok(mem::transmute_copy(&ptr)) } else { Err(last_os_error()) }
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/lsh-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ anyhow = "*"
argh = "*"
lsh.workspace = true
stdext.workspace = true

[lints]
workspace = true
3 changes: 3 additions & 0 deletions crates/lsh/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ rust-version.workspace = true

[dependencies]
stdext.workspace = true

[lints]
workspace = true
12 changes: 6 additions & 6 deletions crates/lsh/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
//! as used by the backend's relocation system.

use std::fmt::{self, Debug};
use std::mem;
use std::{mem, ptr};

use stdext::arena::Arena;
use stdext::arena_write_fmt;
Expand Down Expand Up @@ -474,13 +474,13 @@ impl Registers {
}

#[inline(always)]
unsafe fn as_ptr(&self) -> *const u32 {
self as *const _ as *const u32
fn as_ptr(&self) -> *const u32 {
ptr::from_ref(self).cast()
}

#[inline(always)]
unsafe fn as_mut_ptr(&mut self) -> *mut u32 {
self as *mut _ as *mut u32
fn as_mut_ptr(&mut self) -> *mut u32 {
ptr::from_mut(self).cast()
}
}

Expand Down Expand Up @@ -570,7 +570,7 @@ macro_rules! instruction_decode {
#[inline(always)]
fn dec_u32(bytes: &[u8], off: usize) -> u32 {
debug_assert!(off + 4 <= bytes.len());
unsafe { (bytes.as_ptr().add(off) as *const u32).read_unaligned() }
unsafe { (bytes.as_ptr().add(off).cast::<u32>()).read_unaligned() }
}

let __asm: &[u8] = $assembly;
Expand Down
3 changes: 3 additions & 0 deletions crates/stdext/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ single-threaded = []

[target.'cfg(unix)'.dependencies]
libc = "0.2"

[lints]
workspace = true
4 changes: 2 additions & 2 deletions crates/stdext/src/collections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl<'a, T: Copy> BVec<'a, T> {
let dst = self.spare_mut_ptr();
let src = self.ptr.as_ptr().add(beg);
self.len += add;
ptr::copy_nonoverlapping(src as *const _, dst, add);
ptr::copy_nonoverlapping(src.cast(), dst, add);
}
}

Expand Down Expand Up @@ -455,7 +455,7 @@ impl<'a> BVec<'a, u16> {
// MultiByteToWideChar is ~2x faster than the UTF8 loop below and saves space.
#[cfg(windows)]
unsafe {
let dst = self.spare_mut_ptr() as *mut u16;
let dst = self.spare_mut_ptr().cast();
let len = MultiByteToWideChar(
65001,
0,
Expand Down
Loading
Loading