+struct LiteralExpander<'a, 'tcx> {
+ tcx: TyCtxt<'a, 'tcx, 'tcx>
+}
+
+impl<'a, 'tcx> LiteralExpander<'a, 'tcx> {
+ /// Derefs `val` and potentially unsizes the value if `crty` is an array and `rty` a slice
+ fn fold_const_value_deref(
+ &mut self,
+ val: ConstValue<'tcx>,
+ rty: Ty<'tcx>,
+ crty: Ty<'tcx>,
+ ) -> ConstValue<'tcx> {
+ match (val, &crty.sty, &rty.sty) {
+ // the easy case, deref a reference
+ (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => ConstValue::ByRef(
+ p.alloc_id,
+ self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
+ p.offset,
+ ),
+ // unsize array to slice if pattern is array but match value or other patterns are slice
+ (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
+ assert_eq!(t, u);
+ ConstValue::ScalarPair(
+ Scalar::Ptr(p),
+ n.val.try_to_scalar().unwrap(),
+ )
+ },
+ // fat pointers stay the same
+ (ConstValue::ScalarPair(..), _, _) => val,
+ // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used
+ _ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),
+ }
+ }
+}
+
+impl<'a, 'tcx> PatternFolder<'tcx> for LiteralExpander<'a, 'tcx> {