From 9a17ecce1a6403151d1ee86bda01f18e48b52084 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 19 Jun 2026 10:52:27 +0200 Subject: [PATCH] Give EquatableArray content-based equality and hashing The default struct GetHashCode hashes the array reference, which would break the records that cache these arrays as incremental-generator keys. --- .../DecompilerSyntaxTreeGenerator.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs b/ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs index edba37131..a48937c3a 100644 --- a/ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs +++ b/ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs @@ -800,9 +800,34 @@ readonly struct EquatableArray : IEquatable>, IEnumerable other) { - return other.array.AsSpan().SequenceEqual(this.array); + return this.array.AsSpan().SequenceEqual(other.array.AsSpan()); } + public override bool Equals(object obj) + { + return obj is EquatableArray other && Equals(other); + } + + // Content-based hash so it agrees with the content-based Equals; the default struct + // GetHashCode would hash the array reference and break the records that cache these as + // incremental-generator keys. (System.HashCode is unavailable on netstandard2.0.) + public override int GetHashCode() + { + if (array == null) + return 0; + unchecked + { + int hash = 17; + foreach (T item in array) + hash = hash * 31 + EqualityComparer.Default.GetHashCode(item); + return hash; + } + } + + public static bool operator ==(EquatableArray left, EquatableArray right) => left.Equals(right); + + public static bool operator !=(EquatableArray left, EquatableArray right) => !left.Equals(right); + public IEnumerator GetEnumerator() { return ((IEnumerable)array).GetEnumerator();