diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-11-05 17:42:34 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-05 17:42:34 +0000 |
commit | 57c31311b33e0575adb2c7465f8fa2869e40dbce (patch) | |
tree | 21c23aa6eabd9d7fcdfdb2b5c9f2638b12876977 /gcc | |
parent | 5074f89f4fd0be3f5fbaf46db604a0b961e7267d (diff) | |
parent | 17dc14cb4b0819532376a22b592b26dd6ffc364f (diff) | |
download | gcc-57c31311b33e0575adb2c7465f8fa2869e40dbce.zip gcc-57c31311b33e0575adb2c7465f8fa2869e40dbce.tar.gz gcc-57c31311b33e0575adb2c7465f8fa2869e40dbce.tar.bz2 |
Merge #796
796: Handle forward declared items within blocks r=philberty a=philberty
This changes the resolution in BlockExpr's to iterate the Items then Stmts
but we might want to handle this by desugaring the HIR BlockExpr to have
items then stmts to ensure we type resolve the items before the stmts.
Fixes #531
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 4 | ||||
-rw-r--r-- | gcc/rust/ast/rust-stmt.h | 6 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 9 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-stmt.h | 6 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir.h | 4 | ||||
-rw-r--r-- | gcc/rust/lint/rust-lint-marklive.h | 8 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 43 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tycheck-dump.h | 12 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/forward_decl_5.rs | 19 |
10 files changed, 88 insertions, 34 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 95e4738..72f2609 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -822,6 +822,8 @@ public: virtual bool is_marked_for_strip () const = 0; NodeId get_node_id () const { return node_id; } + virtual bool is_item () const = 0; + protected: Stmt () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} @@ -847,6 +849,8 @@ public: add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const {} + bool is_item () const override final { return true; } + protected: // Clone function implementation as pure virtual method virtual Item *clone_item_impl () const = 0; diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index b83ca11..a1b4e57 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -46,6 +46,8 @@ public: void mark_for_strip () override { marked_for_strip = true; } bool is_marked_for_strip () const override { return marked_for_strip; } + bool is_item () const override final { return false; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -169,6 +171,8 @@ public: return type; } + bool is_item () const override final { return false; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -186,6 +190,8 @@ class ExprStmt : public Stmt public: Location get_locus () const override final { return locus; } + bool is_item () const override final { return false; } + protected: ExprStmt (Location locus) : locus (locus) {} }; 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/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h index cc61142..29e98fa 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.h +++ b/gcc/rust/hir/tree/rust-hir-stmt.h @@ -41,6 +41,8 @@ public: void accept_vis (HIRVisitor &vis) override; + bool is_item () const override final { return false; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -119,6 +121,8 @@ public: HIR::Pattern *get_pattern () { return variables_pattern.get (); } + bool is_item () const override final { return false; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -136,6 +140,8 @@ class ExprStmt : public Stmt public: Location get_locus () const override final { return locus; } + bool is_item () const override final { return false; } + protected: ExprStmt (Analysis::NodeMapping mappings, Location locus) : Stmt (std::move (mappings)), locus (locus) diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index af18d804..e834553 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -104,6 +104,8 @@ public: const Analysis::NodeMapping &get_mappings () const { return mappings; } + virtual bool is_item () const = 0; + protected: Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {} @@ -140,6 +142,8 @@ public: AST::AttrVec &get_outer_attrs () { return outer_attrs; } const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } + bool is_item () const override final { return true; } + protected: // Constructor Item (Analysis::NodeMapping mappings, 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 af04aeb..921b77c 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, + }; +} |