LCOV - code coverage report
Current view: top level - gcc/rust/expand - rust-derive-eq.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 65.7 % 105 69
Test Date: 2025-06-21 16:26:05 Functions: 70.0 % 10 7
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 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-derive-eq.h"
      20                 :             : #include "rust-ast.h"
      21                 :             : #include "rust-expr.h"
      22                 :             : #include "rust-item.h"
      23                 :             : #include "rust-path.h"
      24                 :             : #include "rust-pattern.h"
      25                 :             : #include "rust-system.h"
      26                 :             : 
      27                 :             : namespace Rust {
      28                 :             : namespace AST {
      29                 :             : 
      30                 :           2 : DeriveEq::DeriveEq (location_t loc) : DeriveVisitor (loc) {}
      31                 :             : 
      32                 :             : std::vector<std::unique_ptr<AST::Item>>
      33                 :           2 : DeriveEq::go (Item &item)
      34                 :             : {
      35                 :           2 :   item.accept_vis (*this);
      36                 :             : 
      37                 :           2 :   return std::move (expanded);
      38                 :             : }
      39                 :             : 
      40                 :             : std::unique_ptr<AssociatedItem>
      41                 :           2 : DeriveEq::assert_receiver_is_total_eq_fn (
      42                 :             :   std::vector<std::unique_ptr<Type>> &&types)
      43                 :             : {
      44                 :           2 :   auto stmts = std::vector<std::unique_ptr<Stmt>> ();
      45                 :             : 
      46                 :           2 :   stmts.emplace_back (assert_param_is_eq ());
      47                 :             : 
      48                 :           4 :   for (auto &&type : types)
      49                 :           2 :     stmts.emplace_back (assert_type_is_eq (std::move (type)));
      50                 :             : 
      51                 :           2 :   auto block = std::unique_ptr<BlockExpr> (
      52                 :           2 :     new BlockExpr (std::move (stmts), nullptr, {}, {}, tl::nullopt, loc, loc));
      53                 :             : 
      54                 :           2 :   auto self = builder.self_ref_param ();
      55                 :             : 
      56                 :           6 :   return builder.function ("assert_receiver_is_total_eq",
      57                 :           6 :                            vec (std::move (self)), {}, std::move (block));
      58                 :           2 : }
      59                 :             : 
      60                 :             : std::unique_ptr<Stmt>
      61                 :           2 : DeriveEq::assert_param_is_eq ()
      62                 :             : {
      63                 :           2 :   auto eq_bound = std::unique_ptr<TypeParamBound> (
      64                 :           2 :     new TraitBound (builder.type_path ({"core", "cmp", "Eq"}, true), loc));
      65                 :             : 
      66                 :           2 :   auto sized_bound = std::unique_ptr<TypeParamBound> (
      67                 :           2 :     new TraitBound (builder.type_path (LangItem::Kind::SIZED), loc, false,
      68                 :           2 :                     true /* opening_question_mark */));
      69                 :             : 
      70                 :           2 :   auto bounds = vec (std::move (eq_bound), std::move (sized_bound));
      71                 :             : 
      72                 :           2 :   auto assert_param_is_eq = "AssertParamIsEq";
      73                 :             : 
      74                 :           2 :   auto t = std::unique_ptr<GenericParam> (
      75                 :           4 :     new TypeParam (Identifier ("T"), loc, std::move (bounds)));
      76                 :             : 
      77                 :           6 :   return builder.struct_struct (
      78                 :           4 :     assert_param_is_eq, vec (std::move (t)),
      79                 :             :     {StructField (
      80                 :           6 :       Identifier ("_t"),
      81                 :           4 :       builder.single_generic_type_path (
      82                 :             :         LangItem::Kind::PHANTOM_DATA,
      83                 :           2 :         GenericArgs (
      84                 :           6 :           {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
      85                 :           6 :       Visibility::create_private (), loc)});
      86                 :           2 : }
      87                 :             : 
      88                 :             : std::unique_ptr<Stmt>
      89                 :           2 : DeriveEq::assert_type_is_eq (std::unique_ptr<Type> &&type)
      90                 :             : {
      91                 :           2 :   auto assert_param_is_eq = "AssertParamIsEq";
      92                 :             : 
      93                 :             :   // AssertParamIsCopy::<Self>
      94                 :           2 :   auto assert_param_is_eq_ty
      95                 :             :     = std::unique_ptr<TypePathSegment> (new TypePathSegmentGeneric (
      96                 :           4 :       PathIdentSegment (assert_param_is_eq, loc), false,
      97                 :           6 :       GenericArgs ({}, {GenericArg::create_type (std::move (type))}, {}, loc),
      98                 :           4 :       loc));
      99                 :             : 
     100                 :             :   // TODO: Improve this, it's really ugly
     101                 :           2 :   auto type_paths = std::vector<std::unique_ptr<TypePathSegment>> ();
     102                 :           2 :   type_paths.emplace_back (std::move (assert_param_is_eq_ty));
     103                 :             : 
     104                 :           2 :   auto full_path
     105                 :           2 :     = std::unique_ptr<Type> (new TypePath ({std::move (type_paths)}, loc));
     106                 :             : 
     107                 :           2 :   return builder.let (builder.wildcard (), std::move (full_path));
     108                 :           2 : }
     109                 :             : 
     110                 :             : std::vector<std::unique_ptr<Item>>
     111                 :           2 : DeriveEq::eq_impls (
     112                 :             :   std::unique_ptr<AssociatedItem> &&fn, std::string name,
     113                 :             :   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
     114                 :             : {
     115                 :             :   // We create two copies of the type-path to avoid duplicate NodeIds
     116                 :           2 :   auto eq = builder.type_path ({"core", "cmp", "Eq"}, true);
     117                 :           2 :   auto eq_bound
     118                 :           2 :     = builder.trait_bound (builder.type_path ({"core", "cmp", "Eq"}, true));
     119                 :             : 
     120                 :           2 :   auto steq = builder.type_path (LangItem::Kind::STRUCTURAL_TEQ);
     121                 :             : 
     122                 :           2 :   auto trait_items = vec (std::move (fn));
     123                 :             : 
     124                 :           2 :   auto eq_generics
     125                 :           2 :     = setup_impl_generics (name, type_generics, std::move (eq_bound));
     126                 :           2 :   auto steq_generics = setup_impl_generics (name, type_generics);
     127                 :             : 
     128                 :           4 :   auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
     129                 :             :                                      std::move (trait_items),
     130                 :           2 :                                      std::move (eq_generics.impl));
     131                 :           2 :   auto steq_impl
     132                 :           4 :     = builder.trait_impl (steq, std::move (steq_generics.self_type),
     133                 :             :                           std::move (trait_items),
     134                 :           2 :                           std::move (steq_generics.impl));
     135                 :             : 
     136                 :           2 :   return vec (std::move (eq_impl), std::move (steq_impl));
     137                 :           6 : }
     138                 :             : 
     139                 :             : void
     140                 :           2 : DeriveEq::visit_tuple (TupleStruct &item)
     141                 :             : {
     142                 :           2 :   auto types = std::vector<std::unique_ptr<Type>> ();
     143                 :             : 
     144                 :           4 :   for (auto &field : item.get_fields ())
     145                 :           2 :     types.emplace_back (field.get_field_type ().clone_type ());
     146                 :             : 
     147                 :           4 :   expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
     148                 :           2 :                        item.get_identifier ().as_string (),
     149                 :           4 :                        item.get_generic_params ());
     150                 :           2 : }
     151                 :             : 
     152                 :             : void
     153                 :           0 : DeriveEq::visit_struct (StructStruct &item)
     154                 :             : {
     155                 :           0 :   auto types = std::vector<std::unique_ptr<Type>> ();
     156                 :             : 
     157                 :           0 :   for (auto &field : item.get_fields ())
     158                 :           0 :     types.emplace_back (field.get_field_type ().clone_type ());
     159                 :             : 
     160                 :           0 :   expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
     161                 :           0 :                        item.get_identifier ().as_string (),
     162                 :           0 :                        item.get_generic_params ());
     163                 :           0 : }
     164                 :             : 
     165                 :             : void
     166                 :           0 : DeriveEq::visit_enum (Enum &item)
     167                 :             : {
     168                 :           0 :   auto types = std::vector<std::unique_ptr<Type>> ();
     169                 :             : 
     170                 :           0 :   for (auto &variant : item.get_variants ())
     171                 :             :     {
     172                 :           0 :       switch (variant->get_enum_item_kind ())
     173                 :             :         {
     174                 :           0 :         case EnumItem::Kind::Identifier:
     175                 :           0 :         case EnumItem::Kind::Discriminant:
     176                 :             :           // nothing to do as they contain no inner types
     177                 :           0 :           continue;
     178                 :           0 :           case EnumItem::Kind::Tuple: {
     179                 :           0 :             auto &tuple = static_cast<EnumItemTuple &> (*variant);
     180                 :             : 
     181                 :           0 :             for (auto &field : tuple.get_tuple_fields ())
     182                 :           0 :               types.emplace_back (field.get_field_type ().clone_type ());
     183                 :             : 
     184                 :             :             break;
     185                 :             :           }
     186                 :           0 :           case EnumItem::Kind::Struct: {
     187                 :           0 :             auto &tuple = static_cast<EnumItemStruct &> (*variant);
     188                 :             : 
     189                 :           0 :             for (auto &field : tuple.get_struct_fields ())
     190                 :           0 :               types.emplace_back (field.get_field_type ().clone_type ());
     191                 :             : 
     192                 :             :             break;
     193                 :             :           }
     194                 :           0 :         }
     195                 :             :     }
     196                 :             : 
     197                 :           0 :   expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
     198                 :           0 :                        item.get_identifier ().as_string (),
     199                 :           0 :                        item.get_generic_params ());
     200                 :           0 : }
     201                 :             : 
     202                 :             : void
     203                 :           0 : DeriveEq::visit_union (Union &item)
     204                 :             : {
     205                 :           0 :   auto types = std::vector<std::unique_ptr<Type>> ();
     206                 :             : 
     207                 :           0 :   for (auto &field : item.get_variants ())
     208                 :           0 :     types.emplace_back (field.get_field_type ().clone_type ());
     209                 :             : 
     210                 :           0 :   expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
     211                 :           0 :                        item.get_identifier ().as_string (),
     212                 :           0 :                        item.get_generic_params ());
     213                 :           0 : }
     214                 :             : 
     215                 :             : } // namespace AST
     216                 :             : } // 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.