diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-09-06 16:52:46 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-06 16:52:46 +0000 |
commit | 8a9271e1921d0eac46bda889da6508cf94d32682 (patch) | |
tree | e31ad30bd83f58c5944d9b66b7666190f0b338f1 | |
parent | 50623899998de5a8ffe47227a351c2b3dd29aa0a (diff) | |
parent | eaf5bc5c38412514a5abb028fca343c838ac51ca (diff) | |
download | gcc-8a9271e1921d0eac46bda889da6508cf94d32682.zip gcc-8a9271e1921d0eac46bda889da6508cf94d32682.tar.gz gcc-8a9271e1921d0eac46bda889da6508cf94d32682.tar.bz2 |
Merge #657
657: Add building blocks for enum support r=philberty a=philberty
see https://gcc.gnu.org/pipermail/gcc-rust/2021-September/000174.html
This set of patches adds support for parsing, name resolution and HIR lowering for enums.
Typechecking and code-generation are still in progress but these patches are ready to merge now.
Co-authored-by: Mark Wielaard <mark@klomp.org>
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 6 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 58 | ||||
-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/rust/parse/rust-parse-impl.h | 12 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 36 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.h | 105 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 69 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_pub_enumitems.rs | 47 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_stmt_enums.rs | 22 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_toplevel_enums.rs | 19 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs | 7 |
17 files changed, 698 insertions, 154 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 6241710..2477d74 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -3311,10 +3311,8 @@ StructExprStructFields::as_string () const std::string EnumItem::as_string () const { - // outer attributes - std::string str = append_attributes (outer_attrs, OUTER); - - str += "\n" + variant_name; + std::string str = VisItem::as_string (); + str += variant_name; return str; } diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 0578329..881a888 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -2119,12 +2119,10 @@ protected: }; /* An item used in an "enum" tagged union - not abstract: base represents a - * name-only enum */ -class EnumItem + * name-only enum. EnumItems (variants) syntactically allow a Visibility + * annotation. */ +class EnumItem : public VisItem { - // bool has_attrs; - std::vector<Attribute> outer_attrs; - Identifier variant_name; Location locus; @@ -2132,19 +2130,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, std::vector<Attribute> outer_attrs, - Location locus) - : outer_attrs (std::move (outer_attrs)), + EnumItem (Identifier variant_name, Visibility vis, + std::vector<Attribute> outer_attrs, Location locus) + : VisItem (std::move (vis), 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; @@ -2152,20 +2147,16 @@ public: // not pure virtual as not abstract virtual void accept_vis (ASTVisitor &vis); + Location get_locus () const { return locus; } + + Identifier get_identifier () const { return variant_name; } + // Based on idea that name is never empty. void mark_for_strip () { variant_name = ""; } bool is_marked_for_strip () const { return variant_name.empty (); } - // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - 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 @@ -2178,9 +2169,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, + EnumItemTuple (Identifier variant_name, Visibility vis, + std::vector<TupleField> tuple_fields, std::vector<Attribute> outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + : EnumItem (std::move (variant_name), std::move (vis), + std::move (outer_attrs), locus), tuple_fields (std::move (tuple_fields)) {} @@ -2197,7 +2190,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); } @@ -2213,10 +2206,11 @@ public: // Returns whether struct enum item has struct fields. bool has_struct_fields () const { return !struct_fields.empty (); } - EnumItemStruct (Identifier variant_name, + EnumItemStruct (Identifier variant_name, Visibility vis, std::vector<StructField> struct_fields, std::vector<Attribute> outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + : EnumItem (std::move (variant_name), std::move (vis), + std::move (outer_attrs), locus), struct_fields (std::move (struct_fields)) {} @@ -2233,7 +2227,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); } @@ -2245,9 +2239,11 @@ class EnumItemDiscriminant : public EnumItem std::unique_ptr<Expr> expression; public: - EnumItemDiscriminant (Identifier variant_name, std::unique_ptr<Expr> expr, + EnumItemDiscriminant (Identifier variant_name, Visibility vis, + std::unique_ptr<Expr> expr, std::vector<Attribute> outer_attrs, Location locus) - : EnumItem (std::move (variant_name), std::move (outer_attrs), locus), + : EnumItem (std::move (variant_name), std::move (vis), + std::move (outer_attrs), locus), expression (std::move (expr)) {} @@ -2284,7 +2280,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); } @@ -2374,6 +2370,8 @@ public: void accept_vis (ASTVisitor &vis) override; + Identifier get_identifier () const { return enum_name; } + // Invalid if name is empty, so base stripping on that. void mark_for_strip () override { enum_name = ""; } bool is_marked_for_strip () const override { return enum_name.empty (); } 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/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 1c0644d..8cce933 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -4431,6 +4431,9 @@ Parser<ManagedTokenSource>::parse_enum_item () // parse outer attributes if they exist AST::AttrVec outer_attrs = parse_outer_attributes (); + // parse visibility, which may or may not exist + AST::Visibility vis = parse_visibility (); + // parse name for enum item, which is required const_TokenPtr item_name_tok = lexer.peek_token (); if (item_name_tok->get_id () != IDENTIFIER) @@ -4463,7 +4466,7 @@ Parser<ManagedTokenSource>::parse_enum_item () } return std::unique_ptr<AST::EnumItemTuple> (new AST::EnumItemTuple ( - std::move (item_name), std::move (tuple_fields), + std::move (item_name), std::move (vis), std::move (tuple_fields), std::move (outer_attrs), item_name_tok->get_locus ())); } case LEFT_CURLY: { @@ -4480,7 +4483,7 @@ Parser<ManagedTokenSource>::parse_enum_item () } return std::unique_ptr<AST::EnumItemStruct> (new AST::EnumItemStruct ( - std::move (item_name), std::move (struct_fields), + std::move (item_name), std::move (vis), std::move (struct_fields), std::move (outer_attrs), item_name_tok->get_locus ())); } case EQUAL: { @@ -4490,7 +4493,7 @@ Parser<ManagedTokenSource>::parse_enum_item () std::unique_ptr<AST::Expr> discriminant_expr = parse_expr (); return std::unique_ptr<AST::EnumItemDiscriminant> ( - new AST::EnumItemDiscriminant (std::move (item_name), + new AST::EnumItemDiscriminant (std::move (item_name), std::move (vis), std::move (discriminant_expr), std::move (outer_attrs), item_name_tok->get_locus ())); @@ -4498,7 +4501,8 @@ Parser<ManagedTokenSource>::parse_enum_item () default: // regular enum with just an identifier return std::unique_ptr<AST::EnumItem> ( - new AST::EnumItem (std::move (item_name), std::move (outer_attrs), + new AST::EnumItem (std::move (item_name), std::move (vis), + std::move (outer_attrs), item_name_tok->get_locus ())); } } diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index d3c053b..2a2f956 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -260,6 +260,42 @@ public: resolver->get_type_scope ().pop (); } + void visit (AST::Enum &enum_decl) override + { + NodeId scope_node_id = enum_decl.get_node_id (); + resolver->get_type_scope ().push (scope_node_id); + + if (enum_decl.has_generics ()) + { + for (auto &generic : enum_decl.get_generic_params ()) + { + ResolveGenericParam::go (generic.get (), enum_decl.get_node_id ()); + } + } + + /* The actual fields are inside the variants. */ + for (auto &variant : enum_decl.get_variants ()) + ResolveItem::go (variant.get ()); + + resolver->get_type_scope ().pop (); + } + + /* EnumItem doesn't need to be handled, no fields. */ + + void visit (AST::EnumItemTuple &item) override + { + for (auto &field : item.get_tuple_fields ()) + ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); + } + + void visit (AST::EnumItemStruct &item) override + { + for (auto &field : item.get_struct_fields ()) + ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); + } + + /* EnumItemDiscriminant doesn't need to be handled, no fields. */ + void visit (AST::StructStruct &struct_decl) override { NodeId scope_node_id = struct_decl.get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index b604432..43bf0a4 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -33,9 +33,11 @@ class ResolveStmt : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::Stmt *stmt, NodeId parent) + static void go (AST::Stmt *stmt, NodeId parent, + const CanonicalPath &enum_prefix + = CanonicalPath::create_empty ()) { - ResolveStmt resolver (parent); + ResolveStmt resolver (parent, enum_prefix); stmt->accept_vis (resolver); }; @@ -98,6 +100,97 @@ public: resolver->get_type_scope ().pop (); } + void visit (AST::Enum &enum_decl) override + { + auto enum_path = CanonicalPath::new_seg (enum_decl.get_node_id (), + enum_decl.get_identifier ()); + resolver->get_type_scope ().insert ( + enum_path, enum_decl.get_node_id (), enum_decl.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (enum_decl.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + NodeId scope_node_id = enum_decl.get_node_id (); + resolver->get_type_scope ().push (scope_node_id); + + if (enum_decl.has_generics ()) + { + for (auto &generic : enum_decl.get_generic_params ()) + { + ResolveGenericParam::go (generic.get (), enum_decl.get_node_id ()); + } + } + + for (auto &variant : enum_decl.get_variants ()) + ResolveStmt::go (variant.get (), parent, enum_path); + + resolver->get_type_scope ().pop (); + } + + void visit (AST::EnumItem &item) override + { + auto path = enum_prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + // Done, no fields. + } + + void visit (AST::EnumItemTuple &item) override + { + auto path = enum_prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + for (auto &field : item.get_tuple_fields ()) + ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); + } + + void visit (AST::EnumItemStruct &item) override + { + auto path = enum_prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + for (auto &field : item.get_struct_fields ()) + ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); + } + + void visit (AST::EnumItemDiscriminant &item) override + { + auto path = enum_prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + // Done, no fields. + } + void visit (AST::StructStruct &struct_decl) override { auto path = CanonicalPath::new_seg (struct_decl.get_node_id (), @@ -219,7 +312,13 @@ public: } private: - ResolveStmt (NodeId parent) : ResolverBase (parent) {} + ResolveStmt (NodeId parent, const CanonicalPath &enum_prefix) + : ResolverBase (parent), enum_prefix (enum_prefix) + {} + + /* item declaration statements are not given a canonical path, but enum items + * (variants) do inherit the enum path/identifier name. */ + const CanonicalPath &enum_prefix; }; } // namespace Resolver diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 1239206..6f802a5 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -88,6 +88,75 @@ public: }); } + void visit (AST::Enum &enum_decl) override + { + auto path + = prefix.append (CanonicalPath::new_seg (enum_decl.get_node_id (), + enum_decl.get_identifier ())); + resolver->get_type_scope ().insert ( + path, enum_decl.get_node_id (), enum_decl.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (enum_decl.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + for (auto &variant : enum_decl.get_variants ()) + ResolveTopLevel::go (variant.get (), path); + } + + void visit (AST::EnumItem &item) override + { + auto path = prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + } + + void visit (AST::EnumItemTuple &item) override + { + auto path = prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + } + + void visit (AST::EnumItemStruct &item) override + { + auto path = prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + } + + void visit (AST::EnumItemDiscriminant &item) override + { + auto path = prefix.append ( + CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + resolver->get_type_scope ().insert ( + path, item.get_node_id (), item.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (item.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + } + void visit (AST::StructStruct &struct_decl) override { auto path 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" } + } +} diff --git a/gcc/testsuite/rust/compile/bad_stmt_enums.rs b/gcc/testsuite/rust/compile/bad_stmt_enums.rs new file mode 100644 index 0000000..7b09a94 --- /dev/null +++ b/gcc/testsuite/rust/compile/bad_stmt_enums.rs @@ -0,0 +1,22 @@ +fn main () +{ + enum EE + { + Alpha { alpha: i32 }, + pub Beta (u8), + pub Gamma, + Gamma { gamma: u32 } // { dg-error "redefined" } + } + + struct EE2 { } + enum EE2 { } // { dg-error "redefined" } + + enum EE1 + { + pub Alpha, + Beta = 41, + Beta = 42, // { dg-error "redefined" } + pub Gamma = 3, + D, + } +} diff --git a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs new file mode 100644 index 0000000..b655e30 --- /dev/null +++ b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs @@ -0,0 +1,19 @@ +pub enum E +{ + pub A { a: i32 }, + B (u8), + pub C, + B // { dg-error "redefined" } +} + +enum E2 { } +struct E2 { } // { dg-error "redefined" } + +enum E1 +{ + A, + pub B = 42, + C = 3, + A { a: u8 }, // { dg-error "redefined" } + pub D +} diff --git a/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs b/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs index 26e3e5d..f65bd3b 100644 --- a/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs +++ b/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs @@ -1,4 +1,9 @@ -enum E { T0(), T1(i32), T2(i32,u32) } +enum E // { dg-warning "unused name" } +{ + T0(), // { dg-warning "unused name" } + T1(i32), // { dg-warning "unused name" } + T2(i32,u32) // { dg-warning "unused name" } +} /* The following doesn't parse yet... fn f(e0: E, e1: E, e2: E) -> (E,E,E,()) |