-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not suggest using implicit type for stackalloc initialization #22779
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM Thanks
var initializer = variable.Initializer.Value; | ||
|
||
// Discourage using "var pointer = stackalloc", after introducing C# 7.2, as it might be confusing to users expecting a Span<> | ||
// Check descendant nodes as well, because Span-creating stackallocs can be nested in other nodes (like conditional operators and casts). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that seems odd... what if i had something like Type t = foo(... stackalloc ...);
This would still be a location where converting to 'var' woudl be ok, right? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if the stackalloc is inside a lambda that is on the right hand side? it seems weird that this would disable this feature at this level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such syntax is disabled. Please check #22046 #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't have a stackalloc inside lambda on the RHS? #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can. I'll test that as well.
return false; | ||
} | ||
|
||
if (AssignmentSupportsStylePreference(variable.Identifier, typeName, initializer, semanticModel, optionSet, cancellationToken)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i woudl keep the wrapping as it was before. #Resolved
semanticModel, optionSet, cancellationToken)) | ||
var initializer = variable.Initializer.Value; | ||
|
||
// Discourage using "var pointer = stackalloc", after introducing C# 7.2, as it might be confusing to users expecting a Span<> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❗️ This analyzer isn't the place to do this. The new C# 7.2 features do not affect the use of var
from the perspective of this analyzer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sharwell can you please explain? the IDE should never suggest that particular pattern in that case.
// Discourage using "var pointer = stackalloc", after introducing C# 7.2, as it might be confusing to users expecting a Span<> | ||
// Check descendant nodes as well, because Span-creating stackallocs can be nested in other nodes (like conditional operators and casts). | ||
// https://github.com/dotnet/roslyn/issues/22768 | ||
if (initializer.DescendantNodesAndSelf().Any(node => node.IsKind(SyntaxKind.StackAllocArrayCreationExpression))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Why is this needed? We already have the following block which is intended to catch exactly this case. For example, no special casing is needed for IFormattable f = $"";
.
roslyn/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpUseImplicitTypeDiagnosticAnalyzer.cs
Lines 180 to 184 in 4b1c677
var conversion = semanticModel.GetConversion(expression, cancellationToken); | |
if (conversion.Exists && conversion.IsImplicit && !conversion.IsIdentity) | |
{ | |
return false; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because in cases where compiler can bind the node successfully without errors, it will be replaced with a BoundConvertedStackAllocExpression
. That's what the semantic model will return.
{ | ||
unsafe static void M() | ||
{ | ||
[|int*|] x = stackalloc int [10]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❗️ For the ImplicitTypeEverywhere()
options, this should report a diagnostic. Span<T>
is not a special case, the same way string interpolation with IFormattable
is not a special case.
if (!variableDeclaration.Type.IsKind(SyntaxKind.PointerType) | ||
&& initializer | ||
.DescendantNodesAndSelf(descendIntoChildren: node => !node.IsAnyLambdaOrAnonymousMethod()) | ||
.Any(node => node.IsKind(SyntaxKind.StackAllocArrayCreationExpression))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, i would prefer really long expressions like this get broken out into either a helper method, or into statements. i.e.:
var isPointerType = ...
var containsStackAlloc = ...
if (!isPointerType && containsStackAlloc) { ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just much more readable to me that way (IMO).
@sharwell any other comments? |
@sharwell can you please take a look? |
@OmarTawfik , submitting this for shiproom barcheck...can you fill in the ask mode template . |
@jinujoseph filled the questions in the VSO bug. Please let me know if I should do anything else. |
@OmarTawfik this will need to be rebased so we can target master. |
@sharwell it is not going to be a pretty/straightforward rebase :( |
4fa5c0d
to
e7e9fa4
Compare
@OmarTawfik I went ahead and did the rebase and changed the base branch of this PR to master. This will allow the tests to complete for the correct target so we're ready if approval comes through. If it doesn't get approved, we'll just switch the base branch back to 15.6 - a second rebase would not be required. 👍 |
Pre-approved to merge via link |
Fixes #22768
vso bug : https://devdiv.visualstudio.com/DevDiv/NET%20Developer%20Experience%20Productivity/_workitems/edit/517749
cc @sharwell @jcouv @dotnet/roslyn-ide