aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-06-29 15:37:38 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-06-29 16:35:52 +0100
commit18648e7b9f54c0cec4d4d865ff42b453b8de7101 (patch)
treee81aeb3fa144b3cb85139c2d0eae4092d68db5e8 /gcc/rust/resolve
parent81abc8623cb75fa18315c65e94c5965ec36fdb54 (diff)
downloadgcc-18648e7b9f54c0cec4d4d865ff42b453b8de7101.zip
gcc-18648e7b9f54c0cec4d4d865ff42b453b8de7101.tar.gz
gcc-18648e7b9f54c0cec4d4d865ff42b453b8de7101.tar.bz2
Add support for the self path
This keyword is described in https://doc.rust-lang.org/std/keyword.self.html Which allows it to refer to the current module when used as the first segment. If the keyword is used as any other segment it leads to a confusion between self the local parameter keyword in methods. Rustc emits a generic unresolved segment error in that senario which I have adopted here. Fixes #1227
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc21
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc28
2 files changed, 45 insertions, 4 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 3c69b65..c3631fd 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -59,6 +59,18 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
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 ())
+ {
+ // error[E0433]: failed to resolve: `self` in paths can only be used
+ // in start position
+ rust_error_at (segment.get_locus (),
+ "failed to resolve: %<%s%> in paths can only be used "
+ "in start position",
+ segment.as_string ().c_str ());
+ return;
+ }
+
NodeId crate_scope_id = resolver->peek_crate_module_scope ();
if (segment.is_crate_path_seg ())
{
@@ -170,6 +182,15 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
}
else
{
+ if (segment.is_lower_self_seg ())
+ {
+ module_scope_id = crate_scope_id;
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
+ continue;
+ }
+
rust_error_at (segment.get_locus (),
"Cannot find path %<%s%> in this scope",
segment.as_string ().c_str ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index a823543..7d7eac1 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -95,6 +95,18 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
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 ())
+ {
+ // error[E0433]: failed to resolve: `self` in paths can only be used
+ // in start position
+ rust_error_at (segment->get_locus (),
+ "failed to resolve: %<%s%> in paths can only be used "
+ "in start position",
+ segment->as_string ().c_str ());
+ return false;
+ }
+
NodeId crate_scope_id = resolver->peek_crate_module_scope ();
if (segment->is_crate_path_seg ())
{
@@ -129,10 +141,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
= static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
if (s->has_generic_args ())
{
- for (auto &gt : s->get_generic_args ().get_type_args ())
- {
- ResolveType::go (gt.get ());
- }
+ ResolveType::type_resolve_generic_args (s->get_generic_args ());
}
}
break;
@@ -198,6 +207,17 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
}
else
{
+ if (segment->is_lower_self_seg ())
+ {
+ // what is the current crate scope node id?
+ module_scope_id = crate_scope_id;
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
+
+ continue;
+ }
+
rust_error_at (segment->get_locus (),
"failed to resolve TypePath: %s in this scope",
segment->as_string ().c_str ());