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
)
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
)},
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
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
? "::" : "");
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 ());
106 return CanonicalPath (other
.segs
, crate_num
);
108 std::vector
<std::pair
<NodeId
, std::string
>> copy (segs
);
109 for (auto &s
: other
.segs
)
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:
125 void iterate (std::function
<bool (const CanonicalPath
&)> cb
) const
127 std::vector
<std::pair
<NodeId
, std::string
>> buf
;
128 for (auto &seg
: segs
)
131 if (!cb (CanonicalPath (buf
, crate_num
)))
136 // if we have the path A::B::C this will give a callback for each segment
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
)))
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
);
184 bool operator== (const CanonicalPath
&b
) const { return is_equal (b
); }
186 bool operator< (const CanonicalPath
&b
) const { return get () < b
.get (); }
189 explicit CanonicalPath (std::vector
<std::pair
<NodeId
, std::string
>> path
,
191 : segs (path
), crate_num (crate_num
)
194 std::vector
<std::pair
<NodeId
, std::string
>> segs
;
198 } // namespace Resolver
201 #endif // RUST_CANONICAL_PATH