aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/backend/rust-compile-expr.h9
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h55
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h15
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h13
-rw-r--r--gcc/testsuite/rust.test/compilable/arrays2.rs7
-rw-r--r--gcc/testsuite/rust.test/compilable/arrays_index1.rs8
7 files changed, 96 insertions, 15 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 6ea97ee..5c3206a 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -211,6 +211,15 @@ public:
});
}
+ void visit (HIR::ArrayElemsCopied &elems)
+ {
+ Bexpression *translated_expr
+ = CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
+
+ for (size_t i = 0; i < elems.get_num_elements (); ++i)
+ constructor.push_back (translated_expr);
+ }
+
void visit (HIR::ArithmeticOrLogicalExpr &expr)
{
Operator op;
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index b919905..a165eaf 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -26,6 +26,42 @@
namespace Rust {
namespace HIR {
+class ArrayCapacityConstant : public ASTLoweringBase
+{
+public:
+ static bool fold (AST::Expr *expr, size_t *folded_result)
+ {
+ ArrayCapacityConstant folder;
+ expr->accept_vis (folder);
+ *folded_result = folder.result;
+ return folder.ok;
+ }
+
+ virtual ~ArrayCapacityConstant () {}
+
+ void visit (AST::LiteralExpr &expr)
+ {
+ switch (expr.get_lit_type ())
+ {
+ case AST::Literal::LitType::INT: {
+ ok = true;
+ std::stringstream ss (expr.as_string ());
+ ss >> result;
+ }
+ break;
+
+ default:
+ return;
+ }
+ }
+
+private:
+ ArrayCapacityConstant () : ok (false), result (-1) {}
+
+ bool ok;
+ size_t result;
+}; // namespace Resolver
+
class ASTLoweringExpr : public ASTLoweringBase
{
public:
@@ -209,8 +245,23 @@ public:
void visit (AST::ArrayElemsCopied &elems)
{
- // TODO
- gcc_unreachable ();
+ HIR::Expr *element
+ = ASTLoweringExpr::translate (elems.get_elem_to_copy ().get ());
+ HIR::Expr *num_copies
+ = ASTLoweringExpr::translate (elems.get_num_copies ().get ());
+
+ size_t folded;
+ if (!ArrayCapacityConstant::fold (elems.get_num_copies ().get (), &folded))
+ {
+ rust_fatal_error (elems.get_num_copies ()->get_locus_slow (),
+ "failed to fold capacity constant");
+ return;
+ }
+
+ translated_array_elems
+ = new HIR::ArrayElemsCopied (std::unique_ptr<HIR::Expr> (element),
+ std::unique_ptr<HIR::Expr> (num_copies),
+ folded);
}
void visit (AST::LiteralExpr &expr)
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 7c32ac2..1110f98 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -980,21 +980,25 @@ class ArrayElemsCopied : public ArrayElems
{
std::unique_ptr<Expr> elem_to_copy;
std::unique_ptr<Expr> num_copies;
+ size_t folded_copy_amount;
// TODO: should this store location data?
public:
// Constructor requires pointers for polymorphism
ArrayElemsCopied (std::unique_ptr<Expr> copied_elem,
- std::unique_ptr<Expr> copy_amount)
+ std::unique_ptr<Expr> copy_amount,
+ size_t folded_copy_amount)
: elem_to_copy (std::move (copied_elem)),
- num_copies (std::move (copy_amount))
+ num_copies (std::move (copy_amount)),
+ folded_copy_amount (folded_copy_amount)
{}
// Copy constructor required due to unique_ptr - uses custom clone
ArrayElemsCopied (ArrayElemsCopied const &other)
: elem_to_copy (other.elem_to_copy->clone_expr ()),
- num_copies (other.num_copies->clone_expr ())
+ num_copies (other.num_copies->clone_expr ()),
+ folded_copy_amount (other.folded_copy_amount)
{}
// Overloaded assignment operator for deep copying
@@ -1002,6 +1006,7 @@ public:
{
elem_to_copy = other.elem_to_copy->clone_expr ();
num_copies = other.num_copies->clone_expr ();
+ folded_copy_amount = other.folded_copy_amount;
return *this;
}
@@ -1014,7 +1019,9 @@ public:
void accept_vis (HIRVisitor &vis) override;
- size_t get_num_elements () const override { return 0; }
+ size_t get_num_elements () const override { return folded_copy_amount; }
+
+ Expr *get_elem_to_copy () { return elem_to_copy.get (); }
protected:
ArrayElemsCopied *clone_array_elems_impl () const override
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 54d33a8..d86866c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -150,8 +150,8 @@ public:
void visit (AST::ArrayElemsCopied &elems)
{
- // TODO
- gcc_unreachable ();
+ ResolveExpr::go (elems.get_num_copies ().get (), elems.get_node_id ());
+ ResolveExpr::go (elems.get_elem_to_copy ().get (), elems.get_node_id ());
}
private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 999523f..116fab7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -232,15 +232,9 @@ public:
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)
@@ -270,6 +264,11 @@ public:
}
}
+ void visit (HIR::ArrayElemsCopied &elems)
+ {
+ infered_array_elems = TypeCheckExpr::Resolve (elems.get_elem_to_copy ());
+ }
+
private:
TypeCheckExpr ()
: TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr)
diff --git a/gcc/testsuite/rust.test/compilable/arrays2.rs b/gcc/testsuite/rust.test/compilable/arrays2.rs
new file mode 100644
index 0000000..a3c8523
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/arrays2.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let mut array: [i32; 3] = [0; 3];
+
+ let a = array[0];
+ let mut c;
+ c = array[2];
+}
diff --git a/gcc/testsuite/rust.test/compilable/arrays_index1.rs b/gcc/testsuite/rust.test/compilable/arrays_index1.rs
new file mode 100644
index 0000000..8dd1c04
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/arrays_index1.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let mut array: [i32; 3] = [0; 3];
+
+ let a = array[0];
+ let x = 0;
+ let mut c;
+ c = array[x+1];
+}