Skip to content

Commit 51417a2

Browse files
committed
Fix NotSupportedException from ReduceConstantSubExpressions
C# 14' "first-class spans" causes `MemoryExtensions.Contains` to be picked over `Enumerable.Contains`. `ConstantSubExpressionReductionVisitor.Visit` calls `DynamicInvoke` which then throws a `NotSupportedException` from [`RuntimeMethodInfo.ThrowNoInvokeException`](https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs,70) For more information see dotnet/runtime#120251
1 parent 1c79692 commit 51417a2

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private static Expression ReduceConstantSubExpressions(Expression expression)
4242
{
4343
return new ConstantSubExpressionReductionVisitor().Visit(expression);
4444
}
45-
catch (InvalidOperationException)
45+
catch (Exception e) when (e is InvalidOperationException or NotSupportedException)
4646
{
4747
// Fallback if we make an invalid rewrite of the expression.
4848
return expression;

Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,29 @@ public void When_condition_contains_linq_extension_method_then_extension_method_
9595
int[] allowed = [1, 2, 3];
9696

9797
// Act
98-
string result = Format<int>(a => allowed.Contains(a));
98+
string result = Format<int>(a => Enumerable.Contains(allowed, a));
9999

100100
// Assert
101101
result.Should().Be("value(System.Int32[]).Contains(a)");
102102
}
103103

104+
#if NET6_0_OR_GREATER
105+
#pragma warning disable RCS1196 // Do not call MemoryExtensions.Contains as extension method. This is to exercise first-class spans
106+
[Fact]
107+
public void Methods_using_ReadOnlySpan_can_be_formatted()
108+
{
109+
// Arrange
110+
int[] allowed = [1, 2, 3];
111+
112+
// Act
113+
string result = Format<int>(a => MemoryExtensions.Contains(allowed, a));
114+
115+
// Assert
116+
result.Should().Match("*.Contains(a)");
117+
}
118+
#pragma warning restore RCS1196
119+
#endif
120+
104121
[Fact]
105122
public void Formatting_a_lifted_binary_operator()
106123
{

0 commit comments

Comments
 (0)