Skip to content

Give C# the chain terminators it needs - #786

Closed
SimonCropp wants to merge 6 commits into
mainfrom
fix-patcher-cs-chain-terminator
Closed

Give C# the chain terminators it needs#786
SimonCropp wants to merge 6 commits into
mainfrom
fix-patcher-cs-chain-terminator

Conversation

@SimonCropp

Copy link
Copy Markdown
Member

WalkChain appends a Snapshot call at the end of the chain unless the language
names a terminating call to go in front of instead. F# named ToTask and said
why: Snapshot returns the SettingsTask and ToTask does not, so appending after
it appends to the wrong type.

C# named nothing, and has the same shapes. A test that ends its chain by hand -
GetAwaiter().GetResult(), ConfigureAwait(false), AsTask() - got the Snapshot
appended after the terminator, which does not compile. Worse than not patching
at all: the status came back Applied, so the snapshot is recorded as accepted
while the file no longer builds.

ChainTerminator becomes ChainTerminators, since C# has several, and C# names
them. The first one in the chain wins, so GetAwaiter().GetResult() inserts ahead
of GetAwaiter rather than between the two.

WalkChain appends a Snapshot call at the end of the chain unless the language
names a terminating call to go in front of instead. F# named ToTask and said
why: Snapshot returns the SettingsTask and ToTask does not, so appending after
it appends to the wrong type.

C# named nothing, and has the same shapes. A test that ends its chain by hand -
GetAwaiter().GetResult(), ConfigureAwait(false), AsTask() - got the Snapshot
appended after the terminator, which does not compile. Worse than not patching
at all: the status came back Applied, so the snapshot is recorded as accepted
while the file no longer builds.

ChainTerminator becomes ChainTerminators, since C# has several, and C# names
them. The first one in the chain wins, so GetAwaiter().GetResult() inserts ahead
of GetAwaiter rather than between the two.
…terminator

# Conflicts:
#	src/DiffEngine.Tests/InlinePatcherTests.cs
…terminator

# Conflicts:
#	src/DiffEngine.Tests/InlinePatcherTests.cs
…terminator

# Conflicts:
#	src/DiffEngine.Tests/InlinePatcherTests.cs
AsTask is not a member of SettingsTask. I added it from the audit's suggestion
without checking, and checking Verify's source says it never existed - so it was
a name the patcher would only ever match on somebody's own extension method, and
mis-position the insert if it did.

The other three are real, public and [Pure] on SettingsTask, and the reason they
matter is stronger than "the types do not line up". ToTask sets the task field,
and CurrentSettings then throws "This SettingsTask instance has already been
converted to a Task and can no longer be modified". So a Snapshot appended after
a terminator fails at run time wherever it compiles - and where it does not
compile, the patch still reported Applied and the snapshot was recorded as
accepted.

The test swaps its AsTask case for ToTask, which is the one C# shares with F#.
@SimonCropp SimonCropp closed this Aug 22, 2026
@SimonCropp
SimonCropp deleted the fix-patcher-cs-chain-terminator branch August 23, 2026 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant