fix generics

This commit is contained in:
nora 2022-06-18 11:10:09 +02:00
parent 012e5a0977
commit e5366a21ee
3 changed files with 62 additions and 23 deletions

View file

@ -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,
)
)
}

View file

@ -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() {}

View file

@ -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 {}
}