|
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