aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-name-resolver.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-06-03 15:12:00 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-06-10 17:09:34 +0100
commit7ca7362602d4e827ecbc39d5cfdf56df9044633b (patch)
tree7e149ddc7c9ffb0f72bcd4be2459abc7d1ee688a /gcc/rust/resolve/rust-name-resolver.h
parentfc3ef6c4b1fad0d88a65043df8102437416b1df3 (diff)
downloadgcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.zip
gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.gz
gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.bz2
This patch implements complex Path resolution
This patch completely reimplements our name resolution process for Paths in general. This patch gets rid of the old Resolver::Definition structures which were used so that we can map patterns back to LetStmts and establish an hierarchy of nodes. This was not nessecary and complicated name/type resolution. TypePaths and PathInExpression are similar but have a slightl tweak in the order they lookup the relevant scopes for types. But overall work the same. There are several cases of paths you must consider in type resolution: - i32 (simple type path) - Self::A (associated type reference) - mod::foo::impl_item() (reference to impl item) - super::foo (reference to impl item) - crate::foo - T::bound() In name resolution we cannot always fully resolve a path but have to rely on the type-resolution to fully resolve a path as it may require careful thought. For example a path like: mod::foo::item() might be for a generic foo<T>(), which might have two specialized impl blocks so the best the name resolution can do is resolve mod::foo then leave it up to the type resolution to figure out which item this is. We might have i32 which is just a simple lookup. Apart from that this patch introduces a module parent child hierachy so that on paths such as super::foo we resolve super to be our parent module scope then foo can be resolved with the lookup in the items for that module. More over this patch gets rid of some but not all of the awkward name canonicalization to try and patch paths directly. More cleanup is still needed here to make the name resolution step easier to read. This was notable in the Qualified path handling where we can now rely on the type resolver to setup the associated types properly rather than the name resolver requiring us to resolve this directly. Fixes #1251 #1230 Addresses #1227 #1153
Diffstat (limited to 'gcc/rust/resolve/rust-name-resolver.h')
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h47
1 files changed, 14 insertions, 33 deletions
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 23a9d82..6b611b2 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -73,11 +73,13 @@ public:
bool lookup (const CanonicalPath &ident, NodeId *id);
void iterate (std::function<bool (Rib *)> cb);
+ void iterate (std::function<bool (const Rib *)> cb) const;
Rib *peek ();
void push (NodeId id);
Rib *pop ();
+ bool decl_was_declared_here (NodeId def) const;
void append_reference_for_def (NodeId refId, NodeId defId);
CrateNum get_crate_num () const { return crate_num; }
@@ -87,32 +89,6 @@ private:
std::vector<Rib *> stack;
};
-// This can map simple NodeIds for names to their parent node
-// for example:
-//
-// var x = y + 1;
-//
-// say y has node id=1 and the plus_expression has id=2
-// then the Definition will have
-// Definition { node=1, parent=2 }
-// this will be used later to gather the ribs for the type inferences context
-//
-// if parent is UNKNOWN_NODEID then this is a root declaration
-// say the var_decl hasa node_id=4;
-// the parent could be a BLOCK_Expr node_id but lets make it UNKNOWN_NODE_ID
-// so we know when it terminates
-struct Definition
-{
- NodeId node;
- NodeId parent;
- // add kind ?
-
- bool is_equal (const Definition &other)
- {
- return node == other.node && parent == other.parent;
- }
-};
-
class Resolver
{
public:
@@ -136,9 +112,6 @@ public:
bool find_label_rib (NodeId id, Rib **rib);
bool find_macro_rib (NodeId id, Rib **rib);
- void insert_new_definition (NodeId id, Definition def);
- bool lookup_definition (NodeId id, Definition *def);
-
void insert_resolved_name (NodeId refId, NodeId defId);
bool lookup_resolved_name (NodeId refId, NodeId *defId);
@@ -183,6 +156,18 @@ public:
return current_module_stack.back ();
}
+ NodeId peek_crate_module_scope () const
+ {
+ rust_assert (!current_module_stack.empty ());
+ return current_module_stack.front ();
+ }
+
+ NodeId peek_parent_module_scope () const
+ {
+ rust_assert (current_module_stack.size () > 1);
+ return current_module_stack.at (current_module_stack.size () - 2);
+ }
+
private:
Resolver ();
@@ -207,10 +192,6 @@ private:
std::map<NodeId, Rib *> label_ribs;
std::map<NodeId, Rib *> macro_ribs;
- // map any Node to its Definition
- // ie any name or type usage
- std::map<NodeId, Definition> name_definitions;
-
// Rust uses DefIds to namespace these under a crate_num
// but then it uses the def_collector to assign local_defids
// to each ast node as well. not sure if this is going to fit