xref: /aosp_15_r20/external/abseil-cpp/absl/debugging/internal/demangle_rust_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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.
ResultOfDemangling(const char * mangled,size_t buffer_size)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 
TEST(DemangleRust,EmptyDemangling)87 TEST(DemangleRust, EmptyDemangling) {
88   EXPECT_TRUE(DemangleRustSymbolEncoding("_RC0", nullptr, 0));
89 }
90 
TEST(DemangleRust,FunctionAtCrateLevel)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 
TEST(DemangleRust,TruncationsOfFunctionAtCrateLevel)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 
TEST(DemangleRust,VendorSuffixes)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 
TEST(DemangleRust,UnicodeIdentifiers)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 
TEST(DemangleRust,FunctionInModule)123 TEST(DemangleRust, FunctionInModule) {
124   EXPECT_DEMANGLING("_RNvNtCs09azAZ_10crate_name11module_name9func_name",
125                     "crate_name::module_name::func_name");
126 }
127 
TEST(DemangleRust,FunctionInFunction)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 
TEST(DemangleRust,ClosureInFunction)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 
TEST(DemangleRust,ClosureNumbering)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 
TEST(DemangleRust,ClosureNumberOverflowingInt)173 TEST(DemangleRust, ClosureNumberOverflowingInt) {
174   EXPECT_DEMANGLING(
175       "_RNCNvCs09azAZ_10crate_name9func_names1234567_0Cs123_12client_crate",
176       "crate_name::func_name::{closure#?}");
177 }
178 
TEST(DemangleRust,UnexpectedlyNamedClosure)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 
TEST(DemangleRust,ItemNestedInsideClosure)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 
TEST(DemangleRust,Shim)194 TEST(DemangleRust, Shim) {
195   EXPECT_DEMANGLING(
196       "_RNSNvCs123_10crate_name9func_name6vtableCs456_12client_crate",
197       "crate_name::func_name::{shim:vtable#0}");
198 }
199 
TEST(DemangleRust,UnknownUppercaseNamespace)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 
TEST(DemangleRust,NestedUppercaseNamespaces)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 
TEST(DemangleRust,TraitDefinition)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 
TEST(DemangleRust,BasicTypeNames)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 
TEST(DemangleRust,SliceTypes)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 
TEST(DemangleRust,ImmutableReferenceTypes)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 
TEST(DemangleRust,MutableReferenceTypes)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 
TEST(DemangleRust,ConstantRawPointerTypes)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 
TEST(DemangleRust,MutableRawPointerTypes)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 
TEST(DemangleRust,TupleLength0)269 TEST(DemangleRust, TupleLength0) {
270   EXPECT_DEMANGLING("_RNvYTENtC1c1t1f", "<() as c::t>::f");
271 }
272 
TEST(DemangleRust,TupleLength1)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 
TEST(DemangleRust,TupleLength2)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 
TEST(DemangleRust,TupleLength3)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 
TEST(DemangleRust,LongerTuplesAbbreviated)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 
TEST(DemangleRust,PathBackrefToCrate)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 
TEST(DemangleRust,PathBackrefToNestedPath)302 TEST(DemangleRust, PathBackrefToNestedPath) {
303   EXPECT_DEMANGLING("_RNvYNtNtC1c1m1sNtB4_1t1f", "<c::m::s as c::m::t>::f");
304 }
305 
TEST(DemangleRust,PathBackrefAsInstantiatingCrate)306 TEST(DemangleRust, PathBackrefAsInstantiatingCrate) {
307   EXPECT_DEMANGLING("_RNCNvC8my_crate7my_func0B3_",
308                     "my_crate::my_func::{closure#0}");
309 }
310 
TEST(DemangleRust,TypeBackrefsNestedInTuple)311 TEST(DemangleRust, TypeBackrefsNestedInTuple) {
312   EXPECT_DEMANGLING("_RNvYTTRlB4_ERB3_ENtC1c1t1f",
313                     "<((&i32, &i32), &(&i32, &i32)) as c::t>::f");
314 }
315 
TEST(DemangleRust,NoInfiniteLoopOnBackrefToTheWhole)316 TEST(DemangleRust, NoInfiniteLoopOnBackrefToTheWhole) {
317   EXPECT_DEMANGLING_FAILS("_RB_");
318   EXPECT_DEMANGLING_FAILS("_RNvB_1sNtC1c1t1f");
319 }
320 
TEST(DemangleRust,NoCrashOnForwardBackref)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 
TEST(DemangleRust,PathBackrefsDoNotRecurseDuringSilence)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 
TEST(DemangleRust,TypeBackrefsDoNotRecurseDuringSilence)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 
TEST(DemangleRust,ConstBackrefsDoNotRecurseDuringSilence)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 
TEST(DemangleRust,ReturnFromBackrefToInputPosition256)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 
TEST(DemangleRust,EmptyGenericArgs)368 TEST(DemangleRust, EmptyGenericArgs) {
369   EXPECT_DEMANGLING("_RINvC1c1fE", "c::f::<>");
370 }
371 
TEST(DemangleRust,OneSimpleTypeInGenericArgs)372 TEST(DemangleRust, OneSimpleTypeInGenericArgs) {
373   EXPECT_DEMANGLING("_RINvC1c1flE",  // c::f::<i32>
374                     "c::f::<>");
375 }
376 
TEST(DemangleRust,OneTupleInGenericArgs)377 TEST(DemangleRust, OneTupleInGenericArgs) {
378   EXPECT_DEMANGLING("_RINvC1c1fTlmEE",  // c::f::<(i32, u32)>
379                     "c::f::<>");
380 }
381 
TEST(DemangleRust,OnePathInGenericArgs)382 TEST(DemangleRust, OnePathInGenericArgs) {
383   EXPECT_DEMANGLING("_RINvC1c1fNtC1d1sE",  // c::f::<d::s>
384                     "c::f::<>");
385 }
386 
TEST(DemangleRust,LongerGenericArgs)387 TEST(DemangleRust, LongerGenericArgs) {
388   EXPECT_DEMANGLING("_RINvC1c1flmRNtC1d1sE",  // c::f::<i32, u32, &d::s>
389                     "c::f::<>");
390 }
391 
TEST(DemangleRust,BackrefInGenericArgs)392 TEST(DemangleRust, BackrefInGenericArgs) {
393   EXPECT_DEMANGLING("_RINvC1c1fRlB7_NtB2_1sE",  // c::f::<&i32, &i32, c::s>
394                     "c::f::<>");
395 }
396 
TEST(DemangleRust,NestedGenericArgs)397 TEST(DemangleRust, NestedGenericArgs) {
398   EXPECT_DEMANGLING("_RINvC1c1fINtB2_1slEmE",  // c::f::<c::s::<i32>, u32>
399                     "c::f::<>");
400 }
401 
TEST(DemangleRust,MonomorphicEntityNestedInsideGeneric)402 TEST(DemangleRust, MonomorphicEntityNestedInsideGeneric) {
403   EXPECT_DEMANGLING("_RNvINvC1c1fppE1g",  // c::f::<_, _>::g
404                     "c::f::<>::g");
405 }
406 
TEST(DemangleRust,ArrayTypeWithSimpleElementType)407 TEST(DemangleRust, ArrayTypeWithSimpleElementType) {
408   EXPECT_DEMANGLING("_RNvYAlj1f_NtC1c1t1f", "<[i32; 0x1f] as c::t>::f");
409 }
410 
TEST(DemangleRust,ArrayTypeWithComplexElementType)411 TEST(DemangleRust, ArrayTypeWithComplexElementType) {
412   EXPECT_DEMANGLING("_RNvYAINtC1c1slEj1f_NtB6_1t1f",
413                     "<[c::s::<>; 0x1f] as c::t>::f");
414 }
415 
TEST(DemangleRust,NestedArrayType)416 TEST(DemangleRust, NestedArrayType) {
417   EXPECT_DEMANGLING("_RNvYAAlj1f_j2e_NtC1c1t1f",
418                     "<[[i32; 0x1f]; 0x2e] as c::t>::f");
419 }
420 
TEST(DemangleRust,BackrefArraySize)421 TEST(DemangleRust, BackrefArraySize) {
422   EXPECT_DEMANGLING("_RNvYAAlj1f_B5_NtC1c1t1f",
423                     "<[[i32; 0x1f]; 0x1f] as c::t>::f");
424 }
425 
TEST(DemangleRust,ZeroArraySize)426 TEST(DemangleRust, ZeroArraySize) {
427   EXPECT_DEMANGLING("_RNvYAlj0_NtC1c1t1f", "<[i32; 0x0] as c::t>::f");
428 }
429 
TEST(DemangleRust,SurprisingMinusesInArraySize)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 
TEST(DemangleRust,NumberAsGenericArg)436 TEST(DemangleRust, NumberAsGenericArg) {
437   EXPECT_DEMANGLING("_RINvC1c1fKl8_E",  // c::f::<0x8>
438                     "c::f::<>");
439 }
440 
TEST(DemangleRust,NumberAsFirstOfTwoGenericArgs)441 TEST(DemangleRust, NumberAsFirstOfTwoGenericArgs) {
442   EXPECT_DEMANGLING("_RINvC1c1fKl8_mE",  // c::f::<0x8, u32>
443                     "c::f::<>");
444 }
445 
TEST(DemangleRust,NumberAsSecondOfTwoGenericArgs)446 TEST(DemangleRust, NumberAsSecondOfTwoGenericArgs) {
447   EXPECT_DEMANGLING("_RINvC1c1fmKl8_E",  // c::f::<u32, 0x8>
448                     "c::f::<>");
449 }
450 
TEST(DemangleRust,NumberPlaceholder)451 TEST(DemangleRust, NumberPlaceholder) {
452   EXPECT_DEMANGLING("_RNvINvC1c1fKpE1g",  // c::f::<_>::g
453                     "c::f::<>::g");
454 }
455 
TEST(DemangleRust,InherentImplWithoutDisambiguator)456 TEST(DemangleRust, InherentImplWithoutDisambiguator) {
457   EXPECT_DEMANGLING("_RNvMNtC8my_crate6my_modNtB2_9my_struct7my_func",
458                     "<my_crate::my_mod::my_struct>::my_func");
459 }
460 
TEST(DemangleRust,InherentImplWithDisambiguator)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 
TEST(DemangleRust,TraitImplWithoutDisambiguator)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 
TEST(DemangleRust,TraitImplWithDisambiguator)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 
TEST(DemangleRust,TraitImplWithNonpathSelfType)476 TEST(DemangleRust, TraitImplWithNonpathSelfType) {
477   EXPECT_DEMANGLING("_RNvXC8my_crateRlNtB2_8my_trait7my_func",
478                     "<&i32 as my_crate::my_trait>::my_func");
479 }
480 
TEST(DemangleRust,ThunkType)481 TEST(DemangleRust, ThunkType) {
482   EXPECT_DEMANGLING("_RNvYFEuNtC1c1t1f",  // <fn() as c::t>::f
483                     "<fn... as c::t>::f");
484 }
485 
TEST(DemangleRust,NontrivialFunctionReturnType)486 TEST(DemangleRust, NontrivialFunctionReturnType) {
487   EXPECT_DEMANGLING(
488       "_RNvYFERTlmENtC1c1t1f",  // <fn() -> &(i32, u32) as c::t>::f
489       "<fn... as c::t>::f");
490 }
491 
TEST(DemangleRust,OneParameterType)492 TEST(DemangleRust, OneParameterType) {
493   EXPECT_DEMANGLING("_RNvYFlEuNtC1c1t1f",  // <fn(i32) as c::t>::f
494                     "<fn... as c::t>::f");
495 }
496 
TEST(DemangleRust,TwoParameterTypes)497 TEST(DemangleRust, TwoParameterTypes) {
498   EXPECT_DEMANGLING("_RNvYFlmEuNtC1c1t1f",  // <fn(i32, u32) as c::t>::f
499                     "<fn... as c::t>::f");
500 }
501 
TEST(DemangleRust,ExternC)502 TEST(DemangleRust, ExternC) {
503   EXPECT_DEMANGLING("_RNvYFKCEuNtC1c1t1f",  // <extern "C" fn() as c::t>>::f
504                     "<fn... as c::t>::f");
505 }
506 
TEST(DemangleRust,ExternOther)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 
TEST(DemangleRust,Unsafe)513 TEST(DemangleRust, Unsafe) {
514   EXPECT_DEMANGLING("_RNvYFUEuNtC1c1t1f",  // <unsafe fn() as c::t>::f
515                     "<fn... as c::t>::f");
516 }
517 
TEST(DemangleRust,Binder)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 
TEST(DemangleRust,AllFnSigFeaturesInOrder)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 
TEST(DemangleRust,LifetimeInGenericArgs)532 TEST(DemangleRust, LifetimeInGenericArgs) {
533   EXPECT_DEMANGLING("_RINvC1c1fINtB2_1sL_EE",  // c::f::<c::s::<'_>>
534                     "c::f::<>");
535 }
536 
TEST(DemangleRust,EmptyDynTrait)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 
TEST(DemangleRust,SimpleDynTrait)544 TEST(DemangleRust, SimpleDynTrait) {
545   EXPECT_DEMANGLING("_RNvYDNtC1c1tEL_NtC1d1u1f",
546                     "<dyn c::t as d::u>::f");
547 }
548 
TEST(DemangleRust,DynTraitWithOneAssociatedType)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 
TEST(DemangleRust,DynTraitWithTwoAssociatedTypes)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 
TEST(DemangleRust,DynTraitPlusAutoTrait)562 TEST(DemangleRust, DynTraitPlusAutoTrait) {
563   EXPECT_DEMANGLING(
564       "_RNvYDNtC1c1tNtNtC3std6marker4SendEL_NtC1d1u1f",
565       "<dyn c::t + std::marker::Send as d::u>::f");
566 }
567 
TEST(DemangleRust,DynTraitPlusTwoAutoTraits)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 
TEST(DemangleRust,HigherRankedDynTrait)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
585