LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-enumitem.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.9 % 161 156
Test Date: 2025-06-21 16:26:05 Functions: 100.0 % 6 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             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-hir-expr.h"
      20                 :             : #include "rust-hir-type-check-type.h"
      21                 :             : #include "rust-hir-type-check-expr.h"
      22                 :             : #include "rust-hir-type-check-enumitem.h"
      23                 :             : #include "rust-type-util.h"
      24                 :             : #include "rust-immutable-name-resolution-context.h"
      25                 :             : 
      26                 :             : // for flag_name_resolution_2_0
      27                 :             : #include "options.h"
      28                 :             : 
      29                 :             : namespace Rust {
      30                 :             : namespace Resolver {
      31                 :             : 
      32                 :             : TyTy::VariantDef *
      33                 :         842 : TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
      34                 :             : {
      35                 :         842 :   TypeCheckEnumItem resolver (last_discriminant);
      36                 :         842 :   switch (item.get_enum_item_kind ())
      37                 :             :     {
      38                 :         384 :     case HIR::EnumItem::EnumItemKind::Named:
      39                 :         384 :       resolver.visit (static_cast<HIR::EnumItem &> (item));
      40                 :         384 :       break;
      41                 :             : 
      42                 :         370 :     case HIR::EnumItem::EnumItemKind::Tuple:
      43                 :         370 :       resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
      44                 :         370 :       break;
      45                 :             : 
      46                 :          68 :     case HIR::EnumItem::EnumItemKind::Struct:
      47                 :          68 :       resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
      48                 :          68 :       break;
      49                 :             : 
      50                 :          20 :     case HIR::EnumItem::EnumItemKind::Discriminant:
      51                 :          20 :       resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
      52                 :          20 :       break;
      53                 :             :     }
      54                 :         842 :   return resolver.variant;
      55                 :         842 : }
      56                 :             : 
      57                 :         842 : TypeCheckEnumItem::TypeCheckEnumItem (int64_t last_discriminant)
      58                 :         842 :   : TypeCheckBase (), variant (nullptr), last_discriminant (last_discriminant)
      59                 :         842 : {}
      60                 :             : 
      61                 :             : void
      62                 :         384 : TypeCheckEnumItem::visit (HIR::EnumItem &item)
      63                 :             : {
      64                 :         384 :   if (last_discriminant == INT64_MAX)
      65                 :           0 :     rust_error_at (item.get_locus (), "discriminant too big");
      66                 :             : 
      67                 :         768 :   Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
      68                 :         384 :                                  item.get_mappings ().get_nodeid (),
      69                 :         384 :                                  mappings.get_next_hir_id (
      70                 :         384 :                                    item.get_mappings ().get_crate_num ()),
      71                 :         384 :                                  item.get_mappings ().get_local_defid ());
      72                 :         384 :   auto discim_expr = std::make_unique<HIR::LiteralExpr> (
      73                 :         768 :     HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
      74                 :             :                       HIR::Literal::LitType::INT,
      75                 :        1152 :                       PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
      76                 :             : 
      77                 :         384 :   TyTy::BaseType *isize = nullptr;
      78                 :         384 :   bool ok = context->lookup_builtin ("isize", &isize);
      79                 :         384 :   rust_assert (ok);
      80                 :         384 :   context->insert_type (mapping, isize);
      81                 :             : 
      82                 :         384 :   tl::optional<CanonicalPath> canonical_path;
      83                 :             : 
      84                 :         384 :   if (flag_name_resolution_2_0)
      85                 :             :     {
      86                 :          68 :       auto &nr_ctx
      87                 :          68 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
      88                 :             : 
      89                 :          68 :       canonical_path
      90                 :         136 :         = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
      91                 :             :     }
      92                 :             :   else
      93                 :             :     {
      94                 :         316 :       canonical_path
      95                 :         316 :         = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
      96                 :             :     }
      97                 :             : 
      98                 :         384 :   rust_assert (canonical_path.has_value ());
      99                 :             : 
     100                 :         384 :   RustIdent ident{*canonical_path, item.get_locus ()};
     101                 :         384 :   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
     102                 :         384 :                                   item.get_mappings ().get_defid (),
     103                 :         384 :                                   item.get_identifier ().as_string (), ident,
     104                 :        1536 :                                   std::move (discim_expr));
     105                 :         768 : }
     106                 :             : 
     107                 :             : void
     108                 :          20 : TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
     109                 :             : {
     110                 :          20 :   if (last_discriminant == INT64_MAX)
     111                 :           0 :     rust_error_at (item.get_locus (), "discriminant too big");
     112                 :             : 
     113                 :          20 :   auto &discriminant = item.get_discriminant_expression ();
     114                 :          20 :   auto capacity_type = TypeCheckExpr::Resolve (discriminant);
     115                 :          20 :   if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
     116                 :           0 :     return;
     117                 :             : 
     118                 :          20 :   TyTy::ISizeType *expected_ty
     119                 :          20 :     = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
     120                 :          20 :   context->insert_type (discriminant.get_mappings (), expected_ty);
     121                 :             : 
     122                 :          20 :   unify_site (item.get_mappings ().get_hirid (),
     123                 :          20 :               TyTy::TyWithLocation (expected_ty),
     124                 :          20 :               TyTy::TyWithLocation (capacity_type), item.get_locus ());
     125                 :             : 
     126                 :          20 :   tl::optional<CanonicalPath> canonical_path;
     127                 :             : 
     128                 :          20 :   if (flag_name_resolution_2_0)
     129                 :             :     {
     130                 :          11 :       auto &nr_ctx
     131                 :          11 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     132                 :             : 
     133                 :          11 :       canonical_path
     134                 :          22 :         = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
     135                 :             :     }
     136                 :             :   else
     137                 :             :     {
     138                 :           9 :       canonical_path
     139                 :           9 :         = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
     140                 :             :     }
     141                 :             : 
     142                 :          20 :   rust_assert (canonical_path.has_value ());
     143                 :             : 
     144                 :          20 :   RustIdent ident{*canonical_path, item.get_locus ()};
     145                 :          20 :   variant
     146                 :          20 :     = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
     147                 :          20 :                             item.get_mappings ().get_defid (),
     148                 :          20 :                             item.get_identifier ().as_string (), ident,
     149                 :          80 :                             item.get_discriminant_expression ().clone_expr ());
     150                 :          40 : }
     151                 :             : 
     152                 :             : void
     153                 :         370 : TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
     154                 :             : {
     155                 :         370 :   if (last_discriminant == INT64_MAX)
     156                 :           0 :     rust_error_at (item.get_locus (), "discriminant too big");
     157                 :             : 
     158                 :         370 :   std::vector<TyTy::StructFieldType *> fields;
     159                 :         370 :   size_t idx = 0;
     160                 :         727 :   for (auto &field : item.get_tuple_fields ())
     161                 :             :     {
     162                 :         357 :       TyTy::BaseType *field_type
     163                 :         357 :         = TypeCheckType::Resolve (field.get_field_type ());
     164                 :         357 :       TyTy::StructFieldType *ty_field
     165                 :         714 :         = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
     166                 :         357 :                                      std::to_string (idx), field_type,
     167                 :         357 :                                      field.get_locus ());
     168                 :         357 :       fields.push_back (ty_field);
     169                 :         357 :       context->insert_type (field.get_mappings (), ty_field->get_field_type ());
     170                 :         357 :       idx++;
     171                 :             :     }
     172                 :             : 
     173                 :         740 :   Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
     174                 :         370 :                                  item.get_mappings ().get_nodeid (),
     175                 :         370 :                                  mappings.get_next_hir_id (
     176                 :         370 :                                    item.get_mappings ().get_crate_num ()),
     177                 :         370 :                                  item.get_mappings ().get_local_defid ());
     178                 :         370 :   auto discim_expr = std::make_unique<HIR::LiteralExpr> (
     179                 :         740 :     HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
     180                 :             :                       HIR::Literal::LitType::INT,
     181                 :        1110 :                       PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
     182                 :             : 
     183                 :         370 :   TyTy::BaseType *isize = nullptr;
     184                 :         370 :   bool ok = context->lookup_builtin ("isize", &isize);
     185                 :         370 :   rust_assert (ok);
     186                 :         370 :   context->insert_type (mapping, isize);
     187                 :             : 
     188                 :         370 :   tl::optional<CanonicalPath> canonical_path;
     189                 :             : 
     190                 :         370 :   if (flag_name_resolution_2_0)
     191                 :             :     {
     192                 :          81 :       auto &nr_ctx
     193                 :          81 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     194                 :             : 
     195                 :          81 :       canonical_path
     196                 :         162 :         = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
     197                 :             :     }
     198                 :             :   else
     199                 :             :     {
     200                 :         289 :       canonical_path
     201                 :         289 :         = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
     202                 :             :     }
     203                 :             : 
     204                 :         370 :   rust_assert (canonical_path.has_value ());
     205                 :             : 
     206                 :         370 :   RustIdent ident{*canonical_path, item.get_locus ()};
     207                 :         370 :   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
     208                 :         370 :                                   item.get_mappings ().get_defid (),
     209                 :         370 :                                   item.get_identifier ().as_string (), ident,
     210                 :             :                                   TyTy::VariantDef::VariantType::TUPLE,
     211                 :        1480 :                                   std::move (discim_expr), fields);
     212                 :         740 : }
     213                 :             : 
     214                 :             : void
     215                 :          68 : TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
     216                 :             : {
     217                 :          68 :   if (last_discriminant == INT64_MAX)
     218                 :           0 :     rust_error_at (item.get_locus (), "discriminant too big");
     219                 :             : 
     220                 :          68 :   std::vector<TyTy::StructFieldType *> fields;
     221                 :         187 :   for (auto &field : item.get_struct_fields ())
     222                 :             :     {
     223                 :         119 :       TyTy::BaseType *field_type
     224                 :         119 :         = TypeCheckType::Resolve (field.get_field_type ());
     225                 :         119 :       TyTy::StructFieldType *ty_field
     226                 :         119 :         = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
     227                 :         119 :                                      field.get_field_name ().as_string (),
     228                 :         238 :                                      field_type, field.get_locus ());
     229                 :         119 :       fields.push_back (ty_field);
     230                 :         119 :       context->insert_type (field.get_mappings (), ty_field->get_field_type ());
     231                 :             :     }
     232                 :             : 
     233                 :         136 :   Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
     234                 :          68 :                                  item.get_mappings ().get_nodeid (),
     235                 :          68 :                                  mappings.get_next_hir_id (
     236                 :          68 :                                    item.get_mappings ().get_crate_num ()),
     237                 :          68 :                                  item.get_mappings ().get_local_defid ());
     238                 :          68 :   auto discrim_expr = std::make_unique<HIR::LiteralExpr> (
     239                 :         136 :     HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
     240                 :             :                       HIR::Literal::LitType::INT,
     241                 :         204 :                       PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
     242                 :             : 
     243                 :          68 :   TyTy::BaseType *isize = nullptr;
     244                 :          68 :   bool ok = context->lookup_builtin ("isize", &isize);
     245                 :          68 :   rust_assert (ok);
     246                 :          68 :   context->insert_type (mapping, isize);
     247                 :             : 
     248                 :          68 :   tl::optional<CanonicalPath> canonical_path;
     249                 :             : 
     250                 :          68 :   if (flag_name_resolution_2_0)
     251                 :             :     {
     252                 :          14 :       auto &nr_ctx
     253                 :          14 :         = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     254                 :             : 
     255                 :          14 :       canonical_path
     256                 :          28 :         = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
     257                 :             :     }
     258                 :             :   else
     259                 :             :     {
     260                 :          54 :       canonical_path
     261                 :          54 :         = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
     262                 :             :     }
     263                 :             : 
     264                 :          68 :   rust_assert (canonical_path.has_value ());
     265                 :             : 
     266                 :          68 :   RustIdent ident{*canonical_path, item.get_locus ()};
     267                 :          68 :   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
     268                 :          68 :                                   item.get_mappings ().get_defid (),
     269                 :          68 :                                   item.get_identifier ().as_string (), ident,
     270                 :             :                                   TyTy::VariantDef::VariantType::STRUCT,
     271                 :         272 :                                   std::move (discrim_expr), fields);
     272                 :         136 : }
     273                 :             : 
     274                 :             : } // namespace Resolver
     275                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-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.