]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/checks/errors/rust-unsafe-checker.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / checks / errors / rust-unsafe-checker.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
b1b35204
AC
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-unsafe-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
25namespace Rust {
26namespace HIR {
27
28UnsafeChecker::UnsafeChecker ()
29 : context (*Resolver::TypeCheckContext::get ()),
30 resolver (*Resolver::Resolver::get ()),
31 mappings (*Analysis::Mappings::get ())
32{}
33
34void
35UnsafeChecker::go (HIR::Crate &crate)
36{
37 for (auto &item : crate.items)
38 item->accept_vis (*this);
39}
40
41static void
42check_static_mut (HIR::Item *maybe_static, Location locus)
43{
44 if (maybe_static->get_hir_kind () == Node::BaseKind::VIS_ITEM)
45 {
46 auto item = static_cast<Item *> (maybe_static);
47 if (item->get_item_kind () == Item::ItemKind::Static)
48 {
49 auto static_item = static_cast<StaticItem *> (item);
50 if (static_item->is_mut ())
51 rust_error_at (
52 locus, "use of mutable static requires unsafe function or block");
53 }
54 }
55}
56
57static void
58check_extern_static (HIR::ExternalItem *maybe_static, Location locus)
59{
60 if (maybe_static->get_extern_kind () == ExternalItem::ExternKind::Static)
61 rust_error_at (locus,
62 "use of extern static requires unsafe function or block");
63}
64
65void
66UnsafeChecker::check_use_of_static (HirId node_id, Location locus)
67{
68 if (unsafe_context.is_in_context ())
69 return;
70
71 auto maybe_static_mut = mappings.lookup_hir_item (node_id);
72
73 HirId extern_block;
74 auto maybe_extern_static
75 = mappings.lookup_hir_extern_item (node_id, &extern_block);
76
77 if (maybe_static_mut)
78 check_static_mut (maybe_static_mut, locus);
79
80 if (maybe_extern_static)
81 check_extern_static (static_cast<ExternalItem *> (maybe_extern_static),
82 locus);
83}
84
85static void
86check_unsafe_call (HIR::Function *fn, Location locus, const std::string &kind)
87{
88 if (fn->get_qualifiers ().is_unsafe ())
89 rust_error_at (locus, "call to unsafe %s requires unsafe function or block",
90 kind.c_str ());
91}
92
93static bool
94is_safe_intrinsic (const std::string &fn_name)
95{
96 static const std::unordered_set<std::string> safe_intrinsics = {
97 "abort",
98 "size_of",
99 "min_align_of",
100 "needs_drop",
101 "caller_location",
102 "add_with_overflow",
103 "sub_with_overflow",
104 "mul_with_overflow",
105 "wrapping_add",
106 "wrapping_sub",
107 "wrapping_mul",
108 "saturating_add",
109 "saturating_sub",
110 "rotate_left",
111 "rotate_right",
112 "ctpop",
113 "ctlz",
114 "cttz",
115 "bswap",
116 "bitreverse",
117 "discriminant_value",
118 "type_id",
119 "likely",
120 "unlikely",
121 "ptr_guaranteed_eq",
122 "ptr_guaranteed_ne",
123 "minnumf32",
124 "minnumf64",
125 "maxnumf32",
126 "rustc_peek",
127 "maxnumf64",
128 "type_name",
129 "forget",
130 "black_box",
131 "variant_count",
132 };
133
134 return safe_intrinsics.find (fn_name) != safe_intrinsics.end ();
135}
136
137static void
138check_extern_call (HIR::ExternalItem *maybe_fn, HIR::ExternBlock *parent_block,
139 Location locus)
140{
141 // We have multiple operations to perform here
142 // 1. Is the item an actual function we're calling
143 // 2. Is the block it's defined in an FFI block or an `extern crate` block
144 //
145 // It is not unsafe to call into other crates, so items defined in an `extern
146 // crate` must be callable without being in an unsafe context. On the other
147 // hand, any function defined in a block with a specific ABI (even `extern
148 // "Rust"` blocks) is unsafe to call
149
150 if (maybe_fn->get_extern_kind () != ExternalItem::ExternKind::Function)
151 return;
152
153 // Some intrinsics are safe to call
154 if (parent_block->get_abi () == Rust::ABI::INTRINSIC
155 && is_safe_intrinsic (maybe_fn->get_item_name ()))
156 return;
157
158 rust_error_at (locus,
159 "call to extern function requires unsafe function or block");
160}
161
162void
163UnsafeChecker::check_function_call (HirId node_id, Location locus)
164{
165 if (unsafe_context.is_in_context ())
166 return;
167
168 HirId parent_extern_block;
169 auto maybe_fn = mappings.lookup_hir_item (node_id);
170 auto maybe_extern
171 = mappings.lookup_hir_extern_item (node_id, &parent_extern_block);
172
173 if (maybe_fn && maybe_fn->get_item_kind () == Item::ItemKind::Function)
174 check_unsafe_call (static_cast<Function *> (maybe_fn), locus, "function");
175
176 if (maybe_extern)
177 check_extern_call (static_cast<ExternalItem *> (maybe_extern),
178 mappings.lookup_hir_extern_block (parent_extern_block),
179 locus);
180}
181
776ff053
P
182static void
183check_target_attr (HIR::Function *fn, Location locus)
184{
185 if (std::any_of (fn->get_outer_attrs ().begin (),
186 fn->get_outer_attrs ().end (),
187 [] (const AST::Attribute &attr) {
188 return attr.get_path ().as_string () == "target_feature";
189 }))
190 rust_error_at (locus,
191 "call to function with %<#[target_feature]%> requires "
192 "unsafe function or block");
193}
194
195void
196UnsafeChecker::check_function_attr (HirId node_id, Location locus)
197{
198 if (unsafe_context.is_in_context ())
199 return;
200
201 auto maybe_fn = mappings.lookup_hir_item (node_id);
202
203 if (maybe_fn && maybe_fn->get_item_kind () == Item::ItemKind::Function)
204 check_target_attr (static_cast<Function *> (maybe_fn), locus);
205}
206
b1b35204 207void
9f455ed8 208UnsafeChecker::visit (Lifetime &)
b1b35204
AC
209{}
210
211void
9f455ed8 212UnsafeChecker::visit (LifetimeParam &)
b1b35204
AC
213{}
214
215void
216UnsafeChecker::visit (PathInExpression &path)
217{
218 NodeId ast_node_id = path.get_mappings ().get_nodeid ();
219 NodeId ref_node_id;
220 HirId definition_id;
221
222 if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
223 return;
224
225 rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
226
227 check_use_of_static (definition_id, path.get_locus ());
228}
229
230void
9f455ed8 231UnsafeChecker::visit (TypePathSegment &)
b1b35204
AC
232{}
233
234void
9f455ed8 235UnsafeChecker::visit (TypePathSegmentGeneric &)
b1b35204
AC
236{}
237
238void
9f455ed8 239UnsafeChecker::visit (TypePathSegmentFunction &)
b1b35204
AC
240{}
241
242void
9f455ed8 243UnsafeChecker::visit (TypePath &)
b1b35204
AC
244{}
245
246void
9f455ed8 247UnsafeChecker::visit (QualifiedPathInExpression &)
b1b35204
AC
248{}
249
250void
9f455ed8 251UnsafeChecker::visit (QualifiedPathInType &)
b1b35204
AC
252{}
253
254void
9f455ed8 255UnsafeChecker::visit (LiteralExpr &)
b1b35204
AC
256{}
257
258void
259UnsafeChecker::visit (BorrowExpr &expr)
260{
261 expr.get_expr ()->accept_vis (*this);
262}
263
264void
265UnsafeChecker::visit (DereferenceExpr &expr)
266{
267 TyTy::BaseType *to_deref_type;
268 auto to_deref = expr.get_expr ()->get_mappings ().get_hirid ();
269
270 rust_assert (context.lookup_type (to_deref, &to_deref_type));
271
272 if (to_deref_type->get_kind () == TyTy::TypeKind::POINTER
273 && !unsafe_context.is_in_context ())
274 rust_error_at (expr.get_locus (), "dereference of raw pointer requires "
275 "unsafe function or block");
276}
277
278void
279UnsafeChecker::visit (ErrorPropagationExpr &expr)
280{
281 expr.get_expr ()->accept_vis (*this);
282}
283
284void
285UnsafeChecker::visit (NegationExpr &expr)
286{
287 expr.get_expr ()->accept_vis (*this);
288}
289
290void
291UnsafeChecker::visit (ArithmeticOrLogicalExpr &expr)
292{
293 expr.get_lhs ()->accept_vis (*this);
294 expr.get_rhs ()->accept_vis (*this);
295}
296
297void
298UnsafeChecker::visit (ComparisonExpr &expr)
299{
300 expr.get_lhs ()->accept_vis (*this);
301 expr.get_rhs ()->accept_vis (*this);
302}
303
304void
305UnsafeChecker::visit (LazyBooleanExpr &expr)
306{
307 expr.get_lhs ()->accept_vis (*this);
308 expr.get_rhs ()->accept_vis (*this);
309}
310
311void
312UnsafeChecker::visit (TypeCastExpr &expr)
313{
314 expr.get_expr ()->accept_vis (*this);
315}
316
317void
318UnsafeChecker::visit (AssignmentExpr &expr)
319{
320 expr.get_lhs ()->accept_vis (*this);
321 expr.get_rhs ()->accept_vis (*this);
322}
323
324void
325UnsafeChecker::visit (CompoundAssignmentExpr &expr)
326{
327 expr.get_left_expr ()->accept_vis (*this);
328 expr.get_right_expr ()->accept_vis (*this);
329}
330
331void
332UnsafeChecker::visit (GroupedExpr &expr)
333{
334 expr.get_expr_in_parens ()->accept_vis (*this);
335}
336
337void
338UnsafeChecker::visit (ArrayElemsValues &elems)
339{
340 for (auto &elem : elems.get_values ())
341 elem->accept_vis (*this);
342}
343
344void
345UnsafeChecker::visit (ArrayElemsCopied &elems)
346{
347 elems.get_elem_to_copy ()->accept_vis (*this);
348}
349
350void
351UnsafeChecker::visit (ArrayExpr &expr)
352{
353 expr.get_internal_elements ()->accept_vis (*this);
354}
355
356void
357UnsafeChecker::visit (ArrayIndexExpr &expr)
358{
359 expr.get_array_expr ()->accept_vis (*this);
360 expr.get_index_expr ()->accept_vis (*this);
361}
362
363void
364UnsafeChecker::visit (TupleExpr &expr)
365{
366 for (auto &elem : expr.get_tuple_elems ())
367 elem->accept_vis (*this);
368}
369
370void
371UnsafeChecker::visit (TupleIndexExpr &expr)
372{
373 expr.get_tuple_expr ()->accept_vis (*this);
374}
375
376void
9f455ed8 377UnsafeChecker::visit (StructExprStruct &)
b1b35204
AC
378{}
379
380void
9f455ed8 381UnsafeChecker::visit (StructExprFieldIdentifier &)
b1b35204
AC
382{}
383
384void
385UnsafeChecker::visit (StructExprFieldIdentifierValue &field)
386{
387 field.get_value ()->accept_vis (*this);
388}
389
390void
391UnsafeChecker::visit (StructExprFieldIndexValue &field)
392{
393 field.get_value ()->accept_vis (*this);
394}
395
396void
397UnsafeChecker::visit (StructExprStructFields &expr)
398{
399 for (auto &field : expr.get_fields ())
400 field->accept_vis (*this);
401}
402
403void
9f455ed8 404UnsafeChecker::visit (StructExprStructBase &)
b1b35204
AC
405{}
406
407void
408UnsafeChecker::visit (CallExpr &expr)
409{
410 auto fn = expr.get_fnexpr ();
411 if (!fn)
412 return;
413
414 NodeId ast_node_id = fn->get_mappings ().get_nodeid ();
415 NodeId ref_node_id;
416 HirId definition_id;
417
418 // There are no unsafe types, and functions are defined in the name resolver.
419 // If we can't find the name, then we're dealing with a type and should return
420 // early.
421 if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
422 return;
423
424 rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
425
776ff053 426 // At this point we have the function's HIR Id. There are three checks we
b1b35204
AC
427 // must perform:
428 // 1. The function is an unsafe one
429 // 2. The function is an extern one
776ff053 430 // 3. The function is marked with a target_feature attribute
b1b35204 431 check_function_call (definition_id, expr.get_locus ());
776ff053 432 check_function_attr (definition_id, expr.get_locus ());
b1b35204
AC
433
434 if (expr.has_params ())
435 for (auto &arg : expr.get_arguments ())
436 arg->accept_vis (*this);
437}
438
439void
440UnsafeChecker::visit (MethodCallExpr &expr)
441{
442 TyTy::BaseType *method_type;
443 context.lookup_type (expr.get_method_name ().get_mappings ().get_hirid (),
444 &method_type);
445
446 auto fn = *static_cast<TyTy::FnType *> (method_type);
447 auto method = mappings.lookup_hir_implitem (fn.get_ref (), nullptr);
448
449 if (!unsafe_context.is_in_context () && method)
450 check_unsafe_call (static_cast<Function *> (method), expr.get_locus (),
451 "method");
452
453 expr.get_receiver ()->accept_vis (*this);
454
455 for (auto &arg : expr.get_arguments ())
456 arg->accept_vis (*this);
457}
458
459void
460UnsafeChecker::visit (FieldAccessExpr &expr)
461{
462 expr.get_receiver_expr ()->accept_vis (*this);
463
464 if (unsafe_context.is_in_context ())
465 return;
466
467 TyTy::BaseType *receiver_ty;
468 auto ok = context.lookup_type (
469 expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver_ty);
470 rust_assert (ok);
471
472 if (receiver_ty->get_kind () == TyTy::TypeKind::ADT)
473 {
474 auto maybe_union = static_cast<TyTy::ADTType *> (receiver_ty);
475 if (maybe_union->is_union ())
476 rust_error_at (
477 expr.get_locus (),
478 "access to union field requires unsafe function or block");
479 }
480}
481
482void
870dd9d5 483UnsafeChecker::visit (ClosureExpr &expr)
89824094
PH
484{
485 expr.get_expr ()->accept_vis (*this);
486}
b1b35204
AC
487
488void
489UnsafeChecker::visit (BlockExpr &expr)
490{
491 for (auto &stmt : expr.get_statements ())
492 stmt->accept_vis (*this);
493
494 if (expr.has_expr ())
495 expr.get_final_expr ()->accept_vis (*this);
496}
497
b1b35204 498void
9f455ed8 499UnsafeChecker::visit (ContinueExpr &)
b1b35204
AC
500{}
501
502void
503UnsafeChecker::visit (BreakExpr &expr)
504{
505 if (expr.has_break_expr ())
506 expr.get_expr ()->accept_vis (*this);
507}
508
509void
510UnsafeChecker::visit (RangeFromToExpr &expr)
511{
512 expr.get_from_expr ()->accept_vis (*this);
513 expr.get_to_expr ()->accept_vis (*this);
514}
515
516void
517UnsafeChecker::visit (RangeFromExpr &expr)
518{
519 expr.get_from_expr ()->accept_vis (*this);
520}
521
522void
523UnsafeChecker::visit (RangeToExpr &expr)
524{
525 expr.get_to_expr ()->accept_vis (*this);
526}
527
528void
9f455ed8 529UnsafeChecker::visit (RangeFullExpr &)
b1b35204
AC
530{}
531
532void
533UnsafeChecker::visit (RangeFromToInclExpr &expr)
534{
535 expr.get_from_expr ()->accept_vis (*this);
536 expr.get_to_expr ()->accept_vis (*this);
537}
538
539void
540UnsafeChecker::visit (RangeToInclExpr &expr)
541{
542 expr.get_to_expr ()->accept_vis (*this);
543}
544
545void
546UnsafeChecker::visit (ReturnExpr &expr)
547{
548 if (expr.has_return_expr ())
549 expr.get_expr ()->accept_vis (*this);
550}
551
552void
553UnsafeChecker::visit (UnsafeBlockExpr &expr)
554{
555 unsafe_context.enter (expr.get_mappings ().get_hirid ());
556
557 expr.get_block_expr ()->accept_vis (*this);
558
559 unsafe_context.exit ();
560}
561
562void
563UnsafeChecker::visit (LoopExpr &expr)
564{
565 expr.get_loop_block ()->accept_vis (*this);
566}
567
568void
569UnsafeChecker::visit (WhileLoopExpr &expr)
570{
571 expr.get_predicate_expr ()->accept_vis (*this);
572 expr.get_loop_block ()->accept_vis (*this);
573}
574
575void
576UnsafeChecker::visit (WhileLetLoopExpr &expr)
577{
578 expr.get_cond ()->accept_vis (*this);
579 expr.get_loop_block ()->accept_vis (*this);
580}
581
582void
583UnsafeChecker::visit (ForLoopExpr &expr)
584{
585 expr.get_iterator_expr ()->accept_vis (*this);
586 expr.get_loop_block ()->accept_vis (*this);
587}
588
589void
590UnsafeChecker::visit (IfExpr &expr)
591{
592 expr.get_if_condition ()->accept_vis (*this);
593 expr.get_if_block ()->accept_vis (*this);
594}
595
596void
597UnsafeChecker::visit (IfExprConseqElse &expr)
598{
599 expr.get_if_condition ()->accept_vis (*this);
600 expr.get_if_block ()->accept_vis (*this);
601 expr.get_else_block ()->accept_vis (*this);
602}
603
604void
605UnsafeChecker::visit (IfExprConseqIf &expr)
606{
607 expr.get_if_condition ()->accept_vis (*this);
608 expr.get_if_block ()->accept_vis (*this);
609 expr.get_conseq_if_expr ()->accept_vis (*this);
610}
611
612void
613UnsafeChecker::visit (IfExprConseqIfLet &expr)
614{
615 expr.get_if_condition ()->accept_vis (*this);
616 expr.get_if_block ()->accept_vis (*this);
617
618 // TODO: Visit conseq if let expression
619}
620
621void
622UnsafeChecker::visit (IfLetExpr &expr)
623{
624 expr.get_scrutinee_expr ()->accept_vis (*this);
625 expr.get_if_block ()->accept_vis (*this);
626}
627
628void
629UnsafeChecker::visit (IfLetExprConseqElse &expr)
630{
631 expr.get_scrutinee_expr ()->accept_vis (*this);
632 expr.get_if_block ()->accept_vis (*this);
633
634 // TODO: Visit else expression
635}
636
637void
638UnsafeChecker::visit (IfLetExprConseqIf &expr)
639{
640 expr.get_scrutinee_expr ()->accept_vis (*this);
641 expr.get_if_block ()->accept_vis (*this);
642}
643
644void
645UnsafeChecker::visit (IfLetExprConseqIfLet &expr)
646{
647 expr.get_scrutinee_expr ()->accept_vis (*this);
648 expr.get_if_block ()->accept_vis (*this);
649
650 // TODO: Visit conseq if let expression
651}
652
653void
654UnsafeChecker::visit (MatchExpr &expr)
655{
656 expr.get_scrutinee_expr ()->accept_vis (*this);
657
658 for (auto &match_arm : expr.get_match_cases ())
659 match_arm.get_expr ()->accept_vis (*this);
660}
661
662void
9f455ed8 663UnsafeChecker::visit (AwaitExpr &)
b1b35204
AC
664{
665 // TODO: Visit expression
666}
667
668void
9f455ed8 669UnsafeChecker::visit (AsyncBlockExpr &)
b1b35204
AC
670{
671 // TODO: Visit block expression
672}
673
674void
9f455ed8 675UnsafeChecker::visit (TypeParam &)
b1b35204
AC
676{}
677
678void
9f455ed8 679UnsafeChecker::visit (ConstGenericParam &)
b1b35204
AC
680{}
681
682void
9f455ed8 683UnsafeChecker::visit (LifetimeWhereClauseItem &)
b1b35204
AC
684{}
685
686void
9f455ed8 687UnsafeChecker::visit (TypeBoundWhereClauseItem &)
b1b35204
AC
688{}
689
690void
691UnsafeChecker::visit (Module &module)
692{
693 for (auto &item : module.get_items ())
694 item->accept_vis (*this);
695}
696
697void
9f455ed8 698UnsafeChecker::visit (ExternCrate &)
b1b35204
AC
699{}
700
701void
9f455ed8 702UnsafeChecker::visit (UseTreeGlob &)
b1b35204
AC
703{}
704
705void
9f455ed8 706UnsafeChecker::visit (UseTreeList &)
b1b35204
AC
707{}
708
709void
9f455ed8 710UnsafeChecker::visit (UseTreeRebind &)
b1b35204
AC
711{}
712
713void
9f455ed8 714UnsafeChecker::visit (UseDeclaration &)
b1b35204
AC
715{}
716
717void
718UnsafeChecker::visit (Function &function)
719{
720 auto is_unsafe_fn = function.get_qualifiers ().is_unsafe ();
721
722 if (is_unsafe_fn)
723 unsafe_context.enter (function.get_mappings ().get_hirid ());
724
725 function.get_definition ()->accept_vis (*this);
726
727 if (is_unsafe_fn)
728 unsafe_context.exit ();
729}
730
731void
9f455ed8 732UnsafeChecker::visit (TypeAlias &)
b1b35204
AC
733{
734 // FIXME: What do we need to do to handle type aliasing? Is it possible to
735 // have unsafe types? Type aliases on unsafe functions?
736}
737
738void
9f455ed8 739UnsafeChecker::visit (StructStruct &)
b1b35204
AC
740{}
741
742void
9f455ed8 743UnsafeChecker::visit (TupleStruct &)
b1b35204
AC
744{}
745
746void
9f455ed8 747UnsafeChecker::visit (EnumItem &)
b1b35204
AC
748{}
749
750void
9f455ed8 751UnsafeChecker::visit (EnumItemTuple &)
b1b35204
AC
752{}
753
754void
9f455ed8 755UnsafeChecker::visit (EnumItemStruct &)
b1b35204
AC
756{}
757
758void
9f455ed8 759UnsafeChecker::visit (EnumItemDiscriminant &)
b1b35204
AC
760{}
761
762void
9f455ed8 763UnsafeChecker::visit (Enum &)
b1b35204
AC
764{}
765
766void
9f455ed8 767UnsafeChecker::visit (Union &)
b1b35204
AC
768{}
769
770void
771UnsafeChecker::visit (ConstantItem &const_item)
772{
773 const_item.get_expr ()->accept_vis (*this);
774}
775
776void
777UnsafeChecker::visit (StaticItem &static_item)
778{
779 static_item.get_expr ()->accept_vis (*this);
780}
781
782void
783UnsafeChecker::visit (TraitItemFunc &item)
784{
785 if (item.has_block_defined ())
786 item.get_block_expr ()->accept_vis (*this);
787}
788
789void
790UnsafeChecker::visit (TraitItemConst &item)
791{
792 if (item.has_expr ())
793 item.get_expr ()->accept_vis (*this);
794}
795
796void
9f455ed8 797UnsafeChecker::visit (TraitItemType &)
b1b35204
AC
798{}
799
800void
801UnsafeChecker::visit (Trait &trait)
802{
803 // FIXME: Handle unsafe traits
804 for (auto &item : trait.get_trait_items ())
805 item->accept_vis (*this);
806}
807
808void
809UnsafeChecker::visit (ImplBlock &impl)
810{
811 // FIXME: Handle unsafe impls
812 for (auto &item : impl.get_impl_items ())
813 item->accept_vis (*this);
814}
815
816void
9f455ed8 817UnsafeChecker::visit (ExternalStaticItem &)
b1b35204
AC
818{}
819
820void
9f455ed8 821UnsafeChecker::visit (ExternalFunctionItem &)
b1b35204
AC
822{}
823
824void
825UnsafeChecker::visit (ExternBlock &block)
826{
827 // FIXME: Do we need to do this?
828 for (auto &item : block.get_extern_items ())
829 item->accept_vis (*this);
830}
831
832void
9f455ed8 833UnsafeChecker::visit (LiteralPattern &)
b1b35204
AC
834{}
835
836void
9f455ed8 837UnsafeChecker::visit (IdentifierPattern &)
b1b35204
AC
838{}
839
840void
9f455ed8 841UnsafeChecker::visit (WildcardPattern &)
b1b35204
AC
842{}
843
844void
9f455ed8 845UnsafeChecker::visit (RangePatternBoundLiteral &)
b1b35204
AC
846{}
847
848void
9f455ed8 849UnsafeChecker::visit (RangePatternBoundPath &)
b1b35204
AC
850{}
851
852void
9f455ed8 853UnsafeChecker::visit (RangePatternBoundQualPath &)
b1b35204
AC
854{}
855
856void
9f455ed8 857UnsafeChecker::visit (RangePattern &)
b1b35204
AC
858{}
859
860void
9f455ed8 861UnsafeChecker::visit (ReferencePattern &)
b1b35204
AC
862{}
863
864void
9f455ed8 865UnsafeChecker::visit (StructPatternFieldTuplePat &)
b1b35204
AC
866{}
867
868void
9f455ed8 869UnsafeChecker::visit (StructPatternFieldIdentPat &)
b1b35204
AC
870{}
871
872void
9f455ed8 873UnsafeChecker::visit (StructPatternFieldIdent &)
b1b35204
AC
874{}
875
876void
9f455ed8 877UnsafeChecker::visit (StructPattern &)
b1b35204
AC
878{}
879
880void
9f455ed8 881UnsafeChecker::visit (TupleStructItemsNoRange &)
b1b35204
AC
882{}
883
884void
9f455ed8 885UnsafeChecker::visit (TupleStructItemsRange &)
b1b35204
AC
886{}
887
888void
9f455ed8 889UnsafeChecker::visit (TupleStructPattern &)
b1b35204
AC
890{}
891
892void
9f455ed8 893UnsafeChecker::visit (TuplePatternItemsMultiple &)
b1b35204
AC
894{}
895
896void
9f455ed8 897UnsafeChecker::visit (TuplePatternItemsRanged &)
b1b35204
AC
898{}
899
900void
9f455ed8 901UnsafeChecker::visit (TuplePattern &)
b1b35204
AC
902{}
903
b1b35204 904void
9f455ed8 905UnsafeChecker::visit (SlicePattern &)
b1b35204
AC
906{}
907
908void
9f455ed8 909UnsafeChecker::visit (EmptyStmt &)
b1b35204
AC
910{}
911
912void
913UnsafeChecker::visit (LetStmt &stmt)
914{
915 if (stmt.has_init_expr ())
916 stmt.get_init_expr ()->accept_vis (*this);
917}
918
919void
920UnsafeChecker::visit (ExprStmtWithoutBlock &stmt)
921{
922 stmt.get_expr ()->accept_vis (*this);
923}
924
925void
926UnsafeChecker::visit (ExprStmtWithBlock &stmt)
927{
928 stmt.get_expr ()->accept_vis (*this);
929}
930
931void
9f455ed8 932UnsafeChecker::visit (TraitBound &)
b1b35204
AC
933{}
934
935void
9f455ed8 936UnsafeChecker::visit (ImplTraitType &)
b1b35204
AC
937{}
938
939void
9f455ed8 940UnsafeChecker::visit (TraitObjectType &)
b1b35204
AC
941{}
942
943void
9f455ed8 944UnsafeChecker::visit (ParenthesisedType &)
b1b35204
AC
945{}
946
947void
9f455ed8 948UnsafeChecker::visit (ImplTraitTypeOneBound &)
b1b35204
AC
949{}
950
951void
9f455ed8 952UnsafeChecker::visit (TupleType &)
b1b35204
AC
953{}
954
955void
9f455ed8 956UnsafeChecker::visit (NeverType &)
b1b35204
AC
957{}
958
959void
9f455ed8 960UnsafeChecker::visit (RawPointerType &)
b1b35204
AC
961{}
962
963void
9f455ed8 964UnsafeChecker::visit (ReferenceType &)
b1b35204
AC
965{}
966
967void
9f455ed8 968UnsafeChecker::visit (ArrayType &)
b1b35204
AC
969{}
970
971void
9f455ed8 972UnsafeChecker::visit (SliceType &)
b1b35204
AC
973{}
974
975void
9f455ed8 976UnsafeChecker::visit (InferredType &)
b1b35204
AC
977{}
978
979void
9f455ed8 980UnsafeChecker::visit (BareFunctionType &)
b1b35204
AC
981{}
982
983} // namespace HIR
984} // namespace Rust