From d456d115442cfacde5358da20c579060e61d5ef6 Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Sat, 17 Jun 2023 20:08:33 +0800 Subject: [PATCH 1/7] fix typo in `rustdoc/src/what-is-rustdoc.md` --- src/doc/rustdoc/src/what-is-rustdoc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md index 7a444d77c09d1..7179ee0cf0370 100644 --- a/src/doc/rustdoc/src/what-is-rustdoc.md +++ b/src/doc/rustdoc/src/what-is-rustdoc.md @@ -37,7 +37,7 @@ top, with no contents. ## Configuring rustdoc There are two problems with this: first, why does it -think that our package is named "lib"? Second, why does it not have any +think that our crate is named "lib"? Second, why does it not have any contents? The first problem is due to `rustdoc` trying to be helpful; like `rustc`, From d30294e33c67a19a52f4d2b126c460dae2b87a8f Mon Sep 17 00:00:00 2001 From: "Jonathan Pallant (Ferrous Systems)" Date: Fri, 7 Jul 2023 11:55:04 +0100 Subject: [PATCH 2/7] Add a sparc-unknown-none-elf target. Tested with the Gaisler bcc2 toolchain (both gcc and clang) and the Leon3 simulator. --- compiler/rustc_target/src/spec/mod.rs | 2 ++ .../src/spec/sparc_unknown_none_elf.rs | 27 +++++++++++++++++++ src/doc/rustc/src/platform-support.md | 1 + src/tools/build-manifest/src/main.rs | 1 + 4 files changed, 31 insertions(+) create mode 100644 compiler/rustc_target/src/spec/sparc_unknown_none_elf.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2365dfaf1af80..b615165822550 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1433,6 +1433,8 @@ supported_targets! { ("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu), ("riscv64gc-unknown-linux-musl", riscv64gc_unknown_linux_musl), + ("sparc-unknown-none-elf", sparc_unknown_none_elf), + ("loongarch64-unknown-none", loongarch64_unknown_none), ("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat), diff --git a/compiler/rustc_target/src/spec/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/sparc_unknown_none_elf.rs new file mode 100644 index 0000000000000..7e908a0f36552 --- /dev/null +++ b/compiler/rustc_target/src/spec/sparc_unknown_none_elf.rs @@ -0,0 +1,27 @@ +use crate::abi::Endian; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; + +pub fn target() -> Target { + let options = TargetOptions { + linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), + linker: Some("sparc-elf-gcc".into()), + endian: Endian::Big, + cpu: "v7".into(), + abi: "elf".into(), + max_atomic_width: Some(32), + atomic_cas: true, + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + no_default_libraries: false, + emit_debug_gdb_scripts: false, + eh_frame_header: false, + ..Default::default() + }; + Target { + data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), + llvm_target: "sparc-unknown-none-elf".into(), + pointer_width: 32, + arch: "sparc".into(), + options, + } +} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d2a25e612ec7b..d287cf7a5fe40 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -176,6 +176,7 @@ target | std | notes `thumbv8m.base-none-eabi` | * | Bare ARMv8-M Baseline `thumbv8m.main-none-eabi` | * | Bare ARMv8-M Mainline `thumbv8m.main-none-eabihf` | * | Bare ARMv8-M Mainline, hardfloat +`sparc-unknown-none-elf` | * | Bare 32-bit SPARC V7+ `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8b28c68e04fe9..14618f89aedbf 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -127,6 +127,7 @@ static TARGETS: &[&str] = &[ "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparcv9-sun-solaris", + "sparc-unknown-none-elf", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", From 4bccf832a3ea62318c82adae33e0a2cce1e6572f Mon Sep 17 00:00:00 2001 From: "Jonathan Pallant (Ferrous Systems)" Date: Tue, 11 Jul 2023 11:59:07 +0100 Subject: [PATCH 3/7] Add platform support information. --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../sparc-unknown-none-elf.md | 164 ++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index f8af26326a734..4d4dc3f499650 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -38,6 +38,7 @@ - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) + - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [\*-unknown-netbsd\*](platform-support/netbsd.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d287cf7a5fe40..14fe7242ab951 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -176,7 +176,7 @@ target | std | notes `thumbv8m.base-none-eabi` | * | Bare ARMv8-M Baseline `thumbv8m.main-none-eabi` | * | Bare ARMv8-M Mainline `thumbv8m.main-none-eabihf` | * | Bare ARMv8-M Mainline, hardfloat -`sparc-unknown-none-elf` | * | Bare 32-bit SPARC V7+ +[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | Bare 32-bit SPARC V7+ `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI diff --git a/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md new file mode 100644 index 0000000000000..efd58e8302fd7 --- /dev/null +++ b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md @@ -0,0 +1,164 @@ +# `sparc-unknown-none-elf` + +**Tier: 3** + +Rust for bare-metal 32-bit SPARC V7 and V8 systems, e.g. the Gaisler LEON3. + +| Target | Descriptions | +| ---------------------- | ----------------------------------------- | +| sparc-unknown-none-elf | SPARC V7 32-bit (freestanding, hardfloat) | + +## Target maintainers + +- Jonathan Pallant, , https://ferrous-systems.com + +## Requirements + +This target is cross-compiled. There is no support for `std`. There is no +default allocator, but it's possible to use `alloc` by supplying an allocator. + +This allows the generated code to run in environments, such as kernels, which +may need to avoid the use of such registers or which may have special +considerations about the use of such registers (e.g. saving and restoring them +to avoid breaking userspace code using the same registers). You can change code +generation to use additional CPU features via the `-C target-feature=` codegen +options to rustc, or via the `#[target_feature]` mechanism within Rust code. + +By default, code generated with this target should run on any `SPARC` hardware; +enabling additional target features may raise this baseline. + +- `-Ctarget-cpu=v8` adds the extra SPARC V8 instructions. + +- `-Ctarget-cpu=leon3` adds the SPARC V8 instructions and sets up scheduling to + suit the Gaisler Leon3. + +Functions marked `extern "C"` use the [standard SPARC architecture calling +convention](https://sparc.org/technical-documents/). + +This target generates ELF binaries. Any alternate formats or special +considerations for binary layout will require linker options or linker scripts. + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml`: + +```toml +[build] +build-stage = 1 +target = ["sparc-unknown-none-elf"] +``` + +## Building Rust programs + +```text +cargo build --target sparc-unknown-none-elf +``` + +This target uses GCC as a linker, and so you will need an appropriate GCC +compatible `sparc-unknown-none` toolchain. + +The default linker name is `sparc-elf-gcc`, but you can override this in your +project configuration. + +## Testing + +As `sparc-unknown-none-elf` supports a variety of different environments and does +not support `std`, this target does not support running the Rust test suite. + +## Cross-compilation toolchains and C code + +This target was initially tested using [BCC2] from Gaisler, along with the TSIM +Leon3 processor simulator. Both [BCC2] GCC and [BCC2] Clang have been shown to +work. To work with these tools, your project configuration should contain +something like: + +[BCC2]: https://www.gaisler.com/index.php/downloads/compilers + +`.cargo/config.toml`: +```toml +[target.sparc-unknown-none-elf] +linker = "sparc-gaisler-elf-gcc" +runner = "tsim-leon3" + +[build] +target = ["sparc-unknown-none-elf"] +rustflags = "-Ctarget-cpu=leon3" + +[unstable] +build-std = ["core"] +``` + +With this configuration, running `cargo run` will compile your code for the +SPARC V8 compatible Gaisler Leon3 processor and then start the `tsim-leon3` +simulator. Once the simulator is running, simply enter the command +`run` to start the code executing in the simulator. + +The default C toolchain libraries are linked in, so with the Gaisler [BCC2] +toolchain, and using its default Leon3 BSP, you can use call the C `putchar` +function and friends to output to the simulator console. + +Here's a complete example: + +```rust,ignore (cannot-test-this-because-it-assumes-special-libc-functions) +#![no_std] +#![no_main] + +extern "C" { + fn putchar(ch: i32); + fn _exit(code: i32) -> !; +} + +#[no_mangle] +extern "C" fn main() -> i32 { + let message = "Hello, this is Rust!"; + for b in message.bytes() { + unsafe { + putchar(b as i32); + } + } + 0 +} + +#[panic_handler] +fn panic(_panic: &core::panic::PanicInfo) -> ! { + unsafe { + _exit(1); + } +} +``` + +```console +$ cargo run --target=sparc-unknown-none-elf + Compiling sparc-demo-rust v0.1.0 (/work/sparc-demo-rust) + Finished dev [unoptimized + debuginfo] target(s) in 3.44s + Running `tsim-leon3 target/sparc-unknown-none-elf/debug/sparc-demo-rust` + + TSIM3 LEON3 SPARC simulator, version 3.1.9 (evaluation version) + + Copyright (C) 2023, Frontgrade Gaisler - all rights reserved. + This software may only be used with a valid license. + For latest updates, go to https://www.gaisler.com/ + Comments or bug-reports to support@gaisler.com + + This TSIM evaluation version will expire 2023-11-28 + +Number of CPUs: 2 +system frequency: 50.000 MHz +icache: 1 * 4 KiB, 16 bytes/line (4 KiB total) +dcache: 1 * 4 KiB, 16 bytes/line (4 KiB total) +Allocated 8192 KiB SRAM memory, in 1 bank at 0x40000000 +Allocated 32 MiB SDRAM memory, in 1 bank at 0x60000000 +Allocated 8192 KiB ROM memory at 0x00000000 +section: .text, addr: 0x40000000, size: 20528 bytes +section: .rodata, addr: 0x40005030, size: 128 bytes +section: .data, addr: 0x400050b0, size: 1176 bytes +read 347 symbols + +tsim> run + Initializing and starting from 0x40000000 +Hello, this is Rust! + + Program exited normally on CPU 0. +tsim> +``` From 19d46b690a8dddcb19e4919c19939844c4441594 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 13 Jul 2023 13:35:00 +0200 Subject: [PATCH 4/7] self type param infer, avoid ICE --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 5 ++--- .../src/infer/error_reporting/need_type_info.rs | 2 +- .../need_type_info/infer-var-for-self-param.rs | 7 +++++++ .../need_type_info/infer-var-for-self-param.stderr | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 tests/ui/inference/need_type_info/infer-var-for-self-param.rs create mode 100644 tests/ui/inference/need_type_info/infer-var-for-self-param.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 15ca5808a93ab..c44d12e61e33d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -2,7 +2,7 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::{self, symbol::kw, Span}; use rustc_trait_selection::traits; @@ -267,8 +267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type BreakTy = ty::GenericArg<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let Some(origin) = self.0.type_var_origin(ty) - && let rustc_infer::infer::type_variable::TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = - origin.kind + && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) && let Some(subst) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index b4d8205fd6d6d..36b56fe782c32 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -163,7 +163,7 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind - && !var_origin.span.from_expansion() + && name != kw::SelfUpper && !var_origin.span.from_expansion() { let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id)); let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap(); diff --git a/tests/ui/inference/need_type_info/infer-var-for-self-param.rs b/tests/ui/inference/need_type_info/infer-var-for-self-param.rs new file mode 100644 index 0000000000000..51ac7943f2490 --- /dev/null +++ b/tests/ui/inference/need_type_info/infer-var-for-self-param.rs @@ -0,0 +1,7 @@ +// Regression test for #113610 where we ICEd when trying to print +// inference variables created by instantiating the self type parameter. + +fn main() { + let _ = (Default::default(),); + //~^ ERROR cannot call associated function on trait +} diff --git a/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr new file mode 100644 index 0000000000000..fdef4d0dd0920 --- /dev/null +++ b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr @@ -0,0 +1,14 @@ +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/infer-var-for-self-param.rs:5:14 + | +LL | let _ = (Default::default(),); + | ^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use a fully-qualified path to a specific available implementation (271 found) + | +LL | let _ = (::default(),); + | +++++++++++++++++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0790`. From e449daad6cc3db4890d4dbaa4d0ab2fa66215091 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 14 Jul 2023 10:28:18 +0200 Subject: [PATCH 5/7] stop mentioning number of applicate implementations --- .../src/traits/error_reporting/mod.rs | 11 ++++------- tests/ui/error-codes/E0283.stderr | 2 +- tests/ui/error-codes/E0790.stderr | 2 +- .../need_type_info/infer-var-for-self-param.stderr | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index a821d1be64b70..c14839fe9be08 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2388,14 +2388,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // If there is only one implementation of the trait, suggest using it. // Otherwise, use a placeholder comment for the implementation. let (message, impl_suggestion) = if non_blanket_impl_count == 1 {( - "use the fully-qualified path to the only available implementation".to_string(), + "use the fully-qualified path to the only available implementation", format!("<{} as ", self.tcx.type_of(impl_def_id).instantiate_identity()) - )} else {( - format!( - "use a fully-qualified path to a specific available implementation ({} found)", - non_blanket_impl_count - ), - " u32; LL | let cont: u32 = Generator::create(); | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | -help: use a fully-qualified path to a specific available implementation (2 found) +help: use a fully-qualified path to a specific available implementation | LL | let cont: u32 = ::create(); | +++++++++++++++++++ + diff --git a/tests/ui/error-codes/E0790.stderr b/tests/ui/error-codes/E0790.stderr index 7248766285d71..f559abae39780 100644 --- a/tests/ui/error-codes/E0790.stderr +++ b/tests/ui/error-codes/E0790.stderr @@ -63,7 +63,7 @@ LL | fn my_fn(); LL | MyTrait2::my_fn(); | ^^^^^^^^^^^^^^^ cannot call associated function of trait | -help: use a fully-qualified path to a specific available implementation (2 found) +help: use a fully-qualified path to a specific available implementation | LL | ::my_fn(); | +++++++++++++++++++ + diff --git a/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr index fdef4d0dd0920..36d75469392b6 100644 --- a/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr +++ b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr @@ -4,7 +4,7 @@ error[E0790]: cannot call associated function on trait without specifying the co LL | let _ = (Default::default(),); | ^^^^^^^^^^^^^^^^ cannot call associated function of trait | -help: use a fully-qualified path to a specific available implementation (271 found) +help: use a fully-qualified path to a specific available implementation | LL | let _ = (::default(),); | +++++++++++++++++++ + From f441adc89a880df995ed95ca1402cfe8939d273b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 16 Jul 2023 14:35:16 -0700 Subject: [PATCH 6/7] Generate safe stable code for derives on empty enums Generate `match *self {}` instead of `unsafe { core::intrinsics::unreachable() }`. This is: 1. safe 2. stable for the benefit of everyone looking at these derived impls through `cargo expand`. Both expansions compile to the same code at all optimization levels (including `0`). --- .../src/deriving/generic/mod.rs | 17 +++++++++++++---- tests/ui/deriving/deriving-all-codegen.stdout | 14 +++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 4ba09335cb7ab..0f51b26de0953 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1134,9 +1134,14 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'b>, enum_def: &'b EnumDef, type_ident: Ident, - selflike_args: ThinVec>, + mut selflike_args: ThinVec>, nonselflike_args: &[P], ) -> BlockOrExpr { + assert!( + !selflike_args.is_empty(), + "static methods must use `expand_static_enum_method_body`", + ); + let span = trait_.span; let variants = &enum_def.variants; @@ -1144,10 +1149,14 @@ impl<'a> MethodDef<'a> { let unify_fieldless_variants = self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify; - // There is no sensible code to be generated for *any* deriving on a - // zero-variant enum. So we just generate a failing expression. + // For zero-variant enum, this function body is unreachable. + // Generate `match *self {}`. if variants.is_empty() { - return BlockOrExpr(ThinVec::new(), Some(deriving::call_unreachable(cx, span))); + selflike_args.truncate(1); + let match_arg = cx.expr_deref(span, selflike_args.pop().unwrap()); + let match_arms = ThinVec::new(); + let expr = cx.expr_match(span, match_arg, match_arms); + return BlockOrExpr(ThinVec::new(), Some(expr)); } let prefixes = iter::once("__self".to_string()) diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index d6a2c80cc06b6..6bfc859bfe807 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -798,14 +798,14 @@ impl ::core::marker::Copy for Enum0 { } #[automatically_derived] impl ::core::fmt::Debug for Enum0 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - unsafe { ::core::intrinsics::unreachable() } + match *self {} } } #[automatically_derived] impl ::core::hash::Hash for Enum0 { #[inline] fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - unsafe { ::core::intrinsics::unreachable() } + match *self {} } } #[automatically_derived] @@ -813,9 +813,7 @@ impl ::core::marker::StructuralPartialEq for Enum0 { } #[automatically_derived] impl ::core::cmp::PartialEq for Enum0 { #[inline] - fn eq(&self, other: &Enum0) -> bool { - unsafe { ::core::intrinsics::unreachable() } - } + fn eq(&self, other: &Enum0) -> bool { match *self {} } } #[automatically_derived] impl ::core::marker::StructuralEq for Enum0 { } @@ -831,15 +829,13 @@ impl ::core::cmp::PartialOrd for Enum0 { #[inline] fn partial_cmp(&self, other: &Enum0) -> ::core::option::Option<::core::cmp::Ordering> { - unsafe { ::core::intrinsics::unreachable() } + match *self {} } } #[automatically_derived] impl ::core::cmp::Ord for Enum0 { #[inline] - fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering { - unsafe { ::core::intrinsics::unreachable() } - } + fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering { match *self {} } } // A single-variant enum. From 56633b3f51967f544c988dcabbcd1b99f4cc3558 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 16 Jul 2023 15:33:29 -0700 Subject: [PATCH 7/7] Add a comparison between match *self and intrinsics::unreachable() --- compiler/rustc_builtin_macros/src/deriving/generic/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 0f51b26de0953..9865b6a72ee69 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1149,8 +1149,9 @@ impl<'a> MethodDef<'a> { let unify_fieldless_variants = self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify; - // For zero-variant enum, this function body is unreachable. - // Generate `match *self {}`. + // For zero-variant enum, this function body is unreachable. Generate + // `match *self {}`. This produces machine code identical to `unsafe { + // core::intrinsics::unreachable() }` while being safe and stable. if variants.is_empty() { selflike_args.truncate(1); let match_arg = cx.expr_deref(span, selflike_args.pop().unwrap());