@@ -534,39 +534,53 @@ impl Printer<'tcx> for &mut SymbolMangler<'tcx> {
534
534
}
535
535
536
536
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
+
537
558
if let Some ( & i) = self . consts . get ( & ct) {
538
559
return self . print_backref ( i) ;
539
560
}
540
561
let start = self . out . len ( ) ;
541
562
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 ;
550
573
if val < 0 {
551
- neg = true ;
574
+ self . push ( "n" ) ;
552
575
}
553
- Some ( val. unsigned_abs ( ) )
554
- } )
576
+ bits = val. unsigned_abs ( ) ;
577
+ }
578
+
579
+ let _ = write ! ( self . out, "{:x}_" , bits) ;
555
580
}
556
581
_ => {
557
582
bug ! ( "symbol_names: unsupported constant of type `{}` ({:?})" , ct. ty, ct) ;
558
583
}
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" ) ;
570
584
}
571
585
572
586
// Only cache consts that do not refer to an enclosing
0 commit comments