Skip to content

Commit 3180312

Browse files
eddybtmiasko
authored andcommitted
rustc_symbol_mangling: never cache placeholders in print_const.
1 parent 5038fae commit 3180312

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
@@ -545,39 +545,53 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
545545
}
546546

547547
fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
548+
// We only mangle a typed value if the const can be evaluated.
549+
let ct = ct.eval(self.tcx, ty::ParamEnv::reveal_all());
550+
match ct.val {
551+
ty::ConstKind::Value(_) => {}
552+
553+
// Placeholders (should be demangled as `_`).
554+
// NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
555+
// a path), even for it we still need to encode a placeholder, as
556+
// the path could refer back to e.g. an `impl` using the constant.
557+
ty::ConstKind::Unevaluated(_)
558+
| ty::ConstKind::Param(_)
559+
| ty::ConstKind::Infer(_)
560+
| ty::ConstKind::Bound(..)
561+
| ty::ConstKind::Placeholder(_)
562+
| ty::ConstKind::Error(_) => {
563+
// Never cached (single-character).
564+
self.push("p");
565+
return Ok(self);
566+
}
567+
}
568+
548569
if let Some(&i) = self.compress.as_ref().and_then(|c| c.consts.get(&ct)) {
549570
return self.print_backref(i);
550571
}
551572
let start = self.out.len();
552573

553-
let mut neg = false;
554-
let val = match ct.ty.kind() {
555-
ty::Uint(_) | ty::Bool | ty::Char => {
556-
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)
557-
}
558-
ty::Int(ity) => {
559-
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty).and_then(|b| {
560-
let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(b) as i128;
574+
match ct.ty.kind() {
575+
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
576+
self = ct.ty.print(self)?;
577+
578+
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty);
579+
580+
// Negative integer values are mangled using `n` as a "sign prefix".
581+
if let ty::Int(ity) = ct.ty.kind() {
582+
let val =
583+
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
561584
if val < 0 {
562-
neg = true;
585+
self.push("n");
563586
}
564-
Some(val.unsigned_abs())
565-
})
587+
bits = val.unsigned_abs();
588+
}
589+
590+
let _ = write!(self.out, "{:x}_", bits);
566591
}
567592
_ => {
568593
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
569594
}
570-
};
571-
572-
if let Some(bits) = val {
573-
// We only print the type if the const can be evaluated.
574-
self = ct.ty.print(self)?;
575-
let _ = write!(self.out, "{}{:x}_", if neg { "n" } else { "" }, bits);
576-
} else {
577-
// NOTE(eddyb) despite having the path, we need to
578-
// encode a placeholder, as the path could refer
579-
// back to e.g. an `impl` using the constant.
580-
self.push("p");
581595
}
582596

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

0 commit comments

Comments
 (0)