aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc246
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h10
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,