-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid cycles while binding type parameter constraints #49261
Conversation
/// <returns>True if the types are equivalent.</returns> | ||
internal virtual bool Equals(TypeSymbol t2, TypeCompareKind compareKind, IReadOnlyDictionary<TypeParameterSymbol, bool> isValueTypeOverrideOpt = null) | ||
internal virtual bool Equals(TypeSymbol t2, TypeCompareKind compareKind) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching that. It's a nice cleanup.
There was a problem hiding this 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 Please take a look. |
|
||
if (clauses.All(clause => clause.ConstraintTypes.IsEmpty)) | ||
{ | ||
clauses = ImmutableArray<TypeParameterConstraintClause>.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clauses = ImmutableArray.Empty [](start = 16, length = 61)
return ImmutableArray<TypeWithAnnotations>.Empty;
#Resolved
binder = binder.WithAdditionalFlags(BinderFlags.GenericConstraintsClause | BinderFlags.SuppressConstraintChecks); | ||
if (clauses.All(clause => clause.Constraints == TypeParameterConstraintKind.None)) | ||
{ | ||
clauses = ImmutableArray<TypeParameterConstraintClause>.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clauses = ImmutableArray.Empty; [](start = 16, length = 62)
return ImmutableArray<TypeParameterConstraintKind>.Empty;
#Resolved
internal static class TypeParameterConstraintClauseExtensions | ||
{ | ||
internal static bool HasValue(this ImmutableArray<TypeParameterConstraintClause> constraintClauses, bool canIgnoreNullableContext) | ||
internal static SmallDictionary<TypeParameterSymbol, bool> BuildIsReferenceTypeFromConstraintTypesMap(Symbol container, ImmutableArray<TypeParameterSymbol> typeParameters, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FromConstraintTypesMap [](start = 87, length = 22)
Is there a reason this method name contains "FromConstraintTypes" and the previous method name does not? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this method name contains "FromConstraintTypes" and the previous method name does not?
Yes, this method only takes constraint types into account and the previous method does not.
In reply to: 521604502 [](ancestors = 521604502)
{ | ||
get | ||
{ | ||
return _underlyingTypeParameter.IsReferenceTypeFromConstraintTypes || CalculateIsReferenceTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| CalculateIsReferenceTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics) [](start = 83, length = 83)
Is this necessary? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
Yes, due to possible type substitution involved new types can appear in the constraint types
In reply to: 521607603 [](ancestors = 521607603)
{ | ||
get | ||
{ | ||
return _underlyingTypeParameter.IsValueTypeFromConstraintTypes || CalculateIsValueTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| CalculateIsValueTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics) [](start = 79, length = 79)
Is this necessary? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
Yes, due to possible type substitution involved new types can appear in the constraint types
In reply to: 521607714 [](ancestors = 521607714)
{ | ||
get | ||
{ | ||
return _sourceTypeParameter.IsReferenceTypeFromConstraintTypes || CalculateIsReferenceTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| CalculateIsReferenceTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics) [](start = 79, length = 83)
Is this necessary? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
Yes, due to possible type substitution involved new types can appear in the constraint types
In reply to: 521608683 [](ancestors = 521608683)
{ | ||
get | ||
{ | ||
return _sourceTypeParameter.IsValueTypeFromConstraintTypes || CalculateIsValueTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| CalculateIsValueTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics) [](start = 75, length = 79)
Is this necessary? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
Yes, due to possible type substitution involved new types can appear in the constraint types
In reply to: 521608778 [](ancestors = 521608778)
c1886d2
to
a122504
Compare
Hello @AlekseyTs! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto-approval
This change consolidates two different techniques to avoid cycles into one. It is using special restricted mode of binding constraint types (proposed in #48270) but avoids the need to capture "partially" bound constraint types in symbols and the risk to use them when not appropriate. Instead, the information required to calculate IsValueType/IsReferenceType is immediately calculated from "partially" bound constraint types and preserved as special TypeParameterConstraintKind flags.