diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.cc | 246 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 10 |
4 files changed, 260 insertions, 0 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 9de93fe..69943f9 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -95,6 +95,7 @@ GRS_OBJS = \ rust/rust-hir-type-check-type.o \ rust/rust-hir-type-check-struct.o \ rust/rust-hir-type-check-pattern.o \ + rust/rust-hir-type-check-expr.o \ rust/rust-hir-dot-operator.o \ rust/rust-autoderef.o \ rust/rust-substitution-mapper.o \ diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index d1f34e2..8b98881 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -2430,6 +2430,9 @@ public: void accept_vis (HIRFullVisitor &vis) override; + std::unique_ptr<Expr> &get_from_expr () { return from; } + std::unique_ptr<Expr> &get_to_expr () { return to; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc new file mode 100644 index 0000000..e99432a --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -0,0 +1,246 @@ +// 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-hir-type-check-expr.h" + +namespace Rust { +namespace Resolver { + +void +TypeCheckExpr::visit (HIR::RangeFromToExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + TyTy::BaseType *to_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + TyTy::BaseType *unified = from_ty->unify (to_ty); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeFromExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_FROM; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeToExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_TO; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +void +TypeCheckExpr::visit (HIR::RangeFullExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_FULL; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->is_unit ()); + + infered = item_type; +} + +void +TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr) +{ + auto lang_item_type = Analysis::RustLangItem::ItemType::RANGE_INCLUSIVE; + + DefId respective_lang_item_id = UNKNOWN_DEFID; + bool lang_item_defined + = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); + + // we need to have it maybe + if (!lang_item_defined) + { + rust_internal_error_at ( + expr.get_locus (), "unable to find relevant lang item: %s", + Analysis::RustLangItem::ToString (lang_item_type).c_str ()); + return; + } + + // look it up and it _must_ be a struct definition + HIR::Item *item = mappings->lookup_defid (respective_lang_item_id); + rust_assert (item != nullptr); + + TyTy::BaseType *item_type = nullptr; + bool ok + = context->lookup_type (item->get_mappings ().get_hirid (), &item_type); + rust_assert (ok); + rust_assert (item_type->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (item_type); + + // this is a single generic item lets assert that + rust_assert (adt->get_num_substitutions () == 1); + + // resolve the range expressions and these types must unify then we use that + // type to substitute into the ADT + TyTy::BaseType *from_ty + = TypeCheckExpr::Resolve (expr.get_from_expr ().get (), false); + TyTy::BaseType *to_ty + = TypeCheckExpr::Resolve (expr.get_to_expr ().get (), false); + TyTy::BaseType *unified = from_ty->unify (to_ty); + + // substitute it in + std::vector<TyTy::SubstitutionArg> subst_mappings; + const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); + subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); + + TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + infered = SubstMapperInternal::Resolve (adt, subst); +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index a4b8f0a..0c3d229 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -1271,6 +1271,16 @@ public: } } + void visit (HIR::RangeFromToExpr &expr) override; + + void visit (HIR::RangeFromExpr &expr) override; + + void visit (HIR::RangeToExpr &expr) override; + + void visit (HIR::RangeFullExpr &expr) override; + + void visit (HIR::RangeFromToInclExpr &expr) override; + protected: bool resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type, |