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.4 % 204 166
Test Date: 2026-10-03 16:17:38 Functions: 82.2 % 45 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          299 : TraitItemReference::as_string () const
      27              : {
      28         1196 :   return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
      29              : }
      30              : 
      31              : bool
      32         9034 : TraitItemReference::is_error () const
      33              : {
      34         9034 :   return type == ERROR;
      35              : }
      36              : 
      37              : bool
      38        10335 : TraitItemReference::is_optional () const
      39              : {
      40        10335 :   return optional_flag;
      41              : }
      42              : 
      43              : std::string
      44        53862 : TraitItemReference::get_identifier () const
      45              : {
      46        53862 :   return identifier;
      47              : }
      48              : 
      49              : TraitItemReference::TraitItemType
      50        27637 : TraitItemReference::get_trait_item_type () const
      51              : {
      52        27637 :   return type;
      53              : }
      54              : 
      55              : HIR::TraitItem *
      56        10517 : TraitItemReference::get_hir_trait_item () const
      57              : {
      58        10517 :   return hir_trait_item;
      59              : }
      60              : 
      61              : location_t
      62         2123 : TraitItemReference::get_locus () const
      63              : {
      64         2123 :   return locus;
      65              : }
      66              : 
      67              : const Analysis::NodeMapping
      68        34240 : TraitItemReference::get_mappings () const
      69              : {
      70        34240 :   return hir_trait_item->get_mappings ();
      71              : }
      72              : 
      73              : TyTy::BaseType *
      74        21860 : TraitItemReference::get_tyty () const
      75              : {
      76        21860 :   rust_assert (hir_trait_item != nullptr);
      77              : 
      78        21860 :   TyTy::BaseType *resolved = nullptr;
      79        21860 :   if (type == FN
      80        21860 :       && context->lookup_type (get_mappings ().get_hirid (), &resolved))
      81        10643 :     return resolved;
      82              : 
      83        11217 :   switch (type)
      84              :     {
      85           32 :     case CONST:
      86           32 :       return get_type_from_constant (
      87           32 :         static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
      88         8437 :       break;
      89              : 
      90         8437 :     case TYPE:
      91         8437 :       return get_type_from_typealias (
      92         8437 :         static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
      93              : 
      94         2748 :     case FN:
      95         2748 :       return get_type_from_fn (
      96         2748 :         static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
      97            0 :       break;
      98              : 
      99            0 :     default:
     100            0 :       return get_error ();
     101              :     }
     102              : 
     103              :   rust_unreachable ();
     104              :   return get_error ();
     105              : }
     106              : 
     107              : TyTy::ErrorType *
     108            2 : TraitItemReference::get_error () const
     109              : {
     110            2 :   return new TyTy::ErrorType (get_mappings ().get_hirid ());
     111              : }
     112              : 
     113         6254 : TraitReference::TraitReference (
     114              :   const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
     115              :   std::vector<TyTy::TypeBoundPredicate> super_traits,
     116              :   std::vector<TyTy::SubstitutionParamMapping> substs)
     117         6254 :   : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
     118         6254 :     super_traits (super_traits)
     119              : {
     120         6254 :   trait_substs.clear ();
     121         6254 :   trait_substs.reserve (substs.size ());
     122        11134 :   for (const auto &p : substs)
     123         4880 :     trait_substs.push_back (p.clone ());
     124         6254 : }
     125              : 
     126            0 : TraitReference::TraitReference (TraitReference const &other)
     127            0 :   : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
     128            0 :     super_traits (other.super_traits)
     129              : {
     130            0 :   trait_substs.clear ();
     131            0 :   trait_substs.reserve (other.trait_substs.size ());
     132            0 :   for (const auto &p : other.trait_substs)
     133            0 :     trait_substs.push_back (p.clone ());
     134            0 : }
     135              : 
     136              : TraitReference &
     137            0 : TraitReference::operator= (TraitReference const &other)
     138              : {
     139            0 :   hir_trait_ref = other.hir_trait_ref;
     140            0 :   item_refs = other.item_refs;
     141            0 :   super_traits = other.super_traits;
     142              : 
     143            0 :   trait_substs.clear ();
     144            0 :   trait_substs.reserve (other.trait_substs.size ());
     145            0 :   for (const auto &p : other.trait_substs)
     146            0 :     trait_substs.push_back (p.clone ());
     147              : 
     148            0 :   return *this;
     149              : }
     150              : 
     151              : bool
     152        81534 : TraitReference::is_error () const
     153              : {
     154        81534 :   return hir_trait_ref == nullptr;
     155              : }
     156              : 
     157              : location_t
     158          952 : TraitReference::get_locus () const
     159              : {
     160          952 :   return hir_trait_ref->get_locus ();
     161              : }
     162              : 
     163              : std::string
     164         8587 : TraitReference::get_name () const
     165              : {
     166         8587 :   rust_assert (!is_error ());
     167        17174 :   return hir_trait_ref->get_name ().as_string ();
     168              : }
     169              : 
     170              : std::string
     171          235 : TraitReference::as_string () const
     172              : {
     173          235 :   if (is_error ())
     174            0 :     return "<trait-ref-error-node>";
     175              : 
     176          235 :   std::string item_buf;
     177          534 :   for (auto &item : item_refs)
     178              :     {
     179          897 :       item_buf += item.as_string () + ", ";
     180              :     }
     181          470 :   return "HIR Trait: " + get_name () + "->"
     182         1175 :          + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
     183          235 : }
     184              : 
     185              : const HIR::Trait *
     186        75264 : TraitReference::get_hir_trait_ref () const
     187              : {
     188        75264 :   return hir_trait_ref;
     189              : }
     190              : 
     191              : const Analysis::NodeMapping &
     192       379423 : TraitReference::get_mappings () const
     193              : {
     194       379423 :   return hir_trait_ref->get_mappings ();
     195              : }
     196              : 
     197              : DefId
     198          402 : TraitReference::get_defid () const
     199              : {
     200          402 :   return get_mappings ().get_defid ();
     201              : }
     202              : 
     203              : bool
     204          290 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     205              :                                        TraitItemReference **ref)
     206              : {
     207          290 :   return lookup_trait_item (item.trait_identifier (), ref);
     208              : }
     209              : 
     210              : bool
     211          290 : TraitReference::lookup_trait_item (const std::string &ident,
     212              :                                    TraitItemReference **ref)
     213              : {
     214          667 :   for (auto &item : item_refs)
     215              :     {
     216          667 :       if (ident.compare (item.get_identifier ()) == 0)
     217              :         {
     218          290 :           *ref = &item;
     219          290 :           return true;
     220              :         }
     221              :     }
     222              :   return false;
     223              : }
     224              : 
     225              : bool
     226            0 : TraitReference::lookup_trait_item_by_type (
     227              :   const std::string &ident, TraitItemReference::TraitItemType type,
     228              :   TraitItemReference **ref)
     229              : {
     230            0 :   for (auto &item : item_refs)
     231              :     {
     232            0 :       if (item.get_trait_item_type () != type)
     233            0 :         continue;
     234              : 
     235            0 :       if (ident.compare (item.get_identifier ()) == 0)
     236              :         {
     237            0 :           *ref = &item;
     238            0 :           return true;
     239              :         }
     240              :     }
     241              :   return false;
     242              : }
     243              : 
     244              : bool
     245         6920 : TraitReference::lookup_trait_item_by_type (
     246              :   const std::string &ident, TraitItemReference::TraitItemType type,
     247              :   const TraitItemReference **ref) const
     248              : {
     249        10487 :   for (auto &item : item_refs)
     250              :     {
     251        10483 :       if (item.get_trait_item_type () != type)
     252         1502 :         continue;
     253              : 
     254         8981 :       if (ident.compare (item.get_identifier ()) == 0)
     255              :         {
     256         6916 :           *ref = &item;
     257         6916 :           return true;
     258              :         }
     259              :     }
     260              :   return false;
     261              : }
     262              : 
     263              : bool
     264            0 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
     265              :                                        const TraitItemReference **ref) const
     266              : {
     267            0 :   return lookup_trait_item (item.trait_identifier (), ref);
     268              : }
     269              : 
     270              : bool
     271        17092 : TraitReference::lookup_trait_item (const std::string &ident,
     272              :                                    const TraitItemReference **ref,
     273              :                                    bool lookup_supers) const
     274              : {
     275        23783 :   for (auto &item : item_refs)
     276              :     {
     277        22066 :       if (ident.compare (item.get_identifier ()) == 0)
     278              :         {
     279        15375 :           *ref = &item;
     280        15375 :           return true;
     281              :         }
     282              :     }
     283              : 
     284         1717 :   if (!lookup_supers)
     285              :     return false;
     286              : 
     287              :   // lookup super traits
     288           86 :   for (const auto &super_trait : super_traits)
     289              :     {
     290           14 :       bool found = super_trait.get ()->lookup_trait_item (ident, ref);
     291           14 :       if (found)
     292        17092 :         return true;
     293              :     }
     294              : 
     295              :   return false;
     296              : }
     297              : 
     298              : const TraitItemReference *
     299         2118 : TraitReference::lookup_trait_item (const std::string &ident,
     300              :                                    TraitItemReference::TraitItemType type) const
     301              : {
     302         5831 :   for (auto &item : item_refs)
     303              :     {
     304         5159 :       if (item.get_trait_item_type () != type)
     305          121 :         continue;
     306              : 
     307         5038 :       if (ident.compare (item.get_identifier ()) == 0)
     308         2118 :         return &item;
     309              :     }
     310              : 
     311              :   // lookup super traits
     312         1008 :   for (const auto &super_trait : super_traits)
     313              :     {
     314          336 :       const TraitItemReference *res
     315          336 :         = super_trait.get ()->lookup_trait_item (ident, type);
     316          336 :       if (!res->is_error ())
     317         2118 :         return res;
     318              :     }
     319              : 
     320          672 :   return &TraitItemReference::error_node ();
     321              : }
     322              : 
     323              : size_t
     324         5334 : TraitReference::size () const
     325              : {
     326         5334 :   return item_refs.size ();
     327              : }
     328              : 
     329              : const std::vector<TraitItemReference> &
     330         4877 : TraitReference::get_trait_items () const
     331              : {
     332         4877 :   return item_refs;
     333              : }
     334              : 
     335              : void
     336         1502 : TraitReference::get_trait_items_and_supers (
     337              :   std::vector<const TraitItemReference *> &result) const
     338              : {
     339         3073 :   for (const auto &item : item_refs)
     340         1571 :     result.push_back (&item);
     341              : 
     342         1873 :   for (const auto &super_trait : super_traits)
     343          371 :     super_trait.get ()->get_trait_items_and_supers (result);
     344         1502 : }
     345              : 
     346              : void
     347         4167 : TraitReference::on_resolved ()
     348              : {
     349         7769 :   for (auto &item : item_refs)
     350              :     {
     351         3602 :       if (item.get_trait_item_type ()
     352              :           == TraitItemReference::TraitItemType::TYPE)
     353          814 :         item.on_resolved (this);
     354              :     }
     355         7769 :   for (auto &item : item_refs)
     356              :     {
     357         3602 :       if (item.get_trait_item_type ()
     358              :           != TraitItemReference::TraitItemType::TYPE)
     359         2788 :         item.on_resolved (this);
     360              :     }
     361         4167 : }
     362              : 
     363              : void
     364         4148 : TraitReference::resolve_default_function_bodies ()
     365              : {
     366         7739 :   for (auto &item : item_refs)
     367         3591 :     item.resolve_default_function_body (this);
     368         4148 : }
     369              : 
     370              : bool
     371       166463 : TraitReference::is_equal (const TraitReference &other) const
     372              : {
     373       166463 :   DefId this_id = get_mappings ().get_defid ();
     374       166463 :   DefId other_id = other.get_mappings ().get_defid ();
     375       166463 :   return this_id == other_id;
     376              : }
     377              : 
     378              : std::vector<TyTy::TypeBoundPredicate>
     379        38860 : TraitReference::get_super_traits () const
     380              : {
     381        38860 :   return super_traits;
     382              : }
     383              : 
     384              : bool
     385          327 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
     386              : {
     387              :   // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
     388          327 :   std::vector<const TraitReference *> non_object_super_traits;
     389          383 :   for (auto &super_trait : super_traits)
     390              :     {
     391           56 :       if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
     392            1 :         non_object_super_traits.push_back (super_trait.get ());
     393              :     }
     394              : 
     395          327 :   std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
     396          663 :   for (auto &item : get_trait_items ())
     397              :     {
     398          336 :       if (!item.is_object_safe ())
     399            4 :         non_object_safe_items.push_back (&item);
     400              :     }
     401              : 
     402          327 :   bool is_safe
     403          327 :     = non_object_super_traits.empty () && non_object_safe_items.empty ();
     404          327 :   if (emit_error && !is_safe)
     405              :     {
     406            2 :       rich_location r (line_table, locus);
     407            3 :       for (auto &item : non_object_super_traits)
     408            1 :         r.add_range (item->get_locus ());
     409            4 :       for (auto &item : non_object_safe_items)
     410            2 :         r.add_range (item->get_locus ());
     411              : 
     412            2 :       rust_error_at (r, "trait bound is not object safe");
     413            2 :     }
     414              : 
     415          327 :   return is_safe;
     416          327 : }
     417              : 
     418              : bool
     419            0 : TraitReference::trait_has_generics () const
     420              : {
     421            0 :   return !trait_substs.empty ();
     422              : }
     423              : 
     424              : std::vector<TyTy::SubstitutionParamMapping> &
     425            0 : TraitReference::get_trait_substs ()
     426              : {
     427            0 :   return trait_substs;
     428              : }
     429              : 
     430              : const std::vector<TyTy::SubstitutionParamMapping> &
     431        86946 : TraitReference::get_trait_substs () const
     432              : {
     433        86946 :   return trait_substs;
     434              : }
     435              : 
     436              : bool
     437        80785 : TraitReference::satisfies_bound (const TraitReference &reference) const
     438              : {
     439        80785 :   if (is_equal (reference))
     440              :     return true;
     441              : 
     442        12598 :   for (const auto &super_trait : super_traits)
     443              :     {
     444         1709 :       if (super_trait.get ()->satisfies_bound (reference))
     445        80785 :         return true;
     446              :     }
     447              : 
     448              :   return false;
     449              : }
     450              : 
     451         5335 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
     452              :                                           TyTy::TypeBoundPredicate predicate,
     453              :                                           HIR::ImplBlock *impl,
     454              :                                           TyTy::BaseType *self,
     455              :                                           ImplTraitContextFrame frame)
     456         5335 :   : trait (trait), predicate (predicate), impl (impl), self (self),
     457         5335 :     context (TypeCheckContext::get ()), frame (frame)
     458         5335 : {}
     459              : 
     460              : TyTy::TypeBoundPredicate &
     461         2598 : AssociatedImplTrait::get_predicate ()
     462              : {
     463         2598 :   return predicate;
     464              : }
     465              : 
     466              : HIR::ImplBlock *
     467           53 : AssociatedImplTrait::get_impl_block ()
     468              : {
     469           53 :   return impl;
     470              : }
     471              : 
     472              : TyTy::BaseType *
     473            0 : AssociatedImplTrait::get_self ()
     474              : {
     475            0 :   return self;
     476              : }
     477              : 
     478              : const TyTy::BaseType *
     479            0 : AssociatedImplTrait::get_self () const
     480              : {
     481            0 :   return self;
     482              : }
     483              : 
     484              : ImplTraitContextFrame
     485         6753 : AssociatedImplTrait::get_frame () const
     486              : {
     487         6753 :   return frame;
     488              : }
     489              : 
     490              : } // namespace Resolver
     491              : } // 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.