diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 30 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-pattern.h | 3 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 19 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 1 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-unused.h | 45 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 16 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 48 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-resolver.h | 2 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/unused1.rs | 12 |
15 files changed, 159 insertions, 40 deletions
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index f1b39da..e042ccb 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -180,7 +180,7 @@ public: } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n) mutable -> bool { + rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { Resolver::Definition d; bool ok = ctx->get_resolver ()->lookup_definition (n, &d); rust_assert (ok); diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index c24005e..374f8a0 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -75,7 +75,7 @@ ResolvePathType::visit (HIR::PathInExpression &expr) { // need to look up the reference for this identifier NodeId ref_node_id; - if (!ctx->get_resolver ()->lookup_resolved_name ( + if (!ctx->get_resolver ()->lookup_resolved_type ( expr.get_mappings ().get_nodeid (), &ref_node_id)) { rust_fatal_error (expr.get_locus (), "failed to look up resolved name"); diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index a52f183..3f8a962 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -64,7 +64,7 @@ CompileBlock::visit (HIR::BlockExpr &expr) } std::vector<Bvariable *> locals; - rib->iterate_decls ([&] (NodeId n) mutable -> bool { + rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool { Resolver::Definition d; bool ok = ctx->get_resolver ()->lookup_definition (n, &d); rust_assert (ok); diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 2292d16..324d820 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -40,21 +40,27 @@ public: void visit (AST::PathInExpression &expr) { // name scope first - if (!resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node)) + if (resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node)) { - // check the type scope - if (!resolver->get_type_scope ().lookup (expr.as_string (), + resolver->insert_resolved_name (expr.get_node_id (), resolved_node); + resolver->insert_new_definition (expr.get_node_id (), + Definition{expr.get_node_id (), + parent}); + } + // check the type scope + else if (resolver->get_type_scope ().lookup (expr.as_string (), &resolved_node)) - { - rust_error_at (expr.get_locus (), "unknown path %s", - expr.as_string ().c_str ()); - return; - } + { + resolver->insert_resolved_type (expr.get_node_id (), resolved_node); + resolver->insert_new_definition (expr.get_node_id (), + Definition{expr.get_node_id (), + parent}); + } + else + { + rust_error_at (expr.get_locus (), "unknown path %s", + expr.as_string ().c_str ()); } - - resolver->insert_resolved_name (expr.get_node_id (), resolved_node); - resolver->insert_new_definition (expr.get_node_id (), - Definition{expr.get_node_id (), parent}); } void visit (AST::ReturnExpr &expr) diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 310d296..b0b979f 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -24,6 +24,7 @@ #include "rust-ast-resolve-type.h" #include "rust-ast-resolve-pattern.h" #include "rust-ast-resolve-stmt.h" +#include "rust-ast-resolve-unused.h" namespace Rust { namespace Resolver { @@ -84,6 +85,9 @@ public: ResolveExpr::go (function.get_definition ().get (), function.get_node_id ()); + ScanUnused::Scan (resolver->get_name_scope ().peek ()); + ScanUnused::Scan (resolver->get_type_scope ().peek ()); + resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); } diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h index fc2da70..c79f7d3 100644 --- a/gcc/rust/resolve/rust-ast-resolve-pattern.h +++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h @@ -81,7 +81,8 @@ public: // if we have a duplicate id this then allows for shadowing correctly // as new refs to this decl will match back here so it is ok to overwrite resolver->get_name_scope ().insert (pattern.get_ident (), - pattern.get_node_id ()); + pattern.get_node_id (), + pattern.get_locus ()); resolver->insert_new_definition (pattern.get_node_id (), Definition{pattern.get_node_id (), parent}); diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 6a4395f..447fe4b 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -39,13 +39,14 @@ public: void visit (AST::StructStruct &struct_decl) { resolver->get_type_scope ().insert (struct_decl.get_identifier (), - struct_decl.get_node_id ()); + struct_decl.get_node_id (), + struct_decl.get_locus ()); } void visit (AST::StaticItem &var) { resolver->get_name_scope ().insert (var.get_identifier (), - var.get_node_id ()); + var.get_node_id (), var.get_locus ()); resolver->insert_new_definition (var.get_node_id (), Definition{var.get_node_id (), var.get_node_id ()}); @@ -54,7 +55,8 @@ public: void visit (AST::ConstantItem &constant) { resolver->get_name_scope ().insert (constant.get_identifier (), - constant.get_node_id ()); + constant.get_node_id (), + constant.get_locus ()); resolver->insert_new_definition (constant.get_node_id (), Definition{constant.get_node_id (), constant.get_node_id ()}); @@ -62,10 +64,17 @@ public: void visit (AST::Function &function) { - // function_names are simple std::String identifiers so this can be a - // NodeId mapping to the Function node resolver->get_name_scope ().insert (function.get_function_name (), + function.get_node_id (), + function.get_locus ()); + + // if this does not get a reference it will be determined to be unused + // lets give it a fake reference to itself + if (function.get_function_name ().compare ("main") == 0) + { + resolver->insert_resolved_name (function.get_node_id (), function.get_node_id ()); + } } private: diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 9d408a9..8ec3a9c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -46,7 +46,6 @@ public: { // this will need changed to handle mod/crate/use globs and look // at the segments in granularity - locus = path.get_locus (); if (resolver->get_type_scope ().lookup (path.as_string (), &resolved_node)) { resolver->insert_resolved_type (path.get_node_id (), resolved_node); diff --git a/gcc/rust/resolve/rust-ast-resolve-unused.h b/gcc/rust/resolve/rust-ast-resolve-unused.h new file mode 100644 index 0000000..08b2db1 --- /dev/null +++ b/gcc/rust/resolve/rust-ast-resolve-unused.h @@ -0,0 +1,45 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_RESOLVE_UNUSED_H +#define RUST_AST_RESOLVE_UNUSED_H + +#include "rust-ast-resolve-base.h" + +namespace Rust { +namespace Resolver { + +class ScanUnused : public ResolverBase +{ +public: + static void Scan (Rib *r) + { + r->iterate_decls ([&] (NodeId decl_node_id, Location locus) -> bool { + if (!r->have_references_for_node (decl_node_id)) + { + rust_warning_at (locus, 0, "unused name"); + } + return true; + }); + } +}; + +} // namespace Resolver +} // namespace Rust + +#endif // RUST_AST_RESOLVE_UNUSED_H diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index e5b0942..d6eed93 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -22,6 +22,7 @@ #include "rust-ast-resolve-toplevel.h" #include "rust-ast-resolve-item.h" #include "rust-ast-resolve-expr.h" +#include "rust-ast-resolve-unused.h" #define MKBUILTIN_TYPE(_X, _R, _TY) \ do \ @@ -107,8 +108,9 @@ void Resolver::insert_builtin_types (Rib *r) { auto builtins = get_builtin_types (); - for (auto it = builtins.begin (); it != builtins.end (); it++) - r->insert_name ((*it)->as_string (), (*it)->get_node_id ()); + for (auto &builtin : builtins) + r->insert_name (builtin->as_string (), builtin->get_node_id (), + Linemap::predeclared_location ()); } std::vector<AST::TypePath *> & @@ -187,7 +189,7 @@ Resolver::insert_resolved_name (NodeId refId, NodeId defId) rust_assert (it == resolved_names.end ()); resolved_names[refId] = defId; - get_name_scope ().peek ()->append_reference_for_def (defId, refId); + get_name_scope ().append_reference_for_def (refId, defId); } bool @@ -208,7 +210,7 @@ Resolver::insert_resolved_type (NodeId refId, NodeId defId) rust_assert (it == resolved_types.end ()); resolved_types[refId] = defId; - get_type_scope ().peek ()->append_reference_for_def (defId, refId); + get_type_scope ().append_reference_for_def (refId, defId); } bool @@ -267,6 +269,9 @@ NameResolution::go (AST::Crate &crate) // next we can drill down into the items and their scopes for (auto it = crate.items.begin (); it != crate.items.end (); it++) ResolveItem::go (it->get ()); + + ScanUnused::Scan (resolver->get_name_scope ().peek ()); + ScanUnused::Scan (resolver->get_type_scope ().peek ()); } // rust-ast-resolve-expr.h @@ -288,6 +293,9 @@ ResolveExpr::visit (AST::BlockExpr &expr) if (expr.has_tail_expr ()) ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ()); + ScanUnused::Scan (resolver->get_name_scope ().peek ()); + ScanUnused::Scan (resolver->get_type_scope ().peek ()); + resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); } diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index 38206f6..515ebfd 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -37,10 +37,10 @@ public: ~Rib () {} - void insert_name (std::string ident, NodeId id) + void insert_name (std::string ident, NodeId id, Location locus) { mappings[ident] = id; - decls_within_rib.insert (id); + decls_within_rib.insert (std::pair<NodeId, Location> (id, locus)); references[id] = {}; } @@ -57,11 +57,11 @@ public: CrateNum get_crate_num () const { return crate_num; } NodeId get_node_id () const { return node_id; } - void iterate_decls (std::function<bool (NodeId)> cb) + void iterate_decls (std::function<bool (NodeId, Location)> cb) { for (auto it : decls_within_rib) { - if (!cb (it)) + if (!cb (it.first, it.second)) return; } } @@ -84,11 +84,30 @@ public: references[def].insert (ref); } + bool have_references_for_node (NodeId def) const + { + auto it = references.find (def); + if (it == references.end ()) + return false; + + return !it->second.empty (); + } + + bool decl_was_declared_here (NodeId def) const + { + for (auto &it : decls_within_rib) + { + if (it.first == def) + return true; + } + return false; + } + private: CrateNum crate_num; NodeId node_id; std::map<std::string, NodeId> mappings; - std::set<NodeId> decls_within_rib; + std::set<std::pair<NodeId, Location> > decls_within_rib; std::map<NodeId, std::set<NodeId> > references; }; @@ -98,9 +117,9 @@ public: Scope (CrateNum crate_num) : crate_num (crate_num) {} ~Scope () {} - void insert (std::string ident, NodeId id) + void insert (std::string ident, NodeId id, Location locus) { - peek ()->insert_name (ident, id); + peek ()->insert_name (ident, id, locus); } bool lookup (std::string ident, NodeId *id) @@ -138,6 +157,21 @@ public: CrateNum get_crate_num () const { return crate_num; } + void append_reference_for_def (NodeId refId, NodeId defId) + { + bool ok = false; + iterate ([&] (Rib *r) mutable -> bool { + if (r->decl_was_declared_here (defId)) + { + ok = true; + r->append_reference_for_def (defId, refId); + return false; + } + return true; + }); + rust_assert (ok); + } + private: CrateNum crate_num; std::vector<Rib *> stack; diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index e68ba9a..8fa6714 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -140,10 +140,13 @@ TypeCheckStructExpr::visit (HIR::PathInExpression &expr) NodeId ref_node_id; if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) { - rust_error_at (expr.get_locus (), - "Failed to lookup reference for node: %s", - expr.as_string ().c_str ()); - return; + if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) + { + rust_error_at (expr.get_locus (), + "Failed to lookup reference for node: %s", + expr.as_string ().c_str ()); + return; + } } // node back to HIR diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index 3d2196a..22c3c91 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -44,7 +44,7 @@ public: void go (Rib *rib) { - rib->iterate_decls ([&] (NodeId decl_node_id) mutable -> bool { + rib->iterate_decls ([&] (NodeId decl_node_id, Location) mutable -> bool { // type inference in rust means we need to gather and examine all // references of this decl and combine each to make sure the type is // correctly inferred. Consider the example: diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 238689c..0fea501 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -331,8 +331,6 @@ Mappings::insert_hir_param (CrateNum crateNum, HirId id, { rust_assert (lookup_hir_stmt (crateNum, id) == nullptr); - printf ("inserting param with node id %u hir id: %u\n", - param->get_mappings ()->get_nodeid (), id); hirParamMappings[crateNum][id] = param; nodeIdToHirMappings[crateNum][param->get_mappings ()->get_nodeid ()] = id; } diff --git a/gcc/testsuite/rust.test/compilable/unused1.rs b/gcc/testsuite/rust.test/compilable/unused1.rs new file mode 100644 index 0000000..cb50188 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/unused1.rs @@ -0,0 +1,12 @@ +fn test() -> i32 { + 1 +} + +fn unused() -> i32 { + 2 +} + +fn main() { + let a = 1; + let b = test(); +} |