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
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
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"
28 // https://doc.rust-lang.org/reference/paths.html#canonical-paths
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
43 // impl Trait for Struct {
44 // fn f(&self) {} // <::a::Struct as ::a::Trait>::f
49 CanonicalPath (const CanonicalPath
&other
) : segs (other
.segs
) {}
51 CanonicalPath
&operator= (const CanonicalPath
&other
)
54 crate_num
= other
.crate_num
;
58 static CanonicalPath
new_seg (NodeId id
, const std::string
&path
)
60 rust_assert (!path
.empty ());
61 return CanonicalPath ({std::pair
<NodeId
, std::string
> (id
, path
)},
66 trait_impl_projection_seg (NodeId id
, const CanonicalPath
&trait_seg
,
67 const CanonicalPath
&impl_type_seg
)
69 return CanonicalPath::new_seg (id
, "<" + impl_type_seg
.get () + " as "
70 + trait_seg
.get () + ">");
73 static CanonicalPath
inherent_impl_seg (NodeId id
,
74 const CanonicalPath
&impl_type_seg
)
76 return CanonicalPath::new_seg (id
, "<" + impl_type_seg
.get () + ">");
79 std::string
get () const
82 for (size_t i
= 0; i
< segs
.size (); i
++)
84 bool have_more
= (i
+ 1) < segs
.size ();
85 const std::string
&seg
= segs
.at (i
).second
;
86 buf
+= seg
+ (have_more
? "::" : "");
91 static CanonicalPath
get_big_self (NodeId id
)
93 return CanonicalPath::new_seg (id
, "Self");
96 static CanonicalPath
create_empty ()
98 return CanonicalPath ({}, UNKNOWN_CRATENUM
);
101 bool is_empty () const { return segs
.size () == 0; }
103 CanonicalPath
append (const CanonicalPath
&other
) const
105 rust_assert (!other
.is_empty ());
107 return CanonicalPath (other
.segs
, crate_num
);
109 std::vector
<std::pair
<NodeId
, std::string
>> copy (segs
);
110 for (auto &s
: other
.segs
)
113 return CanonicalPath (copy
, crate_num
);
116 // if we have the path A::B::C this will give a callback for each segment
117 // including the prefix, example:
126 void iterate (std::function
<bool (const CanonicalPath
&)> cb
) const
128 std::vector
<std::pair
<NodeId
, std::string
>> buf
;
129 for (auto &seg
: segs
)
132 if (!cb (CanonicalPath (buf
, crate_num
)))
137 // if we have the path A::B::C this will give a callback for each segment
147 void iterate_segs (std::function
<bool (const CanonicalPath
&)> cb
) const
149 for (auto &seg
: segs
)
151 std::vector
<std::pair
<NodeId
, std::string
>> buf
;
152 buf
.push_back ({seg
.first
, seg
.second
});
153 if (!cb (CanonicalPath (buf
, crate_num
)))
158 size_t size () const { return segs
.size (); }
160 NodeId
get_node_id () const
162 rust_assert (!segs
.empty ());
163 return segs
.back ().first
;
166 const std::pair
<NodeId
, std::string
> &get_seg_at (size_t index
) const
168 rust_assert (index
< size ());
169 return segs
.at (index
);
172 bool is_equal (const CanonicalPath
&b
) const
174 return get ().compare (b
.get ()) == 0;
177 void set_crate_num (CrateNum n
) { crate_num
= n
; }
179 CrateNum
get_crate_num () const
181 rust_assert (crate_num
!= UNKNOWN_CRATENUM
);
185 bool operator== (const CanonicalPath
&b
) const { return is_equal (b
); }
187 bool operator< (const CanonicalPath
&b
) const { return get () < b
.get (); }
190 explicit CanonicalPath (std::vector
<std::pair
<NodeId
, std::string
>> path
,
192 : segs (path
), crate_num (crate_num
)
195 std::vector
<std::pair
<NodeId
, std::string
>> segs
;
199 } // namespace Resolver
202 #endif // RUST_CANONICAL_PATH