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