aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-02-02 14:28:27 +0000
committerGitHub <noreply@github.com>2022-02-02 14:28:27 +0000
commitf7f14de056eb3887e70f29b0f29da4025f746559 (patch)
tree7a9abfd0b49074b315715fa1b2cef51951cabdca /gcc
parent6e5f8f76cbe47880ceae1bcf0bf7f07f601517ec (diff)
parent46ee20dbdbb02b40ae199293dfa774fafad72c0e (diff)
downloadgcc-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.cc10
-rw-r--r--gcc/rust/backend/rust-compile-expr.h12
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc31
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc26
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.h97
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h10
-rw-r--r--gcc/rust/typecheck/rust-tyty.h55
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