The benefit of parsing it as (let <pat> = <expr>) || expr is that the desired semantics then become a natural consequence of existing precedent:
Thus the language becomes more uniform overall.
Furthermore, it would naturally enable other boolean expressions involving let, such as this often-requested one:
if let Foo(x) = get_foo() && let Bar(y) = get_bar(x) {
...
}
Or even:
let Foo(x) = get_foo() || let Bar(x) = get_bar() || continue;
although that’s a bit ugly.
That said, I think your first proposal is largely equivalent to mine, other than not supporting the other boolean expressions I just mentioned. You would special-case || rather than changing the overall operator precedence, which avoids the .. problem, but you can do the same thing in the parser – it’s just nicer to keep a consistent precedence. Doing it as a late transformation would allow delaying the decision until after name resolution, so in theory you wouldn’t have the problem with constant boolean-typed patterns – you could allow this to work:
const MY_TRUE: bool = true;
let MY_TRUE = expr || continue;
But as I said, that’s not very useful (and it’s quite confusing), so I don’t think there’s much benefit in allowing it.