From 67ef999992cf4e95b1e1298525dcf46602479262 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 15 Aug 2026 17:37:27 +0200 Subject: [PATCH] Extract implicit-span-conversion-related logic in HandleImplicitConversion into separate method. --- .gitattributes | 1 + ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 21 ++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.gitattributes b/.gitattributes index a6227fffc..1d3ed1d12 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,7 @@ *.cs text eol=crlf diff=csharp *.sln text eol=crlf *.csproj text eol=crlf +*.resx text eol=crlf # Consumed verbatim by Linux tools (shell-executed rpm spec, dpkg control, desktop entry); # CRLF breaks them, so keep them LF even in Windows working trees. *.spec text eol=lf diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index 0bfb63143..b56fa2e48 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -353,6 +353,22 @@ namespace ICSharpCode.Decompiler.CSharp && method.Parameters[0].Type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT); } + // Gets whether a call to `method` is equivalent to an implicit span conversion. + static bool IsEquivalentToSpanConversion(IMethod method) + { + if (method.DeclaringType.IsKnownType(KnownTypeCode.SpanOfT) + || method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)) + { + if (method.IsOperator + && method.Name == "op_Implicit") + { + return true; + } + } + return IsStringToReadOnlySpanCharAsSpan(method) + || IsReadOnlySpanCastUp(method); + } + public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method, IReadOnlyList callArguments, IReadOnlyList? argumentToParameterMap = null, @@ -1587,13 +1603,10 @@ namespace ICSharpCode.Decompiler.CSharp // own members, so such a call is the conversion and folding it back is exact. Any // other method reaching this point is a user-defined conversion operator, which only // the user-defined conversion resolving to that very operator may be folded into. - bool spanConversionMember = method.DeclaringType.IsKnownType(KnownTypeCode.SpanOfT) - || method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) - || IsStringToReadOnlySpanCharAsSpan(method); bool directlyConvertible = conv.IsValid && (conv.IsUserDefined ? conv.Method.Equals(method, NormalizeTypeVisitor.TypeErasure) - : conv.IsImplicitSpanConversion && spanConversionMember); + : conv.IsImplicitSpanConversion && IsEquivalentToSpanConversion(method)); if (!directlyConvertible) { // implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type