diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 17 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 16 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 43 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 60 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 22 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 13 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 25 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 7 | ||||
-rw-r--r-- | gcc/rust/rust-backend.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 56 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 53 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-resolver.h | 50 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 46 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-visitor.h | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 19 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 22 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/type_infer4.rs | 9 |
18 files changed, 442 insertions, 30 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 8e60557..cc87498 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -952,9 +952,15 @@ public: virtual void accept_vis (ASTVisitor &vis) = 0; + NodeId get_node_id () const { return node_id; } + protected: + ArrayElems () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} + // pure virtual clone implementation virtual ArrayElems *clone_array_elems_impl () const = 0; + + NodeId node_id; }; // Value array elements @@ -966,7 +972,7 @@ class ArrayElemsValues : public ArrayElems public: ArrayElemsValues (std::vector<std::unique_ptr<Expr> > elems) - : values (std::move (elems)) + : ArrayElems (), values (std::move (elems)) {} // copy constructor with vector clone @@ -1032,7 +1038,7 @@ public: // Constructor requires pointers for polymorphism ArrayElemsCopied (std::unique_ptr<Expr> copied_elem, std::unique_ptr<Expr> copy_amount) - : elem_to_copy (std::move (copied_elem)), + : ArrayElems (), elem_to_copy (std::move (copied_elem)), num_copies (std::move (copy_amount)) {} @@ -1091,10 +1097,6 @@ class ArrayExpr : public ExprWithoutBlock // TODO: find another way to store this to save memory? bool marked_for_strip = false; - // this is a reference to what the inferred type is based on - // this init expression - Type *inferredType; - public: std::string as_string () const override; @@ -1159,9 +1161,6 @@ public: return internal_elements; } - Type *get_inferred_type () { return inferredType; } - void set_inferred_type (Type *type) { inferredType = type; } - protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 1924b52..5736bf2 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -211,6 +211,19 @@ public: void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override + { + mpz_t ival; + mpz_init_set_ui (ival, type.get_capacity ()); + + Btype *capacity_type = ctx->get_backend ()->integer_type (true, 32); + Bexpression *length + = ctx->get_backend ()->integer_constant_expression (capacity_type, ival); + + Btype *element_type = TyTyResolveCompile::compile (ctx, type.get_type ()); + translated = ctx->get_backend ()->array_type (element_type, length); + } + void visit (TyTy::BoolType &type) override { ::Btype *compiled_type = nullptr; @@ -221,9 +234,6 @@ public: void visit (TyTy::IntType &type) override { - printf ("type [%s] has ref: %u\n", type.as_string ().c_str (), - type.get_ref ()); - ::Btype *compiled_type = nullptr; bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); rust_assert (ok); diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 854fe5e..6ea97ee 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -169,6 +169,48 @@ public: ctx->add_statement (assignment); } + void visit (HIR::ArrayIndexExpr &expr) + { + Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx); + Bexpression *index = CompileExpr::Compile (expr.get_index_expr (), ctx); + translated + = ctx->get_backend ()->array_index_expression (array, index, + expr.get_locus ()); + } + + void visit (HIR::ArrayExpr &expr) + { + TyTy::TyBase *tyty = nullptr; + if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty)) + { + rust_fatal_error (expr.get_locus (), + "did not resolve type for this array expr"); + return; + } + + Btype *array_type = TyTyResolveCompile::compile (ctx, tyty); + + expr.get_internal_elements ()->accept_vis (*this); + std::vector<unsigned long> indexes; + for (size_t i = 0; i < constructor.size (); i++) + indexes.push_back (i); + + translated + = ctx->get_backend ()->array_constructor_expression (array_type, indexes, + constructor, + expr.get_locus ()); + } + + void visit (HIR::ArrayElemsValues &elems) + { + elems.iterate ([&] (HIR::Expr *e) mutable -> bool { + Bexpression *translated_expr = CompileExpr::Compile (e, ctx); + constructor.push_back (translated_expr); + return true; + }); + } + void visit (HIR::ArithmeticOrLogicalExpr &expr) { Operator op; @@ -303,6 +345,7 @@ private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} Bexpression *translated; + std::vector<Bexpression *> constructor; }; } // namespace Compile diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 19d599a..b919905 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -156,6 +156,63 @@ public: = new HIR::IdentifierExpr (mapping, expr.as_string (), expr.get_locus ()); } + void visit (AST::ArrayExpr &expr) + { + std::vector<HIR::Attribute> outer_attribs; + std::vector<HIR::Attribute> inner_attribs; + + expr.get_array_elems ()->accept_vis (*this); + rust_assert (translated_array_elems != nullptr); + HIR::ArrayElems *elems = translated_array_elems; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ArrayExpr (mapping, std::unique_ptr<HIR::ArrayElems> (elems), + inner_attribs, outer_attribs, expr.get_locus ()); + } + + void visit (AST::ArrayIndexExpr &expr) + { + std::vector<Attribute> outer_attribs; + HIR::Expr *array_expr + = ASTLoweringExpr::translate (expr.get_array_expr ().get ()); + HIR::Expr *array_index_expr + = ASTLoweringExpr::translate (expr.get_index_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ArrayIndexExpr (mapping, + std::unique_ptr<HIR::Expr> (array_expr), + std::unique_ptr<HIR::Expr> (array_index_expr), + outer_attribs, expr.get_locus ()); + } + + void visit (AST::ArrayElemsValues &elems) + { + std::vector<std::unique_ptr<HIR::Expr> > elements; + elems.iterate ([&] (AST::Expr *elem) mutable -> bool { + HIR::Expr *translated_elem = ASTLoweringExpr::translate (elem); + elements.push_back (std::unique_ptr<HIR::Expr> (translated_elem)); + return true; + }); + + translated_array_elems = new HIR::ArrayElemsValues (std::move (elements)); + } + + void visit (AST::ArrayElemsCopied &elems) + { + // TODO + gcc_unreachable (); + } + void visit (AST::LiteralExpr &expr) { HIR::Literal::LitType type = HIR::Literal::LitType::CHAR; @@ -324,9 +381,10 @@ public: } private: - ASTLoweringExpr () : translated (nullptr) {} + ASTLoweringExpr () : translated (nullptr), translated_array_elems (nullptr) {} HIR::Expr *translated; + HIR::ArrayElems *translated_array_elems; }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 4193415..2e14ad2 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -21,6 +21,7 @@ #include "rust-ast-lower-base.h" #include "rust-diagnostics.h" +#include "rust-ast-lower-expr.h" namespace Rust { namespace HIR { @@ -77,6 +78,27 @@ public: translated); } + void visit (AST::ArrayType &type) + { + HIR::Type *translated_type + = ASTLoweringType::translate (type.get_elem_type ().get ()); + HIR::Expr *array_size + = ASTLoweringExpr::translate (type.get_size_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, type.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated + = new HIR::ArrayType (mapping, + std::unique_ptr<HIR::Type> (translated_type), + std::unique_ptr<HIR::Expr> (array_size), + type.get_locus ()); + mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (), + translated); + } + private: ASTLoweringType () : translated (nullptr) {} diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 7e1c76b..7c32ac2 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -912,6 +912,8 @@ public: virtual void accept_vis (HIRVisitor &vis) = 0; + virtual size_t get_num_elements () const = 0; + protected: // pure virtual clone implementation virtual ArrayElems *clone_array_elems_impl () const = 0; @@ -955,7 +957,7 @@ public: void accept_vis (HIRVisitor &vis) override; - size_t get_num_values () const { return values.size (); } + size_t get_num_elements () const override { return values.size (); } void iterate (std::function<bool (Expr *)> cb) { @@ -1012,6 +1014,8 @@ public: void accept_vis (HIRVisitor &vis) override; + size_t get_num_elements () const override { return 0; } + protected: ArrayElemsCopied *clone_array_elems_impl () const override { @@ -1027,10 +1031,6 @@ class ArrayExpr : public ExprWithoutBlock Location locus; - // this is a reference to what the inferred type is based on - // this init expression - Type *inferredType; - public: std::string as_string () const override; @@ -1082,9 +1082,6 @@ public: ArrayElems *get_internal_elements () { return internal_elements.get (); }; - Type *get_inferred_type () { return inferredType; } - void set_inferred_type (Type *type) { inferredType = type; } - protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 3316b2a..54d33a8 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -129,6 +129,31 @@ public: void visit (AST::BlockExpr &expr); + void visit (AST::ArrayElemsValues &elems) + { + elems.iterate ([&] (AST::Expr *elem) mutable -> bool { + ResolveExpr::go (elem, elems.get_node_id ()); + return true; + }); + } + + void visit (AST::ArrayExpr &expr) + { + expr.get_array_elems ()->accept_vis (*this); + } + + void visit (AST::ArrayIndexExpr &expr) + { + ResolveExpr::go (expr.get_array_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_index_expr ().get (), expr.get_node_id ()); + } + + void visit (AST::ArrayElemsCopied &elems) + { + // TODO + gcc_unreachable (); + } + private: ResolveExpr (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 3cffa77..9d408a9 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -42,7 +42,7 @@ public: ~ResolveType () {} - virtual void visit (AST::TypePath &path) + void visit (AST::TypePath &path) { // this will need changed to handle mod/crate/use globs and look // at the segments in granularity @@ -56,6 +56,11 @@ public: } } + void visit (AST::ArrayType &type) + { + type.get_elem_type ()->accept_vis (*this); + } + private: ResolveType (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index bc8ca96..210eff3 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -23,6 +23,8 @@ #include <mpfr.h> #include <mpc.h> +#include "rust-location.h" +#include "rust-linemap.h" #include "operator.h" extern bool diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 8be2dbf..999523f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -23,6 +23,7 @@ #include "rust-hir-full.h" #include "rust-tyty.h" #include "rust-tyty-call.h" +#include "rust-tyty-resolver.h" namespace Rust { namespace Resolver { @@ -219,10 +220,63 @@ public: void visit (HIR::BlockExpr &expr); + void visit (HIR::ArrayIndexExpr &expr) + { + // check the index + 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 ())); + context->insert_type (expr.get_index_expr ()->get_mappings ().get_hirid (), + resolved); + + expr.get_array_expr ()->accept_vis (*this); + rust_assert (infered != nullptr); + printf ("Resolved array-index 1 [%u] -> %s\n", + expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); + // extract the element type out now from the base type + infered = TyTyExtractorArray::ExtractElementTypeFromArray (infered); + + printf ("Resolved array-index 2 [%u] -> %s\n", + expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); + printf ("array-expr node [%u]\n", + expr.get_array_expr ()->get_mappings ().get_hirid ()); + } + + void visit (HIR::ArrayExpr &expr) + { + HIR::ArrayElems *elements = expr.get_internal_elements (); + size_t num_elems = elements->get_num_elements (); + + elements->accept_vis (*this); + rust_assert (infered_array_elems != nullptr); + + infered = new TyTy::ArrayType (expr.get_mappings ().get_hirid (), num_elems, + infered_array_elems); + } + + void visit (HIR::ArrayElemsValues &elems) + { + std::vector<TyTy::TyBase *> types; + elems.iterate ([&] (HIR::Expr *e) mutable -> bool { + types.push_back (TypeCheckExpr::Resolve (e)); + return true; + }); + + infered_array_elems = types[0]; + for (size_t i = 1; i < types.size (); i++) + { + infered_array_elems = infered_array_elems->combine (types.at (i)); + } + } + private: - TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {} + TypeCheckExpr () + : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr) + {} TyTy::TyBase *infered; + TyTy::TyBase *infered_array_elems; }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index d3189cc..dbf6583 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -59,8 +59,15 @@ public: // let x:i32 = 123; if (specified_ty != nullptr && init_expr_ty != nullptr) { - context->insert_type (stmt.get_mappings ().get_hirid (), - specified_ty->combine (init_expr_ty)); + auto combined = specified_ty->combine (init_expr_ty); + if (combined == nullptr) + { + rust_fatal_error (stmt.get_locus (), + "failure in setting up let stmt type"); + return; + } + + context->insert_type (stmt.get_mappings ().get_hirid (), combined); } else { diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index beab77a..21d6c23 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -25,6 +25,42 @@ namespace Rust { namespace Resolver { +class ArrayCapacityConstant : public TypeCheckBase +{ +public: + static bool fold (HIR::Expr *expr, size_t *folded_result) + { + ArrayCapacityConstant folder; + expr->accept_vis (folder); + *folded_result = folder.result; + return folder.ok; + } + + virtual ~ArrayCapacityConstant () {} + + void visit (HIR::LiteralExpr &expr) + { + switch (expr.get_lit_type ()) + { + case HIR::Literal::LitType::INT: { + ok = true; + std::stringstream ss (expr.as_string ()); + ss >> result; + } + break; + + default: + return; + } + } + +private: + ArrayCapacityConstant () : TypeCheckBase (), ok (false), result (-1) {} + + bool ok; + size_t result; +}; // namespace Resolver + class TypeCheckType : public TypeCheckBase { public: @@ -40,7 +76,7 @@ public: return resolver.translated; } - virtual void visit (HIR::TypePath &path) + void visit (HIR::TypePath &path) { // check if this is already defined or not if (context->lookup_type (path.get_mappings ().get_hirid (), &translated)) @@ -70,6 +106,21 @@ public: gcc_unreachable (); } + void visit (HIR::ArrayType &type) + { + size_t capacity; + if (!ArrayCapacityConstant::fold (type.get_size_expr (), &capacity)) + { + rust_error_at (type.get_size_expr ()->get_locus_slow (), + "non-constant value"); + return; + } + + TyTy::TyBase *base = TypeCheckType::Resolve (type.get_element_type ()); + translated + = new TyTy::ArrayType (type.get_mappings ().get_hirid (), capacity, base); + } + private: TypeCheckType () : TypeCheckBase (), translated (nullptr) {} diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index b971e66..2851a1e 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -25,6 +25,7 @@ #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 { @@ -63,9 +64,25 @@ public: TyTy::TyBase *resolved = nullptr; if (!context->lookup_type (hir_node_ref, &resolved)) { - rust_fatal_error (mappings->lookup_location (hir_node_ref), - "failed to lookup type for reference"); - return false; + // this could be an array/adt type + Definition d; + bool ok = resolver->lookup_definition (ref_node, &d); + rust_assert (ok); + + ok = mappings->lookup_node_to_hir (mappings->get_current_crate (), + d.parent, &hir_node_ref); + rust_assert (ok); + + printf ("failed lets try [%u]\n", hir_node_ref); + + if (!context->lookup_type (hir_node_ref, &resolved)) + { + rust_fatal_error ( + mappings->lookup_location (hir_node_ref), + "failed to lookup type for reference at node [%u]", + hir_node_ref); + return false; + } } gathered_types.push_back (resolved); @@ -85,6 +102,11 @@ public: &resolved_type); rust_assert (ok); + if (!resolved_type->is_unit ()) + { + return true; + } + auto resolved_tyty = resolved_type; for (auto it : gathered_types) { @@ -120,8 +142,28 @@ private: TypeCheckContext *context; }; -} // namespace Resolver +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::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 205ef44..97ee895 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -60,6 +60,13 @@ public: type.as_string ().c_str ()); } + virtual void visit (ArrayType &type) override + { + Location locus = mappings->lookup_location (type.get_ref ()); + rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (BoolType &type) override { Location locus = mappings->lookup_location (type.get_ref ()); @@ -181,6 +188,45 @@ private: TyBase *resolved; }; +class ArrayRules : protected BaseRules +{ +public: + ArrayRules (ArrayType *base) + : BaseRules (base), base (base), resolved (nullptr) + {} + + ~ArrayRules () {} + + 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; + + // 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"); + return; + } + + resolved + = new ArrayType (type.get_ref (), type.get_capacity (), base_resolved); + } + +private: + ArrayType *base; + TyBase *resolved; +}; + class BoolRules : protected BaseRules { public: diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 68a8a43..427190f 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) {} virtual void visit (FnType &type) {} virtual void visit (ParamType &type) {} + virtual void visit (ArrayType &type) {} virtual void visit (BoolType &type) {} virtual void visit (IntType &type) {} virtual void visit (UintType &type) {} diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 4a36d4f..2023523 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -110,6 +110,25 @@ ParamType::combine (TyBase *other) } void +ArrayType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +std::string +ArrayType::as_string () const +{ + return "[" + type->as_string () + ":" + std::to_string (capacity) + "]"; +} + +TyBase * +ArrayType::combine (TyBase *other) +{ + ArrayRules r (this); + return r.combine (other); +} + +void BoolType::accept_vis (TyVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 4e04490..b9dc268 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -143,6 +143,28 @@ private: TyBase *type; }; +class ArrayType : public TyBase +{ +public: + ArrayType (HirId ref, size_t capacity, TyBase *type) + : TyBase (ref, TypeKind::ARRAY), capacity (capacity), type (type) + {} + + void accept_vis (TyVisitor &vis) override; + + std::string as_string () const override; + + TyBase *combine (TyBase *other) override; + + size_t get_capacity () const { return capacity; } + + TyBase *get_type () { return type; } + +private: + size_t capacity; + TyBase *type; +}; + class BoolType : public TyBase { public: diff --git a/gcc/testsuite/rust.test/compilable/type_infer4.rs b/gcc/testsuite/rust.test/compilable/type_infer4.rs new file mode 100644 index 0000000..8e123e2 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/type_infer4.rs @@ -0,0 +1,9 @@ +fn main() { + let xs: [i32; 5] = [1, 2, 3, 4, 5]; + let xy = [6, 7, 8]; + + let a = xs[0]; + let b = xy[2]; + let mut c; + c = xs[0]; +} |