Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup (pretty) printing of ty::Const #59276

Merged
merged 27 commits into from
May 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
86d65d8
Remove unnecessary secondary recursion
oli-obk Mar 18, 2019
d85e866
Ignore .vscode even if it is a symlink
oli-obk Mar 26, 2019
8d4f4cd
Reuse the pretty printing architecture for printing of constants
oli-obk Mar 29, 2019
a92d97e
There's a tcx in scope, don't use the tls one
oli-obk Apr 2, 2019
5713677
Merge the string printing paths of ty::Const
oli-obk Apr 2, 2019
9d82107
Print const chars escaped with surrounding quotes
oli-obk Apr 2, 2019
e694b63
Don't use `ty::Const` without immediately interning
oli-obk Apr 3, 2019
264c149
Add test showing how byte slices are printed in MIR
oli-obk Apr 11, 2019
af6ac1f
Refactor string constant printing to prep for byte string printing
oli-obk Apr 11, 2019
fa17654
Make `ConstValue::Slice` solely take `[u8]` and `str`
oli-obk Apr 11, 2019
9b5896a
Render const byte slices in MIR
oli-obk Apr 11, 2019
669bc77
`u8` is printed as a number, not a character
oli-obk Apr 15, 2019
db652fc
Render unresolved anon consts like closures
oli-obk Apr 17, 2019
0528954
Group common printing code during constant pretty printing
oli-obk Apr 17, 2019
fec79d3
Print generic args in function calls in MIR
oli-obk Apr 17, 2019
90bb861
Fix tidy
oli-obk Apr 24, 2019
ecee75d
Use `write_char` to skip the formatting infrastructure
oli-obk Apr 24, 2019
b816ec1
Print unevaluted constants as `_` or as their source representation
oli-obk Apr 24, 2019
28198bb
Update ui tests
oli-obk Apr 24, 2019
89b2fb6
rustc: integrate ty::Const into ty::print as print_const.
eddyb Mar 18, 2019
52fa900
Break cycle during array length printing
oli-obk May 3, 2019
fa459a0
Fix rebase fallout
oli-obk May 7, 2019
825cfdb
Print types for unevaluated constants
oli-obk May 11, 2019
dd32795
Update ui tests
oli-obk May 11, 2019
a0275e3
Only print integers in symbol path's constants
oli-obk May 11, 2019
e694807
Fix missing tcx
varkor May 24, 2019
0b732aa
Update nll ui tests
oli-obk May 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ __pycache__/
.project
.settings/
.valgrindrc
.vscode/
.vscode
.favorites.json
/*-*-*-*/
/*-*-*/
Expand Down
8 changes: 8 additions & 0 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
type Region = !;
type Type = !;
type DynExistential = !;
type Const = !;

fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
self.tcx
Expand All @@ -488,6 +489,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Err(NonTrivialPath)
}

fn print_const(
self,
_ct: &'tcx ty::Const<'tcx>,
) -> Result<Self::Const, Self::Error> {
Err(NonTrivialPath)
}

fn path_crate(
self,
cnum: CrateNum,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {

ConstValue::Param(_) |
ConstValue::Scalar(_) |
ConstValue::Slice(..) |
ConstValue::Slice { .. } |
ConstValue::ByRef(..) |
ConstValue::Unevaluated(..) => {}
}
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
type Region = ();
type Type = ();
type DynExistential = ();
type Const = ();

fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
Expand All @@ -807,7 +808,14 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}

fn print_const(
self,
_ct: &'tcx ty::Const<'tcx>,
) -> Result<Self::Const, Self::Error> {
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl ErrorHandled {
}

pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<ty::Const<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> {
Expand Down
26 changes: 8 additions & 18 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,12 @@ pub enum ConstValue<'tcx> {
/// Not using the enum `Value` to encode that this must not be `Undef`.
Scalar(Scalar),

/// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box<str>`,
/// etc.).
///
/// Empty slices don't necessarily have an address backed by an `AllocId`, thus we also need to
/// enable integer pointers. The `Scalar` type covers exactly those two cases. While we could
/// create dummy-`AllocId`s, the additional code effort for the conversions doesn't seem worth
/// it.
Slice(Scalar, u64),
/// Used only for `&[u8]` and `&str`
Slice {
data: &'tcx Allocation,
start: usize,
end: usize,
},

/// An allocation together with a pointer into the allocation.
/// Invariant: the pointer's `AllocId` resolves to the allocation.
Expand All @@ -54,7 +52,7 @@ pub enum ConstValue<'tcx> {
}

#[cfg(target_arch = "x86_64")]
static_assert_size!(ConstValue<'_>, 40);
static_assert_size!(ConstValue<'_>, 32);

impl<'tcx> ConstValue<'tcx> {
#[inline]
Expand All @@ -65,7 +63,7 @@ impl<'tcx> ConstValue<'tcx> {
ConstValue::Placeholder(_) |
ConstValue::ByRef(..) |
ConstValue::Unevaluated(..) |
ConstValue::Slice(..) => None,
ConstValue::Slice { .. } => None,
ConstValue::Scalar(val) => Some(val),
}
}
Expand All @@ -79,14 +77,6 @@ impl<'tcx> ConstValue<'tcx> {
pub fn try_to_ptr(&self) -> Option<Pointer> {
self.try_to_scalar()?.to_ptr().ok()
}

#[inline]
pub fn new_slice(
val: Scalar,
len: u64,
) -> Self {
ConstValue::Slice(val, len)
}
}

/// A `Scalar` represents an immediate, primitive value existing outside of a
Expand Down
111 changes: 26 additions & 85 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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};
Expand Down Expand Up @@ -1662,28 +1660,25 @@ impl<'tcx> TerminatorKind<'tcx> {
switch_ty,
..
} => {
let size = ty::tls::with(|tcx| {
ty::tls::with(|tcx| {
let param_env = ty::ParamEnv::empty();
let switch_ty = tcx.lift_to_global(&switch_ty).unwrap();
tcx.layout_of(param_env.and(switch_ty)).unwrap().size
});
values
.iter()
.map(|&u| {
let mut s = String::new();
let c = ty::Const {
val: ConstValue::Scalar(
Scalar::Bits {
bits: u,
size: size.bytes() as u8,
}.into(),
),
ty: switch_ty,
};
fmt_const_val(&mut s, c).unwrap();
s.into()
}).chain(iter::once("otherwise".into()))
.collect()
let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
values
.iter()
.map(|&u| {
tcx.mk_const(ty::Const {
val: ConstValue::Scalar(
Scalar::Bits {
bits: u,
size: size.bytes() as u8,
}.into(),
),
ty: switch_ty,
}).to_string().into()
}).chain(iter::once("otherwise".into()))
.collect()
})
}
Call {
destination: Some(_),
Expand Down Expand Up @@ -2331,9 +2326,7 @@ impl<'tcx> Operand<'tcx> {
span,
ty,
user_ty: None,
literal: tcx.mk_const(
ty::Const::zero_sized(ty),
),
literal: ty::Const::zero_sized(tcx, ty),
})
}

Expand Down Expand Up @@ -2827,67 +2820,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> {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,6 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = tcx.mk_const(evaluated);
let evaluated = evaluated.subst(tcx, substs);
return evaluated;
}
Expand All @@ -426,7 +425,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
promoted: None
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
return tcx.mk_const(evaluated);
return evaluated;
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = tcx.mk_const(evaluated);
let evaluated = evaluated.subst(tcx, substs);
return evaluated;
}
Expand All @@ -216,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
promoted: None,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
return tcx.mk_const(evaluated);
return evaluated;
}
}
}
Expand Down
19 changes: 6 additions & 13 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::middle::lang_items;
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::{self, Mir, interpret, ProjectionKind};
use crate::mir::interpret::{ConstValue, Allocation};
use crate::mir::interpret::{ConstValue, Allocation, Scalar};
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
use crate::ty::ReprOptions;
use crate::traits;
Expand Down Expand Up @@ -1000,7 +1000,10 @@ impl<'tcx> CommonConsts<'tcx> {
};

CommonConsts {
err: mk_const(ty::Const::zero_sized(types.err)),
err: mk_const(ty::Const {
val: ConstValue::Scalar(Scalar::Bits { bits: 0, size: 0 }),
ty: types.err,
}),
}
}
}
Expand Down Expand Up @@ -1822,14 +1825,6 @@ nop_list_lift!{ProjectionKind => ProjectionKind}
// this is the impl for `&'a InternalSubsts<'a>`
nop_list_lift!{Kind<'a> => Kind<'tcx>}

impl<'a, 'tcx> Lift<'tcx> for &'a mir::interpret::Allocation {
type Lifted = &'tcx mir::interpret::Allocation;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
assert!(tcx.global_arenas.const_allocs.in_arena(*self as *const _));
Some(unsafe { mem::transmute(*self) })
}
}

pub mod tls {
use super::{GlobalCtxt, TyCtxt, ptr_eq};

Expand Down Expand Up @@ -2594,9 +2589,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

#[inline]
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
self.mk_ty(Array(ty, self.mk_const(
ty::Const::from_usize(self.global_tcx(), n)
)))
self.mk_ty(Array(ty, ty::Const::from_usize(self.global_tcx(), n)))
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
let flags = FlagComputation::for_const(c);
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
flags.intersects(self.flags) || c.super_visit_with(self)
flags.intersects(self.flags)
}
}

Expand Down
Loading