From 61d75f8fd138c4c60bdda56d36596d8ddd006c78 Mon Sep 17 00:00:00 2001 From: travis1829 Date: Fri, 4 Feb 2022 19:16:40 +0900 Subject: [PATCH 1/4] Use `where` bound in Page::as_uninit_mut --- kernel-rs/Cargo.toml | 3 +++ kernel-rs/src/lib.rs | 2 ++ kernel-rs/src/page.rs | 15 +++++---------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel-rs/Cargo.toml b/kernel-rs/Cargo.toml index aa8ea82c1..14cc158ca 100644 --- a/kernel-rs/Cargo.toml +++ b/kernel-rs/Cargo.toml @@ -18,6 +18,9 @@ lfs = [] [profile.dev] panic = "abort" opt-level = 1 +# TODO: The `const_generics` and `const_evaluatable_checked` feature causes an ICE on low nightly versions +# when trying incremental compilation. Remove this after upgrading to a higher nightly version. +incremental = false [profile.release] panic = "abort" diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 6c477babb..091a67a0a 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -48,6 +48,8 @@ #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_trait_impl)] +#![feature(const_generics)] +#![feature(const_evaluatable_checked)] #![feature(generic_associated_types)] #![feature(maybe_uninit_extra)] #![feature(raw_ref_op)] diff --git a/kernel-rs/src/page.rs b/kernel-rs/src/page.rs index a957be77d..cf2d80f5e 100644 --- a/kernel-rs/src/page.rs +++ b/kernel-rs/src/page.rs @@ -74,16 +74,11 @@ impl Page { } } - pub fn as_uninit_mut(&mut self) -> &mut MaybeUninit { - // TODO(https://github.com/kaist-cp/rv6/issues/471): Use const_assert! (or equivalent) - // instead. Currently, use of T inside const_assert! incurs a compile error: "can't use - // generic parameters from outer function". Also, there's a workaround using - // feature(const_generics) and feature(const_evaluatable_checked). However, using them makes - // the compiler panic. When the compiler becomes updated, we will fix the following lines to - // use static checks. - assert!(mem::size_of::() <= PGSIZE); - assert_eq!(PGSIZE % mem::align_of::(), 0); - + pub fn as_uninit_mut(&mut self) -> &mut MaybeUninit + where + [u8; PGSIZE - mem::size_of::()]:, // We need mem::size_of::() <= PGSIZE + [u8; PGSIZE % mem::align_of::() + usize::MAX]: // We need PGSIZE % mem::align_of:: == 0 + { // SAFETY: self.inner is an array of length PGSIZE aligned with PGSIZE bytes. // The above assertions show that it can contain a value of T. As it contains arbitrary // data, we cannot treat it as &mut T. Instead, we use &mut MaybeUninit. It's ok because From b588992feba0073ad44a0c4822fd961f3ba24daa Mon Sep 17 00:00:00 2001 From: travis1829 Date: Fri, 4 Feb 2022 19:25:31 +0900 Subject: [PATCH 2/4] Use `where` bound in memset --- kernel-rs/src/util/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel-rs/src/util/mod.rs b/kernel-rs/src/util/mod.rs index dad1924cc..066708ff6 100644 --- a/kernel-rs/src/util/mod.rs +++ b/kernel-rs/src/util/mod.rs @@ -53,10 +53,11 @@ pub fn memmove(dst: &mut [u8], src: &[u8]) { /// # SAFETY /// /// Filling a value of `T` with a value of `S` must not break the invariant of `T`. -pub unsafe fn memset(dst: &mut T, v: S) { - // Cannot use `const_assert!` here. Compiler optimization will remove `assert!`. - assert!(core::mem::size_of::() % core::mem::size_of::() == 0); - assert!(core::mem::align_of::() % core::mem::align_of::() == 0); +pub unsafe fn memset(dst: &mut T, v: S) +where + [u8; core::mem::size_of::() % core::mem::size_of::() + usize::MAX]:, // We need mem::size_of::() % mem::size_of::() == 0 + [u8; core::mem::align_of::() % core::mem::align_of::() + usize::MAX]:,// We need mem::align_of::() % mem::align_of::() == 0 +{ // SAFETY: T's size/alignment is a multiple of S's size/alignment. let buf = unsafe { core::slice::from_raw_parts_mut( From 3aa51b22f8098a5e3d1d286bb1d24e70b0d170e2 Mon Sep 17 00:00:00 2001 From: travis1829 Date: Fri, 4 Feb 2022 19:37:22 +0900 Subject: [PATCH 3/4] cargo fmt --- kernel-rs/src/page.rs | 4 ++-- kernel-rs/src/util/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel-rs/src/page.rs b/kernel-rs/src/page.rs index cf2d80f5e..507af2778 100644 --- a/kernel-rs/src/page.rs +++ b/kernel-rs/src/page.rs @@ -76,8 +76,8 @@ impl Page { pub fn as_uninit_mut(&mut self) -> &mut MaybeUninit where - [u8; PGSIZE - mem::size_of::()]:, // We need mem::size_of::() <= PGSIZE - [u8; PGSIZE % mem::align_of::() + usize::MAX]: // We need PGSIZE % mem::align_of:: == 0 + [u8; PGSIZE - mem::size_of::()]: , /* We need mem::size_of::() <= PGSIZE */ + [u8; PGSIZE % mem::align_of::() + usize::MAX]: , /* We need PGSIZE % mem::align_of:: == 0 */ { // SAFETY: self.inner is an array of length PGSIZE aligned with PGSIZE bytes. // The above assertions show that it can contain a value of T. As it contains arbitrary diff --git a/kernel-rs/src/util/mod.rs b/kernel-rs/src/util/mod.rs index 066708ff6..1cb9ada60 100644 --- a/kernel-rs/src/util/mod.rs +++ b/kernel-rs/src/util/mod.rs @@ -55,8 +55,8 @@ pub fn memmove(dst: &mut [u8], src: &[u8]) { /// Filling a value of `T` with a value of `S` must not break the invariant of `T`. pub unsafe fn memset(dst: &mut T, v: S) where - [u8; core::mem::size_of::() % core::mem::size_of::() + usize::MAX]:, // We need mem::size_of::() % mem::size_of::() == 0 - [u8; core::mem::align_of::() % core::mem::align_of::() + usize::MAX]:,// We need mem::align_of::() % mem::align_of::() == 0 + [u8; core::mem::size_of::() % core::mem::size_of::() + usize::MAX]: , /* We need mem::size_of::() % mem::size_of::() == 0 */ + [u8; core::mem::align_of::() % core::mem::align_of::() + usize::MAX]: , /* We need mem::align_of::() % mem::align_of::() == 0 */ { // SAFETY: T's size/alignment is a multiple of S's size/alignment. let buf = unsafe { From 61a7a4317fb05522192a0875834574c953245864 Mon Sep 17 00:00:00 2001 From: travis1829 Date: Tue, 8 Feb 2022 18:30:45 +0900 Subject: [PATCH 4/4] Change `u8` to `()` --- kernel-rs/src/page.rs | 4 ++-- kernel-rs/src/util/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel-rs/src/page.rs b/kernel-rs/src/page.rs index 507af2778..ea10f1e41 100644 --- a/kernel-rs/src/page.rs +++ b/kernel-rs/src/page.rs @@ -76,8 +76,8 @@ impl Page { pub fn as_uninit_mut(&mut self) -> &mut MaybeUninit where - [u8; PGSIZE - mem::size_of::()]: , /* We need mem::size_of::() <= PGSIZE */ - [u8; PGSIZE % mem::align_of::() + usize::MAX]: , /* We need PGSIZE % mem::align_of:: == 0 */ + [(); PGSIZE - mem::size_of::()]: , /* We need mem::size_of::() <= PGSIZE */ + [(); PGSIZE % mem::align_of::() + usize::MAX]: , /* We need PGSIZE % mem::align_of:: == 0 */ { // SAFETY: self.inner is an array of length PGSIZE aligned with PGSIZE bytes. // The above assertions show that it can contain a value of T. As it contains arbitrary diff --git a/kernel-rs/src/util/mod.rs b/kernel-rs/src/util/mod.rs index 1cb9ada60..da5a1f3c5 100644 --- a/kernel-rs/src/util/mod.rs +++ b/kernel-rs/src/util/mod.rs @@ -55,8 +55,8 @@ pub fn memmove(dst: &mut [u8], src: &[u8]) { /// Filling a value of `T` with a value of `S` must not break the invariant of `T`. pub unsafe fn memset(dst: &mut T, v: S) where - [u8; core::mem::size_of::() % core::mem::size_of::() + usize::MAX]: , /* We need mem::size_of::() % mem::size_of::() == 0 */ - [u8; core::mem::align_of::() % core::mem::align_of::() + usize::MAX]: , /* We need mem::align_of::() % mem::align_of::() == 0 */ + [(); core::mem::size_of::() % core::mem::size_of::() + usize::MAX]: , /* We need mem::size_of::() % mem::size_of::() == 0 */ + [(); core::mem::align_of::() % core::mem::align_of::() + usize::MAX]: , /* We need mem::align_of::() % mem::align_of::() == 0 */ { // SAFETY: T's size/alignment is a multiple of S's size/alignment. let buf = unsafe {