Collapse dual-constant guard-returns to the bare condition, not c && true#617
Merged
Conversation
… true`
`FoldGuardReturn` rewrites `if (c) return A; return B;` into a short-circuit
boolean when either arm is a bool constant. When BOTH arms are constants it
still ran the generic `tail`-constant formula, appending the `then` literal as
a dead term: `if (a > 0) { if (b > 0) return true; } return false;` folded to
`return a > 0 && b > 0 && true;` (the `BothPositive` fixture), and the dual
`if (c) return false; return true;` to `return !c || false;`.
When the two arms are opposite bool constants the condition itself is the
result — `if (c) return true; return false;` is `return c;` and the dual is
`return !c;` — so special-case that ahead of the generic fold and reuse the
detached condition directly (no extra term, condition still evaluated, so
sound even if it has side effects). Equal-constant arms (dead `if (c) return
true; return true;`) are left to the generic path; they do not arise in
compiled code.
This is an output-fidelity fix: `BothPositive` already diverged from its
fixture's nested-if-to-literal IL (an intentional, idiomatic boolean-fold
over-render, like the IsNullOrEmpty corpus form), and stays on the compile-back
docket as before — but now renders the idiomatic `return a > 0 && b > 0;`
instead of the noisy `&& true`. Compile-back fixture counts unchanged
(exact 157, docket 8, recompile-fail 537; System.Linq unchanged). Decompiler
tests 440 -> 441; main suite 1140 green.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
FoldGuardReturnfoldsif (c) return A; return B;into a short-circuit boolean when either arm is a bool constant. When both arms are constants it still ran the generic formula, appending thethenliteral as a dead term:BothPositive(if (a > 0) { if (b > 0) return true; } return false;) folded toreturn a > 0 && b > 0 && true;if (c) return false; return true;toreturn !c || false;How
When the two arms are opposite bool constants, the condition itself is the result —
if (c) return true; return false;isreturn c;, and the dual isreturn !c;. Special-case that ahead of the generic fold and reuse the (already detached) condition directly: no extra&&/||term, and the condition is still evaluated, so the rewrite is sound even when it has side effects.Equal-constant arms (the dead
if (c) return true; return true;) fall through to the generic path; they do not arise in compiled code.Soundness / scope
This is an output-fidelity fix.
BothPositivealready diverges from its fixture's nested-if-to-literal IL — an intentional, idiomatic boolean-fold over-render (the same policy that rendersIsNullOrEmptyasreturn value is null || value.Length == 0;). It stays on the compile-back docket as before, but now renders the idiomaticreturn a > 0 && b > 0;instead of the noisy&& true.Numbers
BothPositivefold test).Found via the #604
--compile-backoracle while reviewing the ternary/branch-sense docket.