diff --git a/blog/content/second-edition/posts/01-freestanding-rust-binary/index.md b/blog/content/second-edition/posts/01-freestanding-rust-binary/index.md index 47a6b664..7dd231ff 100644 --- a/blog/content/second-edition/posts/01-freestanding-rust-binary/index.md +++ b/blog/content/second-edition/posts/01-freestanding-rust-binary/index.md @@ -134,17 +134,19 @@ This sets the panic strategy to `abort` for both the `dev` profile (used for `ca ### Panic Implementation -The `panic_impl` language item defines the function that the compiler should invoke when a [panic] occurs. Instead of providing the language item directly, we can use the [`panic_implementation`] attribute to create a `panic` function: +The `panic_impl` language item defines the function that the compiler should invoke when a [panic] occurs. Instead of providing the language item directly, we can use the [`panic_handler`] attribute to create a `panic` function. This used to take the for [`panic_implementation`], which has been deprecated and replaced by [`panic_handler`]. [`panic_implementation`]: https://github.com/rust-lang/rfcs/blob/master/text/2070-panic-implementation.md#panic_implementation +Note: [`panic_implementation`] has been deprecated, and we now use [`panic_handler`] instead + ```rust // in main.rs use core::panic::PanicInfo; /// This function is called on panic. -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { loop {} @@ -157,11 +159,11 @@ The [`PanicInfo` parameter][PanicInfo] contains the file and line where the pani [diverging function]: https://doc.rust-lang.org/book/first-edition/functions.html#diverging-functions [“never” type]: https://doc.rust-lang.org/nightly/std/primitive.never.html -When we try `cargo build` now, we get an error that “#[panic_implementation] is an unstable feature”. +When we try `cargo build` now, we get an error that “#[panic_handler] is an unstable feature”. #### Enabling Unstable Features -The `panic_implementation` attribute was recently added and is thus still unstable and protected by a so-called _feature gate_. A feature gate is a special attribute that you have to specify at the top of your `main.rs` in order to use the corresponding feature. By doing this you basically say: “I know that this feature is unstable and that it might stop working without any warnings. I want to use it anyway.” +The `panic_handler` attribute was recently added and is thus still unstable and protected by a so-called _feature gate_. A feature gate is a special attribute that you have to specify at the top of your `main.rs` in order to use the corresponding feature. By doing this you basically say: “I know that this feature is unstable and that it might stop working without any warnings. I want to use it anyway.” Feature gates are not available in the stable or beta Rust compilers, only [nightly Rust] makes it possible to opt-in. This means that you have to use a nightly compiler for OS development for the near future (until all unstable features that we need are added are stabilized). @@ -171,8 +173,6 @@ To manage Rust installations I highly recommend [rustup]. It allows you to insta [rustup]: https://www.rustup.rs/ -After installing a nightly Rust compiler, you can enable the unstable `panic_implementation` feature by inserting `#![feature(panic_implementation)]` right at the top of `main.rs`. - Now we fixed both language item errors. However, if we try to compile it now, another language item is required: ``` @@ -196,14 +196,13 @@ Our freestanding executable does not have access to the Rust runtime and `crt0`, To tell the Rust compiler that we don't want to use the normal entry point chain, we add the `#![no_main]` attribute. ```rust -#![feature(panic_implementation)] #![no_std] #![no_main] use core::panic::PanicInfo; /// This function is called on panic. -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { loop {} @@ -311,14 +310,13 @@ A minimal freestanding Rust binary looks like this: `src/main.rs`: ```rust -#![feature(panic_implementation)] // required for defining the panic handler #![no_std] // don't link the Rust standard library #![no_main] // disable all Rust-level entry points use core::panic::PanicInfo; /// This function is called on panic. -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { loop {} diff --git a/blog/content/second-edition/posts/02-minimal-rust-kernel/index.md b/blog/content/second-edition/posts/02-minimal-rust-kernel/index.md index 997c1ec8..1c43c698 100644 --- a/blog/content/second-edition/posts/02-minimal-rust-kernel/index.md +++ b/blog/content/second-edition/posts/02-minimal-rust-kernel/index.md @@ -199,14 +199,13 @@ Compiling for our new target will use Linux conventions (I'm not quite sure why, ```rust // src/main.rs -#![feature(panic_implementation)] // required for defining the panic handler #![no_std] // don't link the Rust standard library #![no_main] // disable all Rust-level entry points use core::panic::PanicInfo; /// This function is called on panic. -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { loop {} diff --git a/blog/content/second-edition/posts/03-vga-text-buffer/index.md b/blog/content/second-edition/posts/03-vga-text-buffer/index.md index 12761e75..c0bd5ddf 100644 --- a/blog/content/second-edition/posts/03-vga-text-buffer/index.md +++ b/blog/content/second-edition/posts/03-vga-text-buffer/index.md @@ -627,7 +627,7 @@ Now that we have a `println` macro, we can use it in our panic function to print // in main.rs /// This function is called on panic. -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info); diff --git a/blog/content/second-edition/posts/04-unit-testing/index.md b/blog/content/second-edition/posts/04-unit-testing/index.md index cddd015d..14f34959 100644 --- a/blog/content/second-edition/posts/04-unit-testing/index.md +++ b/blog/content/second-edition/posts/04-unit-testing/index.md @@ -37,7 +37,7 @@ error[E0152]: duplicate lang item found: `panic_impl`. = note: first defined in crate `std`. ``` -The problem is that unit tests are built for the host machine, with the `std` library included. This makes sense because they should be able to run as a normal application on the host operating system. Since the standard library has it's own `panic_implementation` function, we get the above error. To fix it, we use [conditional compilation] to include our implementation of the panic handler only in non-test environments: +The problem is that unit tests are built for the host machine, with the `std` library included. This makes sense because they should be able to run as a normal application on the host operating system. Since the standard library has it's own `panic_handler` function, we get the above error. To fix it, we use [conditional compilation] to include our implementation of the panic handler only in non-test environments: [conditional compilation]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation @@ -48,7 +48,7 @@ The problem is that unit tests are built for the host machine, with the `std` li use core::panic::PanicInfo; #[cfg(not(test))] // only compile when the test flag is not set -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info); diff --git a/blog/content/second-edition/posts/05-integration-tests/index.md b/blog/content/second-edition/posts/05-integration-tests/index.md index b75c69d0..87955717 100644 --- a/blog/content/second-edition/posts/05-integration-tests/index.md +++ b/blog/content/second-edition/posts/05-integration-tests/index.md @@ -329,7 +329,6 @@ Cargo allows to add [additional executables] to a project by putting them inside ```rust // src/bin/test-something.rs -#![feature(panic_implementation)] #![no_std] #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -344,7 +343,7 @@ pub extern "C" fn _start() -> ! { } #[cfg(not(test))] -#[panic_implementation] +#[panic_handle] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { loop {} @@ -402,7 +401,6 @@ pub unsafe fn exit_qemu() { ```rust // src/main.rs -#![feature(panic_implementation)] // required for defining the panic handler #![no_std] // don't link the Rust standard library #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -425,7 +423,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info); @@ -464,7 +462,6 @@ We are finally able to create our first integration test executable. We start si ```rust // in src/bin/test-basic-boot.rs -#![feature(panic_implementation)] // required for defining the panic handler #![no_std] // don't link the Rust standard library #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -490,7 +487,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { serial_println!("failed"); @@ -531,7 +528,6 @@ To test that our panic handler is really invoked on a panic, we create a `test-p ```rust // in src/bin/test-panic.rs -#![feature(panic_implementation)] #![no_std] #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -549,7 +545,7 @@ pub extern "C" fn _start() -> ! { } #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { serial_println!("ok"); diff --git a/src/bin/test-basic-boot.rs b/src/bin/test-basic-boot.rs index 54f26572..223ca6a4 100644 --- a/src/bin/test-basic-boot.rs +++ b/src/bin/test-basic-boot.rs @@ -1,4 +1,3 @@ -#![feature(panic_implementation)] // required for defining the panic handler #![no_std] // don't link the Rust standard library #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -25,7 +24,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { serial_println!("failed"); diff --git a/src/bin/test-exception-breakpoint.rs b/src/bin/test-exception-breakpoint.rs index 03906cbd..9e3ae7ec 100644 --- a/src/bin/test-exception-breakpoint.rs +++ b/src/bin/test-exception-breakpoint.rs @@ -1,4 +1,3 @@ -#![feature(panic_implementation)] #![feature(abi_x86_interrupt)] #![no_std] #![cfg_attr(not(test), no_main)] @@ -45,7 +44,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { serial_println!("failed"); diff --git a/src/bin/test-exception-double-fault-stack-overflow.rs b/src/bin/test-exception-double-fault-stack-overflow.rs index 560f8f34..5ed15e41 100644 --- a/src/bin/test-exception-double-fault-stack-overflow.rs +++ b/src/bin/test-exception-double-fault-stack-overflow.rs @@ -1,4 +1,3 @@ -#![feature(panic_implementation)] #![feature(abi_x86_interrupt)] #![no_std] #![cfg_attr(not(test), no_main)] @@ -39,7 +38,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { serial_println!("failed"); diff --git a/src/bin/test-panic.rs b/src/bin/test-panic.rs index 41b181a3..15075755 100644 --- a/src/bin/test-panic.rs +++ b/src/bin/test-panic.rs @@ -1,4 +1,3 @@ -#![feature(panic_implementation)] #![no_std] #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] @@ -16,7 +15,7 @@ pub extern "C" fn _start() -> ! { } #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(_info: &PanicInfo) -> ! { serial_println!("ok"); diff --git a/src/main.rs b/src/main.rs index 9b56c433..52059a2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -#![feature(panic_implementation)] // required for defining the panic handler #![feature(abi_x86_interrupt)] #![no_std] // don't link the Rust standard library #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points @@ -35,7 +34,7 @@ pub extern "C" fn _start() -> ! { /// This function is called on panic. #[cfg(not(test))] -#[panic_implementation] +#[panic_handler] #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info);