public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Support Typechecking of ADT's of enums
@ 2022-06-08 11:46 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:46 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e3defa10bc63ba3f81da00fc322b5b1e0d1717ed
commit e3defa10bc63ba3f81da00fc322b5b1e0d1717ed
Author: Philip Herron <philip.herron@embecosm.com>
Date: Sun Oct 31 00:02:58 2021 +0100
Support Typechecking of ADT's of enums
Enums are ADT's with multiple variants where as structs are ADT's with a
single variant, this changes the typechecking on construction of these to
support enums.
Addresses #79
Diff:
---
gcc/rust/typecheck/rust-hir-type-check-expr.h | 28 ++++++++++++++++-
gcc/rust/typecheck/rust-hir-type-check-path.cc | 19 +++++++++++-
.../typecheck/rust-hir-type-check-struct-field.h | 4 ++-
gcc/rust/typecheck/rust-hir-type-check-struct.cc | 35 ++++++++++++----------
gcc/rust/typecheck/rust-hir-type-check.h | 21 +++++++++++++
gcc/rust/typecheck/rust-tyty-call.h | 11 ++++---
gcc/rust/typecheck/rust-tyty.cc | 13 ++++----
gcc/rust/typecheck/rust-tyty.h | 21 +++++++++++++
8 files changed, 121 insertions(+), 31 deletions(-)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 851407e04b3..2a6bae9ca7d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -198,7 +198,33 @@ public:
return;
}
- infered = TyTy::TypeCheckCallExpr::go (function_tyty, expr, context);
+ TyTy::VariantDef &variant = TyTy::VariantDef::get_error_node ();
+ if (function_tyty->get_kind () == TyTy::TypeKind::ADT)
+ {
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (function_tyty);
+ if (adt->is_enum ())
+ {
+ // lookup variant id
+ HirId variant_id;
+ bool ok = context->lookup_variant_definition (
+ expr.get_fnexpr ()->get_mappings ().get_hirid (), &variant_id);
+ rust_assert (ok);
+
+ TyTy::VariantDef *lookup_variant = nullptr;
+ ok = adt->lookup_variant_by_id (variant_id, &lookup_variant);
+ rust_assert (ok);
+
+ variant = *lookup_variant;
+ }
+ else
+ {
+ rust_assert (adt->number_of_variants () == 1);
+ variant = *adt->get_variants ().at (0);
+ }
+ }
+
+ infered
+ = TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
if (infered == nullptr)
{
rust_error_at (expr.get_locus (), "failed to lookup type to CallExpr");
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 20f71563dca..8aa4484f628 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -359,7 +359,24 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
prev_segment = tyseg;
tyseg = candidate.ty;
- if (candidate.is_impl_candidate ())
+ if (candidate.is_enum_candidate ())
+ {
+ const TyTy::VariantDef *variant = candidate.item.enum_field.variant;
+
+ CrateNum crate_num = mappings->get_current_crate ();
+ HirId variant_id = variant->get_id ();
+
+ HIR::Item *enum_item
+ = mappings->lookup_hir_item (crate_num, variant_id);
+ rust_assert (enum_item != nullptr);
+
+ resolved_node_id = enum_item->get_mappings ().get_nodeid ();
+
+ // insert the id of the variant we are resolved to
+ context->insert_variant_definition (expr_mappings.get_hirid (),
+ variant_id);
+ }
+ else if (candidate.is_impl_candidate ())
{
resolved_node_id
= candidate.item.impl.impl_item->get_impl_mappings ().get_nodeid ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
index 6aa3134c553..4c4b128fc98 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
@@ -51,7 +51,8 @@ private:
TypeCheckStructExpr (HIR::Expr *e)
: TypeCheckBase (),
resolved (new TyTy::ErrorType (e->get_mappings ().get_hirid ())),
- struct_path_resolved (nullptr)
+ struct_path_resolved (nullptr),
+ variant (&TyTy::VariantDef::get_error_node ())
{}
// result
@@ -59,6 +60,7 @@ private:
// internal state:
TyTy::ADTType *struct_path_resolved;
+ TyTy::VariantDef *variant;
TyTy::BaseType *resolved_field_value_expr;
std::set<std::string> fields_assigned;
std::map<size_t, HIR::StructExprField *> adtFieldIndexToField;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index eedd5817ac9..78340c3f182 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -53,6 +53,25 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
}
}
+ // figure out the variant
+ if (struct_path_resolved->is_enum ())
+ {
+ // lookup variant id
+ HirId variant_id;
+ bool ok = context->lookup_variant_definition (
+ struct_expr.get_struct_name ().get_mappings ().get_hirid (),
+ &variant_id);
+ rust_assert (ok);
+
+ ok = struct_path_resolved->lookup_variant_by_id (variant_id, &variant);
+ rust_assert (ok);
+ }
+ else
+ {
+ rust_assert (struct_path_resolved->number_of_variants () == 1);
+ variant = struct_path_resolved->get_variants ().at (0);
+ }
+
std::vector<TyTy::StructFieldType *> infered_fields;
bool ok = true;
@@ -80,10 +99,6 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
}
// check the arguments are all assigned and fix up the ordering
- rust_assert (!struct_path_resolved->is_enum ());
- rust_assert (struct_path_resolved->number_of_variants () == 1);
- TyTy::VariantDef *variant = struct_path_resolved->get_variants ().at (0);
-
if (fields_assigned.size () != variant->num_fields ())
{
if (struct_def->is_union ())
@@ -197,10 +212,6 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
return;
}
- rust_assert (!struct_path_resolved->is_enum ());
- rust_assert (struct_path_resolved->number_of_variants () == 1);
- TyTy::VariantDef *variant = struct_path_resolved->get_variants ().at (0);
-
size_t field_index;
TyTy::StructFieldType *field_type;
bool ok = variant->lookup_field (field.field_name, &field_type, &field_index);
@@ -230,10 +241,6 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
return;
}
- rust_assert (!struct_path_resolved->is_enum ());
- rust_assert (struct_path_resolved->number_of_variants () == 1);
- TyTy::VariantDef *variant = struct_path_resolved->get_variants ().at (0);
-
size_t field_index;
TyTy::StructFieldType *field_type;
bool ok = variant->lookup_field (field_name, &field_type, &field_index);
@@ -262,10 +269,6 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field)
return;
}
- rust_assert (!struct_path_resolved->is_enum ());
- rust_assert (struct_path_resolved->number_of_variants () == 1);
- TyTy::VariantDef *variant = struct_path_resolved->get_variants ().at (0);
-
size_t field_index;
TyTy::StructFieldType *field_type;
bool ok = variant->lookup_field (field.get_field_name (), &field_type,
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 76eac3feae9..aa10f411d01 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -214,6 +214,24 @@ public:
return true;
}
+ void insert_variant_definition (HirId id, HirId variant)
+ {
+ auto it = variants.find (id);
+ rust_assert (it == variants.end ());
+
+ variants[id] = variant;
+ }
+
+ bool lookup_variant_definition (HirId id, HirId *variant)
+ {
+ auto it = variants.find (id);
+ if (it == variants.end ())
+ return false;
+
+ *variant = it->second;
+ return true;
+ }
+
private:
TypeCheckContext ();
@@ -234,6 +252,9 @@ private:
// adjustment mappings
std::map<HirId, std::vector<Adjustment>> autoderef_mappings;
+
+ // variants
+ std::map<HirId, HirId> variants;
};
class TypeResolution
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index c7001dd37d8..9ff5f6f3934 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -32,9 +32,10 @@ class TypeCheckCallExpr : private TyVisitor
{
public:
static BaseType *go (BaseType *ref, HIR::CallExpr &call,
+ TyTy::VariantDef &variant,
Resolver::TypeCheckContext *context)
{
- TypeCheckCallExpr checker (call, context);
+ TypeCheckCallExpr checker (call, variant, context);
ref->accept_vis (checker);
return checker.resolved;
}
@@ -58,6 +59,7 @@ public:
void visit (PlaceholderType &) override { gcc_unreachable (); }
void visit (ProjectionType &) override { gcc_unreachable (); }
void visit (DynamicObjectType &) override { gcc_unreachable (); }
+ void visit (ClosureType &type) override { gcc_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
@@ -65,16 +67,17 @@ public:
// call fns
void visit (FnType &type) override;
void visit (FnPtr &type) override;
- void visit (ClosureType &type) override { gcc_unreachable (); }
private:
- TypeCheckCallExpr (HIR::CallExpr &c, Resolver::TypeCheckContext *context)
- : resolved (nullptr), call (c), context (context),
+ TypeCheckCallExpr (HIR::CallExpr &c, TyTy::VariantDef &variant,
+ Resolver::TypeCheckContext *context)
+ : resolved (nullptr), call (c), variant (variant), context (context),
mappings (Analysis::Mappings::get ())
{}
BaseType *resolved;
HIR::CallExpr &call;
+ TyTy::VariantDef &variant;
Resolver::TypeCheckContext *context;
Analysis::Mappings *mappings;
};
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 9f345c3c259..16cabc8bb1b 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2537,7 +2537,8 @@ DynamicObjectType::get_object_items () const
void
TypeCheckCallExpr::visit (ADTType &type)
{
- if (!type.is_tuple_struct ())
+ rust_assert (!variant.is_error ());
+ if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
{
rust_error_at (
call.get_locus (),
@@ -2546,22 +2547,18 @@ TypeCheckCallExpr::visit (ADTType &type)
return;
}
- rust_assert (!type.is_enum ());
- rust_assert (type.number_of_variants () == 1);
- TyTy::VariantDef *variant = type.get_variants ().at (0);
-
- if (call.num_params () != variant->num_fields ())
+ if (call.num_params () != variant.num_fields ())
{
rust_error_at (call.get_locus (),
"unexpected number of arguments %lu expected %lu",
- call.num_params (), variant->num_fields ());
+ call.num_params (), variant.num_fields ());
return;
}
size_t i = 0;
for (auto &argument : call.get_arguments ())
{
- StructFieldType *field = variant->get_field_at_index (i);
+ StructFieldType *field = variant.get_field_at_index (i);
BaseType *field_tyty = field->get_field_type ();
BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get (), false);
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 473572f39e9..5ffd95c29da 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1045,6 +1045,14 @@ public:
|| (type == VariantType::STRUCT && discriminant == 0));
}
+ static VariantDef &get_error_node ()
+ {
+ static VariantDef node = VariantDef (UNKNOWN_HIRID, "", -1);
+ return node;
+ }
+
+ bool is_error () const { return get_id () == UNKNOWN_HIRID; }
+
HirId get_id () const { return id; }
VariantType get_variant_type () const { return type; }
@@ -1249,6 +1257,19 @@ public:
return false;
}
+ bool lookup_variant_by_id (HirId id, VariantDef **found_variant) const
+ {
+ for (auto &variant : variants)
+ {
+ if (variant->get_id () == id)
+ {
+ *found_variant = variant;
+ return true;
+ }
+ }
+ return false;
+ }
+
ADTType *
handle_substitions (SubstitutionArgumentMappings mappings) override final;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-08 11:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:46 [gcc/devel/rust/master] Support Typechecking of ADT's of enums Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).