about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-03-29 10:52:09 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-05-25 10:07:01 +0200
commit8d4f4cdadafe7c7deca5bc3a2725a380cfe9d01b (patch)
treebd3c49b645decde412da33aa3655a23fb3568d4f
parentd85e866c0d28fce32856d200fd534ac1c2c721c8 (diff)
downloadrust-8d4f4cdadafe7c7deca5bc3a2725a380cfe9d01b.tar.gz
rust-8d4f4cdadafe7c7deca5bc3a2725a380cfe9d01b.zip
Reuse the pretty printing architecture for printing of constants
-rw-r--r--src/librustc/mir/mod.rs77
-rw-r--r--src/librustc/ty/print/pretty.rs59
-rw-r--r--src/librustc/ty/structural_impls.rs33
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs8
-rw-r--r--src/librustdoc/clean/mod.rs3
5 files changed, 100 insertions, 80 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 6de4350c2aa..e44493dec2c 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -9,8 +9,6 @@ use crate::hir::def_id::DefId;
 use crate::hir::{self, InlineAsm as HirInlineAsm};
 use crate::mir::interpret::{ConstValue, InterpError, Scalar};
 use crate::mir::visit::MirVisitable;
-use rustc_apfloat::ieee::{Double, Single};
-use rustc_apfloat::Float;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::dominators::{dominators, Dominators};
 use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
@@ -21,13 +19,13 @@ use rustc_macros::HashStable;
 use crate::rustc_serialize::{self as serialize};
 use smallvec::SmallVec;
 use std::borrow::Cow;
-use std::fmt::{self, Debug, Formatter, Write};
+use std::fmt::{self, Debug, Formatter, Write, Display};
 use std::iter::FusedIterator;
 use std::ops::{Index, IndexMut};
 use std::slice;
 use std::vec::IntoIter;
 use std::{iter, mem, option, u32};
-use syntax::ast::{self, Name};
+use syntax::ast::Name;
 use syntax::symbol::{InternedString, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -1670,8 +1668,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                 values
                     .iter()
                     .map(|&u| {
-                        let mut s = String::new();
-                        let c = ty::Const {
+                        (&ty::Const {
                             val: ConstValue::Scalar(
                                 Scalar::Bits {
                                     bits: u,
@@ -1679,9 +1676,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                                 }.into(),
                             ),
                             ty: switch_ty,
-                        };
-                        fmt_const_val(&mut s, c).unwrap();
-                        s.into()
+                        }).to_string().into()
                     }).chain(iter::once("otherwise".into()))
                     .collect()
             }
@@ -2827,67 +2822,15 @@ newtype_index! {
 
 impl<'tcx> Debug for Constant<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(fmt, "const ")?;
-        fmt_const_val(fmt, *self.literal)
-    }
-}
-/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
-pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result {
-    use crate::ty::TyKind::*;
-    let value = const_val.val;
-    let ty = const_val.ty;
-    // print some primitives
-    if let ConstValue::Scalar(Scalar::Bits { bits, .. }) = value {
-        match ty.sty {
-            Bool if bits == 0 => return write!(f, "false"),
-            Bool if bits == 1 => return write!(f, "true"),
-            Float(ast::FloatTy::F32) => return write!(f, "{}f32", Single::from_bits(bits)),
-            Float(ast::FloatTy::F64) => return write!(f, "{}f64", Double::from_bits(bits)),
-            Uint(ui) => return write!(f, "{:?}{}", bits, ui),
-            Int(i) => {
-                let bit_width = ty::tls::with(|tcx| {
-                    let ty = tcx.lift_to_global(&ty).unwrap();
-                    tcx.layout_of(ty::ParamEnv::empty().and(ty))
-                        .unwrap()
-                        .size
-                        .bits()
-                });
-                let shift = 128 - bit_width;
-                return write!(f, "{:?}{}", ((bits as i128) << shift) >> shift, i);
-            }
-            Char => return write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap()),
-            _ => {}
-        }
+        write!(fmt, "{}", self)
     }
-    // print function definitions
-    if let FnDef(did, _) = ty.sty {
-        return write!(f, "{}", def_path_str(did));
-    }
-    // print string literals
-    if let ConstValue::Slice(ptr, len) = value {
-        if let Scalar::Ptr(ptr) = ptr {
-            if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
-                return ty::tls::with(|tcx| {
-                    let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
-                    if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
-                        assert_eq!(len as usize as u64, len);
-                        let slice =
-                            &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
-                        let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
-                        write!(f, "{:?}", s)
-                    } else {
-                        write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
-                    }
-                });
-            }
-        }
-    }
-    // just raw dump everything else
-    write!(f, "{:?} : {}", value, ty)
 }
 
-fn def_path_str(def_id: DefId) -> String {
-    ty::tls::with(|tcx| tcx.def_path_str(def_id))
+impl<'tcx> Display for Constant<'tcx> {
+    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
+        write!(fmt, "const ")?;
+        write!(fmt, "{}", self.literal)
+    }
 }
 
 impl<'tcx> graph::DirectedGraph for Mir<'tcx> {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 06db4b9b65b..87be78857e3 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -6,7 +6,10 @@ use crate::middle::cstore::{ExternCrate, ExternCrateSource};
 use crate::middle::region;
 use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
 use crate::ty::subst::{Kind, Subst, UnpackedKind};
-use crate::mir::interpret::ConstValue;
+use crate::mir::interpret::{ConstValue, sign_extend, Scalar};
+use syntax::ast;
+use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
 use rustc_target::spec::abi::Abi;
 use syntax::symbol::{kw, InternedString};
 
@@ -1533,12 +1536,54 @@ define_print_and_forward_display! {
         p!(print_def_path(self.def_id, self.substs));
     }
 
-    &'tcx ty::Const<'tcx> {
-        match self.val {
-            ConstValue::Unevaluated(..) |
-            ConstValue::Infer(..) => p!(write("_")),
-            ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
-            _ => p!(write("{:?}", self)),
+    ty::Const<'tcx> {
+        match (self.val, &self.ty.sty) {
+            | (ConstValue::Unevaluated(..), _)
+            | (ConstValue::Infer(..), _)
+            => p!(write("_: "), print(self.ty)),
+            (ConstValue::Param(ParamConst { name, .. }), _) => p!(write("{}", name)),
+            (ConstValue::Scalar(Scalar::Bits { bits: 0, .. }), ty::Bool) => p!(write("false")),
+            (ConstValue::Scalar(Scalar::Bits { bits: 1, .. }), ty::Bool) => p!(write("true")),
+            (ConstValue::Scalar(Scalar::Bits { bits, .. }), ty::Float(ast::FloatTy::F32)) =>
+                p!(write(
+                    "{}f32",
+                    Single::from_bits(bits)
+                )),
+            (ConstValue::Scalar(Scalar::Bits { bits, .. }), ty::Float(ast::FloatTy::F64)) =>
+                p!(write(
+                    "{}f64",
+                    Double::from_bits(bits)
+                )),
+            (ConstValue::Scalar(Scalar::Bits { bits, ..}), ty::Uint(ui)) =>
+                p!(write("{}{}", bits, ui)),
+            (ConstValue::Scalar(Scalar::Bits { bits, ..}), ty::Int(i)) => {
+                let size = ty::tls::with(|tcx| {
+                    let ty = tcx.lift_to_global(&self.ty).unwrap();
+                    tcx.layout_of(ty::ParamEnv::empty().and(ty))
+                        .unwrap()
+                        .size
+                });
+                p!(write("{}{}", sign_extend(bits, size) as i128, i))
+            },
+            (ConstValue::Scalar(Scalar::Bits { bits, ..}), ty::Char)
+                => p!(write("{}", ::std::char::from_u32(bits as u32).unwrap())),
+            (_, ty::FnDef(did, _)) => p!(write("{}", ty::tls::with(|tcx| tcx.def_path_str(*did)))),
+            (ConstValue::Slice(_, 0), ty::Ref(_, &ty::TyS { sty: ty::Str, .. }, _)) =>
+                p!(write("\"\"")),
+            (
+                ConstValue::Slice(Scalar::Ptr(ptr), len),
+                ty::Ref(_, &ty::TyS { sty: ty::Str, .. }, _),
+            ) => {
+                ty::tls::with(|tcx| {
+                    let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
+                    assert_eq!(len as usize as u64, len);
+                    let slice =
+                        &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
+                    let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
+                    Ok(p!(write("{:?}", s)))
+                })?;
+            },
+            _ => p!(write("{:?} : ", self.val), print(self.ty)),
         }
     }
 
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index cf04d6eac3a..35d0359dbcf 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -295,6 +295,9 @@ CloneTypeFoldableAndLiftImpls! {
     (),
     bool,
     usize,
+    u32,
+    crate::ty::BoundVar,
+    crate::ty::DebruijnIndex,
     crate::ty::layout::VariantIdx,
     u64,
     String,
@@ -311,6 +314,8 @@ CloneTypeFoldableAndLiftImpls! {
     ::rustc_target::spec::abi::Abi,
     crate::mir::Local,
     crate::mir::Promoted,
+    crate::mir::interpret::Scalar,
+    crate::mir::interpret::Pointer,
     crate::traits::Reveal,
     crate::ty::adjustment::AutoBorrowMutability,
     crate::ty::AdtKind,
@@ -788,6 +793,34 @@ BraceStructLiftImpl! {
     }
 }
 
+BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
+        type Lifted = ty::Const<'tcx>;
+        val, ty
+    }
+}
+
+EnumLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for interpret::ConstValue<'a> {
+        type Lifted = interpret::ConstValue<'tcx>;
+        (interpret::ConstValue::Unevaluated)(a, b),
+        (interpret::ConstValue::Param)(a),
+        (interpret::ConstValue::Infer)(a),
+        (interpret::ConstValue::Scalar)(a),
+        (interpret::ConstValue::Slice)(a, b),
+        (interpret::ConstValue::ByRef)(a, b),
+    }
+}
+
+EnumLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for ty::InferConst<'a> {
+        type Lifted = ty::InferConst<'tcx>;
+        (ty::InferConst::Var)(a),
+        (ty::InferConst::Fresh)(a),
+        (ty::InferConst::Canonical)(a, b),
+    }
+}
+
 impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
     type Lifted = ConstVid<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 0576bb53d8f..a3e43d64819 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -10,7 +10,7 @@ use crate::const_eval::{const_field, const_variant_index};
 use crate::hair::util::UserAnnotatedTyHelpers;
 use crate::hair::constant::*;
 
-use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
+use rustc::mir::{Field, BorrowKind, Mutability};
 use rustc::mir::{UserTypeProjection};
 use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
 use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
@@ -291,15 +291,15 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
                 write!(f, "{}", subpattern)
             }
             PatternKind::Constant { value } => {
-                fmt_const_val(f, value)
+                write!(f, "{}", &value)
             }
             PatternKind::Range(PatternRange { lo, hi, ty: _, end }) => {
-                fmt_const_val(f, lo)?;
+                write!(f, "{}", &lo)?;
                 match end {
                     RangeEnd::Included => write!(f, "..=")?,
                     RangeEnd::Excluded => write!(f, "..")?,
                 }
-                fmt_const_val(f, hi)
+                write!(f, "{}", &hi)
             }
             PatternKind::Slice { ref prefix, ref slice, ref suffix } |
             PatternKind::Array { ref prefix, ref slice, ref suffix } => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9c3f522d847..f344c529c59 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -4136,8 +4136,7 @@ fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
             }
         },
         _ => {
-            let mut s = String::new();
-            ::rustc::mir::fmt_const_val(&mut s, n).expect("fmt_const_val failed");
+            let mut s = n.to_string();
             // array lengths are obviously usize
             if s.ends_with("usize") {
                 let n = s.len() - "usize".len();