-
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
Report diagnostics from TryFindDisposePatternMethod
when binding foreach
loop
#75422
Conversation
971b422
to
e2dac8f
Compare
TryFindDisposePatternMethod
when binding foreach
loop
e2dac8f
to
44c38f4
Compare
44c38f4
to
9bab481
Compare
@@ -4860,9 +4863,52 @@ public sealed class AsyncEnumerator : System.IAsyncDisposable | |||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.MoveNextAsync()").WithLocation(7, 15), | |||
// (7,15): warning CS0612: 'C.AsyncEnumerator.Current' is obsolete | |||
// await foreach (var i in new C()) | |||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.Current").WithLocation(7, 15) | |||
); | |||
// Note: Obsolete on DisposeAsync is not reported since always called through IAsyncDisposable interface |
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.
So the comment was incorrect - we do not go through IAsyncDisposable interface? #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.
Yes, this was changed in PR but this comment in test was missed
} | ||
|
||
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30257")] | ||
public void TestWithPatternAndObsolete_WithoutDisposableInterface() |
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.
Consider testing with explicit interface implementation of the DisposeAsync method. #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.
Did you add this test? I couldn't find it.
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.
My mistake. Added now :-)
@@ -0,0 +1,46 @@ | |||
# This document lists known breaking changes in Roslyn after .NET 9 all the way to .NET 10. | |||
|
|||
## Diagnostics now reported for improper use of pattern-based disposal method in `foreach` |
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.
if (patternDisposeMethod is object) | ||
{ | ||
Debug.Assert(!patternDisposeMethod.IsExtensionMethod); | ||
Debug.Assert(patternDisposeMethod.ParameterRefKinds.IsDefaultOrEmpty || | ||
patternDisposeMethod.ParameterRefKinds.All(static refKind => refKind is RefKind.None or RefKind.In or RefKind.RefReadOnlyParameter)); | ||
|
||
diagnostics.AddRangeAndFree(patternDiagnostics); |
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.
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.MoveNextAsync()").WithLocation(7, 15), | ||
// (7,15): warning CS0612: 'C.AsyncEnumerator.Current' is obsolete | ||
// await foreach (var i in new C()) | ||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.Current").WithLocation(7, 15)); |
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.
@@ -8503,8 +8552,7 @@ public static class Extensions | |||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.Enumerator.MoveNextAsync()").WithLocation(8, 15), | |||
// (8,15): warning CS0612: 'C.Enumerator.Current' is obsolete | |||
// await foreach (var i in new C()) | |||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.Enumerator.Current").WithLocation(8, 15) | |||
); | |||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.Enumerator.Current").WithLocation(8, 15)); |
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.
// [UnmanagedCallersOnly] | ||
Diagnostic(ErrorCode.ERR_UnmanagedCallersOnlyRequiresStatic, "UnmanagedCallersOnly").WithLocation(14, 6) | ||
); | ||
Diagnostic(ErrorCode.ERR_UnmanagedCallersOnlyRequiresStatic, "UnmanagedCallersOnly").WithLocation(14, 6)); |
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.
// 0.cs(7,9): error CS8901: 'SEnumerator.Dispose()' is attributed with 'UnmanagedCallersOnly' and cannot be called directly. Obtain a function pointer to this method. | ||
// foreach (var i in s) {} | ||
Diagnostic(ErrorCode.ERR_UnmanagedCallersOnlyMethodsCannotBeCalledDirectly, "foreach (var i in s) {}").WithArguments("SEnumerator.Dispose()").WithLocation(7, 9), | ||
// 0.cs(14,6): error CS8896: 'UnmanagedCallersOnly' can only be applied to ordinary static non-abstract, non-virtual methods or static local functions. |
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.
{ | ||
public static void M2(S s) | ||
{ | ||
int[] a = [42, ..s]; |
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.
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 didn't follow. How could that involve binding the Dispose
method?
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 didn't follow. How could that involve binding the
Dispose
method?
It looks like TryFindDisposePatternMethod
might be reachable from TryGetCollectionIterationType
.
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.
Added a test. The behavior seems fine (because TryGetCollectionIterationType
discards diagnostics)
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.MoveNextAsync()").WithLocation(7, 15), | ||
// (7,15): warning CS0612: 'C.AsyncEnumerator.Current' is obsolete | ||
// await foreach (var i in new C()) | ||
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "foreach").WithArguments("C.AsyncEnumerator.Current").WithLocation(7, 15)); |
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.
Done with review pass (commit 4) |
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 (commit 8)
Fixes #30257
Fixes #73934