aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-05 13:16:38 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-06 15:16:23 +0000
commitc4be77f7e0f6b35c019940200f94c7a7b30fff84 (patch)
treebe0673177880aba5edc02b13632ad93e052e0aa2 /gcc
parent9abf0733814c5e4131b96afb1c0abad68f4cf4ef (diff)
downloadgcc-c4be77f7e0f6b35c019940200f94c7a7b30fff84.zip
gcc-c4be77f7e0f6b35c019940200f94c7a7b30fff84.tar.gz
gcc-c4be77f7e0f6b35c019940200f94c7a7b30fff84.tar.bz2
Enforce Duplicate definition rules
Rust does not allow functions/methods/constants/static definitions to shadow otherwise you end up with unuseable items.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h24
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h48
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc3
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h28
-rw-r--r--gcc/testsuite/rust.test/compilable/name_resolve1.rs23
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error1.rs8
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error2.rs4
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error3.rs9
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error4.rs27
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error5.rs8
10 files changed, 159 insertions, 23 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 74f2cdc..9cbef53 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -39,8 +39,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + constant.get_identifier ();
- resolver->get_name_scope ().insert (identifier, constant.get_node_id (),
- constant.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, constant.get_node_id (), constant.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (constant.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
@@ -50,8 +54,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + function.get_function_name ();
- resolver->get_name_scope ().insert (identifier, function.get_node_id (),
- function.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, function.get_node_id (), function.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (function.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
function.get_node_id ()});
@@ -61,8 +69,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + method.get_method_name ();
- resolver->get_name_scope ().insert (identifier, method.get_node_id (),
- method.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, method.get_node_id (), method.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (method.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (method.get_node_id (),
Definition{method.get_node_id (),
method.get_node_id ()});
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 7ca8275..0ed838a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -38,22 +38,34 @@ public:
void visit (AST::TupleStruct &struct_decl)
{
- resolver->get_type_scope ().insert (struct_decl.get_identifier (),
- struct_decl.get_node_id (),
- struct_decl.get_locus ());
+ resolver->get_type_scope ().insert (
+ struct_decl.get_identifier (), struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (struct_decl.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
}
void visit (AST::StructStruct &struct_decl)
{
- resolver->get_type_scope ().insert (struct_decl.get_identifier (),
- struct_decl.get_node_id (),
- struct_decl.get_locus ());
+ resolver->get_type_scope ().insert (
+ struct_decl.get_identifier (), struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (struct_decl.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
}
void visit (AST::StaticItem &var)
{
- resolver->get_name_scope ().insert (var.get_identifier (),
- var.get_node_id (), var.get_locus ());
+ resolver->get_name_scope ().insert (
+ var.get_identifier (), var.get_node_id (), var.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (var.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (var.get_node_id (),
Definition{var.get_node_id (),
var.get_node_id ()});
@@ -62,9 +74,13 @@ public:
void visit (AST::ConstantItem &constant)
{
- resolver->get_name_scope ().insert (constant.get_identifier (),
- constant.get_node_id (),
- constant.get_locus ());
+ resolver->get_name_scope ().insert (
+ constant.get_identifier (), constant.get_node_id (),
+ constant.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (constant.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
@@ -72,9 +88,13 @@ public:
void visit (AST::Function &function)
{
- resolver->get_name_scope ().insert (function.get_function_name (),
- function.get_node_id (),
- function.get_locus ());
+ resolver->get_name_scope ().insert (
+ function.get_function_name (), function.get_node_id (),
+ function.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (function.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
function.get_node_id ()});
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index c6d7148..fd49720 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -110,7 +110,8 @@ Resolver::insert_builtin_types (Rib *r)
auto builtins = get_builtin_types ();
for (auto &builtin : builtins)
r->insert_name (builtin->as_string (), builtin->get_node_id (),
- Linemap::predeclared_location ());
+ Linemap::predeclared_location (), false,
+ [] (std::string, NodeId, Location) -> void {});
}
std::vector<AST::Type *> &
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 5bc6aba..f22eba7 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -37,8 +37,25 @@ public:
~Rib () {}
- void insert_name (std::string ident, NodeId id, Location locus)
+ void insert_name (std::string ident, NodeId id, Location locus, bool shadow,
+ std::function<void (std::string, NodeId, Location)> dup_cb)
{
+ auto it = mappings.find (ident);
+ bool already_exists = it != mappings.end ();
+ if (already_exists && !shadow)
+ {
+ for (auto &decl : decls_within_rib)
+ {
+ if (decl.first == it->second)
+ {
+ dup_cb (ident, it->second, decl.second);
+ return;
+ }
+ }
+ dup_cb (ident, it->second, locus);
+ return;
+ }
+
mappings[ident] = id;
decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
references[id] = {};
@@ -117,9 +134,16 @@ public:
Scope (CrateNum crate_num) : crate_num (crate_num) {}
~Scope () {}
+ void insert (std::string ident, NodeId id, Location locus, bool shadow,
+ std::function<void (std::string, NodeId, Location)> dup_cb)
+ {
+ peek ()->insert_name (ident, id, locus, shadow, dup_cb);
+ }
+
void insert (std::string ident, NodeId id, Location locus)
{
- peek ()->insert_name (ident, id, locus);
+ peek ()->insert_name (ident, id, locus, true,
+ [] (std::string, NodeId, Location) -> void {});
}
bool lookup (std::string ident, NodeId *id)
diff --git a/gcc/testsuite/rust.test/compilable/name_resolve1.rs b/gcc/testsuite/rust.test/compilable/name_resolve1.rs
new file mode 100644
index 0000000..817f48b
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/name_resolve1.rs
@@ -0,0 +1,23 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test() -> i32 {
+ test()
+ }
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test();
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs
new file mode 100644
index 0000000..9acdf5f
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs
@@ -0,0 +1,8 @@
+struct S1 {
+ x: f64,
+ y: f64,
+}
+
+struct S1(i32, bool);
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs
new file mode 100644
index 0000000..c04d2cf
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs
@@ -0,0 +1,4 @@
+const TEST: i32 = 2;
+const TEST: f32 = 3.0;
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs
new file mode 100644
index 0000000..9ffa4e5
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs
@@ -0,0 +1,9 @@
+fn test() -> bool {
+ true
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs
new file mode 100644
index 0000000..5b20e1b
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs
@@ -0,0 +1,27 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test() -> i32 {
+ test()
+ }
+
+ fn test() -> bool {
+ true
+ }
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test();
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs
new file mode 100644
index 0000000..342a67e
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs
@@ -0,0 +1,8 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ const TEST: i32 = 123;
+ const TEST: bool = false;
+}
+
+fn main() {}