aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h31
-rw-r--r--gcc/rust/backend/rust-compile-expr.h8
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h2
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h6
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc18
-rw-r--r--gcc/rust/hir/tree/rust-hir.h7
-rw-r--r--gcc/rust/rust-session-manager.cc5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h249
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h62
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h22
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h32
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc134
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h9
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h178
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h14
-rw-r--r--gcc/rust/typecheck/rust-tyty-resolver.h214
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h372
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc126
-rw-r--r--gcc/rust/typecheck/rust-tyty.h183
-rw-r--r--gcc/rust/util/rust-hir-map.cc1
-rw-r--r--gcc/rust/util/rust-hir-map.h8
-rw-r--r--gcc/testsuite/rust.test/compilable/ints_infer1.rs18
-rw-r--r--gcc/testsuite/rust.test/compilable/type_infer6.rs12
25 files changed, 1115 insertions, 613 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index df29e36..ed03f02 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -298,6 +298,37 @@ public:
translated = named_struct;
}
+ void visit (TyTy::TupleType &type) override
+ {
+ bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &translated);
+ if (ok)
+ return;
+
+ // create implicit struct
+ std::vector<Backend::Btyped_identifier> fields;
+ for (size_t i = 0; i < type.num_fields (); i++)
+ {
+ TyTy::TyBase *field = type.get_field (i);
+ Btype *compiled_field_ty
+ = TyTyCompile::compile (ctx->get_backend (), field);
+
+ Backend::Btyped_identifier f (std::to_string (i), compiled_field_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
+ fields.push_back (std::move (f));
+ }
+
+ Btype *struct_type_record = ctx->get_backend ()->struct_type (fields);
+ Btype *named_struct
+ = ctx->get_backend ()->named_type (type.as_string (), struct_type_record,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
+
+ ctx->push_type (named_struct);
+ ctx->insert_compiled_type (type.get_ty_ref (), named_struct);
+ translated = named_struct;
+ }
+
void visit (TyTy::ArrayType &type) override
{
mpz_t ival;
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index da3c9cd..7c2f32d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -145,17 +145,19 @@ public:
void visit (HIR::LiteralExpr &expr)
{
+ auto literal_value = expr.get_literal ();
switch (expr.get_lit_type ())
{
case HIR::Literal::BOOL: {
- bool bval = expr.as_string ().compare ("true") == 0;
+ bool bval = literal_value->as_string ().compare ("true") == 0;
translated = ctx->get_backend ()->boolean_constant_expression (bval);
}
return;
case HIR::Literal::INT: {
mpz_t ival;
- if (mpz_init_set_str (ival, expr.as_string ().c_str (), 10) != 0)
+ if (mpz_init_set_str (ival, literal_value->as_string ().c_str (), 10)
+ != 0)
{
rust_fatal_error (expr.get_locus (), "bad number in literal");
return;
@@ -178,7 +180,7 @@ public:
case HIR::Literal::FLOAT: {
mpfr_t fval;
- if (mpfr_init_set_str (fval, expr.as_string ().c_str (), 10,
+ if (mpfr_init_set_str (fval, literal_value->as_string ().c_str (), 10,
MPFR_RNDN)
!= 0)
{
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
index f74b4ac..b6794bc 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -52,6 +52,8 @@ public:
void visit (TyTy::ADTType &type) override { gcc_unreachable (); }
+ void visit (TyTy::TupleType &type) override { gcc_unreachable (); }
+
void visit (TyTy::ArrayType &type) override { gcc_unreachable (); }
void visit (TyTy::UnitType &type) override
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 0ce678b..69b680d 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -61,7 +61,11 @@ class LiteralExpr : public ExprWithoutBlock
Location locus;
public:
- std::string as_string () const override { return literal.as_string (); }
+ std::string as_string () const override
+ {
+ return "( " + literal.as_string () + " (" + get_mappings ().as_string ()
+ + "))";
+ }
Literal::LitType get_lit_type () const { return literal.get_lit_type (); }
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index f4e9f5a..b727917 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -2072,23 +2072,15 @@ ArithmeticOrLogicalExpr::as_string () const
operator_str = ">>";
break;
default:
- operator_str = "invalid operator. wtf";
+ gcc_unreachable ();
break;
}
- std::string str ("ArithmeticOrLogicalExpr: ");
- if (main_or_left_expr == nullptr || right_expr == nullptr)
- {
- str += "error. this is probably a parsing failure.";
- }
- else
- {
- str += main_or_left_expr->as_string () + " ";
- str += operator_str + " ";
- str += right_expr->as_string ();
- }
+ std::string str = main_or_left_expr->as_string () + " ";
+ str += operator_str + " ";
+ str += right_expr->as_string ();
- return str + "::" + get_mappings ().as_string ();
+ return "( " + str + " (" + get_mappings ().as_string () + "))";
}
std::string
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index fabc31d..e4a81c5 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -895,7 +895,10 @@ public:
ident (std::move (ident)), locus (locus)
{}
- std::string as_string () const override { return ident; }
+ std::string as_string () const override
+ {
+ return "( " + ident + " (" + get_mappings ().as_string () + "))";
+ }
Location get_locus () const { return locus; }
Location get_locus_slow () const override { return get_locus (); }
@@ -908,6 +911,8 @@ public:
return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
}
+ Identifier get_identifier () const { return ident; }
+
protected:
// Clone method implementation
IdentifierExpr *clone_expr_without_block_impl () const override
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index c1df913..281049d 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -34,6 +34,7 @@
#include "rust-ast-resolve.h"
#include "rust-ast-lower.h"
#include "rust-hir-type-check.h"
+#include "rust-tycheck-dump.h"
#include "rust-compile.h"
extern Linemap *
@@ -548,6 +549,10 @@ Session::parse_file (const char *filename)
// type resolve
type_resolution (hir);
+ // FIXME this needs an option of itself
+ // auto buf = Resolver::TypeResolverDump::go (hir);
+ // fprintf (stderr, "%s\n", buf.c_str ());
+
if (saw_errors ())
return;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 02830cd..8f60f72 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -23,7 +23,6 @@
#include "rust-hir-full.h"
#include "rust-tyty.h"
#include "rust-tyty-call.h"
-#include "rust-tyty-resolver.h"
#include "rust-hir-type-check-struct-field.h"
namespace Rust {
@@ -38,10 +37,15 @@ public:
expr->accept_vis (resolver);
if (resolver.infered == nullptr)
- resolver.infered
- = new TyTy::UnitType (expr->get_mappings ().get_hirid ());
+ {
+ resolver.infered
+ = new TyTy::UnitType (expr->get_mappings ().get_hirid ());
+ }
+ auto ref = expr->get_mappings ().get_hirid ();
+ resolver.infered->set_ref (ref);
resolver.context->insert_type (expr->get_mappings (), resolver.infered);
+
return resolver.infered;
}
@@ -54,14 +58,40 @@ public:
"failed to resolve TupleIndexExpr receiver");
return;
}
- if (resolved->get_kind () != TyTy::TypeKind::ADT)
+
+ bool is_valid_type = resolved->get_kind () == TyTy::TypeKind::ADT
+ || resolved->get_kind () == TyTy::TypeKind::TUPLE;
+ if (!is_valid_type)
{
rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
- "Expected ADT type got: %s",
+ "Expected Tuple or ADT got: %s",
resolved->as_string ().c_str ());
return;
}
+ if (resolved->get_kind () == TyTy::TypeKind::TUPLE)
+ {
+ TyTy::TupleType *tuple = (TyTy::TupleType *) resolved;
+ TupleIndex index = expr.get_tuple_index ();
+ if ((size_t) index >= tuple->num_fields ())
+ {
+ rust_error_at (expr.get_locus (), "unknown field at index %i",
+ index);
+ return;
+ }
+
+ auto field_tyty = tuple->get_field ((size_t) index);
+ if (field_tyty == nullptr)
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup field type at index %i", index);
+ return;
+ }
+
+ infered = field_tyty;
+ return;
+ }
+
TyTy::ADTType *adt = (TyTy::ADTType *) resolved;
TupleIndex index = expr.get_tuple_index ();
if ((size_t) index >= adt->num_fields ())
@@ -94,34 +124,32 @@ public:
return;
}
- size_t index = 0;
- std::string identifier = "(";
- std::vector<TyTy::StructFieldType *> fields;
+ std::vector<HirId> fields;
for (auto &elem : expr.get_tuple_elems ())
{
auto field_ty = TypeCheckExpr::Resolve (elem.get ());
- identifier += field_ty->as_string ();
- if ((index + 1) < expr.get_tuple_elems ().size ())
- identifier += ",";
-
- auto field_tyty
- = new TyTy::StructFieldType (elem->get_mappings ().get_hirid (),
- std::to_string (index), field_ty);
- fields.push_back (field_tyty);
- index++;
- }
- identifier += ")";
- infered = new TyTy::ADTType (expr.get_mappings ().get_hirid (), identifier,
- true, fields);
+ fields.push_back (field_ty->get_ref ());
+ }
+ infered = new TyTy::TupleType (expr.get_mappings ().get_hirid (), fields);
}
void visit (HIR::ReturnExpr &expr)
{
- auto ret = context->peek_return_type ();
- rust_assert (ret != nullptr);
+ auto fn_return_tyty = context->peek_return_type ();
+ rust_assert (fn_return_tyty != nullptr);
auto expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
- infered = ret->combine (expr_ty);
+ if (expr_ty == nullptr)
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve type for ReturnExpr");
+ return;
+ }
+
+ infered = fn_return_tyty->combine (expr_ty);
+ fn_return_tyty->append_reference (expr_ty->get_ref ());
+ for (auto &ref : infered->get_combined_refs ())
+ fn_return_tyty->append_reference (ref);
}
void visit (HIR::CallExpr &expr)
@@ -163,15 +191,13 @@ public:
return;
}
- infered = TyTy::TypeCheckCallExpr::go (lookup, expr);
+ infered = TyTy::TypeCheckCallExpr::go (lookup, expr, context);
if (infered == nullptr)
{
rust_error_at (expr.get_locus (), "failed to lookup type to CallExpr");
return;
}
- TyTy::InferType infer (expr.get_mappings ().get_hirid ());
- infered = infer.combine (infered);
infered->set_ref (expr.get_mappings ().get_hirid ());
}
@@ -181,6 +207,12 @@ public:
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
infered = lhs->combine (rhs);
+ if (infered == nullptr)
+ {
+ rust_error_at (expr.get_locus (),
+ "failure in TypeInference AssignmentExpr");
+ return;
+ }
// in the case of declare first for an ADT Type:
//
@@ -191,36 +223,34 @@ public:
// The lhs will have a TyTy of INFER and so when the declaration is
// referenced it will still have an unknown type so we will fail to resolve
// FieldAccessExpr
- if (lhs->get_kind () == TyTy::TypeKind::INFER)
- {
- NodeId ast_node_id = expr.get_lhs ()->get_mappings ().get_nodeid ();
- NodeId ref_node_id;
- if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- return;
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "assignment infer - unknown reference");
- return;
- }
+ NodeId ast_node_id = expr.get_lhs ()->get_mappings ().get_nodeid ();
+ NodeId ref_node_id;
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ return;
- HirId ref;
- if (!mappings->lookup_node_to_hir (
- expr.get_mappings ().get_crate_num (), def.parent, &ref))
- {
- rust_error_at (expr.get_locus (),
- "assignment infer - reverse lookup failure");
- return;
- }
+ Definition def;
+ if (!resolver->lookup_definition (ref_node_id, &def))
+ {
+ rust_error_at (expr.get_locus (),
+ "assignment infer - unknown reference");
+ return;
+ }
- context->insert_type (
- Analysis::NodeMapping (
- expr.get_lhs ()->get_mappings ().get_crate_num (), ref_node_id, ref,
- UNKNOWN_LOCAL_DEFID),
- infered);
+ HirId ref;
+ if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+ def.parent, &ref))
+ {
+ rust_error_at (expr.get_locus (),
+ "assignment infer - reverse lookup failure");
+ return;
}
+
+ // FIXME free the old one
+ context->insert_type (
+ Analysis::NodeMapping (expr.get_lhs ()->get_mappings ().get_crate_num (),
+ ref_node_id, ref, UNKNOWN_LOCAL_DEFID),
+ infered->clone ());
}
void visit (HIR::IdentifierExpr &expr)
@@ -265,8 +295,8 @@ public:
return;
}
- TyTy::InferType infer (expr.get_mappings ().get_hirid ());
- infered = infer.combine (lookup);
+ lookup->append_reference (lookup->get_ref ());
+ infered = lookup->clone ();
infered->set_ref (expr.get_mappings ().get_hirid ());
}
@@ -321,7 +351,10 @@ public:
break;
default:
- ok = context->lookup_builtin ("i32", &infered);
+ ok = true;
+ infered = new TyTy::InferType (
+ expr.get_mappings ().get_hirid (),
+ TyTy::InferType::InferTypeKind::INTEGRAL);
break;
}
rust_assert (ok);
@@ -339,8 +372,12 @@ public:
case CORETYPE_F64:
ok = context->lookup_builtin ("f64", &infered);
break;
+
default:
- ok = context->lookup_builtin ("f32", &infered);
+ ok = true;
+ infered
+ = new TyTy::InferType (expr.get_mappings ().get_hirid (),
+ TyTy::InferType::InferTypeKind::FLOAT);
break;
}
rust_assert (ok);
@@ -358,9 +395,7 @@ public:
break;
}
- TyTy::InferType infer (expr.get_mappings ().get_hirid ());
- infered = infer.combine (infered);
- infered->set_ref (expr.get_mappings ().get_hirid ());
+ infered = infered->clone ();
}
void visit (HIR::ArithmeticOrLogicalExpr &expr)
@@ -380,7 +415,13 @@ public:
case HIR::ArithmeticOrLogicalExpr::MODULUS: {
bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
|| (combined->get_kind () == TyTy::TypeKind::UINT)
- || (combined->get_kind () == TyTy::TypeKind::FLOAT);
+ || (combined->get_kind () == TyTy::TypeKind::FLOAT)
+ || (combined->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) combined)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL))
+ || (combined->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) combined)->get_infer_kind ()
+ == TyTy::InferType::FLOAT));
if (!valid)
{
rust_error_at (expr.get_locus (), "cannot apply operator to %s",
@@ -396,7 +437,10 @@ public:
case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR: {
bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
|| (combined->get_kind () == TyTy::TypeKind::UINT)
- || (combined->get_kind () == TyTy::TypeKind::BOOL);
+ || (combined->get_kind () == TyTy::TypeKind::BOOL)
+ || (combined->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) combined)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
if (!valid)
{
rust_error_at (expr.get_locus (), "cannot apply operator to %s",
@@ -410,7 +454,10 @@ public:
case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT: {
bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
- || (combined->get_kind () == TyTy::TypeKind::UINT);
+ || (combined->get_kind () == TyTy::TypeKind::UINT)
+ || (combined->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) combined)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
if (!valid)
{
rust_error_at (expr.get_locus (), "cannot apply operator to %s",
@@ -422,6 +469,8 @@ public:
}
infered = combined;
+ infered->append_reference (lhs->get_ref ());
+ infered->append_reference (rhs->get_ref ());
}
void visit (HIR::ComparisonExpr &expr)
@@ -435,6 +484,8 @@ public:
// we expect this to be
infered = new TyTy::BoolType (expr.get_mappings ().get_hirid ());
+ infered->append_reference (lhs->get_ref ());
+ infered->append_reference (rhs->get_ref ());
}
void visit (HIR::LazyBooleanExpr &expr)
@@ -454,6 +505,8 @@ public:
return;
infered = lhs->combine (rhs);
+ infered->append_reference (lhs->get_ref ());
+ infered->append_reference (rhs->get_ref ());
}
void visit (HIR::NegationExpr &expr)
@@ -467,7 +520,13 @@ public:
bool valid
= (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
|| (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT)
- || (negated_expr_ty->get_kind () == TyTy::TypeKind::FLOAT);
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::FLOAT)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) negated_expr_ty)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL))
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) negated_expr_ty)->get_infer_kind ()
+ == TyTy::InferType::FLOAT));
if (!valid)
{
rust_error_at (expr.get_locus (), "cannot apply unary - to %s",
@@ -481,7 +540,10 @@ public:
bool valid
= (negated_expr_ty->get_kind () == TyTy::TypeKind::BOOL)
|| (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
- || (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT);
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT)
+ || (negated_expr_ty->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) negated_expr_ty)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
if (!valid)
{
rust_error_at (expr.get_locus (), "cannot apply unary ! to %s",
@@ -492,7 +554,8 @@ public:
break;
}
- infered = negated_expr_ty;
+ infered = negated_expr_ty->clone ();
+ infered->append_reference (negated_expr_ty->get_ref ());
}
void visit (HIR::IfExpr &expr)
@@ -567,23 +630,45 @@ public:
void visit (HIR::ArrayIndexExpr &expr)
{
- // FIXME this should be size type
- TyTy::IntType size_ty (expr.get_index_expr ()->get_mappings ().get_hirid (),
- TyTy::IntType::I32);
- auto resolved
- = size_ty.combine (TypeCheckExpr::Resolve (expr.get_index_expr ()));
- rust_assert (resolved != nullptr);
+ TyTy::TyBase *size_ty;
+ if (!context->lookup_builtin ("i32", &size_ty))
+ {
+ rust_error_at (
+ expr.get_locus (),
+ "Failure looking up size type for index in ArrayIndexExpr");
+ return;
+ }
+
+ auto resolved_index_expr
+ = size_ty->combine (TypeCheckExpr::Resolve (expr.get_index_expr ()));
+ if (resolved_index_expr == nullptr)
+ {
+ rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+ "Type Resolver failure in Index for ArrayIndexExpr");
+ return;
+ }
+ context->insert_type (expr.get_index_expr ()->get_mappings (),
+ resolved_index_expr);
+ // resolve the array reference
expr.get_array_expr ()->accept_vis (*this);
- if (infered->get_kind () != TyTy::TypeKind::ARRAY)
+ if (infered == nullptr)
{
- rust_fatal_error (expr.get_array_expr ()->get_locus_slow (),
- "expected an ArrayType for index expression");
+ rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+ "failed to resolve array reference expression");
+ return;
+ }
+ else if (infered->get_kind () != TyTy::TypeKind::ARRAY)
+ {
+ rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+ "expected an ArrayType got [%s]",
+ infered->as_string ().c_str ());
+ infered = nullptr;
return;
}
- // extract the element type out now from the base type
- infered = TyTyExtractorArray::ExtractElementTypeFromArray (infered);
+ TyTy::ArrayType *array_type = (TyTy::ArrayType *) infered;
+ infered = array_type->get_type ()->clone ();
}
void visit (HIR::ArrayExpr &expr)
@@ -611,6 +696,9 @@ public:
{
infered_array_elems = infered_array_elems->combine (types.at (i));
}
+
+ for (auto &elem : types)
+ infered_array_elems->append_reference (elem->get_ref ());
}
void visit (HIR::ArrayElemsCopied &elems)
@@ -632,9 +720,12 @@ public:
{
auto struct_base
= TypeCheckExpr::Resolve (expr.get_receiver_expr ().get ());
- if (struct_base->get_kind () != TyTy::TypeKind::ADT)
+
+ bool is_valid_type = struct_base->get_kind () == TyTy::TypeKind::ADT;
+ if (!is_valid_type)
{
- rust_error_at (expr.get_locus (), "expected ADT Type got: [%s]",
+ rust_error_at (expr.get_locus (),
+ "expected ADT or Tuple Type got: [%s]",
struct_base->as_string ().c_str ());
return;
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 566d43e..d7f9af1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -24,43 +24,10 @@
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-stmt.h"
#include "rust-tyty-visitor.h"
-#include "rust-tyty-resolver.h"
namespace Rust {
namespace Resolver {
-class ResolveFnType : public TyTy::TyVisitor
-{
-public:
- ResolveFnType (TyTy::TyBase *base) : base (base), state (nullptr) {}
-
- TyTy::TyBase *go ()
- {
- base->accept_vis (*this);
- if (state == nullptr)
- gcc_unreachable ();
-
- return state;
- }
-
- void visit (TyTy::UnitType &type) override { gcc_unreachable (); }
- void visit (TyTy::InferType &type) override { gcc_unreachable (); }
- void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); }
- void visit (TyTy::ADTType &type) override { gcc_unreachable (); }
- void visit (TyTy::ArrayType &type) override { gcc_unreachable (); }
- void visit (TyTy::BoolType &type) override { gcc_unreachable (); }
- void visit (TyTy::IntType &type) override { gcc_unreachable (); }
- void visit (TyTy::UintType &type) override { gcc_unreachable (); }
- void visit (TyTy::FloatType &type) override { gcc_unreachable (); }
- void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
-
- void visit (TyTy::FnType &type) override { state = type.return_type (); }
-
-private:
- TyTy::TyBase *base;
- TyTy::TyBase *state;
-};
-
class TypeCheckItem : public TypeCheckBase
{
public:
@@ -72,23 +39,42 @@ public:
void visit (HIR::Function &function)
{
- TyTy::TyBase *fnType;
- if (!context->lookup_type (function.get_mappings ().get_hirid (), &fnType))
+ TyTy::TyBase *lookup;
+ if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
{
rust_error_at (function.locus, "failed to lookup function type");
return;
}
+ if (lookup->get_kind () != TyTy::TypeKind::FNDEF)
+ {
+ rust_error_at (function.get_locus (),
+ "found invalid type for function [%s]",
+ lookup->as_string ().c_str ());
+ return;
+ }
+
// need to get the return type from this
- ResolveFnType resolve_fn_type (fnType);
- context->push_return_type (resolve_fn_type.go ());
+ TyTy::FnType *resolve_fn_type = (TyTy::FnType *) lookup;
+ auto expected_ret_tyty = resolve_fn_type->return_type ();
+ context->push_return_type (expected_ret_tyty);
TypeCheckExpr::Resolve (function.function_body.get ());
if (function.function_body->has_expr ())
{
auto resolved
= TypeCheckExpr::Resolve (function.function_body->expr.get ());
- context->peek_return_type ()->combine (resolved);
+
+ auto ret_resolved = expected_ret_tyty->combine (resolved);
+ if (ret_resolved == nullptr)
+ {
+ rust_error_at (function.function_body->expr->get_locus_slow (),
+ "failed to resolve final expression");
+ return;
+ }
+
+ context->peek_return_type ()->append_reference (
+ ret_resolved->get_ref ());
}
context->pop_return_type ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index e60c051..99be0b7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -49,10 +49,19 @@ public:
void visit (HIR::LetStmt &stmt)
{
+ infered = new TyTy::UnitType (stmt.get_mappings ().get_hirid ());
+
TyTy::TyBase *init_expr_ty = nullptr;
if (stmt.has_init_expr ())
- init_expr_ty
- = TypeCheckExpr::Resolve (stmt.get_init_expr (), is_final_stmt);
+ {
+ init_expr_ty
+ = TypeCheckExpr::Resolve (stmt.get_init_expr (), is_final_stmt);
+
+ init_expr_ty = init_expr_ty->clone ();
+ auto ref = init_expr_ty->get_ref ();
+ init_expr_ty->set_ref (stmt.get_mappings ().get_hirid ());
+ init_expr_ty->append_reference (ref);
+ }
TyTy::TyBase *specified_ty = nullptr;
if (stmt.has_type ())
@@ -86,16 +95,17 @@ public:
// let x;
else
{
- context->insert_type (stmt.get_mappings (),
- new TyTy::InferType (
- stmt.get_mappings ().get_hirid ()));
+ context->insert_type (
+ stmt.get_mappings (),
+ new TyTy::InferType (stmt.get_mappings ().get_hirid (),
+ TyTy::InferType::InferTypeKind::GENERAL));
}
}
}
private:
TypeCheckStmt (bool is_final_stmt)
- : TypeCheckBase (), is_final_stmt (is_final_stmt)
+ : TypeCheckBase (), infered (nullptr), is_final_stmt (is_final_stmt)
{}
TyTy::TyBase *infered;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index fcaf724..52b6cde 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -56,8 +56,7 @@ public:
TyTy::TyBase *type
= new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- struct_decl.get_identifier (), true,
- std::move (fields));
+ struct_decl.get_identifier (), std::move (fields));
context->insert_type (struct_decl.get_mappings (), type);
}
@@ -78,8 +77,7 @@ public:
TyTy::TyBase *type
= new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- struct_decl.get_identifier (), false,
- std::move (fields));
+ struct_decl.get_identifier (), std::move (fields));
context->insert_type (struct_decl.get_mappings (), type);
}
@@ -107,9 +105,15 @@ public:
ret_type = new TyTy::UnitType (function.get_mappings ().get_hirid ());
else
{
- TyTy::InferType infer (function.get_mappings ().get_hirid ());
auto resolved = TypeCheckType::Resolve (function.return_type.get ());
- ret_type = infer.combine (resolved);
+ if (resolved == nullptr)
+ {
+ rust_error_at (function.get_locus (),
+ "failed to resolve return type");
+ return;
+ }
+
+ ret_type = resolved->clone ();
ret_type->set_ref (function.return_type->get_mappings ().get_hirid ());
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 579dfb0..e5d3898 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -40,11 +40,12 @@ public:
void visit (HIR::LiteralExpr &expr)
{
+ auto literal_value = expr.get_literal ();
switch (expr.get_lit_type ())
{
case HIR::Literal::LitType::INT: {
ok = true;
- std::stringstream ss (expr.as_string ());
+ std::stringstream ss (literal_value->as_string ());
ss >> result;
}
break;
@@ -70,8 +71,10 @@ public:
type->accept_vis (resolver);
if (resolver.translated != nullptr)
- resolver.context->insert_type (type->get_mappings (),
- resolver.translated);
+ {
+ resolver.context->insert_type (type->get_mappings (),
+ resolver.translated);
+ }
return resolver.translated;
}
@@ -89,25 +92,15 @@ public:
return;
}
- size_t index = 0;
- std::string identifier = "(";
- std::vector<TyTy::StructFieldType *> fields;
+ std::vector<HirId> fields;
for (auto &elem : tuple.get_elems ())
{
auto field_ty = TypeCheckType::Resolve (elem.get ());
- identifier += field_ty->as_string ();
- if ((index + 1) < tuple.get_elems ().size ())
- identifier += ",";
-
- auto field_tyty
- = new TyTy::StructFieldType (elem->get_mappings ().get_hirid (),
- std::to_string (index), field_ty);
- fields.push_back (field_tyty);
- index++;
+ fields.push_back (field_ty->get_ref ());
}
- identifier += ")";
- translated = new TyTy::ADTType (tuple.get_mappings ().get_hirid (),
- identifier, true, fields);
+
+ translated
+ = new TyTy::TupleType (tuple.get_mappings ().get_hirid (), fields);
}
void visit (HIR::TypePath &path)
@@ -129,6 +122,9 @@ public:
// we got an HIR node
if (context->lookup_type (hir_lookup, &translated))
{
+ translated = translated->clone ();
+ auto ref = path.get_mappings ().get_hirid ();
+ translated->set_ref (ref);
return;
}
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index aa3d505..cf3a846 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -34,6 +34,54 @@ TypeResolution::Resolve (HIR::Crate &crate)
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
TypeCheckItem::Resolve (it->get ());
+
+ auto mappings = Analysis::Mappings::get ();
+ auto context = TypeCheckContext::get ();
+
+ context->iterate ([&] (HirId id, TyTy::TyBase *ty) mutable -> bool {
+ // nothing to do
+ if (ty->get_kind () != TyTy::TypeKind::INFER)
+ return true;
+
+ TyTy::InferType *infer_var = (TyTy::InferType *) ty;
+ switch (infer_var->get_infer_kind ())
+ {
+ case TyTy::InferType::GENERAL:
+ rust_error_at (mappings->lookup_location (id),
+ "unable to determine type: %u", id);
+ break;
+
+ case TyTy::InferType::INTEGRAL: {
+ TyTy::TyBase *default_integer;
+ bool ok = context->lookup_builtin ("i32", &default_integer);
+ rust_assert (ok);
+
+ auto result = ty->combine (default_integer);
+ result->set_ref (id);
+ context->insert_type (
+ Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
+ UNKNOWN_LOCAL_DEFID),
+ result);
+ }
+ break;
+
+ case TyTy::InferType::FLOAT: {
+ TyTy::TyBase *default_float;
+ bool ok = context->lookup_builtin ("f32", &default_float);
+ rust_assert (ok);
+
+ auto result = ty->combine (default_float);
+ result->set_ref (id);
+ context->insert_type (
+ Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
+ UNKNOWN_LOCAL_DEFID),
+ result);
+ }
+ break;
+ }
+
+ return true;
+ });
}
// RUST_HIR_TYPE_CHECK_EXPR
@@ -48,6 +96,12 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
bool is_final_expr = is_final_stmt && !expr.has_expr ();
auto infered = TypeCheckStmt::Resolve (s, is_final_expr);
+ if (infered == nullptr)
+ {
+ rust_error_at (s->get_locus_slow (), "failure to resolve type");
+ return false;
+ }
+
if (is_final_expr)
{
delete block_tyty;
@@ -59,21 +113,19 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
// tail expression must be checked as part of the caller since
// the result of this is very dependant on what we expect it to be
- if (expr.has_expr ())
- TypeCheckExpr::Resolve (expr.expr.get ());
// now that the stmts have been resolved we must resolve the block of locals
// and make sure the variables have been resolved
- auto body_mappings = expr.get_mappings ();
- Rib *rib = nullptr;
- if (!resolver->find_name_rib (body_mappings.get_nodeid (), &rib))
- {
- rust_fatal_error (expr.get_locus (), "failed to lookup locals per block");
- return;
- }
- TyTyResolver::Resolve (rib, mappings, resolver, context);
-
- infered = block_tyty;
+ // auto body_mappings = expr.get_mappings ();
+ // Rib *rib = nullptr;
+ // if (!resolver->find_name_rib (body_mappings.get_nodeid (), &rib))
+ // {
+ // rust_fatal_error (expr.get_locus (), "failed to lookup locals per
+ // block"); return;
+ // }
+ // TyTyResolver::Resolve (rib, mappings, resolver, context);
+
+ infered = block_tyty->clone ();
}
// RUST_HIR_TYPE_CHECK_STRUCT_FIELD
@@ -154,47 +206,23 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
= struct_expr.struct_base->base_struct->clone_expr_impl ();
HIR::StructExprField *implicit_field = nullptr;
- if (struct_path_resolved->is_tuple_struct ())
- {
- std::vector<HIR::Attribute> outer_attribs;
- TupleIndex tuple_index = std::stoi (missing);
-
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (
- crate_num,
- struct_expr.struct_base->base_struct->get_mappings ()
- .get_nodeid (),
- mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
-
- HIR::Expr *field_value = new HIR::TupleIndexExpr (
- mapping, std::unique_ptr<HIR::Expr> (receiver), tuple_index,
- std::move (outer_attribs),
- struct_expr.struct_base->base_struct->get_locus_slow ());
-
- implicit_field = new HIR::StructExprFieldIndexValue (
- mapping, tuple_index,
- std::unique_ptr<HIR::Expr> (field_value),
- struct_expr.struct_base->base_struct->get_locus_slow ());
- }
- else
- {
- std::vector<HIR::Attribute> outer_attribs;
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (
- crate_num,
- struct_expr.struct_base->base_struct->get_mappings ()
- .get_nodeid (),
- mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
-
- HIR::Expr *field_value = new HIR::FieldAccessExpr (
- mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
- std::move (outer_attribs),
- struct_expr.struct_base->base_struct->get_locus_slow ());
-
- implicit_field = new HIR::StructExprFieldIdentifierValue (
- mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
- struct_expr.struct_base->base_struct->get_locus_slow ());
- }
+
+ std::vector<HIR::Attribute> outer_attribs;
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (
+ crate_num,
+ struct_expr.struct_base->base_struct->get_mappings ()
+ .get_nodeid (),
+ mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
+
+ HIR::Expr *field_value = new HIR::FieldAccessExpr (
+ mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
+ std::move (outer_attribs),
+ struct_expr.struct_base->base_struct->get_locus_slow ());
+
+ implicit_field = new HIR::StructExprFieldIdentifierValue (
+ mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
+ struct_expr.struct_base->base_struct->get_locus_slow ());
size_t field_index;
bool ok = struct_path_resolved->get_field (missing, &field_index);
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index e0458a7..d033878 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -47,6 +47,15 @@ public:
void push_return_type (TyTy::TyBase *return_type);
void pop_return_type ();
+ void iterate (std::function<bool (HirId, TyTy::TyBase *)> cb)
+ {
+ for (auto it = resolved.begin (); it != resolved.end (); it++)
+ {
+ if (!cb (it->first, it->second))
+ return;
+ }
+ }
+
private:
TypeCheckContext ();
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
new file mode 100644
index 0000000..863c2eb
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -0,0 +1,178 @@
+// Copyright (C) 2020 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/>.
+
+#ifndef RUST_TYCHECK_DUMP
+#define RUST_TYCHECK_DUMP
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeResolverDump : public TypeCheckBase
+{
+public:
+ static std::string go (HIR::Crate &crate)
+ {
+ TypeResolverDump dumper;
+ for (auto &item : crate.items)
+ item->accept_vis (dumper);
+
+ return dumper.dump;
+ }
+
+ void visit (HIR::Function &function)
+ {
+ dump += indent () + "fn " + function.function_name + " "
+ + type_string (function.get_mappings ()) + "\n";
+ dump += indent () + "{\n";
+
+ HIR::BlockExpr *function_body = function.function_body.get ();
+ function_body->accept_vis (*this);
+
+ dump += indent () + "}\n";
+ }
+
+ void visit (HIR::BlockExpr &expr)
+ {
+ indentation_level++;
+
+ expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
+ s->accept_vis (*this);
+ dump += ";\n";
+ return true;
+ });
+
+ if (expr.has_expr () && expr.tail_expr_reachable ())
+ {
+ expr.expr->accept_vis (*this);
+ dump += ";\n";
+ }
+
+ indentation_level--;
+ }
+
+ void visit (HIR::LetStmt &stmt)
+ {
+ dump += indent () + "let " + stmt.get_pattern ()->as_string () + ":"
+ + type_string (stmt.get_mappings ());
+ if (stmt.has_init_expr ())
+ {
+ dump += " = ";
+ stmt.get_init_expr ()->accept_vis (*this);
+ }
+ }
+
+ void visit (HIR::ExprStmtWithBlock &stmt)
+ {
+ dump += indent ();
+ stmt.get_expr ()->accept_vis (*this);
+ }
+
+ void visit (HIR::ExprStmtWithoutBlock &stmt)
+ {
+ dump += indent ();
+ stmt.get_expr ()->accept_vis (*this);
+ }
+
+ void visit (HIR::AssignmentExpr &expr)
+ {
+ expr.get_lhs ()->accept_vis (*this);
+ dump += " = ";
+ expr.get_rhs ()->accept_vis (*this);
+ }
+
+ void visit (HIR::LiteralExpr &expr)
+ {
+ dump += expr.get_literal ()->as_string () + ":"
+ + type_string (expr.get_mappings ());
+ }
+
+ void visit (HIR::IdentifierExpr &expr)
+ {
+ dump += expr.get_identifier () + ":" + type_string (expr.get_mappings ());
+ }
+
+ void visit (HIR::ArrayExpr &expr)
+ {
+ dump += type_string (expr.get_mappings ()) + ":[";
+
+ HIR::ArrayElems *elements = expr.get_internal_elements ();
+ elements->accept_vis (*this);
+
+ dump += "]";
+ }
+
+ void visit (HIR::ArrayElemsValues &elems)
+ {
+ elems.iterate ([&] (HIR::Expr *e) mutable -> bool {
+ e->accept_vis (*this);
+ dump += ",";
+ return true;
+ });
+ }
+
+ void visit (HIR::GroupedExpr &expr)
+ {
+ HIR::Expr *paren_expr = expr.get_expr_in_parens ().get ();
+ dump += "(";
+ paren_expr->accept_vis (*this);
+ dump += ")";
+ }
+
+protected:
+ std::string type_string (const Analysis::NodeMapping &mappings)
+ {
+ TyTy::TyBase *lookup = nullptr;
+ if (!context->lookup_type (mappings.get_hirid (), &lookup))
+ return "<error>";
+
+ std::string buf = "[";
+ for (auto &ref : lookup->get_combined_refs ())
+ {
+ buf += std::to_string (ref);
+ buf += ", ";
+ }
+ buf += "]";
+
+ return "<" + lookup->as_string ()
+ + " RF:" + std::to_string (lookup->get_ref ()) + " TF:"
+ + std::to_string (lookup->get_ty_ref ()) + +" - " + buf + ">";
+ }
+
+ std::string indent ()
+ {
+ std::string buf;
+ for (size_t i = 0; i < indentation_level; ++i)
+ buf += " ";
+
+ return buf;
+ }
+
+private:
+ TypeResolverDump () : TypeCheckBase (), indentation_level (0) {}
+
+ std::string dump;
+ size_t indentation_level;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_TYCHECK_DUMP
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 2e98cbb..84cfdce 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -23,6 +23,7 @@
#include "rust-hir-full.h"
#include "rust-tyty-visitor.h"
#include "rust-tyty.h"
+#include "rust-hir-type-check.h"
namespace Rust {
namespace TyTy {
@@ -30,9 +31,10 @@ namespace TyTy {
class TypeCheckCallExpr : private TyVisitor
{
public:
- static TyBase *go (TyBase *ref, HIR::CallExpr &call)
+ static TyBase *go (TyBase *ref, HIR::CallExpr &call,
+ Resolver::TypeCheckContext *context)
{
- TypeCheckCallExpr checker (call);
+ TypeCheckCallExpr checker (call, context);
ref->accept_vis (checker);
return checker.resolved;
}
@@ -40,6 +42,7 @@ public:
void visit (UnitType &type) override { gcc_unreachable (); }
void visit (InferType &type) override { gcc_unreachable (); }
+ void visit (TupleType &type) override { gcc_unreachable (); }
void visit (StructFieldType &type) override { gcc_unreachable (); }
void visit (ArrayType &type) override { gcc_unreachable (); }
void visit (BoolType &type) override { gcc_unreachable (); }
@@ -55,10 +58,15 @@ public:
void visit (FnType &type) override;
private:
- TypeCheckCallExpr (HIR::CallExpr &c) : resolved (nullptr), call (c) {}
+ TypeCheckCallExpr (HIR::CallExpr &c, Resolver::TypeCheckContext *context)
+ : resolved (nullptr), call (c), context (context),
+ mappings (Analysis::Mappings::get ())
+ {}
TyBase *resolved;
HIR::CallExpr &call;
+ Resolver::TypeCheckContext *context;
+ Analysis::Mappings *mappings;
};
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h
deleted file mode 100644
index d48952c..0000000
--- a/gcc/rust/typecheck/rust-tyty-resolver.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (C) 2020 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/>.
-
-#ifndef RUST_TYTY_RESOLVER
-#define RUST_TYTY_RESOLVER
-
-#include "rust-system.h"
-#include "rust-diagnostics.h"
-#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
-#include "rust-hir-type-check.h"
-#include "rust-hir-full.h"
-#include "rust-tyty-visitor.h"
-
-namespace Rust {
-namespace Resolver {
-
-class TyTyResolver
-{
-public:
- static void Resolve (Rib *rib, Analysis::Mappings *mappings,
- Resolver *resolver, TypeCheckContext *context)
- {
- TyTyResolver r (mappings, resolver, context);
- r.go (rib);
- }
-
- virtual ~TyTyResolver () {}
-
- void go (Rib *rib)
- {
- rib->iterate_decls ([&] (NodeId decl_node_id,
- Location locus) mutable -> bool {
- // type inference in rust means we need to gather and examine all
- // references of this decl and combine each to make sure the type is
- // correctly inferred. Consider the example:
- // let mut x; x = 1;
- // we can only say x is an infer variable then at the assignment
- // we think x must be an integer
-
- bool ok = true;
- std::vector<TyTy::TyBase *> gathered_types;
- rib->iterate_references_for_def (
- decl_node_id, [&] (NodeId ref_node) mutable -> bool {
- HirId hir_node_ref;
- if (!mappings->lookup_node_to_hir (mappings->get_current_crate (),
- ref_node, &hir_node_ref))
- {
- rust_error_at (locus,
- "failed to reserve lookup HIR node for reference");
- ok = false;
- return false;
- }
-
- TyTy::TyBase *resolved = nullptr;
- if (!context->lookup_type (hir_node_ref, &resolved))
- {
- // this could be an array/adt type
- Definition d;
- if (!resolver->lookup_definition (ref_node, &d))
- {
- rust_error_at (
- locus,
- "failed to lookup definition for referenced hir node");
-
- ok = false;
- return false;
- }
-
- if (!mappings->lookup_node_to_hir (mappings->get_current_crate (),
- d.parent, &hir_node_ref))
- {
- rust_error_at (locus,
- "failed to lookup HIR node for parent NodeId");
-
- ok = false;
- return false;
- }
-
- if (!context->lookup_type (hir_node_ref, &resolved))
- {
- rust_error_at (
- mappings->lookup_location (hir_node_ref),
- "failed to lookup type for reference at node [%u]",
- hir_node_ref);
-
- ok = false;
- return false;
- }
- }
-
- gathered_types.push_back (resolved);
- return true;
- });
-
- Definition d;
- if (!resolver->lookup_definition (decl_node_id, &d))
- {
- rust_error_at (locus, "Failed to lookup definition within rib");
- return false;
- }
-
- HIR::Stmt *decl = nullptr;
- if (!mappings->resolve_nodeid_to_stmt (d.parent, &decl))
- {
- rust_error_at (locus, "Failed to resolve decl to HIR::Stmt");
- return false;
- }
-
- TyTy::TyBase *resolved_type = nullptr;
- if (!context->lookup_type (decl->get_mappings ().get_hirid (),
- &resolved_type))
- {
- rust_error_at (locus, "Unknown base type for decl in Rib");
- return false;
- }
-
- // if it is not infer then it must have been figured out already
- // we might need changes for generics later on
- if (resolved_type->get_kind () != TyTy::TypeKind::INFER)
- return true;
-
- auto resolved_tyty = resolved_type;
- for (auto it : gathered_types)
- {
- auto combined = resolved_tyty->combine (it);
- if (combined == nullptr)
- {
- rust_fatal_error (decl->get_locus_slow (),
- "type-check resolver failed");
- break;
- }
-
- resolved_tyty = combined;
- }
-
- // something is not inferred we need to look at all references now
- if (resolved_tyty == nullptr
- || resolved_tyty->get_kind () == TyTy::TypeKind::INFER
- || resolved_tyty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_fatal_error (decl->get_locus_slow (), "failed to resolve type");
- return false;
- }
-
- // insert the new resolved definition
- context->insert_type (decl->get_mappings (), resolved_tyty);
- return true;
- });
- }
-
-protected:
-private:
- TyTyResolver (Analysis::Mappings *mappings, Resolver *resolver,
- TypeCheckContext *context)
- : mappings (mappings), resolver (resolver), context (context)
- {}
-
- Analysis::Mappings *mappings;
- Resolver *resolver;
- TypeCheckContext *context;
-};
-
-class TyTyExtractorArray : public TyTy::TyVisitor
-{
-public:
- static TyTy::TyBase *ExtractElementTypeFromArray (TyTy::TyBase *base)
- {
- TyTyExtractorArray e;
- base->accept_vis (e);
- rust_assert (e.extracted != nullptr);
- return e.extracted;
- }
-
- virtual ~TyTyExtractorArray () {}
-
- void visit (TyTy::UnitType &type) override { gcc_unreachable (); }
- void visit (TyTy::InferType &type) override { gcc_unreachable (); }
- void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); }
- void visit (TyTy::ADTType &type) override { gcc_unreachable (); }
- void visit (TyTy::FnType &type) override { gcc_unreachable (); }
- void visit (TyTy::BoolType &type) override { gcc_unreachable (); }
- void visit (TyTy::IntType &type) override { gcc_unreachable (); }
- void visit (TyTy::UintType &type) override { gcc_unreachable (); }
- void visit (TyTy::FloatType &type) override { gcc_unreachable (); }
- void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
-
- void visit (TyTy::ArrayType &type) override { extracted = type.get_type (); }
-
-private:
- TyTyExtractorArray () : extracted (nullptr) {}
-
- TyTy::TyBase *extracted;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_TYTY_RESOLVER
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 241b9be..890931f 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -23,6 +23,7 @@
#include "rust-tyty.h"
#include "rust-tyty-visitor.h"
#include "rust-hir-map.h"
+#include "rust-hir-type-check.h"
namespace Rust {
namespace TyTy {
@@ -32,161 +33,306 @@ class BaseRules : public TyVisitor
public:
virtual ~BaseRules () {}
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ if (resolved != nullptr)
+ {
+ resolved->append_reference (base->get_ref ());
+ resolved->append_reference (other->get_ref ());
+ for (auto ref : base->get_combined_refs ())
+ resolved->append_reference (ref);
+ for (auto ref : other->get_combined_refs ())
+ resolved->append_reference (ref);
+
+ bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
+ if (result_resolved)
+ {
+ for (auto &ref : resolved->get_combined_refs ())
+ {
+ TyTy::TyBase *ref_tyty = nullptr;
+ bool ok = context->lookup_type (ref, &ref_tyty);
+ if (!ok)
+ continue;
+
+ // if any of the types are inference variables lets fix them
+ if (ref_tyty->get_kind () == TyTy::TypeKind::INFER)
+ {
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ context->insert_type (
+ Analysis::NodeMapping (mappings->get_current_crate (),
+ ref_node_id, ref,
+ UNKNOWN_LOCAL_DEFID),
+ resolved->clone ());
+ }
+ }
+ }
+ }
+ return resolved;
+ }
+
virtual void visit (UnitType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
+ }
+
+ virtual void visit (TupleType &type) override
+ {
+ Location ref_locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (ref_locus, "expected [%s] got [%s]",
+ base->as_string ().c_str (), type.as_string ().c_str ());
}
virtual void visit (ADTType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (InferType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (FnType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (ArrayType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (BoolType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (IntType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (UintType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (FloatType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (ErrorType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
virtual void visit (StructFieldType &type) override
{
Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location def_locus = mappings->lookup_location (base->get_ref ());
rust_error_at (ref_locus, "expected [%s] got [%s]",
base->as_string ().c_str (), type.as_string ().c_str ());
- rust_error_at (def_locus, "declared here");
}
protected:
BaseRules (TyBase *base)
- : mappings (Analysis::Mappings::get ()), base (base),
+ : mappings (Analysis::Mappings::get ()),
+ context (Resolver::TypeCheckContext::get ()), base (base),
resolved (new ErrorType (base->get_ref (), base->get_ref ()))
{}
Analysis::Mappings *mappings;
+ Resolver::TypeCheckContext *context;
+
TyBase *base;
TyBase *resolved;
};
-class InferRules : protected BaseRules
+class InferRules : public BaseRules
{
public:
InferRules (InferType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
+ void visit (UnitType &type) override
{
- other->accept_vis (*this);
- return resolved;
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
+
+ void visit (BoolType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
+
+ void visit (IntType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
+ || (base->get_infer_kind ()
+ == TyTy::InferType::InferTypeKind::INTEGRAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
+
+ void visit (UintType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
+ || (base->get_infer_kind ()
+ == TyTy::InferType::InferTypeKind::INTEGRAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
+
+ void visit (FloatType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
+ || (base->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
}
- // we are an inference variable so this means we can take the other as the
- // type
- void visit (InferType &type) override { resolved = type.clone (); }
+ void visit (ArrayType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
- void visit (UnitType &type) override { resolved = type.clone (); }
+ void visit (ADTType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
- void visit (BoolType &type) override { resolved = type.clone (); }
+ BaseRules::visit (type);
+ }
- void visit (IntType &type) override { resolved = type.clone (); }
+ void visit (TupleType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
- void visit (UintType &type) override { resolved = type.clone (); }
+ BaseRules::visit (type);
+ }
- void visit (FloatType &type) override { resolved = type.clone (); }
+ void visit (InferType &type) override
+ {
+ switch (base->get_infer_kind ())
+ {
+ case InferType::InferTypeKind::GENERAL:
+ resolved = type.clone ();
+ return;
- void visit (ArrayType &type) override { resolved = type.clone (); }
+ case InferType::InferTypeKind::INTEGRAL: {
+ if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
+ {
+ resolved = type.clone ();
+ return;
+ }
+ else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
+ {
+ resolved = base->clone ();
+ return;
+ }
+ }
+ break;
+
+ case InferType::InferTypeKind::FLOAT: {
+ if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
+ {
+ resolved = type.clone ();
+ return;
+ }
+ else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
+ {
+ resolved = base->clone ();
+ return;
+ }
+ }
+ break;
+ }
- void visit (ADTType &type) override { resolved = type.clone (); }
+ BaseRules::visit (type);
+ }
private:
InferType *base;
};
-class StructFieldTypeRules : protected BaseRules
+class StructFieldTypeRules : public BaseRules
{
public:
StructFieldTypeRules (StructFieldType *base) : BaseRules (base), base (base)
{}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
void visit (StructFieldType &type)
{
TyBase *ty = base->get_field_type ()->combine (type.get_field_type ());
@@ -201,17 +347,11 @@ private:
StructFieldType *base;
};
-class UnitRules : protected BaseRules
+class UnitRules : public BaseRules
{
public:
UnitRules (UnitType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
void visit (UnitType &type) override
{
resolved = new UnitType (type.get_ref (), type.get_ty_ref ());
@@ -221,44 +361,36 @@ private:
UnitType *base;
};
-class FnRules : protected BaseRules
+class FnRules : public BaseRules
{
public:
FnRules (FnType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
private:
FnType *base;
};
-class ArrayRules : protected BaseRules
+class ArrayRules : public BaseRules
{
public:
ArrayRules (ArrayType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
void visit (ArrayType &type) override
{
// check base type
auto base_resolved = base->get_type ()->combine (type.get_type ());
if (base_resolved == nullptr)
- return;
+ {
+ // fixme add error message
+ return;
+ }
// need to check the base types and capacity
if (type.get_capacity () != base->get_capacity ())
{
Location locus = mappings->lookup_location (type.get_ref ());
rust_error_at (locus, "mismatch in array capacity");
+ BaseRules::visit (type);
return;
}
@@ -270,17 +402,11 @@ private:
ArrayType *base;
};
-class BoolRules : protected BaseRules
+class BoolRules : public BaseRules
{
public:
BoolRules (BoolType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
void visit (BoolType &type) override
{
resolved = new BoolType (type.get_ref (), type.get_ty_ref ());
@@ -290,15 +416,22 @@ private:
BoolType *base;
};
-class IntRules : protected BaseRules
+class IntRules : public BaseRules
{
public:
IntRules (IntType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
+ void visit (InferType &type) override
{
- other->accept_vis (*this);
- return resolved;
+ // cant assign a float inference variable
+ if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
}
void visit (IntType &type) override
@@ -317,15 +450,22 @@ private:
IntType *base;
};
-class UintRules : protected BaseRules
+class UintRules : public BaseRules
{
public:
UintRules (UintType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
+ void visit (InferType &type) override
{
- other->accept_vis (*this);
- return resolved;
+ // cant assign a float inference variable
+ if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
}
void visit (UintType &type) override
@@ -344,15 +484,21 @@ private:
UintType *base;
};
-class FloatRules : protected BaseRules
+class FloatRules : public BaseRules
{
public:
FloatRules (FloatType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
+ void visit (InferType &type) override
{
- other->accept_vis (*this);
- return resolved;
+ if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
}
void visit (FloatType &type) override
@@ -371,17 +517,11 @@ private:
FloatType *base;
};
-class ADTRules : protected BaseRules
+class ADTRules : public BaseRules
{
public:
ADTRules (ADTType *base) : BaseRules (base), base (base) {}
- TyBase *combine (TyBase *other)
- {
- other->accept_vis (*this);
- return resolved;
- }
-
void visit (ADTType &type)
{
if (base->num_fields () != type.num_fields ())
@@ -390,12 +530,6 @@ public:
return;
}
- if (base->get_name ().compare (type.get_name ()) != 0)
- {
- BaseRules::visit (type);
- return;
- }
-
std::vector<TyTy::StructFieldType *> fields;
for (size_t i = 0; i < type.num_fields (); ++i)
{
@@ -412,15 +546,51 @@ public:
fields.push_back ((TyTy::StructFieldType *) combined);
}
- resolved
- = new TyTy::ADTType (type.get_ref (), type.get_ty_ref (),
- type.get_name (), type.is_tuple_struct (), fields);
+ resolved = new TyTy::ADTType (type.get_ref (), type.get_ty_ref (),
+ type.get_name (), fields);
}
private:
ADTType *base;
};
+class TupleRules : public BaseRules
+{
+public:
+ TupleRules (TupleType *base) : BaseRules (base), base (base) {}
+
+ void visit (TupleType &type)
+ {
+ if (base->num_fields () != type.num_fields ())
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ std::vector<HirId> fields;
+ for (size_t i = 0; i < base->num_fields (); i++)
+ {
+ TyBase *bo = base->get_field (i);
+ TyBase *fo = type.get_field (i);
+
+ TyBase *combined = bo->combine (fo);
+ if (combined == nullptr)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ fields.push_back (combined->get_ref ());
+ }
+
+ resolved
+ = new TyTy::TupleType (type.get_ref (), type.get_ty_ref (), fields);
+ }
+
+private:
+ TupleType *base;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
index b6759dd..3997295 100644
--- a/gcc/rust/typecheck/rust-tyty-visitor.h
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -31,6 +31,7 @@ public:
virtual void visit (InferType &type) = 0;
virtual void visit (StructFieldType &type) = 0;
virtual void visit (ADTType &type) = 0;
+ virtual void visit (TupleType &type) = 0;
virtual void visit (FnType &type) = 0;
virtual void visit (ArrayType &type) = 0;
virtual void visit (BoolType &type) = 0;
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 2e09de6..9efde68 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -47,7 +47,7 @@ UnitType::combine (TyBase *other)
TyBase *
UnitType::clone ()
{
- return new UnitType (get_ref (), get_ty_ref ());
+ return new UnitType (get_ref (), get_ty_ref (), get_combined_refs ());
}
void
@@ -59,7 +59,16 @@ InferType::accept_vis (TyVisitor &vis)
std::string
InferType::as_string () const
{
- return "?";
+ switch (infer_kind)
+ {
+ case GENERAL:
+ return "T?";
+ case INTEGRAL:
+ return "<integer>";
+ case FLOAT:
+ return "<float>";
+ }
+ return "<infer::error>";
}
TyBase *
@@ -72,7 +81,8 @@ InferType::combine (TyBase *other)
TyBase *
InferType::clone ()
{
- return new InferType (get_ref (), get_ty_ref ());
+ return new InferType (get_ref (), get_ty_ref (), get_infer_kind (),
+ get_combined_refs ());
}
void
@@ -98,7 +108,7 @@ ErrorType::combine (TyBase *other)
TyBase *
ErrorType::clone ()
{
- return new ErrorType (get_ref ());
+ return new ErrorType (get_ref (), get_ty_ref (), get_combined_refs ());
}
void
@@ -124,7 +134,8 @@ TyBase *
StructFieldType::clone ()
{
return new StructFieldType (get_ref (), get_ty_ref (), get_name (),
- get_field_type ()->clone ());
+ get_field_type ()->clone (),
+ get_combined_refs ());
}
void
@@ -157,8 +168,50 @@ ADTType::clone ()
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->clone ());
- return new ADTType (get_ref (), get_ty_ref (), get_name (),
- is_tuple_struct (), cloned_fields);
+ return new ADTType (get_ref (), get_ty_ref (), get_name (), cloned_fields,
+ get_combined_refs ());
+}
+
+void
+TupleType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+TupleType::as_string () const
+{
+ std::string fields_buffer;
+ iterate_fields ([&] (TyBase *field) mutable -> bool {
+ fields_buffer += field->as_string ();
+ fields_buffer += ", ";
+ return true;
+ });
+ return "(" + fields_buffer + ")";
+}
+
+TyBase *
+TupleType::get_field (size_t index) const
+{
+ auto context = Resolver::TypeCheckContext::get ();
+ TyBase *lookup = nullptr;
+ bool ok = context->lookup_type (fields.at (index), &lookup);
+ rust_assert (ok);
+ return lookup;
+}
+
+TyBase *
+TupleType::combine (TyBase *other)
+{
+ TupleRules r (this);
+ return r.combine (other);
+}
+
+TyBase *
+TupleType::clone ()
+{
+ return new TupleType (get_ref (), get_ty_ref (), fields,
+ get_combined_refs ());
}
void
@@ -199,7 +252,7 @@ FnType::clone ()
std::pair<HIR::Pattern *, TyBase *> (p.first, p.second->clone ()));
return new FnType (get_ref (), get_ty_ref (), cloned_params,
- get_return_type ()->clone ());
+ get_return_type ()->clone (), get_combined_refs ());
}
void
@@ -211,7 +264,8 @@ ArrayType::accept_vis (TyVisitor &vis)
std::string
ArrayType::as_string () const
{
- return "[" + type->as_string () + ":" + std::to_string (capacity) + "]";
+ return "[" + get_type ()->as_string () + ":" + std::to_string (capacity)
+ + "]";
}
TyBase *
@@ -222,10 +276,20 @@ ArrayType::combine (TyBase *other)
}
TyBase *
+ArrayType::get_type () const
+{
+ auto context = Resolver::TypeCheckContext::get ();
+ TyBase *lookup = nullptr;
+ bool ok = context->lookup_type (element_type_id, &lookup);
+ rust_assert (ok);
+ return lookup;
+}
+
+TyBase *
ArrayType::clone ()
{
return new ArrayType (get_ref (), get_ty_ref (), get_capacity (),
- get_type ()->clone ());
+ get_type ()->clone (), get_combined_refs ());
}
void
@@ -250,7 +314,7 @@ BoolType::combine (TyBase *other)
TyBase *
BoolType::clone ()
{
- return new BoolType (get_ref (), get_ty_ref ());
+ return new BoolType (get_ref (), get_ty_ref (), get_combined_refs ());
}
void
@@ -289,7 +353,8 @@ IntType::combine (TyBase *other)
TyBase *
IntType::clone ()
{
- return new IntType (get_ref (), get_ty_ref (), get_kind ());
+ return new IntType (get_ref (), get_ty_ref (), get_kind (),
+ get_combined_refs ());
}
void
@@ -328,7 +393,8 @@ UintType::combine (TyBase *other)
TyBase *
UintType::clone ()
{
- return new UintType (get_ref (), get_ty_ref (), get_kind ());
+ return new UintType (get_ref (), get_ty_ref (), get_kind (),
+ get_combined_refs ());
}
void
@@ -361,18 +427,13 @@ FloatType::combine (TyBase *other)
TyBase *
FloatType::clone ()
{
- return new FloatType (get_ref (), get_ty_ref (), get_kind ());
+ return new FloatType (get_ref (), get_ty_ref (), get_kind (),
+ get_combined_refs ());
}
void
TypeCheckCallExpr::visit (ADTType &type)
{
- if (!type.is_tuple_struct ())
- {
- rust_error_at (call.get_locus (), "Expected TupleStruct");
- return;
- }
-
if (call.num_params () != type.num_fields ())
{
rust_error_at (call.get_locus (),
@@ -425,21 +486,26 @@ TypeCheckCallExpr::visit (FnType &type)
}
size_t i = 0;
- call.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
+ call.iterate_params ([&] (HIR::Expr *param) mutable -> bool {
auto fnparam = type.param_at (i);
- auto t = Resolver::TypeCheckExpr::Resolve (p);
- if (t == nullptr)
+ auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param);
+ if (argument_expr_tyty == nullptr)
{
- rust_error_at (p->get_locus_slow (), "failed to resolve type");
+ rust_error_at (param->get_locus_slow (),
+ "failed to resolve type for argument expr in CallExpr");
return false;
}
- auto pt = fnparam.second;
- auto res = pt->combine (t);
- if (res == nullptr)
- return false;
+ auto resolved_argument_type = fnparam.second->combine (argument_expr_tyty);
+ if (resolved_argument_type == nullptr)
+ {
+ rust_error_at (param->get_locus_slow (),
+ "Type Resolution failure on parameter");
+ return false;
+ }
+
+ context->insert_type (param->get_mappings (), resolved_argument_type);
- delete res;
i++;
return true;
});
@@ -452,7 +518,7 @@ TypeCheckCallExpr::visit (FnType &type)
return;
}
- resolved = type.get_return_type ();
+ resolved = type.get_return_type ()->clone ();
}
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index a73a344..6c6f27c 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -24,6 +24,7 @@
namespace Rust {
namespace TyTy {
+// https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
enum TypeKind
{
@@ -72,22 +73,42 @@ public:
virtual TyBase *clone () = 0;
+ std::set<HirId> get_combined_refs () { return combined; }
+
+ void append_reference (HirId id) { combined.insert (id); }
+
protected:
- TyBase (HirId ref, HirId ty_ref, TypeKind kind)
- : kind (kind), ref (ref), ty_ref (ty_ref)
+ TyBase (HirId ref, HirId ty_ref, TypeKind kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : kind (kind), ref (ref), ty_ref (ty_ref), combined (refs)
{}
TypeKind kind;
HirId ref;
HirId ty_ref;
+
+ std::set<HirId> combined;
};
class InferType : public TyBase
{
public:
- InferType (HirId ref) : TyBase (ref, ref, TypeKind::INFER) {}
+ enum InferTypeKind
+ {
+ GENERAL,
+ INTEGRAL,
+ FLOAT
+ };
+
+ InferType (HirId ref, InferTypeKind infer_kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::INFER, refs), infer_kind (infer_kind)
+ {}
- InferType (HirId ref, HirId ty_ref) : TyBase (ref, ty_ref, TypeKind::INFER) {}
+ InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::INFER, refs), infer_kind (infer_kind)
+ {}
void accept_vis (TyVisitor &vis) override;
@@ -98,14 +119,23 @@ public:
TyBase *combine (TyBase *other) override;
TyBase *clone () final override;
+
+ InferTypeKind get_infer_kind () const { return infer_kind; }
+
+private:
+ InferTypeKind infer_kind;
};
class ErrorType : public TyBase
{
public:
- ErrorType (HirId ref) : TyBase (ref, ref, TypeKind::ERROR) {}
+ ErrorType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::ERROR, refs)
+ {}
- ErrorType (HirId ref, HirId ty_ref) : TyBase (ref, ty_ref, TypeKind::ERROR) {}
+ ErrorType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::ERROR, refs)
+ {}
void accept_vis (TyVisitor &vis) override;
@@ -121,9 +151,13 @@ public:
class UnitType : public TyBase
{
public:
- UnitType (HirId ref) : TyBase (ref, ref, TypeKind::UNIT) {}
+ UnitType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::UNIT, refs)
+ {}
- UnitType (HirId ref, HirId ty_ref) : TyBase (ref, ty_ref, TypeKind::UNIT) {}
+ UnitType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::UNIT, refs)
+ {}
void accept_vis (TyVisitor &vis) override;
@@ -139,12 +173,14 @@ public:
class StructFieldType : public TyBase
{
public:
- StructFieldType (HirId ref, std::string name, TyBase *ty)
- : TyBase (ref, ref, TypeKind::FIELD), name (name), ty (ty)
+ StructFieldType (HirId ref, std::string name, TyBase *ty,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::FIELD, refs), name (name), ty (ty)
{}
- StructFieldType (HirId ref, HirId ty_ref, std::string name, TyBase *ty)
- : TyBase (ref, ty_ref, TypeKind::FIELD), name (name), ty (ty)
+ StructFieldType (HirId ref, HirId ty_ref, std::string name, TyBase *ty,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::FIELD, refs), name (name), ty (ty)
{}
void accept_vis (TyVisitor &vis) override;
@@ -166,19 +202,61 @@ private:
TyBase *ty;
};
+class TupleType : public TyBase
+{
+public:
+ TupleType (HirId ref, std::vector<HirId> fields,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::TUPLE, refs), fields (fields)
+ {}
+
+ TupleType (HirId ref, HirId ty_ref, std::vector<HirId> fields,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::TUPLE, refs), fields (fields)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ bool is_unit () const override { return false; }
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+
+ size_t num_fields () const { return fields.size (); }
+
+ TyBase *get_field (size_t index) const;
+
+ TyBase *clone () final override;
+
+ void iterate_fields (std::function<bool (TyBase *)> cb) const
+ {
+ for (size_t i = 0; i < num_fields (); i++)
+ {
+ if (!cb (get_field (i)))
+ return;
+ }
+ }
+
+private:
+ std::vector<HirId> fields;
+};
+
class ADTType : public TyBase
{
public:
- ADTType (HirId ref, std::string identifier, bool is_tuple,
- std::vector<StructFieldType *> fields)
- : TyBase (ref, ref, TypeKind::ADT), identifier (identifier),
- is_tuple (is_tuple), fields (fields)
+ ADTType (HirId ref, std::string identifier,
+ std::vector<StructFieldType *> fields,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::ADT, refs), identifier (identifier),
+ fields (fields)
{}
- ADTType (HirId ref, HirId ty_ref, std::string identifier, bool is_tuple,
- std::vector<StructFieldType *> fields)
- : TyBase (ref, ty_ref, TypeKind::ADT), identifier (identifier),
- is_tuple (is_tuple), fields (fields)
+ ADTType (HirId ref, HirId ty_ref, std::string identifier,
+ std::vector<StructFieldType *> fields,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::ADT, refs), identifier (identifier),
+ fields (fields)
{}
void accept_vis (TyVisitor &vis) override;
@@ -193,8 +271,6 @@ public:
std::string get_name () const { return identifier; }
- bool is_tuple_struct () const { return is_tuple; }
-
StructFieldType *get_field (size_t index) { return fields.at (index); }
StructFieldType *get_field (const std::string &lookup,
@@ -230,7 +306,6 @@ public:
private:
std::string identifier;
- bool is_tuple;
std::vector<StructFieldType *> fields;
};
@@ -238,15 +313,15 @@ class FnType : public TyBase
{
public:
FnType (HirId ref, std::vector<std::pair<HIR::Pattern *, TyBase *> > params,
- TyBase *type)
- : TyBase (ref, ref, TypeKind::FNDEF), params (std::move (params)),
+ TyBase *type, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::FNDEF, refs), params (std::move (params)),
type (type)
{}
FnType (HirId ref, HirId ty_ref,
std::vector<std::pair<HIR::Pattern *, TyBase *> > params,
- TyBase *type)
- : TyBase (ref, ty_ref, TypeKind::FNDEF), params (params), type (type)
+ TyBase *type, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::FNDEF, refs), params (params), type (type)
{}
void accept_vis (TyVisitor &vis) override;
@@ -281,12 +356,16 @@ private:
class ArrayType : public TyBase
{
public:
- ArrayType (HirId ref, size_t capacity, TyBase *type)
- : TyBase (ref, ref, TypeKind::ARRAY), capacity (capacity), type (type)
+ ArrayType (HirId ref, size_t capacity, TyBase *type,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::ARRAY, refs), capacity (capacity),
+ element_type_id (type->get_ref ())
{}
- ArrayType (HirId ref, HirId ty_ref, size_t capacity, TyBase *type)
- : TyBase (ref, ty_ref, TypeKind::ARRAY), capacity (capacity), type (type)
+ ArrayType (HirId ref, HirId ty_ref, size_t capacity, TyBase *type,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::ARRAY, refs), capacity (capacity),
+ element_type_id (type->get_ref ())
{}
void accept_vis (TyVisitor &vis) override;
@@ -297,21 +376,27 @@ public:
size_t get_capacity () const { return capacity; }
- TyBase *get_type () { return type; }
+ HirId element_type_ref () const { return element_type_id; }
+
+ TyBase *get_type () const;
TyBase *clone () final override;
private:
size_t capacity;
- TyBase *type;
+ HirId element_type_id;
};
class BoolType : public TyBase
{
public:
- BoolType (HirId ref) : TyBase (ref, ref, TypeKind::BOOL) {}
+ BoolType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::BOOL, refs)
+ {}
- BoolType (HirId ref, HirId ty_ref) : TyBase (ref, ty_ref, TypeKind::BOOL) {}
+ BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::BOOL, refs)
+ {}
void accept_vis (TyVisitor &vis) override;
@@ -334,12 +419,13 @@ public:
I128
};
- IntType (HirId ref, IntKind kind)
- : TyBase (ref, ref, TypeKind::INT), int_kind (kind)
+ IntType (HirId ref, IntKind kind, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::INT, refs), int_kind (kind)
{}
- IntType (HirId ref, HirId ty_ref, IntKind kind)
- : TyBase (ref, ty_ref, TypeKind::INT), int_kind (kind)
+ IntType (HirId ref, HirId ty_ref, IntKind kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::INT, refs), int_kind (kind)
{}
void accept_vis (TyVisitor &vis) override;
@@ -368,12 +454,13 @@ public:
U128
};
- UintType (HirId ref, UintKind kind)
- : TyBase (ref, ref, TypeKind::UINT), uint_kind (kind)
+ UintType (HirId ref, UintKind kind, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::UINT, refs), uint_kind (kind)
{}
- UintType (HirId ref, HirId ty_ref, UintKind kind)
- : TyBase (ref, ty_ref, TypeKind::UINT), uint_kind (kind)
+ UintType (HirId ref, HirId ty_ref, UintKind kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::UINT, refs), uint_kind (kind)
{}
void accept_vis (TyVisitor &vis) override;
@@ -399,12 +486,14 @@ public:
F64
};
- FloatType (HirId ref, FloatKind kind)
- : TyBase (ref, ref, TypeKind::FLOAT), float_kind (kind)
+ FloatType (HirId ref, FloatKind kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::FLOAT, refs), float_kind (kind)
{}
- FloatType (HirId ref, HirId ty_ref, FloatKind kind)
- : TyBase (ref, ty_ref, TypeKind::FLOAT), float_kind (kind)
+ FloatType (HirId ref, HirId ty_ref, FloatKind kind,
+ std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::FLOAT, refs), float_kind (kind)
{}
void accept_vis (TyVisitor &vis) override;
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 951bdcc..925130f 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -159,6 +159,7 @@ Mappings::get_next_hir_id (CrateNum crateNum)
auto id = it->second + 1;
hirIdIter[crateNum] = id;
+ hirNodesWithinCrate[crateNum].insert (id);
return id;
}
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 3818be9..4859d1e 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -143,6 +143,11 @@ public:
return resolve_nodeid_to_stmt (get_current_crate (), id, stmt);
}
+ std::set<HirId> &get_hirids_within_crate (CrateNum crate)
+ {
+ return hirNodesWithinCrate[crate];
+ }
+
private:
Mappings ();
@@ -171,6 +176,9 @@ private:
// reverse mappings
std::map<CrateNum, std::map<NodeId, HirId> > nodeIdToHirMappings;
+
+ // all hirid nodes
+ std::map<CrateNum, std::set<HirId> > hirNodesWithinCrate;
};
} // namespace Analysis
diff --git a/gcc/testsuite/rust.test/compilable/ints_infer1.rs b/gcc/testsuite/rust.test/compilable/ints_infer1.rs
new file mode 100644
index 0000000..3170c7c
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/ints_infer1.rs
@@ -0,0 +1,18 @@
+const TEST_CONST: i32 = 10;
+
+fn main() {
+ let mut x = TEST_CONST;
+ x = x + 1;
+
+ let mut y = x + TEST_CONST;
+
+ let z = 1u32;
+
+ let a = z;
+
+ let b;
+ b = 1;
+
+ let c;
+ c = a;
+}
diff --git a/gcc/testsuite/rust.test/compilable/type_infer6.rs b/gcc/testsuite/rust.test/compilable/type_infer6.rs
new file mode 100644
index 0000000..f6eac9e
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/type_infer6.rs
@@ -0,0 +1,12 @@
+fn test(x: u32) -> u32 {
+ return x + 1;
+}
+
+fn main() {
+ let a;
+ a = 1;
+ let b = test(a);
+
+ let c = 1;
+ let d = test(c + 1);
+}