diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-10 14:38:10 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-10 18:10:57 +0000 |
commit | f10e695fc508c472c77e968e644f710806f82f54 (patch) | |
tree | 1628784a0b83981ea01f024e5989832edf447a1a /gcc | |
parent | ae273ffac99cb75d832a11a83fd63291bb74cbdc (diff) | |
download | gcc-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.h | 14 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/loop3.rs | 14 |
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; + } +} |