mirror of
https://github.com/Noratrieb/accursed-unutterable-type-id.git
synced 2026-01-14 08:35:02 +01:00
fix generics
This commit is contained in:
parent
012e5a0977
commit
e5366a21ee
3 changed files with 62 additions and 23 deletions
|
|
@ -39,7 +39,7 @@ pub fn my_macro(input: TokenStream) -> TokenStream {
|
|||
|
||||
let new_value = old
|
||||
.checked_add(1)
|
||||
.unwrap_or_else(|| fail("integer overflow. you have too many derives"));
|
||||
.unwrap_or_else(|| fail("integer overflow. use cargo clean. if the problem persists, you have way too many derives, the fuck"));
|
||||
|
||||
fs::write(&file_path, new_value.to_string())
|
||||
.unwrap_or_else(|_| fail("failed to write new number"));
|
||||
|
|
@ -51,7 +51,7 @@ pub fn my_macro(input: TokenStream) -> TokenStream {
|
|||
GenericParam::Type(ty) => {
|
||||
let name = &ty.ident;
|
||||
let bounds = ty.bounds.iter();
|
||||
quote!(#name: #(#bounds +)* 'static)
|
||||
quote!(#name: #(#bounds +)* ::accursed_unutterable_type_id::AccursedUnutterablyTypeIdentified + 'static)
|
||||
}
|
||||
other => other.to_token_stream(),
|
||||
});
|
||||
|
|
@ -63,16 +63,38 @@ pub fn my_macro(input: TokenStream) -> TokenStream {
|
|||
|
||||
let where_clause = input.generics.where_clause;
|
||||
|
||||
let ty_param_ids = input.generics.params.iter().filter_map(|p| match p {
|
||||
GenericParam::Lifetime(_) => None,
|
||||
GenericParam::Type(ty) => {
|
||||
let name = &ty.ident;
|
||||
Some(quote! {
|
||||
::accursed_unutterable_type_id::AccursedUnutterableTypeId::of::<#name>()
|
||||
})
|
||||
}
|
||||
GenericParam::Const(_) => Some(quote!(compile_error!(
|
||||
"const generics are not supported yet"
|
||||
))),
|
||||
});
|
||||
|
||||
// SAFETY: We literally are the proc macro. and we have made sure that no duplicate type ids
|
||||
// will ever happen, right? :ferrisClueless:
|
||||
let expanded = quote! {
|
||||
unsafe impl<#(#generics1),*> ::accursed_unutterable_type_id::AccursedUnutterablyTypeIdentified for #name<#(#generics2),*>
|
||||
#where_clause
|
||||
{
|
||||
#[allow(unused_mut)]
|
||||
fn type_id() -> ::accursed_unutterable_type_id::AccursedUnutterableTypeId {
|
||||
let mut hasher = ::std::collections::hash_map::DefaultHasher::new();
|
||||
|
||||
#(
|
||||
::std::hash::Hash::hash(&#ty_param_ids, &mut hasher);
|
||||
)*
|
||||
|
||||
let value = <::std::collections::hash_map::DefaultHasher as ::std::hash::Hasher>::finish(&hasher);
|
||||
|
||||
::accursed_unutterable_type_id::AccursedUnutterableTypeId::__internal_new(
|
||||
::accursed_unutterable_type_id::InternalAccursedUnutterableTypeId::__internal_new(
|
||||
#new_value
|
||||
#new_value, value,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
use accursed_unutterable_type_id::AccursedUnutterablyTypeIdentified;
|
||||
|
||||
#[derive(AccursedUnutterablyTypeIdentified)]
|
||||
struct Uwu<T, const N: usize>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
_x: [T; N],
|
||||
struct Uwu<T> {
|
||||
_x: T,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
50
src/lib.rs
50
src/lib.rs
|
|
@ -27,7 +27,10 @@
|
|||
//! println!("{type_id:?}")
|
||||
//! ```
|
||||
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::{
|
||||
fmt::{Debug, Formatter},
|
||||
hash::Hash,
|
||||
};
|
||||
|
||||
pub use accursed_unutterable_type_id_derive::AccursedUnutterablyTypeIdentified;
|
||||
|
||||
|
|
@ -66,30 +69,30 @@ impl AccursedUnutterableTypeId {
|
|||
#[doc(hidden)]
|
||||
#[cfg(debug_assertions)]
|
||||
// we do a little trolling
|
||||
pub struct InternalAccursedUnutterableTypeId(u128, u64);
|
||||
pub struct InternalAccursedUnutterableTypeId(u128, u64, u64);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub struct InternalAccursedUnutterableTypeId(u64);
|
||||
pub struct InternalAccursedUnutterableTypeId(u64, u64);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl InternalAccursedUnutterableTypeId {
|
||||
pub fn __internal_new(n: u64) -> Self {
|
||||
Self(0, n)
|
||||
pub fn __internal_new(s: u64, g: u64) -> Self {
|
||||
Self(0, s, g)
|
||||
}
|
||||
fn inner(self) -> u64 {
|
||||
self.1
|
||||
fn inner(self) -> (u64, u64) {
|
||||
(self.1, self.2)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
impl InternalAccursedUnutterableTypeId {
|
||||
pub fn __internal_new(n: u64) -> Self {
|
||||
Self(n)
|
||||
pub fn __internal_new(s: u64, g: u64) -> Self {
|
||||
Self(s, g)
|
||||
}
|
||||
fn inner(self) -> u64 {
|
||||
self.0
|
||||
fn inner(self) -> (u64, u64) {
|
||||
(self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,8 +133,8 @@ mod __doctest {
|
|||
/// use accursed_unutterable_type_id::AccursedUnutterablyTypeIdentified;
|
||||
///
|
||||
/// #[derive(AccursedUnutterablyTypeIdentified)]
|
||||
/// struct Uwu<T: 'static, const N: usize> {
|
||||
/// _x: [T; N],
|
||||
/// struct Uwu<T: 'static, /* const N: usize */> {
|
||||
/// _x: [T; /* N */ 0],
|
||||
/// }
|
||||
/// ```
|
||||
mod complex {}
|
||||
|
|
@ -142,8 +145,8 @@ mod __doctest {
|
|||
/// trait Sussy {}
|
||||
///
|
||||
/// #[derive(AccursedUnutterablyTypeIdentified)]
|
||||
/// struct Uwu<T: Sussy, const N: usize> {
|
||||
/// _x: [T; N],
|
||||
/// struct Uwu<T: Sussy> {
|
||||
/// _x: T,
|
||||
/// }
|
||||
/// ```
|
||||
mod type_bounds {}
|
||||
|
|
@ -167,4 +170,21 @@ mod __doctest {
|
|||
/// }
|
||||
/// ```
|
||||
mod where_clause {}
|
||||
|
||||
/// ```
|
||||
/// use accursed_unutterable_type_id::{AccursedUnutterableTypeId as Id, AccursedUnutterablyTypeIdentified};
|
||||
///
|
||||
/// #[derive(AccursedUnutterablyTypeIdentified)]
|
||||
/// struct Uwu<T> {
|
||||
/// _x: T,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(AccursedUnutterablyTypeIdentified)]
|
||||
/// struct A;
|
||||
/// #[derive(AccursedUnutterablyTypeIdentified)]
|
||||
/// struct B;
|
||||
///
|
||||
/// assert_ne!(Id::of::<Uwu<A>>(), Id::of::<Uwu<B>>());
|
||||
/// ```
|
||||
mod type_param {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue