-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Dispose extension methods should not even be considered in pattern-based disposal #32767
Copy link
Copy link
Open
Labels
Area-CompilersBugConcept-Diagnostic ClarityThe issues deals with the ease of understanding of errors and warnings.The issues deals with the ease of understanding of errors and warnings.Feature - Async StreamsAsync StreamsAsync StreamsFeature - enhanced usingUsing pattern and declarationUsing pattern and declarationhelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on itThe issue is "up for grabs" - add a comment if you are interested in working on it
Milestone
Description
Currently, we bind x.Dispose() and reject the result if it is an extension. But we should not even consider extensions, to avoid diagnostics about ambiguities.
There is the same issue with binding GetAsyncEnumerator.
[Fact]
public void UsingPatternScopedExtensionMethodTest()
{
var source = @"
ref struct S1
{
}
namespace N1
{
static class C2
{
public static void Dispose(this S1 s1) { }
}
}
namespace N2
{
static class C3
{
public static void Dispose(this S1 s1) { }
}
}
namespace N3
{
static class C4
{
public static int Dispose(this S1 s1) { return 0; }
}
}
namespace N4
{
partial class C5
{
static void M()
{
using (S1 s = new S1()) // error 1
{
}
}
}
}
namespace N4
{
using N1;
partial class C5
{
static void M2()
{
using (S1 s = new S1()) // error 2
{
}
}
}
}
namespace N4
{
using N3;
partial class C5
{
static void M3()
{
using (S1 s = new S1()) // error 3
{
}
}
}
}
namespace N4
{
using N1;
using N3;
partial class C5
{
static void M4()
{
using (S1 s = new S1()) // error 4
{
}
}
}
}
namespace N4
{
using N3;
namespace N5
{
partial class C5
{
static void M5()
{
using (S1 s = new S1()) // error 5
{
}
}
}
namespace N6
{
using N1;
partial class C5
{
static void M6()
{
using (S1 s = new S1()) // error 6
{
}
}
}
}
}
}";
// Extension methods should just be ignored, rather than rejected after-the-fact. So there should be no error about ambiguities
CreateCompilation(source).VerifyDiagnostics(
// (37,20): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 1
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(37, 20),
// (50,20): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 2
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(50, 20),
// (63,20): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 3
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(63, 20),
// (77,20): error CS0121: The call is ambiguous between the following methods or properties: 'N1.C2.Dispose(S1)' and 'N3.C4.Dispose(S1)'
// using (S1 s = new S1()) // error 4
Diagnostic(ErrorCode.ERR_AmbigCall, "S1 s = new S1()").WithArguments("N1.C2.Dispose(S1)", "N3.C4.Dispose(S1)").WithLocation(77, 20),
// (77,20): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 4
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(77, 20),
// (92,24): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 5
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(92, 24),
// (105,28): error CS1674: 'S1': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
// using (S1 s = new S1()) // error 6
Diagnostic(ErrorCode.ERR_NoConvToIDisp, "S1 s = new S1()").WithArguments("S1").WithLocation(105, 28)
);
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Area-CompilersBugConcept-Diagnostic ClarityThe issues deals with the ease of understanding of errors and warnings.The issues deals with the ease of understanding of errors and warnings.Feature - Async StreamsAsync StreamsAsync StreamsFeature - enhanced usingUsing pattern and declarationUsing pattern and declarationhelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on itThe issue is "up for grabs" - add a comment if you are interested in working on it