LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-trait-reference.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.7 % 210 182
Test Date: 2026-02-28 14:20:25 Functions: 88.9 % 45 40
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-hir-trait-reference.h"
      20              : 
      21              : namespace Rust {
      22              : namespace Resolver {
      23              : 
      24              : std::string
      25         5930 : TraitItemReference::as_string () const
      26              : {
      27        23720 :   return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
      28              : }
      29              : 
      30              : bool
      31       165354 : TraitItemReference::is_error () const
      32              : {
      33       165354 :   return type == ERROR;
      34              : }
      35              : 
      36              : bool
      37         6345 : TraitItemReference::is_optional () const
      38              : {
      39         6345 :   return optional_flag;
      40              : }
      41              : 
      42              : std::string
      43       265685 : TraitItemReference::get_identifier () const
      44              : {
      45       265685 :   return identifier;
      46              : }
      47              : 
      48              : TraitItemReference::TraitItemType
      49       286111 : TraitItemReference::get_trait_item_type () const
      50              : {
      51       286111 :   return type;
      52              : }
      53              : 
      54              : HIR::TraitItem *
      55        22754 : TraitItemReference::get_hir_trait_item () const
      56              : {
      57        22754 :   return hir_trait_item;
      58              : }
      59              : 
      60              : location_t
      61         1953 : TraitItemReference::get_locus () const
      62              : {
      63         1953 :   return locus;
      64              : }
      65              : 
      66              : const Analysis::NodeMapping
      67        26044 : TraitItemReference::get_mappings () const
      68              : {
      69        26044 :   return hir_trait_item->get_mappings ();
      70              : }
      71              : 
      72              : TyTy::BaseType *
      73        46019 : TraitItemReference::get_tyty () const
      74              : {
      75        46019 :   rust_assert (hir_trait_item != nullptr);
      76              : 
      77        46019 :   switch (type)
      78              :     {
      79           31 :     case CONST:
      80           31 :       return get_type_from_constant (
      81           31 :         static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
      82        21251 :       break;
      83              : 
      84        21251 :     case TYPE:
      85        21251 :       return get_type_from_typealias (
      86        21251 :         static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
      87              : 
      88        24737 :     case FN:
      89        24737 :       return get_type_from_fn (
      90        24737 :         static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
      91            0 :       break;
      92              : 
      93            0 :     default:
      94            0 :       return get_error ();
      95              :     }
      96              : 
      97              :   rust_unreachable ();
      98              :   return get_error ();
      99              : }
     100              : 
     101              : TyTy::ErrorType *
     102            2 : TraitItemReference::get_error () const
     103              : {
     104            2 :   return new TyTy::ErrorType (get_mappings ().get_hirid ());
     105              : }
     106              : 
     107         5477 : TraitReference::TraitReference (
     108              :   const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
     109              :   std::vector<TyTy::TypeBoundPredicate> super_traits,
     110         5477 :   std::vector<TyTy::SubstitutionParamMapping> substs)
     111         5477 :   : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
     112         5477 :     super_traits (super_traits)
     113              : {
     114         5477 :   trait_substs.clear ();
     115         5477 :   trait_substs.reserve (substs.size ());
     116         9798 :   for (const auto &p : substs)
     117         4321 :     trait_substs.push_back (p.clone ());
     118         5477 : }
     119              : 
     120            0 : TraitReference::TraitReference (TraitReference const &other)
     121            0 :   : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
     122            0 :     super_traits (other.super_traits)
     123              : {
     124            0 :   trait_substs.clear ();
     125            0 :   trait_substs.reserve (other.trait_substs.size ());
     126            0 :   for (const auto &p : other.trait_substs)
     127            0 :     trait_substs.push_back (p.clone ());
     128            0 : }
     129              : 
     130              : TraitReference &
     131            0 : TraitReference::operator= (TraitReference const &other)
     132              : {
     133            0 :   hir_trait_ref = other.hir_trait_ref;
     134            0 :   item_refs = other.item_refs;
     135            0 :   super_traits = other.super_traits;
     136              : 
     137            0 :   trait_substs.clear ();
     138            0 :   trait_substs.reserve (other.trait_substs.size ());
     139            0 :   for (const auto &p : other.trait_substs)
     140            0 :     trait_substs.push_back (p.clone ());
     141              : 
     142            0 :   return *this;
     143              : }
     144              : 
     145              : bool
     146       500839 : TraitReference::is_error () const
     147              : {
     148       500839 :   return hir_trait_ref == nullptr;
     149              : }
     150              : 
     151              : location_t
     152            1 : TraitReference::get_locus () const
     153              : {
     154            1 :   return hir_trait_ref->get_locus ();
     155              : }
     156              : 
     157              : std::string
     158        61429 : TraitReference::get_name () const
     159              : {
     160        61429 :   rust_assert (!is_error ());
     161       122858 :   return hir_trait_ref->get_name ().as_string ();
     162              : }
     163              : 
     164              : std::string
     165         3271 : TraitReference::as_string () const
     166              : {
     167         3271 :   if (is_error ())
     168            0 :     return "<trait-ref-error-node>";
     169              : 
     170         3271 :   std::string item_buf;
     171         9201 :   for (auto &item : item_refs)
     172              :     {
     173        17790 :       item_buf += item.as_string () + ", ";
     174              :     }
     175         6542 :   return "HIR Trait: " + get_name () + "->"
     176        16355 :          + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
     177         3271 : }
     178              : 
     179              : const HIR::Trait *
     180        19640 : TraitReference::get_hir_trait_ref () const
     181              : {
     182        19640 :   return hir_trait_ref;
     183              : }
     184              : 
     185              : const Analysis::NodeMapping &
     186       849547 : TraitReference::get_mappings () const
     187              : {
     188       849547 :   return hir_trait_ref->get_mappings ();
     189              : }
     190              : 
     191              : DefId
     192          165 : TraitReference::get_defid () const
     193              : {
     194          165 :   return get_mappings ().get_defid ();
     195              : }
     196              : 
     197              : bool
     198          241 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     199              :                                        TraitItemReference **ref)
     200              : {
     201          241 :   return lookup_trait_item (item.trait_identifier (), ref);
     202              : }
     203              : 
     204              : bool
     205         1837 : TraitReference::lookup_trait_item (const std::string &ident,
     206              :                                    TraitItemReference **ref)
     207              : {
     208         2204 :   for (auto &item : item_refs)
     209              :     {
     210         2204 :       if (ident.compare (item.get_identifier ()) == 0)
     211              :         {
     212         1837 :           *ref = &item;
     213         1837 :           return true;
     214              :         }
     215              :     }
     216              :   return false;
     217              : }
     218              : 
     219              : bool
     220          100 : TraitReference::lookup_trait_item_by_type (
     221              :   const std::string &ident, TraitItemReference::TraitItemType type,
     222              :   TraitItemReference **ref)
     223              : {
     224          100 :   for (auto &item : item_refs)
     225              :     {
     226          100 :       if (item.get_trait_item_type () != type)
     227            0 :         continue;
     228              : 
     229          100 :       if (ident.compare (item.get_identifier ()) == 0)
     230              :         {
     231          100 :           *ref = &item;
     232          100 :           return true;
     233              :         }
     234              :     }
     235              :   return false;
     236              : }
     237              : 
     238              : bool
     239         5350 : TraitReference::lookup_trait_item_by_type (
     240              :   const std::string &ident, TraitItemReference::TraitItemType type,
     241              :   const TraitItemReference **ref) const
     242              : {
     243         8544 :   for (auto &item : item_refs)
     244              :     {
     245         8541 :       if (item.get_trait_item_type () != type)
     246         1267 :         continue;
     247              : 
     248         7274 :       if (ident.compare (item.get_identifier ()) == 0)
     249              :         {
     250         5347 :           *ref = &item;
     251         5347 :           return true;
     252              :         }
     253              :     }
     254              :   return false;
     255              : }
     256              : 
     257              : bool
     258            0 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     259              :                                        const TraitItemReference **ref) const
     260              : {
     261            0 :   return lookup_trait_item (item.trait_identifier (), ref);
     262              : }
     263              : 
     264              : bool
     265        24909 : TraitReference::lookup_trait_item (const std::string &ident,
     266              :                                    const TraitItemReference **ref,
     267              :                                    bool lookup_supers) const
     268              : {
     269        31031 :   for (auto &item : item_refs)
     270              :     {
     271        29465 :       if (ident.compare (item.get_identifier ()) == 0)
     272              :         {
     273        23343 :           *ref = &item;
     274        23343 :           return true;
     275              :         }
     276              :     }
     277              : 
     278         1566 :   if (!lookup_supers)
     279              :     return false;
     280              : 
     281              :   // lookup super traits
     282           85 :   for (const auto &super_trait : super_traits)
     283              :     {
     284           14 :       bool found = super_trait.get ()->lookup_trait_item (ident, ref);
     285           14 :       if (found)
     286        23357 :         return true;
     287              :     }
     288              : 
     289              :   return false;
     290              : }
     291              : 
     292              : const TraitItemReference *
     293       160007 : TraitReference::lookup_trait_item (const std::string &ident,
     294              :                                    TraitItemReference::TraitItemType type) const
     295              : {
     296       385173 :   for (auto &item : item_refs)
     297              :     {
     298       240730 :       if (item.get_trait_item_type () != type)
     299        26514 :         continue;
     300              : 
     301       214216 :       if (ident.compare (item.get_identifier ()) == 0)
     302       160007 :         return &item;
     303              :     }
     304              : 
     305              :   // lookup super traits
     306       197450 :   for (const auto &super_trait : super_traits)
     307              :     {
     308        67403 :       const TraitItemReference *res
     309        67403 :         = super_trait.get ()->lookup_trait_item (ident, type);
     310        67403 :       if (!res->is_error ())
     311       160007 :         return res;
     312              :     }
     313              : 
     314       130047 :   return &TraitItemReference::error_node ();
     315              : }
     316              : 
     317              : size_t
     318         4650 : TraitReference::size () const
     319              : {
     320         4650 :   return item_refs.size ();
     321              : }
     322              : 
     323              : const std::vector<TraitItemReference> &
     324         2001 : TraitReference::get_trait_items () const
     325              : {
     326         2001 :   return item_refs;
     327              : }
     328              : 
     329              : void
     330         1229 : TraitReference::get_trait_items_and_supers (
     331              :   std::vector<const TraitItemReference *> &result) const
     332              : {
     333         2548 :   for (const auto &item : item_refs)
     334         1319 :     result.push_back (&item);
     335              : 
     336         1600 :   for (const auto &super_trait : super_traits)
     337          371 :     super_trait.get ()->get_trait_items_and_supers (result);
     338         1229 : }
     339              : 
     340              : void
     341         3680 : TraitReference::on_resolved ()
     342              : {
     343         6990 :   for (auto &item : item_refs)
     344              :     {
     345         3310 :       if (item.get_trait_item_type ()
     346              :           == TraitItemReference::TraitItemType::TYPE)
     347          736 :         item.on_resolved ();
     348              :     }
     349         6990 :   for (auto &item : item_refs)
     350              :     {
     351         3310 :       if (item.get_trait_item_type ()
     352              :           != TraitItemReference::TraitItemType::TYPE)
     353         2574 :         item.on_resolved ();
     354              :     }
     355         3680 : }
     356              : 
     357              : void
     358         4651 : TraitReference::clear_associated_types () const
     359              : {
     360        12050 :   for (const auto &item : item_refs)
     361              :     {
     362         7399 :       bool is_assoc_type = item.get_trait_item_type ()
     363         7399 :                            == TraitItemReference::TraitItemType::TYPE;
     364         7399 :       if (is_assoc_type)
     365         1177 :         item.associated_type_reset (false);
     366              :     }
     367         4651 : }
     368              : 
     369              : void
     370         3384 : TraitReference::clear_associated_type_projections () const
     371              : {
     372         8905 :   for (const auto &item : item_refs)
     373              :     {
     374         5521 :       bool is_assoc_type = item.get_trait_item_type ()
     375         5521 :                            == TraitItemReference::TraitItemType::TYPE;
     376         5521 :       if (is_assoc_type)
     377          176 :         item.associated_type_reset (true);
     378              :     }
     379         3384 : }
     380              : 
     381              : bool
     382       412086 : TraitReference::is_equal (const TraitReference &other) const
     383              : {
     384       412086 :   DefId this_id = get_mappings ().get_defid ();
     385       412086 :   DefId other_id = other.get_mappings ().get_defid ();
     386       412086 :   return this_id == other_id;
     387              : }
     388              : 
     389              : std::vector<TyTy::TypeBoundPredicate>
     390        20224 : TraitReference::get_super_traits () const
     391              : {
     392        20224 :   return super_traits;
     393              : }
     394              : 
     395              : bool
     396          256 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
     397              : {
     398              :   // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
     399          256 :   std::vector<const TraitReference *> non_object_super_traits;
     400          312 :   for (auto &super_trait : super_traits)
     401              :     {
     402           56 :       if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
     403            1 :         non_object_super_traits.push_back (super_trait.get ());
     404              :     }
     405              : 
     406          256 :   std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
     407          527 :   for (auto &item : get_trait_items ())
     408              :     {
     409          271 :       if (!item.is_object_safe ())
     410            4 :         non_object_safe_items.push_back (&item);
     411              :     }
     412              : 
     413          256 :   bool is_safe
     414          256 :     = non_object_super_traits.empty () && non_object_safe_items.empty ();
     415          256 :   if (emit_error && !is_safe)
     416              :     {
     417            2 :       rich_location r (line_table, locus);
     418            3 :       for (auto &item : non_object_super_traits)
     419            1 :         r.add_range (item->get_locus ());
     420            4 :       for (auto &item : non_object_safe_items)
     421            2 :         r.add_range (item->get_locus ());
     422              : 
     423            2 :       rust_error_at (r, "trait bound is not object safe");
     424            2 :     }
     425              : 
     426          256 :   return is_safe;
     427          256 : }
     428              : 
     429              : bool
     430            0 : TraitReference::trait_has_generics () const
     431              : {
     432            0 :   return !trait_substs.empty ();
     433              : }
     434              : 
     435              : std::vector<TyTy::SubstitutionParamMapping> &
     436            8 : TraitReference::get_trait_substs ()
     437              : {
     438            8 :   return trait_substs;
     439              : }
     440              : 
     441              : const std::vector<TyTy::SubstitutionParamMapping> &
     442        40448 : TraitReference::get_trait_substs () const
     443              : {
     444        40448 :   return trait_substs;
     445              : }
     446              : 
     447              : bool
     448       233893 : TraitReference::satisfies_bound (const TraitReference &reference) const
     449              : {
     450       233893 :   if (is_equal (reference))
     451              :     return true;
     452              : 
     453       232476 :   for (const auto &super_trait : super_traits)
     454              :     {
     455        74368 :       if (super_trait.get ()->satisfies_bound (reference))
     456        75785 :         return true;
     457              :     }
     458              : 
     459              :   return false;
     460              : }
     461              : 
     462         4651 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
     463              :                                           TyTy::TypeBoundPredicate predicate,
     464              :                                           HIR::ImplBlock *impl,
     465              :                                           TyTy::BaseType *self,
     466         4651 :                                           Resolver::TypeCheckContext *context)
     467         4651 :   : trait (trait), predicate (predicate), impl (impl), self (self),
     468         4651 :     context (context)
     469         4651 : {}
     470              : 
     471              : TyTy::TypeBoundPredicate &
     472        20536 : AssociatedImplTrait::get_predicate ()
     473              : {
     474        20536 :   return predicate;
     475              : }
     476              : 
     477              : HIR::ImplBlock *
     478         4795 : AssociatedImplTrait::get_impl_block ()
     479              : {
     480         4795 :   return impl;
     481              : }
     482              : 
     483              : TyTy::BaseType *
     484         2242 : AssociatedImplTrait::get_self ()
     485              : {
     486         2242 :   return self;
     487              : }
     488              : 
     489              : const TyTy::BaseType *
     490            0 : AssociatedImplTrait::get_self () const
     491              : {
     492            0 :   return self;
     493              : }
     494              : 
     495              : } // namespace Resolver
     496              : } // 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.