diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-07-29 16:21:33 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-08-04 15:48:36 +0100 |
commit | 2dc902baa1388841096e16e660082a8e79fce17e (patch) | |
tree | dfa398113378b17e22b64b952399d4ca556a393c /gcc | |
parent | ffb419d6a46302126944066ef46bd0c9f590ee30 (diff) | |
download | gcc-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.in | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.cc | 7 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.h | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-struct.cc | 13 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.cc | 267 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 238 |
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 |