diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-03 12:29:32 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-06 15:45:51 +0000 |
commit | 59a8fa1a80c3b2c6520c627a6bf200274732d395 (patch) | |
tree | 111e1da00bbea7d6e0d21c2aebe07089e21823bf /gcc | |
parent | 7098b373172354a9d68d319fdbfcc07f99970914 (diff) | |
download | gcc-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.h | 10 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/impl_block3.rs | 31 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/self_type1.rs | 12 |
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); +} |