Skip to content

Commit 36e9396

Browse files
gating behind version 1.83.0
1 parent 54c00aa commit 36e9396

File tree

5 files changed

+82
-24
lines changed

5 files changed

+82
-24
lines changed

Diff for: init/Kconfig

+3
Original file line numberDiff line numberDiff line change
@@ -1964,6 +1964,9 @@ config RUST
19641964

19651965
If unsure, say N.
19661966

1967+
config RUST_COERCE_POINTEE
1968+
def_bool y if RUSTC_VERSION >= 108300
1969+
19671970
config RUSTC_VERSION_TEXT
19681971
string
19691972
depends on RUST

Diff for: rust/kernel/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
1414
#![no_std]
1515
#![feature(arbitrary_self_types)]
16-
#![feature(coerce_unsized)]
17-
#![feature(derive_coerce_pointee, pin_coerce_unsized_trait)]
16+
#![cfg_attr(
17+
CONFIG_RUST_COERCE_POINTEE,
18+
feature(derive_coerce_pointee, pin_coerce_unsized_trait)
19+
)]
20+
#![cfg_attr(not(CONFIG_RUST_COERCE_POINTEE), feature(coerce_unsized, unsize))]
1821
#![feature(inline_const)]
1922
#![feature(lint_reasons)]
20-
#![feature(unsize)]
2123

2224
// Ensure conditional compilation based on the kernel configuration works;
2325
// otherwise we may silently break things like initcall handling.

Diff for: rust/kernel/list/arc.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
use crate::alloc::{AllocError, Flags};
88
use crate::prelude::*;
99
use crate::sync::{Arc, ArcBorrow, UniqueArc};
10-
use core::marker::CoercePointee;
1110
use core::marker::PhantomPinned;
1211
use core::ops::Deref;
13-
use core::pin::{Pin, PinCoerceUnsized};
12+
use core::pin::Pin;
1413
use core::sync::atomic::{AtomicBool, Ordering};
1514

1615
/// Declares that this type has some way to ensure that there is exactly one `ListArc` instance for
@@ -160,7 +159,7 @@ pub use impl_list_arc_safe;
160159
///
161160
/// [`List`]: crate::list::List
162161
#[repr(transparent)]
163-
#[derive(CoercePointee)]
162+
#[cfg_attr(CONFIG_RUST_COERCE_POINTEE, derive(core::marker::CoercePointee))]
164163
pub struct ListArc<T, const ID: u64 = 0>
165164
where
166165
T: ListArcSafe<ID> + ?Sized,
@@ -443,8 +442,32 @@ where
443442
}
444443
}
445444

445+
// This is to allow coercion from `ListArc<T>` to `ListArc<U>` if `T` can be converted to the
446+
// dynamically-sized type (DST) `U`.
447+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
448+
impl<T, U, const ID: u64> core::ops::CoerceUnsized<ListArc<U, ID>> for ListArc<T, ID>
449+
where
450+
T: ListArcSafe<ID> + Unsize<U> + ?Sized,
451+
U: ListArcSafe<ID> + ?Sized,
452+
{
453+
}
454+
455+
// This is to allow `ListArc<U>` to be dispatched on when `ListArc<T>` can be coerced into
456+
// `ListArc<U>`.
457+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
458+
impl<T, U, const ID: u64> core::ops::DispatchFromDyn<ListArc<U, ID>> for ListArc<T, ID>
459+
where
460+
T: ListArcSafe<ID> + Unsize<U> + ?Sized,
461+
U: ListArcSafe<ID> + ?Sized,
462+
{
463+
}
464+
446465
/// `ListArc` is well-behaved so that its dereferencing operation does not mutate.
447-
unsafe impl<T: ?Sized + ListArcSafe<ID>, const ID: u64> PinCoerceUnsized for ListArc<T, ID> {}
466+
#[cfg(CONFIG_RUST_COERCE_POINTEE)]
467+
unsafe impl<T: ?Sized + ListArcSafe<ID>, const ID: u64> core::pin::PinCoerceUnsized
468+
for ListArc<T, ID>
469+
{
470+
}
448471

449472
/// A utility for tracking whether a [`ListArc`] exists using an atomic.
450473
///

Diff for: rust/kernel/sync/arc.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ use crate::{
2323
try_init,
2424
types::{ForeignOwnable, Opaque},
2525
};
26+
#[cfg(CONFIG_RUST_COERCE_POINTEE)]
27+
use core::marker::CoercePointee;
28+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
29+
use core::marker::Unsize;
2630
use core::{
2731
alloc::Layout,
2832
fmt,
29-
marker::{CoercePointee, PhantomData},
33+
marker::PhantomData,
3034
mem::{ManuallyDrop, MaybeUninit},
3135
ops::{Deref, DerefMut},
3236
pin::Pin,
@@ -125,8 +129,8 @@ mod std_vendor;
125129
/// let coerced: Arc<dyn MyTrait> = obj;
126130
/// # Ok::<(), Error>(())
127131
/// ```
128-
#[repr(transparent)]
129-
#[derive(CoercePointee)]
132+
#[cfg_attr(CONFIG_RUST_COERCE_POINTEE, repr(transparent))]
133+
#[cfg_attr(CONFIG_RUST_COERCE_POINTEE, derive(CoercePointee))]
130134
pub struct Arc<T: ?Sized> {
131135
ptr: NonNull<ArcInner<T>>,
132136
_p: PhantomData<ArcInner<T>>,
@@ -172,6 +176,15 @@ impl<T: ?Sized> ArcInner<T> {
172176
}
173177
}
174178

179+
// This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the
180+
// dynamically-sized type (DST) `U`.
181+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
182+
impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {}
183+
184+
// This is to allow `Arc<U>` to be dispatched on when `Arc<T>` can be coerced into `Arc<U>`.
185+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
186+
impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<Arc<U>> for Arc<T> {}
187+
175188
// SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because
176189
// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
177190
// `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` using a
@@ -466,13 +479,21 @@ impl<T: ?Sized> From<Pin<UniqueArc<T>>> for Arc<T> {
466479
/// obj.as_arc_borrow().use_reference();
467480
/// # Ok::<(), Error>(())
468481
/// ```
469-
#[repr(transparent)]
470-
#[derive(CoercePointee)]
482+
#[cfg_attr(CONFIG_RUST_COERCE_POINTEE, repr(transparent))]
483+
#[cfg_attr(CONFIG_RUST_COERCE_POINTEE, derive(CoercePointee))]
471484
pub struct ArcBorrow<'a, T: ?Sized + 'a> {
472485
inner: NonNull<ArcInner<T>>,
473486
_p: PhantomData<&'a ()>,
474487
}
475488

489+
// This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into
490+
// `ArcBorrow<U>`.
491+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
492+
impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>>
493+
for ArcBorrow<'_, T>
494+
{
495+
}
496+
476497
impl<T: ?Sized> Clone for ArcBorrow<'_, T> {
477498
fn clone(&self) -> Self {
478499
*self

Diff for: samples/rust/rust_print.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,34 @@ fn arc_print() -> Result {
3434
// Uses `dbg` to print, will move `c` (for temporary debugging purposes).
3535
dbg!(c);
3636

37-
// `Arc` can be used to delegate dynamic dispatch and the following is an example.
38-
// Both `i32` and `&str` implements `Display`.
39-
// This enables us to express a unified behaviour, contract or protocol on both `i32` and `&str`
40-
// in a single `Arc` type `Arc<dyn Display>`.
41-
let a_i32_display: Arc<dyn Display> = Arc::new(42i32, GFP_KERNEL)?;
42-
let a_str_display: Arc<dyn Display> = a.clone();
43-
arc_dyn_print(&a_i32_display);
44-
arc_dyn_print(&a_str_display);
37+
#[cfg(CONFIG_RUST_COERCE_POINTEE)]
38+
{
39+
use core::fmt::Display;
40+
fn arc_dyn_print(arc: &Arc<dyn Display>) {
41+
pr_info!("Arc<dyn Display> says {arc}");
42+
}
43+
// `Arc` can be used to delegate dynamic dispatch and the following is an example.
44+
// Both `i32` and `&str` implements `Display`.
45+
// This enables us to express a unified behaviour, contract or protocol on both `i32` and `&str`
46+
// in a single `Arc` type `Arc<dyn Display>`.
47+
let a_i32_display: Arc<dyn Display> = Arc::new(42i32, GFP_KERNEL)?;
48+
let a_str_display: Arc<dyn Display> = a.clone();
49+
arc_dyn_print(&a_i32_display);
50+
arc_dyn_print(&a_str_display);
51+
}
52+
53+
#[cfg(not(CONFIG_RUST_COERCE_POINTEE))]
54+
pr_info!(
55+
"The demonstration for dynamic dispatching through Arc is skipped. "
56+
"To see the print-out from this example, please upgrade your Rust compiler to 1.83.0 or higher.\n"
57+
);
4558

4659
// Pretty-prints the debug formatting with lower-case hexadecimal integers.
4760
pr_info!("{:#x?}", a);
4861

4962
Ok(())
5063
}
5164

52-
fn arc_dyn_print(arc: &Arc<dyn Display>) {
53-
pr_info!("Arc<dyn Display> says {arc}");
54-
}
55-
5665
impl kernel::Module for RustPrint {
5766
fn init(_module: &'static ThisModule) -> Result<Self> {
5867
pr_info!("Rust printing macros sample (init)\n");

0 commit comments

Comments
 (0)