From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> 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 <pierre-emmanuel.pa...@embecosm.com> --- 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