Skip to content

Commit

Permalink
remove duplicated Eq and Hash impls
Browse files Browse the repository at this point in the history
  • Loading branch information
mversic committed Sep 23, 2023
1 parent d7f22a2 commit 98df7c8
Showing 1 changed file with 1 addition and 80 deletions.
81 changes: 1 addition & 80 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type ParamIdent = syn::Ident;

/// AST node type of the trait identifier such as 'Deref<Target = u32>' in `impl<T: Deref<Target = u32>> Clone for T`.
/// Equality of this type doesn't compare associated bounds. Therefore `Deref<Target = u32>` == `Deref<Target = u64>`.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct TraitBound<'ast>(pub &'ast syn::Path);

/// Unique name based identifier of the associated type bound such as:
Expand All @@ -46,85 +46,6 @@ type AssocBoundIdent<'ast> = (&'ast ParamIdent, TraitBound<'ast>, &'ast syn::Ide
// TODO: how to support GATs? make a test
type AssocBoundPayload = syn::Type;

impl PartialEq for TraitBound<'_> {
fn eq(&self, other: &Self) -> bool {
if self.0.leading_colon != other.0.leading_colon {
return false;
}

let mut first_iter = self.0.segments.iter().rev();
let mut second_iter = other.0.segments.iter().rev();

let first_elem = first_iter.next().unwrap();
let second_elem = second_iter.next().unwrap();

if first_elem.ident != second_elem.ident || !first_iter.eq(second_iter) {
return false;
}

match (&first_elem.arguments, &second_elem.arguments) {
(
syn::PathArguments::AngleBracketed(first_args),
syn::PathArguments::AngleBracketed(second_args),
) => {
if first_args.colon2_token != second_args.colon2_token {
return false;
}

let first_args = first_args
.args
.iter()
.filter(|arg| !matches!(arg, syn::GenericArgument::AssocType(_)))
.collect::<Vec<_>>();
let second_args = second_args
.args
.iter()
.filter(|arg| !matches!(arg, syn::GenericArgument::AssocType(_)))
.collect::<Vec<_>>();

if first_args.len() != second_args.len() {
return false;
}

first_args
.iter()
.zip(&second_args)
.all(|zipped_args| match zipped_args {
(syn::GenericArgument::AssocType(_), _)
| (_, syn::GenericArgument::AssocType(_)) => unreachable!(),
_ => zipped_args.0 == zipped_args.1,
})
}
_ => first_elem.arguments == second_elem.arguments,
}
}
}

impl Eq for TraitBound<'_> {}
impl core::hash::Hash for TraitBound<'_> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.0.leading_colon.hash(state);

let mut iter = self.0.segments.iter().rev();
let first_elem = iter.next().unwrap();

iter.rev().for_each(|elem| elem.hash(state));
first_elem.ident.hash(state);

match &first_elem.arguments {
syn::PathArguments::AngleBracketed(first_args) => {
first_args.colon2_token.hash(state);

first_args.args.iter().for_each(|args| match args {
syn::GenericArgument::AssocType(_) => {}
_ => args.hash(state),
})
}
_ => first_elem.arguments.hash(state),
}
}
}

impl quote::ToTokens for TraitBound<'_> {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.leading_colon.to_tokens(tokens);
Expand Down

0 comments on commit 98df7c8

Please sign in to comment.