aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-name-resolver.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-name-resolver.h')
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h88
1 files changed, 74 insertions, 14 deletions
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 9c01d47..205c877 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -26,6 +26,62 @@
namespace Rust {
namespace Resolver {
+// https://doc.rust-lang.org/reference/paths.html#canonical-paths
+//
+// struct X - path X
+// impl X { fn test - path X::test }
+//
+// struct X<T> - path X
+//
+// impl X<T> { fn test - path X::test}
+// impl X<i32> { fn test - path X<i32>::test }
+// impl X<f32> { fn test - path X<f32>::test }
+class CanonicalPath
+{
+public:
+ explicit CanonicalPath (std::string path) : path (path) {}
+
+ CanonicalPath (const CanonicalPath &other) : path (other.path) {}
+
+ CanonicalPath &operator= (const CanonicalPath &other)
+ {
+ path = other.path;
+ return *this;
+ }
+
+ std::string get () const { return path; }
+
+ static CanonicalPath get_big_self () { return CanonicalPath ("Self"); }
+
+ static CanonicalPath get_wee_self () { return CanonicalPath ("self"); }
+
+ static CanonicalPath create_empty ()
+ {
+ return CanonicalPath (std::string ());
+ }
+
+ bool is_error () const { return path.empty (); }
+
+ CanonicalPath append (const CanonicalPath &other) const
+ {
+ rust_assert (!other.is_error ());
+ return is_error () ? CanonicalPath (other.get ())
+ : CanonicalPath (append (other.get ()));
+ }
+
+ bool operator== (const CanonicalPath &b) const
+ {
+ return get ().compare (b.get ()) == 0;
+ }
+
+ bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
+
+private:
+ std::string append (std::string elem) const { return path + "::" + elem; }
+
+ std::string path;
+};
+
class Rib
{
public:
@@ -37,10 +93,11 @@ public:
~Rib () {}
- void insert_name (std::string ident, NodeId id, Location locus, bool shadow,
- std::function<void (std::string, NodeId, Location)> dup_cb)
+ void insert_name (
+ const CanonicalPath &path, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
{
- auto it = mappings.find (ident);
+ auto it = mappings.find (path);
bool already_exists = it != mappings.end ();
if (already_exists && !shadow)
{
@@ -48,20 +105,20 @@ public:
{
if (decl.first == it->second)
{
- dup_cb (ident, it->second, decl.second);
+ dup_cb (path, it->second, decl.second);
return;
}
}
- dup_cb (ident, it->second, locus);
+ dup_cb (path, it->second, locus);
return;
}
- mappings[ident] = id;
+ mappings[path] = id;
decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
references[id] = {};
}
- bool lookup_name (std::string ident, NodeId *id)
+ bool lookup_name (const CanonicalPath &ident, NodeId *id)
{
auto it = mappings.find (ident);
if (it == mappings.end ())
@@ -71,7 +128,7 @@ public:
return true;
}
- void clear_name (std::string ident, NodeId id)
+ void clear_name (const CanonicalPath &ident, NodeId id)
{
mappings.erase (ident);
for (auto &it : decls_within_rib)
@@ -136,7 +193,7 @@ public:
private:
CrateNum crate_num;
NodeId node_id;
- std::map<std::string, NodeId> mappings;
+ std::map<CanonicalPath, NodeId> mappings;
std::set<std::pair<NodeId, Location> > decls_within_rib;
std::map<NodeId, std::set<NodeId> > references;
};
@@ -145,21 +202,24 @@ class Scope
{
public:
Scope (CrateNum crate_num) : crate_num (crate_num) {}
+
~Scope () {}
- void insert (std::string ident, NodeId id, Location locus, bool shadow,
- std::function<void (std::string, NodeId, Location)> dup_cb)
+ void
+ insert (const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
{
peek ()->insert_name (ident, id, locus, shadow, dup_cb);
}
- void insert (std::string ident, NodeId id, Location locus)
+ void insert (const CanonicalPath &ident, NodeId id, Location locus)
{
peek ()->insert_name (ident, id, locus, true,
- [] (std::string, NodeId, Location) -> void {});
+ [] (const CanonicalPath &, NodeId, Location) -> void {
+ });
}
- bool lookup (std::string ident, NodeId *id)
+ bool lookup (const CanonicalPath &ident, NodeId *id)
{
NodeId lookup = UNKNOWN_NODEID;
iterate ([&] (Rib *r) mutable -> bool {