aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-07-29 16:21:33 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-04 15:48:36 +0100
commit2dc902baa1388841096e16e660082a8e79fce17e (patch)
treedfa398113378b17e22b64b952399d4ca556a393c /gcc
parentffb419d6a46302126944066ef46bd0c9f590ee30 (diff)
downloadgcc-2dc902baa1388841096e16e660082a8e79fce17e.zip
gcc-2dc902baa1388841096e16e660082a8e79fce17e.tar.gz
gcc-2dc902baa1388841096e16e660082a8e79fce17e.tar.bz2
Refactor all coercion type calls into a single coercion_site function
In order to fully support coercion sites we need a single place in order to implement the logic. This refactors all the coercion calls to have a single TypeCheckBase::coercion_site(lhs, rhs, location). Eventually we will do something similar for unifications and casts so we can improve our diagnostics.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc7
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc13
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc267
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc238
8 files changed, 288 insertions, 245 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 78c3d0f..ee8473f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -106,6 +106,7 @@ GRS_OBJS = \
rust/rust-pub-restricted-visitor.o \
rust/rust-privacy-reporter.o \
rust/rust-tyty.o \
+ rust/rust-tyty-call.o \
rust/rust-tyctx.o \
rust/rust-tyty-bounds.o \
rust/rust-hir-type-check-util.o \
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 2a47c58..092b635 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -327,5 +327,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, Location locus)
return repr;
}
+TyTy::BaseType *
+TypeCheckBase::coercion_site (TyTy::BaseType *lhs, TyTy::BaseType *rhs,
+ Location)
+{
+ return lhs->coerce (rhs);
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index f7a1bd4..9d53610 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -39,6 +39,9 @@ public:
virtual ~TypeCheckBase () {}
+ static TyTy::BaseType *coercion_site (TyTy::BaseType *lhs,
+ TyTy::BaseType *rhs, Location locus);
+
protected:
TypeCheckBase ()
: mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index df07cb3..88545c6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -380,7 +380,7 @@ public:
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
- lhs->coerce (rhs);
+ coercion_site (lhs, rhs, expr.get_locus ());
}
void visit (HIR::CompoundAssignmentExpr &expr) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index b2b68c0..11f4d64 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -99,7 +99,7 @@ public:
if (specified_ty != nullptr && init_expr_ty != nullptr)
{
// FIXME use this result and look at the regressions
- specified_ty->coerce (init_expr_ty);
+ coercion_site (specified_ty, init_expr_ty, stmt.get_locus ());
context->insert_type (stmt_pattern.get_pattern_mappings (),
specified_ty);
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 6634ad4..736bc5e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -42,8 +42,8 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
{
TyTy::BaseType *base_resolved
= TypeCheckExpr::Resolve (struct_expr.struct_base->base_struct.get ());
- struct_def
- = (TyTy::ADTType *) struct_path_resolved->coerce (base_resolved);
+ struct_def = static_cast<TyTy::ADTType *> (
+ struct_path_resolved->coerce (base_resolved));
if (struct_def == nullptr)
{
rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
@@ -221,7 +221,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
}
TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
- resolved_field_value_expr = field_type->get_field_type ()->coerce (value);
+ resolved_field_value_expr
+ = coercion_site (field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
fields_assigned.insert (field.field_name);
@@ -250,7 +251,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
}
TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
- resolved_field_value_expr = field_type->get_field_type ()->coerce (value);
+ resolved_field_value_expr
+ = coercion_site (field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
fields_assigned.insert (field_name);
@@ -284,7 +286,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field)
field.get_locus ());
TyTy::BaseType *value = TypeCheckExpr::Resolve (&expr);
- resolved_field_value_expr = field_type->get_field_type ()->coerce (value);
+ resolved_field_value_expr
+ = coercion_site (field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
new file mode 100644
index 0000000..416527e
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -0,0 +1,267 @@
+// Copyright (C) 2020-2022 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/>.
+
+#include "rust-tyty-call.h"
+#include "rust-hir-type-check-expr.h"
+
+namespace Rust {
+namespace TyTy {
+
+void
+TypeCheckCallExpr::visit (ADTType &type)
+{
+ rust_assert (!variant.is_error ());
+ if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
+ {
+ rust_error_at (
+ call.get_locus (),
+ "expected function, tuple struct or tuple variant, found struct %<%s%>",
+ type.get_name ().c_str ());
+ return;
+ }
+
+ if (call.num_params () != variant.num_fields ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) call.num_params (),
+ (unsigned long) variant.num_fields ());
+ return;
+ }
+
+ size_t i = 0;
+ for (auto &argument : call.get_arguments ())
+ {
+ StructFieldType *field = variant.get_field_at_index (i);
+ BaseType *field_tyty = field->get_field_type ();
+
+ BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ if (arg->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (argument->get_locus (),
+ "failed to resolve argument type");
+ return;
+ }
+
+ auto res = field_tyty->coerce (arg);
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ return;
+ }
+
+ delete res;
+ i++;
+ }
+
+ if (i != call.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) i, (unsigned long) call.num_params ());
+ return;
+ }
+
+ resolved = type.clone ();
+}
+
+void
+TypeCheckCallExpr::visit (FnType &type)
+{
+ type.monomorphize ();
+ if (call.num_params () != type.num_params ())
+ {
+ if (type.is_varadic ())
+ {
+ if (call.num_params () < type.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) call.num_params (),
+ (unsigned long) type.num_params ());
+ return;
+ }
+ }
+ else
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) call.num_params (),
+ (unsigned long) type.num_params ());
+ return;
+ }
+ }
+
+ size_t i = 0;
+ for (auto &argument : call.get_arguments ())
+ {
+ auto argument_expr_tyty
+ = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (
+ argument->get_locus (),
+ "failed to resolve type for argument expr in CallExpr");
+ return;
+ }
+
+ // it might be a varadic function
+ if (i < type.num_params ())
+ {
+ auto fnparam = type.param_at (i);
+ auto resolved_argument_type
+ = fnparam.second->coerce (argument_expr_tyty);
+ if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (argument->get_locus (),
+ "Type Resolution failure on parameter");
+ return;
+ }
+ }
+
+ context->insert_type (argument->get_mappings (), argument_expr_tyty);
+
+ i++;
+ }
+
+ if (i < call.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) i, (unsigned long) call.num_params ());
+ return;
+ }
+
+ type.monomorphize ();
+ resolved = type.get_return_type ()->clone ();
+}
+
+void
+TypeCheckCallExpr::visit (FnPtr &type)
+{
+ if (call.num_params () != type.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) call.num_params (),
+ (unsigned long) type.num_params ());
+ return;
+ }
+
+ size_t i = 0;
+ for (auto &argument : call.get_arguments ())
+ {
+ auto fnparam = type.param_at (i);
+ auto argument_expr_tyty
+ = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (
+ argument->get_locus (),
+ "failed to resolve type for argument expr in CallExpr");
+ return;
+ }
+
+ auto resolved_argument_type
+ = Resolver::TypeCheckBase::coercion_site (fnparam, argument_expr_tyty,
+ argument->get_locus ());
+ if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (argument->get_locus (),
+ "Type Resolution failure on parameter");
+ return;
+ }
+
+ context->insert_type (argument->get_mappings (), argument_expr_tyty);
+
+ i++;
+ }
+
+ if (i != call.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) i, (unsigned long) call.num_params ());
+ return;
+ }
+
+ resolved = type.get_return_type ()->monomorphized_clone ();
+}
+
+// method call checker
+
+void
+TypeCheckMethodCallExpr::visit (FnType &type)
+{
+ type.get_self_type ()->unify (adjusted_self);
+
+ // +1 for the receiver self
+ size_t num_args_to_call = call.num_params () + 1;
+ if (num_args_to_call != type.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) call.num_params (),
+ (unsigned long) type.num_params ());
+ return;
+ }
+
+ size_t i = 1;
+ for (auto &argument : call.get_arguments ())
+ {
+ auto fnparam = type.param_at (i);
+ auto argument_expr_tyty
+ = Resolver::TypeCheckExpr::Resolve (argument.get ());
+ if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (
+ argument->get_locus (),
+ "failed to resolve type for argument expr in CallExpr");
+ return;
+ }
+
+ auto resolved_argument_type
+ = Resolver::TypeCheckBase::coercion_site (fnparam.second,
+ argument_expr_tyty,
+ argument->get_locus ());
+ if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (argument->get_locus (),
+ "Type Resolution failure on parameter");
+ return;
+ }
+
+ context->insert_type (argument->get_mappings (), argument_expr_tyty);
+
+ i++;
+ }
+
+ if (i != num_args_to_call)
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ (unsigned long) i, (unsigned long) call.num_params ());
+ return;
+ }
+
+ type.monomorphize ();
+
+ resolved = type.get_return_type ()->monomorphized_clone ();
+}
+
+} // namespace TyTy
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 05cd8ce..daedfc3 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -3205,243 +3205,5 @@ DynamicObjectType::get_object_items () const
return items;
}
-// rust-tyty-call.h
-
-void
-TypeCheckCallExpr::visit (ADTType &type)
-{
- rust_assert (!variant.is_error ());
- if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
- {
- rust_error_at (
- call.get_locus (),
- "expected function, tuple struct or tuple variant, found struct %<%s%>",
- type.get_name ().c_str ());
- return;
- }
-
- if (call.num_params () != variant.num_fields ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) call.num_params (),
- (unsigned long) variant.num_fields ());
- return;
- }
-
- size_t i = 0;
- for (auto &argument : call.get_arguments ())
- {
- StructFieldType *field = variant.get_field_at_index (i);
- BaseType *field_tyty = field->get_field_type ();
-
- BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ());
- if (arg->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (argument->get_locus (),
- "failed to resolve argument type");
- return;
- }
-
- auto res = field_tyty->coerce (arg);
- if (res->get_kind () == TyTy::TypeKind::ERROR)
- {
- return;
- }
-
- delete res;
- i++;
- }
-
- if (i != call.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) i, (unsigned long) call.num_params ());
- return;
- }
-
- resolved = type.clone ();
-}
-
-void
-TypeCheckCallExpr::visit (FnType &type)
-{
- type.monomorphize ();
- if (call.num_params () != type.num_params ())
- {
- if (type.is_varadic ())
- {
- if (call.num_params () < type.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) call.num_params (),
- (unsigned long) type.num_params ());
- return;
- }
- }
- else
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) call.num_params (),
- (unsigned long) type.num_params ());
- return;
- }
- }
-
- size_t i = 0;
- for (auto &argument : call.get_arguments ())
- {
- auto argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (argument.get ());
- if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (
- argument->get_locus (),
- "failed to resolve type for argument expr in CallExpr");
- return;
- }
-
- // it might be a varadic function
- if (i < type.num_params ())
- {
- auto fnparam = type.param_at (i);
- auto resolved_argument_type
- = fnparam.second->coerce (argument_expr_tyty);
- if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (argument->get_locus (),
- "Type Resolution failure on parameter");
- return;
- }
- }
-
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
- i++;
- }
-
- if (i < call.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) i, (unsigned long) call.num_params ());
- return;
- }
-
- type.monomorphize ();
- resolved = type.get_return_type ()->clone ();
-}
-
-void
-TypeCheckCallExpr::visit (FnPtr &type)
-{
- if (call.num_params () != type.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) call.num_params (),
- (unsigned long) type.num_params ());
- return;
- }
-
- size_t i = 0;
- for (auto &argument : call.get_arguments ())
- {
- auto fnparam = type.param_at (i);
- auto argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (argument.get ());
- if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (
- argument->get_locus (),
- "failed to resolve type for argument expr in CallExpr");
- return;
- }
-
- auto resolved_argument_type = fnparam->coerce (argument_expr_tyty);
- if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (argument->get_locus (),
- "Type Resolution failure on parameter");
- return;
- }
-
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
- i++;
- }
-
- if (i != call.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) i, (unsigned long) call.num_params ());
- return;
- }
-
- resolved = type.get_return_type ()->monomorphized_clone ();
-}
-
-// method call checker
-
-void
-TypeCheckMethodCallExpr::visit (FnType &type)
-{
- type.get_self_type ()->unify (adjusted_self);
-
- // +1 for the receiver self
- size_t num_args_to_call = call.num_params () + 1;
- if (num_args_to_call != type.num_params ())
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) call.num_params (),
- (unsigned long) type.num_params ());
- return;
- }
-
- size_t i = 1;
- for (auto &argument : call.get_arguments ())
- {
- auto fnparam = type.param_at (i);
- auto argument_expr_tyty
- = Resolver::TypeCheckExpr::Resolve (argument.get ());
- if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (
- argument->get_locus (),
- "failed to resolve type for argument expr in CallExpr");
- return;
- }
-
- auto resolved_argument_type = fnparam.second->coerce (argument_expr_tyty);
- if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (argument->get_locus (),
- "Type Resolution failure on parameter");
- return;
- }
-
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
- i++;
- }
-
- if (i != num_args_to_call)
- {
- rust_error_at (call.get_locus (),
- "unexpected number of arguments %lu expected %lu",
- (unsigned long) i, (unsigned long) call.num_params ());
- return;
- }
-
- type.monomorphize ();
-
- resolved = type.get_return_type ()->monomorphized_clone ();
-}
-
} // namespace TyTy
} // namespace Rust