|
3 | 3 |
|
4 | 4 | use std::convert::{TryFrom, TryInto}; |
5 | 5 |
|
6 | | -use rustc::ty::layout::{ |
7 | | - self, HasDataLayout, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, |
8 | | -}; |
9 | | -use rustc::{mir, ty}; |
10 | | - |
11 | 6 | use super::{InterpCx, MPlaceTy, Machine, MemPlace, Place, PlaceTy}; |
12 | 7 | pub use rustc::mir::interpret::ScalarMaybeUndef; |
13 | 8 | use rustc::mir::interpret::{ |
14 | 9 | sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar, |
15 | 10 | }; |
16 | | -use rustc_ast::ast; |
| 11 | +use rustc::ty::layout::{ |
| 12 | + self, HasDataLayout, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, |
| 13 | +}; |
| 14 | +use rustc::ty::print::{FmtPrinter, PrettyPrinter, Printer}; |
| 15 | +use rustc::ty::Ty; |
| 16 | +use rustc::{mir, ty}; |
| 17 | +use rustc_hir::def::Namespace; |
17 | 18 | use rustc_macros::HashStable; |
| 19 | +use std::fmt::Write; |
18 | 20 |
|
19 | 21 | /// An `Immediate` represents a single immediate self-contained Rust value. |
20 | 22 | /// |
@@ -92,47 +94,44 @@ pub struct ImmTy<'tcx, Tag = ()> { |
92 | 94 | pub layout: TyLayout<'tcx>, |
93 | 95 | } |
94 | 96 |
|
95 | | -// `Tag: Copy` because some methods on `Scalar` consume them by value |
96 | 97 | impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> { |
97 | | - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
98 | | - match &self.imm { |
99 | | - // We cannot use `to_bits_or_ptr` as we do not have a `tcx`. |
100 | | - // So we use `is_bits` and circumvent a bunch of sanity checking -- but |
101 | | - // this is anyway only for printing. |
102 | | - Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) if s.is_ptr() => { |
103 | | - fmt.write_str("{pointer}") |
| 98 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 99 | + /// Helper function for printing a scalar to a FmtPrinter |
| 100 | + fn p<'a, 'tcx, F: std::fmt::Write, Tag>( |
| 101 | + cx: FmtPrinter<'a, 'tcx, F>, |
| 102 | + s: ScalarMaybeUndef<Tag>, |
| 103 | + ty: Ty<'tcx>, |
| 104 | + ) -> Result<FmtPrinter<'a, 'tcx, F>, std::fmt::Error> { |
| 105 | + match s { |
| 106 | + ScalarMaybeUndef::Scalar(s) => { |
| 107 | + cx.pretty_print_const_scalar(s.erase_tag(), ty, true) |
| 108 | + } |
| 109 | + ScalarMaybeUndef::Undef => cx.typed_value( |
| 110 | + |mut this| { |
| 111 | + this.write_str("{undef ")?; |
| 112 | + Ok(this) |
| 113 | + }, |
| 114 | + |this| this.print_type(ty), |
| 115 | + " ", |
| 116 | + ), |
104 | 117 | } |
105 | | - Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) => { |
106 | | - let s = s.assert_bits(self.layout.size); |
107 | | - match self.layout.ty.kind { |
108 | | - ty::Int(_) => { |
109 | | - return write!(fmt, "{}", super::sign_extend(s, self.layout.size) as i128,); |
110 | | - } |
111 | | - ty::Uint(_) => return write!(fmt, "{}", s), |
112 | | - ty::Bool if s == 0 => return fmt.write_str("false"), |
113 | | - ty::Bool if s == 1 => return fmt.write_str("true"), |
114 | | - ty::Char => { |
115 | | - if let Some(c) = u32::try_from(s).ok().and_then(std::char::from_u32) { |
116 | | - return write!(fmt, "{}", c); |
117 | | - } |
118 | | - } |
119 | | - ty::Float(ast::FloatTy::F32) => { |
120 | | - if let Ok(u) = u32::try_from(s) { |
121 | | - return write!(fmt, "{}", f32::from_bits(u)); |
122 | | - } |
123 | | - } |
124 | | - ty::Float(ast::FloatTy::F64) => { |
125 | | - if let Ok(u) = u64::try_from(s) { |
126 | | - return write!(fmt, "{}", f64::from_bits(u)); |
127 | | - } |
| 118 | + } |
| 119 | + ty::tls::with(|tcx| { |
| 120 | + match self.imm { |
| 121 | + Immediate::Scalar(s) => { |
| 122 | + if let Some(ty) = tcx.lift(&self.layout.ty) { |
| 123 | + let cx = FmtPrinter::new(tcx, f, Namespace::ValueNS); |
| 124 | + p(cx, s, ty)?; |
| 125 | + return Ok(()); |
128 | 126 | } |
129 | | - _ => {} |
| 127 | + write!(f, "{:?}: {}", s.erase_tag(), self.layout.ty) |
| 128 | + } |
| 129 | + Immediate::ScalarPair(a, b) => { |
| 130 | + // FIXME(oli-obk): at least print tuples and slices nicely |
| 131 | + write!(f, "({:?}, {:?}): {}", a.erase_tag(), b.erase_tag(), self.layout.ty,) |
130 | 132 | } |
131 | | - write!(fmt, "{:x}", s) |
132 | 133 | } |
133 | | - Immediate::Scalar(ScalarMaybeUndef::Undef) => fmt.write_str("{undef}"), |
134 | | - Immediate::ScalarPair(..) => fmt.write_str("{wide pointer or tuple}"), |
135 | | - } |
| 134 | + }) |
136 | 135 | } |
137 | 136 | } |
138 | 137 |
|
|
0 commit comments