Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ForeverStack APIs for Name Resolution 2.0 #2739

Merged
2 changes: 1 addition & 1 deletion gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ TokenCollector::visit (SimplePathSegment &segment)
{
push (Rust::Token::make (SUPER, segment.get_locus ()));
}
else if (segment.is_lower_self ())
else if (segment.is_lower_self_seg ())
{
push (Rust::Token::make (SELF, segment.get_locus ()));
}
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ class SimplePathSegment : public PathSegment
{
return as_string ().compare ("crate") == 0;
}
bool is_lower_self () const { return as_string ().compare ("self") == 0; }
bool is_lower_self_seg () const { return as_string ().compare ("self") == 0; }
bool is_big_self () const { return as_string ().compare ("Self") == 0; }
Comment on lines +402 to 403
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sure why is_lower_self got renamed, shouldn't is_big_self be renamed too ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is for using them in a templated function, so that the API is consistent with other Path-like nodes. I think changing is_big_self also makes sense

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should fix this in another PR though, I'm not sure about any potential conflicts or anything later down the line

};

Expand Down
9 changes: 9 additions & 0 deletions gcc/rust/ast/rust-path.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ class PathExprSegment
{
return !has_generic_args () && get_ident_segment ().is_crate_segment ();
}

bool is_lower_self_seg () const
{
return !has_generic_args () && get_ident_segment ().is_lower_self ();
Expand Down Expand Up @@ -646,6 +647,14 @@ class PathInExpression : public PathPattern, public PathExpr
outer_attrs = std::move (new_attrs);
}

NodeId get_pattern_node_id () const { return get_node_id (); }

PathExprSegment &get_final_segment () { return get_segments ().back (); }
const PathExprSegment &get_final_segment () const
{
return get_segments ().back ();
}

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/resolve/rust-ast-resolve-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ ResolveItem::visit (AST::UseDeclaration &use_item)
if (!ok)
continue;

const AST::SimplePathSegment &final_seg = path.get_final_segment ();
const AST::SimplePathSegment &final_seg = path.get_segments ().back ();

auto decl
= CanonicalPath::new_seg (resolved_node_id, final_seg.as_string ());
Expand Down
6 changes: 2 additions & 4 deletions gcc/rust/resolve/rust-ast-resolve-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,8 @@ ResolvePath::resolve_path (AST::SimplePath *expr)
// is_first_segment ? "true" : "false",
// is_final_segment ? "true" : "false");
if (resolved_node_id == UNKNOWN_NODEID && !is_first_segment
&& is_final_segment && segment.is_lower_self ())
{
resolved_node_id = previous_resolved_node_id;
}
&& is_final_segment && segment.is_lower_self_seg ())
resolved_node_id = previous_resolved_node_id;

// final check
if (resolved_node_id == UNKNOWN_NODEID)
Expand Down
8 changes: 5 additions & 3 deletions gcc/rust/resolve/rust-early-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Early::visit (AST::MacroInvocation &invoc)
// we won't have changed `definition` from `nullopt` if there are more
// than one segments in our path
if (!definition.has_value ())
definition = ctx.macros.resolve_path (path);
definition = ctx.macros.resolve_path (path.get_segments ());

// if the definition still does not have a value, then it's an error
if (!definition.has_value ())
Expand Down Expand Up @@ -188,7 +188,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto traits = attr.get_traits_to_derive ();
for (auto &trait : traits)
{
auto definition = ctx.macros.resolve_path (trait.get ());
auto definition
= ctx.macros.resolve_path (trait.get ().get_segments ());
if (!definition.has_value ())
{
// FIXME: Change to proper error message
Expand All @@ -210,7 +211,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
->lookup_builtin (name)
.is_error ()) // Do not resolve builtins
{
auto definition = ctx.macros.resolve_path (attr.get_path ());
auto definition
= ctx.macros.resolve_path (attr.get_path ().get_segments ());
if (!definition.has_value ())
{
// FIXME: Change to proper error message
Expand Down
49 changes: 37 additions & 12 deletions gcc/rust/resolve/rust-forever-stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,10 @@ template <Namespace N> class ForeverStack
{
public:
ForeverStack ()
: root (Node (Rib (Rib::Kind::Normal))), cursor_reference (root)
// 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)),
cursor_reference (root)
{
rust_assert (root.is_root ());
rust_assert (root.is_leaf ());
Expand Down Expand Up @@ -470,10 +473,19 @@ template <Namespace N> class ForeverStack
/**
* Resolve a path to its definition in the current `ForeverStack`
*
* // TODO: Add documentation for `segments`
*
* @return a valid option with the NodeId if the path is present in the
* current map, an empty one otherwise.
*/
tl::optional<NodeId> resolve_path (const AST::SimplePath &path);
template <typename S>
tl::optional<NodeId> resolve_path (const std::vector<S> &segments);

// FIXME: Documentation
tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id);

// FIXME: Documentation
tl::optional<Rib &> to_rib (NodeId rib_id);

std::string as_debug_string ();

Expand Down Expand Up @@ -506,8 +518,10 @@ template <Namespace N> class ForeverStack
class Node
{
public:
Node (Rib rib) : rib (rib) {}
Node (Rib rib, Node &parent) : rib (rib), parent (parent) {}
Node (Rib rib, NodeId id) : rib (rib), id (id) {}
Node (Rib rib, NodeId id, Node &parent)
: rib (rib), id (id), parent (parent)
{}

bool is_root () const;
bool is_leaf () const;
Expand All @@ -517,6 +531,8 @@ template <Namespace N> class ForeverStack
Rib rib; // this is the "value" of the node - the data it keeps.
std::map<Link, Node, LinkCmp> children; // all the other nodes it links to

NodeId id; // The node id of the Node's scope

tl::optional<Node &> parent; // `None` only if the node is a root
};

Expand Down Expand Up @@ -550,18 +566,27 @@ template <Namespace N> class ForeverStack

/* Helper types and functions for `resolve_path` */

using SegIterator = std::vector<AST::SimplePathSegment>::const_iterator;
template <typename S>
using SegIterator = typename std::vector<S>::const_iterator;

Node &find_closest_module (Node &starting_point);

tl::optional<SegIterator>
find_starting_point (const std::vector<AST::SimplePathSegment> &segments,
Node &starting_point);
template <typename S>
tl::optional<SegIterator<S>>
find_starting_point (const std::vector<S> &segments, Node &starting_point);

template <typename S>
tl::optional<Node &> resolve_segments (Node &starting_point,
const std::vector<S> &segments,
SegIterator<S> iterator);

/* Helper functions for forward resolution (to_canonical_path, to_rib...) */

tl::optional<Node &>
resolve_segments (Node &starting_point,
const std::vector<AST::SimplePathSegment> &segments,
SegIterator iterator);
// FIXME: Documentation
tl::optional<std::pair<Node &, std::string>> dfs (Node &starting_point,
NodeId to_find);
// FIXME: Documentation
tl::optional<Rib &> dfs_rib (Node &starting_point, NodeId to_find);
};

} // namespace Resolver2_0
Expand Down
Loading