Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-const-checker.h"
20 : : #include "rust-hir.h"
21 : : #include "rust-hir-expr.h"
22 : : #include "rust-hir-stmt.h"
23 : : #include "rust-hir-item.h"
24 : :
25 : : namespace Rust {
26 : : namespace HIR {
27 : :
28 : 3348 : ConstChecker::ConstChecker ()
29 : 3348 : : resolver (*Resolver::Resolver::get ()),
30 : 3348 : mappings (*Analysis::Mappings::get ())
31 : 3348 : {}
32 : :
33 : : void
34 : 3348 : ConstChecker::go (HIR::Crate &crate)
35 : : {
36 : 16210 : for (auto &item : crate.get_items ())
37 : 12862 : item->accept_vis (*this);
38 : 3348 : }
39 : :
40 : : bool
41 : 302 : ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem &fn)
42 : : {
43 : : // FIXME: Is it really how we want to handle `rustc_const_stable`
44 : : // and `rustc_const_unstable`?
45 : : // TODO: Add these attributes to the attribute check and handle
46 : : // `stable` and `unstable` as well
47 : 302 : return std::any_of (
48 : 302 : fn.get_outer_attrs ().begin (), fn.get_outer_attrs ().end (),
49 : 290 : [] (const AST::Attribute &attr) {
50 : : // `starts_with` in C++11...
51 : 290 : return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
52 : 302 : });
53 : : }
54 : :
55 : : const char *
56 : 3 : ConstChecker::ctx_to_str (ConstGenericCtx ctx)
57 : : {
58 : 3 : switch (ctx)
59 : : {
60 : : case ConstGenericCtx::Function:
61 : : return "function";
62 : 0 : case ConstGenericCtx::TypeAlias:
63 : 0 : return "type alias";
64 : 0 : case ConstGenericCtx::Struct:
65 : 0 : return "struct";
66 : 0 : case ConstGenericCtx::Enum:
67 : 0 : return "enum";
68 : 1 : case ConstGenericCtx::Union:
69 : 1 : return "union";
70 : 0 : case ConstGenericCtx::Trait:
71 : 0 : return "trait";
72 : 1 : case ConstGenericCtx::Impl:
73 : 1 : return "impl";
74 : 0 : default:
75 : 0 : rust_unreachable ();
76 : : }
77 : : }
78 : :
79 : : bool
80 : 15786 : ConstChecker::ctx_allows_default (ConstGenericCtx ctx)
81 : : {
82 : 15786 : switch (ctx)
83 : : {
84 : : case ConstGenericCtx::TypeAlias:
85 : : case ConstGenericCtx::Struct:
86 : : case ConstGenericCtx::Enum:
87 : : case ConstGenericCtx::Trait:
88 : : return true;
89 : 11262 : default:
90 : 11262 : return false;
91 : : }
92 : : }
93 : :
94 : : void
95 : 15786 : ConstChecker::check_default_const_generics (
96 : : std::vector<std::unique_ptr<GenericParam>> ¶ms, ConstGenericCtx context)
97 : : {
98 : 15786 : if (ctx_allows_default (context))
99 : : return;
100 : :
101 : 12564 : for (auto ¶m : params)
102 : : {
103 : 1302 : if (param->get_kind () == GenericParam::GenericKind::CONST)
104 : : {
105 : 3 : auto const_param = static_cast<ConstGenericParam *> (param.get ());
106 : 3 : if (const_param->has_default_expression ())
107 : 3 : rust_error_at (
108 : 3 : param->get_locus (),
109 : : "default values for const generic parameters are not "
110 : : "allowed in %qs items",
111 : : ctx_to_str (context));
112 : : }
113 : : }
114 : : }
115 : :
116 : : void
117 : 0 : ConstChecker::visit (Lifetime &)
118 : 0 : {}
119 : :
120 : : void
121 : 0 : ConstChecker::visit (LifetimeParam &)
122 : 0 : {}
123 : :
124 : : void
125 : 17208 : ConstChecker::visit (PathInExpression &)
126 : 17208 : {}
127 : :
128 : : void
129 : 0 : ConstChecker::visit (TypePathSegment &)
130 : 0 : {}
131 : :
132 : : void
133 : 0 : ConstChecker::visit (TypePathSegmentGeneric &)
134 : 0 : {}
135 : :
136 : : void
137 : 0 : ConstChecker::visit (TypePathSegmentFunction &)
138 : 0 : {}
139 : :
140 : : void
141 : 2119 : ConstChecker::visit (TypePath &)
142 : 2119 : {}
143 : :
144 : : void
145 : 14 : ConstChecker::visit (QualifiedPathInExpression &)
146 : 14 : {}
147 : :
148 : : void
149 : 0 : ConstChecker::visit (QualifiedPathInType &)
150 : 0 : {}
151 : :
152 : : void
153 : 11655 : ConstChecker::visit (LiteralExpr &)
154 : 11655 : {}
155 : :
156 : : void
157 : 846 : ConstChecker::visit (BorrowExpr &expr)
158 : : {
159 : 846 : expr.get_expr ()->accept_vis (*this);
160 : 846 : }
161 : :
162 : : void
163 : 1164 : ConstChecker::visit (DereferenceExpr &expr)
164 : : {
165 : 1164 : expr.get_expr ()->accept_vis (*this);
166 : 1164 : }
167 : :
168 : : void
169 : 0 : ConstChecker::visit (ErrorPropagationExpr &expr)
170 : : {
171 : 0 : expr.get_expr ()->accept_vis (*this);
172 : 0 : }
173 : :
174 : : void
175 : 274 : ConstChecker::visit (NegationExpr &expr)
176 : : {
177 : 274 : expr.get_expr ()->accept_vis (*this);
178 : 274 : }
179 : :
180 : : void
181 : 2350 : ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
182 : : {
183 : 2350 : expr.get_lhs ()->accept_vis (*this);
184 : 2350 : expr.get_rhs ()->accept_vis (*this);
185 : 2350 : }
186 : :
187 : : void
188 : 893 : ConstChecker::visit (ComparisonExpr &expr)
189 : : {
190 : 893 : expr.get_lhs ()->accept_vis (*this);
191 : 893 : expr.get_rhs ()->accept_vis (*this);
192 : 893 : }
193 : :
194 : : void
195 : 378 : ConstChecker::visit (LazyBooleanExpr &expr)
196 : : {
197 : 378 : expr.get_lhs ()->accept_vis (*this);
198 : 378 : expr.get_rhs ()->accept_vis (*this);
199 : 378 : }
200 : :
201 : : void
202 : 3238 : ConstChecker::visit (TypeCastExpr &expr)
203 : : {
204 : 3238 : expr.get_expr ()->accept_vis (*this);
205 : 3238 : }
206 : :
207 : : void
208 : 1593 : ConstChecker::visit (AssignmentExpr &expr)
209 : : {
210 : 1593 : expr.get_lhs ()->accept_vis (*this);
211 : 1593 : expr.get_rhs ()->accept_vis (*this);
212 : 1593 : }
213 : :
214 : : void
215 : 159 : ConstChecker::visit (CompoundAssignmentExpr &expr)
216 : : {
217 : 159 : expr.get_lhs ()->accept_vis (*this);
218 : 159 : expr.get_rhs ()->accept_vis (*this);
219 : 159 : }
220 : :
221 : : void
222 : 135 : ConstChecker::visit (GroupedExpr &expr)
223 : : {
224 : 135 : expr.get_expr_in_parens ()->accept_vis (*this);
225 : 135 : }
226 : :
227 : : void
228 : 183 : ConstChecker::visit (ArrayElemsValues &elems)
229 : : {
230 : 1099 : for (auto &elem : elems.get_values ())
231 : 916 : elem->accept_vis (*this);
232 : 183 : }
233 : :
234 : : void
235 : 106 : ConstChecker::visit (ArrayElemsCopied &elems)
236 : : {
237 : 106 : elems.get_elem_to_copy ()->accept_vis (*this);
238 : :
239 : 106 : const_context.enter (elems.get_mappings ().get_hirid ());
240 : :
241 : 106 : elems.get_num_copies_expr ()->accept_vis (*this);
242 : :
243 : 106 : const_context.exit ();
244 : 106 : }
245 : :
246 : : void
247 : 289 : ConstChecker::visit (ArrayExpr &expr)
248 : : {
249 : 289 : expr.get_internal_elements ()->accept_vis (*this);
250 : 289 : }
251 : :
252 : : void
253 : 431 : ConstChecker::visit (ArrayIndexExpr &expr)
254 : : {
255 : 431 : expr.get_array_expr ()->accept_vis (*this);
256 : 431 : expr.get_index_expr ()->accept_vis (*this);
257 : 431 : }
258 : :
259 : : void
260 : 295 : ConstChecker::visit (TupleExpr &expr)
261 : : {
262 : 888 : for (auto &elem : expr.get_tuple_elems ())
263 : 593 : elem->accept_vis (*this);
264 : 295 : }
265 : :
266 : : void
267 : 672 : ConstChecker::visit (TupleIndexExpr &expr)
268 : : {
269 : 672 : expr.get_tuple_expr ()->accept_vis (*this);
270 : 672 : }
271 : :
272 : : void
273 : 50 : ConstChecker::visit (StructExprStruct &)
274 : 50 : {}
275 : :
276 : : void
277 : 211 : ConstChecker::visit (StructExprFieldIdentifier &)
278 : 211 : {}
279 : :
280 : : void
281 : 1887 : ConstChecker::visit (StructExprFieldIdentifierValue &field)
282 : : {
283 : 1887 : field.get_value ()->accept_vis (*this);
284 : 1887 : }
285 : :
286 : : void
287 : 42 : ConstChecker::visit (StructExprFieldIndexValue &field)
288 : : {
289 : 42 : field.get_value ()->accept_vis (*this);
290 : 42 : }
291 : :
292 : : void
293 : 805 : ConstChecker::visit (StructExprStructFields &expr)
294 : : {
295 : 2945 : for (auto &field : expr.get_fields ())
296 : 2140 : field->accept_vis (*this);
297 : 805 : }
298 : :
299 : : void
300 : 0 : ConstChecker::visit (StructExprStructBase &)
301 : 0 : {}
302 : :
303 : : void
304 : 5705 : ConstChecker::check_function_call (HirId fn_id, location_t locus)
305 : : {
306 : 5705 : if (!const_context.is_in_context ())
307 : 5218 : return;
308 : :
309 : 487 : auto maybe_fn = mappings.lookup_hir_item (fn_id);
310 : 487 : if (maybe_fn && maybe_fn->get_item_kind () != Item::ItemKind::Function)
311 : : return;
312 : :
313 : : // There are const extern functions (intrinsics)
314 : : // TODO: Should we check the ABI is only "rust intrinsics"? Is that handled
315 : : // elsewhere?
316 : 487 : HirId parent_block;
317 : 487 : auto maybe_extern_item
318 : 487 : = mappings.lookup_hir_extern_item (fn_id, &parent_block);
319 : 487 : if (maybe_extern_item
320 : 487 : && maybe_extern_item->get_extern_kind ()
321 : : != ExternalItem::ExternKind::Function)
322 : : return;
323 : :
324 : 487 : auto is_error = false;
325 : 487 : if (maybe_fn)
326 : : {
327 : 23 : auto fn = static_cast<Function *> (maybe_fn);
328 : 23 : if (!fn->get_qualifiers ().is_const ())
329 : 487 : is_error = true;
330 : : }
331 : :
332 : 487 : if (maybe_extern_item)
333 : : {
334 : 302 : {
335 : 302 : auto fn = static_cast<ExternalFunctionItem *> (maybe_extern_item);
336 : 302 : if (!is_const_extern_fn (*fn))
337 : : is_error = true;
338 : : }
339 : : }
340 : :
341 : 475 : if (is_error)
342 : 15 : rust_error_at (locus, ErrorCode::E0015,
343 : : "only functions marked as %<const%> are allowed to be "
344 : : "called from constant contexts");
345 : : }
346 : :
347 : : void
348 : 6652 : ConstChecker::visit (CallExpr &expr)
349 : : {
350 : 6652 : if (!expr.get_fnexpr ())
351 : 947 : return;
352 : :
353 : 6652 : NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
354 : 6652 : NodeId ref_node_id;
355 : 6652 : HirId definition_id;
356 : :
357 : : // We don't care about types here
358 : 6652 : if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
359 : : return;
360 : :
361 : 5705 : rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
362 : :
363 : 5705 : check_function_call (definition_id, expr.get_locus ());
364 : :
365 : 11905 : for (auto &arg : expr.get_arguments ())
366 : 6200 : arg->accept_vis (*this);
367 : : }
368 : :
369 : : void
370 : 977 : ConstChecker::visit (MethodCallExpr &expr)
371 : : {
372 : 977 : expr.get_receiver ()->accept_vis (*this);
373 : :
374 : 1390 : for (auto &arg : expr.get_arguments ())
375 : 413 : arg->accept_vis (*this);
376 : 977 : }
377 : :
378 : : void
379 : 1990 : ConstChecker::visit (FieldAccessExpr &expr)
380 : : {
381 : 1990 : expr.get_receiver_expr ()->accept_vis (*this);
382 : 1990 : }
383 : :
384 : : void
385 : 45 : ConstChecker::visit (ClosureExpr &expr)
386 : : {
387 : 45 : expr.get_expr ()->accept_vis (*this);
388 : 45 : }
389 : :
390 : : void
391 : 12582 : ConstChecker::visit (BlockExpr &expr)
392 : : {
393 : 28479 : for (auto &stmt : expr.get_statements ())
394 : 15897 : stmt->accept_vis (*this);
395 : :
396 : 12582 : if (expr.has_expr ())
397 : 8366 : expr.get_final_expr ()->accept_vis (*this);
398 : 12582 : }
399 : :
400 : : void
401 : 7 : ConstChecker::visit (ContinueExpr &)
402 : 7 : {}
403 : :
404 : : void
405 : 55 : ConstChecker::visit (BreakExpr &expr)
406 : : {
407 : 55 : if (expr.has_break_expr ())
408 : 15 : expr.get_expr ()->accept_vis (*this);
409 : 55 : }
410 : :
411 : : void
412 : 50 : ConstChecker::visit (RangeFromToExpr &expr)
413 : : {
414 : 50 : expr.get_from_expr ()->accept_vis (*this);
415 : 50 : expr.get_to_expr ()->accept_vis (*this);
416 : 50 : }
417 : :
418 : : void
419 : 7 : ConstChecker::visit (RangeFromExpr &expr)
420 : : {
421 : 7 : expr.get_from_expr ()->accept_vis (*this);
422 : 7 : }
423 : :
424 : : void
425 : 7 : ConstChecker::visit (RangeToExpr &expr)
426 : : {
427 : 7 : expr.get_to_expr ()->accept_vis (*this);
428 : 7 : }
429 : :
430 : : void
431 : 0 : ConstChecker::visit (RangeFullExpr &)
432 : 0 : {}
433 : :
434 : : void
435 : 7 : ConstChecker::visit (RangeFromToInclExpr &expr)
436 : : {
437 : 7 : expr.get_from_expr ()->accept_vis (*this);
438 : 7 : expr.get_to_expr ()->accept_vis (*this);
439 : 7 : }
440 : :
441 : : void
442 : 0 : ConstChecker::visit (RangeToInclExpr &)
443 : : {
444 : : // FIXME: Visit to_expr
445 : 0 : }
446 : :
447 : : void
448 : 315 : ConstChecker::visit (ReturnExpr &expr)
449 : : {
450 : 315 : if (expr.has_return_expr ())
451 : 306 : expr.get_expr ()->accept_vis (*this);
452 : 315 : }
453 : :
454 : : void
455 : 2478 : ConstChecker::visit (UnsafeBlockExpr &expr)
456 : : {
457 : 2478 : expr.get_block_expr ()->accept_vis (*this);
458 : 2478 : }
459 : :
460 : : void
461 : 90 : ConstChecker::visit (LoopExpr &expr)
462 : : {
463 : 90 : expr.get_loop_block ()->accept_vis (*this);
464 : 90 : }
465 : :
466 : : void
467 : 33 : ConstChecker::visit (WhileLoopExpr &expr)
468 : : {
469 : 33 : expr.get_predicate_expr ()->accept_vis (*this);
470 : 33 : expr.get_loop_block ()->accept_vis (*this);
471 : 33 : }
472 : :
473 : : void
474 : 0 : ConstChecker::visit (WhileLetLoopExpr &expr)
475 : : {
476 : 0 : expr.get_cond ()->accept_vis (*this);
477 : 0 : expr.get_loop_block ()->accept_vis (*this);
478 : 0 : }
479 : :
480 : : void
481 : 295 : ConstChecker::visit (IfExpr &expr)
482 : : {
483 : 295 : expr.get_if_condition ()->accept_vis (*this);
484 : 295 : expr.get_if_block ()->accept_vis (*this);
485 : 295 : }
486 : :
487 : : void
488 : 343 : ConstChecker::visit (IfExprConseqElse &expr)
489 : : {
490 : 343 : expr.get_if_condition ()->accept_vis (*this);
491 : 343 : expr.get_if_block ()->accept_vis (*this);
492 : 343 : expr.get_else_block ()->accept_vis (*this);
493 : 343 : }
494 : :
495 : : void
496 : 0 : ConstChecker::visit (IfLetExpr &expr)
497 : : {
498 : 0 : expr.get_scrutinee_expr ()->accept_vis (*this);
499 : 0 : expr.get_if_block ()->accept_vis (*this);
500 : 0 : }
501 : :
502 : : void
503 : 1 : ConstChecker::visit (IfLetExprConseqElse &expr)
504 : : {
505 : 1 : expr.get_scrutinee_expr ()->accept_vis (*this);
506 : 1 : expr.get_if_block ()->accept_vis (*this);
507 : :
508 : : // TODO: Visit else expression
509 : 1 : }
510 : :
511 : : void
512 : 191 : ConstChecker::visit (MatchExpr &expr)
513 : : {
514 : 191 : expr.get_scrutinee_expr ()->accept_vis (*this);
515 : :
516 : 665 : for (auto &match_arm : expr.get_match_cases ())
517 : 474 : match_arm.get_expr ()->accept_vis (*this);
518 : 191 : }
519 : :
520 : : void
521 : 0 : ConstChecker::visit (AwaitExpr &)
522 : : {
523 : : // TODO: Visit expression
524 : 0 : }
525 : :
526 : : void
527 : 0 : ConstChecker::visit (AsyncBlockExpr &)
528 : : {
529 : : // TODO: Visit block expression
530 : 0 : }
531 : :
532 : : void
533 : 0 : ConstChecker::visit (TypeParam &)
534 : 0 : {}
535 : :
536 : : void
537 : 0 : ConstChecker::visit (ConstGenericParam &)
538 : 0 : {}
539 : :
540 : : void
541 : 0 : ConstChecker::visit (LifetimeWhereClauseItem &)
542 : 0 : {}
543 : :
544 : : void
545 : 0 : ConstChecker::visit (TypeBoundWhereClauseItem &)
546 : 0 : {}
547 : :
548 : : void
549 : 419 : ConstChecker::visit (Module &module)
550 : : {
551 : 941 : for (auto &item : module.get_items ())
552 : 522 : item->accept_vis (*this);
553 : 419 : }
554 : :
555 : : void
556 : 0 : ConstChecker::visit (ExternCrate &)
557 : 0 : {}
558 : :
559 : : void
560 : 0 : ConstChecker::visit (UseTreeGlob &)
561 : 0 : {}
562 : :
563 : : void
564 : 0 : ConstChecker::visit (UseTreeList &)
565 : 0 : {}
566 : :
567 : : void
568 : 0 : ConstChecker::visit (UseTreeRebind &)
569 : 0 : {}
570 : :
571 : : void
572 : 0 : ConstChecker::visit (UseDeclaration &)
573 : 0 : {}
574 : :
575 : : void
576 : 8196 : ConstChecker::visit (Function &function)
577 : : {
578 : 8196 : auto const_fn = function.get_qualifiers ().is_const ();
579 : 8196 : if (const_fn)
580 : 604 : const_context.enter (function.get_mappings ().get_hirid ());
581 : :
582 : 8196 : check_default_const_generics (function.get_generic_params (),
583 : : ConstGenericCtx::Function);
584 : :
585 : 11130 : for (auto ¶m : function.get_function_params ())
586 : 2934 : param.get_type ()->accept_vis (*this);
587 : :
588 : 8196 : function.get_definition ()->accept_vis (*this);
589 : :
590 : 8196 : if (const_fn)
591 : 604 : const_context.exit ();
592 : 8196 : }
593 : :
594 : : void
595 : 740 : ConstChecker::visit (TypeAlias &type_alias)
596 : : {
597 : 740 : check_default_const_generics (type_alias.get_generic_params (),
598 : : ConstGenericCtx::TypeAlias);
599 : 740 : }
600 : :
601 : : void
602 : 889 : ConstChecker::visit (StructStruct &struct_item)
603 : : {
604 : 889 : check_default_const_generics (struct_item.get_generic_params (),
605 : : ConstGenericCtx::Struct);
606 : 889 : }
607 : :
608 : : void
609 : 734 : ConstChecker::visit (TupleStruct &tuple_struct)
610 : : {
611 : 734 : check_default_const_generics (tuple_struct.get_generic_params (),
612 : : ConstGenericCtx::Struct);
613 : 734 : }
614 : :
615 : : void
616 : 0 : ConstChecker::visit (EnumItem &)
617 : 0 : {}
618 : :
619 : : void
620 : 0 : ConstChecker::visit (EnumItemTuple &)
621 : 0 : {}
622 : :
623 : : void
624 : 0 : ConstChecker::visit (EnumItemStruct &)
625 : 0 : {}
626 : :
627 : : void
628 : 0 : ConstChecker::visit (EnumItemDiscriminant &item)
629 : : {
630 : 0 : const_context.enter (item.get_mappings ().get_hirid ());
631 : :
632 : 0 : item.get_discriminant_expression ()->accept_vis (*this);
633 : :
634 : 0 : const_context.exit ();
635 : 0 : }
636 : :
637 : : void
638 : 158 : ConstChecker::visit (Enum &enum_item)
639 : : {
640 : 158 : check_default_const_generics (enum_item.get_generic_params (),
641 : : ConstGenericCtx::Enum);
642 : 158 : }
643 : :
644 : : void
645 : 89 : ConstChecker::visit (Union &union_item)
646 : : {
647 : 89 : check_default_const_generics (union_item.get_generic_params (),
648 : : ConstGenericCtx::Union);
649 : 89 : }
650 : :
651 : : void
652 : 453 : ConstChecker::visit (ConstantItem &const_item)
653 : : {
654 : 453 : const_context.enter (const_item.get_mappings ().get_hirid ());
655 : :
656 : 453 : const_item.get_expr ()->accept_vis (*this);
657 : :
658 : 453 : const_context.exit ();
659 : 453 : }
660 : :
661 : : void
662 : 40 : ConstChecker::visit (StaticItem &static_item)
663 : : {
664 : 40 : const_context.enter (static_item.get_mappings ().get_hirid ());
665 : :
666 : 40 : static_item.get_expr ()->accept_vis (*this);
667 : :
668 : 40 : const_context.exit ();
669 : 40 : }
670 : :
671 : : void
672 : 981 : ConstChecker::visit (TraitItemFunc &item)
673 : : {
674 : 981 : if (item.has_block_defined ())
675 : 163 : item.get_block_expr ()->accept_vis (*this);
676 : 981 : }
677 : :
678 : : void
679 : 29 : ConstChecker::visit (TraitItemConst &item)
680 : : {
681 : 29 : if (item.has_expr ())
682 : 7 : item.get_expr ()->accept_vis (*this);
683 : 29 : }
684 : :
685 : : void
686 : 463 : ConstChecker::visit (TraitItemType &)
687 : 463 : {}
688 : :
689 : : void
690 : 2003 : ConstChecker::visit (Trait &trait)
691 : : {
692 : 2003 : check_default_const_generics (trait.get_generic_params (),
693 : : ConstGenericCtx::Trait);
694 : :
695 : 3476 : for (auto &item : trait.get_trait_items ())
696 : 1473 : item->accept_vis (*this);
697 : 2003 : }
698 : :
699 : : void
700 : 2977 : ConstChecker::visit (ImplBlock &impl)
701 : : {
702 : 2977 : check_default_const_generics (impl.get_generic_params (),
703 : : ConstGenericCtx::Impl);
704 : :
705 : 7047 : for (auto &item : impl.get_impl_items ())
706 : 4070 : item->accept_vis (*this);
707 : 2977 : }
708 : :
709 : : void
710 : 1 : ConstChecker::visit (ExternalStaticItem &)
711 : 1 : {}
712 : :
713 : : void
714 : 1579 : ConstChecker::visit (ExternalFunctionItem &)
715 : 1579 : {}
716 : :
717 : : void
718 : 0 : ConstChecker::visit (ExternalTypeItem &)
719 : 0 : {}
720 : :
721 : : void
722 : 1012 : ConstChecker::visit (ExternBlock &block)
723 : : {
724 : : // FIXME: Do we need to do this?
725 : 2592 : for (auto &item : block.get_extern_items ())
726 : 1580 : item->accept_vis (*this);
727 : 1012 : }
728 : :
729 : : void
730 : 0 : ConstChecker::visit (LiteralPattern &)
731 : 0 : {}
732 : :
733 : : void
734 : 0 : ConstChecker::visit (IdentifierPattern &)
735 : 0 : {}
736 : :
737 : : void
738 : 0 : ConstChecker::visit (WildcardPattern &)
739 : 0 : {}
740 : :
741 : : void
742 : 0 : ConstChecker::visit (RangePatternBoundLiteral &)
743 : 0 : {}
744 : :
745 : : void
746 : 0 : ConstChecker::visit (RangePatternBoundPath &)
747 : 0 : {}
748 : :
749 : : void
750 : 0 : ConstChecker::visit (RangePatternBoundQualPath &)
751 : 0 : {}
752 : :
753 : : void
754 : 0 : ConstChecker::visit (RangePattern &)
755 : 0 : {}
756 : :
757 : : void
758 : 0 : ConstChecker::visit (ReferencePattern &)
759 : 0 : {}
760 : :
761 : : void
762 : 0 : ConstChecker::visit (StructPatternFieldTuplePat &)
763 : 0 : {}
764 : :
765 : : void
766 : 0 : ConstChecker::visit (StructPatternFieldIdentPat &)
767 : 0 : {}
768 : :
769 : : void
770 : 0 : ConstChecker::visit (StructPatternFieldIdent &)
771 : 0 : {}
772 : :
773 : : void
774 : 0 : ConstChecker::visit (StructPattern &)
775 : 0 : {}
776 : :
777 : : void
778 : 0 : ConstChecker::visit (TupleStructItemsNoRange &)
779 : 0 : {}
780 : :
781 : : void
782 : 0 : ConstChecker::visit (TupleStructItemsRange &)
783 : 0 : {}
784 : :
785 : : void
786 : 0 : ConstChecker::visit (TupleStructPattern &)
787 : 0 : {}
788 : :
789 : : void
790 : 0 : ConstChecker::visit (TuplePatternItemsMultiple &)
791 : 0 : {}
792 : :
793 : : void
794 : 0 : ConstChecker::visit (TuplePatternItemsRanged &)
795 : 0 : {}
796 : :
797 : : void
798 : 0 : ConstChecker::visit (TuplePattern &)
799 : 0 : {}
800 : :
801 : : void
802 : 0 : ConstChecker::visit (SlicePattern &)
803 : 0 : {}
804 : :
805 : : void
806 : 0 : ConstChecker::visit (AltPattern &)
807 : 0 : {}
808 : :
809 : : void
810 : 44 : ConstChecker::visit (EmptyStmt &)
811 : 44 : {}
812 : :
813 : : void
814 : 9802 : ConstChecker::visit (LetStmt &stmt)
815 : : {
816 : 9802 : if (stmt.has_init_expr ())
817 : 8796 : stmt.get_init_expr ()->accept_vis (*this);
818 : 9802 : }
819 : :
820 : : void
821 : 5795 : ConstChecker::visit (ExprStmt &stmt)
822 : : {
823 : 5795 : stmt.get_expr ()->accept_vis (*this);
824 : 5795 : }
825 : :
826 : : void
827 : 0 : ConstChecker::visit (TraitBound &)
828 : 0 : {}
829 : :
830 : : void
831 : 0 : ConstChecker::visit (ImplTraitType &)
832 : 0 : {}
833 : :
834 : : void
835 : 0 : ConstChecker::visit (TraitObjectType &)
836 : 0 : {}
837 : :
838 : : void
839 : 0 : ConstChecker::visit (ParenthesisedType &)
840 : 0 : {}
841 : :
842 : : void
843 : 0 : ConstChecker::visit (ImplTraitTypeOneBound &)
844 : 0 : {}
845 : :
846 : : void
847 : 16 : ConstChecker::visit (TupleType &)
848 : 16 : {}
849 : :
850 : : void
851 : 0 : ConstChecker::visit (NeverType &)
852 : 0 : {}
853 : :
854 : : void
855 : 198 : ConstChecker::visit (RawPointerType &)
856 : 198 : {}
857 : :
858 : : void
859 : 417 : ConstChecker::visit (ReferenceType &type)
860 : : {
861 : 417 : if (const_context.is_in_context () && type.is_mut ())
862 : 1 : rust_error_at (type.get_locus (), ErrorCode::E0658,
863 : : "mutable references are not allowed in constant functions");
864 : 417 : }
865 : :
866 : : void
867 : 177 : ConstChecker::visit (ArrayType &type)
868 : : {
869 : 177 : const_context.enter (type.get_mappings ().get_hirid ());
870 : :
871 : 177 : type.get_size_expr ()->accept_vis (*this);
872 : :
873 : 177 : const_context.exit ();
874 : 177 : }
875 : :
876 : : void
877 : 1 : ConstChecker::visit (SliceType &)
878 : 1 : {}
879 : :
880 : : void
881 : 0 : ConstChecker::visit (InferredType &)
882 : 0 : {}
883 : :
884 : : void
885 : 6 : ConstChecker::visit (BareFunctionType &)
886 : 6 : {}
887 : :
888 : : } // namespace HIR
889 : : } // namespace Rust
|