aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-forever-stack.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-forever-stack.h')
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h73
1 files changed, 61 insertions, 12 deletions
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 66e1266..81468e5 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -547,13 +547,18 @@ template <Namespace N> class ForeverStack
{
public:
ForeverStack ()
- // FIXME: Is that valid? Do we use the root? If yes, we should give the
- // crate's node id to ForeverStack's constructor
: root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
+ lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
+ extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)),
cursor_reference (root)
{
rust_assert (root.is_root ());
rust_assert (root.is_leaf ());
+
+ // TODO: Should we be using the forever stack root as the crate scope?
+ // TODO: Is this how we should be getting the crate node id?
+ auto &mappings = Analysis::Mappings::get ();
+ root.id = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
}
/**
@@ -588,6 +593,9 @@ public:
*/
tl::expected<NodeId, DuplicateNameError> insert (Identifier name, NodeId id);
+ tl::expected<NodeId, DuplicateNameError> insert_variant (Identifier name,
+ NodeId id);
+
/**
* Insert a new shadowable definition in the innermost `Rib` in this stack
*
@@ -651,6 +659,8 @@ public:
* the current map, an empty one otherwise.
*/
tl::optional<Rib::Definition> get (const Identifier &name);
+ tl::optional<Rib::Definition> get_lang_prelude (const Identifier &name);
+ tl::optional<Rib::Definition> get_lang_prelude (const std::string &name);
/**
* Resolve a path to its definition in the current `ForeverStack`
@@ -661,7 +671,10 @@ public:
* current map, an empty one otherwise.
*/
template <typename S>
- tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments);
+ tl::optional<Rib::Definition> resolve_path (
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors);
// FIXME: Documentation
tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id) const;
@@ -670,7 +683,7 @@ public:
tl::optional<Rib &> to_rib (NodeId rib_id);
tl::optional<const Rib &> to_rib (NodeId rib_id) const;
- std::string as_debug_string ();
+ std::string as_debug_string () const;
/**
* Used to check if a module is a descendant of another module
@@ -713,6 +726,7 @@ private:
{}
bool is_root () const;
+ bool is_prelude () const;
bool is_leaf () const;
void insert_child (Link link, Node child);
@@ -748,13 +762,25 @@ private:
const Node &cursor () const;
void update_cursor (Node &new_cursor);
+ /* The forever stack's actual nodes */
Node root;
+ /*
+ * A special prelude node used currently for resolving language builtins
+ * It has the root node as a parent, and acts as a "special case" for name
+ * resolution
+ */
+ Node lang_prelude;
+ /*
+ * The extern prelude, used for resolving external crates
+ */
+ Node extern_prelude;
+
std::reference_wrapper<Node> cursor_reference;
void stream_rib (std::stringstream &stream, const Rib &rib,
- const std::string &next, const std::string &next_next);
+ const std::string &next, const std::string &next_next) const;
void stream_node (std::stringstream &stream, unsigned indentation,
- const Node &node);
+ const Node &node) const;
/* Helper types and functions for `resolve_path` */
@@ -764,14 +790,22 @@ private:
Node &find_closest_module (Node &starting_point);
template <typename S>
- tl::optional<SegIterator<S>>
- find_starting_point (const std::vector<S> &segments,
- std::reference_wrapper<Node> &starting_point);
+ tl::optional<SegIterator<S>> find_starting_point (
+ const std::vector<S> &segments,
+ std::reference_wrapper<Node> &starting_point,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors);
template <typename S>
- tl::optional<Node &> resolve_segments (Node &starting_point,
- const std::vector<S> &segments,
- SegIterator<S> iterator);
+ tl::optional<Node &> resolve_segments (
+ Node &starting_point, const std::vector<S> &segments,
+ SegIterator<S> iterator,
+ std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::vector<Error> &collect_errors);
+
+ tl::optional<Rib::Definition> resolve_final_segment (Node &final_node,
+ std::string &seg_name,
+ bool is_lower_self);
/* Helper functions for forward resolution (to_canonical_path, to_rib...) */
struct DfsResult
@@ -797,6 +831,21 @@ private:
tl::optional<Node &> dfs_node (Node &starting_point, NodeId to_find);
tl::optional<const Node &> dfs_node (const Node &starting_point,
NodeId to_find) const;
+
+public:
+ bool forward_declared (NodeId definition, NodeId usage)
+ {
+ if (peek ().kind != Rib::Kind::ForwardTypeParamBan)
+ return false;
+
+ const auto &definition_rib = dfs_rib (cursor (), definition);
+
+ if (!definition_rib)
+ return false;
+
+ return (definition_rib
+ && definition_rib.value ().kind == Rib::Kind::ForwardTypeParamBan);
+ }
};
} // namespace Resolver2_0