aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-ast-resolve-path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve-path.cc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc558
1 files changed, 0 insertions, 558 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
deleted file mode 100644
index fb6715d..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright (C) 2020-2024 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/>.
-
-#include "rust-ast-resolve-path.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-hir-map.h"
-#include "rust-path.h"
-
-namespace Rust {
-namespace Resolver {
-
-ResolvePath::ResolvePath () : ResolverBase () {}
-
-NodeId
-ResolvePath::go (AST::PathInExpression &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (expr);
-}
-
-NodeId
-ResolvePath::go (AST::QualifiedPathInExpression &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (expr);
-}
-
-NodeId
-ResolvePath::go (AST::SimplePath &expr)
-{
- ResolvePath resolver;
- return resolver.resolve_path (expr);
-}
-
-NodeId
-ResolvePath::resolve_path (AST::PathInExpression &expr)
-{
- if (expr.is_lang_item ())
- return Analysis::Mappings::get ().get_lang_item_node (
- expr.get_lang_item ());
-
- NodeId resolved_node_id = UNKNOWN_NODEID;
- NodeId module_scope_id = resolver->peek_current_module_scope ();
- NodeId previous_resolved_node_id = module_scope_id;
- for (size_t i = 0; i < expr.get_segments ().size (); i++)
- {
- auto &segment = expr.get_segments ().at (i);
- const AST::PathIdentSegment &ident_seg = segment.get_ident_segment ();
- bool is_first_segment = i == 0;
- resolved_node_id = UNKNOWN_NODEID;
-
- bool in_middle_of_path = i > 0;
- if (in_middle_of_path && segment.is_lower_self_seg ())
- {
- rust_error_at (segment.get_locus (), ErrorCode::E0433,
- "%qs in paths can only be used in start position",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
-
- NodeId crate_scope_id = resolver->peek_crate_module_scope ();
- if (segment.is_crate_path_seg ())
- {
- // what is the current crate scope node id?
- module_scope_id = crate_scope_id;
- previous_resolved_node_id = module_scope_id;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == module_scope_id);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
- continue;
- }
- else if (segment.is_super_path_seg ())
- {
- if (module_scope_id == crate_scope_id)
- {
- rust_error_at (segment.get_locus (),
- "cannot use %<super%> at the crate scope");
- return UNKNOWN_NODEID;
- }
-
- module_scope_id = resolver->peek_parent_module_scope ();
- previous_resolved_node_id = module_scope_id;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == module_scope_id);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
- continue;
- }
-
- // resolve any generic args
- if (segment.has_generic_args ())
- ResolveGenericArgs::go (segment.get_generic_args ());
-
- // logic is awkward here there are a few cases
- //
- // T::Default
- // mod::foo::impl_item
- // super::super::module::item
- // self
- // self::foo
- // self::foo::baz
- //
- // T::Default we can only resolve the T and cant do anything about Default
- // its dependant on associated types
- //
- // mod::foo::impl_item
- // we can resolve mod::foo but nothing about impl_item but we need to
- // _always resolve generic arguments
- //
- // self is a simple single lookup
- //
- // we have module_scope_id for the next module_scope to lookup
- // resolved_node_id is the thing we have resolve this segment to
- //
- // new algo?
- // we can only use module resolution when the previous segment is either
- // unknown or equal to this module_scope_id
- //
- // can only use old resolution when previous segment is unkown
-
- if (is_first_segment)
- {
- // name scope first
- NodeId resolved_node = UNKNOWN_NODEID;
- const CanonicalPath path
- = CanonicalPath::new_seg (segment.get_node_id (),
- ident_seg.as_string ());
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
- resolved_node_id = resolved_node;
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (path, &resolved_node))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
- resolved_node_id = resolved_node;
- }
- else if (segment.is_lower_self_seg ())
- {
- module_scope_id = crate_scope_id;
- previous_resolved_node_id = module_scope_id;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == module_scope_id);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
- continue;
- }
- else
- {
- // no error handling here since we might be able to resolve via
- // the module hierarchy and handle errors at the end
- }
- }
-
- if (resolved_node_id == UNKNOWN_NODEID
- && previous_resolved_node_id == module_scope_id)
- {
- tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id,
- ident_seg.as_string ());
- if (resolved_child.has_value ())
- {
- NodeId resolved_node = resolved_child->get_node_id ();
- if (resolver->get_name_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
- }
- else if (resolver->get_type_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_type (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
- }
- else
- {
- rust_error_at (segment.get_locus (),
- "Cannot find path %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
- }
-
- bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
- if (did_resolve_segment)
- {
- if (mappings.node_is_module (resolved_node_id)
- || mappings.node_is_crate (resolved_node_id))
- {
- module_scope_id = resolved_node_id;
- }
- previous_resolved_node_id = resolved_node_id;
- }
- else if (is_first_segment)
- {
- rust_error_at (segment.get_locus (), ErrorCode::E0433,
- "Cannot find path %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
-
- resolved_node = resolved_node_id;
- if (resolved_node_id != UNKNOWN_NODEID)
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_name (expr.get_node_id (), &existing);
-
- if (ok)
- rust_assert (existing == resolved_node_id);
- else
- resolver->insert_resolved_name (expr.get_node_id (),
- resolved_node_id);
- }
- // check the type scope
- else if (resolver->get_type_scope ().decl_was_declared_here (
- resolved_node_id))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_type (expr.get_node_id (), &existing);
-
- if (ok)
- rust_assert (existing == resolved_node_id);
- else
- resolver->insert_resolved_type (expr.get_node_id (),
- resolved_node_id);
- }
- else
- {
- rust_unreachable ();
- }
- }
- return resolved_node_id;
-}
-
-NodeId
-ResolvePath::resolve_path (AST::QualifiedPathInExpression &expr)
-{
- auto &root_segment = expr.get_qualified_path_type ();
- ResolveType::go (root_segment.get_type ());
- if (root_segment.has_as_clause ())
- ResolveType::go (root_segment.get_as_type_path ());
-
- for (auto &segment : expr.get_segments ())
- {
- // we cant actually do anything with the segment itself since this is all
- // the job of the type system to figure it out but we can resolve any
- // generic arguments used
- if (segment.has_generic_args ())
- ResolveGenericArgs::go (segment.get_generic_args ());
- }
-
- // cannot fully resolve a qualified path as it is dependant on associated
- // items
- return UNKNOWN_NODEID;
-}
-
-NodeId
-ResolvePath::resolve_path (AST::SimplePath &expr)
-{
- NodeId crate_scope_id = resolver->peek_crate_module_scope ();
- NodeId module_scope_id = resolver->peek_current_module_scope ();
-
- NodeId previous_resolved_node_id = UNKNOWN_NODEID;
- NodeId resolved_node_id = UNKNOWN_NODEID;
- for (size_t i = 0; i < expr.get_segments ().size (); i++)
- {
- AST::SimplePathSegment &segment = expr.get_segments ().at (i);
- bool is_first_segment = i == 0;
- bool is_final_segment = i >= (expr.get_segments ().size () - 1);
- resolved_node_id = UNKNOWN_NODEID;
-
- if (segment.is_crate_path_seg ())
- {
- // what is the current crate scope node id?
- module_scope_id = crate_scope_id;
- previous_resolved_node_id = module_scope_id;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == module_scope_id);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
- resolved_node_id = module_scope_id;
-
- continue;
- }
- else if (segment.is_super_path_seg ())
- {
- if (!is_first_segment)
- {
- rust_error_at (
- segment.get_locus (), ErrorCode::E0433,
- "%<super%> in paths can only be used in start position");
- return UNKNOWN_NODEID;
- }
- if (module_scope_id == crate_scope_id)
- {
- rust_error_at (segment.get_locus (),
- "cannot use %<super%> at the crate scope");
- return UNKNOWN_NODEID;
- }
-
- module_scope_id = resolver->peek_parent_module_scope ();
- previous_resolved_node_id = module_scope_id;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == module_scope_id);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- module_scope_id);
- resolved_node_id = module_scope_id;
-
- continue;
- }
-
- tl::optional<CanonicalPath &> resolved_child
- = mappings.lookup_module_child (module_scope_id,
- segment.get_segment_name ());
- if (resolved_child.has_value ())
- {
- NodeId resolved_node = resolved_child->get_node_id ();
- if (resolver->get_name_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
- }
- else if (resolver->get_type_scope ().decl_was_declared_here (
- resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
- }
- else
- {
- rust_error_at (segment.get_locus (),
- "Cannot find path %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
- }
-
- if (resolved_node_id == UNKNOWN_NODEID && is_first_segment)
- {
- // name scope first
- NodeId resolved_node = UNKNOWN_NODEID;
- const CanonicalPath path
- = CanonicalPath::new_seg (segment.get_node_id (),
- segment.get_segment_name ());
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_name (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_name (segment.get_node_id (),
- resolved_node);
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (path, &resolved_node))
- {
- resolved_node_id = resolved_node;
-
- NodeId existing = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_type (segment.get_node_id (),
- &existing);
-
- if (ok)
- rust_assert (existing == resolved_node);
- else
- resolver->insert_resolved_type (segment.get_node_id (),
- resolved_node);
- }
- }
-
- // if we still have not resolved and this is the final segment and the
- // final segment is self its likely the case: pub use
- //
- // result::Result::{self, Err, Ok};
- //
- // Then the resolved_node_id is just the previous one so long as it is a
- // resolved node id
- // rust_debug_loc (segment.get_locus (),
- // "trying to resolve seg: [%s] first [%s] last [%s]",
- // segment.get_segment_name ().c_str (),
- // is_first_segment ? "true" : "false",
- // is_final_segment ? "true" : "false");
- if (resolved_node_id == UNKNOWN_NODEID && !is_first_segment
- && is_final_segment && segment.is_lower_self_seg ())
- resolved_node_id = previous_resolved_node_id;
-
- // final check
- if (resolved_node_id == UNKNOWN_NODEID)
- {
- rust_error_at (segment.get_locus (),
- "cannot find simple path segment %<%s%> in this scope",
- segment.as_string ().c_str ());
- return UNKNOWN_NODEID;
- }
-
- if (mappings.node_is_module (resolved_node_id))
- {
- module_scope_id = resolved_node_id;
- }
-
- previous_resolved_node_id = resolved_node_id;
- }
-
- resolved_node = resolved_node_id;
- if (resolved_node_id != UNKNOWN_NODEID)
- {
- // name scope first
- if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_name (expr.get_node_id (), &existing);
-
- if (ok)
- rust_assert (existing == resolved_node_id);
- else
- resolver->insert_resolved_name (expr.get_node_id (),
- resolved_node_id);
- }
- // check the type scope
- else if (resolver->get_type_scope ().decl_was_declared_here (
- resolved_node_id))
- {
- NodeId existing = UNKNOWN_NODEID;
- bool ok
- = resolver->lookup_resolved_type (expr.get_node_id (), &existing);
-
- if (ok)
- rust_assert (existing == resolved_node_id);
- else
- resolver->insert_resolved_type (expr.get_node_id (),
- resolved_node_id);
- }
- else
- {
- rust_unreachable ();
- }
- }
- return resolved_node_id;
-}
-
-} // namespace Resolver
-} // namespace Rust