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