diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-09-18 13:02:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-18 13:02:19 +0200 |
| commit | 0d29cdd18794dd72901d2f4093b99bf0fec32ca7 (patch) | |
| tree | 7ddd2636950502bff925b72f98c9b717172a46a8 | |
| parent | 497701876f549cd2c39eb789cc98b30a850265ab (diff) | |
| parent | 3b817b2810ff7ecacab02f901f2a1a2902e5e72f (diff) | |
| download | rust-0d29cdd18794dd72901d2f4093b99bf0fec32ca7.tar.gz rust-0d29cdd18794dd72901d2f4093b99bf0fec32ca7.zip | |
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.
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 880d3029451..e8d50a1c025 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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()); } |
