diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-05 13:16:38 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-06 15:16:23 +0000 |
commit | c4be77f7e0f6b35c019940200f94c7a7b30fff84 (patch) | |
tree | be0673177880aba5edc02b13632ad93e052e0aa2 /gcc | |
parent | 9abf0733814c5e4131b96afb1c0abad68f4cf4ef (diff) | |
download | gcc-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.h | 24 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 48 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 3 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 28 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/name_resolve1.rs | 23 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/redef_error1.rs | 8 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/redef_error2.rs | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/redef_error3.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/redef_error4.rs | 27 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/redef_error5.rs | 8 |
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() {} |