LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors - rust-const-checker.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 73.2 % 448 328
Test Date: 2026-09-19 16:22:48 Functions: 63.5 % 137 87
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.