Skip to content

Commit

Permalink
Add a macro that simplifies transitioning to the Rust intrinsic ABI
Browse files Browse the repository at this point in the history
Migrating intrinsics at this time seems to come with a lot of
boilerplate in the form of attributes and empty bodies (see
<rust-lang#127337> for an example). Add a
macro that simplifies this, and makes the transition from `extern
"rust-intrinsic"` intrinsics much cleaner.
  • Loading branch information
tgross35 committed Jul 17, 2024
1 parent f00f850 commit 24e6ba0
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,93 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
unsafe { crate::ptr::drop_in_place(to_drop) }
}

/// Turn function signatures into an intrinsic implementation in the Rust ABI, with an
/// `unimplemented!` body.
///
/// This applies an `unstable` attribute, so don't use it with functions that are stable.
/// Due to macro limitations, functions with keyword qualifiers `const` or `unsafe` cannot be
/// combined with functions that do not have them, or have a different combination, and as such
/// must be placed in separate `intrinsics!` blocks.
///
/// Const intrinsics do not get `rustc_const_{stable, unstable}`.
macro_rules! intrinsics {
// Default: non-const, safe
( $(
$(#[$meta:meta])*
pub fn $name:ident
$(<$( $gen:ident $(: $bound:ident $(+ $bound2:ident)* $(+ $bound_lt:lifetime)*)? ),* >)?
($($args:tt)*) $(-> $ret:ty)?;

)* ) => { $(
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[unstable(feature = "core_intrinsics", issue = "none")]
$(#[$meta])*
pub fn $name $(<$( $gen $(: $bound $(+ $bound2)* $(+ $bound_lt)*)? ),* >)?
($($args)*) $(-> $ret)? {
unreachable!();
}
)+ };

// non-const, unsafe
( $(
$(#[$meta:meta])*
pub unsafe fn $name:ident
$(<$( $gen:ident $(: $bound:ident $(+ $bound2:ident)* $(+ $bound_lt:lifetime)*)? ),* >)?
($($args:tt)*) $(-> $ret:ty)?;

)* ) => { $(
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[unstable(feature = "core_intrinsics", issue = "none")]
$(#[$meta])*
pub unsafe fn $name $(<$( $gen $(: $bound $(+ $bound2)* $(+ $bound_lt)*)? ),* >)?
($($args)*) $(-> $ret)? {
unreachable!();
}
)+ };

// const, safe
( $(
$(#[$meta:meta])*
pub const fn $name:ident
$(<$( $gen:ident $(: $bound:ident $(+ $bound2:ident)* $(+ $bound_lt:lifetime)*)? ),* >)?
($($args:tt)*) $(-> $ret:ty)?;

)* ) => { $(
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[unstable(feature = "core_intrinsics", issue = "none")]
$(#[$meta])*
pub const fn $name $(<$( $gen $(: $bound $(+ $bound2)* $(+ $bound_lt)*)? ),* >)?
($($args)*) $(-> $ret)? {
unreachable!();
}
)+ };

// const, unsafe
( $(
$(#[$meta:meta])*
pub const unsafe fn $name:ident
$(<$( $gen:ident $(: $bound:ident $(+ $bound2:ident)* $(+ $bound_lt:lifetime)*)? ),* >)?
($($args:tt)*) $(-> $ret:ty)?;

)* ) => { $(
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[unstable(feature = "core_intrinsics", issue = "none")]
$(#[$meta])*
pub const unsafe fn $name $(<$( $gen $(: $bound $(+ $bound2)* $(+ $bound_lt)*)? ),* >)?
($($args)*) $(-> $ret)? {
unreachable!();
}
)+ };
}

extern "rust-intrinsic" {
// N.B., these intrinsics take raw pointers because they mutate aliased
// memory, which is not valid for either `&` or `&mut`.
Expand Down

0 comments on commit 24e6ba0

Please sign in to comment.