aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h22
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h67
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc29
4 files changed, 88 insertions, 42 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index d76cbac..d88b275f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -34,13 +34,19 @@ public:
static void go (AST::InherentImplItem *item, AST::Type *base)
{
ResolveToplevelImplItem resolver (base);
+ if (resolver.base_path.is_empty ())
+ {
+ rust_error_at (base->get_locus_slow (),
+ "failed to resolve simple path");
+ return;
+ }
item->accept_vis (resolver);
- };
+ }
void visit (AST::ConstantItem &constant) override
{
std::string identifier
- = base->as_string () + "::" + constant.get_identifier ();
+ = base_path.as_string () + "::" + constant.get_identifier ();
resolver->get_name_scope ().insert (
identifier, constant.get_node_id (), constant.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -55,7 +61,7 @@ public:
void visit (AST::Function &function) override
{
std::string identifier
- = base->as_string () + "::" + function.get_function_name ();
+ = base_path.as_string () + "::" + function.get_function_name ();
resolver->get_name_scope ().insert (
identifier, function.get_node_id (), function.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -70,7 +76,7 @@ public:
void visit (AST::Method &method) override
{
std::string identifier
- = base->as_string () + "::" + method.get_method_name ();
+ = base_path.as_string () + "::" + method.get_method_name ();
resolver->get_name_scope ().insert (
identifier, method.get_node_id (), method.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -84,10 +90,14 @@ public:
private:
ResolveToplevelImplItem (AST::Type *base)
- : ResolverBase (UNKNOWN_NODEID), base (base)
- {}
+ : ResolverBase (UNKNOWN_NODEID), base (base),
+ base_path (AST::SimplePath::create_empty ())
+ {
+ ResolveTypeToSimplePath::go (base, base_path, true);
+ }
AST::Type *base;
+ AST::SimplePath base_path;
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 95e335b..1074031 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -152,6 +152,17 @@ public:
void visit (AST::InherentImpl &impl_block) override
{
+ NodeId scope_node_id = impl_block.get_node_id ();
+ resolver->get_type_scope ().push (scope_node_id);
+
+ if (impl_block.has_generics ())
+ {
+ for (auto &generic : impl_block.get_generic_params ())
+ {
+ ResolveGenericParam::go (generic.get (), impl_block.get_node_id ());
+ }
+ }
+
NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
impl_block.get_node_id ());
if (resolved_node == UNKNOWN_NODEID)
@@ -164,6 +175,7 @@ public:
impl_item->accept_vis (*this);
resolver->get_type_scope ().peek ()->clear_name ("Self", resolved_node);
+ resolver->get_type_scope ().pop ();
}
void visit (AST::Method &method) override
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index c829ed0..9e7568e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -25,25 +25,22 @@
namespace Rust {
namespace Resolver {
-class ResolveTypePath : public ResolverBase
+class ResolveTypeToSimplePath : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
- static NodeId go (AST::TypePath &path, NodeId parent)
+ static bool go (AST::Type *type, AST::SimplePath &simple_path_result,
+ bool path_only = false)
{
- ResolveTypePath resolver (parent);
- resolver.resolve (path);
- return resolver.resolved_node;
+ ResolveTypeToSimplePath resolver (simple_path_result, path_only);
+ type->accept_vis (resolver);
+ return !resolver.type_seg_failed_flag;
}
- void visit (AST::TypePathSegmentGeneric &seg) override;
-
- void visit (AST::TypePathSegment &seg) override;
-
-private:
- void resolve (AST::TypePath &path)
+ void visit (AST::TypePath &path) override
{
+ segs.reserve (path.get_num_segments ());
for (auto &seg : path.get_segments ())
{
seg->accept_vis (*this);
@@ -51,27 +48,55 @@ private:
return;
}
- if (path_buffer.empty ())
+ if (segs.empty ())
{
rust_error_at (path.get_locus (), "failed to resolve path: %s",
path.as_string ().c_str ());
return;
}
- if (!resolver->get_type_scope ().lookup (path_buffer, &resolved_node))
- {
- rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
- path_buffer.c_str ());
- return;
- }
+ bool has_opening_scope_res = false;
+ result = AST::SimplePath (std::move (segs), has_opening_scope_res,
+ path.get_locus ());
}
- ResolveTypePath (NodeId parent)
- : ResolverBase (parent), type_seg_failed_flag (false)
+ void visit (AST::TypePathSegmentGeneric &seg) override;
+
+ void visit (AST::TypePathSegment &seg) override;
+
+private:
+ ResolveTypeToSimplePath (AST::SimplePath &simple_path_result, bool path_only)
+ : ResolverBase (UNKNOWN_NODEID), type_seg_failed_flag (false),
+ result (simple_path_result), path_only_flag (path_only)
{}
- std::string path_buffer;
bool type_seg_failed_flag;
+ std::vector<AST::SimplePathSegment> segs;
+ AST::SimplePath &result;
+ bool path_only_flag;
+};
+
+class ResolveTypePath
+{
+public:
+ static NodeId go (AST::TypePath &path, NodeId parent)
+ {
+ AST::SimplePath path_buffer = AST::SimplePath::create_empty ();
+ if (!ResolveTypeToSimplePath::go (&path, path_buffer))
+ return UNKNOWN_NODEID;
+
+ auto resolver = Resolver::get ();
+ NodeId resolved_node = UNKNOWN_NODEID;
+ if (!resolver->get_type_scope ().lookup (path_buffer.as_string (),
+ &resolved_node))
+ {
+ rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s",
+ path_buffer.as_string ().c_str ());
+ return UNKNOWN_NODEID;
+ }
+
+ return resolved_node;
+ }
};
class ResolveType : public ResolverBase
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index b4ca34f..4cc1a93 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -375,11 +375,14 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field)
// rust-ast-resolve-type.h
void
-ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg)
+ResolveTypeToSimplePath::visit (AST::TypePathSegmentGeneric &seg)
{
- AST::GenericArgs &generics = seg.get_generic_args ();
- for (auto &gt : generics.get_type_args ())
- ResolveType::go (gt.get (), UNKNOWN_NODEID);
+ if (!path_only_flag)
+ {
+ AST::GenericArgs &generics = seg.get_generic_args ();
+ for (auto &gt : generics.get_type_args ())
+ ResolveType::go (gt.get (), UNKNOWN_NODEID);
+ }
if (seg.is_error ())
{
@@ -389,14 +392,12 @@ ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg)
return;
}
- if (seg.get_separating_scope_resolution ())
- path_buffer += "::";
-
- path_buffer += seg.get_ident_segment ().as_string ();
+ segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (),
+ seg.get_locus ()));
}
void
-ResolveTypePath::visit (AST::TypePathSegment &seg)
+ResolveTypeToSimplePath::visit (AST::TypePathSegment &seg)
{
if (seg.is_error ())
{
@@ -406,10 +407,8 @@ ResolveTypePath::visit (AST::TypePathSegment &seg)
return;
}
- if (seg.get_separating_scope_resolution ())
- path_buffer += "::";
-
- path_buffer += seg.get_ident_segment ().as_string ();
+ segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (),
+ seg.get_locus ()));
}
// rust-ast-resolve-expr.h
@@ -465,8 +464,8 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
}
else
{
- rust_error_at (expr->get_locus (), "unknown path %s",
- expr->as_string ().c_str ());
+ rust_error_at (expr->get_locus (), "unknown path %s lookup %s",
+ expr->as_string ().c_str (), path_buf.c_str ());
}
}