Skip to content

Suggestion to use pattern matching breaks compilation #21097

@TessenR

Description

@TessenR

Version Used:

Microsoft Visual Studio Professional 2017 
Version 15.2 (26430.14) Release
VisualStudio.15.Release/15.2.0+26430.14
Microsoft .NET Framework
Version 4.7.02053

Steps to Reproduce:

Paste the following code into VS2017:

public class C
{
  public void M(object o)
  {
    var s = o as string;
    if (s != null)
    {

    }
    else
    {
      if (o is int?)
        s = null;
      s.ToString();
    }
  }
}

Expected Behavior:
No suggestion to use pattern matching

Actual Behavior:
Roslyn suggests to change the code into following:

public class C
{
  public void M(object o)
  {
    if (o is string s)
    {

    }
    else
    {
      if (o is int?)
        s = null;
      s.ToString(); // Error CS0165: Use of unassigned local variable 's'
    }
  }
}

which doesn't compile

I think that the problem is the way CSharpAsAndNullCheckDiagnosticAnalyzer checks definite assignment for suggested code

        private void CheckDefiniteAssignment(
            SemanticModel semanticModel, ISymbol localVariable, SyntaxNode node,
            out bool isAssigned, out bool isAccessedBeforeAssignment,
            CancellationToken cancellationToken)
        {
            if (node != null)
            {
                foreach (var id in node.DescendantNodes().OfType<IdentifierNameSyntax>())
                {
                    var symbol = semanticModel.GetSymbolInfo(id, cancellationToken).GetAnySymbol();
                    if (localVariable.Equals(symbol))
                    {
                        isAssigned = id.IsOnlyWrittenTo();
                        isAccessedBeforeAssignment = !isAssigned;
                        return;
                    }
                }
            }
 
            isAssigned = false;
            isAccessedBeforeAssignment = false;
        }

it looks like this method just checks the first reference for an analyzed variable (which is s = null under if in the example above) and doesn't check that it will actually initialize the variable. If I remove the s = null; line the suggestion disappears.

Metadata

Metadata

Assignees

Labels

Area-IDEBugResolution-FixedThe bug has been fixed and/or the requested behavior has been implemented

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions