diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-02-02 14:28:27 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-02 14:28:27 +0000 |
commit | f7f14de056eb3887e70f29b0f29da4025f746559 (patch) | |
tree | 7a9abfd0b49074b315715fa1b2cef51951cabdca /gcc | |
parent | 6e5f8f76cbe47880ceae1bcf0bf7f07f601517ec (diff) | |
parent | 46ee20dbdbb02b40ae199293dfa774fafad72c0e (diff) | |
download | gcc-f7f14de056eb3887e70f29b0f29da4025f746559.zip gcc-f7f14de056eb3887e70f29b0f29da4025f746559.tar.gz gcc-f7f14de056eb3887e70f29b0f29da4025f746559.tar.bz2 |
Merge #902
902: Fix enum variant discriminant values r=philberty a=philberty
Enum discriminants before this patch were either:
- The hir-id of the tuple/struct variant
- The expression of the specified discriminant
- Computed int64 of the dataless variant
Each of these had tree ways of computing the qualifier this patch changes
this to be more in line with rust to compute the values unless its a
specified discriminant value. In order to compile this we now create an
implicit HIR::LiteralExpr and feed this into our constexpr code so it
reuses the same path as the variants with a specified constant
discriminant.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 10 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 12 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.cc | 31 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 26 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-enumitem.h | 97 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 55 |
9 files changed, 134 insertions, 126 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 1048027..ae4a841 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -397,13 +397,11 @@ CompileExpr::visit (HIR::CallExpr &expr) std::vector<tree> ctor_arguments; if (adt->is_enum ()) { - HirId variant_id = variant->get_id (); - mpz_t val; - mpz_init_set_ui (val, variant_id); + HIR::Expr *discrim_expr = variant->get_discriminant (); + tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); + tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); + tree qualifier = folded_discrim_expr; - tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx); - tree qualifier - = double_int_to_tree (t, mpz_get_double_int (t, val, true)); ctor_arguments.push_back (qualifier); } for (auto &arg : arguments) diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 4cc4dfc..43eff72 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -24,6 +24,7 @@ #include "rust-compile-resolve-path.h" #include "rust-compile-block.h" #include "rust-compile-struct-field-expr.h" +#include "rust-constexpr.h" namespace Rust { namespace Compile { @@ -488,13 +489,10 @@ public: std::vector<tree> ctor_arguments; if (adt->is_enum ()) { - HirId variant_id = variant->get_id (); - mpz_t val; - mpz_init_set_ui (val, variant_id); - - tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx); - tree qualifier - = double_int_to_tree (t, mpz_get_double_int (t, val, true)); + HIR::Expr *discrim_expr = variant->get_discriminant (); + tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); + tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); + tree qualifier = folded_discrim_expr; ctor_arguments.push_back (qualifier); } diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index b255dc6..d715c7c 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -48,33 +48,10 @@ CompilePatternCaseLabelExpr::visit (HIR::PathInExpression &pattern) ok = adt->lookup_variant_by_id (variant_id, &variant); rust_assert (ok); - tree case_low = error_mark_node; - if (variant->is_specified_discriminant_node ()) - { - auto discrim_node = variant->get_discriminant_node (); - auto &discrim_expr = discrim_node->get_discriminant_expression (); - - tree discrim_expr_node = CompileExpr::Compile (discrim_expr.get (), ctx); - tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); - case_low = folded_discrim_expr; - } - else - { - mpz_t disciminantl; - if (variant->get_variant_type () == TyTy::VariantDef::VariantType::NUM) - { - mpz_init_set_ui (disciminantl, variant->get_discriminant ()); - } - else - { - HirId variant_id = variant->get_id (); - mpz_init_set_ui (disciminantl, variant_id); - } - - tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx); - case_low - = double_int_to_tree (t, mpz_get_double_int (t, disciminantl, true)); - } + HIR::Expr *discrim_expr = variant->get_discriminant (); + tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); + tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); + tree case_low = folded_discrim_expr; case_label_expr = build_case_label (case_low, NULL_TREE, associated_case_label); diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index ddb6c91..c624046 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -86,8 +86,8 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, &union_disriminator)) return ctx->get_backend ()->error_expression (); - // FIXME should really return error_mark_node and or rust_internal_error - // error_mark_node + // this can only be for discriminant variants the others are built up + // using call-expr or struct-init rust_assert (variant->get_variant_type () == TyTy::VariantDef::VariantType::NUM); @@ -95,24 +95,10 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt); // make the ctor for the union - tree qualifier = error_mark_node; - if (variant->is_specified_discriminant_node ()) - { - auto discrim_node = variant->get_discriminant_node (); - auto &discrim_expr = discrim_node->get_discriminant_expression (); - - tree discrim_expr_node - = CompileExpr::Compile (discrim_expr.get (), ctx); - tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); - qualifier = folded_discrim_expr; - } - else - { - mpz_t val; - mpz_init_set_ui (val, variant->get_discriminant ()); - tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx); - qualifier = double_int_to_tree (t, mpz_get_double_int (t, val, true)); - } + HIR::Expr *discrim_expr = variant->get_discriminant (); + tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); + tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node); + tree qualifier = folded_discrim_expr; return ctx->get_backend ()->constructor_expression (compiled_adt_type, true, {qualifier}, diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 234d865..cff3dbb 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -340,6 +340,15 @@ public: } /* EnumItem doesn't need to be handled, no fields. */ + void visit (AST::EnumItem &item) override + { + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + } void visit (AST::EnumItemTuple &item) override { diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h index d3be747..83d9cf5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h @@ -48,9 +48,30 @@ public: if (last_discriminant == INT64_MAX) rust_error_at (item.get_locus (), "discriminant too big"); - variant - = new TyTy::VariantDef (item.get_mappings ().get_hirid (), - item.get_identifier (), last_discriminant + 1); + Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + mappings->get_next_hir_id ( + item.get_mappings ().get_crate_num ()), + item.get_mappings ().get_local_defid ()); + HIR::LiteralExpr *discim_expr + = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant), + HIR::Literal::LitType::INT, + PrimitiveCoreType::CORETYPE_I64, + item.get_locus ()); + + TyTy::BaseType *isize = nullptr; + bool ok = context->lookup_builtin ("isize", &isize); + rust_assert (ok); + context->insert_type (mapping, isize); + + const CanonicalPath *canonical_path = nullptr; + ok = mappings->lookup_canonical_path (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + &canonical_path); + rust_assert (ok); + + variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (), + item.get_identifier (), discim_expr); } void visit (HIR::EnumItemDiscriminant &item) override @@ -71,8 +92,16 @@ public: if (unified->get_kind () == TyTy::TypeKind::ERROR) return; + const CanonicalPath *canonical_path = nullptr; + bool ok + = mappings->lookup_canonical_path (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + &canonical_path); + rust_assert (ok); + variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (), - item.get_identifier (), &item); + item.get_identifier (), + item.get_discriminant_expression ().get ()); } void visit (HIR::EnumItemTuple &item) override @@ -95,10 +124,32 @@ public: idx++; } - variant - = new TyTy::VariantDef (item.get_mappings ().get_hirid (), - item.get_identifier (), - TyTy::VariantDef::VariantType::TUPLE, fields); + Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + mappings->get_next_hir_id ( + item.get_mappings ().get_crate_num ()), + item.get_mappings ().get_local_defid ()); + HIR::LiteralExpr *discim_expr + = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant), + HIR::Literal::LitType::INT, + PrimitiveCoreType::CORETYPE_I64, + item.get_locus ()); + + TyTy::BaseType *isize = nullptr; + bool ok = context->lookup_builtin ("isize", &isize); + rust_assert (ok); + context->insert_type (mapping, isize); + + const CanonicalPath *canonical_path = nullptr; + ok = mappings->lookup_canonical_path (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + &canonical_path); + rust_assert (ok); + + variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (), + item.get_identifier (), + TyTy::VariantDef::VariantType::TUPLE, + discim_expr, fields); } void visit (HIR::EnumItemStruct &item) override @@ -119,10 +170,32 @@ public: ty_field->get_field_type ()); } - variant - = new TyTy::VariantDef (item.get_mappings ().get_hirid (), - item.get_identifier (), - TyTy::VariantDef::VariantType::STRUCT, fields); + Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + mappings->get_next_hir_id ( + item.get_mappings ().get_crate_num ()), + item.get_mappings ().get_local_defid ()); + HIR::LiteralExpr *discrim_expr + = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant), + HIR::Literal::LitType::INT, + PrimitiveCoreType::CORETYPE_I64, + item.get_locus ()); + + TyTy::BaseType *isize = nullptr; + bool ok = context->lookup_builtin ("isize", &isize); + rust_assert (ok); + context->insert_type (mapping, isize); + + const CanonicalPath *canonical_path = nullptr; + ok = mappings->lookup_canonical_path (item.get_mappings ().get_crate_num (), + item.get_mappings ().get_nodeid (), + &canonical_path); + rust_assert (ok); + + variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (), + item.get_identifier (), + TyTy::VariantDef::VariantType::STRUCT, + discrim_expr, fields); } private: diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index 5f24df4..b287fe5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -171,7 +171,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (), - TyTy::VariantDef::VariantType::TUPLE, std::move (fields))); + TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), @@ -219,10 +219,8 @@ public: TyTy::VariantDef *field_type = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value); + discriminant_value++; variants.push_back (field_type); - if (field_type->get_variant_type () - == TyTy::VariantDef::VariantType::NUM) - discriminant_value = field_type->get_discriminant (); } TyTy::BaseType *type @@ -281,7 +279,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (), - TyTy::VariantDef::VariantType::STRUCT, std::move (fields))); + TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), @@ -339,7 +337,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (), - TyTy::VariantDef::VariantType::STRUCT, std::move (fields))); + TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (), diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index c0fa91e..c447920 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -106,7 +106,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (), - TyTy::VariantDef::VariantType::TUPLE, std::move (fields))); + TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), @@ -175,7 +175,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (), - TyTy::VariantDef::VariantType::STRUCT, std::move (fields))); + TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), @@ -222,10 +222,8 @@ public: TyTy::VariantDef *field_type = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value); + discriminant_value++; variants.push_back (field_type); - if (field_type->get_variant_type () - == TyTy::VariantDef::VariantType::NUM) - discriminant_value = field_type->get_discriminant (); } TyTy::BaseType *type @@ -288,7 +286,7 @@ public: std::vector<TyTy::VariantDef *> variants; variants.push_back (new TyTy::VariantDef ( union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (), - TyTy::VariantDef::VariantType::STRUCT, std::move (fields))); + TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields))); TyTy::BaseType *type = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (), diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index f99d8ce..6f392b0 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -1027,44 +1027,26 @@ public: return ""; } - VariantDef (HirId id, std::string identifier, int discriminant) - : id (id), identifier (identifier), discriminant (discriminant), - discriminant_node (nullptr) + VariantDef (HirId id, std::string identifier, HIR::Expr *discriminant) + : id (id), identifier (identifier), discriminant (discriminant) { type = VariantType::NUM; fields = {}; } - VariantDef (HirId id, std::string identifier, - HIR::EnumItemDiscriminant *discriminant) - : id (id), identifier (identifier), discriminant_node (discriminant) - { - type = VariantType::NUM; - fields = {}; - } - - VariantDef (HirId id, std::string identifier, VariantType type, - std::vector<StructFieldType *> fields) - : id (id), identifier (identifier), type (type), fields (fields), - discriminant_node (nullptr) - { - discriminant = 0; - rust_assert (type == VariantType::TUPLE || type == VariantType::STRUCT); - } - VariantDef (HirId id, std::string identifier, VariantType type, - int discriminant, std::vector<StructFieldType *> fields) + HIR::Expr *discriminant, std::vector<StructFieldType *> fields) : id (id), identifier (identifier), type (type), discriminant (discriminant), fields (fields) { - rust_assert ((type == VariantType::NUM && fields.empty ()) - || (type == VariantType::TUPLE && discriminant == 0) - || (type == VariantType::STRUCT && discriminant == 0)); + rust_assert ( + (type == VariantType::NUM && fields.empty ()) + || (type == VariantType::TUPLE || type == VariantType::STRUCT)); } static VariantDef &get_error_node () { - static VariantDef node = VariantDef (UNKNOWN_HIRID, "", -1); + static VariantDef node = VariantDef (UNKNOWN_HIRID, "", nullptr); return node; } @@ -1078,12 +1060,6 @@ public: std::string get_identifier () const { return identifier; } - int get_discriminant () const - { - rust_assert (!is_specified_discriminant_node ()); - return discriminant; - } - size_t num_fields () const { return fields.size (); } StructFieldType *get_field_at_index (size_t index) { @@ -1118,21 +1094,16 @@ public: return false; } - bool is_specified_discriminant_node () const + HIR::Expr *get_discriminant () const { - return discriminant_node != nullptr; - } - - HIR::EnumItemDiscriminant *get_discriminant_node () const - { - rust_assert (is_specified_discriminant_node ()); - return discriminant_node; + rust_assert (discriminant != nullptr); + return discriminant; } std::string as_string () const { if (type == VariantType::NUM) - return identifier + " = " + std::to_string (discriminant); + return identifier + " = " + discriminant->as_string (); std::string buffer; for (size_t i = 0; i < fields.size (); ++i) @@ -1184,9 +1155,9 @@ private: HirId id; std::string identifier; VariantType type; - int discriminant; /* Either discriminant or fields are valid. */ + // can either be a structure or a discriminant value + HIR::Expr *discriminant; std::vector<StructFieldType *> fields; - HIR::EnumItemDiscriminant *discriminant_node; }; class ADTType : public BaseType, public SubstitutionRef |