@@ -545,39 +545,53 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
545
545
}
546
546
547
547
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
+
548
569
if let Some ( & i) = self . compress . as_ref ( ) . and_then ( |c| c. consts . get ( & ct) ) {
549
570
return self . print_backref ( i) ;
550
571
}
551
572
let start = self . out . len ( ) ;
552
573
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 ;
561
584
if val < 0 {
562
- neg = true ;
585
+ self . push ( "n" ) ;
563
586
}
564
- Some ( val. unsigned_abs ( ) )
565
- } )
587
+ bits = val. unsigned_abs ( ) ;
588
+ }
589
+
590
+ let _ = write ! ( self . out, "{:x}_" , bits) ;
566
591
}
567
592
_ => {
568
593
bug ! ( "symbol_names: unsupported constant of type `{}` ({:?})" , ct. ty, ct) ;
569
594
}
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" ) ;
581
595
}
582
596
583
597
// Only cache consts that do not refer to an enclosing
0 commit comments