Skip to content

Type inference should be able to infer U? for T when T? (and inference differs when a discard is used) #50782

@MrJul

Description

@MrJul

Version Used:
VisualStudio.16.Release/16.8.4+30907.101
C# Tools 3.8.0-5.20604.10+9ed4b774d20940880de8df1ca8b07508aa01c8cd

Steps to Reproduce:
<LangVersion>9</LangVersion>

using System.Diagnostics.CodeAnalysis;

#nullable enable

interface IOperation<T> { }
class StringOperation : IOperation<string?> { }

class C {   
    void M() {
        TestA(new StringOperation(), out string? discard1); // 1: no warning
        TestA(new StringOperation(), out string? _);        // 2: CS8620
        TestA(new StringOperation(), out _);                // 3: CS8620
        
        TestB(new StringOperation(), out string? discard2); // 4: CS8620
        TestB(new StringOperation(), out string? _);        // 5: CS8620
        TestB(new StringOperation(), out _);                // 6: CS8620
    }

    void TestA<T>(IOperation<T> operation, [MaybeNull] out T result) => result = default;
    void TestB<T>(IOperation<T> operation, out T? result) => result = default;
}

Expected Behavior:

  • Ideally, no warnings at all, I would expect the compiler to see that T?/[MaybeNull] T can be matched by string? (in effect making it string??) without warnings. Currently T is always inferred to be string instead of string?, resulting in warnings.
  • At the very least, 1 and 2 should have same behavior: the specified types are the same, only the parameter name is missing in 2.

Actual Behavior:
Warnings everywhere but on 1.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions