-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Report hidden diagnostic for unnecessary !
#25372
Comments
LDM decided not to produce such a warning for un-necessary |
I'm thinking about this again. Updated title accordingly. |
!
!
An analyzer + auto-fix for this (#34714) would be very welcome. |
…ference) This commit suppresses CS8602 for a potentially incorrect expression that needs to be investigated separately. It also includes a suppression for a CS8602 warning that is reported by version 3.3 of the compiler, but fixed for more recent releases. This suppression operator will eventually be flagged for removal by dotnet/roslyn#25372.
@jcouv I think we should follow the same pattern as other compiler + analyzer diagnostics. Report a diagnostic with correct severity, but with
@jcouv I am going to try and prototype this if it sounds reasonable to you. |
I ran into a (probably very) uncommon case where a warning would've been helpful - after a while of using Kotlin, I got the languages mixed up a bit and tried using Kotlin's if (obj !is Something) is understood as if (obj! is Something) rather than an error or a warning, so at least a warning would've saved me some confusion at compile time :P |
@chylex You can definitely write an analyzer for that purpose. |
Of course, I'm just pointing out a possible case where silently accepting |
Yup. We're discussing this internally right now :) |
I wrote up a very specific fix for the |
I took a stab at the approach I mentioned in #25372 (comment). I was able to update the Nullability walker to track and report suppressed diagnostics in presence of #nullable enable
class C<T> { }
class C
{
static void F(C<object>? x, C<object?> y, bool c)
{
var b = x!; // Removing the ! here causes a CS8600 on 'c ? b : y!'
C<object> a = c ? b : y!;
}
} So the above code snippet reports no suppressed nullable diagnostics from Basically, it seems the only way to detect a redundant |
@mavasani To make things worse, I bet it's possible to be in a situation where removing two unnecessary I'm less sure about this because I can't think of an example yet. |
One possible approach would be to support Tagging @333fred as I believe he did the work of hooking up nullable analysis for speculative semantic model. |
I found an example where removing exactly one For the try-and-see black box approach to detect this, it would have to speculatively bind up to 2^(operator count) times, comparing every combination of removals to the baseline till it finds something. class C
{
void M(string? p)
{
var x = new[] { p! };
var y = new[] { p! };
y = x;
x = y;
}
} |
There's a very simple example: https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQBMQGoA+BiAdgVwBtCJhC4ACOXU8gWACgABAZgqYCYKBhCgb0YUh7NkwAsFALIAKAJT9BwpUwCMABgD8FKBQC8FAsQCEAbkVKhUAHQAVAPYBlGAgCWuAOZyzDJQF9GvkA== I'll have to think about the speculative semantic model diagnostics. |
I'm worried by this because we know that speculative analysis isn't super precise. There are a number of places in the compiler with the speculative model that we take shortcuts because we know we won't have to provide diagnostics on speculative models. We don't fully rerun nullable analysis, for example: we only run nullable analysis on the node given to speculate, not the entire body. |
Self-assigning due to interest in the issue, but anyone else wishing to do design/implementation work should feel free |
I tried this in an analyzer, but the TypeInfo is the same for nullable and non-nullable types. What do I do wrong? public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.RegisterSyntaxNodeAction(AnalyzeNullForgivenessOperator, SyntaxKind.SuppressNullableWarningExpression);
}
private void AnalyzeNullForgivenessOperator(SyntaxNodeAnalysisContext context)
{
var node = (PostfixUnaryExpressionSyntax)context.Node;
TypeInfo typeInfo = context.SemanticModel.GetTypeInfo(node.Operand, context.CancellationToken);
if (typeInfo.Nullability.FlowState != NullableFlowState.MaybeNull)
{
var diagnostic = Diagnostic.Create(Rule, node.GetLocation());
context.ReportDiagnostic(diagnostic);
}
} The |
I don't think that #68267 is duplicate @Youssef1313 This only diagnostic the ! and the other looks for ! , !. and ?. |
Consider reporting a warning for unnecessary
!
.The text was updated successfully, but these errors were encountered: