tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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