diff options
Diffstat (limited to 'gcc/rust/resolve/rust-forever-stack.hxx')
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.hxx | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 885f282..993e2d4 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> |