Skip to content

Missing expected nullable mismatch warnings around constraints checks #30003

@AlekseyTs

Description

@AlekseyTs
        [Fact]
        public void ConstraintCyclesFromMetadata_02()
        {
            var source0 =
@"using System;
public class A2<T> where T : class, IEquatable<T?> { }
";
            var source =
@"class B
{
    static void Main()
    {
        new A2<string?>(); // 2
        new A2<string>(); // 3
    }
}";
            // No [NullNullTypes]
            var comp0 = CreateCompilation(source0);
            comp0.VerifyDiagnostics(
                // (2,48): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.
                // public class A2<T> where T : class, IEquatable<T?> { }
                Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 48),
                // (2,49): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context.
                // public class A2<T> where T : class, IEquatable<T?> { }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(2, 49)
                );

            MetadataReference ref0 = comp0.ToMetadataReference();
            var comp = CreateCompilation(source, references: new[] { ref0 });
            // PROTOTYPE(NullableReferenceTypes): Should report a nullability mismatch warning for A2<string>().
            comp.VerifyDiagnostics(
                // (5,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context.
                //         new A2<string?>(); // 2
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 22)
                );
            verifyTypeParameterConstraint("A2", "System.IEquatable<T?>");

            // [NullNullTypes(false)]
            comp0 = CreateCompilation(new[] { source0, NonNullTypesFalse, NonNullTypesAttributesDefinition });
            comp0.VerifyDiagnostics(
                // (2,48): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.
                // public class A2<T> where T : class, IEquatable<T?> { }
                Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithLocation(2, 48),
                // (2,49): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context.
                // public class A2<T> where T : class, IEquatable<T?> { }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(2, 49)
                );
            ref0 = comp0.ToMetadataReference();
            comp = CreateCompilation(source, references: new[] { ref0 });
            // PROTOTYPE(NullableReferenceTypes): Should report same warnings as other two cases.
            comp.VerifyDiagnostics(
                // (5,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context.
                //         new A2<string?>(); // 2
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 22)
                );
            verifyTypeParameterConstraint("A2", "System.IEquatable<T?>");

            // [NullNullTypes(true)]
            comp0 = CreateCompilation(new[] { source0, NonNullTypesTrue, NonNullTypesAttributesDefinition });
            ref0 = comp0.EmitToImageReference();
            comp = CreateCompilation(source, references: new[] { ref0 });
            // PROTOTYPE(NullableReferenceTypes): Should report a nullability mismatch warning for A2<string>().
            comp.VerifyDiagnostics(
                // (5,16): warning CS8634: The type 'string?' cannot be used as type parameter 'T' in the generic type or method 'A2<T>'. Nullability of type argument 'string?' doesn't match 'class' constraint.
                //         new A2<string?>(); // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint, "string?").WithArguments("A2<T>", "T", "string?").WithLocation(5, 16),
                // (5,22): warning CS8632: The annotation for nullable reference types should only be used in code within a '[NonNullTypes(true)]' context.
                //         new A2<string?>(); // 2
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(5, 22)
                );
            verifyTypeParameterConstraint("A2", "System.IEquatable<T?>");

            void verifyTypeParameterConstraint(string typeName, string expected)
            {
                var type = comp.GetMember<NamedTypeSymbol>(typeName);
                var constraintType = type.TypeParameters[0].ConstraintTypesNoUseSiteDiagnostics[0];
                Assert.Equal(expected, constraintType.ToTestDisplayString());
            }
        }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions