diff --git a/Cargo.lock b/Cargo.lock index 0e7d398a..f080098d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1825,18 +1825,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", diff --git a/alloc/src/bump.rs b/alloc/src/bump.rs index d45ecdcd..362682ea 100644 --- a/alloc/src/bump.rs +++ b/alloc/src/bump.rs @@ -51,6 +51,12 @@ impl Alloc { } } +impl Default for Alloc { + fn default() -> Self { + Self::new() + } +} + unsafe impl GlobalAlloc for Alloc { /// # Safety /// diff --git a/bitfield/src/bitfield.rs b/bitfield/src/bitfield.rs index 0be46a9e..35f671e0 100644 --- a/bitfield/src/bitfield.rs +++ b/bitfield/src/bitfield.rs @@ -419,6 +419,10 @@ macro_rules! bitfield { /// Constructs a new instance of `Self` with all bits set to 0. #[inline] #[must_use] + // Allow "new without default", as the user may wish to derive + // default or provide their own implementation with different values + // from `new`. + #[allow(clippy::new_without_default)] $vis const fn new() -> Self { Self(0) } diff --git a/bitfield/src/pack.rs b/bitfield/src/pack.rs index ee8cb4db..fe976900 100644 --- a/bitfield/src/pack.rs +++ b/bitfield/src/pack.rs @@ -1229,7 +1229,7 @@ mod tests { prop_assert_bits_eq!(packed, pack_from_src.set_all(0), state); prop_assert_bits_eq!(pack_from_src.unpack_bits(packed), pack_from_dst.unpack_bits(dst), &state); - let dst = <$Bits>::max_value(); + let dst = <$Bits>::MAX; let packed = pair.pack_from_src(src, dst); prop_assert_bits_eq!(packed, pack_from_src.set_all(0), state); prop_assert_bits_eq!(pack_from_src.unpack_bits(packed), pack_from_dst.unpack_bits(dst), &state); diff --git a/hal-core/Cargo.toml b/hal-core/Cargo.toml index 018ea636..0560d8de 100644 --- a/hal-core/Cargo.toml +++ b/hal-core/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Eliza Weisman ", "iximeow "] edition = "2021" license = "MIT" -rust-version = "1.81.0" +rust-version = "1.84.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/hal-core/src/addr.rs b/hal-core/src/addr.rs index 72dcbc5b..030d0a35 100644 --- a/hal-core/src/addr.rs +++ b/hal-core/src/addr.rs @@ -1,4 +1,4 @@ -use core::{fmt, ops}; +use core::{fmt, ops, ptr}; pub trait Address: Copy @@ -76,10 +76,10 @@ pub trait Address: self.align_down(core::mem::align_of::()) } - /// Offsets this address by `offset`. + /// Offsets this address by `offset` bytes. /// /// If the specified offset would overflow, this function saturates instead. - fn offset(self, offset: i32) -> Self { + fn offset(self, offset: isize) -> Self { if offset > 0 { self + offset as usize } else { @@ -117,11 +117,32 @@ pub trait Address: self.is_aligned(core::mem::align_of::()) } + /// Converts this address into a const pointer to a value of type `T`. + /// + /// # Panics + /// + /// - If `self` is not aligned for a `T`-typed value. + #[inline] + #[track_caller] + fn as_ptr(self) -> *const T { + // Some architectures permit unaligned reads, but Rust considers + // dereferencing a pointer that isn't type-aligned to be UB. + assert!( + self.is_aligned_for::(), + "assertion failed: self.is_aligned_for::<{}>();\n\tself={self:?}", + core::any::type_name::(), + ); + ptr::with_exposed_provenance(self.as_usize()) + } + + /// Converts this address into a mutable pointer to a value of type `T`. + /// /// # Panics /// /// - If `self` is not aligned for a `T`-typed value. + #[inline] #[track_caller] - fn as_ptr(self) -> *mut T { + fn as_mut_ptr(self) -> *mut T { // Some architectures permit unaligned reads, but Rust considers // dereferencing a pointer that isn't type-aligned to be UB. assert!( @@ -129,7 +150,19 @@ pub trait Address: "assertion failed: self.is_aligned_for::<{}>();\n\tself={self:?}", core::any::type_name::(), ); - self.as_usize() as *mut T + ptr::with_exposed_provenance_mut(self.as_usize()) + } + + /// Converts this address into a `Option>` from a + /// `VAddr`, returning `None` if the address is null. + /// + /// # Panics + /// + /// - If `self` is not aligned for a `T`-typed value. + #[inline] + #[track_caller] + fn as_non_null(self) -> Option> { + ptr::NonNull::new(self.as_mut_ptr::()) } } @@ -300,11 +333,11 @@ macro_rules! impl_addrs { Address::align_down(self, align) } - /// Offsets this address by `offset`. + /// Offsets this address by `offset` bytes. /// /// If the specified offset would overflow, this function saturates instead. #[inline] - pub fn offset(self, offset: i32) -> Self { + pub fn offset(self, offset: isize) -> Self { Address::offset(self, offset) } @@ -327,13 +360,39 @@ macro_rules! impl_addrs { Address::is_aligned_for::(self) } + /// Converts this address into a const pointer to a value of type `T`. + /// /// # Panics /// /// - If `self` is not aligned for a `T`-typed value. #[inline] - pub fn as_ptr(self) -> *mut T { + #[track_caller] + pub fn as_ptr(self) -> *const T { Address::as_ptr(self) } + + /// Converts this address into a mutable pointer to a value of type `T`. + /// + /// # Panics + /// + /// - If `self` is not aligned for a `T`-typed value. + #[inline] + #[track_caller] + pub fn as_mut_ptr(self) -> *mut T { + Address::as_mut_ptr(self) + } + + /// Converts this address into a `Option>` from a + /// `VAddr`, returning `None` if the address is null. + /// + /// # Panics + /// + /// - If `self` is not aligned for a `T`-typed value. + #[inline] + #[track_caller] + pub fn as_non_null(self) -> Option> { + ptr::NonNull::new(self.as_mut_ptr::()) + } } )+ } @@ -392,9 +451,15 @@ impl VAddr { Self(u) } + /// Constructs a `VAddr` from a `*const T` pointer, exposing its provenance. + #[inline] + pub fn from_ptr(ptr: *const T) -> Self { + Self::from_usize(ptr.expose_provenance()) + } + #[inline] pub fn of(pointee: &T) -> Self { - Self::from_usize(pointee as *const _ as *const () as usize) + Self::from_ptr(pointee as *const T) } } diff --git a/hal-core/src/framebuffer.rs b/hal-core/src/framebuffer.rs index 32465ac6..b631abfd 100644 --- a/hal-core/src/framebuffer.rs +++ b/hal-core/src/framebuffer.rs @@ -187,7 +187,7 @@ macro_rules! deref_draw_body { }; } -impl<'lock, D, L> Draw for blocking::MutexGuard<'lock, D, L> +impl Draw for blocking::MutexGuard<'_, D, L> where D: Draw, L: blocking::RawMutex, @@ -195,7 +195,7 @@ where deref_draw_body! {} } -impl<'draw, D> Draw for &'draw mut D +impl Draw for &'_ mut D where D: Draw, { diff --git a/hal-core/src/interrupt.rs b/hal-core/src/interrupt.rs index c37ef400..d14aca55 100644 --- a/hal-core/src/interrupt.rs +++ b/hal-core/src/interrupt.rs @@ -91,7 +91,7 @@ enum RegistrationErrorKind { // === impl CriticalGuard === -impl<'a, C: Control + ?Sized> Drop for CriticalGuard<'a, C> { +impl Drop for CriticalGuard<'_, C> { fn drop(&mut self) { unsafe { self.ctrl.enable(); diff --git a/hal-core/src/mem.rs b/hal-core/src/mem.rs index 8828ab55..25a3ba65 100644 --- a/hal-core/src/mem.rs +++ b/hal-core/src/mem.rs @@ -84,13 +84,13 @@ impl Region { } pub fn split_front(&mut self, size: usize) -> Option { - assert!(size <= core::i32::MAX as usize); + assert!(size <= isize::MAX as usize); if size > self.size { return None; } let base = self.base; tracing::trace!(size, self.size, "splitting down by"); - self.base = self.base.offset(size as i32); + self.base = self.base.offset(size as isize); self.size -= size; Some(Self { base, @@ -100,12 +100,12 @@ impl Region { } pub fn split_back(&mut self, size: usize) -> Option { - assert!(size <= core::i32::MAX as usize); + assert!(size <= isize::MAX as usize); if size >= self.size { return None; } let rem_size = self.size - size; - let base = self.base.offset(size as i32); + let base = self.base.offset(size as isize); tracing::trace!( size, self.size, diff --git a/hal-core/src/mem/page.rs b/hal-core/src/mem/page.rs index eb381ff3..10f16509 100644 --- a/hal-core/src/mem/page.rs +++ b/hal-core/src/mem/page.rs @@ -484,7 +484,7 @@ impl Page { /// When calling this method, ensure that the page will not be mutated /// concurrently, including by user code. pub unsafe fn as_slice(&self) -> &[u8] { - let start = self.base.as_ptr() as *const u8; + let start = self.base.as_mut_ptr() as *const u8; slice::from_raw_parts::(start, self.size.as_usize()) } @@ -495,7 +495,7 @@ impl Page { /// When calling this method, ensure that the page will not be read or mutated /// concurrently, including by user code. pub unsafe fn as_slice_mut(&mut self) -> &mut [u8] { - let start = self.base.as_ptr::() as *mut _; + let start = self.base.as_mut_ptr::() as *mut _; slice::from_raw_parts_mut::(start, self.size.as_usize()) } } diff --git a/hal-x86_64/src/cpu/entropy.rs b/hal-x86_64/src/cpu/entropy.rs index ebcea003..a6d0405b 100644 --- a/hal-x86_64/src/cpu/entropy.rs +++ b/hal-x86_64/src/cpu/entropy.rs @@ -69,7 +69,7 @@ pub fn seed_rng() -> R { #[derive(Debug, Copy, Clone)] pub struct Rdrand(()); -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Default)] pub struct PitEntropy(()); // === impl Rdrand === diff --git a/hal-x86_64/src/cpu/msr.rs b/hal-x86_64/src/cpu/msr.rs index abfb8126..db877023 100644 --- a/hal-x86_64/src/cpu/msr.rs +++ b/hal-x86_64/src/cpu/msr.rs @@ -281,7 +281,7 @@ impl Msr { options(nomem, nostack, preserves_flags) ); } - (hi as u64) << 32 | (lo as u64) + ((hi as u64) << 32) | (lo as u64) } /// Writes the given raw `u64` value to this MSR. diff --git a/hal-x86_64/src/framebuffer.rs b/hal-x86_64/src/framebuffer.rs index 54d00027..78fa96ae 100644 --- a/hal-x86_64/src/framebuffer.rs +++ b/hal-x86_64/src/framebuffer.rs @@ -71,7 +71,7 @@ where } } -impl<'buf, B> Draw for Framebuffer<'buf, B> +impl Draw for Framebuffer<'_, B> where B: Deref + DerefMut, { @@ -101,7 +101,7 @@ where // `Volatile` is only `Debug` if `::Target: Copy`, // so we must implement this manually. -impl<'buf, B> fmt::Debug for Framebuffer<'buf, B> +impl fmt::Debug for Framebuffer<'_, B> where B: Deref, { diff --git a/hal-x86_64/src/interrupt.rs b/hal-x86_64/src/interrupt.rs index dcc4de9c..0a7092d1 100644 --- a/hal-x86_64/src/interrupt.rs +++ b/hal-x86_64/src/interrupt.rs @@ -390,7 +390,7 @@ impl Controller { } } -impl<'a, T> hal_core::interrupt::Context for Context<'a, T> { +impl hal_core::interrupt::Context for Context<'_, T> { type Registers = Registers; fn registers(&self) -> &Registers { @@ -406,7 +406,7 @@ impl<'a, T> hal_core::interrupt::Context for Context<'a, T> { } } -impl<'a> ctx::PageFault for Context<'a, PageFaultCode> { +impl ctx::PageFault for Context<'_, PageFaultCode> { fn fault_vaddr(&self) -> crate::VAddr { crate::control_regs::Cr2::read() } @@ -420,7 +420,7 @@ impl<'a> ctx::PageFault for Context<'a, PageFaultCode> { } } -impl<'a> ctx::CodeFault for Context<'a, CodeFault<'a>> { +impl ctx::CodeFault for Context<'_, CodeFault<'_>> { fn is_user_mode(&self) -> bool { false // TODO(eliza) } @@ -438,13 +438,13 @@ impl<'a> ctx::CodeFault for Context<'a, CodeFault<'a>> { } } -impl<'a> Context<'a, ErrorCode> { +impl Context<'_, ErrorCode> { pub fn error_code(&self) -> ErrorCode { self.code } } -impl<'a> Context<'a, PageFaultCode> { +impl Context<'_, PageFaultCode> { pub fn page_fault_code(&self) -> PageFaultCode { self.code } diff --git a/hal-x86_64/src/interrupt/apic/ioapic.rs b/hal-x86_64/src/interrupt/apic/ioapic.rs index 0a0426df..10cf7fdb 100644 --- a/hal-x86_64/src/interrupt/apic/ioapic.rs +++ b/hal-x86_64/src/interrupt/apic/ioapic.rs @@ -348,7 +348,7 @@ impl IoApic { tracing::debug!("mapped I/O APIC MMIO page!"); } - let registers = unsafe { Volatile::new(&mut *base.as_ptr::()) }; + let registers = unsafe { Volatile::new(&mut *base.as_mut_ptr::()) }; let mut ioapic = Self { registers }; tracing::info!( addr = ?base, @@ -440,7 +440,7 @@ impl IoApic { fn entry_raw(&mut self, register_low: u32) -> RedirectionEntry { let low = self.read(register_low); let high = self.read(register_low + 1); - RedirectionEntry::from_bits((high as u64) << 32 | low as u64) + RedirectionEntry::from_bits(((high as u64) << 32) | low as u64) } #[inline] @@ -453,7 +453,6 @@ impl IoApic { } #[must_use] - fn read(&mut self, offset: u32) -> u32 { self.set_offset(offset); self.registers.map_mut(|ioapic| &mut ioapic.data).read() diff --git a/hal-x86_64/src/interrupt/apic/local.rs b/hal-x86_64/src/interrupt/apic/local.rs index 1c1a5904..2508e2bf 100644 --- a/hal-x86_64/src/interrupt/apic/local.rs +++ b/hal-x86_64/src/interrupt/apic/local.rs @@ -545,7 +545,7 @@ impl LocalApic { addr.is_aligned(16usize), "Local APIC memory-mapped registers must be 16-byte aligned!" ); - let reference = &mut *addr.as_ptr::(); + let reference = &mut *addr.as_mut_ptr::(); LocalApicRegister::::volatile(reference) } } diff --git a/hal-x86_64/src/interrupt/idt.rs b/hal-x86_64/src/interrupt/idt.rs index 73acdf92..5423719a 100644 --- a/hal-x86_64/src/interrupt/idt.rs +++ b/hal-x86_64/src/interrupt/idt.rs @@ -237,6 +237,12 @@ impl Idt { } } +impl Default for Idt { + fn default() -> Self { + Self::new() + } +} + impl fmt::Debug for Idt { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let Self { descriptors } = self; diff --git a/hal-x86_64/src/mm.rs b/hal-x86_64/src/mm.rs index af90c7e9..1c51be72 100644 --- a/hal-x86_64/src/mm.rs +++ b/hal-x86_64/src/mm.rs @@ -110,14 +110,14 @@ where /// This value should only be set once, early in the kernel boot process before /// we have access to multiple cores. So, technically, it could be a `static /// mut`. But, using an atomic is safe, even though it's not strictly necessary. -static VM_OFFSET: AtomicUsize = AtomicUsize::new(core::usize::MAX); +static VM_OFFSET: AtomicUsize = AtomicUsize::new(usize::MAX); // XXX(eliza): this sucks pub fn vm_offset() -> VAddr { let off = VM_OFFSET.load(Ordering::Acquire); assert_ne!( off, - core::usize::MAX, + usize::MAX, "`init_paging` must be called before calling `vm_offset`!" ); VAddr::from_usize(off) @@ -204,7 +204,7 @@ impl PageCtrl { let vm_offset = VM_OFFSET.load(Ordering::Acquire); assert_ne!( vm_offset, - core::usize::MAX, + usize::MAX, "`init_paging` must be called before calling `PageTable::current`!" ); let vm_offset = VAddr::from_usize(vm_offset); @@ -303,7 +303,7 @@ impl PageTable { tracing::trace!(next.addr = ?vaddr, "found next table virtual address"); // XXX(eliza): this _probably_ could be be a `new_unchecked`...if, after // all this, the next table address is null...we're probably pretty fucked! - Some(unsafe { &*NonNull::new(vaddr.as_ptr())?.as_ptr() }) + Some(unsafe { vaddr.as_non_null()?.as_ref() }) } #[inline] @@ -336,7 +336,7 @@ impl PageTable { tracing::trace!(next.addr = ?vaddr, "found next table virtual address"); // XXX(eliza): this _probably_ could be be a `new_unchecked`...if, after // all this, the next table address is null...we're probably pretty fucked! - Some(unsafe { &mut *NonNull::new(vaddr.as_ptr())?.as_ptr() }) + Some(unsafe { vaddr.as_non_null()?.as_mut() }) } fn create_next_table( @@ -587,7 +587,7 @@ impl page::PageFlags for Entry { impl fmt::Debug for Entry { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { struct FmtFlags<'a, L>(&'a Entry); - impl<'a, L> fmt::Debug for FmtFlags<'a, L> { + impl fmt::Debug for FmtFlags<'_, L> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { macro_rules! write_flags { @@ -893,7 +893,7 @@ mycotest::decl_test! { }; tracing::info!(?page, "page mapped!"); - let page_ptr = page.base_addr().as_ptr::(); + let page_ptr = page.base_addr().as_mut_ptr::(); unsafe { page_ptr.offset(400).write_volatile(0x_f021_f077_f065_f04e)}; tracing::info!("wow, it didn't fault"); diff --git a/hal-x86_64/src/segment.rs b/hal-x86_64/src/segment.rs index a422d8eb..d0c77209 100644 --- a/hal-x86_64/src/segment.rs +++ b/hal-x86_64/src/segment.rs @@ -396,6 +396,12 @@ impl Gdt { } } +impl Default for Gdt { + fn default() -> Self { + Self::new() + } +} + impl fmt::Debug for Gdt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { struct GdtEntries<'a, const SIZE: usize>(&'a Gdt); diff --git a/hal-x86_64/src/serial.rs b/hal-x86_64/src/serial.rs index f1900f94..3a193c1b 100644 --- a/hal-x86_64/src/serial.rs +++ b/hal-x86_64/src/serial.rs @@ -274,7 +274,7 @@ impl Lock<'_, B> { } let divisor = Port::MAX_BAUD_RATE / baud; - if divisor > (core::u16::MAX as usize) { + if divisor > (u16::MAX as usize) { return Err(io::Error::new( io::ErrorKind::InvalidInput, "divisor for target baud rate is too high!", diff --git a/hal-x86_64/src/task.rs b/hal-x86_64/src/task.rs index f4b10959..27c5cf30 100644 --- a/hal-x86_64/src/task.rs +++ b/hal-x86_64/src/task.rs @@ -37,7 +37,7 @@ impl StateSegment { /// Returns the virtual address of the I/O permission bitmap. #[inline] pub fn iomap_addr(&self) -> VAddr { - VAddr::of(self).offset(self.iomap_offset as i32) + VAddr::of(self).offset(self.iomap_offset as isize) } /// Loads the provided [`selector`](segment::Selector) into the current task diff --git a/inoculate/src/qemu.rs b/inoculate/src/qemu.rs index 658aed78..0fe9ca70 100644 --- a/inoculate/src/qemu.rs +++ b/inoculate/src/qemu.rs @@ -31,9 +31,15 @@ pub enum Cmd { Test { /// Timeout for failing test run, in seconds. /// - /// If a test run doesn't complete before this timeout has elapsed, it's - /// considered to have failed. - #[clap(long, value_parser = parse_secs, default_value = "60")] + /// If a test run doesn't complete before this timeout has elapsed, the + /// QEMU VM is killed and the test run is assumed to have failed. + /// + /// Note that this timeout applies to the entire test run, including + /// booting the kernel and running the whole kernel test suite, rather + /// than to each individual test. + /// + /// By default, this is 20 minutes (1200 seconds). + #[clap(long, value_parser = parse_secs, default_value = "1200")] timeout_secs: Duration, /// Disables capturing test serial output. @@ -78,12 +84,7 @@ struct TestResults { impl Cmd { fn should_capture(&self) -> bool { match self { - Cmd::Test { - nocapture: true, .. - } => { - tracing::debug!("running tests with `--nocapture`, will not capture."); - false - } + Cmd::Test { .. } => true, Cmd::Run { serial: true, .. } => { tracing::debug!("running normally with `--serial`, will not capture"); false @@ -184,6 +185,7 @@ impl Cmd { } Cmd::Test { + nocapture, qemu_settings, timeout_secs, .. @@ -198,16 +200,21 @@ impl Cmd { "none", "-serial", "stdio", + // tell QEMU to log guest errors + "-d", + "guest_errors", ]; tracing::info!("running kernel tests ({})", paths.relative(image).display()); qemu_settings.configure(&mut qemu); + + tracing::info!(qemu.test_args = ?TEST_ARGS, "using test mode qemu args"); qemu.args(TEST_ARGS); + let nocapture = *nocapture; let mut child = self.spawn_qemu(&mut qemu, paths.kernel_bin())?; - let stdout = child - .stdout - .take() - .map(|stdout| std::thread::spawn(move || TestResults::watch_tests(stdout))); + let stdout = child.stdout.take().map(|stdout| { + std::thread::spawn(move || TestResults::watch_tests(stdout, nocapture)) + }); let res = match child .wait_timeout(*timeout_secs) @@ -293,7 +300,7 @@ fn parse_secs(s: &str) -> Result { } impl TestResults { - fn watch_tests(output: impl std::io::Read) -> Result { + fn watch_tests(output: impl std::io::Read, nocapture: bool) -> Result { use std::io::{BufRead, BufReader}; let mut results = Self { tests: 0, @@ -358,8 +365,11 @@ impl TestResults { .note(format!("line: {line:?}")); } } - - curr_output.push(line); + if nocapture { + println!("{line}") + } else { + curr_output.push(line); + } } match curr_outcome { @@ -380,7 +390,9 @@ impl TestResults { } None => { tracing::info!("qemu exited unexpectedly! wtf!"); - curr_output.push("".to_string()); + if !nocapture { + curr_output.push("".to_string()); + } eprintln!(" {}", "exit!".style(red)); results.failed.insert(test.to_static(), curr_output); break; diff --git a/maitake-sync/src/lib.rs b/maitake-sync/src/lib.rs index 6354efbb..eb2127e8 100644 --- a/maitake-sync/src/lib.rs +++ b/maitake-sync/src/lib.rs @@ -2,7 +2,6 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))] #![cfg_attr(docsrs, doc(cfg_hide(docsrs, loom)))] #![cfg_attr(not(any(test, feature = "std")), no_std)] -#![cfg_attr(feature = "core-error", feature(error_in_core))] #![warn(missing_docs, missing_debug_implementations)] #[cfg(any(feature = "alloc", test))] diff --git a/maitake-sync/src/mutex.rs b/maitake-sync/src/mutex.rs index 2edd86fe..af71c6e0 100644 --- a/maitake-sync/src/mutex.rs +++ b/maitake-sync/src/mutex.rs @@ -94,7 +94,6 @@ mod tests; // for some reason, intra-doc links don't work in footnotes? /// [storage]: https://mycelium.elizas.website/maitake/task/trait.Storage.html /// [no-unwinding]: https://mycelium.elizas.website/maitake/index.html#maitake-does-not-support-unwinding - pub struct Mutex { wait: WaitQueue, data: UnsafeCell, diff --git a/maitake-sync/src/util.rs b/maitake-sync/src/util.rs index bb15dc3a..0e4b5a08 100644 --- a/maitake-sync/src/util.rs +++ b/maitake-sync/src/util.rs @@ -217,7 +217,6 @@ pub(crate) mod test { /// /// Returns a [TestGuard] that must be held for the duration of test to ensure /// tracing messages are correctly output - #[cfg(all(test, not(loom)))] pub(crate) fn trace_init() -> TestGuard { trace_init_with_default("maitake=debug,cordyceps=debug") diff --git a/maitake-sync/src/util/maybe_uninit.rs b/maitake-sync/src/util/maybe_uninit.rs index 1b2ebf66..d7ac8295 100644 --- a/maitake-sync/src/util/maybe_uninit.rs +++ b/maitake-sync/src/util/maybe_uninit.rs @@ -365,7 +365,6 @@ impl CheckedMaybeUninit { /// foo.assume_init() /// }; /// ``` - #[inline(always)] #[track_caller] pub unsafe fn assume_init_mut(&mut self) -> &mut T { diff --git a/maitake-sync/src/wait_cell.rs b/maitake-sync/src/wait_cell.rs index 8cb85bdd..02366ff3 100644 --- a/maitake-sync/src/wait_cell.rs +++ b/maitake-sync/src/wait_cell.rs @@ -103,6 +103,12 @@ impl WaitCell { } } +impl Default for WaitCell { + fn default() -> Self { + Self::new() + } +} + impl WaitCell { /// Poll to wait on this `WaitCell`, consuming a stored wakeup or /// registering the [`Waker`] from the provided [`Context`] to be woken by diff --git a/maitake-sync/src/wait_map.rs b/maitake-sync/src/wait_map.rs index 07bddaf2..e150cdb0 100644 --- a/maitake-sync/src/wait_map.rs +++ b/maitake-sync/src/wait_map.rs @@ -465,6 +465,16 @@ impl WaitMap { } } +impl Default for WaitMap +where + K: PartialEq, + Lock: ScopedRawMutex + Default, +{ + fn default() -> Self { + Self::new_with_raw_mutex(Lock::default()) + } +} + impl WaitMap where K: PartialEq, @@ -725,7 +735,7 @@ where wait: Pin<&'a mut Wait<'b, K, V, Lock>>, } -impl<'a, 'b, K, V, Lock> Future for Subscribe<'a, 'b, K, V, Lock> +impl Future for Subscribe<'_, '_, K, V, Lock> where K: PartialEq, Lock: ScopedRawMutex, diff --git a/maitake-sync/src/wait_queue.rs b/maitake-sync/src/wait_queue.rs index e7459f55..24c1e051 100644 --- a/maitake-sync/src/wait_queue.rs +++ b/maitake-sync/src/wait_queue.rs @@ -379,6 +379,15 @@ impl WaitQueue { } } +impl Default for WaitQueue +where + Lock: ScopedRawMutex + Default, +{ + fn default() -> Self { + Self::new_with_raw_mutex(Lock::default()) + } +} + impl WaitQueue where Lock: ScopedRawMutex, diff --git a/maitake/src/lib.rs b/maitake/src/lib.rs index f5223eb0..cd6fc39a 100644 --- a/maitake/src/lib.rs +++ b/maitake/src/lib.rs @@ -2,7 +2,6 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))] #![cfg_attr(docsrs, doc(cfg_hide(docsrs, loom)))] #![cfg_attr(not(test), no_std)] -#![cfg_attr(feature = "core-error", feature(error_in_core))] #![allow(unused_unsafe)] #[cfg(feature = "alloc")] diff --git a/maitake/src/scheduler.rs b/maitake/src/scheduler.rs index 139268b1..ffcab4c0 100644 --- a/maitake/src/scheduler.rs +++ b/maitake/src/scheduler.rs @@ -528,6 +528,9 @@ struct Core { impl TaskStub { loom_const_fn! { /// Create a new unique stub [`Task`]. + // Thee whole point of this thing is to be const-initialized, so a + // non-const-fn `Default` impl is basically useless. + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { hdr: Header::new_static_stub(), diff --git a/maitake/src/task/builder.rs b/maitake/src/task/builder.rs index 84854bf1..e074f96c 100644 --- a/maitake/src/task/builder.rs +++ b/maitake/src/task/builder.rs @@ -246,7 +246,7 @@ feature! { // === impl Settings === -impl<'a> Settings<'a> { +impl Settings<'_> { /// Returns a new, empty task builder with no settings configured. #[must_use] pub(crate) const fn new() -> Self { diff --git a/maitake/src/task/state.rs b/maitake/src/task/state.rs index c4fac972..46d5841c 100644 --- a/maitake/src/task/state.rs +++ b/maitake/src/task/state.rs @@ -561,6 +561,7 @@ impl mycelium_bitfield::FromBits for JoinWakerState { const BITS: u32 = 2; #[inline] + #[allow(clippy::literal_string_with_formatting_args)] fn try_from_bits(bits: usize) -> Result { match bits { b if b == Self::Registering as usize => Ok(Self::Registering), @@ -590,7 +591,7 @@ mod tests { fn packing_specs_valid() { State::assert_valid() } - + #[test] // No sense spending time running these trivial tests under Miri... #[cfg_attr(miri, ignore)] diff --git a/maitake/src/task/tests/alloc_tests.rs b/maitake/src/task/tests/alloc_tests.rs index d01447e7..08082f72 100644 --- a/maitake/src/task/tests/alloc_tests.rs +++ b/maitake/src/task/tests/alloc_tests.rs @@ -11,9 +11,7 @@ use tokio_test::{assert_pending, assert_ready_err, assert_ready_ok}; /// vtable methods are valid. #[test] fn task_is_valid_for_casts() { - let task = Box::new(Task::::new(async { - unimplemented!("this task should never be polled") - })); + let task = Box::new(Task::::new(async {})); let task_ptr = Box::into_raw(task); diff --git a/maitake/src/time.rs b/maitake/src/time.rs index 80c1f5f7..688366fc 100644 --- a/maitake/src/time.rs +++ b/maitake/src/time.rs @@ -90,7 +90,6 @@ use core::future::Future; /// [global]: #global-timers /// [max]: Timer::max_duration #[track_caller] - pub fn sleep(duration: Duration) -> Sleep<'static> { util::expect_display(try_sleep(duration), "cannot create `Sleep` future") } @@ -105,7 +104,7 @@ pub fn sleep(duration: Duration) -> Sleep<'static> { /// # Returns /// /// - [`Ok`]`(`[`Sleep`]`)` if a new [`Sleep`] future was created -/// successfully. +/// successfully. /// - [`Err`]`(`[`TimerError::NoGlobalTimer`]`)` if a [global timer][global] was /// not set by calling [`set_global_timer`] first. /// - [`Err`]`(`[`TimerError::DurationTooLong`]`)` if the requested sleep diff --git a/maitake/src/time/timer/tests.rs b/maitake/src/time/timer/tests.rs index 5f2c1e00..d9861a4b 100644 --- a/maitake/src/time/timer/tests.rs +++ b/maitake/src/time/timer/tests.rs @@ -9,6 +9,9 @@ use crate::time::{timer::Ticks, Clock}; use std::time::Duration; crate::loom::thread_local! { + // Clippy doesn't realize that this might be a loom simulated thread local, + // which doessn't accept const initializers... + #[allow(clippy::missing_const_for_thread_local)] static CLOCK: RefCell>> = RefCell::new(None); } diff --git a/mycotest/src/lib.rs b/mycotest/src/lib.rs index 0f14dccc..4b782909 100644 --- a/mycotest/src/lib.rs +++ b/mycotest/src/lib.rs @@ -91,7 +91,7 @@ macro_rules! decl_test { // === impl TestName === -impl<'a, S> TestName<'a, S> { +impl TestName<'_, S> { pub const fn new(module: S, name: S) -> Self { Self { name, @@ -101,7 +101,7 @@ impl<'a, S> TestName<'a, S> { } } -impl<'a, S> TestName<'a, S> +impl TestName<'_, S> where S: AsRef, { diff --git a/pci/Cargo.toml b/pci/Cargo.toml index d2335b3d..3d010f17 100644 --- a/pci/Cargo.toml +++ b/pci/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" keywords = ["no_std", "pci", "pcie"] categories = ["no-std",] edition = "2021" -rust-version = "1.61.0" +rust-version = "1.62.0" [dependencies] mycelium-util = { path = "../util" } diff --git a/pci/src/addr.rs b/pci/src/addr.rs index 4de542f4..77b6f4e0 100644 --- a/pci/src/addr.rs +++ b/pci/src/addr.rs @@ -109,6 +109,12 @@ impl Address { } } +impl Default for Address { + fn default() -> Self { + Self::new() + } +} + impl fmt::Display for Address { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(self, f) diff --git a/pci/src/express.rs b/pci/src/express.rs index 376013fb..7ac8fd42 100644 --- a/pci/src/express.rs +++ b/pci/src/express.rs @@ -17,7 +17,7 @@ enum MmKind<'device> { PciBridge(Volatile<&'device mut PciBridgeDetails>), } -impl<'device> MemoryMappedDevice<'device> { +impl MemoryMappedDevice<'_> { pub fn header(&self) -> device::Header { self.header.read() } diff --git a/src/allocator.rs b/src/allocator.rs index 1af7221d..9d85a9de 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -84,6 +84,12 @@ impl Allocator { } } +impl Default for Allocator { + fn default() -> Self { + Self::new() + } +} + unsafe impl GlobalAlloc for Allocator { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/src/arch/x86_64/acpi.rs b/src/arch/x86_64/acpi.rs index 70042fcf..c5e9df64 100644 --- a/src/arch/x86_64/acpi.rs +++ b/src/arch/x86_64/acpi.rs @@ -1,5 +1,5 @@ use acpi::{AcpiError, AcpiHandler, AcpiTables}; -use core::{fmt, ptr::NonNull}; +use core::fmt; use hal_core::{Address, PAddr}; use hal_x86_64::mm; @@ -74,8 +74,9 @@ impl AcpiHandler for IdentityMappedAcpiHandler { ) -> acpi::PhysicalMapping { let paddr = PAddr::from_u64(physical_address as u64); let vaddr = mm::kernel_vaddr_of(paddr); - let vptr = - NonNull::new(vaddr.as_ptr()).expect("virtual address for ACPI region is not null"); + let vptr = vaddr + .as_non_null() + .expect("virtual address for ACPI region is not null"); // we have identity mapped all physical memory, so we don't actually // have to map any pages --- just tell the ACPI crate that it can use // this region. diff --git a/src/arch/x86_64/interrupt.rs b/src/arch/x86_64/interrupt.rs index 6fedeb2f..9676603b 100644 --- a/src/arch/x86_64/interrupt.rs +++ b/src/arch/x86_64/interrupt.rs @@ -45,11 +45,9 @@ static mut DOUBLE_FAULT_STACK: [StackFrame; DOUBLE_FAULT_STACK_SIZE] = static TSS: sync::Lazy = sync::Lazy::new(|| { tracing::trace!("initializing TSS.."); let mut tss = task::StateSegment::empty(); - tss.interrupt_stacks[Idt::DOUBLE_FAULT_IST_OFFSET] = unsafe { - // safety: asdf - VAddr::from_usize_unchecked(core::ptr::addr_of!(DOUBLE_FAULT_STACK) as usize) - .offset(DOUBLE_FAULT_STACK_SIZE as i32) - }; + tss.interrupt_stacks[Idt::DOUBLE_FAULT_IST_OFFSET] = + VAddr::from_ptr(core::ptr::addr_of!(DOUBLE_FAULT_STACK)) + .offset(DOUBLE_FAULT_STACK_SIZE as isize); tracing::debug!(?tss, "TSS initialized"); tss }); diff --git a/src/arch/x86_64/oops.rs b/src/arch/x86_64/oops.rs index 825b00f4..49976079 100644 --- a/src/arch/x86_64/oops.rs +++ b/src/arch/x86_64/oops.rs @@ -312,7 +312,7 @@ impl<'a> From<&'a PanicInfo<'a>> for Oops<'a> { // === impl OopsSituation === -impl<'a> OopsSituation<'a> { +impl OopsSituation<'_> { fn header(&self) -> &'static str { match self { Self::Fault { .. } => " OOPSIE-WOOPSIE! ", diff --git a/src/shell.rs b/src/shell.rs index 286bc814..30299b39 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -634,7 +634,7 @@ impl<'cmd> Context<'cmd> { T::Err: core::fmt::Display, { self.parse_optional_flag(names).and_then(|val| { - val.ok_or_else(|| Error { + val.ok_or(Error { line: self.line, kind: ErrorKind::FlagRequired { flags: names }, }) diff --git a/trace/src/color.rs b/trace/src/color.rs index 6f0a0c01..e8acb25a 100644 --- a/trace/src/color.rs +++ b/trace/src/color.rs @@ -96,7 +96,7 @@ impl SetColor for &'_ mut W { // === impl WithFgColor === -impl<'writer, W> fmt::Write for WithFgColor<'writer, W> +impl fmt::Write for WithFgColor<'_, W> where W: fmt::Write + SetColor, { @@ -116,7 +116,7 @@ where } } -impl<'writer, W> Drop for WithFgColor<'writer, W> +impl Drop for WithFgColor<'_, W> where W: fmt::Write + SetColor, { @@ -127,7 +127,7 @@ where // === impl WithBold === -impl<'writer, W> fmt::Write for WithBold<'writer, W> +impl fmt::Write for WithBold<'_, W> where W: fmt::Write + SetColor, { @@ -147,7 +147,7 @@ where } } -impl<'writer, W> Drop for WithBold<'writer, W> +impl Drop for WithBold<'_, W> where W: fmt::Write + SetColor, { diff --git a/trace/src/embedded_graphics.rs b/trace/src/embedded_graphics.rs index 09c0cb67..04e00111 100644 --- a/trace/src/embedded_graphics.rs +++ b/trace/src/embedded_graphics.rs @@ -35,7 +35,7 @@ pub struct TextWriter<'mk, D> { } const fn pack_point(Point { x, y }: Point) -> u64 { - (x as u64) << 32 | y as u64 + ((x as u64) << 32) | y as u64 } const fn unpack_point(u: u64) -> Point { @@ -140,7 +140,7 @@ where } } -impl<'mk, D> SetColor for TextWriter<'mk, D> +impl SetColor for TextWriter<'_, D> where D: Draw, { @@ -188,7 +188,7 @@ where } } -impl<'mk, D> TextWriter<'mk, D> +impl TextWriter<'_, D> where D: Draw, { diff --git a/trace/src/lib.rs b/trace/src/lib.rs index ff9968bc..bc1b21aa 100644 --- a/trace/src/lib.rs +++ b/trace/src/lib.rs @@ -285,7 +285,7 @@ impl Output { // === impl WriterPair === -impl<'a, D, S> SetColor for WriterPair<'a, D, S> +impl SetColor for WriterPair<'_, D, S> where D: Write + SetColor, S: Write + SetColor, @@ -317,7 +317,7 @@ where } } -impl<'a, D, S> Write for WriterPair<'a, D, S> +impl Write for WriterPair<'_, D, S> where D: Write, S: Write, @@ -347,7 +347,7 @@ where } } -impl<'a, D, S> WriterPair<'a, D, S> +impl WriterPair<'_, D, S> where D: Write, S: Write, @@ -371,7 +371,7 @@ where // ==== impl Writer === -impl<'a, W: Write> Writer<'a, W> { +impl Writer<'_, W> { fn indent(&mut self, kind: IndentKind) -> fmt::Result { let indent = self.cfg.indent.load(Ordering::Acquire); self.write_indent(" ")?; @@ -409,7 +409,7 @@ impl<'a, W: Write> Writer<'a, W> { } } -impl<'a, W> Write for Writer<'a, W> +impl Write for Writer<'_, W> where W: Write, { @@ -456,7 +456,7 @@ where } } -impl<'a, W> SetColor for Writer<'a, W> +impl SetColor for Writer<'_, W> where W: Write + SetColor, { @@ -473,7 +473,7 @@ where } } -impl<'a, W: Write> Drop for Writer<'a, W> { +impl Drop for Writer<'_, W> { fn drop(&mut self) { let _ = self.finish(); } @@ -539,7 +539,7 @@ where has_written_punct: bool, } - impl<'a, W: fmt::Write> fmt::Write for HasWrittenNewline<'a, W> { + impl fmt::Write for HasWrittenNewline<'_, W> { #[inline] fn write_str(&mut self, s: &str) -> fmt::Result { self.has_written_punct = s.ends_with(|ch: char| ch.is_ascii_punctuation()); @@ -550,7 +550,7 @@ where } } - impl<'a, W: fmt::Write> SetColor for HasWrittenNewline<'a, W> + impl SetColor for HasWrittenNewline<'_, W> where W: SetColor, { diff --git a/trace/src/writer.rs b/trace/src/writer.rs index 7203e02e..c6471e83 100644 --- a/trace/src/writer.rs +++ b/trace/src/writer.rs @@ -396,7 +396,7 @@ where } } -impl<'a, W, Lock> fmt::Write for MutexGuardWriter<'a, W, Lock> +impl fmt::Write for MutexGuardWriter<'_, W, Lock> where W: fmt::Write, Lock: RawMutex, diff --git a/util/src/fmt.rs b/util/src/fmt.rs index c0bba460..9a535eec 100644 --- a/util/src/fmt.rs +++ b/util/src/fmt.rs @@ -272,7 +272,7 @@ where } } -impl<'a, W: Write> Write for WithIndent<'a, W> { +impl Write for WithIndent<'_, W> { fn write_str(&mut self, mut s: &str) -> Result { while !s.is_empty() { let (split, nl) = match s.find('\n') { diff --git a/util/src/io.rs b/util/src/io.rs index 312f353c..d65417c7 100644 --- a/util/src/io.rs +++ b/util/src/io.rs @@ -641,7 +641,6 @@ pub trait BufRead: Read { /// Each line of the iterator has the same error semantics as [`BufRead::read_line`]. /// /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line - #[cfg(feature = "alloc")] fn lines(self) -> Lines where diff --git a/util/src/io/error.rs b/util/src/io/error.rs index 7f0e44d0..8457eadf 100644 --- a/util/src/io/error.rs +++ b/util/src/io/error.rs @@ -18,7 +18,6 @@ use core::fmt; /// [`io::Error`]: Error /// [`Result`]: core::result::Result /// [prelude]: core::prelude - pub type Result = core::result::Result; /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and diff --git a/util/src/io/util.rs b/util/src/io/util.rs index a15e5ea9..210f7883 100644 --- a/util/src/io/util.rs +++ b/util/src/io/util.rs @@ -15,10 +15,10 @@ use core::{fmt, mem::MaybeUninit}; /// This function will return an error immediately if any call to `read` or /// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// handled by this function and the underlying operation is retried. -pub fn copy(reader: &mut R, writer: &mut W) -> io::Result +pub fn copy(reader: &mut R, writer: &mut W) -> io::Result where - R: Read, - W: Write, + R: ?Sized + Read, + W: ?Sized + Write, { let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit(); // FIXME(eliza): the stdlib has a scary comment that says we haven't decided diff --git a/util/src/macros.rs b/util/src/macros.rs index a416d91c..6d450e60 100644 --- a/util/src/macros.rs +++ b/util/src/macros.rs @@ -34,6 +34,7 @@ macro_rules! unreachable_unchecked { }); ($fmt:expr, $($arg:tt)*) => ({ #[cfg(any(test, debug_assertions))] + #[allow(clippy::literal_string_with_formatting_args)] panic!( concat!( "internal error: entered unreachable code: ", diff --git a/util/src/mem/maybe_uninit.rs b/util/src/mem/maybe_uninit.rs index 1b2ebf66..d7ac8295 100644 --- a/util/src/mem/maybe_uninit.rs +++ b/util/src/mem/maybe_uninit.rs @@ -365,7 +365,6 @@ impl CheckedMaybeUninit { /// foo.assume_init() /// }; /// ``` - #[inline(always)] #[track_caller] pub unsafe fn assume_init_mut(&mut self) -> &mut T {