Skip to content

Commit 985e376

Browse files
Fix 'use var' with spans (#79348)
2 parents c2a8957 + b264377 commit 985e376

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,9 +2097,11 @@ static void M()
20972097
}
20982098
""", new TestParameters(options: ImplicitTypeEverywhere()));
20992099

2100-
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")]
2101-
public Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedConditional()
2102-
=> TestMissingInRegularAndScriptAsync("""
2100+
[Fact]
2101+
[WorkItem("https://github.com/dotnet/roslyn/issues/22768")]
2102+
[WorkItem("https://github.com/dotnet/roslyn/issues/79337")]
2103+
public Task DoSuggestVarOnStackAllocExpressions_SpanType_NestedConditional()
2104+
=> TestInRegularAndScript1Async("""
21032105
using System;
21042106
namespace System
21052107
{
@@ -2115,11 +2117,29 @@ static void M(bool choice)
21152117
[|Span<int>|] x = choice ? stackalloc int [10] : stackalloc int [100];
21162118
}
21172119
}
2120+
""", """
2121+
using System;
2122+
namespace System
2123+
{
2124+
public readonly ref struct Span<T>
2125+
{
2126+
unsafe public Span(void* pointer, int length) { }
2127+
}
2128+
}
2129+
class C
2130+
{
2131+
static void M(bool choice)
2132+
{
2133+
var x = choice ? stackalloc int [10] : stackalloc int [100];
2134+
}
2135+
}
21182136
""", new TestParameters(options: ImplicitTypeEverywhere()));
21192137

2120-
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")]
2121-
public Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedCast()
2122-
=> TestMissingInRegularAndScriptAsync("""
2138+
[Fact]
2139+
[WorkItem("https://github.com/dotnet/roslyn/issues/22768")]
2140+
[WorkItem("https://github.com/dotnet/roslyn/issues/79337")]
2141+
public Task DoSuggestVarOnStackAllocExpressions_SpanType_NestedCast()
2142+
=> TestInRegularAndScript1Async("""
21232143
using System;
21242144
namespace System
21252145
{
@@ -2135,6 +2155,22 @@ static void M()
21352155
[|Span<int>|] x = (Span<int>)stackalloc int [100];
21362156
}
21372157
}
2158+
""", """
2159+
using System;
2160+
namespace System
2161+
{
2162+
public readonly ref struct Span<T>
2163+
{
2164+
unsafe public Span(void* pointer, int length) { }
2165+
}
2166+
}
2167+
class C
2168+
{
2169+
static void M()
2170+
{
2171+
var x = (Span<int>)stackalloc int [100];
2172+
}
2173+
}
21382174
""", new TestParameters(options: ImplicitTypeEverywhere()));
21392175

21402176
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")]

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,18 +122,14 @@ SyntaxKind.ForStatement or
122122
if (variableDeclaration.Variables is not [{ Initializer.Value: var initializer } variable])
123123
return false;
124124

125-
// Do not suggest var replacement for stackalloc span expressions.
126-
// This will change the bound type from a span to a pointer.
127-
if (!variableDeclaration.Type.IsKind(SyntaxKind.PointerType))
125+
// Do not suggest var replacement for stackalloc span expressions. This will change the bound type from a
126+
// span to a pointer. Note: this only applies to `var v = stackalloc ...;` If `stackalloc` is anywhere
127+
// lower (including `var v = (stackalloc ...);`), then this is will be a span, and it will be ok to change
128+
// to use 'var'.
129+
if (!variableDeclaration.Type.IsKind(SyntaxKind.PointerType) &&
130+
initializer is StackAllocArrayCreationExpressionSyntax)
128131
{
129-
var containsStackAlloc = initializer
130-
.DescendantNodesAndSelf(descendIntoChildren: node => node is not AnonymousFunctionExpressionSyntax)
131-
.Any(node => node.IsKind(SyntaxKind.StackAllocArrayCreationExpression));
132-
133-
if (containsStackAlloc)
134-
{
135-
return false;
136-
}
132+
return false;
137133
}
138134

139135
if (AssignmentSupportsStylePreference(

0 commit comments

Comments
 (0)