Skip to content

Commit

Permalink
Merge pull request #1008 from WalterSmuts/exhaustive-branch-returns
Browse files Browse the repository at this point in the history
Exhaustive branch returns
  • Loading branch information
kyouko-taiga authored Sep 15, 2023
2 parents d04d402 + b076201 commit 4304044
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
17 changes: 17 additions & 0 deletions Sources/IR/Analysis/Module+NormalizeObjectStates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,16 @@ extension Module {
if o.value == .full(.initialized) { return }

if k == .set {
// If the parameter is a return value (index == 0) we emit specialized diagnostics.
if case .parameter(_, 0) = p {
let t = self[f].output
if !t.isVoidOrNever {
diagnostics.insert(
.missingFunctionReturn(expectedReturnType: t, at: site)
)
return
}
}
diagnostics.insert(
.uninitializedSetParameter(beforeReturningFrom: f, in: self, at: site))
return
Expand Down Expand Up @@ -991,4 +1001,11 @@ extension Diagnostic {
.error("use of uninitialized object", at: site)
}

fileprivate static func missingFunctionReturn(
expectedReturnType: AnyType,
at site: SourceRange
) -> Diagnostic {
.error("missing return in function expected to return '\(expectedReturnType)'", at: site)
}

}
10 changes: 1 addition & 9 deletions Sources/IR/Emitter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,7 @@ struct Emitter {
) -> SourceRange {
switch emit(braceStmt: b) {
case .next:
if !canonical(returnType).isVoidOrNever {
report(.error(missingReturn: returnType, at: .empty(atEndOf: ast[b].site)))
} else {
if canonical(returnType).isVoidOrNever {
emitStore(value: .void, to: returnValue!, at: .empty(atEndOf: ast[b].site))
}
return ast[b].site
Expand Down Expand Up @@ -2609,12 +2607,6 @@ extension Diagnostic {
.error("integer literal '\(s)' overflows when stored into '\(t)'", at: site)
}

fileprivate static func error(
missingReturn returnType: AnyType, at site: SourceRange
) -> Diagnostic {
.error("missing return in function expected to return '\(returnType)'", at: site)
}

fileprivate static func warning(unreachableStatement s: AnyStmtID, in ast: AST) -> Diagnostic {
.error("statement will never be executed", at: .empty(at: ast[s].site.first()))
}
Expand Down
9 changes: 9 additions & 0 deletions Tests/EndToEndTests/TestCases/ExhaustiveBranchReturns.hylo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//- compileAndRun expecting: success

public fun main() {
let _ = f()
}

public fun f() -> Int {
if true { return 0 } else { return 1 }
}

0 comments on commit 4304044

Please sign in to comment.