aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2025-03-24 22:49:12 -0400
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2025-04-01 09:19:04 +0000
commitbdfdaef9069a557ac47384c1a845a9e3dcf02ccc (patch)
tree69bcece9c064f5911ef0019aadbb693ec518dbb1
parentb8ef598308e7bd08fb40651bf4c17490ccbb855f (diff)
downloadgcc-bdfdaef9069a557ac47384c1a845a9e3dcf02ccc.zip
gcc-bdfdaef9069a557ac47384c1a845a9e3dcf02ccc.tar.gz
gcc-bdfdaef9069a557ac47384c1a845a9e3dcf02ccc.tar.bz2
nr2.0: Handle global paths
gcc/rust/ChangeLog: * resolve/rust-forever-stack.h (ForeverStack::ForeverStack): Initialize extern_prelude. (ForeverStack::resolve_path): Add parameter has_opening_scope_resolution. (ForeverStack::extern_prelude): Add field. * resolve/rust-forever-stack.hxx: Include rust-edition.h. (ForeverStacl::resolve_path): Handle global paths (paths with an opening scope resolution operator). * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Handle global paths. * resolve/rust-name-resolution-context.h (NameResolutionContext::resolve_path): Handle global paths. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: Remove entries. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h7
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx79
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc18
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h41
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude2
5 files changed, 96 insertions, 51 deletions
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 0f6ad95..d4b4ead 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -549,6 +549,7 @@ public:
ForeverStack ()
: 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 ());
@@ -671,7 +672,7 @@ public:
*/
template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments,
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
std::function<void (const S &, NodeId)> insert_segment_resolution);
// FIXME: Documentation
@@ -768,6 +769,10 @@ private:
* resolution
*/
Node lang_prelude;
+ /*
+ * The extern prelude, used for resolving external crates
+ */
+ Node extern_prelude;
std::reference_wrapper<Node> cursor_reference;
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index a8b8f98..e9024b5 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -20,6 +20,7 @@
#include "rust-ast.h"
#include "rust-diagnostics.h"
#include "rust-forever-stack.h"
+#include "rust-edition.h"
#include "rust-rib.h"
#include "rust-unwrap-segment.h"
#include "optional.h"
@@ -618,11 +619,24 @@ template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments,
+ const std::vector<S> &segments, bool has_opening_scope_resolution,
std::function<void (const S &, NodeId)> insert_segment_resolution)
{
// TODO: What to do if segments.empty() ?
+ // handle paths with opening scopes
+ std::function<void (void)> cleanup_current = [] () {};
+ if (has_opening_scope_resolution)
+ {
+ Node *last_current = &cursor_reference.get ();
+ if (get_rust_edition () == Edition::E2015)
+ cursor_reference = root;
+ else
+ cursor_reference = extern_prelude;
+ cleanup_current
+ = [this, last_current] () { cursor_reference = *last_current; };
+ }
+
// if there's only one segment, we just use `get`
if (segments.size () == 1)
{
@@ -633,6 +647,7 @@ ForeverStack<N>::resolve_path (
lang_item.value ());
insert_segment_resolution (seg, seg_id);
+ cleanup_current ();
// TODO: does NonShadowable matter?
return Rib::Definition::NonShadowable (seg_id);
}
@@ -646,40 +661,44 @@ ForeverStack<N>::resolve_path (
if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
+ cleanup_current ();
return res;
}
std::reference_wrapper<Node> starting_point = cursor ();
- return find_starting_point (segments, starting_point,
- insert_segment_resolution)
- .and_then ([this, &segments, &starting_point, &insert_segment_resolution] (
- typename std::vector<S>::const_iterator iterator) {
- return resolve_segments (starting_point.get (), segments, iterator,
- insert_segment_resolution);
- })
- .and_then ([this, &segments, &insert_segment_resolution] (
- Node final_node) -> tl::optional<Rib::Definition> {
- // leave resolution within impl blocks to type checker
- if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
- return tl::nullopt;
-
- auto &seg = unwrap_type_segment (segments.back ());
- std::string seg_name = seg.as_string ();
-
- // assuming this can't be a lang item segment
- tl::optional<Rib::Definition> res
- = resolve_final_segment (final_node, seg_name,
- seg.is_lower_self_seg ());
- // Ok we didn't find it in the rib, Lets try the prelude...
- if (!res)
- res = get_lang_prelude (seg_name);
-
- if (res && !res->is_ambiguous ())
- insert_segment_resolution (segments.back (), res->get_node_id ());
-
- return res;
- });
+ auto res
+ = find_starting_point (segments, starting_point, insert_segment_resolution)
+ .and_then (
+ [this, &segments, &starting_point, &insert_segment_resolution] (
+ typename std::vector<S>::const_iterator iterator) {
+ return resolve_segments (starting_point.get (), segments, iterator,
+ insert_segment_resolution);
+ })
+ .and_then ([this, &segments, &insert_segment_resolution] (
+ Node final_node) -> tl::optional<Rib::Definition> {
+ // leave resolution within impl blocks to type checker
+ if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
+ return tl::nullopt;
+
+ auto &seg = unwrap_type_segment (segments.back ());
+ std::string seg_name = seg.as_string ();
+
+ // assuming this can't be a lang item segment
+ tl::optional<Rib::Definition> res
+ = resolve_final_segment (final_node, seg_name,
+ seg.is_lower_self_seg ());
+ // Ok we didn't find it in the rib, Lets try the prelude...
+ if (!res)
+ res = get_lang_prelude (seg_name);
+
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+
+ return res;
+ });
+ cleanup_current ();
+ return res;
}
template <Namespace N>
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index d685826..bf5f9d0 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -307,8 +307,7 @@ Late::visit (AST::PathInExpression &expr)
return;
}
- auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values,
- Namespace::Types);
+ auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
if (!resolved)
{
@@ -340,13 +339,9 @@ Late::visit (AST::TypePath &type)
DefaultResolver::visit (type);
- // take care of only simple cases
- // TODO: remove this?
- rust_assert (!type.has_opening_scope_resolution_op ());
-
// this *should* mostly work
// TODO: make sure typepath-like path resolution (?) is working
- auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types);
+ auto resolved = ctx.resolve_path (type, Namespace::Types);
if (!resolved.has_value ())
{
@@ -394,8 +389,7 @@ Late::visit (AST::StructExprStruct &s)
visit_inner_attrs (s);
DefaultResolver::visit (s.get_struct_name ());
- auto resolved
- = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
@@ -409,8 +403,7 @@ Late::visit (AST::StructExprStructBase &s)
DefaultResolver::visit (s.get_struct_name ());
visit (s.get_struct_base ());
- auto resolved
- = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
@@ -427,8 +420,7 @@ Late::visit (AST::StructExprStructFields &s)
for (auto &field : s.get_fields ())
visit (field);
- auto resolved
- = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
+ auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index d21b868..bb5590e 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -221,6 +221,7 @@ public:
template <typename S>
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
Namespace ns)
{
std::function<void (const S &, NodeId)> insert_segment_resolution
@@ -232,13 +233,17 @@ public:
switch (ns)
{
case Namespace::Values:
- return values.resolve_path (segments, insert_segment_resolution);
+ return values.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Types:
- return types.resolve_path (segments, insert_segment_resolution);
+ return types.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Macros:
- return macros.resolve_path (segments, insert_segment_resolution);
+ return macros.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
case Namespace::Labels:
- return labels.resolve_path (segments, insert_segment_resolution);
+ return labels.resolve_path (segments, has_opening_scope_resolution,
+ insert_segment_resolution);
default:
rust_unreachable ();
}
@@ -246,19 +251,45 @@ public:
template <typename S, typename... Args>
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ bool has_opening_scope_resolution,
Args... ns_args)
{
std::initializer_list<Namespace> namespaces = {ns_args...};
for (auto ns : namespaces)
{
- if (auto ret = resolve_path (segments, ns))
+ if (auto ret
+ = resolve_path (segments, has_opening_scope_resolution, ns))
return ret;
}
return tl::nullopt;
}
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution (), ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (), path.opening_scope_resolution (),
+ ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path,
+ Args... ns_args)
+ {
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution_op (), ns_args...);
+ }
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index 19bf6f8..ca72571 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -21,8 +21,6 @@ issue-266.rs
derive_clone_enum3.rs
derive-debug1.rs
derive-default1.rs
-issue-3402-1.rs
-issue-3403.rs
derive-eq-invalid.rs
derive-hash1.rs
torture/alt_patterns1.rs