From: Owen Avery <powerboat9.ga...@gmail.com> 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.ga...@gmail.com> --- gcc/rust/resolve/rust-forever-stack.h | 7 +- gcc/rust/resolve/rust-forever-stack.hxx | 79 ++++++++++++------- .../resolve/rust-late-name-resolver-2.0.cc | 18 ++--- .../resolve/rust-name-resolution-context.h | 41 ++++++++-- gcc/testsuite/rust/compile/nr2/exclude | 2 - 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 f390e3889df..cf0265140de 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 885f2820684..993e2d4fd2a 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 7d323745edb..d18e7e2a324 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 ea81bdeed54..84c0800ac4a 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 19bf6f8f609..ca725719196 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 -- 2.49.0