kaist-cp / rv6

Other
125 stars 13 forks source link

[Closes #471] Use `where` bound to const check at compilation time #592

Closed travis1829 closed 2 years ago

travis1829 commented 2 years ago

Partially resolves #471 https://github.com/kaist-cp/rv6/issues/471#issuecomment-1024471179

PR#489와 비슷하게 여전히 error message를 띄우는 건 안되지만, 그래도 이전보다는 훨씬 깔끔한 방법을 사용해봤습니다.

pub fn as_uninit_mut<T>(&mut self) -> &mut MaybeUninit<T>
where
    [u8; PGSIZE - mem::size_of::<T>()]:,                // We need mem::size_of::<T>() <= PGSIZE
        [u8; PGSIZE % mem::align_of::<T>() + usize::MAX]:   // We need PGSIZE % mem::align_of::<T> == 0
{
    //...
}

Rust blog 등을 확인해보면, 아직은 위 예처럼 array length부분 등을 이용해 검사를 해보기를 권고하는 것 같습니다. (추후에 훨찐 직관적인 syntax를 제공하겠다고는 했으나, 아직 안 나온 것 같습니다.)

travis1829 commented 2 years ago

또는 다음과 같이 자동으로 impl되는 trait을 추가해서 해결할수도 있습니다. ex)

pub fn as_uninit_mut<T: FromPage>(&mut self) -> &mut MaybeUninit<T> {
    //...
}

/// This trait is auto-implemented for types that suffice the following.
/// * mem::size_of::<T>() <= PGSIZE
/// * PGSIZE % mem::align_of::<T>() == 0
pub trait FromPage {}
impl<T> FromPage for T
where
    [u8; PGSIZE - mem::size_of::<T>()]:,                // We need mem::size_of::<T>() <= PGSIZE
        [u8; PGSIZE % mem::align_of::<T>() + usize::MAX]:   // We need PGSIZE % mem::align_of::<T> == 0
{}
travis1829 commented 2 years ago

아직까지는 const_evaluatable_checkedgeneric_const_exprs feature가 unstable하므로 버그 등을 일으킬 수 있고 syntax가 깔끔하지 못한 것 같으므로, 이 문제는 추후에 rustc version을 올린 후 revisit하는게 좋을 것 같습니다. 일단은 close합니다.