Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 : 13921607 : class CanonicalPath
47 : : {
48 : : public:
49 : 26957309 : CanonicalPath (const CanonicalPath &other) : segs (other.segs) {}
50 : :
51 : 17497 : CanonicalPath &operator= (const CanonicalPath &other)
52 : : {
53 : 9130 : segs = other.segs;
54 : 17497 : return *this;
55 : : }
56 : :
57 : 12655126 : static CanonicalPath new_seg (NodeId id, const std::string &path)
58 : : {
59 : 12655126 : rust_assert (!path.empty ());
60 : 12655126 : return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
61 : 37965378 : UNKNOWN_CRATENUM);
62 : : }
63 : :
64 : : static CanonicalPath
65 : 6993 : trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
66 : : const CanonicalPath &impl_type_seg)
67 : : {
68 : 13986 : return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
69 : 20979 : + trait_seg.get () + ">");
70 : : }
71 : :
72 : 1460 : static CanonicalPath inherent_impl_seg (NodeId id,
73 : : const CanonicalPath &impl_type_seg)
74 : : {
75 : 2920 : return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">");
76 : : }
77 : :
78 : 2579979 : std::string get () const
79 : : {
80 : 2579979 : std::string buf;
81 : 5408686 : for (size_t i = 0; i < segs.size (); i++)
82 : : {
83 : 2828707 : bool have_more = (i + 1) < segs.size ();
84 : 2828707 : const std::string &seg = segs.at (i).second;
85 : 5408686 : buf += seg + (have_more ? "::" : "");
86 : : }
87 : 2579979 : return buf;
88 : : }
89 : :
90 : 5092 : static CanonicalPath get_big_self (NodeId id)
91 : : {
92 : 5092 : return CanonicalPath::new_seg (id, "Self");
93 : : }
94 : :
95 : 738413 : static CanonicalPath create_empty ()
96 : : {
97 : 738413 : return CanonicalPath ({}, UNKNOWN_CRATENUM);
98 : : }
99 : :
100 : 23787 : bool is_empty () const { return segs.size () == 0; }
101 : :
102 : 70799 : CanonicalPath append (const CanonicalPath &other) const
103 : : {
104 : 70799 : rust_assert (!other.is_empty ());
105 : 70799 : if (is_empty ())
106 : 61484 : return CanonicalPath (other.segs, crate_num);
107 : :
108 : 40057 : std::vector<std::pair<NodeId, std::string>> copy (segs);
109 : 80137 : for (auto &s : other.segs)
110 : 40080 : copy.push_back (s);
111 : :
112 : 40057 : return CanonicalPath (copy, crate_num);
113 : 40057 : }
114 : :
115 : : // if we have the path A::B::C this will give a callback for each segment
116 : : // including the prefix, example:
117 : : //
118 : : // path:
119 : : // A::B::C
120 : : //
121 : : // iterate:
122 : : // A
123 : : // A::B
124 : : // A::B::C
125 : : void iterate (std::function<bool (const CanonicalPath &)> cb) const
126 : : {
127 : : std::vector<std::pair<NodeId, std::string>> buf;
128 : : for (auto &seg : segs)
129 : : {
130 : : buf.push_back (seg);
131 : : if (!cb (CanonicalPath (buf, crate_num)))
132 : : return;
133 : : }
134 : : }
135 : :
136 : : // if we have the path A::B::C this will give a callback for each segment
137 : : // example:
138 : : //
139 : : // path:
140 : : // A::B::C
141 : : //
142 : : // iterate:
143 : : // A
144 : : // B
145 : : // C
146 : 25 : void iterate_segs (std::function<bool (const CanonicalPath &)> cb) const
147 : : {
148 : 82 : for (auto &seg : segs)
149 : : {
150 : 57 : std::vector<std::pair<NodeId, std::string>> buf;
151 : 57 : buf.push_back ({seg.first, seg.second});
152 : 114 : if (!cb (CanonicalPath (buf, crate_num)))
153 : 0 : return;
154 : 57 : }
155 : : }
156 : :
157 : 53267 : size_t size () const { return segs.size (); }
158 : :
159 : 17477 : NodeId get_node_id () const
160 : : {
161 : 17477 : rust_assert (!segs.empty ());
162 : 17477 : return segs.back ().first;
163 : : }
164 : :
165 : 31689 : const std::pair<NodeId, std::string> &get_seg_at (size_t index) const
166 : : {
167 : 31689 : rust_assert (index < size ());
168 : 31689 : return segs.at (index);
169 : : }
170 : :
171 : 10332 : bool is_equal (const CanonicalPath &b) const
172 : : {
173 : 10332 : return get ().compare (b.get ()) == 0;
174 : : }
175 : :
176 : 3613 : void set_crate_num (CrateNum n) { crate_num = n; }
177 : :
178 : 25 : CrateNum get_crate_num () const
179 : : {
180 : 25 : rust_assert (crate_num != UNKNOWN_CRATENUM);
181 : 25 : return crate_num;
182 : : }
183 : :
184 : : bool operator== (const CanonicalPath &b) const { return is_equal (b); }
185 : :
186 : 1248256 : bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
187 : :
188 : : private:
189 : 13464395 : explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path,
190 : : CrateNum crate_num)
191 : 13464395 : : segs (path), crate_num (crate_num)
192 : : {}
193 : :
194 : : std::vector<std::pair<NodeId, std::string>> segs;
195 : : CrateNum crate_num;
196 : : };
197 : :
198 : : } // namespace Resolver
199 : : } // namespace Rust
200 : :
201 : : #endif // RUST_CANONICAL_PATH
|