Skip to content

Commit

Permalink
Merge pull request #264 from baszalmstra/fix/issue_262
Browse files Browse the repository at this point in the history
fix: never return type in let initializer
  • Loading branch information
Wodann authored Sep 6, 2020
2 parents d9ebc18 + 63239a6 commit 5b80df4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
22 changes: 18 additions & 4 deletions crates/mun_codegen/src/ir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,10 @@ impl<'db, 'ink, 't> BodyIrGenerator<'db, 'ink, 't> {
Statement::Let {
pat, initializer, ..
} => {
self.gen_let_statement(*pat, *initializer);
// If the let statement never finishes, there is no need to generate more code
if !self.gen_let_statement(*pat, *initializer) {
return None;
}
}
Statement::Expr(expr) => {
// No need to generate code after a statement that has a `never` return type.
Expand Down Expand Up @@ -510,9 +513,19 @@ impl<'db, 'ink, 't> BodyIrGenerator<'db, 'ink, 't> {
temp_builder
}

/// Generate IR for a let statement: `let a:int = 3`
fn gen_let_statement(&mut self, pat: PatId, initializer: Option<ExprId>) {
let initializer = initializer.and_then(|expr| self.gen_expr(expr));
/// Generate IR for a let statement: `let a:int = 3`. Returns `false` if the initializer of the
/// statement never returns; `true` otherwise.
fn gen_let_statement(&mut self, pat: PatId, initializer: Option<ExprId>) -> bool {
let initializer = match initializer {
Some(expr) => match self.gen_expr(expr) {
Some(expr) => Some(expr),
None => {
// If the initializer doesnt return a value it never returns
return false;
}
},
None => None,
};

match &self.body[pat] {
Pat::Bind { name } => {
Expand All @@ -534,6 +547,7 @@ impl<'db, 'ink, 't> BodyIrGenerator<'db, 'ink, 't> {
Pat::Wild => {}
Pat::Missing | Pat::Path(_) => unreachable!(),
}
true
}

/// Generates IR for looking up a certain path expression.
Expand Down
18 changes: 18 additions & 0 deletions crates/mun_codegen/src/snapshots/mun_codegen__test__issue_262.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn foo() -> i32 {\n let bar = {\n let b = 3;\n return b + 3;\n };\n\n // This code will never be executed\n let a = 3 + 4;\n a\n}"
---
; == FILE IR =====================================
; ModuleID = 'main.mun'
source_filename = "main.mun"

define i32 @foo() {
body:
ret i32 6
}


; == GROUP IR ====================================
; ModuleID = 'group_name'
source_filename = "group_name"

17 changes: 17 additions & 0 deletions crates/mun_codegen/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ use inkwell::{context::Context, OptimizationLevel};
use mun_target::spec::Target;
use std::{cell::RefCell, sync::Arc};

#[test]
fn issue_262() {
test_snapshot(
r"
fn foo() -> i32 {
let bar = {
let b = 3;
return b + 3;
};
// This code will never be executed
let a = 3 + 4;
a
}",
)
}

#[test]
fn issue_225() {
test_snapshot(
Expand Down

0 comments on commit 5b80df4

Please sign in to comment.