Skip to content

Commit eec84b3

Browse files
committed
rustc_symbol_mangling: never cache placeholders in print_const.
1 parent e291234 commit eec84b3

File tree

1 file changed

+36
-22
lines changed
  • compiler/rustc_symbol_mangling/src

1 file changed

+36
-22
lines changed

compiler/rustc_symbol_mangling/src/v0.rs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -534,39 +534,53 @@ impl Printer<'tcx> for &mut SymbolMangler<'tcx> {
534534
}
535535

536536
fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
537+
// We only mangle a typed value if the const can be evaluated.
538+
let ct = ct.eval(self.tcx, ty::ParamEnv::reveal_all());
539+
match ct.val {
540+
ty::ConstKind::Value(_) => {}
541+
542+
// Placeholders (should be demangled as `_`).
543+
// NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
544+
// a path), even for it we still need to encode a placeholder, as
545+
// the path could refer back to e.g. an `impl` using the constant.
546+
ty::ConstKind::Unevaluated(_)
547+
| ty::ConstKind::Param(_)
548+
| ty::ConstKind::Infer(_)
549+
| ty::ConstKind::Bound(..)
550+
| ty::ConstKind::Placeholder(_)
551+
| ty::ConstKind::Error(_) => {
552+
// Never cached (single-character).
553+
self.push("p");
554+
return Ok(self);
555+
}
556+
}
557+
537558
if let Some(&i) = self.consts.get(&ct) {
538559
return self.print_backref(i);
539560
}
540561
let start = self.out.len();
541562

542-
let mut neg = false;
543-
let val = match ct.ty.kind() {
544-
ty::Uint(_) | ty::Bool | ty::Char => {
545-
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)
546-
}
547-
ty::Int(ity) => {
548-
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty).and_then(|b| {
549-
let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(b) as i128;
563+
match ct.ty.kind() {
564+
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
565+
self = ct.ty.print(self)?;
566+
567+
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty);
568+
569+
// Negative integer values are mangled using `n` as a "sign prefix".
570+
if let ty::Int(ity) = ct.ty.kind() {
571+
let val =
572+
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
550573
if val < 0 {
551-
neg = true;
574+
self.push("n");
552575
}
553-
Some(val.unsigned_abs())
554-
})
576+
bits = val.unsigned_abs();
577+
}
578+
579+
let _ = write!(self.out, "{:x}_", bits);
555580
}
556581
_ => {
557582
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
558583
}
559-
};
560-
561-
if let Some(bits) = val {
562-
// We only print the type if the const can be evaluated.
563-
self = ct.ty.print(self)?;
564-
let _ = write!(self.out, "{}{:x}_", if neg { "n" } else { "" }, bits);
565-
} else {
566-
// NOTE(eddyb) despite having the path, we need to
567-
// encode a placeholder, as the path could refer
568-
// back to e.g. an `impl` using the constant.
569-
self.push("p");
570584
}
571585

572586
// Only cache consts that do not refer to an enclosing

0 commit comments

Comments
 (0)