#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 {
FromExtern, // extern prelude
};
+class ResolutionPath
+{
+public:
+ template <typename T>
+ ResolutionPath (const std::vector<T> &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<std::pair<LangItem::Kind, NodeId>> get_lang_prefix () const
+ {
+ return lang_prefix;
+ }
+
+ const std::vector<Segment> &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<std::pair<LangItem::Kind, NodeId>> lang_prefix;
+ std::vector<Segment> segments;
+ NodeId node_id;
+};
+
template <Namespace N> class ForeverStack
{
public:
* @return a valid option with the Definition if the path is present in the
* current map, an empty one otherwise.
*/
- template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors);
- template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors, NodeId starting_point_id);
// FIXME: Documentation
tl::optional<Rib::Definition> get (Node &start, const Identifier &name);
- template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors,
std::reference_wrapper<Node> starting_point);
/* Helper types and functions for `resolve_path` */
- template <typename S>
- using SegIterator = typename std::vector<S>::const_iterator;
+ using SegIterator =
+ typename std::vector<ResolutionPath::Segment>::const_iterator;
Node &find_closest_module (Node &starting_point);
- template <typename S>
- tl::optional<SegIterator<S>> find_starting_point (
- const std::vector<S> &segments,
+ tl::optional<SegIterator> find_starting_point (
+ const std::vector<ResolutionPath::Segment> &segments,
std::reference_wrapper<Node> &starting_point,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors);
- template <typename S>
tl::optional<Node &> resolve_segments (
- Node &starting_point, const std::vector<S> &segments,
- SegIterator<S> iterator,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ Node &starting_point, const std::vector<ResolutionPath::Segment> &segments,
+ SegIterator iterator,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors);
tl::optional<Rib::Definition> resolve_final_segment (Node &final_node,
/* If a the given condition is met, emit an error about misused leading path
* segments */
-template <typename S>
static inline bool
-check_leading_kw_at_start (std::vector<Error> &collect_errors, const S &segment,
+check_leading_kw_at_start (std::vector<Error> &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;
}
// `super` segment, we go back to the cursor's parent until we reach the
// correct one or the root.
template <Namespace N>
-template <typename S>
-tl::optional<typename std::vector<S>::const_iterator>
+tl::optional<typename std::vector<ResolutionPath::Segment>::const_iterator>
ForeverStack<N>::find_starting_point (
- const std::vector<S> &segments, std::reference_wrapper<Node> &starting_point,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const std::vector<ResolutionPath::Segment> &segments,
+ std::reference_wrapper<Node> &starting_point,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &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 ();
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;
}
{
// 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;
}
if (starting_point.get ().is_root ())
{
collect_errors.emplace_back (
- seg.get_locus (), ErrorCode::E0433,
+ seg.locus, ErrorCode::E0433,
"too many leading %<super%> keywords");
return tl::nullopt;
}
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;
}
}
template <Namespace N>
-template <typename S>
tl::optional<typename ForeverStack<N>::Node &>
ForeverStack<N>::resolve_segments (
- Node &starting_point, const std::vector<S> &segments,
- typename std::vector<S>::const_iterator iterator,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ Node &starting_point, const std::vector<ResolutionPath::Segment> &segments,
+ typename std::vector<ResolutionPath::Segment>::const_iterator iterator,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &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
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 ()
}
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;
}
}
// 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;
}
template <Namespace N>
-template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors, NodeId starting_point_id)
{
auto starting_point = dfs_node (root, starting_point_id);
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 <Namespace N>
-template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors)
{
std::reference_wrapper<Node> 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 <Namespace N>
-template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments, ResolutionMode mode,
- std::function<void (const S &, NodeId)> insert_segment_resolution,
+ const ResolutionPath &path, ResolutionMode mode,
+ std::function<void (Usage, Definition)> insert_segment_resolution,
std::vector<Error> &collect_errors,
std::reference_wrapper<Node> 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)
{
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<Rib::Definition> res
- = get (starting_point.get (), seg.as_string ());
+ tl::optional<Rib::Definition> 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);
}
= 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 %<super%> 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);
}
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);
}
}
}
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<S>::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<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 ();
+ auto &seg = segments.back ();
+ std::string seg_name = seg.name;
- // 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 ());
},
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;
});
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#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"
#include "rust-rib.h"
#include "rust-stacked-contexts.h"
#include "rust-item.h"
+#include "rust-name-resolution.h"
namespace Rust {
namespace Resolver2_0 {
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;
return canonical_ctx.get_path (id);
}
- template <typename S>
tl::optional<Rib::Definition>
- resolve_path (const std::vector<S> &segments, ResolutionMode mode,
+ resolve_path (const ResolutionPath &path, ResolutionMode mode,
std::vector<Error> &collect_errors, Namespace ns)
{
- std::function<void (const S &, NodeId)> 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<void (Usage, Definition)> 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<Rib::Definition> resolved = tl::nullopt;
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 ();
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 ();
return resolved;
}
+ class ResolutionBuilder
+ {
+ public:
+ ResolutionBuilder (NameResolutionContext &ctx) : ctx (&ctx) {}
+
+ template <typename S>
+ void set_path (const std::vector<S> &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 <typename S>
+ void set_path (const std::vector<S> &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 <typename... Args> void add_namespaces (Namespace ns, Args... rest)
+ {
+ add_namespaces (ns);
+ add_namespaces (rest...);
+ }
+
+ void set_collect_errors (tl::optional<std::vector<Error> &> collect_errors)
+ {
+ this->collect_errors = collect_errors;
+ }
+
+ tl::optional<Rib::Definition> resolve ()
+ {
+ rust_assert (has_path_set);
+
+ for (auto ns : namespace_list)
+ {
+ std::vector<Error> 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> namespace_list;
+
+ tl::optional<std::vector<Error> &> collect_errors;
+
+ NameResolutionContext *ctx;
+ };
+
template <typename S, typename... Args>
tl::optional<Rib::Definition>
- resolve_path (const std::vector<S> &segments, ResolutionMode mode,
+ resolve_path (const std::vector<S> &path_segments, ResolutionMode mode,
tl::optional<std::vector<Error> &> collect_errors,
Namespace ns_first, Args... ns_args)
{
- std::initializer_list<Namespace> 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<Error> 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 <typename S, typename... Args>
tl::optional<std::vector<Error> &> 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 <typename S, typename... Args>
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 <typename S, typename... Args>
resolve_path (const std::vector<S> &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 <typename... Args>
} // namespace Resolver2_0
} // namespace Rust
-#endif // ! RUST_NAME_RESOLVER_2_0_H
+#endif // ! RUST_NAME_RESOLVER_2_0_CTX_H
--- /dev/null
+// 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
+// <http://www.gnu.org/licenses/>.
+
+#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
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#ifndef RUST_UNWRAP_SEGMENT_H
+#define RUST_UNWRAP_SEGMENT_H
+
#include "rust-system.h"
#include "optional.h"
#include "rust-lang-item.h"
}
} // namespace Rust
+
+#endif // RUST_UNWRAP_SEGMENT_H