From 0bb8a0e91c41ef2c324600562ce0741c71aeddb0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 16 Aug 2025 22:08:41 +0800 Subject: [PATCH] remove `#[derive(TryFromU32)]` seems like it could just be replaced with a declarative macro --- .../src/coverageinfo/mapgen.rs | 5 +- compiler/rustc_codegen_llvm/src/lib.rs | 21 +++++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 57 +++++++++++++++++-- compiler/rustc_macros/src/lib.rs | 9 --- compiler/rustc_macros/src/try_from.rs | 55 ------------------ tests/ui-fulldeps/try-from-u32/errors.rs | 24 -------- tests/ui-fulldeps/try-from-u32/errors.stderr | 32 ----------- tests/ui-fulldeps/try-from-u32/hygiene.rs | 32 ----------- tests/ui-fulldeps/try-from-u32/values.rs | 36 ------------ 9 files changed, 77 insertions(+), 194 deletions(-) delete mode 100644 compiler/rustc_macros/src/try_from.rs delete mode 100644 tests/ui-fulldeps/try-from-u32/errors.rs delete mode 100644 tests/ui-fulldeps/try-from-u32/errors.stderr delete mode 100644 tests/ui-fulldeps/try-from-u32/hygiene.rs delete mode 100644 tests/ui-fulldeps/try-from-u32/values.rs diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index d1cb95507d91c..ebee0bfbdd736 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -6,7 +6,6 @@ use rustc_abi::Align; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; -use rustc_macros::TryFromU32; use rustc_middle::ty::TyCtxt; use rustc_session::RemapFileNameExt; use rustc_session::config::RemapPathScopeComponents; @@ -27,12 +26,14 @@ mod unused; /// or at least the subset that we know and care about. /// /// Note that version `n` is encoded as `(n-1)`. -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, TryFromU32)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] enum CovmapVersion { /// Used by LLVM 18 onwards. Version7 = 6, } +crate::impl_try_from_u32!(CovmapVersion { Version7 }); + impl CovmapVersion { fn to_u32(self) -> u32 { self as u32 diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 79e80db6f5554..d36cae1b38fb2 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -79,6 +79,27 @@ mod value; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +// FIXME(fee1-dead) use `macro_attr` feature once that is available in bootstrap beta +macro_rules! impl_try_from_u32 { + ($Type:ident { $($Variant:ident),*$(,)? }) => { + impl ::core::convert::TryFrom for $Type { + type Error = u32; + #[allow(deprecated)] // Don't warn about deprecated variants. + fn try_from(value: u32) -> ::core::result::Result<$Type, Self::Error> { + fn _assert_all_variants_provided(x: $Type) { + match x { + $($Type::$Variant => (),)* + } + } + $( if value == const { $Type::$Variant as u32 } { return Ok($Type::$Variant) } )* + Err(value) + } + } + } +} + +pub(crate) use impl_try_from_u32; + #[derive(Clone)] pub struct LlvmCodegenBackend(()); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index ad3c3d5932eef..4b16ca7d009a9 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -20,7 +20,6 @@ use std::ptr; use bitflags::bitflags; use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t}; -use rustc_macros::TryFromU32; use rustc_target::spec::SymbolVisibility; use super::RustString; @@ -110,7 +109,7 @@ pub(crate) enum TailCallKind { /// LLVM CallingConv::ID. Should we wrap this? /// /// See -#[derive(Copy, Clone, PartialEq, Debug, TryFromU32)] +#[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] pub(crate) enum CallConv { CCallConv = 0, @@ -134,8 +133,32 @@ pub(crate) enum CallConv { AmdgpuKernel = 91, } +crate::impl_try_from_u32! { + CallConv { + CCallConv, + FastCallConv, + ColdCallConv, + PreserveMost, + PreserveAll, + Tail, + X86StdcallCallConv, + X86FastcallCallConv, + ArmAapcsCallConv, + Msp430Intr, + X86_ThisCall, + PtxKernel, + X86_64_SysV, + X86_64_Win64, + X86_VectorCall, + X86_Intr, + AvrNonBlockingInterrupt, + AvrInterrupt, + AmdgpuKernel, + } +} + /// Must match the layout of `LLVMLinkage`. -#[derive(Copy, Clone, PartialEq, TryFromU32)] +#[derive(Copy, Clone, PartialEq)] #[repr(C)] pub(crate) enum Linkage { ExternalLinkage = 0, @@ -161,15 +184,41 @@ pub(crate) enum Linkage { LinkerPrivateWeakLinkage = 16, } +crate::impl_try_from_u32! { + Linkage { + ExternalLinkage, + AvailableExternallyLinkage, + LinkOnceAnyLinkage, + LinkOnceODRLinkage, + LinkOnceODRAutoHideLinkage, + WeakAnyLinkage, + WeakODRLinkage, + AppendingLinkage, + InternalLinkage, + PrivateLinkage, + DLLImportLinkage, + DLLExportLinkage, + ExternalWeakLinkage, + GhostLinkage, + CommonLinkage, + LinkerPrivateLinkage, + LinkerPrivateWeakLinkage, + } +} + /// Must match the layout of `LLVMVisibility`. #[repr(C)] -#[derive(Copy, Clone, PartialEq, TryFromU32)] +#[derive(Copy, Clone, PartialEq)] pub(crate) enum Visibility { Default = 0, Hidden = 1, Protected = 2, } +crate::impl_try_from_u32! { + Visibility { Default, Hidden, Protected } +} + impl Visibility { pub(crate) fn from_generic(visibility: SymbolVisibility) -> Self { match visibility { diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 803b3621c887e..a6f53d92e1006 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -18,7 +18,6 @@ mod print_attribute; mod query; mod serialize; mod symbols; -mod try_from; mod type_foldable; mod type_visitable; mod visitable; @@ -176,14 +175,6 @@ decl_derive!( applicability)] => diagnostics::subdiagnostic_derive ); -decl_derive! { - [TryFromU32] => - /// Derives `TryFrom` for the annotated `enum`, which must have no fields. - /// Each variant maps to the value it would produce under an `as u32` cast. - /// - /// The error type is `u32`. - try_from::try_from_u32 -} decl_derive! { [PrintAttribute] => /// Derives `PrintAttribute` for `AttributeKind`. diff --git a/compiler/rustc_macros/src/try_from.rs b/compiler/rustc_macros/src/try_from.rs deleted file mode 100644 index 9338c1c2b3361..0000000000000 --- a/compiler/rustc_macros/src/try_from.rs +++ /dev/null @@ -1,55 +0,0 @@ -use proc_macro2::TokenStream; -use quote::{quote, quote_spanned}; -use syn::Data; -use syn::spanned::Spanned; -use synstructure::Structure; - -pub(crate) fn try_from_u32(s: Structure<'_>) -> TokenStream { - let span_error = |span, message: &str| { - quote_spanned! { span => const _: () = ::core::compile_error!(#message); } - }; - - // Must be applied to an enum type. - if let Some(span) = match &s.ast().data { - Data::Enum(_) => None, - Data::Struct(s) => Some(s.struct_token.span()), - Data::Union(u) => Some(u.union_token.span()), - } { - return span_error(span, "type is not an enum (TryFromU32)"); - } - - // The enum's variants must not have fields. - let variant_field_errors = s - .variants() - .iter() - .filter_map(|v| v.ast().fields.iter().map(|f| f.span()).next()) - .map(|span| span_error(span, "enum variant cannot have fields (TryFromU32)")) - .collect::(); - if !variant_field_errors.is_empty() { - return variant_field_errors; - } - - let ctor = s - .variants() - .iter() - .map(|v| v.construct(|_, _| -> TokenStream { unreachable!() })) - .collect::>(); - // FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here? - #[allow(keyword_idents_2024)] - s.gen_impl(quote! { - // The surrounding code might have shadowed these identifiers. - use ::core::convert::TryFrom; - use ::core::primitive::u32; - use ::core::result::Result::{self, Ok, Err}; - - gen impl TryFrom for @Self { - type Error = u32; - - #[allow(deprecated)] // Don't warn about deprecated variants. - fn try_from(value: u32) -> Result { - #( if value == const { #ctor as u32 } { return Ok(#ctor) } )* - Err(value) - } - } - }) -} diff --git a/tests/ui-fulldeps/try-from-u32/errors.rs b/tests/ui-fulldeps/try-from-u32/errors.rs deleted file mode 100644 index a25069c0a53cb..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/errors.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![feature(rustc_private)] -//@ edition: 2021 - -// Checks the error messages produced by `#[derive(TryFromU32)]`. - -extern crate rustc_macros; - -use rustc_macros::TryFromU32; - -#[derive(TryFromU32)] -struct MyStruct {} //~ ERROR type is not an enum - -#[derive(TryFromU32)] -enum NonTrivial { - A, - B(), - C {}, - D(bool), //~ ERROR enum variant cannot have fields - E(bool, bool), //~ ERROR enum variant cannot have fields - F { x: bool }, //~ ERROR enum variant cannot have fields - G { x: bool, y: bool }, //~ ERROR enum variant cannot have fields -} - -fn main() {} diff --git a/tests/ui-fulldeps/try-from-u32/errors.stderr b/tests/ui-fulldeps/try-from-u32/errors.stderr deleted file mode 100644 index d20567061d7bb..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/errors.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: type is not an enum (TryFromU32) - --> $DIR/errors.rs:11:1 - | -LL | struct MyStruct {} - | ^^^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:18:7 - | -LL | D(bool), - | ^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:19:7 - | -LL | E(bool, bool), - | ^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:20:9 - | -LL | F { x: bool }, - | ^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:21:9 - | -LL | G { x: bool, y: bool }, - | ^ - -error: aborting due to 5 previous errors - diff --git a/tests/ui-fulldeps/try-from-u32/hygiene.rs b/tests/ui-fulldeps/try-from-u32/hygiene.rs deleted file mode 100644 index e0655a64a64db..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/hygiene.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![feature(rustc_private)] -//@ edition: 2021 -//@ check-pass - -// Checks that the derive macro still works even if the surrounding code has -// shadowed the relevant library types. - -extern crate rustc_macros; - -mod submod { - use rustc_macros::TryFromU32; - - struct Result; - trait TryFrom {} - #[allow(non_camel_case_types)] - struct u32; - struct Ok; - struct Err; - mod core {} - mod std {} - - #[derive(TryFromU32)] - pub(crate) enum MyEnum { - Zero, - One, - } -} - -fn main() { - use submod::MyEnum; - let _: Result = MyEnum::try_from(1u32); -} diff --git a/tests/ui-fulldeps/try-from-u32/values.rs b/tests/ui-fulldeps/try-from-u32/values.rs deleted file mode 100644 index 180a8f2beb75b..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/values.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![feature(assert_matches)] -#![feature(rustc_private)] -//@ edition: 2021 -//@ run-pass - -// Checks the values accepted by the `TryFrom` impl produced by `#[derive(TryFromU32)]`. - -extern crate rustc_macros; - -use core::assert_matches::assert_matches; -use rustc_macros::TryFromU32; - -#[derive(TryFromU32, Debug, PartialEq)] -#[repr(u32)] -enum Repr { - Zero, - One(), - Seven = 7, -} - -#[derive(TryFromU32, Debug)] -enum NoRepr { - Zero, - One, -} - -fn main() { - assert_eq!(Repr::try_from(0u32), Ok(Repr::Zero)); - assert_eq!(Repr::try_from(1u32), Ok(Repr::One())); - assert_eq!(Repr::try_from(2u32), Err(2)); - assert_eq!(Repr::try_from(7u32), Ok(Repr::Seven)); - - assert_matches!(NoRepr::try_from(0u32), Ok(NoRepr::Zero)); - assert_matches!(NoRepr::try_from(1u32), Ok(NoRepr::One)); - assert_matches!(NoRepr::try_from(2u32), Err(2)); -}