Daily bump.
[official-gcc.git] / gcc / rust / util / rust-canonical-path.h
blobf2865eba9ae407cf364c8da9d4304107f5308bd2
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #ifndef RUST_CANONICAL_PATH
20 #define RUST_CANONICAL_PATH
22 #include "rust-system.h"
23 #include "rust-mapping-common.h"
25 namespace Rust {
26 namespace Resolver {
28 // https://doc.rust-lang.org/reference/paths.html#canonical-paths
30 // struct X - path X
31 // impl X { fn test - path X::test }
33 // struct X<T> - path X
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 }
39 // pub trait Trait { // ::a::Trait
40 // fn f(&self); // ::a::Trait::f
41 // }
43 // impl Trait for Struct {
44 // fn f(&self) {} // <::a::Struct as ::a::Trait>::f
45 // }
46 class CanonicalPath
48 public:
49 CanonicalPath (const CanonicalPath &other) : segs (other.segs) {}
51 CanonicalPath &operator= (const CanonicalPath &other)
53 segs = other.segs;
54 return *this;
57 static CanonicalPath new_seg (NodeId id, const std::string &path)
59 rust_assert (!path.empty ());
60 return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
61 UNKNOWN_CRATENUM);
64 static CanonicalPath
65 trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
66 const CanonicalPath &impl_type_seg)
68 return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
69 + trait_seg.get () + ">");
72 static CanonicalPath inherent_impl_seg (NodeId id,
73 const CanonicalPath &impl_type_seg)
75 return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">");
78 std::string get () const
80 std::string buf;
81 for (size_t i = 0; i < segs.size (); i++)
83 bool have_more = (i + 1) < segs.size ();
84 const std::string &seg = segs.at (i).second;
85 buf += seg + (have_more ? "::" : "");
87 return buf;
90 static CanonicalPath get_big_self (NodeId id)
92 return CanonicalPath::new_seg (id, "Self");
95 static CanonicalPath create_empty ()
97 return CanonicalPath ({}, UNKNOWN_CRATENUM);
100 bool is_empty () const { return segs.size () == 0; }
102 CanonicalPath append (const CanonicalPath &other) const
104 rust_assert (!other.is_empty ());
105 if (is_empty ())
106 return CanonicalPath (other.segs, crate_num);
108 std::vector<std::pair<NodeId, std::string>> copy (segs);
109 for (auto &s : other.segs)
110 copy.push_back (s);
112 return CanonicalPath (copy, crate_num);
115 // if we have the path A::B::C this will give a callback for each segment
116 // including the prefix, example:
118 // path:
119 // A::B::C
121 // iterate:
122 // A
123 // A::B
124 // A::B::C
125 void iterate (std::function<bool (const CanonicalPath &)> cb) const
127 std::vector<std::pair<NodeId, std::string>> buf;
128 for (auto &seg : segs)
130 buf.push_back (seg);
131 if (!cb (CanonicalPath (buf, crate_num)))
132 return;
136 // if we have the path A::B::C this will give a callback for each segment
137 // example:
139 // path:
140 // A::B::C
142 // iterate:
143 // A
144 // B
145 // C
146 void iterate_segs (std::function<bool (const CanonicalPath &)> cb) const
148 for (auto &seg : segs)
150 std::vector<std::pair<NodeId, std::string>> buf;
151 buf.push_back ({seg.first, seg.second});
152 if (!cb (CanonicalPath (buf, crate_num)))
153 return;
157 size_t size () const { return segs.size (); }
159 NodeId get_node_id () const
161 rust_assert (!segs.empty ());
162 return segs.back ().first;
165 const std::pair<NodeId, std::string> &get_seg_at (size_t index) const
167 rust_assert (index < size ());
168 return segs.at (index);
171 bool is_equal (const CanonicalPath &b) const
173 return get ().compare (b.get ()) == 0;
176 void set_crate_num (CrateNum n) { crate_num = n; }
178 CrateNum get_crate_num () const
180 rust_assert (crate_num != UNKNOWN_CRATENUM);
181 return crate_num;
184 bool operator== (const CanonicalPath &b) const { return is_equal (b); }
186 bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
188 private:
189 explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path,
190 CrateNum crate_num)
191 : segs (path), crate_num (crate_num)
194 std::vector<std::pair<NodeId, std::string>> segs;
195 CrateNum crate_num;
198 } // namespace Resolver
199 } // namespace Rust
201 #endif // RUST_CANONICAL_PATH