The return expression is evaluated before finally executes, but the value is not handed to the caller until afterwards — which means a finally that returns wins, silently.
function f(): int
{
try {
return 1;
} finally {
return 2; // wins. and swallows an exception too.
}
}
f(); // 2
// what finally is for:
try {
$lock->acquire();
return $this->work();
} finally {
$lock->release();
}
A return inside finally discards both the original return value and any exception in flight, which turns a crash into a silently wrong result. Some static analysers flag it and most coding standards forbid it, for good reason. The legitimate use is exactly the second example — releasing something on every path out, including the ones nobody anticipated — and keeping the block to cleanup only is what makes it predictable.