From f10e695fc508c472c77e968e644f710806f82f54 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 10 Feb 2021 14:38:10 +0000 Subject: 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 --- gcc/rust/backend/rust-compile-expr.h | 14 +++++++++----- gcc/rust/parse/rust-parse-impl.h | 6 ++++-- gcc/rust/typecheck/rust-hir-type-check-expr.h | 6 ++++++ gcc/testsuite/rust.test/compilable/loop3.rs | 14 ++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/rust.test/compilable/loop3.rs (limited to 'gcc') 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 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::parse_return_expr ( } // parse expression to return, if it exists - std::unique_ptr 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 returned_expr + = parse_expr (std::vector (), restrictions); return std::unique_ptr ( 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; + } +} -- cgit v1.1