aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-11-05 12:32:44 +0000
committerPhilip Herron <philip.herron@embecosm.com>2021-11-05 12:45:32 +0000
commit17dc14cb4b0819532376a22b592b26dd6ffc364f (patch)
tree9286859b3eac842bcb0f76f1fc1d6ce987d488b6 /gcc
parentd2f92e6a73338c986601a071b8641c051e700aba (diff)
downloadgcc-17dc14cb4b0819532376a22b592b26dd6ffc364f.zip
gcc-17dc14cb4b0819532376a22b592b26dd6ffc364f.tar.gz
gcc-17dc14cb4b0819532376a22b592b26dd6ffc364f.tar.bz2
Support forward declared items within blocks
This changes the BlockExpr resolution to iterate Items first, then the Stmts. This could be handled in HIR by desugaring the BlockExpr by lowering the block into { <items>; <stmts>; } would also work. But the HIR lowering of blocks is a little messy right now and we need to clean up the unreachable lint. Fixes #531
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h9
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc43
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h12
-rw-r--r--gcc/testsuite/rust/compile/torture/forward_decl_5.rs19
6 files changed, 68 insertions, 34 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index c472cab..575d1f6 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2007,15 +2007,6 @@ public:
void accept_vis (HIRVisitor &vis) override;
- void iterate_stmts (std::function<bool (Stmt *)> cb)
- {
- for (auto it = statements.begin (); it != statements.end (); it++)
- {
- if (!cb (it->get ()))
- return;
- }
- }
-
bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
Location get_closing_locus ()
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index 7b7b68f..ca5d894 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -97,10 +97,10 @@ public:
void visit (HIR::BlockExpr &expr) override
{
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- s->accept_vis (*this);
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ s->accept_vis (*this);
+ }
if (expr.has_expr ())
{
expr.get_final_expr ()->accept_vis (*this);
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 83a15a8..2758c83 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -349,7 +349,16 @@ ResolveExpr::visit (AST::BlockExpr &expr)
resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
for (auto &s : expr.get_statements ())
- ResolveStmt::go (s.get (), s->get_node_id ());
+ {
+ if (s->is_item ())
+ ResolveStmt::go (s.get (), s->get_node_id ());
+ }
+
+ for (auto &s : expr.get_statements ())
+ {
+ if (!s->is_item ())
+ ResolveStmt::go (s.get (), s->get_node_id ());
+ }
if (expr.has_tail_expr ())
ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 5237082..ca4842a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -93,22 +93,37 @@ TypeResolution::Resolve (HIR::Crate &crate)
void
TypeCheckExpr::visit (HIR::BlockExpr &expr)
{
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- auto resolved = TypeCheckStmt::Resolve (s, inside_loop);
- if (resolved == nullptr)
- {
- rust_error_at (s->get_locus (), "failure to resolve type");
- return false;
- }
+ for (auto &s : expr.get_statements ())
+ {
+ if (!s->is_item ())
+ continue;
- if (s->is_unit_check_needed () && !resolved->is_unit ())
- {
- auto unit = new TyTy::TupleType (s->get_mappings ().get_hirid ());
- resolved = unit->unify (resolved);
- }
+ auto resolved = TypeCheckStmt::Resolve (s.get (), inside_loop);
+ if (resolved == nullptr)
+ {
+ rust_error_at (s->get_locus (), "failure to resolve type");
+ return;
+ }
+ }
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ if (s->is_item ())
+ continue;
+
+ auto resolved = TypeCheckStmt::Resolve (s.get (), inside_loop);
+ if (resolved == nullptr)
+ {
+ rust_error_at (s->get_locus (), "failure to resolve type");
+ return;
+ }
+
+ if (s->is_unit_check_needed () && !resolved->is_unit ())
+ {
+ auto unit = new TyTy::TupleType (s->get_mappings ().get_hirid ());
+ resolved = unit->unify (resolved);
+ }
+ }
if (expr.has_expr ())
infered
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index c0681b8..c305d48 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -94,12 +94,12 @@ public:
{
indentation_level++;
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- dump += indent ();
- s->accept_vis (*this);
- dump += ";\n";
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ dump += indent ();
+ s->accept_vis (*this);
+ dump += ";\n";
+ }
if (expr.has_expr ())
{
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_5.rs b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
new file mode 100644
index 0000000..73a47fe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
@@ -0,0 +1,19 @@
+pub fn main() {
+ let a;
+ a = foo { a: 123, b: 456f32 };
+
+ let mut a = 123;
+ a = bar(a);
+
+ let mut b = 456f32;
+ b = bar(b);
+
+ fn bar<T>(x: T) -> T {
+ x
+ }
+
+ struct foo {
+ a: i32,
+ b: f32,
+ };
+}