Line data Source code
1 : /* General AST-related method implementations for Rust frontend.
2 : Copyright (C) 2009-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "rust-system.h"
21 : #include "rust-ast-full.h"
22 : #include "rust-diagnostics.h"
23 : #include "rust-ast-visitor.h"
24 : #include "rust-macro.h"
25 : #include "rust-lex.h"
26 : #include "rust-parse.h"
27 : #include "rust-operators.h"
28 :
29 : namespace Rust {
30 : namespace AST {
31 :
32 : RangeKind
33 56 : tokenid_to_rangekind (TokenId id)
34 : {
35 56 : switch (id)
36 : {
37 : case DOT_DOT_EQ:
38 : return RangeKind::INCLUDED;
39 : case ELLIPSIS:
40 : return RangeKind::ELLIPSIS;
41 : case DOT_DOT:
42 : return RangeKind::EXCLUDED;
43 0 : default:
44 0 : rust_unreachable ();
45 : }
46 : }
47 :
48 : std::string
49 0 : LiteralPattern::as_string () const
50 : {
51 0 : return (has_minus ? "-" : "") + lit.as_string ();
52 : }
53 :
54 : std::string
55 0 : IdentifierPattern::as_string () const
56 : {
57 : // TODO: maybe rewrite to work with non-linearisable patterns
58 0 : std::string str;
59 :
60 0 : if (is_ref)
61 0 : str += "ref ";
62 :
63 0 : if (is_mut)
64 0 : str += "mut ";
65 :
66 0 : str += variable_ident.as_string ();
67 :
68 0 : if (has_subpattern ())
69 0 : str += " @ " + subpattern->as_string ();
70 :
71 0 : return str;
72 : }
73 :
74 : std::string
75 0 : RangePatternBoundLiteral::as_string () const
76 : {
77 0 : std::string str;
78 :
79 0 : if (has_minus)
80 0 : str += "-";
81 :
82 0 : str += literal.as_string ();
83 :
84 0 : return str;
85 : }
86 :
87 : std::string
88 0 : RangePattern::as_string () const
89 : {
90 : // TODO: maybe rewrite to work with non-linearisable bounds
91 0 : switch (range_kind)
92 : {
93 0 : case RangeKind::EXCLUDED:
94 0 : return lower->as_string () + ".." + upper->as_string ();
95 0 : case RangeKind::INCLUDED:
96 0 : return lower->as_string () + "..=" + upper->as_string ();
97 0 : case RangeKind::ELLIPSIS:
98 0 : return lower->as_string () + "..." + upper->as_string ();
99 0 : default:
100 0 : rust_unreachable ();
101 : }
102 : }
103 :
104 : std::string
105 0 : ReferencePattern::as_string () const
106 : {
107 : // TODO: maybe rewrite to work with non-linearisable patterns
108 0 : std::string str ("&");
109 :
110 0 : if (has_two_amps)
111 0 : str += "&";
112 :
113 0 : if (is_mut)
114 0 : str += "mut ";
115 :
116 0 : str += pattern->as_string ();
117 :
118 0 : return str;
119 : }
120 :
121 : std::string
122 0 : StructPatternField::as_string () const
123 : {
124 : // outer attributes
125 0 : std::string str = append_attributes (outer_attrs, OUTER);
126 :
127 0 : return str;
128 : }
129 :
130 : std::string
131 0 : StructPatternFieldTuplePat::as_string () const
132 : {
133 : // TODO: maybe rewrite to work with non-linearisable patterns
134 0 : std::string str = StructPatternField::as_string ();
135 :
136 0 : str += "\n";
137 :
138 0 : str += std::to_string (index) + " : " + tuple_pattern->as_string ();
139 :
140 0 : return str;
141 : }
142 :
143 : std::string
144 0 : StructPatternFieldIdentPat::as_string () const
145 : {
146 : // TODO: maybe rewrite to work with non-linearisable patterns
147 0 : std::string str = StructPatternField::as_string ();
148 :
149 0 : str += "\n";
150 :
151 0 : str += ident.as_string () + " : " + ident_pattern->as_string ();
152 :
153 0 : return str;
154 : }
155 :
156 : std::string
157 0 : StructPatternFieldIdent::as_string () const
158 : {
159 0 : std::string str = StructPatternField::as_string ();
160 :
161 0 : str += "\n";
162 :
163 0 : if (has_ref)
164 0 : str += "ref ";
165 :
166 0 : if (has_mut)
167 0 : str += "mut ";
168 :
169 0 : str += ident.as_string ();
170 :
171 0 : return str;
172 : }
173 :
174 : std::string
175 0 : StructPatternElements::as_string () const
176 : {
177 0 : std::string str ("\n Fields: ");
178 :
179 0 : if (!has_struct_pattern_fields ())
180 : {
181 0 : str += "none";
182 : }
183 : else
184 : {
185 0 : for (const auto &field : fields)
186 0 : str += "\n " + field->as_string ();
187 : }
188 :
189 0 : str += "\n Has rest: ";
190 0 : if (has_rest_pattern)
191 0 : str += "true";
192 : else
193 0 : str += "false";
194 :
195 0 : return str;
196 : }
197 :
198 : std::string
199 0 : StructPattern::as_string () const
200 : {
201 0 : std::string str ("StructPattern: \n Path: ");
202 :
203 0 : str += path.as_string ();
204 :
205 0 : str += "\n Struct pattern elems: ";
206 0 : if (!has_struct_pattern_elems ())
207 0 : str += "none";
208 : else
209 0 : str += elems.as_string ();
210 :
211 0 : return str;
212 : }
213 :
214 : std::string
215 0 : TupleStructItemsNoRest::as_string () const
216 : {
217 0 : std::string str;
218 :
219 0 : for (const auto &pattern : patterns)
220 0 : str += "\n " + pattern->as_string ();
221 :
222 0 : return str;
223 : }
224 :
225 : std::string
226 0 : TupleStructItemsHasRest::as_string () const
227 : {
228 0 : std::string str ("\n Lower patterns: ");
229 :
230 0 : if (lower_patterns.empty ())
231 : {
232 0 : str += "none";
233 : }
234 : else
235 : {
236 0 : for (const auto &lower : lower_patterns)
237 0 : str += "\n " + lower->as_string ();
238 : }
239 :
240 0 : str += "\n Upper patterns: ";
241 0 : if (upper_patterns.empty ())
242 : {
243 0 : str += "none";
244 : }
245 : else
246 : {
247 0 : for (const auto &upper : upper_patterns)
248 0 : str += "\n " + upper->as_string ();
249 : }
250 :
251 0 : return str;
252 : }
253 :
254 : std::string
255 0 : TupleStructPattern::as_string () const
256 : {
257 0 : std::string str ("TupleStructPattern: \n Path: ");
258 :
259 0 : str += path.as_string ();
260 :
261 0 : str += "\n Tuple struct items: " + items->as_string ();
262 :
263 0 : return str;
264 : }
265 :
266 : std::string
267 0 : TuplePatternItemsNoRest::as_string () const
268 : {
269 0 : std::string str;
270 :
271 0 : for (const auto &pattern : patterns)
272 0 : str += "\n " + pattern->as_string ();
273 :
274 0 : return str;
275 : }
276 :
277 : std::string
278 0 : TuplePatternItemsHasRest::as_string () const
279 : {
280 0 : std::string str;
281 :
282 0 : str += "\n Lower patterns: ";
283 0 : if (lower_patterns.empty ())
284 : {
285 0 : str += "none";
286 : }
287 : else
288 : {
289 0 : for (const auto &lower : lower_patterns)
290 0 : str += "\n " + lower->as_string ();
291 : }
292 :
293 0 : str += "\n Upper patterns: ";
294 0 : if (upper_patterns.empty ())
295 : {
296 0 : str += "none";
297 : }
298 : else
299 : {
300 0 : for (const auto &upper : upper_patterns)
301 0 : str += "\n " + upper->as_string ();
302 : }
303 :
304 0 : return str;
305 : }
306 :
307 : std::string
308 0 : TuplePattern::as_string () const
309 : {
310 0 : return "TuplePattern: " + items->as_string ();
311 : }
312 :
313 : std::string
314 0 : GroupedExpr::as_string () const
315 : {
316 0 : std::string str ("Grouped expr:");
317 :
318 : // outer attrs
319 0 : str += append_attributes (outer_attrs, OUTER);
320 :
321 : // inner attributes
322 0 : str += append_attributes (inner_attrs, INNER);
323 :
324 0 : str += "\n Expr in parens: " + expr_in_parens->as_string ();
325 :
326 0 : return str;
327 : }
328 :
329 : std::string
330 0 : SlicePatternItemsNoRest::as_string () const
331 : {
332 0 : std::string str;
333 :
334 0 : for (const auto &pattern : patterns)
335 0 : str += "\n " + pattern->as_string ();
336 :
337 0 : return str;
338 : }
339 :
340 : std::string
341 0 : SlicePatternItemsHasRest::as_string () const
342 : {
343 0 : std::string str;
344 :
345 0 : str += "\n Lower patterns: ";
346 0 : if (lower_patterns.empty ())
347 : {
348 0 : str += "none";
349 : }
350 : else
351 : {
352 0 : for (const auto &lower : lower_patterns)
353 0 : str += "\n " + lower->as_string ();
354 : }
355 :
356 0 : str += "\n Upper patterns: ";
357 0 : if (upper_patterns.empty ())
358 : {
359 0 : str += "none";
360 : }
361 : else
362 : {
363 0 : for (const auto &upper : upper_patterns)
364 0 : str += "\n " + upper->as_string ();
365 : }
366 :
367 0 : return str;
368 : }
369 :
370 : std::string
371 0 : SlicePattern::as_string () const
372 : {
373 0 : return "SlicePattern: " + items->as_string ();
374 : }
375 :
376 : std::string
377 0 : AltPattern::as_string () const
378 : {
379 0 : std::string str ("AltPattern: ");
380 :
381 0 : for (const auto &pattern : alts)
382 0 : str += "\n " + pattern->as_string ();
383 :
384 0 : return str;
385 : }
386 :
387 : void
388 3676 : AltPattern::accept_vis (ASTVisitor &vis)
389 : {
390 3676 : vis.visit (*this);
391 3676 : }
392 :
393 : void
394 707 : GroupedPattern::accept_vis (ASTVisitor &vis)
395 : {
396 707 : vis.visit (*this);
397 707 : }
398 :
399 : void
400 6643 : GroupedExpr::accept_vis (ASTVisitor &vis)
401 : {
402 6643 : vis.visit (*this);
403 6643 : }
404 :
405 : void
406 504 : SlicePatternItemsNoRest::accept_vis (ASTVisitor &vis)
407 : {
408 504 : vis.visit (*this);
409 504 : }
410 :
411 : void
412 702 : SlicePatternItemsHasRest::accept_vis (ASTVisitor &vis)
413 : {
414 702 : vis.visit (*this);
415 702 : }
416 :
417 : void
418 1282 : SlicePattern::accept_vis (ASTVisitor &vis)
419 : {
420 1282 : vis.visit (*this);
421 1282 : }
422 :
423 : void
424 426 : TuplePatternItemsHasRest::accept_vis (ASTVisitor &vis)
425 : {
426 426 : vis.visit (*this);
427 426 : }
428 :
429 : void
430 10737 : TuplePattern::accept_vis (ASTVisitor &vis)
431 : {
432 10737 : vis.visit (*this);
433 10737 : }
434 :
435 : void
436 9887 : TuplePatternItemsNoRest::accept_vis (ASTVisitor &vis)
437 : {
438 9887 : vis.visit (*this);
439 9887 : }
440 :
441 : void
442 7274 : LiteralPattern::accept_vis (ASTVisitor &vis)
443 : {
444 7274 : vis.visit (*this);
445 7274 : }
446 :
447 : void
448 502041 : IdentifierPattern::accept_vis (ASTVisitor &vis)
449 : {
450 502041 : vis.visit (*this);
451 502041 : }
452 :
453 : void
454 22615 : WildcardPattern::accept_vis (ASTVisitor &vis)
455 : {
456 22615 : vis.visit (*this);
457 22615 : }
458 :
459 : void
460 0 : RestPattern::accept_vis (ASTVisitor &vis)
461 : {
462 0 : vis.visit (*this);
463 0 : }
464 :
465 : void
466 1573 : RangePatternBoundLiteral::accept_vis (ASTVisitor &vis)
467 : {
468 1573 : vis.visit (*this);
469 1573 : }
470 :
471 : void
472 273 : RangePatternBoundPath::accept_vis (ASTVisitor &vis)
473 : {
474 273 : vis.visit (*this);
475 273 : }
476 :
477 : void
478 0 : RangePatternBoundQualPath::accept_vis (ASTVisitor &vis)
479 : {
480 0 : vis.visit (*this);
481 0 : }
482 :
483 : void
484 1014 : RangePattern::accept_vis (ASTVisitor &vis)
485 : {
486 1014 : vis.visit (*this);
487 1014 : }
488 :
489 : void
490 3468 : ReferencePattern::accept_vis (ASTVisitor &vis)
491 : {
492 3468 : vis.visit (*this);
493 3468 : }
494 :
495 : void
496 384 : StructPatternFieldTuplePat::accept_vis (ASTVisitor &vis)
497 : {
498 384 : vis.visit (*this);
499 384 : }
500 :
501 : void
502 2421 : StructPatternFieldIdentPat::accept_vis (ASTVisitor &vis)
503 : {
504 2421 : vis.visit (*this);
505 2421 : }
506 :
507 : void
508 1487 : StructPatternFieldIdent::accept_vis (ASTVisitor &vis)
509 : {
510 1487 : vis.visit (*this);
511 1487 : }
512 :
513 : void
514 2736 : StructPattern::accept_vis (ASTVisitor &vis)
515 : {
516 2736 : vis.visit (*this);
517 2736 : }
518 :
519 : void
520 18601 : TupleStructItemsNoRest::accept_vis (ASTVisitor &vis)
521 : {
522 18601 : vis.visit (*this);
523 18601 : }
524 :
525 : void
526 616 : TupleStructItemsHasRest::accept_vis (ASTVisitor &vis)
527 : {
528 616 : vis.visit (*this);
529 616 : }
530 :
531 : void
532 20223 : TupleStructPattern::accept_vis (ASTVisitor &vis)
533 : {
534 20223 : vis.visit (*this);
535 20223 : }
536 :
537 : } // namespace AST
538 : } // namespace Rust
|