aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-18 15:51:35 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-20 09:59:22 +0000
commitf8d41b7e8a3a65382dc5ce30dfb3f85abe298d19 (patch)
treef1b6f0b25bfafe426090a3294762ba982f215165
parent9a942d6fbd0cc087cbc801ce4681a498e59dce2c (diff)
downloadgcc-f8d41b7e8a3a65382dc5ce30dfb3f85abe298d19.zip
gcc-f8d41b7e8a3a65382dc5ce30dfb3f85abe298d19.tar.gz
gcc-f8d41b7e8a3a65382dc5ce30dfb3f85abe298d19.tar.bz2
Add TupleIndexExpressions
Now we can type resolve and reference the results from TupleIndexExpr's.
-rw-r--r--gcc/rust/backend/rust-compile-expr.h11
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h19
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h36
-rw-r--r--gcc/testsuite/rust.test/compilable/tuple3.rs9
-rw-r--r--gcc/testsuite/rust.test/compilable/tuple_struct2.rs11
7 files changed, 97 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 8b99574..ff02d6b 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -38,6 +38,17 @@ public:
return compiler.translated;
}
+ void visit (HIR::TupleIndexExpr &expr)
+ {
+ HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
+ TupleIndex index = expr.get_tuple_index ();
+
+ Bexpression *receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
+ translated
+ = ctx->get_backend ()->struct_field_expression (receiver_ref, index,
+ expr.get_locus ());
+ }
+
void visit (HIR::TupleExpr &expr)
{
if (expr.is_unit ())
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 29be5cc..6f872ab 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -132,6 +132,25 @@ public:
return resolver.translated;
}
+ void visit (AST::TupleIndexExpr &expr)
+ {
+ std::vector<HIR::Attribute> outer_attribs;
+
+ HIR::Expr *tuple_expr
+ = ASTLoweringExpr::translate (expr.get_tuple_expr ().get (), &terminated);
+
+ 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::TupleIndexExpr (mapping,
+ std::unique_ptr<HIR::Expr> (tuple_expr),
+ expr.get_tuple_index (),
+ std::move (outer_attribs), expr.get_locus ());
+ }
+
void visit (AST::TupleExpr &expr)
{
std::vector<HIR::Attribute> inner_attribs;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index cc717a8..a81d523 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -1314,6 +1314,12 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::unique_ptr<Expr> &get_tuple_expr ()
+ {
+ rust_assert (tuple_expr != nullptr);
+ return tuple_expr;
+ }
+
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 9a7e231..91ed6e0 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -35,6 +35,11 @@ public:
expr->accept_vis (resolver);
};
+ void visit (AST::TupleIndexExpr &expr)
+ {
+ ResolveExpr::go (expr.get_tuple_expr ().get (), expr.get_node_id ());
+ }
+
void visit (AST::TupleExpr &expr)
{
if (expr.is_unit ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 5f2477e..fddbdeb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -46,6 +46,42 @@ public:
return resolver.infered;
}
+ void visit (HIR::TupleIndexExpr &expr)
+ {
+ auto resolved = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get ());
+ if (resolved == nullptr)
+ {
+ rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+ "failed to resolve TupleIndexExpr receiver");
+ return;
+ }
+ if (resolved->get_kind () != TyTy::TypeKind::ADT)
+ {
+ rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+ "Expected ADT type got: %s",
+ resolved->as_string ().c_str ());
+ return;
+ }
+
+ TyTy::ADTType *adt = (TyTy::ADTType *) resolved;
+ TupleIndex index = expr.get_tuple_index ();
+ if ((size_t) index >= adt->num_fields ())
+ {
+ rust_error_at (expr.get_locus (), "unknown field at index %i", index);
+ return;
+ }
+
+ auto field_tyty = adt->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->get_field_type ();
+ }
+
void visit (HIR::TupleExpr &expr)
{
if (expr.is_unit ())
diff --git a/gcc/testsuite/rust.test/compilable/tuple3.rs b/gcc/testsuite/rust.test/compilable/tuple3.rs
new file mode 100644
index 0000000..d0fb6fc
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/tuple3.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let a = (1, true);
+
+ let b;
+ let c;
+
+ b = a.0;
+ c = a.1;
+}
diff --git a/gcc/testsuite/rust.test/compilable/tuple_struct2.rs b/gcc/testsuite/rust.test/compilable/tuple_struct2.rs
new file mode 100644
index 0000000..5e0a76e
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/tuple_struct2.rs
@@ -0,0 +1,11 @@
+struct Foo(i32, bool);
+
+fn main() {
+ let a = Foo(1, true);
+
+ let b;
+ let c;
+
+ b = a.0;
+ c = a.1;
+}