dotnet/roslyn

`IDE0063` fix introduces `CS8648` in presence of `goto` statements

Open

#39,637 建立於 2019年11月1日

在 GitHub 查看
 (3 留言) (0 反應) (0 負責人)C# (20,414 star) (4,257 fork)batch import
Area-CompilersBugFeature - IDE0063IDE-CodeStylehelp wanted

描述

Version Used: I think 3.4.0-beta2-19504-06 as C# Interactive shows that version.

VS is 16.4.0 Preview 2.0.

<TargetFramework> is netcoreapp3.1 so I believe I am using <LangVersion>Preview</LangVersion> implicitly.

Steps to Reproduce:

The code below will show the fix suggestion /*IDE0063*/ and the code after applying the IDE0063 fix at the location shown with error /*CS8648*/.

  • IDE0063 Use simple 'using' statement
  • CS8648 A goto cannot jump to a location after a using declaration

The crux appears to be that there are two statements blocks nested, with the nested one bing a using statement. The first isn't showing IDE0063 whereas the second does offer the fix, which breaks the code when applied.

Expected Behavior: The fix suggestion does not appear.

Or in fact, even if there is code between the two } such that the finally blocks are apart, applying the fix would in fact have to put the finalizer for the simple using statement at the end of the block it is in, which is the finalizer position of the first using statement in the code below. So one could argue whether the code below in both forms should produce the exact same syntax tree end hence both compile without error.

On top of that, my understanding of the feature is that any block in which the simple using statement appears would become protected by the finalizer, even if there is just an if block or even just { ... } without any construct accompanying it. And indeed, if I remove the exact text using (var d = new Disposable()) (but leave the brace-open) in the IDE0063_After code, the goto preceding the brace-open does not show CS8648.

So:

Really Expected Behavior Whether I accept the fix or not, the code compiles and CS8648 does not appear.

Actual Behavior: The fix suggestion, even before it is applied - in the preview, produces error CS8648 "A goto cannot jump to a location after a using declaration".

Code

struct Disposable : IDisposable { public void Dispose() { } }
class IDE0063_Before
{
    static int Main(string[] args) {
        var errorLevel = 0;
        if (args.Length == 0) goto Fail;
        using (var d = new Disposable()) {
            if (int.TryParse(args[0], out errorLevel)) goto Fail;
            /*IDE0063*/
            using (var e = new Disposable()) {
                foreach (var arg in args)
                    if (int.TryParse(arg, out errorLevel)) goto Fail;
            }
        }
        return errorLevel;
    Fail:
        errorLevel = default;
        return errorLevel;
    }
}
class IDE0063_After
{
    static int NotMain(string[] args) {
        var errorLevel = 0;
        if (args.Length == 0) goto Fail;
        using (var d = new Disposable()) {
            if (int.TryParse(args[0], out errorLevel)) /*CS8648*/ goto Fail;
            using var e = new Disposable();
            foreach (var arg in args)
                if (int.TryParse(arg, out errorLevel)) goto Fail;
        }
        return errorLevel;
    Fail:
        errorLevel = default;
        return errorLevel;
    }
}

貢獻者指南

`IDE0063` fix introduces `CS8648` in presence of `goto` statements · dotnet/roslyn#39637 | Good First Issue