@@ -3274,11 +3274,11 @@ fn select_specialized_builtin_kind(
32743274 } ) ;
32753275 }
32763276 BuiltinFunction :: ToString => {
3277- return Some ( if container. known_type == Some ( ValueType :: String ) {
3278- SpecializedBuiltinKind :: ToStringIdentity
3279- } else {
3280- SpecializedBuiltinKind :: ToString
3281- } ) ;
3277+ return match ( container. known_type , container . repr ) {
3278+ ( Some ( ValueType :: String ) , _ ) => Some ( SpecializedBuiltinKind :: ToStringIdentity ) ,
3279+ ( _ , SsaValueRepr :: Tagged ) => Some ( SpecializedBuiltinKind :: ToString ) ,
3280+ _ => None ,
3281+ } ;
32823282 }
32833283 BuiltinFunction :: StringSplitLiteral => {
32843284 return Some ( SpecializedBuiltinKind :: StringSplitLiteral ) ;
@@ -5272,6 +5272,38 @@ mod tests {
52725272 ) ;
52735273 }
52745274
5275+ #[ test]
5276+ fn scalar_to_string_stays_on_general_call_path ( ) {
5277+ let program = Program :: new ( Vec :: new ( ) , Vec :: new ( ) ) ;
5278+ for info in [
5279+ ValueInfo :: int ( None ) ,
5280+ ValueInfo :: float ( None ) ,
5281+ ValueInfo :: bool ( None ) ,
5282+ ] {
5283+ assert_eq ! (
5284+ select_specialized_builtin_kind(
5285+ & program,
5286+ 0 ,
5287+ BuiltinFunction :: ToString ,
5288+ info,
5289+ false ,
5290+ ) ,
5291+ None ,
5292+ "unboxed scalar to_string needs a tagged Value slot"
5293+ ) ;
5294+ }
5295+ assert_eq ! (
5296+ select_specialized_builtin_kind(
5297+ & program,
5298+ 0 ,
5299+ BuiltinFunction :: ToString ,
5300+ ValueInfo :: tagged( ) ,
5301+ false ,
5302+ ) ,
5303+ Some ( SpecializedBuiltinKind :: ToString )
5304+ ) ;
5305+ }
5306+
52755307 #[ test]
52765308 fn unboxed_numeric_compare_ignores_stale_operand_type_hint ( ) {
52775309 let program = Program :: new ( Vec :: new ( ) , Vec :: new ( ) ) . with_type_map ( crate :: TypeMap {
0 commit comments