aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-03 12:29:32 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-06 15:45:51 +0000
commit59a8fa1a80c3b2c6520c627a6bf200274732d395 (patch)
tree111e1da00bbea7d6e0d21c2aebe07089e21823bf /gcc
parent7098b373172354a9d68d319fdbfcc07f99970914 (diff)
downloadgcc-59a8fa1a80c3b2c6520c627a6bf200274732d395.zip
gcc-59a8fa1a80c3b2c6520c627a6bf200274732d395.tar.gz
gcc-59a8fa1a80c3b2c6520c627a6bf200274732d395.tar.bz2
Support Self used within impl blocks
This is simply a type reference so we can use the name resolver to resolve Self as a type reference back to the Type used for the impl block. Fixes #204
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h10
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h4
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h4
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h13
-rw-r--r--gcc/testsuite/rust.test/compilable/impl_block3.rs31
-rw-r--r--gcc/testsuite/rust.test/compilable/self_type1.rs12
6 files changed, 68 insertions, 6 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index cc8e451..5ed98a9 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -115,8 +115,18 @@ public:
void visit (AST::InherentImpl &impl_block)
{
+ NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
+ impl_block.get_node_id ());
+ if (resolved_node == UNKNOWN_NODEID)
+ return;
+
+ resolver->get_type_scope ().insert (
+ "Self", resolved_node, impl_block.get_type ()->get_locus_slow ());
+
for (auto &impl_item : impl_block.get_impl_items ())
impl_item->accept_vis (*this);
+
+ resolver->get_type_scope ().peek ()->clear_name ("Self", resolved_node);
}
private:
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 0ed838a..2e4e8e7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -110,10 +110,6 @@ public:
void visit (AST::InherentImpl &impl_block)
{
- if (!ResolveType::go (impl_block.get_type ().get (),
- impl_block.get_node_id ()))
- return;
-
for (auto &impl_item : impl_block.get_impl_items ())
ResolveToplevelImplItem::go (impl_item.get (),
impl_block.get_type ().get ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 258524b..ec8ee87 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -28,14 +28,14 @@ namespace Resolver {
class ResolveType : public ResolverBase
{
public:
- static bool go (AST::Type *type, NodeId parent)
+ static NodeId go (AST::Type *type, NodeId parent)
{
ResolveType resolver (parent);
type->accept_vis (resolver);
if (!resolver.ok)
rust_error_at (type->get_locus_slow (), "unresolved type");
- return resolver.ok;
+ return resolver.resolved_node;
};
void visit (AST::BareFunctionType &fntype)
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 5544f30..ea0e4f5 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -71,6 +71,19 @@ public:
return true;
}
+ void clear_name (std::string ident, NodeId id)
+ {
+ mappings.erase (ident);
+ for (auto &it : decls_within_rib)
+ {
+ if (it.first == id)
+ {
+ decls_within_rib.erase (it);
+ break;
+ }
+ }
+ }
+
CrateNum get_crate_num () const { return crate_num; }
NodeId get_node_id () const { return node_id; }
diff --git a/gcc/testsuite/rust.test/compilable/impl_block3.rs b/gcc/testsuite/rust.test/compilable/impl_block3.rs
new file mode 100644
index 0000000..3093a6c
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/impl_block3.rs
@@ -0,0 +1,31 @@
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+impl Point {
+ fn origin() -> Point {
+ Point { x: 0.0, y: 0.0 }
+ }
+
+ fn new(x: f64, y: f64) -> Point {
+ Point { x: x, y: y }
+ }
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+impl Rectangle {
+ fn from(p1: Point, p2: Point) -> Self {
+ Self { p1, p2 }
+ }
+}
+
+fn main() {
+ let p1 = Point::origin();
+ let p2 = Point::new(3.0, 4.0);
+ let rect = Rectangle::from(p1, p2);
+}
diff --git a/gcc/testsuite/rust.test/compilable/self_type1.rs b/gcc/testsuite/rust.test/compilable/self_type1.rs
new file mode 100644
index 0000000..373d6dd
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/self_type1.rs
@@ -0,0 +1,12 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Self {
+ Self(a, b)
+ }
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+}