implement valtrees as the type-system representation for constant values
This commit is contained in:
@@ -5,7 +5,6 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::CtorKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::print::{Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
@@ -604,16 +603,18 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
||||
if let Some(&i) = self.consts.get(&ct) {
|
||||
return self.print_backref(i);
|
||||
}
|
||||
|
||||
let start = self.out.len();
|
||||
let ty = ct.ty();
|
||||
|
||||
match ct.ty().kind() {
|
||||
match ty.kind() {
|
||||
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
|
||||
self = ct.ty().print(self)?;
|
||||
self = ty.print(self)?;
|
||||
|
||||
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty());
|
||||
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ty);
|
||||
|
||||
// Negative integer values are mangled using `n` as a "sign prefix".
|
||||
if let ty::Int(ity) = ct.ty().kind() {
|
||||
if let ty::Int(ity) = ty.kind() {
|
||||
let val =
|
||||
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
|
||||
if val < 0 {
|
||||
@@ -626,45 +627,57 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
||||
}
|
||||
|
||||
// HACK(eddyb) because `ty::Const` only supports sized values (for now),
|
||||
// we can't use `deref_const` + supporting `str`, we have to specially
|
||||
// we can't use dereference the const + supporting `str`, we have to specially
|
||||
// handle `&str` and include both `&` ("R") and `str` ("e") prefixes.
|
||||
ty::Ref(_, ty, hir::Mutability::Not) if *ty == self.tcx.types.str_ => {
|
||||
self.push("R");
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => {
|
||||
// NOTE(eddyb) the following comment was kept from `ty::print::pretty`:
|
||||
// The `inspect` here is okay since we checked the bounds, and there are no
|
||||
// relocations (we have an active `str` reference here). We don't use this
|
||||
// result to affect interpreter execution.
|
||||
let slice = data
|
||||
.inner()
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(start..end);
|
||||
let s = std::str::from_utf8(slice).expect("non utf8 str from miri");
|
||||
|
||||
self.push("e");
|
||||
// FIXME(eddyb) use a specialized hex-encoding loop.
|
||||
for byte in s.bytes() {
|
||||
let _ = write!(self.out, "{:02x}", byte);
|
||||
}
|
||||
self.push("_");
|
||||
}
|
||||
|
||||
_ => {
|
||||
bug!("symbol_names: unsupported `&str` constant: {:?}", ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::Ref(_, _, mutbl) => {
|
||||
ty::Ref(_, inner_ty, mutbl) => {
|
||||
self.push(match mutbl {
|
||||
hir::Mutability::Not => "R",
|
||||
hir::Mutability::Mut => "Q",
|
||||
});
|
||||
self = self.tcx.deref_const(ty::ParamEnv::reveal_all().and(ct)).print(self)?;
|
||||
|
||||
match inner_ty.kind() {
|
||||
ty::Str if *mutbl == hir::Mutability::Not => {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Value(valtree) => {
|
||||
let slice =
|
||||
valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
|
||||
bug!(
|
||||
"expected to get raw bytes from valtree {:?} for type {:}",
|
||||
valtree, ty
|
||||
)
|
||||
});
|
||||
let s = std::str::from_utf8(slice).expect("non utf8 str from miri");
|
||||
|
||||
self.push("e");
|
||||
|
||||
// FIXME(eddyb) use a specialized hex-encoding loop.
|
||||
for byte in s.bytes() {
|
||||
let _ = write!(self.out, "{:02x}", byte);
|
||||
}
|
||||
|
||||
self.push("_");
|
||||
}
|
||||
|
||||
_ => {
|
||||
bug!("symbol_names: unsupported `&str` constant: {:?}", ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let pointee_ty = ct
|
||||
.ty()
|
||||
.builtin_deref(true)
|
||||
.expect("tried to dereference on non-ptr type")
|
||||
.ty;
|
||||
let dereferenced_const =
|
||||
self.tcx.mk_const(ty::ConstS { val: ct.val(), ty: pointee_ty });
|
||||
self = dereferenced_const.print(self)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::Array(..) | ty::Tuple(..) | ty::Adt(..) => {
|
||||
let contents = self.tcx.destructure_const(ty::ParamEnv::reveal_all().and(ct));
|
||||
ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => {
|
||||
let contents = self.tcx.destructure_const(ct);
|
||||
let fields = contents.fields.iter().copied();
|
||||
|
||||
let print_field_list = |mut this: Self| {
|
||||
@@ -676,7 +689,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
||||
};
|
||||
|
||||
match *ct.ty().kind() {
|
||||
ty::Array(..) => {
|
||||
ty::Array(..) | ty::Slice(_) => {
|
||||
self.push("A");
|
||||
self = print_field_list(self)?;
|
||||
}
|
||||
@@ -723,7 +736,6 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty(), ct);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user