diff options
Diffstat (limited to 'gcc')
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); +} |