dotnet/roslyn

VB: Strange widening-numeric conversion returned by ClassifyConversion

Open

#6,365 建立於 2015年10月27日

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

描述

Consider the following VB program:

Module Program

    Sub Main()
        Dim b As Byte
        b += 1

        Console.WriteLine(b)
    End Sub

End Module

I tried using the VB compiler API to classify the conversion between the right-side of the compound assignment statement (the numeric literal, 1) and the type of the left-side (System.Byte). My expectation is that this would classify as a narrowing-numeric conversion since 1 has the type, System.Int32. However, I was surprised to get back a widening-numeric conversion. Is this by design, or a bug? If it's by design, why?

Here's a C# interactive session I used to verify the result.

> #r "C:\Projects\Roslyn\Open\Binaries\Debug\Microsoft.CodeAnalysis.dll"
> #r "C:\Projects\Roslyn\Open\Binaries\Debug\Microsoft.CodeAnalysis.VisualBasic.dll"
> using Microsoft.CodeAnalysis;
> using Microsoft.CodeAnalysis.VisualBasic;
> using Microsoft.CodeAnalysis.VisualBasic.Syntax;
> var code = @"
. Module Program
. 
.     Sub Main()
.         Dim b As Byte
.         b += 1
. 
.         Console.WriteLine(b)
.     End Sub
. 
. End Module
. ";
> var tree = SyntaxFactory.ParseSyntaxTree(code);
> var compilation = VisualBasicCompilation.Create("Test")
.     .AddSyntaxTrees(tree)
.     .AddReferences(MetadataReference.CreateFromFile(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"));
> var semanticModel = compilation.GetSemanticModel(tree);
> var statements = tree.GetRoot().DescendantNodes().OfType<ExecutableStatementSyntax>().ToArray();
> var assignment = statements[1] as AssignmentStatementSyntax;
> assignment
AssignmentStatementSyntax(AssignmentStatementSyntax AddAssignmentStatement b += 1)
> var type = semanticModel.GetTypeInfo(assignment.Left).Type;
> type
PENamedTypeSymbolWithEmittedNamespaceName(NamedType System.Byte)
> var conversion = semanticModel.ClassifyConversion(assignment.Right, type);
> conversion
[WideningNumeric, InvolvesNarrowingFromNumericConstant]
> 

Note that the conversion includes the internal InvolvesNarrowingFromNumericConstant flag as well, which seems a bit suspicious.

貢獻者指南