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: 81.8 % 198 162
Test Date: 2026-07-11 15:47:05 Functions: 84.1 % 44 37
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              : #include "rust-hir-type-check.h"
      21              : 
      22              : namespace Rust {
      23              : namespace Resolver {
      24              : 
      25              : std::string
      26         1297 : TraitItemReference::as_string () const
      27              : {
      28         5188 :   return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
      29              : }
      30              : 
      31              : bool
      32       166166 : TraitItemReference::is_error () const
      33              : {
      34       166166 :   return type == ERROR;
      35              : }
      36              : 
      37              : bool
      38         6396 : TraitItemReference::is_optional () const
      39              : {
      40         6396 :   return optional_flag;
      41              : }
      42              : 
      43              : std::string
      44       273879 : TraitItemReference::get_identifier () const
      45              : {
      46       273879 :   return identifier;
      47              : }
      48              : 
      49              : TraitItemReference::TraitItemType
      50       261271 : TraitItemReference::get_trait_item_type () const
      51              : {
      52       261271 :   return type;
      53              : }
      54              : 
      55              : HIR::TraitItem *
      56        23738 : TraitItemReference::get_hir_trait_item () const
      57              : {
      58        23738 :   return hir_trait_item;
      59              : }
      60              : 
      61              : location_t
      62         2016 : TraitItemReference::get_locus () const
      63              : {
      64         2016 :   return locus;
      65              : }
      66              : 
      67              : const Analysis::NodeMapping
      68        33560 : TraitItemReference::get_mappings () const
      69              : {
      70        33560 :   return hir_trait_item->get_mappings ();
      71              : }
      72              : 
      73              : TyTy::BaseType *
      74        43624 : TraitItemReference::get_tyty () const
      75              : {
      76        43624 :   rust_assert (hir_trait_item != nullptr);
      77              : 
      78        43624 :   switch (type)
      79              :     {
      80           31 :     case CONST:
      81           31 :       return get_type_from_constant (
      82           31 :         static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
      83        18639 :       break;
      84              : 
      85        18639 :     case TYPE:
      86        18639 :       return get_type_from_typealias (
      87        18639 :         static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
      88              : 
      89        24954 :     case FN:
      90        24954 :       return get_type_from_fn (
      91        24954 :         static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
      92            0 :       break;
      93              : 
      94            0 :     default:
      95            0 :       return get_error ();
      96              :     }
      97              : 
      98              :   rust_unreachable ();
      99              :   return get_error ();
     100              : }
     101              : 
     102              : TyTy::ErrorType *
     103            2 : TraitItemReference::get_error () const
     104              : {
     105            2 :   return new TyTy::ErrorType (get_mappings ().get_hirid ());
     106              : }
     107              : 
     108         5913 : TraitReference::TraitReference (
     109              :   const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
     110              :   std::vector<TyTy::TypeBoundPredicate> super_traits,
     111         5913 :   std::vector<TyTy::SubstitutionParamMapping> substs)
     112         5913 :   : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
     113         5913 :     super_traits (super_traits)
     114              : {
     115         5913 :   trait_substs.clear ();
     116         5913 :   trait_substs.reserve (substs.size ());
     117        10472 :   for (const auto &p : substs)
     118         4559 :     trait_substs.push_back (p.clone ());
     119         5913 : }
     120              : 
     121            0 : TraitReference::TraitReference (TraitReference const &other)
     122            0 :   : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
     123            0 :     super_traits (other.super_traits)
     124              : {
     125            0 :   trait_substs.clear ();
     126            0 :   trait_substs.reserve (other.trait_substs.size ());
     127            0 :   for (const auto &p : other.trait_substs)
     128            0 :     trait_substs.push_back (p.clone ());
     129            0 : }
     130              : 
     131              : TraitReference &
     132            0 : TraitReference::operator= (TraitReference const &other)
     133              : {
     134            0 :   hir_trait_ref = other.hir_trait_ref;
     135            0 :   item_refs = other.item_refs;
     136            0 :   super_traits = other.super_traits;
     137              : 
     138            0 :   trait_substs.clear ();
     139            0 :   trait_substs.reserve (other.trait_substs.size ());
     140            0 :   for (const auto &p : other.trait_substs)
     141            0 :     trait_substs.push_back (p.clone ());
     142              : 
     143            0 :   return *this;
     144              : }
     145              : 
     146              : bool
     147       567849 : TraitReference::is_error () const
     148              : {
     149       567849 :   return hir_trait_ref == nullptr;
     150              : }
     151              : 
     152              : location_t
     153            1 : TraitReference::get_locus () const
     154              : {
     155            1 :   return hir_trait_ref->get_locus ();
     156              : }
     157              : 
     158              : std::string
     159        62958 : TraitReference::get_name () const
     160              : {
     161        62958 :   rust_assert (!is_error ());
     162       125916 :   return hir_trait_ref->get_name ().as_string ();
     163              : }
     164              : 
     165              : std::string
     166         1184 : TraitReference::as_string () const
     167              : {
     168         1184 :   if (is_error ())
     169            0 :     return "<trait-ref-error-node>";
     170              : 
     171         1184 :   std::string item_buf;
     172         2481 :   for (auto &item : item_refs)
     173              :     {
     174         3891 :       item_buf += item.as_string () + ", ";
     175              :     }
     176         2368 :   return "HIR Trait: " + get_name () + "->"
     177         5920 :          + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
     178         1184 : }
     179              : 
     180              : const HIR::Trait *
     181        19842 : TraitReference::get_hir_trait_ref () const
     182              : {
     183        19842 :   return hir_trait_ref;
     184              : }
     185              : 
     186              : const Analysis::NodeMapping &
     187      1133176 : TraitReference::get_mappings () const
     188              : {
     189      1133176 :   return hir_trait_ref->get_mappings ();
     190              : }
     191              : 
     192              : DefId
     193          186 : TraitReference::get_defid () const
     194              : {
     195          186 :   return get_mappings ().get_defid ();
     196              : }
     197              : 
     198              : bool
     199          241 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     200              :                                        TraitItemReference **ref)
     201              : {
     202          241 :   return lookup_trait_item (item.trait_identifier (), ref);
     203              : }
     204              : 
     205              : bool
     206          241 : TraitReference::lookup_trait_item (const std::string &ident,
     207              :                                    TraitItemReference **ref)
     208              : {
     209          542 :   for (auto &item : item_refs)
     210              :     {
     211          542 :       if (ident.compare (item.get_identifier ()) == 0)
     212              :         {
     213          241 :           *ref = &item;
     214          241 :           return true;
     215              :         }
     216              :     }
     217              :   return false;
     218              : }
     219              : 
     220              : bool
     221            0 : TraitReference::lookup_trait_item_by_type (
     222              :   const std::string &ident, TraitItemReference::TraitItemType type,
     223              :   TraitItemReference **ref)
     224              : {
     225            0 :   for (auto &item : item_refs)
     226              :     {
     227            0 :       if (item.get_trait_item_type () != type)
     228            0 :         continue;
     229              : 
     230            0 :       if (ident.compare (item.get_identifier ()) == 0)
     231              :         {
     232            0 :           *ref = &item;
     233            0 :           return true;
     234              :         }
     235              :     }
     236              :   return false;
     237              : }
     238              : 
     239              : bool
     240         6082 : TraitReference::lookup_trait_item_by_type (
     241              :   const std::string &ident, TraitItemReference::TraitItemType type,
     242              :   const TraitItemReference **ref) const
     243              : {
     244         9287 :   for (auto &item : item_refs)
     245              :     {
     246         9283 :       if (item.get_trait_item_type () != type)
     247         1276 :         continue;
     248              : 
     249         8007 :       if (ident.compare (item.get_identifier ()) == 0)
     250              :         {
     251         6078 :           *ref = &item;
     252         6078 :           return true;
     253              :         }
     254              :     }
     255              :   return false;
     256              : }
     257              : 
     258              : bool
     259            0 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     260              :                                        const TraitItemReference **ref) const
     261              : {
     262            0 :   return lookup_trait_item (item.trait_identifier (), ref);
     263              : }
     264              : 
     265              : bool
     266        26564 : TraitReference::lookup_trait_item (const std::string &ident,
     267              :                                    const TraitItemReference **ref,
     268              :                                    bool lookup_supers) const
     269              : {
     270        32736 :   for (auto &item : item_refs)
     271              :     {
     272        31186 :       if (ident.compare (item.get_identifier ()) == 0)
     273              :         {
     274        25014 :           *ref = &item;
     275        25014 :           return true;
     276              :         }
     277              :     }
     278              : 
     279         1550 :   if (!lookup_supers)
     280              :     return false;
     281              : 
     282              :   // lookup super traits
     283           85 :   for (const auto &super_trait : super_traits)
     284              :     {
     285           14 :       bool found = super_trait.get ()->lookup_trait_item (ident, ref);
     286           14 :       if (found)
     287        25028 :         return true;
     288              :     }
     289              : 
     290              :   return false;
     291              : }
     292              : 
     293              : const TraitItemReference *
     294       160088 : TraitReference::lookup_trait_item (const std::string &ident,
     295              :                                    TraitItemReference::TraitItemType type) const
     296              : {
     297       385304 :   for (auto &item : item_refs)
     298              :     {
     299       240786 :       if (item.get_trait_item_type () != type)
     300        26517 :         continue;
     301              : 
     302       214269 :       if (ident.compare (item.get_identifier ()) == 0)
     303       160088 :         return &item;
     304              :     }
     305              : 
     306              :   // lookup super traits
     307       197525 :   for (const auto &super_trait : super_traits)
     308              :     {
     309        67412 :       const TraitItemReference *res
     310        67412 :         = super_trait.get ()->lookup_trait_item (ident, type);
     311        67412 :       if (!res->is_error ())
     312       160088 :         return res;
     313              :     }
     314              : 
     315       130113 :   return &TraitItemReference::error_node ();
     316              : }
     317              : 
     318              : size_t
     319         4718 : TraitReference::size () const
     320              : {
     321         4718 :   return item_refs.size ();
     322              : }
     323              : 
     324              : const std::vector<TraitItemReference> &
     325         8765 : TraitReference::get_trait_items () const
     326              : {
     327         8765 :   return item_refs;
     328              : }
     329              : 
     330              : void
     331         1451 : TraitReference::get_trait_items_and_supers (
     332              :   std::vector<const TraitItemReference *> &result) const
     333              : {
     334         2971 :   for (const auto &item : item_refs)
     335         1520 :     result.push_back (&item);
     336              : 
     337         1822 :   for (const auto &super_trait : super_traits)
     338          371 :     super_trait.get ()->get_trait_items_and_supers (result);
     339         1451 : }
     340              : 
     341              : void
     342         3915 : TraitReference::on_resolved ()
     343              : {
     344         7270 :   for (auto &item : item_refs)
     345              :     {
     346         3355 :       if (item.get_trait_item_type ()
     347              :           == TraitItemReference::TraitItemType::TYPE)
     348          739 :         item.on_resolved (this);
     349              :     }
     350         7270 :   for (auto &item : item_refs)
     351              :     {
     352         3355 :       if (item.get_trait_item_type ()
     353              :           != TraitItemReference::TraitItemType::TYPE)
     354         2616 :         item.on_resolved (this);
     355              :     }
     356         3915 : }
     357              : 
     358              : bool
     359       553388 : TraitReference::is_equal (const TraitReference &other) const
     360              : {
     361       553388 :   DefId this_id = get_mappings ().get_defid ();
     362       553388 :   DefId other_id = other.get_mappings ().get_defid ();
     363       553388 :   return this_id == other_id;
     364              : }
     365              : 
     366              : std::vector<TyTy::TypeBoundPredicate>
     367        21160 : TraitReference::get_super_traits () const
     368              : {
     369        21160 :   return super_traits;
     370              : }
     371              : 
     372              : bool
     373          305 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
     374              : {
     375              :   // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
     376          305 :   std::vector<const TraitReference *> non_object_super_traits;
     377          361 :   for (auto &super_trait : super_traits)
     378              :     {
     379           56 :       if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
     380            1 :         non_object_super_traits.push_back (super_trait.get ());
     381              :     }
     382              : 
     383          305 :   std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
     384          618 :   for (auto &item : get_trait_items ())
     385              :     {
     386          313 :       if (!item.is_object_safe ())
     387            4 :         non_object_safe_items.push_back (&item);
     388              :     }
     389              : 
     390          305 :   bool is_safe
     391          305 :     = non_object_super_traits.empty () && non_object_safe_items.empty ();
     392          305 :   if (emit_error && !is_safe)
     393              :     {
     394            2 :       rich_location r (line_table, locus);
     395            3 :       for (auto &item : non_object_super_traits)
     396            1 :         r.add_range (item->get_locus ());
     397            4 :       for (auto &item : non_object_safe_items)
     398            2 :         r.add_range (item->get_locus ());
     399              : 
     400            2 :       rust_error_at (r, "trait bound is not object safe");
     401            2 :     }
     402              : 
     403          305 :   return is_safe;
     404          305 : }
     405              : 
     406              : bool
     407            0 : TraitReference::trait_has_generics () const
     408              : {
     409            0 :   return !trait_substs.empty ();
     410              : }
     411              : 
     412              : std::vector<TyTy::SubstitutionParamMapping> &
     413            8 : TraitReference::get_trait_substs ()
     414              : {
     415            8 :   return trait_substs;
     416              : }
     417              : 
     418              : const std::vector<TyTy::SubstitutionParamMapping> &
     419        50615 : TraitReference::get_trait_substs () const
     420              : {
     421        50615 :   return trait_substs;
     422              : }
     423              : 
     424              : bool
     425       297499 : TraitReference::satisfies_bound (const TraitReference &reference) const
     426              : {
     427       297499 :   if (is_equal (reference))
     428              :     return true;
     429              : 
     430       302269 :   for (const auto &super_trait : super_traits)
     431              :     {
     432        98623 :       if (super_trait.get ()->satisfies_bound (reference))
     433        93853 :         return true;
     434              :     }
     435              : 
     436              :   return false;
     437              : }
     438              : 
     439         4719 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
     440              :                                           TyTy::TypeBoundPredicate predicate,
     441              :                                           HIR::ImplBlock *impl,
     442              :                                           TyTy::BaseType *self,
     443         4719 :                                           ImplTraitContextFrame frame)
     444         4719 :   : trait (trait), predicate (predicate), impl (impl), self (self),
     445         4719 :     context (TypeCheckContext::get ()), frame (frame)
     446         4719 : {}
     447              : 
     448              : TyTy::TypeBoundPredicate &
     449        17665 : AssociatedImplTrait::get_predicate ()
     450              : {
     451        17665 :   return predicate;
     452              : }
     453              : 
     454              : HIR::ImplBlock *
     455           54 : AssociatedImplTrait::get_impl_block ()
     456              : {
     457           54 :   return impl;
     458              : }
     459              : 
     460              : TyTy::BaseType *
     461            0 : AssociatedImplTrait::get_self ()
     462              : {
     463            0 :   return self;
     464              : }
     465              : 
     466              : const TyTy::BaseType *
     467            0 : AssociatedImplTrait::get_self () const
     468              : {
     469            0 :   return self;
     470              : }
     471              : 
     472              : ImplTraitContextFrame
     473         6128 : AssociatedImplTrait::get_frame () const
     474              : {
     475         6128 :   return frame;
     476              : }
     477              : 
     478              : } // namespace Resolver
     479              : } // 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.