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};
},
_,
),
- ) => {
- 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")),
)?;
}
(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),