Skip to content

Unexpected inference for conditional expression #35029

@gafter

Description

@gafter

The following test demonstrates the behavior I would expect for the ?: expression when only one side of the : "has a type". But this isn't how the compiler behaves. It is inferring an oblivious result rather than taking the type from the only operand that has a type and reporting a warning on the conversion. Silently inferring an oblivious result undermines the safety of the nullable feature.

        [Fact]
        public void CheckLambdaInConditional()
        {
            var source =
@"using System;

class C
{
    static Func<T> M<T>(Func<T> f) => f;
    static void G(int i, object? o, string? s)
    {
        if (o == null) return;
        var f = M(() => o) /*T:System.Func<object!>!*/;
        f().ToString();
        var f2 = (i == 0) ? f : (() => s); // 1
        _ = f2 /*T:System.Func<object!>!*/;
        f2().ToString();
        var f3 = (i == 0) ? f : (() => { return s; }); // 2
        _ = f3 /*T:System.Func<object!>!*/;
        f3().ToString();
    }
}
";
            var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
            comp.VerifyTypes();
            comp.VerifyDiagnostics(
                // (12,42): warning CS8603: Possible null reference return.
                //        var f2 = (i == 0) ? f : (() => s); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReturn, "s").WithLocation(12, 42),
                // (14,32): warning CS8603: Possible null reference return.
                //        var f3 = (i == 0) ? f : (() => { return s; }); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReturn, "s").WithLocation(14, 32));
        }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions