use crate::hir;
-use crate::hir::def::Namespace;
+use crate::hir::def::{Namespace, Def};
use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
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::ty::layout::Size;
+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::{keywords, InternedString};
+use syntax::symbol::{kw, InternedString};
use std::cell::Cell;
use std::fmt::{self, Write as _};
// 2. for an extern inferred from a path or an indirect crate,
// where there is no explicit `extern crate`, we just prepend
// the crate name.
- match *self.tcx().extern_crate(def_id) {
- Some(ExternCrate {
+ match self.tcx().extern_crate(def_id) {
+ Some(&ExternCrate {
src: ExternCrateSource::Extern(def_id),
direct: true,
span,
if self.tcx.sess.rust_2018() {
// We add the `crate::` keyword on Rust 2018, only when desired.
if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
- write!(self, "{}", keywords::Crate.name())?;
+ write!(self, "{}", kw::Crate)?;
self.empty_path = false;
}
}
match *region {
ty::ReEarlyBound(ref data) => {
- data.name.as_symbol() != keywords::Invalid.name() &&
- data.name.as_symbol() != keywords::UnderscoreLifetime.name()
+ data.name.as_symbol() != kw::Invalid &&
+ data.name.as_symbol() != kw::UnderscoreLifetime
}
ty::ReLateBound(_, br) |
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
if let ty::BrNamed(_, name) = br {
- if name.as_symbol() != keywords::Invalid.name() &&
- name.as_symbol() != keywords::UnderscoreLifetime.name() {
+ if name.as_symbol() != kw::Invalid &&
+ name.as_symbol() != kw::UnderscoreLifetime {
return true;
}
}
// `explain_region()` or `note_and_explain_region()`.
match *region {
ty::ReEarlyBound(ref data) => {
- if data.name.as_symbol() != keywords::Invalid.name() {
+ if data.name.as_symbol() != kw::Invalid {
p!(write("{}", data.name));
return Ok(self);
}
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
if let ty::BrNamed(_, name) = br {
- if name.as_symbol() != keywords::Invalid.name() &&
- name.as_symbol() != keywords::UnderscoreLifetime.name() {
+ if name.as_symbol() != kw::Invalid &&
+ name.as_symbol() != kw::UnderscoreLifetime {
p!(write("{}", name));
return Ok(self);
}
}
&'tcx ty::Const<'tcx> {
- match self.val {
- ConstValue::Unevaluated(..) |
- ConstValue::Infer(..) => p!(write("_")),
- ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
- _ => p!(write("{:?}", self)),
+ let u8 = cx.tcx().types.u8;
+ if let ty::FnDef(did, _) = self.ty.sty {
+ p!(write("{}", cx.tcx().def_path_str(did)));
+ return Ok(cx);
+ }
+ if let ConstValue::Unevaluated(did, substs) = self.val {
+ match cx.tcx().describe_def(did) {
+ | Some(Def::Static(_, _))
+ | Some(Def::Const(_, false))
+ | Some(Def::AssociatedConst(_)) => p!(write("{}", cx.tcx().def_path_str(did))),
+ _ => p!(write("_")),
+ }
+ return Ok(cx);
+ }
+ if let ConstValue::Infer(..) = self.val {
+ p!(write("_: "), print(self.ty));
+ return Ok(cx);
+ }
+ if let ConstValue::Param(ParamConst { name, .. }) = self.val {
+ p!(write("{}", name));
+ return Ok(cx);
+ }
+ if let ConstValue::Scalar(Scalar::Bits { bits, .. }) = self.val {
+ match self.ty.sty {
+ ty::Bool => {
+ p!(write("{}", if bits == 0 { "false" } else { "true" }));
+ return Ok(cx);
+ },
+ ty::Float(ast::FloatTy::F32) => {
+ p!(write("{}f32", Single::from_bits(bits)));
+ return Ok(cx);
+ },
+ ty::Float(ast::FloatTy::F64) => {
+ p!(write("{}f64", Double::from_bits(bits)));
+ return Ok(cx);
+ },
+ ty::Uint(ui) => {
+ p!(write("{}{}", bits, ui));
+ return Ok(cx);
+ },
+ ty::Int(i) =>{
+ let ty = cx.tcx().lift_to_global(&self.ty).unwrap();
+ let size = cx.tcx().layout_of(ty::ParamEnv::empty().and(ty))
+ .unwrap()
+ .size;
+ p!(write("{}{}", sign_extend(bits, size) as i128, i));
+ return Ok(cx);
+ },
+ ty::Char => {
+ p!(write("{:?}", ::std::char::from_u32(bits as u32).unwrap()));
+ return Ok(cx);
+ }
+ _ => {},
+ }
+ }
+ if let ty::Ref(_, ref_ty, _) = self.ty.sty {
+ let byte_str = match (self.val, &ref_ty.sty) {
+ (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
+ let n = n.unwrap_usize(cx.tcx());
+ Some(cx.tcx()
+ .alloc_map.lock()
+ .unwrap_memory(ptr.alloc_id)
+ .get_bytes(&cx.tcx(), ptr, Size::from_bytes(n)).unwrap())
+ },
+ (ConstValue::Slice { data, start, end }, ty::Slice(t)) if *t == u8 => {
+ Some(&data.bytes[start..end])
+ },
+ (ConstValue::Slice { data, start, end }, ty::Str) => {
+ let slice = &data.bytes[start..end];
+ let s = ::std::str::from_utf8(slice)
+ .expect("non utf8 str from miri");
+ p!(write("{:?}", s));
+ return Ok(cx);
+ },
+ _ => None,
+ };
+ if let Some(byte_str) = byte_str {
+ p!(write("b\""));
+ for &c in byte_str {
+ for e in std::ascii::escape_default(c) {
+ p!(write("{}", e as char));
+ }
+ }
+ p!(write("\""));
+ return Ok(cx);
+ }
}
+ p!(write("{:?} : ", self.val), print(self.ty));
}
ty::ParamTy {