@@ -142,28 +142,30 @@ impl WhenToSkip {
142
142
}
143
143
}
144
144
145
- pub struct Interner < ' a > ( Option < & ' a Lifetime > ) ;
145
+ pub enum Interner < ' a > {
146
+ Middle ( & ' a Lifetime ) ,
147
+ Generic ( Ident ) ,
148
+ }
146
149
147
150
impl < ' a > Interner < ' a > {
148
- /// Return the `TyCtxt` interner for the given `structure`.
151
+ /// Return the interner for the given `structure`.
149
152
///
150
- /// If the input represented by `structure` has a `'tcx` lifetime parameter, then that will be used
151
- /// used as the lifetime of the `TyCtxt`. Otherwise a `'tcx` lifetime parameter that is unrelated
152
- /// to the input will be used.
153
- fn resolve ( generics : & ' a Generics ) -> Self {
154
- Self (
155
- generics
156
- . lifetimes ( )
157
- . find_map ( |def| ( def. lifetime . ident == "tcx" ) . then_some ( & def. lifetime ) ) ,
158
- )
153
+ /// If the input represented by `structure` has a `'tcx` lifetime parameter, then `Middle('tcx)`
154
+ /// will be returned; otherwise our derived implementation will be generic over a new parameter.
155
+ fn resolve ( suffix : impl ToString , generics : & ' a Generics ) -> Self {
156
+ generics
157
+ . lifetimes ( )
158
+ . find_map ( |def| ( def. lifetime . ident == "tcx" ) . then_some ( Self :: Middle ( & def. lifetime ) ) )
159
+ . unwrap_or_else ( || Self :: Generic ( gen_param ( suffix, generics) ) )
159
160
}
160
161
}
161
162
162
163
impl ToTokens for Interner < ' _ > {
163
164
fn to_tokens ( & self , tokens : & mut TokenStream ) {
164
- let default = parse_quote ! { ' tcx } ;
165
- let lt = self . 0 . unwrap_or ( & default) ;
166
- tokens. extend ( quote ! { :: rustc_middle:: ty:: TyCtxt <#lt> } ) ;
165
+ match self {
166
+ Interner :: Middle ( lt) => tokens. extend ( quote ! { :: rustc_middle:: ty:: TyCtxt <#lt> } ) ,
167
+ Interner :: Generic ( ident) => ident. to_tokens ( tokens) ,
168
+ }
167
169
}
168
170
}
169
171
@@ -301,7 +303,7 @@ impl Interner<'_> {
301
303
302
304
if !referenced_ty_params. is_empty ( ) {
303
305
Generic
304
- } else if let Some ( interner) = & self . 0 && fields. into_iter ( ) . any ( |field| {
306
+ } else if let Interner :: Middle ( interner) = self && fields. into_iter ( ) . any ( |field| {
305
307
let mut info = Info { interner, contains_interner : false } ;
306
308
info. visit_type ( & field. ty ) ;
307
309
info. contains_interner
@@ -320,7 +322,7 @@ pub fn traversable_derive<T: Traversable>(
320
322
321
323
let ast = structure. ast ( ) ;
322
324
323
- let interner = Interner :: resolve ( & ast. generics ) ;
325
+ let interner = Interner :: resolve ( "I" , & ast. generics ) ;
324
326
let traverser = gen_param ( "T" , & ast. generics ) ;
325
327
let traversable = T :: traversable ( & interner) ;
326
328
@@ -331,8 +333,8 @@ pub fn traversable_derive<T: Traversable>(
331
333
structure. add_bounds ( synstructure:: AddBounds :: None ) ;
332
334
structure. bind_with ( |_| synstructure:: BindStyle :: Move ) ;
333
335
334
- let not_generic = if interner . 0 . is_none ( ) {
335
- structure. add_impl_generic ( parse_quote ! { ' tcx } ) ;
336
+ let not_generic = if let Interner :: Generic ( ident ) = & interner {
337
+ structure. add_impl_generic ( parse_quote ! { #ident : :: rustc_type_ir :: Interner } ) ;
336
338
Trivial
337
339
} else {
338
340
NotGeneric
0 commit comments