Skip to content

Add initial support for 'notnull' generic type constraint.#36109

Merged
AlekseyTs merged 7 commits intodotnet:masterfrom
AlekseyTs:NotNull_01
Jun 4, 2019
Merged

Add initial support for 'notnull' generic type constraint.#36109
AlekseyTs merged 7 commits intodotnet:masterfrom
AlekseyTs:NotNull_01

Conversation

@AlekseyTs
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs requested review from a team as code owners June 1, 2019 00:14
@AlekseyTs
Copy link
Copy Markdown
Contributor Author

@dotnet/roslyn-compiler Please review.

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

@dotnet/roslyn-compiler, @cston, @jcouv Please review.

NullableAttribute(1) should be placed on a type parameter definition that has a `class!` constraint.
NullableAttribute(2) should be placed on a type parameter definition that has a `class?` constraint.
NullableAttribute(2) should be placed on a type parameter definition that has no type constraints, `class`, `struct` and `unmanaged` constraints and
NullableAttribute(2) should be placed on a type parameter definition that has no type constraints, `notnull`, `class`, `struct` and `unmanaged` constraints and
Copy link
Copy Markdown
Member

@jcouv jcouv Jun 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constraints [](start = 86, length = 11)

nit: I had trouble parsing this sentence, so was confused. Consider removing the word "constraints" here ("... that has no type, notnull, class ... constraints"). Also typo on next line (equivalent). #Resolved

internal override bool? IsNotNullableIfReferenceType
{
get
{
Copy link
Copy Markdown
Member

@jcouv jcouv Jun 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{ [](start = 12, length = 1)

Could we do if (HasNotnullConstraint) { return true; }? #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do if (HasNotnullConstraint) { return true; }?

We could (as in other implementations of IsNotNullableIfReferenceType), but I decided against duplicating the logic around that and keep it in CalculateIsNotNullableIfReferenceType.


In reply to: 289953856 [](ancestors = 289953856)

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Jun 3, 2019

            // (8,59): error CS0449: The 'class' or 'struct' constraint must come before any other constraints

Consider consolidating the error messages CS8713 and CS0449 together. "The class, struct, notnull constraints must come before ..." #Resolved


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:61204 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

            // (8,59): error CS0449: The 'class' or 'struct' constraint must come before any other constraints

We already have a specialized error for unmanaged. I'll open an issue to suggest to consolidate them all.


In reply to: 498373294 [](ancestors = 498373294)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:61204 in e463d06. [](commit_id = e463d06, deletion_comment = False)


public bool IsUnmanaged => ((InternalSyntax.TypeSyntax)this.Green).IsUnmanaged;

public bool IsNotnull => ((InternalSyntax.TypeSyntax)this.Green).IsNotnull;
Copy link
Copy Markdown
Contributor

@cston cston Jun 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsNotnull [](start = 20, length = 9)

Should this be "IsNotNull" (uppercase "N")? It looks like other members of the public API use uppercase for compound keywords ("IsReadOnly", "NameOf", "OrderBy", etc.). #Resolved

/// </summary>
internal abstract bool? ReferenceTypeConstraintIsNullable { get; }

public abstract bool HasNotnullConstraint { get; }
Copy link
Copy Markdown
Contributor

@cston cston Jun 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notnull [](start = 32, length = 7)

Consider using "NotNull" (uppercase "N") throughout. #Resolved

}

// "Constraint cannot be special class '{0}'"
Error(diagnostics, ErrorCode.WRN_SpecialTypeAsBound, syntax, typeWithAnnotations);
Copy link
Copy Markdown
Contributor

@cston cston Jun 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WRN_SpecialTypeAsBound [](start = 49, length = 22)

Should an object constraint be reported as an error rather than a warning, as in C#7? #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to keep this as for the moment, and disallow it later to allow corefx to migrate.


In reply to: 289997980 [](ancestors = 289997980)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should an object constraint be reported as an error rather than a warning, as in C#7?

If I remember correctly, removal of support for object constraint is in the second phase. The reason is to avoid breaking CoreFx right from the first compiler upgrade.


In reply to: 290001495 [](ancestors = 290001495,289997980)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

            //     public void F1<TF1A>() where TF1A : object

Comments are stale. #Resolved


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:62001 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

            // partial void M1<TF1>() where TF1 : object

notnull #Resolved


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:65653 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@jcouv jcouv added this to the 16.2.P3 milestone Jun 3, 2019
@jcouv jcouv self-assigned this Jun 3, 2019
Copy link
Copy Markdown
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 3)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

    }

Consider testing the current constraints with M<notnull?>(), and also testing where T : notnull?. #Resolved


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:66945 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

    }

Consider testing: M<notnull>() where notnull : notnull


In reply to: 498396946 [](ancestors = 498396946)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:66945 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

    }

Are we testing cases where the notnull constraint is on a declaration from metadata? #Resolved


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

    }

Are we testing cases where the notnull constraint is on a declaration from metadata?

To the same degree as we tested that for object constraint. For example, Constraints_46, Constraints_47, Constraints_59, etc.


In reply to: 498404345 [](ancestors = 498404345)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

    }

Do any of those test the check in ConstraintsHelper?


In reply to: 498410871 [](ancestors = 498410871,498404345)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

    }

Do any of those test the check in ConstraintsHelper?

I do not think so, they test APIs that those changes use.


In reply to: 498413865 [](ancestors = 498413865,498410871,498404345)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor

cston commented Jun 3, 2019

    }

In short, what is the error reported for the following? Does it refer to notnull?
a.cs:

public interface I<T> where T : notnull { }

b.cs:

class Program
{
    static void M<T>()
    {
        I<T> i;
    }
}

In reply to: 498414534 [](ancestors = 498414534,498413865,498410871,498404345)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

    }

In short, what is the error reported for the following? Does it refer to notnull?

Yes, there is an example several lines above:

                // (8,18): warning CS8714: The type 'TIB' cannot be used as type parameter 'TA' in the generic type or method 'IA<TA>'. Nullability of type argument 'TIB' doesn't match 'notnull' constraint.
                // public interface IB<TIB> : IA<TIB> // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotnullConstraint, "IB").WithArguments("IA<TA>", "TA", "TIB").WithLocation(8, 18),

In reply to: 498417252 [](ancestors = 498417252,498414534,498413865,498410871,498404345)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:68742 in e463d06. [](commit_id = e463d06, deletion_comment = False)

@AlekseyTs
Copy link
Copy Markdown
Contributor Author

@jcouv, @cston The feedback has been addressed.


namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
public class NotnullKeywordRecommenderTests : RecommenderTests
Copy link
Copy Markdown
Contributor

@cston cston Jun 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notnull [](start = 17, length = 7)

Consider using "NotNull". #Resolved


namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders
{
internal class NotnullKeywordRecommender : IKeywordRecommender<CSharpSyntaxContext>
Copy link
Copy Markdown
Contributor

@cston cston Jun 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notnull [](start = 19, length = 7)

Consider using "NotNull". #Resolved

Copy link
Copy Markdown
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 6)

@AlekseyTs AlekseyTs merged commit 10e0d22 into dotnet:master Jun 4, 2019
@AlekseyTs
Copy link
Copy Markdown
Contributor Author

            // (8,59): error CS0449: The 'class' or 'struct' constraint must come before any other constraints

Opened #36160


In reply to: 498375369 [](ancestors = 498375369,498373294)


Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:61204 in e463d06. [](commit_id = e463d06, deletion_comment = False)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing nullable warnings for scenarios involving type constraints that a nullable value type can satisfy.

4 participants