Remove support for explicit object generic type constraints#36269
Remove support for explicit object generic type constraints#36269AlekseyTs merged 6 commits intodotnet:masterfrom
object generic type constraints#36269Conversation
| } | ||
| else | ||
| { | ||
| result[mergeWith] = ConstraintsHelper.MergeTopLevelNullabilityForConstraint(result[mergeWith], substituted); |
There was a problem hiding this comment.
MergeTopLevelNullabilityForConstraint [](start = 66, length = 37)
I didn't understand why we need to merge. The map uses the strictest type and annotation comparison, so if map.TryGetValue found an existing substituted type I would think they are identical already. #Closed
| } | ||
| } | ||
|
|
||
| internal static bool IsObjectConstraint(TypeWithAnnotations type, ref TypeWithAnnotations possiblySignificantObjectConstraint) |
There was a problem hiding this comment.
possiblySignificantObjectConstraint [](start = 98, length = 35)
nit: consider naming bestObjectConstraint as in caller. Or maybe mergedObjectConstraint both here and in caller? #Closed
| conversions.HasBoxingConversion(deducedBase, effectiveBase, ref useSiteDiagnostics)); | ||
| } | ||
|
|
||
| internal static TypeWithAnnotations MergeTopLevelNullabilityForConstraint(TypeWithAnnotations type1, TypeWithAnnotations type2) |
There was a problem hiding this comment.
Merge [](start = 44, length = 5)
nit: "Merge" did throw me off a bit because it has many connotations (Merge/Join in flow analysis). Maybe StrictestTopLevelNullabilityConstraint? #Closed
|
|
||
| if (bestObjectConstraint.HasType) | ||
| { | ||
| constraintTypes.Insert(0, bestObjectConstraint); |
There was a problem hiding this comment.
.Insert(0, [](start = 39, length = 11)
nit: why insert at index 0 rather than just append with .Add? #Closed
There was a problem hiding this comment.
why insert at index 0 rather than just append with .Add?
Having significant constraint at the beginning is likely to make following calculations faster - we might get the answer from the first item and stop.
In reply to: 292127065 [](ancestors = 292127065)
| } | ||
|
|
||
| internal static bool? IsNotNullableIfReferenceTypeFromConstraintType(TypeWithAnnotations constraintType) | ||
| internal static bool? IsNotNullableIfReferenceTypeFromConstraintType(TypeWithAnnotations constraintType, out bool isNonNullableValueType) |
There was a problem hiding this comment.
bool? [](start = 24, length = 5)
I don't know if it's worth the effort to refactor, but it feels like we're trying to return a Nullable<NullableAnnotation> (3 possible annotations when applicable + 1 case for not applicable) #Closed
There was a problem hiding this comment.
I don't know if it's worth the effort to refactor, but it feels like we're trying to return a Nullable (3 possible annotations when applicable + 1 case for not applicable)
The returned value is applicable in all cases. It is convenient to return an extra information that we already calculated here and avoid recalculating it again.
In reply to: 292128942 [](ancestors = 292128942)
| { | ||
| continue; | ||
| } | ||
| // Droped 'System.ValueType' constraint type when the 'valuetype' constraint was also specified. |
There was a problem hiding this comment.
Droped [](start = 31, length = 6)
nit: typo "Drop" or "Dropped" #Closed
| [4/25/18](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-04-25.md) | ||
|
|
||
| An explicit `object` (or `System.Object`) constraint is allowed, which requires the type to be non-nullable (value or reference type). | ||
| An explicit `object` (or `System.Object`) constraints of any nullability are disallowed. However, type substitution can lead to |
There was a problem hiding this comment.
An explicit [](start = 0, length = 11)
Consider removing "an" to match "constraints ... are". #Closed
| return true; | ||
| } | ||
|
|
||
| private bool? CalculateIsNotNullableIfReferenceType(ConsList<PETypeParameterSymbol> inProgress, out bool isNonNullableValueType) |
There was a problem hiding this comment.
CalculateIsNotNullableIfReferenceType [](start = 22, length = 37)
nit: consider making this a local function (single use in IsNotNullableIfReferenceType property as far as I can tell) #Closed
There was a problem hiding this comment.
consider making this a local function (single use in IsNotNullableIfReferenceType property as far as I can tell)
I find it clearer to have it as an instance method because it operates on a different instance than its caller.
In reply to: 292138728 [](ancestors = 292138728)
| return true; | ||
| } | ||
|
|
||
| bool? fromNonTypeConstraints = CalculateIsNotNullableFromNonTypeConstraints(); |
There was a problem hiding this comment.
fromNonTypeConstraints [](start = 18, length = 22)
I don't know if it's worth optimizing, but if we have a ! from non-type constraints, we should be able to return without looking at type constraints. #Closed
There was a problem hiding this comment.
I don't know if it's worth optimizing, but if we have a ! from non-type constraints, we should be able to return without looking at type constraints.
We need to calculate isNonNullableValueType, only then we can return
In reply to: 292143869 [](ancestors = 292143869)
| return true; | ||
| } | ||
|
|
||
| if (fromTypes == true || fromNonTypeConstraints == false) |
There was a problem hiding this comment.
if (fromTypes == true || fromNonTypeConstraints == false) [](start = 12, length = 57)
nit: It feels like we're implementing the "strictest top-level nullability from constraints" here again. Might there be a way to factor that out (share with existing implementation)?
Maybe this comes back to whether we're dealing with pairs of bool?, NullableAnnotations or TypeWithAnnotations... Aligning on one (possibly NullableAnnotations) might make things simpler and less custom. #WontFix
| return true; | ||
| } | ||
|
|
||
| if (fromType == true) |
There was a problem hiding this comment.
if (fromType == true) [](start = 16, length = 21)
nit: same comment here (having a method to pick strictest from two bool? or maybe dealing with NullableAnnotation) #WontFix
This comment is not part of the changes. In reply to: 500559705 [](ancestors = 500559705) Refers to: src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs:223 in f960134. [](commit_id = f960134, deletion_comment = False) |
means "if and only if" In reply to: 500563221 [](ancestors = 500563221,500559705) Refers to: src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs:223 in f960134. [](commit_id = f960134, deletion_comment = False) |
Consider changing Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:61215 in f960134. [](commit_id = f960134, deletion_comment = False) |
|
We'll hold onto this PR until we get a greenlight from Stephen (ie. after they adopt the compiler that introduced |
|
Santiago confirmed that all instances of the |
Part of #35816