aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-10 14:38:10 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-10 18:10:57 +0000
commitf10e695fc508c472c77e968e644f710806f82f54 (patch)
tree1628784a0b83981ea01f024e5989832edf447a1a /gcc
parentae273ffac99cb75d832a11a83fd63291bb74cbdc (diff)
downloadgcc-f10e695fc508c472c77e968e644f710806f82f54.zip
gcc-f10e695fc508c472c77e968e644f710806f82f54.tar.gz
gcc-f10e695fc508c472c77e968e644f710806f82f54.tar.bz2
Return expressions can be empty which us unit-type
The parser has the same bug as in #225 for break expressions. This tidies up the type resolver and GENERIC translation to handle the case where there is no return expression as well. Fixes #226
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h14
-rw-r--r--gcc/rust/parse/rust-parse-impl.h6
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h6
-rw-r--r--gcc/testsuite/rust.test/compilable/loop3.rs14
4 files changed, 33 insertions, 7 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 92cb392..0c8d25a 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -84,14 +84,18 @@ public:
void visit (HIR::ReturnExpr &expr)
{
- Bexpression *compiled_expr
- = CompileExpr::Compile (expr.return_expr.get (), ctx);
- rust_assert (compiled_expr != nullptr);
-
auto fncontext = ctx->peek_fn ();
std::vector<Bexpression *> retstmts;
- retstmts.push_back (compiled_expr);
+ if (expr.has_return_expr ())
+ {
+ Bexpression *compiled_expr
+ = CompileExpr::Compile (expr.return_expr.get (), ctx);
+ rust_assert (compiled_expr != nullptr);
+
+ retstmts.push_back (compiled_expr);
+ }
+
auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts,
expr.get_locus ());
ctx->add_statement (s);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 18e6983..fcb3d18 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -7400,8 +7400,10 @@ Parser<ManagedTokenSource>::parse_return_expr (
}
// parse expression to return, if it exists
- std::unique_ptr<AST::Expr> returned_expr = parse_expr ();
- // FIXME: ensure this doesn't ruin the middle of any expressions or anything
+ ParseRestrictions restrictions;
+ restrictions.expr_can_be_null = true;
+ std::unique_ptr<AST::Expr> returned_expr
+ = parse_expr (std::vector<AST::Attribute> (), restrictions);
return std::unique_ptr<AST::ReturnExpr> (
new AST::ReturnExpr (locus, std::move (returned_expr),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 9fe6e4f..c8493f0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -137,6 +137,12 @@ public:
void visit (HIR::ReturnExpr &expr)
{
+ if (!expr.has_return_expr ())
+ {
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
+ return;
+ }
+
auto fn_return_tyty = context->peek_return_type ();
rust_assert (fn_return_tyty != nullptr);
diff --git a/gcc/testsuite/rust.test/compilable/loop3.rs b/gcc/testsuite/rust.test/compilable/loop3.rs
new file mode 100644
index 0000000..76fadfb
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/loop3.rs
@@ -0,0 +1,14 @@
+fn main() {
+ let mut a = 1;
+ let mut b = 1;
+
+ // first number in Fibonacci sequence over 10:
+ loop {
+ if b > 10 {
+ return;
+ }
+ let c = a + b;
+ a = b;
+ b = c;
+ }
+}