@@ -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