LCOV - code coverage report
Current view: top level - gcc/rust/util - rust-canonical-path.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.2 % 59 55
Test Date: 2026-02-28 14:20:25 Functions: 83.3 % 12 10
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              : #ifndef RUST_CANONICAL_PATH
      20              : #define RUST_CANONICAL_PATH
      21              : 
      22              : #include "rust-system.h"
      23              : #include "rust-mapping-common.h"
      24              : 
      25              : namespace Rust {
      26              : namespace Resolver {
      27              : 
      28              : // https://doc.rust-lang.org/reference/paths.html#canonical-paths
      29              : //
      30              : // struct X - path X
      31              : // impl X { fn test - path X::test }
      32              : //
      33              : // struct X<T> - path X
      34              : //
      35              : // impl X<T>   { fn test - path X::test}
      36              : // impl X<i32> { fn test - path X<i32>::test }
      37              : // impl X<f32> { fn test - path X<f32>::test }
      38              : //
      39              : // pub trait Trait { // ::a::Trait
      40              : //   fn f(&self); // ::a::Trait::f
      41              : // }
      42              : //
      43              : // impl Trait for Struct {
      44              : //    fn f(&self) {} // <::a::Struct as ::a::Trait>::f
      45              : // }
      46    174156445 : class CanonicalPath
      47              : {
      48              : public:
      49    261291764 :   CanonicalPath (const CanonicalPath &other)
      50    261288774 :     : segs (other.segs), crate_num (other.crate_num)
      51              :   {}
      52              : 
      53           64 :   CanonicalPath &operator= (const CanonicalPath &other)
      54              :   {
      55           64 :     segs = other.segs;
      56           64 :     crate_num = other.crate_num;
      57           64 :     return *this;
      58              :   }
      59              : 
      60     86085658 :   static CanonicalPath new_seg (NodeId id, std::string path)
      61              :   {
      62     86085658 :     rust_assert (!path.empty ());
      63     86085658 :     return CanonicalPath ({std::pair<NodeId, std::string> (id,
      64              :                                                            std::move (path))},
      65    258256974 :                           UNKNOWN_CRATENUM);
      66              :   }
      67              : 
      68              :   static CanonicalPath
      69        10261 :   trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
      70              :                              const CanonicalPath &impl_type_seg)
      71              :   {
      72              :     // https://doc.rust-lang.org/reference/paths.html#canonical-paths
      73              :     // should be "<X>"?
      74        20522 :     return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + " as "
      75        30783 :                                          + trait_seg.get () + ">");
      76              :   }
      77              : 
      78         6855 :   static CanonicalPath inherent_impl_seg (NodeId id,
      79              :                                           const CanonicalPath &impl_type_seg)
      80              :   {
      81              :     // https://doc.rust-lang.org/reference/paths.html#canonical-paths
      82              :     // should be "<X as Y>"?
      83        13710 :     return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + ">");
      84              :   }
      85              : 
      86        81162 :   std::string get () const
      87              :   {
      88        81162 :     std::string buf;
      89       287854 :     for (size_t i = 0; i < segs.size (); i++)
      90              :       {
      91       206692 :         bool have_more = (i + 1) < segs.size ();
      92       206692 :         const std::string &seg = segs.at (i).second;
      93       493357 :         buf += seg + (have_more ? "::" : "");
      94              :       }
      95        81162 :     return buf;
      96              :   }
      97              : 
      98              :   static CanonicalPath get_big_self (NodeId id)
      99              :   {
     100              :     return CanonicalPath::new_seg (id, "Self");
     101              :   }
     102              : 
     103      1305807 :   static CanonicalPath create_empty ()
     104              :   {
     105      1305807 :     return CanonicalPath ({}, UNKNOWN_CRATENUM);
     106              :   }
     107              : 
     108       658284 :   bool is_empty () const { return segs.size () == 0; }
     109              : 
     110       164571 :   CanonicalPath append (const CanonicalPath &other) const
     111              :   {
     112       164571 :     rust_assert (!other.is_empty ());
     113       164571 :     if (is_empty ())
     114            2 :       return CanonicalPath (other.segs, crate_num);
     115              : 
     116       164570 :     std::vector<std::pair<NodeId, std::string>> copy (segs);
     117       164570 :     copy.reserve (other.segs.size ());
     118              : 
     119       329140 :     for (auto &s : other.segs)
     120       164570 :       copy.push_back (s);
     121              : 
     122       164570 :     return CanonicalPath (copy, crate_num);
     123       164570 :   }
     124              : 
     125              :   // if we have the path A::B::C this will give a callback for each segment
     126              :   // including the prefix, example:
     127              :   //
     128              :   // path:
     129              :   //   A::B::C
     130              :   //
     131              :   // iterate:
     132              :   //   A
     133              :   //   A::B
     134              :   //   A::B::C
     135              :   void iterate (std::function<bool (const CanonicalPath &)> cb) const
     136              :   {
     137              :     std::vector<std::pair<NodeId, std::string>> buf;
     138              :     for (auto &seg : segs)
     139              :       {
     140              :         buf.push_back (seg);
     141              :         if (!cb (CanonicalPath (buf, crate_num)))
     142              :           return;
     143              :       }
     144              :   }
     145              : 
     146              :   // if we have the path A::B::C this will give a callback for each segment
     147              :   // example:
     148              :   //
     149              :   // path:
     150              :   //   A::B::C
     151              :   //
     152              :   // iterate:
     153              :   //   A
     154              :   //      B
     155              :   //         C
     156           25 :   void iterate_segs (std::function<bool (const CanonicalPath &)> cb) const
     157              :   {
     158           82 :     for (auto &seg : segs)
     159              :       {
     160           57 :         std::vector<std::pair<NodeId, std::string>> buf;
     161          114 :         buf.push_back ({seg.first, seg.second});
     162          114 :         if (!cb (CanonicalPath (buf, crate_num)))
     163            0 :           return;
     164           57 :       }
     165              :   }
     166              : 
     167       108437 :   size_t size () const { return segs.size (); }
     168              : 
     169           57 :   NodeId get_node_id () const
     170              :   {
     171           57 :     rust_assert (!segs.empty ());
     172           57 :     return segs.back ().first;
     173              :   }
     174              : 
     175        75022 :   const std::pair<NodeId, std::string> &get_seg_at (size_t index) const
     176              :   {
     177        75022 :     rust_assert (index < size ());
     178        75022 :     return segs.at (index);
     179              :   }
     180              : 
     181            0 :   bool is_equal (const CanonicalPath &b) const
     182              :   {
     183            0 :     return get ().compare (b.get ()) == 0;
     184              :   }
     185              : 
     186        74527 :   void set_crate_num (CrateNum n) { crate_num = n; }
     187              : 
     188           25 :   CrateNum get_crate_num () const
     189              :   {
     190           25 :     rust_assert (crate_num != UNKNOWN_CRATENUM);
     191           25 :     return crate_num;
     192              :   }
     193              : 
     194              :   bool operator== (const CanonicalPath &b) const { return is_equal (b); }
     195              : 
     196            0 :   bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
     197              : 
     198              : private:
     199     87556093 :   explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path,
     200              :                           CrateNum crate_num)
     201     87556093 :     : segs (path), crate_num (crate_num)
     202              :   {}
     203              : 
     204              :   std::vector<std::pair<NodeId, std::string>> segs;
     205              :   CrateNum crate_num;
     206              : };
     207              : 
     208              : } // namespace Resolver
     209              : } // namespace Rust
     210              : 
     211              : #endif // RUST_CANONICAL_PATH
        

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.