trap 0.1.1

Bare metal traps.
Documentation
// Copyright 2025 Gabriel Bjørnager Jensen.

//! Bare metal traps.

#![no_std]

#![allow(unused_imports)]

#![cfg_attr(feature = "nightly", allow(internal_features))]

#![cfg_attr(feature = "nightly", feature(core_intrinsics))]

#[cfg(doc)]
extern crate std;

use core::arch::asm;
use core::hint::unreachable_unchecked;

/// Traps the machine.
///
/// This function serves as a replacement for [`std::process::abort`]() on platforms that don't support it and for users want to avoid panicking.
///
/// The exact behaviour of this function is unspecified except that calling it indicates abnormal programme termination.
///
/// # Machine-specific behaviour
///
/// Currently, this function only has special behaviour on the following, target architectures:
///
/// * `aarch64`
/// * `arm`
/// * `riscv32`
/// * `riscv64`
/// * `x86`
/// * `x86_64`
///
/// On all other architectures, calling `trap` will result in a panic.
///
/// The above behaviour can be overridden by enabling the `nightly` feature, in which case this function will behave like [`core::intrinsics::abort`] on all platforms.
#[allow(unreachable_code)]
#[cold]
#[inline(never)]
#[track_caller]
pub fn trap() -> ! {
	// powerpc: trap
	// powerpc64: trap

	#[cfg(feature = "nightly")]
	core::intrinsics::abort();

	#[cfg(target_arch = "aarch64")]
	unsafe {
		asm!("brk #1");
		unreachable_unchecked();
	}

	#[cfg(target_arch = "arm")]
	unsafe {
		// `0xE7FFDEFE` is conventially seen as the "trap"
		// instruction, although it is just an undefined.
		asm!(".inst 0xE7FFDEFE");
		unreachable_unchecked();
	}

	#[cfg(target_arch = "riscv32")]
	unsafe {
		asm!("unimp");
		unreachable_unchecked();
	}

	#[cfg(target_arch = "riscv64")]
	unsafe {
		asm!("unimp");
		unreachable_unchecked();
	}

	#[cfg(target_arch = "x86")]
	unsafe {
		asm!("ud2");
		unreachable_unchecked();
	}

	#[cfg(target_arch = "x86_64")]
	unsafe {
		asm!("ud2");
		unreachable_unchecked();
	}

	panic!("trap");
}