demangle_rust_test.cc (21028B)
1 // Copyright 2024 The Abseil Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/debugging/internal/demangle_rust.h" 16 17 #include <cstddef> 18 #include <string> 19 20 #include "gtest/gtest.h" 21 #include "absl/base/config.h" 22 23 namespace absl { 24 ABSL_NAMESPACE_BEGIN 25 namespace debugging_internal { 26 namespace { 27 28 // If DemangleRustSymbolEncoding(mangled, <buffer with room for buffer_size 29 // chars>, buffer_size) returns true and seems not to have overrun its output 30 // buffer, returns the string written by DemangleRustSymbolEncoding; otherwise 31 // returns an error message. 32 std::string ResultOfDemangling(const char* mangled, size_t buffer_size) { 33 // Fill the buffer with something other than NUL so we test whether Demangle 34 // appends trailing NUL as expected. 35 std::string buffer(buffer_size + 1, '~'); 36 constexpr char kCanaryCharacter = 0x7f; // arbitrary unlikely value 37 buffer[buffer_size] = kCanaryCharacter; 38 if (!DemangleRustSymbolEncoding(mangled, &buffer[0], buffer_size)) { 39 return "Failed parse"; 40 } 41 if (buffer[buffer_size] != kCanaryCharacter) { 42 return "Buffer overrun by output: " + buffer.substr(0, buffer_size + 1) 43 + "..."; 44 } 45 return buffer.data(); // Not buffer itself: this trims trailing padding. 46 } 47 48 // Tests that DemangleRustSymbolEncoding converts mangled into plaintext given 49 // enough output buffer space but returns false and avoids overrunning a buffer 50 // that is one byte too short. 51 // 52 // The lambda wrapping allows ASSERT_EQ to branch out the first time an 53 // expectation is not satisfied, preventing redundant errors for the same bug. 54 // 55 // We test first with excess space so that if the algorithm just computes the 56 // wrong answer, it will be clear from the error log that the bounds checks are 57 // unlikely to be the code at fault. 58 #define EXPECT_DEMANGLING(mangled, plaintext) \ 59 do { \ 60 [] { \ 61 constexpr size_t plenty_of_space = sizeof(plaintext) + 128; \ 62 constexpr size_t just_enough_space = sizeof(plaintext); \ 63 constexpr size_t one_byte_too_few = sizeof(plaintext) - 1; \ 64 const char* expected_plaintext = plaintext; \ 65 const char* expected_error = "Failed parse"; \ 66 ASSERT_EQ(ResultOfDemangling(mangled, plenty_of_space), \ 67 expected_plaintext); \ 68 ASSERT_EQ(ResultOfDemangling(mangled, just_enough_space), \ 69 expected_plaintext); \ 70 ASSERT_EQ(ResultOfDemangling(mangled, one_byte_too_few), \ 71 expected_error); \ 72 }(); \ 73 } while (0) 74 75 // Tests that DemangleRustSymbolEncoding rejects the given input (typically, a 76 // truncation of a real Rust symbol name). 77 #define EXPECT_DEMANGLING_FAILS(mangled) \ 78 do { \ 79 constexpr size_t plenty_of_space = 1024; \ 80 const char* expected_error = "Failed parse"; \ 81 EXPECT_EQ(ResultOfDemangling(mangled, plenty_of_space), expected_error); \ 82 } while (0) 83 84 // Piping grep -C 1 _R demangle_test.cc into your favorite c++filt 85 // implementation allows you to verify that the goldens below are reasonable. 86 87 TEST(DemangleRust, EmptyDemangling) { 88 EXPECT_TRUE(DemangleRustSymbolEncoding("_RC0", nullptr, 0)); 89 } 90 91 TEST(DemangleRust, FunctionAtCrateLevel) { 92 EXPECT_DEMANGLING("_RNvC10crate_name9func_name", "crate_name::func_name"); 93 EXPECT_DEMANGLING( 94 "_RNvCs09azAZ_10crate_name9func_name", "crate_name::func_name"); 95 } 96 97 TEST(DemangleRust, TruncationsOfFunctionAtCrateLevel) { 98 EXPECT_DEMANGLING_FAILS("_R"); 99 EXPECT_DEMANGLING_FAILS("_RN"); 100 EXPECT_DEMANGLING_FAILS("_RNvC"); 101 EXPECT_DEMANGLING_FAILS("_RNvC10"); 102 EXPECT_DEMANGLING_FAILS("_RNvC10crate_nam"); 103 EXPECT_DEMANGLING_FAILS("_RNvC10crate_name"); 104 EXPECT_DEMANGLING_FAILS("_RNvC10crate_name9"); 105 EXPECT_DEMANGLING_FAILS("_RNvC10crate_name9func_nam"); 106 EXPECT_DEMANGLING_FAILS("_RNvCs"); 107 EXPECT_DEMANGLING_FAILS("_RNvCs09azAZ"); 108 EXPECT_DEMANGLING_FAILS("_RNvCs09azAZ_"); 109 } 110 111 TEST(DemangleRust, VendorSuffixes) { 112 EXPECT_DEMANGLING("_RNvC10crate_name9func_name.!@#", "crate_name::func_name"); 113 EXPECT_DEMANGLING("_RNvC10crate_name9func_name$!@#", "crate_name::func_name"); 114 } 115 116 TEST(DemangleRust, UnicodeIdentifiers) { 117 EXPECT_DEMANGLING("_RNvC7ice_cap17Eyjafjallajökull", 118 "ice_cap::Eyjafjallajökull"); 119 EXPECT_DEMANGLING("_RNvC7ice_caps_u19Eyjafjallajkull_jtb", 120 "ice_cap::Eyjafjallajökull"); 121 } 122 123 TEST(DemangleRust, FunctionInModule) { 124 EXPECT_DEMANGLING("_RNvNtCs09azAZ_10crate_name11module_name9func_name", 125 "crate_name::module_name::func_name"); 126 } 127 128 TEST(DemangleRust, FunctionInFunction) { 129 EXPECT_DEMANGLING( 130 "_RNvNvCs09azAZ_10crate_name15outer_func_name15inner_func_name", 131 "crate_name::outer_func_name::inner_func_name"); 132 } 133 134 TEST(DemangleRust, ClosureInFunction) { 135 EXPECT_DEMANGLING( 136 "_RNCNvCs09azAZ_10crate_name9func_name0", 137 "crate_name::func_name::{closure#0}"); 138 EXPECT_DEMANGLING( 139 "_RNCNvCs09azAZ_10crate_name9func_name0Cs123_12client_crate", 140 "crate_name::func_name::{closure#0}"); 141 } 142 143 TEST(DemangleRust, ClosureNumbering) { 144 EXPECT_DEMANGLING( 145 "_RNCNvCs09azAZ_10crate_name9func_names_0Cs123_12client_crate", 146 "crate_name::func_name::{closure#1}"); 147 EXPECT_DEMANGLING( 148 "_RNCNvCs09azAZ_10crate_name9func_names0_0Cs123_12client_crate", 149 "crate_name::func_name::{closure#2}"); 150 EXPECT_DEMANGLING( 151 "_RNCNvCs09azAZ_10crate_name9func_names9_0Cs123_12client_crate", 152 "crate_name::func_name::{closure#11}"); 153 EXPECT_DEMANGLING( 154 "_RNCNvCs09azAZ_10crate_name9func_namesa_0Cs123_12client_crate", 155 "crate_name::func_name::{closure#12}"); 156 EXPECT_DEMANGLING( 157 "_RNCNvCs09azAZ_10crate_name9func_namesz_0Cs123_12client_crate", 158 "crate_name::func_name::{closure#37}"); 159 EXPECT_DEMANGLING( 160 "_RNCNvCs09azAZ_10crate_name9func_namesA_0Cs123_12client_crate", 161 "crate_name::func_name::{closure#38}"); 162 EXPECT_DEMANGLING( 163 "_RNCNvCs09azAZ_10crate_name9func_namesZ_0Cs123_12client_crate", 164 "crate_name::func_name::{closure#63}"); 165 EXPECT_DEMANGLING( 166 "_RNCNvCs09azAZ_10crate_name9func_names10_0Cs123_12client_crate", 167 "crate_name::func_name::{closure#64}"); 168 EXPECT_DEMANGLING( 169 "_RNCNvCs09azAZ_10crate_name9func_namesg6_0Cs123_12client_crate", 170 "crate_name::func_name::{closure#1000}"); 171 } 172 173 TEST(DemangleRust, ClosureNumberOverflowingInt) { 174 EXPECT_DEMANGLING( 175 "_RNCNvCs09azAZ_10crate_name9func_names1234567_0Cs123_12client_crate", 176 "crate_name::func_name::{closure#?}"); 177 } 178 179 TEST(DemangleRust, UnexpectedlyNamedClosure) { 180 EXPECT_DEMANGLING( 181 "_RNCNvCs123_10crate_name9func_name12closure_nameCs456_12client_crate", 182 "crate_name::func_name::{closure:closure_name#0}"); 183 EXPECT_DEMANGLING( 184 "_RNCNvCs123_10crate_name9func_names2_12closure_nameCs456_12client_crate", 185 "crate_name::func_name::{closure:closure_name#4}"); 186 } 187 188 TEST(DemangleRust, ItemNestedInsideClosure) { 189 EXPECT_DEMANGLING( 190 "_RNvNCNvCs123_10crate_name9func_name015inner_func_nameCs_12client_crate", 191 "crate_name::func_name::{closure#0}::inner_func_name"); 192 } 193 194 TEST(DemangleRust, Shim) { 195 EXPECT_DEMANGLING( 196 "_RNSNvCs123_10crate_name9func_name6vtableCs456_12client_crate", 197 "crate_name::func_name::{shim:vtable#0}"); 198 } 199 200 TEST(DemangleRust, UnknownUppercaseNamespace) { 201 EXPECT_DEMANGLING( 202 "_RNXNvCs123_10crate_name9func_name14mystery_objectCs456_12client_crate", 203 "crate_name::func_name::{X:mystery_object#0}"); 204 } 205 206 TEST(DemangleRust, NestedUppercaseNamespaces) { 207 EXPECT_DEMANGLING( 208 "_RNCNXNYCs123_10crate_names0_1ys1_1xs2_0Cs456_12client_crate", 209 "crate_name::{Y:y#2}::{X:x#3}::{closure#4}"); 210 } 211 212 TEST(DemangleRust, TraitDefinition) { 213 EXPECT_DEMANGLING( 214 "_RNvYNtC7crate_a9my_structNtC7crate_b8my_trait1f", 215 "<crate_a::my_struct as crate_b::my_trait>::f"); 216 } 217 218 TEST(DemangleRust, BasicTypeNames) { 219 EXPECT_DEMANGLING("_RNvYaNtC1c1t1f", "<i8 as c::t>::f"); 220 EXPECT_DEMANGLING("_RNvYbNtC1c1t1f", "<bool as c::t>::f"); 221 EXPECT_DEMANGLING("_RNvYcNtC1c1t1f", "<char as c::t>::f"); 222 EXPECT_DEMANGLING("_RNvYdNtC1c1t1f", "<f64 as c::t>::f"); 223 EXPECT_DEMANGLING("_RNvYeNtC1c1t1f", "<str as c::t>::f"); 224 EXPECT_DEMANGLING("_RNvYfNtC1c1t1f", "<f32 as c::t>::f"); 225 EXPECT_DEMANGLING("_RNvYhNtC1c1t1f", "<u8 as c::t>::f"); 226 EXPECT_DEMANGLING("_RNvYiNtC1c1t1f", "<isize as c::t>::f"); 227 EXPECT_DEMANGLING("_RNvYjNtC1c1t1f", "<usize as c::t>::f"); 228 EXPECT_DEMANGLING("_RNvYlNtC1c1t1f", "<i32 as c::t>::f"); 229 EXPECT_DEMANGLING("_RNvYmNtC1c1t1f", "<u32 as c::t>::f"); 230 EXPECT_DEMANGLING("_RNvYnNtC1c1t1f", "<i128 as c::t>::f"); 231 EXPECT_DEMANGLING("_RNvYoNtC1c1t1f", "<u128 as c::t>::f"); 232 EXPECT_DEMANGLING("_RNvYpNtC1c1t1f", "<_ as c::t>::f"); 233 EXPECT_DEMANGLING("_RNvYsNtC1c1t1f", "<i16 as c::t>::f"); 234 EXPECT_DEMANGLING("_RNvYtNtC1c1t1f", "<u16 as c::t>::f"); 235 EXPECT_DEMANGLING("_RNvYuNtC1c1t1f", "<() as c::t>::f"); 236 EXPECT_DEMANGLING("_RNvYvNtC1c1t1f", "<... as c::t>::f"); 237 EXPECT_DEMANGLING("_RNvYxNtC1c1t1f", "<i64 as c::t>::f"); 238 EXPECT_DEMANGLING("_RNvYyNtC1c1t1f", "<u64 as c::t>::f"); 239 EXPECT_DEMANGLING("_RNvYzNtC1c1t1f", "<! as c::t>::f"); 240 241 EXPECT_DEMANGLING_FAILS("_RNvYkNtC1c1t1f"); 242 } 243 244 TEST(DemangleRust, SliceTypes) { 245 EXPECT_DEMANGLING("_RNvYSlNtC1c1t1f", "<[i32] as c::t>::f"); 246 EXPECT_DEMANGLING("_RNvYSNtC1d1sNtC1c1t1f", "<[d::s] as c::t>::f"); 247 } 248 249 TEST(DemangleRust, ImmutableReferenceTypes) { 250 EXPECT_DEMANGLING("_RNvYRlNtC1c1t1f", "<&i32 as c::t>::f"); 251 EXPECT_DEMANGLING("_RNvYRNtC1d1sNtC1c1t1f", "<&d::s as c::t>::f"); 252 } 253 254 TEST(DemangleRust, MutableReferenceTypes) { 255 EXPECT_DEMANGLING("_RNvYQlNtC1c1t1f", "<&mut i32 as c::t>::f"); 256 EXPECT_DEMANGLING("_RNvYQNtC1d1sNtC1c1t1f", "<&mut d::s as c::t>::f"); 257 } 258 259 TEST(DemangleRust, ConstantRawPointerTypes) { 260 EXPECT_DEMANGLING("_RNvYPlNtC1c1t1f", "<*const i32 as c::t>::f"); 261 EXPECT_DEMANGLING("_RNvYPNtC1d1sNtC1c1t1f", "<*const d::s as c::t>::f"); 262 } 263 264 TEST(DemangleRust, MutableRawPointerTypes) { 265 EXPECT_DEMANGLING("_RNvYOlNtC1c1t1f", "<*mut i32 as c::t>::f"); 266 EXPECT_DEMANGLING("_RNvYONtC1d1sNtC1c1t1f", "<*mut d::s as c::t>::f"); 267 } 268 269 TEST(DemangleRust, TupleLength0) { 270 EXPECT_DEMANGLING("_RNvYTENtC1c1t1f", "<() as c::t>::f"); 271 } 272 273 TEST(DemangleRust, TupleLength1) { 274 EXPECT_DEMANGLING("_RNvYTlENtC1c1t1f", "<(i32,) as c::t>::f"); 275 EXPECT_DEMANGLING("_RNvYTNtC1d1sENtC1c1t1f", "<(d::s,) as c::t>::f"); 276 } 277 278 TEST(DemangleRust, TupleLength2) { 279 EXPECT_DEMANGLING("_RNvYTlmENtC1c1t1f", "<(i32, u32) as c::t>::f"); 280 EXPECT_DEMANGLING("_RNvYTNtC1d1xNtC1e1yENtC1c1t1f", 281 "<(d::x, e::y) as c::t>::f"); 282 } 283 284 TEST(DemangleRust, TupleLength3) { 285 EXPECT_DEMANGLING("_RNvYTlmnENtC1c1t1f", "<(i32, u32, i128) as c::t>::f"); 286 EXPECT_DEMANGLING("_RNvYTNtC1d1xNtC1e1yNtC1f1zENtC1c1t1f", 287 "<(d::x, e::y, f::z) as c::t>::f"); 288 } 289 290 TEST(DemangleRust, LongerTuplesAbbreviated) { 291 EXPECT_DEMANGLING("_RNvYTlmnoENtC1c1t1f", 292 "<(i32, u32, i128, ...) as c::t>::f"); 293 EXPECT_DEMANGLING("_RNvYTlmnNtC1d1xNtC1e1yENtC1c1t1f", 294 "<(i32, u32, i128, ...) as c::t>::f"); 295 } 296 297 TEST(DemangleRust, PathBackrefToCrate) { 298 EXPECT_DEMANGLING("_RNvYNtC8my_crate9my_structNtB4_8my_trait1f", 299 "<my_crate::my_struct as my_crate::my_trait>::f"); 300 } 301 302 TEST(DemangleRust, PathBackrefToNestedPath) { 303 EXPECT_DEMANGLING("_RNvYNtNtC1c1m1sNtB4_1t1f", "<c::m::s as c::m::t>::f"); 304 } 305 306 TEST(DemangleRust, PathBackrefAsInstantiatingCrate) { 307 EXPECT_DEMANGLING("_RNCNvC8my_crate7my_func0B3_", 308 "my_crate::my_func::{closure#0}"); 309 } 310 311 TEST(DemangleRust, TypeBackrefsNestedInTuple) { 312 EXPECT_DEMANGLING("_RNvYTTRlB4_ERB3_ENtC1c1t1f", 313 "<((&i32, &i32), &(&i32, &i32)) as c::t>::f"); 314 } 315 316 TEST(DemangleRust, NoInfiniteLoopOnBackrefToTheWhole) { 317 EXPECT_DEMANGLING_FAILS("_RB_"); 318 EXPECT_DEMANGLING_FAILS("_RNvB_1sNtC1c1t1f"); 319 } 320 321 TEST(DemangleRust, NoCrashOnForwardBackref) { 322 EXPECT_DEMANGLING_FAILS("_RB0_"); 323 EXPECT_DEMANGLING_FAILS("_RB1_"); 324 EXPECT_DEMANGLING_FAILS("_RB2_"); 325 EXPECT_DEMANGLING_FAILS("_RB3_"); 326 EXPECT_DEMANGLING_FAILS("_RB4_"); 327 } 328 329 TEST(DemangleRust, PathBackrefsDoNotRecurseDuringSilence) { 330 // B_ points at the value f (the whole mangling), so the cycle would lead to 331 // parse failure if the parser tried to parse what was pointed to. 332 EXPECT_DEMANGLING("_RNvYTlmnNtB_1sENtC1c1t1f", 333 "<(i32, u32, i128, ...) as c::t>::f"); 334 } 335 336 TEST(DemangleRust, TypeBackrefsDoNotRecurseDuringSilence) { 337 // B2_ points at the tuple type, likewise making a cycle that the parser 338 // avoids following. 339 EXPECT_DEMANGLING("_RNvYTlmnB2_ENtC1c1t1f", 340 "<(i32, u32, i128, ...) as c::t>::f"); 341 } 342 343 TEST(DemangleRust, ConstBackrefsDoNotRecurseDuringSilence) { 344 // B_ points at the whole I...E mangling, which does not parse as a const. 345 EXPECT_DEMANGLING("_RINvC1c1fAlB_E", "c::f::<>"); 346 } 347 348 TEST(DemangleRust, ReturnFromBackrefToInputPosition256) { 349 // Show that we can resume at input positions that don't fit into a byte. 350 EXPECT_DEMANGLING("_RNvYNtC1c238very_long_type_" 351 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 352 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 353 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 354 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 355 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 356 "ABCDEFGHIJabcdefghijABC" 357 "NtB4_1t1f", 358 "<c::very_long_type_" 359 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 360 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 361 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 362 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 363 "ABCDEFGHIJabcdefghijABCDEFGHIJabcdefghij" 364 "ABCDEFGHIJabcdefghijABC" 365 " as c::t>::f"); 366 } 367 368 TEST(DemangleRust, EmptyGenericArgs) { 369 EXPECT_DEMANGLING("_RINvC1c1fE", "c::f::<>"); 370 } 371 372 TEST(DemangleRust, OneSimpleTypeInGenericArgs) { 373 EXPECT_DEMANGLING("_RINvC1c1flE", // c::f::<i32> 374 "c::f::<>"); 375 } 376 377 TEST(DemangleRust, OneTupleInGenericArgs) { 378 EXPECT_DEMANGLING("_RINvC1c1fTlmEE", // c::f::<(i32, u32)> 379 "c::f::<>"); 380 } 381 382 TEST(DemangleRust, OnePathInGenericArgs) { 383 EXPECT_DEMANGLING("_RINvC1c1fNtC1d1sE", // c::f::<d::s> 384 "c::f::<>"); 385 } 386 387 TEST(DemangleRust, LongerGenericArgs) { 388 EXPECT_DEMANGLING("_RINvC1c1flmRNtC1d1sE", // c::f::<i32, u32, &d::s> 389 "c::f::<>"); 390 } 391 392 TEST(DemangleRust, BackrefInGenericArgs) { 393 EXPECT_DEMANGLING("_RINvC1c1fRlB7_NtB2_1sE", // c::f::<&i32, &i32, c::s> 394 "c::f::<>"); 395 } 396 397 TEST(DemangleRust, NestedGenericArgs) { 398 EXPECT_DEMANGLING("_RINvC1c1fINtB2_1slEmE", // c::f::<c::s::<i32>, u32> 399 "c::f::<>"); 400 } 401 402 TEST(DemangleRust, MonomorphicEntityNestedInsideGeneric) { 403 EXPECT_DEMANGLING("_RNvINvC1c1fppE1g", // c::f::<_, _>::g 404 "c::f::<>::g"); 405 } 406 407 TEST(DemangleRust, ArrayTypeWithSimpleElementType) { 408 EXPECT_DEMANGLING("_RNvYAlj1f_NtC1c1t1f", "<[i32; 0x1f] as c::t>::f"); 409 } 410 411 TEST(DemangleRust, ArrayTypeWithComplexElementType) { 412 EXPECT_DEMANGLING("_RNvYAINtC1c1slEj1f_NtB6_1t1f", 413 "<[c::s::<>; 0x1f] as c::t>::f"); 414 } 415 416 TEST(DemangleRust, NestedArrayType) { 417 EXPECT_DEMANGLING("_RNvYAAlj1f_j2e_NtC1c1t1f", 418 "<[[i32; 0x1f]; 0x2e] as c::t>::f"); 419 } 420 421 TEST(DemangleRust, BackrefArraySize) { 422 EXPECT_DEMANGLING("_RNvYAAlj1f_B5_NtC1c1t1f", 423 "<[[i32; 0x1f]; 0x1f] as c::t>::f"); 424 } 425 426 TEST(DemangleRust, ZeroArraySize) { 427 EXPECT_DEMANGLING("_RNvYAlj0_NtC1c1t1f", "<[i32; 0x0] as c::t>::f"); 428 } 429 430 TEST(DemangleRust, SurprisingMinusesInArraySize) { 431 // Compilers shouldn't do this stuff, but existing demanglers accept it. 432 EXPECT_DEMANGLING("_RNvYAljn0_NtC1c1t1f", "<[i32; -0x0] as c::t>::f"); 433 EXPECT_DEMANGLING("_RNvYAljn42_NtC1c1t1f", "<[i32; -0x42] as c::t>::f"); 434 } 435 436 TEST(DemangleRust, NumberAsGenericArg) { 437 EXPECT_DEMANGLING("_RINvC1c1fKl8_E", // c::f::<0x8> 438 "c::f::<>"); 439 } 440 441 TEST(DemangleRust, NumberAsFirstOfTwoGenericArgs) { 442 EXPECT_DEMANGLING("_RINvC1c1fKl8_mE", // c::f::<0x8, u32> 443 "c::f::<>"); 444 } 445 446 TEST(DemangleRust, NumberAsSecondOfTwoGenericArgs) { 447 EXPECT_DEMANGLING("_RINvC1c1fmKl8_E", // c::f::<u32, 0x8> 448 "c::f::<>"); 449 } 450 451 TEST(DemangleRust, NumberPlaceholder) { 452 EXPECT_DEMANGLING("_RNvINvC1c1fKpE1g", // c::f::<_>::g 453 "c::f::<>::g"); 454 } 455 456 TEST(DemangleRust, InherentImplWithoutDisambiguator) { 457 EXPECT_DEMANGLING("_RNvMNtC8my_crate6my_modNtB2_9my_struct7my_func", 458 "<my_crate::my_mod::my_struct>::my_func"); 459 } 460 461 TEST(DemangleRust, InherentImplWithDisambiguator) { 462 EXPECT_DEMANGLING("_RNvMs_NtC8my_crate6my_modNtB4_9my_struct7my_func", 463 "<my_crate::my_mod::my_struct>::my_func"); 464 } 465 466 TEST(DemangleRust, TraitImplWithoutDisambiguator) { 467 EXPECT_DEMANGLING("_RNvXC8my_crateNtB2_9my_structNtB2_8my_trait7my_func", 468 "<my_crate::my_struct as my_crate::my_trait>::my_func"); 469 } 470 471 TEST(DemangleRust, TraitImplWithDisambiguator) { 472 EXPECT_DEMANGLING("_RNvXs_C8my_crateNtB4_9my_structNtB4_8my_trait7my_func", 473 "<my_crate::my_struct as my_crate::my_trait>::my_func"); 474 } 475 476 TEST(DemangleRust, TraitImplWithNonpathSelfType) { 477 EXPECT_DEMANGLING("_RNvXC8my_crateRlNtB2_8my_trait7my_func", 478 "<&i32 as my_crate::my_trait>::my_func"); 479 } 480 481 TEST(DemangleRust, ThunkType) { 482 EXPECT_DEMANGLING("_RNvYFEuNtC1c1t1f", // <fn() as c::t>::f 483 "<fn... as c::t>::f"); 484 } 485 486 TEST(DemangleRust, NontrivialFunctionReturnType) { 487 EXPECT_DEMANGLING( 488 "_RNvYFERTlmENtC1c1t1f", // <fn() -> &(i32, u32) as c::t>::f 489 "<fn... as c::t>::f"); 490 } 491 492 TEST(DemangleRust, OneParameterType) { 493 EXPECT_DEMANGLING("_RNvYFlEuNtC1c1t1f", // <fn(i32) as c::t>::f 494 "<fn... as c::t>::f"); 495 } 496 497 TEST(DemangleRust, TwoParameterTypes) { 498 EXPECT_DEMANGLING("_RNvYFlmEuNtC1c1t1f", // <fn(i32, u32) as c::t>::f 499 "<fn... as c::t>::f"); 500 } 501 502 TEST(DemangleRust, ExternC) { 503 EXPECT_DEMANGLING("_RNvYFKCEuNtC1c1t1f", // <extern "C" fn() as c::t>>::f 504 "<fn... as c::t>::f"); 505 } 506 507 TEST(DemangleRust, ExternOther) { 508 EXPECT_DEMANGLING( 509 "_RNvYFK5not_CEuNtC1c1t1f", // <extern "not-C" fn() as c::t>::f 510 "<fn... as c::t>::f"); 511 } 512 513 TEST(DemangleRust, Unsafe) { 514 EXPECT_DEMANGLING("_RNvYFUEuNtC1c1t1f", // <unsafe fn() as c::t>::f 515 "<fn... as c::t>::f"); 516 } 517 518 TEST(DemangleRust, Binder) { 519 EXPECT_DEMANGLING( 520 // <for<'a> fn(&'a i32) -> &'a i32 as c::t>::f 521 "_RNvYFG_RL0_lEB5_NtC1c1t1f", 522 "<fn... as c::t>::f"); 523 } 524 525 TEST(DemangleRust, AllFnSigFeaturesInOrder) { 526 EXPECT_DEMANGLING( 527 // <for<'a> unsafe extern "C" fn(&'a i32) -> &'a i32 as c::t>::f 528 "_RNvYFG_UKCRL0_lEB8_NtC1c1t1f", 529 "<fn... as c::t>::f"); 530 } 531 532 TEST(DemangleRust, LifetimeInGenericArgs) { 533 EXPECT_DEMANGLING("_RINvC1c1fINtB2_1sL_EE", // c::f::<c::s::<'_>> 534 "c::f::<>"); 535 } 536 537 TEST(DemangleRust, EmptyDynTrait) { 538 // This shouldn't happen, but the grammar allows it and existing demanglers 539 // accept it. 540 EXPECT_DEMANGLING("_RNvYDEL_NtC1c1t1f", 541 "<dyn as c::t>::f"); 542 } 543 544 TEST(DemangleRust, SimpleDynTrait) { 545 EXPECT_DEMANGLING("_RNvYDNtC1c1tEL_NtC1d1u1f", 546 "<dyn c::t as d::u>::f"); 547 } 548 549 TEST(DemangleRust, DynTraitWithOneAssociatedType) { 550 EXPECT_DEMANGLING( 551 "_RNvYDNtC1c1tp1xlEL_NtC1d1u1f", // <dyn c::t<x = i32> as d::u>::f 552 "<dyn c::t<> as d::u>::f"); 553 } 554 555 TEST(DemangleRust, DynTraitWithTwoAssociatedTypes) { 556 EXPECT_DEMANGLING( 557 // <dyn c::t<x = i32, y = u32> as d::u>::f 558 "_RNvYDNtC1c1tp1xlp1ymEL_NtC1d1u1f", 559 "<dyn c::t<> as d::u>::f"); 560 } 561 562 TEST(DemangleRust, DynTraitPlusAutoTrait) { 563 EXPECT_DEMANGLING( 564 "_RNvYDNtC1c1tNtNtC3std6marker4SendEL_NtC1d1u1f", 565 "<dyn c::t + std::marker::Send as d::u>::f"); 566 } 567 568 TEST(DemangleRust, DynTraitPlusTwoAutoTraits) { 569 EXPECT_DEMANGLING( 570 "_RNvYDNtC1c1tNtNtC3std6marker4CopyNtBc_4SyncEL_NtC1d1u1f", 571 "<dyn c::t + std::marker::Copy + std::marker::Sync as d::u>::f"); 572 } 573 574 TEST(DemangleRust, HigherRankedDynTrait) { 575 EXPECT_DEMANGLING( 576 // <dyn for<'a> c::t::<&'a i32> as d::u>::f 577 "_RNvYDG_INtC1c1tRL0_lEEL_NtC1d1u1f", 578 "<dyn c::t::<> as d::u>::f"); 579 } 580 581 } // namespace 582 } // namespace debugging_internal 583 ABSL_NAMESPACE_END 584 } // namespace absl