diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-18 15:51:35 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-20 09:59:22 +0000 |
commit | f8d41b7e8a3a65382dc5ce30dfb3f85abe298d19 (patch) | |
tree | f1b6f0b25bfafe426090a3294762ba982f215165 | |
parent | 9a942d6fbd0cc087cbc801ce4681a498e59dce2c (diff) | |
download | gcc-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.h | 11 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 19 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 36 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/tuple3.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/tuple_struct2.rs | 11 |
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; +} |