Skip to content

[API contract regression] SymbolDisplay.ToDisplayString(IntPtrTypeSymbol, FullnameFormat) returns nint instead of System.IntPtr with .NET 8.0 SDK #76895

@ceztko

Description

@ceztko

Description:

In a simple compilation SymbolDisplay.ToDisplayString(IntPtrTypeSymbol, FullnameFormat), with IntPtrTypeSymbol the type symbol for System.IntPtr and FullnameFormat defined below, returns nint instead of System.IntPtr when compiled depending on .NET 8.0 SDK, despite no SymbolDisplayMiscellaneousOptions.UseSpecialTypes is being used. If the same source is compiled depending on .NET 6.0 SDK the returned value is System.IntPtr, as expected.

FullnameFormat is defined as:

static readonly SymbolDisplayFormat FullnameFormat = new SymbolDisplayFormat(
    globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining,
    typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
    localOptions: SymbolDisplayLocalOptions.IncludeType,
    genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters
    | SymbolDisplayGenericsOptions.IncludeVariance,
    memberOptions:
        SymbolDisplayMemberOptions.IncludeContainingType |
        SymbolDisplayMemberOptions.IncludeExplicitInterface,
    miscellaneousOptions:
        SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName |
        SymbolDisplayMiscellaneousOptions.ExpandNullable
        // NOTE: SymbolDisplayMiscellaneousOptions.UseSpecialTypes is not used!

Version Used:

Microsoft.CodeAnalysis.CSharp 4.12

Steps to Reproduce:

  1. Decompress IntPtrTest.zip and launch the IntPtrTest.sln solution
  2. Run the Net6SystemIntPtr project, it will print net6.0 dependency: IntPtr fullname is System.IntPtr;
  3. Run the Net8nint project, it will print net8.0 dependency: IntPtr fullname is nint.

Expected Behavior:

I understand that using .NET 8.0 SDK nint is now an alias for System.IntPtr (or the other way round). Despite this SymbolDisplayMiscellaneousOptions.UseSpecialTypes is documented in this way:

/// <summary>
/// Uses keywords for predefined types. 
/// For example, "int" instead of "System.Int32" in C#
/// or "Integer" instead of "System.Integer" in Visual Basic.
/// </summary>
UseSpecialTypes = 1 << 0,

Similarly I expect nint to be a special type, and not having used this flag I expect SymbolDisplay.ToDisplayString(IntPtrTypeSymbol, FullnameFormat) to return System.IntPtr.

Actual Behavior:

Depending on the dependent SDK used for the compilation,SymbolDisplay.ToDisplayString returns a different value for the ubiquitous System.IntPtr type, which is burden when maintaining analyzers that will process code that can be dependent on a unpredictable SDK.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.Feature - Native Intapi-approvedAPI was approved in API review, it can be implemented

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions