From: Pierre-Emmanuel Patry <[email protected]>
An error should be emitted on unsafe modules during the AST validation
pass as the syntax allows those even though they're not alowed later down
the line.
gcc/rust/ChangeLog:
* ast/rust-item.h: Add safety getter to modules.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit): Check
a module's safety and emit an error when meeting an unsafe module.
* checks/errors/rust-ast-validation.h: Add function prototype.
* parse/rust-parse-impl.h (Parser::parse_module): Move the module locus
to the first token instead of the mod keyword.
Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
gcc/rust/ast/rust-item.h | 2 ++
gcc/rust/checks/errors/rust-ast-validation.cc | 10 ++++++++++
gcc/rust/checks/errors/rust-ast-validation.h | 1 +
gcc/rust/parse/rust-parse-impl.h | 3 ++-
4 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 6c3715e1eeb..3bf023b3c5a 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -840,6 +840,8 @@ public:
// Returns the kind of the module
enum ModuleKind get_kind () const { return kind; }
+ Unsafety get_unsafety () const { return safety; }
+
// TODO: think of better way to do this - mutable getter seems dodgy
const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs;
}
std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc
b/gcc/rust/checks/errors/rust-ast-validation.cc
index dad7f5edded..4b209908f9e 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-validation.h"
+#include "rust-common.h"
#include "rust-diagnostics.h"
#include "rust-item.h"
#include "rust-keyword-values.h"
@@ -136,4 +137,13 @@ ASTValidation::visit (AST::Trait &trait)
AST::ContextualASTVisitor::visit (trait);
}
+void
+ASTValidation::visit (AST::Module &module)
+{
+ if (module.get_unsafety () == Unsafety::Unsafe)
+ rust_error_at (module.get_locus (), "module cannot be declared unsafe");
+
+ AST::ContextualASTVisitor::visit (module);
+}
+
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-ast-validation.h
b/gcc/rust/checks/errors/rust-ast-validation.h
index 1052168ea72..01d923ceff3 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.h
+++ b/gcc/rust/checks/errors/rust-ast-validation.h
@@ -34,6 +34,7 @@ public:
void check (AST::Crate &crate) { AST::ContextualASTVisitor::visit (crate); }
+ virtual void visit (AST::Module &module);
virtual void visit (AST::ConstantItem &const_item);
virtual void visit (AST::Lifetime &lifetime);
virtual void visit (AST::LoopLabel &label);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 8087e0c2b94..f83cc122c89 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2429,6 +2429,8 @@ std::unique_ptr<AST::Module>
Parser<ManagedTokenSource>::parse_module (AST::Visibility vis,
AST::AttrVec outer_attrs)
{
+ location_t locus = lexer.peek_token ()->get_locus ();
+
Unsafety safety = Unsafety::Normal;
if (lexer.peek_token ()->get_id () == UNSAFE)
{
@@ -2436,7 +2438,6 @@ Parser<ManagedTokenSource>::parse_module (AST::Visibility
vis,
skip_token (UNSAFE);
}
- location_t locus = lexer.peek_token ()->get_locus ();
skip_token (MOD);
const_TokenPtr module_name = expect_token (IDENTIFIER);
--
2.42.1