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};
format!("typeid{}", arg_count)
}
+pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ trait_ref: ty::PolyExistentialTraitRef<'tcx>,
+) -> String {
+ // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`.
+ let mut cx = &mut SymbolMangler {
+ tcx,
+ start_offset: 0,
+ paths: FxHashMap::default(),
+ types: FxHashMap::default(),
+ consts: FxHashMap::default(),
+ binders: vec![],
+ out: String::new(),
+ };
+ cx = cx.print_def_path(trait_ref.def_id(), &[]).unwrap();
+ std::mem::take(&mut cx.out)
+}
+
struct BinderLevel {
/// The range of distances from the root of what's
/// being printed, to the lifetimes in a binder.
fn print_const(mut self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
// We only mangle a typed value if the const can be evaluated.
let ct = ct.eval(self.tcx, ty::ParamEnv::reveal_all());
- match ct.val() {
+ match ct.kind() {
ty::ConstKind::Value(_) => {}
// Placeholders (should be demangled as `_`).
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 {
let _ = write!(self.out, "{:x}_", bits);
}
- // HACK(eddyb) because `ty::Const` only supports sized values (for now),
- // we can't use `deref_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.val() {
- 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);
+ // FIXME(valtrees): Remove the special case for `str`
+ // here and fully support unsized constants.
+ ty::Ref(_, inner_ty, mutbl) => {
+ self.push(match mutbl {
+ hir::Mutability::Not => "R",
+ hir::Mutability::Mut => "Q",
+ });
+
+ 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);
+ }
}
- 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 { kind: ct.kind(), ty: pointee_ty });
+ self = dereferenced_const.print(self)?;
}
}
}
- ty::Ref(_, _, 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)?;
- }
-
- 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| {
};
match *ct.ty().kind() {
- ty::Array(..) => {
+ ty::Array(..) | ty::Slice(_) => {
self.push("A");
self = print_field_list(self)?;
}
_ => unreachable!(),
}
}
-
_ => {
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty(), ct);
}