From f8d41b7e8a3a65382dc5ce30dfb3f85abe298d19 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Mon, 18 Jan 2021 15:51:35 +0000 Subject: Add TupleIndexExpressions Now we can type resolve and reference the results from TupleIndexExpr's. --- gcc/rust/backend/rust-compile-expr.h | 11 ++++++++ gcc/rust/hir/rust-ast-lower-expr.h | 19 ++++++++++++++ gcc/rust/hir/tree/rust-hir-expr.h | 6 +++++ gcc/rust/resolve/rust-ast-resolve-expr.h | 5 ++++ gcc/rust/typecheck/rust-hir-type-check-expr.h | 36 +++++++++++++++++++++++++++ 5 files changed, 77 insertions(+) (limited to 'gcc/rust') 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 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 (tuple_expr), + expr.get_tuple_index (), + std::move (outer_attribs), expr.get_locus ()); + } + void visit (AST::TupleExpr &expr) { std::vector 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 &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 ()) -- cgit v1.1