From d59fa081ec272573ef560c4ea914466fce74db3c Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 25 May 2020 08:52:16 +0200
Subject: [PATCH] fix ICE when debug-printing MIR

---
 src/librustc_middle/ty/print/pretty.rs | 30 +++++++++++++++++---------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index f03d91aa64b78..a47addf18044c 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -1,5 +1,7 @@
 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
-use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar};
+use crate::mir::interpret::{
+    sign_extend, truncate, AllocId, ConstValue, GlobalAlloc, Pointer, Scalar,
+};
 use crate::ty::layout::IntegerExt;
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
 use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
@@ -951,15 +953,20 @@ pub trait PrettyPrinter<'tcx>:
                     },
                     _,
                 ),
-            ) => {
-                let byte_str = self
-                    .tcx()
-                    .global_alloc(ptr.alloc_id)
-                    .unwrap_memory()
-                    .get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
-                    .unwrap();
-                p!(pretty_print_byte_str(byte_str));
-            }
+            ) => match self.tcx().get_global_alloc(ptr.alloc_id) {
+                Some(GlobalAlloc::Memory(alloc)) => {
+                    if let Ok(byte_str) = alloc.get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
+                    {
+                        p!(pretty_print_byte_str(byte_str))
+                    } else {
+                        p!(write("<too short allocation>"))
+                    }
+                }
+                // FIXME: for statics and functions, we could in principle print more detail.
+                Some(GlobalAlloc::Static(def_id)) => p!(write("<static({:?})>", def_id)),
+                Some(GlobalAlloc::Function(_)) => p!(write("<function>")),
+                None => p!(write("<dangling pointer>")),
+            },
             // Bool
             (Scalar::Raw { data: 0, .. }, ty::Bool) => p!(write("false")),
             (Scalar::Raw { data: 1, .. }, ty::Bool) => p!(write("true")),
@@ -1018,6 +1025,9 @@ pub trait PrettyPrinter<'tcx>:
                 )?;
             }
             (Scalar::Ptr(ptr), ty::FnPtr(_)) => {
+                // FIXME: this can ICE when the ptr is dangling or points to a non-function.
+                // We should probably have a helper method to share code with the "Byte strings"
+                // printing above (which also has to handle pointers to all sorts of things).
                 let instance = self.tcx().global_alloc(ptr.alloc_id).unwrap_fn();
                 self = self.typed_value(
                     |this| this.print_value_path(instance.def_id(), instance.substs),