From: Owen Avery Date: Sat, 7 Feb 2026 01:11:20 +0000 (-0500) Subject: gccrs: Improve path resolution X-Git-Tag: basepoints/gcc-17~188 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b22b874feabc2f6f57fb2cb3798fc8bea48a461;p=thirdparty%2Fgcc.git gccrs: Improve path resolution This makes path resolution less dependent on templates for path handling. gcc/rust/ChangeLog: * resolve/rust-forever-stack.h: Include more headers. (class ResolutionPath): New class for representing paths. (ForeverStack::resolve_path): Change function signature. (ForeverStack::find_starting_point): Likewise. (ForeverStack::resolve_segments): Likewise. (ForeverStack::SegIterator): Change type alias. * resolve/rust-forever-stack.hxx (check_leading_kw_at_start): Change function signature. (ForeverStack::find_starting_point): Likewise. (ForeverStack::resolve_segments): Likewise. (ForeverStack::resolve_path): Likewise. * resolve/rust-name-resolution-context.h: Tweak include guard, include "rust-name-resolution.h". (NameResolutionContext::resolve_path): Use ResolutionPath and ResolutionBuilder. (class NameResolutionContext::ResolutionBuilder): New class. (class Usage): Move this... (class Definition): ...and this... * resolve/rust-name-resolution.h: ...to new file. * util/rust-unwrap-segment.h: Add include guard. Signed-off-by: Owen Avery --- diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index 309a0ccd630..f6e351a1c4f 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -25,6 +25,8 @@ #include "rust-path.h" #include "optional.h" #include "expected.h" +#include "rust-name-resolution.h" +#include "rust-unwrap-segment.h" namespace Rust { namespace Resolver2_0 { @@ -550,6 +552,74 @@ enum class ResolutionMode FromExtern, // extern prelude }; +class ResolutionPath +{ +public: + template + ResolutionPath (const std::vector &segments_in, NodeId node_id) + : node_id (node_id) + { + segments.clear (); + segments.reserve (segments_in.size ()); + for (auto &outer_seg : segments_in) + { + if (auto lang_item = unwrap_segment_get_lang_item (outer_seg)) + { + rust_assert (!lang_prefix.has_value ()); + lang_prefix = std::make_pair (lang_item.value (), + unwrap_segment_node_id (outer_seg)); + continue; + } + + auto &seg = unwrap_type_segment (outer_seg); + + Segment new_seg; + new_seg.name = seg.as_string (); + new_seg.node_id = unwrap_segment_node_id (outer_seg); + new_seg.locus = seg.get_locus (); + segments.push_back (std::move (new_seg)); + } + } + + ResolutionPath () : node_id (UNKNOWN_NODEID) {} + + struct Segment + { + std::string name; + NodeId node_id; + location_t locus; + + bool is_super_path_seg () const { return name.compare ("super") == 0; } + bool is_crate_path_seg () const { return name.compare ("crate") == 0; } + bool is_lower_self_seg () const { return name.compare ("self") == 0; } + bool is_big_self_seg () const { return name.compare ("Self") == 0; } + }; + + tl::optional> get_lang_prefix () const + { + return lang_prefix; + } + + const std::vector &get_segments () const { return segments; } + + NodeId get_node_id () const { return node_id; } + + std::string as_string () const + { + std::string ret; + if (lang_prefix) + ret = "#[lang]::"; + for (auto &seg : segments) + ret += "::" + seg.name; + return ret; + } + +private: + tl::optional> lang_prefix; + std::vector segments; + NodeId node_id; +}; + template class ForeverStack { public: @@ -687,15 +757,13 @@ public: * @return a valid option with the Definition if the path is present in the * current map, an empty one otherwise. */ - template tl::optional resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors); - template tl::optional resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors, NodeId starting_point_id); // FIXME: Documentation @@ -764,10 +832,9 @@ private: tl::optional get (Node &start, const Identifier &name); - template tl::optional resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors, std::reference_wrapper starting_point); @@ -817,23 +884,21 @@ private: /* Helper types and functions for `resolve_path` */ - template - using SegIterator = typename std::vector::const_iterator; + using SegIterator = + typename std::vector::const_iterator; Node &find_closest_module (Node &starting_point); - template - tl::optional> find_starting_point ( - const std::vector &segments, + tl::optional find_starting_point ( + const std::vector &segments, std::reference_wrapper &starting_point, - std::function insert_segment_resolution, + std::function insert_segment_resolution, std::vector &collect_errors); - template tl::optional resolve_segments ( - Node &starting_point, const std::vector &segments, - SegIterator iterator, - std::function insert_segment_resolution, + Node &starting_point, const std::vector &segments, + SegIterator iterator, + std::function insert_segment_resolution, std::vector &collect_errors); tl::optional resolve_final_segment (Node &final_node, diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 0f92a7f332a..c7c5c9439e4 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -431,16 +431,15 @@ ForeverStack::find_closest_module (Node &starting_point) /* If a the given condition is met, emit an error about misused leading path * segments */ -template static inline bool -check_leading_kw_at_start (std::vector &collect_errors, const S &segment, +check_leading_kw_at_start (std::vector &collect_errors, + const ResolutionPath::Segment &segment, bool condition) { if (condition) collect_errors.emplace_back ( - segment.get_locus (), ErrorCode::E0433, - "%qs in paths can only be used in start position", - segment.as_string ().c_str ()); + segment.locus, ErrorCode::E0433, + "%qs in paths can only be used in start position", segment.name.c_str ()); return condition; } @@ -451,23 +450,19 @@ check_leading_kw_at_start (std::vector &collect_errors, const S &segment, // `super` segment, we go back to the cursor's parent until we reach the // correct one or the root. template -template -tl::optional::const_iterator> +tl::optional::const_iterator> ForeverStack::find_starting_point ( - const std::vector &segments, std::reference_wrapper &starting_point, - std::function insert_segment_resolution, + const std::vector &segments, + std::reference_wrapper &starting_point, + std::function insert_segment_resolution, std::vector &collect_errors) { auto iterator = segments.begin (); for (; !is_last (iterator, segments); iterator++) { - auto &outer_seg = *iterator; + auto &seg = *iterator; - if (unwrap_segment_get_lang_item (outer_seg).has_value ()) - break; - - auto &seg = unwrap_type_segment (outer_seg); bool is_self_or_crate = seg.is_crate_path_seg () || seg.is_lower_self_seg (); @@ -481,7 +476,8 @@ ForeverStack::find_starting_point ( if (seg.is_crate_path_seg ()) { starting_point = root; - insert_segment_resolution (outer_seg, starting_point.get ().id); + insert_segment_resolution (Usage (seg.node_id), + Definition (starting_point.get ().id)); iterator++; break; } @@ -489,7 +485,8 @@ ForeverStack::find_starting_point ( { // insert segment resolution and exit starting_point = find_closest_module (starting_point); - insert_segment_resolution (outer_seg, starting_point.get ().id); + insert_segment_resolution (Usage (seg.node_id), + Definition (starting_point.get ().id)); iterator++; break; } @@ -499,7 +496,7 @@ ForeverStack::find_starting_point ( if (starting_point.get ().is_root ()) { collect_errors.emplace_back ( - seg.get_locus (), ErrorCode::E0433, + seg.locus, ErrorCode::E0433, "too many leading % keywords"); return tl::nullopt; } @@ -507,7 +504,8 @@ ForeverStack::find_starting_point ( starting_point = find_closest_module (starting_point.get ().parent.value ()); - insert_segment_resolution (outer_seg, starting_point.get ().id); + insert_segment_resolution (Usage (seg.node_id), + Definition (starting_point.get ().id)); continue; } @@ -521,31 +519,19 @@ ForeverStack::find_starting_point ( } template -template tl::optional::Node &> ForeverStack::resolve_segments ( - Node &starting_point, const std::vector &segments, - typename std::vector::const_iterator iterator, - std::function insert_segment_resolution, + Node &starting_point, const std::vector &segments, + typename std::vector::const_iterator iterator, + std::function insert_segment_resolution, std::vector &collect_errors) { Node *current_node = &starting_point; for (; !is_last (iterator, segments); iterator++) { - auto &outer_seg = *iterator; - - if (auto lang_item = unwrap_segment_get_lang_item (outer_seg)) - { - NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node ( - lang_item.value ()); - current_node = &dfs_node (root, seg_id).value (); + auto &seg = *iterator; - insert_segment_resolution (outer_seg, seg_id); - continue; - } - - auto &seg = unwrap_type_segment (outer_seg); - std::string str = seg.as_string (); + std::string str = seg.name; rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ()); // check that we don't encounter *any* leading keywords afterwards @@ -607,7 +593,7 @@ ForeverStack::resolve_segments ( break; } - auto rib_lookup = current_node->rib.get (seg.as_string ()); + auto rib_lookup = current_node->rib.get (seg.name); if (rib_lookup && !rib_lookup->is_ambiguous ()) { if (Analysis::Mappings::get () @@ -619,8 +605,9 @@ ForeverStack::resolve_segments ( } else { - insert_segment_resolution (outer_seg, - rib_lookup->get_node_id ()); + insert_segment_resolution (Usage (seg.node_id), + Definition ( + rib_lookup->get_node_id ())); return tl::nullopt; } } @@ -645,7 +632,8 @@ ForeverStack::resolve_segments ( // if child didn't point to a value // the while loop above would have returned or kept looping current_node = &child->get (); - insert_segment_resolution (outer_seg, current_node->id); + insert_segment_resolution (Usage (seg.node_id), + Definition (current_node->id)); } return *current_node; @@ -672,11 +660,10 @@ ForeverStack::resolve_final_segment (Node &final_node, std::string &seg_name, } template -template tl::optional ForeverStack::resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors, NodeId starting_point_id) { auto starting_point = dfs_node (root, starting_point_id); @@ -686,34 +673,56 @@ ForeverStack::resolve_path ( if (!starting_point) return tl::nullopt; - return resolve_path (segments, mode, insert_segment_resolution, - collect_errors, *starting_point); + return resolve_path (path, mode, insert_segment_resolution, collect_errors, + *starting_point); } template -template tl::optional ForeverStack::resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors) { std::reference_wrapper starting_point = cursor (); - return resolve_path (segments, mode, insert_segment_resolution, - collect_errors, starting_point); + return resolve_path (path, mode, insert_segment_resolution, collect_errors, + starting_point); } template -template tl::optional ForeverStack::resolve_path ( - const std::vector &segments, ResolutionMode mode, - std::function insert_segment_resolution, + const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, std::vector &collect_errors, std::reference_wrapper starting_point) { - rust_assert (!segments.empty ()); + bool can_descend = true; + + rust_debug ("resolving %s", path.as_string ().c_str ()); + + if (auto lang_item = path.get_lang_prefix ()) + { + NodeId seg_id + = Analysis::Mappings::get ().get_lang_item_node (lang_item->first); + + insert_segment_resolution (Usage (lang_item->second), + Definition (seg_id)); + + if (path.get_segments ().empty ()) + return Rib::Definition::NonShadowable (seg_id); + + auto new_start = dfs_node (root, seg_id); + rust_assert (new_start.has_value ()); + starting_point = new_start.value (); + + can_descend = false; + } + else + { + rust_assert (!path.get_segments ().empty ()); + } switch (mode) { @@ -729,40 +738,31 @@ ForeverStack::resolve_path ( rust_unreachable (); } + auto &segments = path.get_segments (); + // if there's only one segment, we just use `get` - if (segments.size () == 1) + if (can_descend && segments.size () == 1) { - auto &outer_seg = segments.front (); - if (auto lang_item = unwrap_segment_get_lang_item (outer_seg)) - { - NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node ( - lang_item.value ()); - - insert_segment_resolution (outer_seg, seg_id); - // TODO: does NonShadowable matter? - return Rib::Definition::NonShadowable (seg_id); - } + auto &seg = segments.front (); - auto &seg = unwrap_type_segment (outer_seg); - - tl::optional res - = get (starting_point.get (), seg.as_string ()); + tl::optional res = get (starting_point.get (), seg.name); if (!res) - res = get_lang_prelude (seg.as_string ()); + res = get_lang_prelude (seg.name); if (N == Namespace::Types && !res) { if (seg.is_crate_path_seg ()) { - insert_segment_resolution (outer_seg, root.id); + insert_segment_resolution (Usage (seg.node_id), + Definition (root.id)); // TODO: does NonShadowable matter? return Rib::Definition::NonShadowable (root.id); } else if (seg.is_lower_self_seg ()) { NodeId id = find_closest_module (starting_point.get ()).id; - insert_segment_resolution (outer_seg, id); + insert_segment_resolution (Usage (seg.node_id), Definition (id)); // TODO: does NonShadowable matter? return Rib::Definition::NonShadowable (id); } @@ -772,14 +772,14 @@ ForeverStack::resolve_path ( = find_closest_module (starting_point.get ()); if (closest_module.is_root ()) { - rust_error_at (seg.get_locus (), ErrorCode::E0433, + rust_error_at (seg.locus, ErrorCode::E0433, "too many leading % keywords"); return tl::nullopt; } NodeId id = find_closest_module (closest_module.parent.value ()).id; - insert_segment_resolution (outer_seg, id); + insert_segment_resolution (Usage (seg.node_id), Definition (id)); // TODO: does NonShadowable matter? return Rib::Definition::NonShadowable (id); } @@ -794,11 +794,12 @@ ForeverStack::resolve_path ( if (link.path.map_or ( [&seg] (Identifier path) { auto &path_str = path.as_string (); - return path_str == seg.as_string (); + return path_str == seg.name; }, false)) { - insert_segment_resolution (outer_seg, kv.second.id); + insert_segment_resolution (Usage (seg.node_id), + Definition (kv.second.id)); return Rib::Definition::NonShadowable (kv.second.id); } } @@ -806,28 +807,33 @@ ForeverStack::resolve_path ( } if (res && !res->is_ambiguous ()) - insert_segment_resolution (outer_seg, res->get_node_id ()); + insert_segment_resolution (Usage (seg.node_id), + Definition (res->get_node_id ())); return res; } - return find_starting_point (segments, starting_point, - insert_segment_resolution, collect_errors) - .and_then ( - [this, &segments, &starting_point, &insert_segment_resolution, - &collect_errors] (typename std::vector::const_iterator iterator) { - return resolve_segments (starting_point.get (), segments, iterator, - insert_segment_resolution, collect_errors); - }) + auto iterator = segments.begin (); + if (can_descend) + { + if (auto res + = find_starting_point (segments, starting_point, + insert_segment_resolution, collect_errors)) + iterator = *res; + else + return tl::nullopt; + } + + return resolve_segments (starting_point.get (), segments, iterator, + insert_segment_resolution, collect_errors) .and_then ([this, &segments, &insert_segment_resolution] ( Node &final_node) -> tl::optional { // 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 (); + auto &seg = segments.back (); + std::string seg_name = seg.name; - // assuming this can't be a lang item segment tl::optional res = resolve_final_segment (final_node, seg_name, seg.is_lower_self_seg ()); @@ -849,14 +855,16 @@ ForeverStack::resolve_path ( }, false)) { - insert_segment_resolution (segments.back (), kv.second.id); + insert_segment_resolution (Usage (seg.node_id), + Definition (kv.second.id)); return Rib::Definition::NonShadowable (kv.second.id); } } } if (res && !res->is_ambiguous ()) - insert_segment_resolution (segments.back (), res->get_node_id ()); + insert_segment_resolution (Usage (seg.node_id), + Definition (res->get_node_id ())); return res; }); diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 2d1ce3117b5..91eb0dcde75 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -16,8 +16,8 @@ // along with GCC; see the file COPYING3. If not see // . -#ifndef RUST_NAME_RESOLVER_2_0_H -#define RUST_NAME_RESOLVER_2_0_H +#ifndef RUST_NAME_RESOLVER_2_0_CTX_H +#define RUST_NAME_RESOLVER_2_0_CTX_H #include "optional.h" #include "rust-forever-stack.h" @@ -25,6 +25,7 @@ #include "rust-rib.h" #include "rust-stacked-contexts.h" #include "rust-item.h" +#include "rust-name-resolution.h" namespace Rust { namespace Resolver2_0 { @@ -136,28 +137,6 @@ change? correct */ -// FIXME: Documentation -class Usage -{ -public: - explicit Usage (NodeId id) : id (id) {} - - // TODO: move to name-resolution-ctx.cc - // storing it as a key in a map - bool operator< (const Usage other) const { return other.id < id; } - - NodeId id; -}; - -// FIXME: Documentation -class Definition -{ -public: - explicit Definition (NodeId id) : id (id) {} - - NodeId id; -}; - struct IdentifierMode { bool is_ref; @@ -549,16 +528,14 @@ public: return canonical_ctx.get_path (id); } - template tl::optional - resolve_path (const std::vector &segments, ResolutionMode mode, + resolve_path (const ResolutionPath &path, ResolutionMode mode, std::vector &collect_errors, Namespace ns) { - std::function insert_segment_resolution - = [this] (const S &seg, NodeId id) { - auto seg_id = unwrap_segment_node_id (seg); - if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ()) - map_usage (Usage (seg_id), Definition (id)); + std::function insert_segment_resolution + = [this] (Usage seg_id, Definition id) { + if (resolved_nodes.find (seg_id) == resolved_nodes.end ()) + map_usage (seg_id, id); }; tl::optional resolved = tl::nullopt; @@ -566,24 +543,20 @@ public: switch (ns) { case Namespace::Values: - resolved - = values.resolve_path (segments, mode, insert_segment_resolution, - collect_errors); + resolved = values.resolve_path (path, mode, insert_segment_resolution, + collect_errors); break; case Namespace::Types: - resolved - = types.resolve_path (segments, mode, insert_segment_resolution, - collect_errors); + resolved = types.resolve_path (path, mode, insert_segment_resolution, + collect_errors); break; case Namespace::Macros: - resolved - = macros.resolve_path (segments, mode, insert_segment_resolution, - collect_errors); + resolved = macros.resolve_path (path, mode, insert_segment_resolution, + collect_errors); break; case Namespace::Labels: - resolved - = labels.resolve_path (segments, mode, insert_segment_resolution, - collect_errors); + resolved = labels.resolve_path (path, mode, insert_segment_resolution, + collect_errors); break; default: rust_unreachable (); @@ -596,20 +569,16 @@ public: switch (ns) { case Namespace::Values: - return values.resolve_path (segments, mode, - insert_segment_resolution, + return values.resolve_path (path, mode, insert_segment_resolution, collect_errors, *prelude); case Namespace::Types: - return types.resolve_path (segments, mode, - insert_segment_resolution, + return types.resolve_path (path, mode, insert_segment_resolution, collect_errors, *prelude); case Namespace::Macros: - return macros.resolve_path (segments, mode, - insert_segment_resolution, + return macros.resolve_path (path, mode, insert_segment_resolution, collect_errors, *prelude); case Namespace::Labels: - return labels.resolve_path (segments, mode, - insert_segment_resolution, + return labels.resolve_path (path, mode, insert_segment_resolution, collect_errors, *prelude); default: rust_unreachable (); @@ -619,37 +588,122 @@ public: return resolved; } + class ResolutionBuilder + { + public: + ResolutionBuilder (NameResolutionContext &ctx) : ctx (&ctx) {} + + template + void set_path (const std::vector &path_segments, NodeId node_id, + bool has_opening_scope) + { + path = ResolutionPath (path_segments, node_id); + mode = ResolutionMode::Normal; + if (has_opening_scope) + { + if (get_rust_edition () == Edition::E2015) + mode = ResolutionMode::FromRoot; + else + mode = ResolutionMode::FromExtern; + } + has_path_set = true; + } + + template + void set_path (const std::vector &path_segments, NodeId node_id, + ResolutionMode mode) + { + path = ResolutionPath (path_segments, node_id); + this->mode = mode; + has_path_set = true; + } + + void set_path (const AST::SimplePath &path) + { + set_path (path.get_segments (), path.get_node_id (), + path.has_opening_scope_resolution ()); + } + + void set_path (const AST::PathInExpression &path) + { + set_path (path.get_segments (), path.get_node_id (), + path.opening_scope_resolution ()); + } + + void set_path (const AST::TypePath &path) + { + set_path (path.get_segments (), path.get_node_id (), + path.has_opening_scope_resolution_op ()); + } + + void set_mode (ResolutionMode mode) { this->mode = mode; } + + void add_namespaces (Namespace ns) { namespace_list.push_back (ns); } + + template void add_namespaces (Namespace ns, Args... rest) + { + add_namespaces (ns); + add_namespaces (rest...); + } + + void set_collect_errors (tl::optional &> collect_errors) + { + this->collect_errors = collect_errors; + } + + tl::optional resolve () + { + rust_assert (has_path_set); + + for (auto ns : namespace_list) + { + std::vector collect_errors_inner; + if (auto ret + = ctx->resolve_path (path, mode, collect_errors_inner, ns)) + return ret; + if (!collect_errors_inner.empty ()) + { + if (collect_errors.has_value ()) + { + std::move (collect_errors_inner.begin (), + collect_errors_inner.end (), + std::back_inserter (collect_errors.value ())); + } + else + { + for (auto &e : collect_errors_inner) + e.emit (); + } + } + } + + return tl::nullopt; + } + + private: + ResolutionPath path; + ResolutionMode mode; + bool has_path_set; + + std::vector namespace_list; + + tl::optional &> collect_errors; + + NameResolutionContext *ctx; + }; + template tl::optional - resolve_path (const std::vector &segments, ResolutionMode mode, + resolve_path (const std::vector &path_segments, ResolutionMode mode, tl::optional &> collect_errors, Namespace ns_first, Args... ns_args) { - std::initializer_list namespaces = {ns_first, ns_args...}; + ResolutionBuilder builder (*this); + builder.set_path (path_segments, UNKNOWN_NODEID, mode); + builder.add_namespaces (ns_first, ns_args...); + builder.set_collect_errors (collect_errors); - for (auto ns : namespaces) - { - std::vector collect_errors_inner; - if (auto ret = resolve_path (segments, mode, collect_errors_inner, ns)) - return ret; - if (!collect_errors_inner.empty ()) - { - if (collect_errors.has_value ()) - { - std::move (collect_errors_inner.begin (), - collect_errors_inner.end (), - std::back_inserter (collect_errors.value ())); - } - else - { - for (auto &e : collect_errors_inner) - e.emit (); - } - return tl::nullopt; - } - } - - return tl::nullopt; + return builder.resolve (); } template @@ -659,16 +713,13 @@ public: tl::optional &> collect_errors, Namespace ns_first, Args... ns_args) { - auto mode = ResolutionMode::Normal; - if (has_opening_scope_resolution) - { - if (get_rust_edition () == Edition::E2015) - mode = ResolutionMode::FromRoot; - else - mode = ResolutionMode::FromExtern; - } - return resolve_path (path_segments, mode, collect_errors, ns_first, - ns_args...); + ResolutionBuilder builder (*this); + builder.set_path (path_segments, UNKNOWN_NODEID, + has_opening_scope_resolution); + builder.add_namespaces (ns_first, ns_args...); + builder.set_collect_errors (collect_errors); + + return builder.resolve (); } template @@ -677,8 +728,12 @@ public: bool has_opening_scope_resolution, Namespace ns_first, Args... ns_args) { - return resolve_path (path_segments, has_opening_scope_resolution, - tl::nullopt, ns_first, ns_args...); + ResolutionBuilder builder (*this); + builder.set_path (path_segments, UNKNOWN_NODEID, + has_opening_scope_resolution); + builder.add_namespaces (ns_first, ns_args...); + + return builder.resolve (); } template @@ -686,8 +741,11 @@ public: resolve_path (const std::vector &path_segments, ResolutionMode mode, Namespace ns_first, Args... ns_args) { - return resolve_path (path_segments, mode, tl::nullopt, ns_first, - ns_args...); + ResolutionBuilder builder (*this); + builder.set_path (path_segments, UNKNOWN_NODEID, mode); + builder.add_namespaces (ns_first, ns_args...); + + return builder.resolve (); } template @@ -727,4 +785,4 @@ private: } // namespace Resolver2_0 } // namespace Rust -#endif // ! RUST_NAME_RESOLVER_2_0_H +#endif // ! RUST_NAME_RESOLVER_2_0_CTX_H diff --git a/gcc/rust/resolve/rust-name-resolution.h b/gcc/rust/resolve/rust-name-resolution.h new file mode 100644 index 00000000000..6d5b4ec874d --- /dev/null +++ b/gcc/rust/resolve/rust-name-resolution.h @@ -0,0 +1,50 @@ +// Copyright (C) 2026 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_NAME_RESOLVER_2_0_H +#define RUST_NAME_RESOLVER_2_0_H + +namespace Rust { +namespace Resolver2_0 { + +// FIXME: Documentation +class Usage +{ +public: + explicit Usage (NodeId id) : id (id) {} + + // TODO: move to name-resolution-ctx.cc + // storing it as a key in a map + bool operator< (const Usage other) const { return other.id < id; } + + NodeId id; +}; + +// FIXME: Documentation +class Definition +{ +public: + explicit Definition (NodeId id) : id (id) {} + + NodeId id; +}; + +} // namespace Resolver2_0 +} // namespace Rust + +#endif // RUST_NAME_RESOLVER_2_0_H diff --git a/gcc/rust/util/rust-unwrap-segment.h b/gcc/rust/util/rust-unwrap-segment.h index 7181bd25379..0bebe287152 100644 --- a/gcc/rust/util/rust-unwrap-segment.h +++ b/gcc/rust/util/rust-unwrap-segment.h @@ -16,6 +16,9 @@ // along with GCC; see the file COPYING3. If not see // . +#ifndef RUST_UNWRAP_SEGMENT_H +#define RUST_UNWRAP_SEGMENT_H + #include "rust-system.h" #include "optional.h" #include "rust-lang-item.h" @@ -136,3 +139,5 @@ unwrap_segment_error_string (const AST::PathInExpression &path) } } // namespace Rust + +#endif // RUST_UNWRAP_SEGMENT_H