Skip to content

Commit 2d9f760

Browse files
Fix remove cast in ternary (#79186)
Fixes: #79180 You can continue writing code this way when this fix arrives in VS, Sergio 😎
2 parents 8aa0e2e + f04d418 commit 2d9f760

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14183,4 +14183,104 @@ public void ConvertFieldValueForStorage(object value)
1418314183
ReferenceAssemblies = ReferenceAssemblies.Net.Net80,
1418414184
}.RunAsync();
1418514185
}
14186+
14187+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79180")]
14188+
public async Task ImplicitNumericConversionCastInTernary1()
14189+
{
14190+
await VerifyCS.VerifyAnalyzerAsync("""
14191+
class C
14192+
{
14193+
private const int ConstInt = 1;
14194+
14195+
uint M(bool condition)
14196+
{
14197+
return condition ? (uint)ConstInt : 0;
14198+
}
14199+
}
14200+
""");
14201+
}
14202+
14203+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79180")]
14204+
public async Task ImplicitNumericConversionCastInTernary2()
14205+
{
14206+
await VerifyCS.VerifyCodeFixAsync("""
14207+
class C
14208+
{
14209+
private const int ConstInt = 1;
14210+
14211+
uint M(bool condition)
14212+
{
14213+
return condition ? [|(uint)|]ConstInt : 0u;
14214+
}
14215+
}
14216+
""", """
14217+
class C
14218+
{
14219+
private const int ConstInt = 1;
14220+
14221+
uint M(bool condition)
14222+
{
14223+
return condition ? ConstInt : 0u;
14224+
}
14225+
}
14226+
""");
14227+
}
14228+
14229+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79180")]
14230+
public async Task ImplicitNumericConversionCastInTernary3()
14231+
{
14232+
await VerifyCS.VerifyCodeFixAsync("""
14233+
class C
14234+
{
14235+
private const int ConstInt = 1;
14236+
14237+
uint M(bool condition)
14238+
{
14239+
return condition ? [|(uint)|]ConstInt : [|(uint)|]0;
14240+
}
14241+
}
14242+
""", """
14243+
class C
14244+
{
14245+
private const int ConstInt = 1;
14246+
14247+
uint M(bool condition)
14248+
{
14249+
return condition ? ConstInt : (uint)0;
14250+
}
14251+
}
14252+
""");
14253+
}
14254+
14255+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79180")]
14256+
public async Task ImplicitNumericConversionCastInTernary4()
14257+
{
14258+
await new VerifyCS.Test
14259+
{
14260+
TestCode = """
14261+
class C
14262+
{
14263+
private const int ConstInt = 1;
14264+
14265+
uint M(bool condition)
14266+
{
14267+
return condition ? [|(uint)|]ConstInt : [|(uint)|]0;
14268+
}
14269+
}
14270+
""",
14271+
FixedCode = """
14272+
class C
14273+
{
14274+
private const int ConstInt = 1;
14275+
14276+
uint M(bool condition)
14277+
{
14278+
return condition ? (uint)ConstInt : 0;
14279+
}
14280+
}
14281+
""",
14282+
CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck,
14283+
DiagnosticSelector = d => d[1],
14284+
}.RunAsync();
14285+
}
1418614286
}

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ private static bool IsConversionCastSafeToRemove(
548548
}
549549
}
550550

551-
// We can safely remove convertion to object in interpolated strings regardless of nullability
551+
// We can safely remove conversion to object in interpolated strings regardless of nullability
552552
if (castNode.IsParentKind(SyntaxKind.Interpolation) && originalConversionOperation.Type?.SpecialType is SpecialType.System_Object)
553553
return true;
554554

@@ -922,13 +922,17 @@ bool IsConditionalCastSafeToRemoveDueToConversionToOtherBranch()
922922
if (!otherSideType.Equals(thisSideRewrittenType))
923923
return false;
924924

925-
// Now check that with the (T) cast removed, that the outer `x ? y : z` is still immediately converted to a
926-
// 'T'. If so, we can remove this inner (T) cast.
925+
// Now check that with the (T) cast removed, that the outer `x ? y : z` is still
926+
// immediately implicitly converted to a 'T'. If so, we can remove this inner (T) cast.
927927

928928
var rewrittenConditionalConvertedType = rewrittenSemanticModel.GetTypeInfo(rewrittenConditionalExpression, cancellationToken).ConvertedType;
929929
if (rewrittenConditionalConvertedType is null)
930930
return false;
931931

932+
var outerConversion = rewrittenSemanticModel.GetConversion(rewrittenConditionalExpression, cancellationToken);
933+
if (!outerConversion.IsImplicit)
934+
return false;
935+
932936
return rewrittenConditionalConvertedType.Equals(conversionOperation.Type);
933937
}
934938
}

0 commit comments

Comments
 (0)