Rollup merge of #115907 - RalfJung:interner-check, r=compiler-errors

nop_lift macros: ensure that we are using the right interner

Right now someone could put down the wrong list name when using these macros, and everything would still build. Nothing does a type-check to ensure that the `$set` contains element of type `Self::Lifted`. Let's fix that.

For lists this is fairly easy; for the other interners we need to unwrap some newtypes which makes this more complicated.
This commit is contained in:
Matthias Krüger 2023-09-18 13:02:19 +02:00 committed by GitHub
commit 0d29cdd187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1214,6 +1214,25 @@ macro_rules! nop_lift {
impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type.
// Given an argument that has an interned type, the return type has the type of
// the corresponding interner set. This won't actually return anything, we're
// just doing this to compute said type!
fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
_x: Interned<'tcx, Inner>,
) -> InternedSet<'tcx, Inner> {
unreachable!()
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
// If `x` is a newtype around an `Interned<T>`, then `interner` is an
// interner of appropriate type. (Ideally we'd also check that `x` is a
// newtype with just that one field. Not sure how to do that.)
let interner = _intern_set_ty_from_interned_ty(x.0);
// Now check that this is the same type as `interners.$set`.
_type_eq(&interner, &tcx.interners.$set);
}
tcx.interners
.$set
.contains_pointer_to(&InternedInSet(&*self.0.0))
@ -1230,6 +1249,11 @@ macro_rules! nop_list_lift {
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
type Lifted = &'tcx List<$lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type.
if false {
let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
}
if self.is_empty() {
return Some(List::empty());
}