diff options
author | Mark Wielaard <mark@klomp.org> | 2021-09-06 00:48:11 +0200 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-09-06 11:07:35 +0100 |
commit | eaf5bc5c38412514a5abb028fca343c838ac51ca (patch) | |
tree | e31ad30bd83f58c5944d9b66b7666190f0b338f1 | |
parent | a3ac8573495919f1c8f6d6cca6578edd5e3ab01e (diff) | |
download | gcc-eaf5bc5c38412514a5abb028fca343c838ac51ca.zip gcc-eaf5bc5c38412514a5abb028fca343c838ac51ca.tar.gz gcc-eaf5bc5c38412514a5abb028fca343c838ac51ca.tar.bz2 |
Add EnumItem HIR lowering
Make HIT EnumItem class an Item, not VisItem like in the AST. At the
HIR level EnumItems shouldn't have visibility anymore.
Move struct_field_name_exists to rust-ast-lower.cc with the
declaration in rust-ast-lower.h to make it reusable in the different
visitors.
Add a new ASTLoweringEnumItem that can be used from ASTLoweringItem
and ASTLoweringStmt. It checks the EnumItems don't have visibility and
that EnumItemStruct fields are not duplicated.
Add a new testcase 'bad_pub_enumitems.rs' to check the no-visibility and
no-duplicates properties hold.
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-enumitem.h | 192 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 103 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-stmt.h | 74 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 20 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.h | 5 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 19 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 58 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_pub_enumitems.rs | 47 |
8 files changed, 406 insertions, 112 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-enumitem.h b/gcc/rust/hir/rust-ast-lower-enumitem.h new file mode 100644 index 0000000..333cb7b --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-enumitem.h @@ -0,0 +1,192 @@ +// 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_LOWER_ENUMITEM +#define RUST_AST_LOWER_ENUMITEM + +#include "rust-diagnostics.h" + +#include "rust-ast-lower-base.h" +#include "rust-ast-lower-type.h" +#include "rust-ast-lower-expr.h" +#include "rust-hir-full-decls.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringEnumItem : public ASTLoweringBase +{ + using Rust::HIR::ASTLoweringBase::visit; + +public: + static HIR::EnumItem *translate (AST::EnumItem *item) + { + ASTLoweringEnumItem resolver; + item->accept_vis (resolver); + return resolver.translated; + } + + void visit (AST::EnumItem &item) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, item.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + if (item.has_visibility ()) + rust_error_at (item.get_locus (), + "visibility qualifier %qs not allowed on enum item", + item.get_vis ().as_string ().c_str ()); + + translated = new HIR::EnumItem (mapping, item.get_identifier (), + item.get_outer_attrs (), item.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + item.get_locus ()); + } + + void visit (AST::EnumItemTuple &item) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, item.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + if (item.has_visibility ()) + rust_error_at (item.get_locus (), + "visibility qualifier %qs not allowed on enum item", + item.get_vis ().as_string ().c_str ()); + + std::vector<HIR::TupleField> fields; + for (auto &field : item.get_tuple_fields ()) + { + HIR::Visibility vis = HIR::Visibility::create_public (); + HIR::Type *type + = ASTLoweringType::translate (field.get_field_type ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping field_mapping ( + crate_num, field.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + HIR::TupleField translated_field (field_mapping, + std::unique_ptr<HIR::Type> (type), + vis, field.get_locus (), + field.get_outer_attrs ()); + fields.push_back (std::move (translated_field)); + } + + translated + = new HIR::EnumItemTuple (mapping, item.get_identifier (), + std::move (fields), item.get_outer_attrs (), + item.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + item.get_locus ()); + } + + void visit (AST::EnumItemStruct &item) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, item.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + if (item.has_visibility ()) + rust_error_at (item.get_locus (), + "visibility qualifier %qs not allowed on enum item", + item.get_vis ().as_string ().c_str ()); + + std::vector<HIR::StructField> fields; + for (auto &field : item.get_struct_fields ()) + { + HIR::Visibility vis = HIR::Visibility::create_public (); + HIR::Type *type + = ASTLoweringType::translate (field.get_field_type ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping field_mapping ( + crate_num, field.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + HIR::StructField translated_field (field_mapping, + field.get_field_name (), + std::unique_ptr<HIR::Type> (type), + vis, field.get_locus (), + field.get_outer_attrs ()); + + if (struct_field_name_exists (fields, translated_field)) + break; + + fields.push_back (std::move (translated_field)); + } + + translated + = new HIR::EnumItemStruct (mapping, item.get_identifier (), + std::move (fields), item.get_outer_attrs (), + item.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + item.get_locus ()); + } + void visit (AST::EnumItemDiscriminant &item) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, item.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + if (item.has_visibility ()) + rust_error_at (item.get_locus (), + "visibility qualifier %qs not allowed on enum item", + item.get_vis ().as_string ().c_str ()); + + HIR::Expr *expr = ASTLoweringExpr::translate (item.get_expr ().get ()); + translated + = new HIR::EnumItemDiscriminant (mapping, item.get_identifier (), + std::unique_ptr<HIR::Expr> (expr), + item.get_outer_attrs (), + item.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + item.get_locus ()); + } + +private: + ASTLoweringEnumItem () : translated (nullptr) {} + HIR::EnumItem *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_ENUMITEM diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index 7efcffa..dfc2612 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -22,6 +22,7 @@ #include "rust-diagnostics.h" #include "rust-ast-lower-base.h" +#include "rust-ast-lower-enumitem.h" #include "rust-ast-lower-type.h" #include "rust-ast-lower-implitem.h" #include "rust-ast-lower-stmt.h" @@ -65,7 +66,7 @@ public: // should be lowered from module.get_vis() HIR::Visibility vis = HIR::Visibility::create_public (); - auto items = std::vector<std::unique_ptr<Item> > (); + auto items = std::vector<std::unique_ptr<Item>> (); for (auto &item : module.get_items ()) { @@ -93,11 +94,11 @@ public: void visit (AST::TypeAlias &alias) override { - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (alias.has_generics ()) generic_params = lower_generic_params (alias.get_generic_params ()); @@ -125,14 +126,14 @@ public: void visit (AST::TupleStruct &struct_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (struct_decl.has_generics ()) { generic_params = lower_generic_params (struct_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -175,35 +176,16 @@ public: struct_decl.get_locus ()); } - /* Checks whether the name of a field already exists. Returns true - and produces an error if so. */ - static bool struct_field_name_exists (std::vector<HIR::StructField> &fields, - HIR::StructField &new_field) - { - for (auto &field : fields) - { - if (field.get_field_name ().compare (new_field.get_field_name ()) == 0) - { - RichLocation r (new_field.get_locus ()); - r.add_range (field.get_locus ()); - rust_error_at (r, "duplicate field name %qs", - field.get_field_name ().c_str ()); - return true; - } - } - return false; - } - void visit (AST::StructStruct &struct_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (struct_decl.has_generics ()) { generic_params = lower_generic_params (struct_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -251,16 +233,55 @@ public: struct_decl.get_locus ()); } + void visit (AST::Enum &enum_decl) override + { + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; + if (enum_decl.has_generics ()) + { + generic_params = lower_generic_params (enum_decl.get_generic_params ()); + } + + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::Visibility vis = HIR::Visibility::create_public (); + + // bool is_unit = enum_decl.is_zero_variant (); + std::vector<std::unique_ptr<HIR::EnumItem>> items; + for (auto &variant : enum_decl.get_variants ()) + { + HIR::EnumItem *hir_item + = ASTLoweringEnumItem::translate (variant.get ()); + items.push_back (std::unique_ptr<HIR::EnumItem> (hir_item)); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, enum_decl.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated = new HIR::Enum (mapping, enum_decl.get_identifier (), vis, + std::move (generic_params), + std::move (where_clause), /* is_unit, */ + std::move (items), enum_decl.get_outer_attrs (), + enum_decl.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + enum_decl.get_locus ()); + } + void visit (AST::Union &union_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (union_decl.has_generics ()) { generic_params = lower_generic_params (union_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -359,14 +380,14 @@ public: void visit (AST::Function &function) override { // ignore for now and leave empty - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::FunctionQualifiers qualifiers ( HIR::FunctionQualifiers::AsyncConstStatus::NONE, false); HIR::Visibility vis = HIR::Visibility::create_public (); // need - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (function.has_generics ()) { generic_params = lower_generic_params (function.get_generic_params ()); @@ -443,12 +464,12 @@ public: void visit (AST::InherentImpl &impl_block) override { - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (impl_block.has_generics ()) { generic_params @@ -486,7 +507,7 @@ public: mappings->get_next_hir_id (crate_num), mappings->get_next_localdef_id (crate_num)); - std::vector<std::unique_ptr<HIR::ImplItem> > impl_items; + std::vector<std::unique_ptr<HIR::ImplItem>> impl_items; std::vector<HirId> impl_item_ids; for (auto &impl_item : impl_block.get_impl_items ()) { @@ -523,12 +544,12 @@ public: void visit (AST::Trait &trait) override { - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (trait.has_generics ()) { generic_params = lower_generic_params (trait.get_generic_params ()); @@ -557,9 +578,9 @@ public: } } - std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds; + std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds; - std::vector<std::unique_ptr<HIR::TraitItem> > trait_items; + std::vector<std::unique_ptr<HIR::TraitItem>> trait_items; std::vector<HirId> trait_item_ids; for (auto &item : trait.get_trait_items ()) { @@ -595,12 +616,12 @@ public: void visit (AST::TraitImpl &impl_block) override { - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (impl_block.has_generics ()) { generic_params @@ -640,7 +661,7 @@ public: mappings->get_next_hir_id (crate_num), mappings->get_next_localdef_id (crate_num)); - std::vector<std::unique_ptr<HIR::ImplItem> > impl_items; + std::vector<std::unique_ptr<HIR::ImplItem>> impl_items; std::vector<HirId> impl_item_ids; for (auto &impl_item : impl_block.get_impl_items ()) { @@ -680,7 +701,7 @@ public: { HIR::Visibility vis = HIR::Visibility::create_public (); - std::vector<std::unique_ptr<HIR::ExternalItem> > extern_items; + std::vector<std::unique_ptr<HIR::ExternalItem>> extern_items; for (auto &item : extern_block.get_extern_items ()) { HIR::ExternalItem *lowered diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h index fdd5041..ee9b675 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.h +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -22,6 +22,7 @@ #include "rust-diagnostics.h" #include "rust-ast-lower-base.h" +#include "rust-ast-lower-enumitem.h" #include "rust-ast-lower-type.h" #include "rust-ast-lower-block.h" #include "rust-ast-lower-expr.h" @@ -110,14 +111,14 @@ public: void visit (AST::TupleStruct &struct_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (struct_decl.has_generics ()) { generic_params = lower_generic_params (struct_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -159,35 +160,16 @@ public: struct_decl.get_locus ()); } - /* Checks whether the name of a field already exists. Returns true - and produces an error if so. */ - static bool struct_field_name_exists (std::vector<HIR::StructField> &fields, - HIR::StructField &new_field) - { - for (auto &field : fields) - { - if (field.get_field_name ().compare (new_field.get_field_name ()) == 0) - { - RichLocation r (new_field.get_locus ()); - r.add_range (field.get_locus ()); - rust_error_at (r, "duplicate field name %qs", - field.get_field_name ().c_str ()); - return true; - } - } - return false; - } - void visit (AST::StructStruct &struct_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (struct_decl.has_generics ()) { generic_params = lower_generic_params (struct_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -236,14 +218,14 @@ public: void visit (AST::Union &union_decl) override { - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (union_decl.has_generics ()) { generic_params = lower_generic_params (union_decl.get_generic_params ()); } - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::Visibility vis = HIR::Visibility::create_public (); @@ -288,6 +270,44 @@ public: union_decl.get_locus ()); } + void visit (AST::Enum &enum_decl) override + { + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; + if (enum_decl.has_generics ()) + { + generic_params = lower_generic_params (enum_decl.get_generic_params ()); + } + + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::Visibility vis = HIR::Visibility::create_public (); + + // bool is_unit = enum_decl.is_zero_variant (); + std::vector<std::unique_ptr<HIR::EnumItem>> items; + for (auto &variant : enum_decl.get_variants ()) + { + HIR::EnumItem *hir_item + = ASTLoweringEnumItem::translate (variant.get ()); + items.push_back (std::unique_ptr<HIR::EnumItem> (hir_item)); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, enum_decl.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated = new HIR::Enum (mapping, enum_decl.get_identifier (), vis, + std::move (generic_params), + std::move (where_clause), /* is_unit, */ + std::move (items), enum_decl.get_outer_attrs (), + enum_decl.get_locus ()); + + mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + enum_decl.get_locus ()); + } + void visit (AST::EmptyStmt &empty) override { auto crate_num = mappings->get_current_crate (); @@ -306,14 +326,14 @@ public: void visit (AST::Function &function) override { // ignore for now and leave empty - std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items; HIR::WhereClause where_clause (std::move (where_clause_items)); HIR::FunctionQualifiers qualifiers ( HIR::FunctionQualifiers::AsyncConstStatus::NONE, false); HIR::Visibility vis = HIR::Visibility::create_public (); // need - std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<std::unique_ptr<HIR::GenericParam>> generic_params; if (function.has_generics ()) { generic_params = lower_generic_params (function.get_generic_params ()); diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index e8784b6..b64e1a0 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -520,5 +520,25 @@ ASTLoweringBase::lower_bound (AST::TypeParamBound *bound) return ASTLoweringTypeBounds::translate (bound); } +/* Checks whether the name of a field already exists. Returns true + and produces an error if so. */ +bool +struct_field_name_exists (std::vector<HIR::StructField> &fields, + HIR::StructField &new_field) +{ + for (auto &field : fields) + { + if (field.get_field_name ().compare (new_field.get_field_name ()) == 0) + { + RichLocation r (new_field.get_locus ()); + r.add_range (field.get_locus ()); + rust_error_at (r, "duplicate field name %qs", + field.get_field_name ().c_str ()); + return true; + } + } + return false; +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower.h b/gcc/rust/hir/rust-ast-lower.h index bdc21ba..254f686 100644 --- a/gcc/rust/hir/rust-ast-lower.h +++ b/gcc/rust/hir/rust-ast-lower.h @@ -27,6 +27,11 @@ namespace Rust { namespace HIR { +/* Checks whether the name of a field already exists. Returns true + and produces an error if so. */ +bool +struct_field_name_exists (std::vector<HIR::StructField> &fields, + HIR::StructField &new_field); class ASTLowering { public: diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index f328ae6..b0e418c 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -3086,23 +3086,8 @@ StructExprStructFields::as_string () const std::string EnumItem::as_string () const { - // outer attributes - std::string str = "outer attributes: "; - if (outer_attrs.empty ()) - { - str += "none"; - } - else - { - /* note that this does not print them with "outer attribute" syntax - - * just the body */ - for (const auto &attr : outer_attrs) - { - str += "\n " + attr.as_string (); - } - } - - str += "\n" + variant_name; + std::string str = Item::as_string (); + str += variant_name; return str; } diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 7a2c267..35b1c64 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -1636,12 +1636,11 @@ protected: }; /* An item used in an "enum" tagged union - not abstract: base represents a - * name-only enum */ -class EnumItem + name-only enum. Syntactically EnumItem's can have a Visibility. But not + Semantically. So check there is no Visibility when lowering and make this + an Item, not an VisItem. */ +class EnumItem : public Item { - // bool has_attrs; - AST::AttrVec outer_attrs; - Identifier variant_name; Location locus; @@ -1649,18 +1648,16 @@ class EnumItem public: virtual ~EnumItem () {} - // Returns whether enum item has outer attributes. - bool has_outer_attrs () const { return !outer_attrs.empty (); } - - EnumItem (Identifier variant_name, AST::AttrVec outer_attrs, Location locus) - : outer_attrs (std::move (outer_attrs)), + EnumItem (Analysis::NodeMapping mappings, Identifier variant_name, + AST::AttrVec outer_attrs, Location locus) + : Item (std::move (mappings), std::move (outer_attrs)), variant_name (std::move (variant_name)), locus (locus) {} // Unique pointer custom clone function std::unique_ptr<EnumItem> clone_enum_item () const { - return std::unique_ptr<EnumItem> (clone_enum_item_impl ()); + return std::unique_ptr<EnumItem> (clone_item_impl ()); } virtual std::string as_string () const; @@ -1668,12 +1665,12 @@ public: // not pure virtual as not abstract virtual void accept_vis (HIRVisitor &vis); + Location get_locus () const { return locus; } + + Identifier get_identifier () const { return variant_name; } + protected: - // Clone function implementation as (not pure) virtual method - virtual EnumItem *clone_enum_item_impl () const - { - return new EnumItem (*this); - } + EnumItem *clone_item_impl () const override { return new EnumItem (*this); } }; // A tuple item used in an "enum" tagged union @@ -1686,9 +1683,11 @@ public: // Returns whether tuple enum item has tuple fields. bool has_tuple_fields () const { return !tuple_fields.empty (); } - EnumItemTuple (Identifier variant_name, std::vector<TupleField> tuple_fields, - AST::AttrVec outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name, + std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs, + Location locus) + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), tuple_fields (std::move (tuple_fields)) {} @@ -1698,7 +1697,7 @@ public: protected: // Clone function implementation as (not pure) virtual method - EnumItemTuple *clone_enum_item_impl () const override + EnumItemTuple *clone_item_impl () const override { return new EnumItemTuple (*this); } @@ -1714,10 +1713,11 @@ public: // Returns whether struct enum item has struct fields. bool has_struct_fields () const { return !struct_fields.empty (); } - EnumItemStruct (Identifier variant_name, + EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name, std::vector<StructField> struct_fields, AST::AttrVec outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), struct_fields (std::move (struct_fields)) {} @@ -1727,7 +1727,7 @@ public: protected: // Clone function implementation as (not pure) virtual method - EnumItemStruct *clone_enum_item_impl () const override + EnumItemStruct *clone_item_impl () const override { return new EnumItemStruct (*this); } @@ -1739,9 +1739,11 @@ class EnumItemDiscriminant : public EnumItem std::unique_ptr<Expr> expression; public: - EnumItemDiscriminant (Identifier variant_name, std::unique_ptr<Expr> expr, - AST::AttrVec outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name, + std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs, + Location locus) + : EnumItem (std::move (mappings), std::move (variant_name), + std::move (outer_attrs), locus), expression (std::move (expr)) {} @@ -1771,7 +1773,7 @@ public: protected: // Clone function implementation as (not pure) virtual method - EnumItemDiscriminant *clone_enum_item_impl () const override + EnumItemDiscriminant *clone_item_impl () const override { return new EnumItemDiscriminant (*this); } @@ -1861,6 +1863,8 @@ public: void accept_vis (HIRVisitor &vis) override; + Identifier get_identifier () const { return enum_name; } + protected: /* Use covariance to implement clone function as returning this object * rather than base */ diff --git a/gcc/testsuite/rust/compile/bad_pub_enumitems.rs b/gcc/testsuite/rust/compile/bad_pub_enumitems.rs new file mode 100644 index 0000000..e7fd5ed --- /dev/null +++ b/gcc/testsuite/rust/compile/bad_pub_enumitems.rs @@ -0,0 +1,47 @@ +pub enum E +{ + pub A { a: i32 }, // { dg-error "visibility qualifier" } + B (u8), + pub C, // { dg-error "visibility qualifier" } + D +} + +enum E1 +{ + A, + pub B = 42, // { dg-error "visibility qualifier" } + C = 3, + D, + pub E // { dg-error "visibility qualifier" } +} + +enum E2 +{ + pub A (u8, i32, u64), // { dg-error "visibility qualifier" } + B { a: u8, a: u8 } // { dg-error "duplicate field" }} +} + +fn main () +{ + enum EE + { + Alpha { alpha: i32 }, + pub Beta (u8), // { dg-error "visibility qualifier" } + pub Gamma, // { dg-error "visibility qualifier" } + Delta { delta: u32 } + } + + enum EE1 + { + pub Alpha, // { dg-error "visibility qualifier" } + Beta = 41, + pub Gamma = 3, // { dg-error "visibility qualifier" } + Delta, + } + + enum E2 + { + Alpha { a: u8, a: u8 }, // { dg-error "duplicate field" }} + pub Beta (u8, i32, u64) // { dg-error "visibility qualifier" } + } +} |