Skip to content

Commit 8da36bd

Browse files
committed
Derive traversables over generic interners
1 parent 6833eea commit 8da36bd

File tree

2 files changed

+20
-25
lines changed

2 files changed

+20
-25
lines changed

compiler/rustc_macros/src/lib.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,12 @@ decl_derive!(
141141
/// such derived implementations are only applicable if the annotated type does not contain
142142
/// anything that may be of interest to a folder.
143143
///
144-
/// If the annotated type has a `'tcx` lifetime parameter, then that will be used as the
145-
/// lifetime for the type context/interner; otherwise the lifetime of the type context/interner
146-
/// will be unrelated to the annotated type. It therefore matters how any lifetime parameters of
147-
/// the annotated type are named. For example, deriving `TypeFoldable` for both `Foo<'a>` and
148-
/// `Bar<'tcx>` will respectively produce:
144+
/// The derived implementation will use `TyCtxt<'tcx>` as the interner iff the annotated type
145+
/// has a `'tcx` lifetime parameter; otherwise it will be generic over all interners. It
146+
/// therefore matters how any lifetime parameters of the annotated type are named. For example,
147+
/// deriving `TypeFoldable` for both `Foo<'a>` and `Bar<'tcx>` will respectively produce:
149148
///
150-
/// `impl<'a, 'tcx> TypeFoldable<TyCtxt<'tcx>> for Foo<'a>`
149+
/// `impl<'a, I: Interner> TypeFoldable<I> for Foo<'a>`
151150
///
152151
/// and
153152
///
@@ -176,13 +175,12 @@ decl_derive!(
176175
/// above, such derived implementations are only applicable if the annotated type does not
177176
/// contain anything that may be of interest to visitors.
178177
///
179-
/// If the annotated type has a `'tcx` lifetime parameter, then that will be used as the
180-
/// lifetime for the type context/interner; otherwise the lifetime of the type context/interner
181-
/// will be unrelated to the annotated type. It therefore matters how any lifetime parameters of
182-
/// the annotated type are named. For example, deriving `TypeVisitable` for both `Foo<'a>` and
183-
/// `Bar<'tcx>` will respectively produce:
178+
/// The derived implementation will use `TyCtxt<'tcx>` as the interner iff the annotated type
179+
/// has a `'tcx` lifetime parameter; otherwise it will be generic over all interners. It
180+
/// therefore matters how any lifetime parameters of the annotated type are named. For example,
181+
/// deriving `TypeVisitable` for both `Foo<'a>` and `Bar<'tcx>` will respectively produce:
184182
///
185-
/// `impl<'a, 'tcx> TypeVisitable<TyCtxt<'tcx>> for Foo<'a>`
183+
/// `impl<'a, I: Interner> TypeVisitable<I> for Foo<'a>`
186184
///
187185
/// and
188186
///

compiler/rustc_macros/src/traversable.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use proc_macro2::{Span, TokenStream};
22
use quote::{quote, quote_spanned, ToTokens};
33
use std::collections::HashMap;
4-
use syn::{parse_quote, spanned::Spanned, Attribute, Generics, Ident, Lifetime, LifetimeDef};
4+
use syn::{parse_quote, spanned::Spanned, Attribute, Generics, Ident};
55

66
/// Generate a type parameter with the given `suffix` that does not conflict with
77
/// any of the `existing` generics.
@@ -13,25 +13,22 @@ fn gen_param(suffix: impl ToString, existing: &Generics) -> Ident {
1313
Ident::new(&suffix, Span::call_site())
1414
}
1515

16-
/// Return the `TyCtxt` interner for the given `structure`.
16+
/// Return the interner for the given `structure`.
1717
///
18-
/// If the input represented by `structure` has a `'tcx` lifetime parameter, then that will be used
19-
/// used as the lifetime of the `TyCtxt`. Otherwise a `'tcx` lifetime parameter that is unrelated
20-
/// to the input will be used.
18+
/// If the input represented by `structure` has a `'tcx` lifetime parameter, then we `TyCtxt<'tcx>`
19+
/// will be returned; otherwise our derived implementation will be generic over the interner.
2120
fn gen_interner(structure: &mut synstructure::Structure<'_>) -> TokenStream {
22-
let lt = structure
21+
structure
2322
.ast()
2423
.generics
2524
.lifetimes()
2625
.find_map(|def| (def.lifetime.ident == "tcx").then_some(&def.lifetime))
27-
.cloned()
26+
.map(|lt| quote! { ::rustc_middle::ty::TyCtxt<#lt> })
2827
.unwrap_or_else(|| {
29-
let tcx: Lifetime = parse_quote! { 'tcx };
30-
structure.add_impl_generic(LifetimeDef::new(tcx.clone()).into());
31-
tcx
32-
});
33-
34-
quote! { ::rustc_middle::ty::TyCtxt<#lt> }
28+
let ident = gen_param("I", &structure.ast().generics);
29+
structure.add_impl_generic(parse_quote! { #ident: ::rustc_type_ir::Interner });
30+
ident.into_token_stream()
31+
})
3532
}
3633

3734
/// Returns the `Span` of the first `#[skip_traversal]` attribute in `attrs`.

0 commit comments

Comments
 (0)