//!
//! Typical usage will look like this:
//!
-//! ```rust
+#![cfg_attr(bootstrap, doc = "```rust,ignore")]
+#![cfg_attr(not(bootstrap), doc = "```rust")]
//! #![feature(core_intrinsics, custom_mir)]
+//! #![allow(internal_features)]
//!
-//! extern crate core;
//! use core::intrinsics::mir::*;
//!
//! #[custom_mir(dialect = "built")]
//!
//! # Examples
//!
-//! ```rust
+#![cfg_attr(bootstrap, doc = "```rust,ignore")]
+#![cfg_attr(not(bootstrap), doc = "```rust")]
//! #![feature(core_intrinsics, custom_mir)]
+//! #![allow(internal_features)]
//!
-//! extern crate core;
//! use core::intrinsics::mir::*;
//!
//! #[custom_mir(dialect = "built")]
//! }
//!
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
+#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set
//! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
//! mir!(
-//! let unused;
+//! let _unused;
//! let popped;
//!
//! {
-//! Call(unused, pop, Vec::push(v, value))
+//! Call(_unused = Vec::push(v, value), pop)
//! }
//!
//! pop = {
-//! Call(popped, drop, Vec::pop(v))
+//! Call(popped = Vec::pop(v), drop)
//! }
//!
//! drop = {
//!
//! - Operands implicitly convert to `Use` rvalues.
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
-//! - [`Discriminant`] and [`Len`] have associated functions.
+//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions.
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
//! - The binary operation `Offset` can be created via [`Offset`].
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
macro_rules! define {
($name:literal, $( #[ $meta:meta ] )* fn $($sig:tt)*) => {
#[rustc_diagnostic_item = $name]
+ #[inline]
$( #[ $meta ] )*
pub fn $($sig)* { panic!() }
}
define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
define!("mir_unreachable", fn Unreachable() -> BasicBlock);
define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
-define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
+define!("mir_call", fn Call(call: (), goto: BasicBlock));
define!("mir_storage_live", fn StorageLive<T>(local: T));
define!("mir_storage_dead", fn StorageDead<T>(local: T));
define!("mir_deinit", fn Deinit<T>(place: T));
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
define!("mir_len", fn Len<T>(place: T) -> usize);
+define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
define!("mir_retag", fn Retag<T>(place: T));
define!("mir_move", fn Move<T>(place: T) -> T);
define!("mir_static", fn Static<T>(s: T) -> &'static T);
///
/// # Examples
///
- /// ```rust
+ #[cfg_attr(bootstrap, doc = "```rust,ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```rust")]
+ /// #![allow(internal_features)]
/// #![feature(custom_mir, core_intrinsics)]
///
- /// extern crate core;
/// use core::intrinsics::mir::*;
///
/// #[custom_mir(dialect = "built")]
#[doc(hidden)]
fn __internal_make_place<T>(place: T) -> *mut T
);
+define!(
+ "mir_debuginfo",
+ #[doc(hidden)]
+ fn __debuginfo<T>(name: &'static str, s: T)
+);
/// Macro for generating custom MIR.
///
(
$(type RET = $ret_ty:ty ;)?
$(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*
+ $(debug $dbg_name:ident => $dbg_data:expr ;)*
{
$($entry:tt)*
$(
let $local_decl $(: $local_decl_ty)? ;
)*
-
::core::intrinsics::mir::__internal_extract_let!($($entry)*);
$(
::core::intrinsics::mir::__internal_extract_let!($($block)*);
)*
{
- // Finally, the contents of the basic blocks
- ::core::intrinsics::mir::__internal_remove_let!({
- {}
- { $($entry)* }
- });
+ // Now debuginfo
$(
+ __debuginfo(stringify!($dbg_name), $dbg_data);
+ )*
+
+ {
+ // Finally, the contents of the basic blocks
::core::intrinsics::mir::__internal_remove_let!({
{}
- { $($block)* }
+ { $($entry)* }
});
- )*
+ $(
+ ::core::intrinsics::mir::__internal_remove_let!({
+ {}
+ { $($block)* }
+ });
+ )*
- RET
+ RET
+ }
}
}
}}