DeclareVariables.ResolveCollisions() asserts that two variables it has found colliding share a type:
if (point1.nextNode.Parent == point2.nextNode.Parent)
{
Debug.Assert(prev.Type.Equals(v.Type)); // DeclareVariables.cs:504
That does not hold. Two variables can legally carry the same name in disjoint scopes, and their
types are then unrelated. When both declarations are hoisted to the same parent block, the check
above matches and the assert fails. A Debug build aborts; Release silently continues into the
collision-merging code with two differently-typed variables.
Observed
Decompiling the assembly attached to #3282 (err131.zip), in one type's OnRender:
name = brush_2
prev.Type = [UnknownType System.Windows.Media.Brush]
v.Type = [UnknownType SharpDX.Direct2D1.Brush]
Two distinct Brush types from different libraries, sharing a short name. Both come back as
UnknownType here because the referenced assemblies are not present, but nothing about the
failure depends on that: two resolved types with the same short name in disjoint scopes reach the
same check.
Reproducing
ilspycmd -t <type> err131.dll on a Debug build, where err131.dll is the attachment on #3282.
Only one of the 246 top-level types in that assembly triggers it.
I did not find a way to trigger it from hand-written C#: it needs both insertion points to be
hoisted to the same parent block, which I could not force with same-named locals in sibling
scopes. A fixture would be welcome but the attachment reproduces it reliably.
Note on visibility
This is currently unreachable on master, because ArgumentList.CheckNoNamedOrOptionalArguments()
asserts first on the same assembly (that is #3282). Emptying that method's body on master reaches
this assert at the same line, so the defect is pre-existing rather than introduced by the fix for
#3282 — but it does become reachable once that fix lands (#4043).
Filed by an AI agent (Claude Opus 5) working under the account owner's direction.
DeclareVariables.ResolveCollisions()asserts that two variables it has found colliding share a type:That does not hold. Two variables can legally carry the same name in disjoint scopes, and their
types are then unrelated. When both declarations are hoisted to the same parent block, the check
above matches and the assert fails. A Debug build aborts; Release silently continues into the
collision-merging code with two differently-typed variables.
Observed
Decompiling the assembly attached to #3282 (
err131.zip), in one type'sOnRender:Two distinct
Brushtypes from different libraries, sharing a short name. Both come back asUnknownTypehere because the referenced assemblies are not present, but nothing about thefailure depends on that: two resolved types with the same short name in disjoint scopes reach the
same check.
Reproducing
ilspycmd -t <type> err131.dllon a Debug build, whereerr131.dllis the attachment on #3282.Only one of the 246 top-level types in that assembly triggers it.
I did not find a way to trigger it from hand-written C#: it needs both insertion points to be
hoisted to the same parent block, which I could not force with same-named locals in sibling
scopes. A fixture would be welcome but the attachment reproduces it reliably.
Note on visibility
This is currently unreachable on master, because
ArgumentList.CheckNoNamedOrOptionalArguments()asserts first on the same assembly (that is #3282). Emptying that method's body on master reaches
this assert at the same line, so the defect is pre-existing rather than introduced by the fix for
#3282 — but it does become reachable once that fix lands (#4043).
Filed by an AI agent (Claude Opus 5) working under the account owner's direction.