Skip to content

Commit 92e37b5

Browse files
ndmitchellmeta-codesync[bot]
authored andcommitted
Support lifetime parameters in TypeEq derive macro
Summary: The TypeEq derive macro previously rejected lifetime generic parameters with "Unsupported generic parameter". This adds support for lifetimes by passing them through to the impl block without trait bounds, which is needed for the upcoming Type<'t> migration. Reviewed By: yangdanny97 Differential Revision: D92713866 fbshipit-source-id: 70a28ce033570dbfc42d498a570710fe99502e30
1 parent 2a6e00b commit 92e37b5

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

crates/pyrefly_derive/src/type_eq.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ pub(crate) fn derive_type_eq(input: proc_macro::TokenStream) -> proc_macro::Toke
2828
fn generics(
2929
generics: &Generics,
3030
) -> syn::Result<(proc_macro2::TokenStream, proc_macro2::TokenStream)> {
31+
let mut lifetimes = Vec::new();
3132
let mut ts = Vec::new();
3233
for param in &generics.params {
3334
match param {
35+
GenericParam::Lifetime(l) => {
36+
lifetimes.push(&l.lifetime);
37+
}
3438
GenericParam::Type(t) if t.bounds.is_empty() => {
3539
ts.push(&t.ident);
3640
}
@@ -42,8 +46,9 @@ fn generics(
4246
}
4347
}
4448
}
45-
let before = quote_spanned! { generics.span() => < #(#ts: crate::equality::TypeEq),* > };
46-
let after = quote_spanned! { generics.span() => < #(#ts),* > };
49+
let before =
50+
quote_spanned! { generics.span() => < #(#lifetimes,)* #(#ts: crate::equality::TypeEq),* > };
51+
let after = quote_spanned! { generics.span() => < #(#lifetimes,)* #(#ts),* > };
4752
Ok((before, after))
4853
}
4954

crates/pyrefly_types/src/equality.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
use std::hash::Hash;
9+
use std::marker::PhantomData;
910
use std::sync::Arc;
1011

1112
use compact_str::CompactString;
@@ -147,6 +148,8 @@ impl TypeEq for String {}
147148
impl TypeEq for CompactString {}
148149
impl TypeEq for str {}
149150

151+
impl<T> TypeEq for PhantomData<T> {}
152+
150153
impl TypeEq for Name {}
151154
impl TypeEq for ModuleName {}
152155
impl TypeEq for TextRange {}
@@ -319,6 +322,12 @@ mod tests {
319322
#[derive(TypeEq, PartialEq, Eq, Debug)]
320323
struct Generic<T>(T);
321324

325+
#[derive(TypeEq, PartialEq, Eq, Debug)]
326+
enum WithLifetime<'t> {
327+
Unused(std::marker::PhantomData<&'t ()>),
328+
Value(i32),
329+
}
330+
322331
#[test]
323332
fn test_type_eq() {
324333
let mut ctx = TypeEqCtx::default();
@@ -363,6 +372,13 @@ mod tests {
363372
);
364373
assert!(Generic(1).type_eq(&Generic(1), &mut ctx));
365374
assert!(!Generic(1).type_eq(&Generic(2), &mut ctx));
375+
376+
assert!(WithLifetime::Value(1).type_eq(&WithLifetime::Value(1), &mut ctx));
377+
assert!(!WithLifetime::Value(1).type_eq(&WithLifetime::Value(2), &mut ctx));
378+
assert!(
379+
!WithLifetime::Value(1)
380+
.type_eq(&WithLifetime::Unused(std::marker::PhantomData), &mut ctx)
381+
);
366382
}
367383

368384
#[test]

0 commit comments

Comments
 (0)