Skip to content
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

Add public API for ref like type parameters #73335

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8673,7 +8673,7 @@ private void CheckReceiverAndRuntimeSupportForSymbolAccess(SyntaxNode node, Boun
}
}

if (receiverOpt is { Type: TypeParameterSymbol { AllowByRefLike: true } } &&
if (receiverOpt is { Type: TypeParameterSymbol { AllowsByRefLike: true } } &&
isNotImplementableInstanceMember(symbol))
{
Error(diagnostics, ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, node);
Expand Down
8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3570,28 +3570,28 @@ internal static ConstantValue GetIsOperatorConstantResult(
// a restricted type cannot be boxed or unboxed into.
if (targetType.IsRestrictedType() || operandType.IsRestrictedType())
{
if (targetType is TypeParameterSymbol { AllowByRefLike: true })
if (targetType is TypeParameterSymbol { AllowsByRefLike: true })
{
if (!operandType.IsRefLikeType && operandType is not TypeParameterSymbol)
{
return null;
}
}
else if (operandType is not TypeParameterSymbol { AllowByRefLike: true })
else if (operandType is not TypeParameterSymbol { AllowsByRefLike: true })
{
if (targetType.IsRefLikeType)
{
if (operandType is TypeParameterSymbol)
{
Debug.Assert(operandType is TypeParameterSymbol { AllowByRefLike: false });
Debug.Assert(operandType is TypeParameterSymbol { AllowsByRefLike: false });
return ConstantValue.False;
}
}
else if (operandType.IsRefLikeType)
{
if (targetType is TypeParameterSymbol)
{
Debug.Assert(targetType is TypeParameterSymbol { AllowByRefLike: false });
Debug.Assert(targetType is TypeParameterSymbol { AllowsByRefLike: false });
return ConstantValue.False;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,7 @@ private void GetDisposalInfoForEnumerator(SyntaxNode syntax, ref ForEachEnumerat
{
Debug.Assert(!enumeratorType.IsRefLikeType); // Ref like types are supposed to be structs, therefore, sealed.

if (enumeratorType is TypeParameterSymbol { AllowByRefLike: true })
if (enumeratorType is TypeParameterSymbol { AllowsByRefLike: true })
{
Error(diagnostics, ErrorCode.ERR_BadAllowByRefLikeEnumerator, expr.Syntax, enumeratorType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2829,8 +2829,8 @@ public bool HasImplicitTypeParameterConversion(TypeParameterSymbol source, TypeS
return true;
}

if (destination is TypeParameterSymbol { AllowByRefLike: false } &&
!source.AllowByRefLike &&
if (destination is TypeParameterSymbol { AllowsByRefLike: false } &&
!source.AllowsByRefLike &&
source.DependsOn((TypeParameterSymbol)destination))
{
return true;
Expand All @@ -2849,7 +2849,7 @@ private bool HasImplicitReferenceTypeParameterConversion(TypeParameterSymbol sou
return false; // Not a reference conversion.
}

if (source.AllowByRefLike)
if (source.AllowsByRefLike)
{
return false;
}
Expand All @@ -2872,7 +2872,7 @@ private bool HasImplicitReferenceTypeParameterConversion(TypeParameterSymbol sou
}

// * From T to a type parameter U, provided T depends on U.
if (destination is TypeParameterSymbol { AllowByRefLike: false } &&
if (destination is TypeParameterSymbol { AllowsByRefLike: false } &&
source.DependsOn((TypeParameterSymbol)destination))
{
return true;
Expand Down Expand Up @@ -2979,7 +2979,7 @@ private bool IsRefLikeOrAllowsByRefLikeImplementingVarianceCompatibleInterface(T
{
if (typeToCheck is TypeParameterSymbol typeParameter)
{
return typeParameter.AllowByRefLike && HasVarianceCompatibleInterfaceInEffectiveInterfaceSet(typeParameter, targetInterfaceType, ref useSiteInfo);
return typeParameter.AllowsByRefLike && HasVarianceCompatibleInterfaceInEffectiveInterfaceSet(typeParameter, targetInterfaceType, ref useSiteInfo);
}
else if (typeToCheck.IsRefLikeType)
{
Expand Down Expand Up @@ -3202,7 +3202,7 @@ private bool HasImplicitBoxingTypeParameterConversion(TypeParameterSymbol source
return false; // Not a boxing conversion; both source and destination are references.
}

if (source.AllowByRefLike)
if (source.AllowsByRefLike)
{
return false;
}
Expand All @@ -3225,7 +3225,7 @@ private bool HasImplicitBoxingTypeParameterConversion(TypeParameterSymbol source
}

// SPEC: From T to a type parameter U, provided T depends on U
if (destination is TypeParameterSymbol { AllowByRefLike: false } d &&
if (destination is TypeParameterSymbol { AllowsByRefLike: false } d &&
source.DependsOn(d))
{
return true;
Expand Down Expand Up @@ -3480,7 +3480,7 @@ private bool HasExplicitReferenceTypeParameterConversion(TypeSymbol source, Type
TypeParameterSymbol s = source as TypeParameterSymbol;
TypeParameterSymbol t = destination as TypeParameterSymbol;

if (s?.AllowByRefLike == true || t?.AllowByRefLike == true)
if (s?.AllowsByRefLike == true || t?.AllowsByRefLike == true)
{
return false;
}
Expand Down Expand Up @@ -3532,7 +3532,7 @@ private bool HasUnboxingTypeParameterConversion(TypeSymbol source, TypeSymbol de
TypeParameterSymbol s = source as TypeParameterSymbol;
TypeParameterSymbol t = destination as TypeParameterSymbol;

if (s?.AllowByRefLike == true || t?.AllowByRefLike == true)
if (s?.AllowsByRefLike == true || t?.AllowsByRefLike == true)
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,8 @@ private void GetAllBuiltInOperators(BinaryOperatorKind kind, bool isChecked, Bou
GetReferenceEquality(kind, operators);
Debug.Assert(operators.Count == 1);

if ((left.Type is TypeParameterSymbol { AllowByRefLike: true } && right.IsLiteralNull()) ||
(right.Type is TypeParameterSymbol { AllowByRefLike: true } && left.IsLiteralNull()))
if ((left.Type is TypeParameterSymbol { AllowsByRefLike: true } && right.IsLiteralNull()) ||
(right.Type is TypeParameterSymbol { AllowsByRefLike: true } && left.IsLiteralNull()))
{
BinaryOperatorSignature op = operators[0];
Debug.Assert(op.LeftType.IsObjectType());
Expand Down Expand Up @@ -776,7 +776,7 @@ static bool isUtf8ByteRepresentation(BoundExpression value)

Conversion getOperandConversionForAllowByRefLikeNullCheck(bool isChecked, BoundExpression operand, TypeSymbol objectType, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
return (operand.Type is TypeParameterSymbol { AllowByRefLike: true }) ? Conversion.Boxing : Conversions.ClassifyConversionFromExpression(operand, objectType, isChecked: isChecked, ref useSiteInfo);
return (operand.Type is TypeParameterSymbol { AllowsByRefLike: true }) ? Conversion.Boxing : Conversions.ClassifyConversionFromExpression(operand, objectType, isChecked: isChecked, ref useSiteInfo);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ private void EmitBinaryCondOperator(BoundBinaryOperator binOp, bool sense)
{
if (!constant.IsFloating)
{
if (comparand is BoundConversion { Type.SpecialType: SpecialType.System_Object, ConversionKind: ConversionKind.Boxing, Operand.Type: TypeParameterSymbol { AllowByRefLike: true } } &&
if (comparand is BoundConversion { Type.SpecialType: SpecialType.System_Object, ConversionKind: ConversionKind.Boxing, Operand.Type: TypeParameterSymbol { AllowsByRefLike: true } } &&
constant.IsNull)
{
// Boxing is not supported for ref like type parameters, therefore the code that we usually emit 'box; ldnull; ceq/cgt'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ private static bool AreTypeParametersEqual(TypeParameterSymbol type, TypeParamet
// edit. Furthermore, comparing constraint types might lead to a cycle.
Debug.Assert(type.HasConstructorConstraint == other.HasConstructorConstraint);
Debug.Assert(type.HasValueTypeConstraint == other.HasValueTypeConstraint);
Debug.Assert(type.AllowByRefLike == other.AllowByRefLike);
Debug.Assert(type.AllowsByRefLike == other.AllowsByRefLike);
Debug.Assert(type.HasUnmanagedTypeConstraint == other.HasUnmanagedTypeConstraint);
Debug.Assert(type.HasReferenceTypeConstraint == other.HasReferenceTypeConstraint);
Debug.Assert(type.ConstraintTypesNoUseSiteDiagnostics.Length == other.ConstraintTypesNoUseSiteDiagnostics.Length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ bool Cci.IGenericParameter.AllowByRefLike
{
get
{
return AdaptedTypeParameterSymbol.AllowByRefLike;
return AdaptedTypeParameterSymbol.AllowsByRefLike;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected override bool AllowByRefLike
{
get
{
return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.AllowByRefLike;
return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.AllowsByRefLike;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ _ when !variableType.IsManagedTypeNoUseSiteDiagnostics
=> WellKnownMember.Microsoft_CodeAnalysis_Runtime_LocalStoreTracker__LogLocalStoreUnmanaged,
_ when variableType.IsRefLikeType && !hasOverriddenToString(variableType)
=> null, // not possible to invoke ToString on ref struct that doesn't override it
_ when variableType is TypeParameterSymbol { AllowByRefLike: true }
_ when variableType is TypeParameterSymbol { AllowsByRefLike: true }
=> null, // not possible to invoke ToString on ref struct type parameter
_ when variableType.TypeKind is TypeKind.Struct
// we'll emit ToString constrained virtcall to avoid boxing the struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ public BoundExpression Convert(TypeSymbol type, BoundExpression arg, bool allowB
Conversion c = Compilation.Conversions.ClassifyConversionFromExpression(arg, type, isChecked: false, ref useSiteInfo);

if (allowBoxingByRefLikeTypeParametersToObject && !c.Exists &&
arg.Type is TypeParameterSymbol { AllowByRefLike: true } && type.IsObjectType())
arg.Type is TypeParameterSymbol { AllowsByRefLike: true } && type.IsObjectType())
{
c = Conversion.Boxing;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ public override void VisitParameter(IParameterSymbol symbol)

if (symbol.ScopedKind == ScopedKind.ScopedValue &&
symbol.RefKind == RefKind.None &&
!(symbol.IsParams && symbol.Type.IsRefLikeType))
!(symbol.IsParams && symbol.Type is { IsRefLikeType: true } or ITypeParameterSymbol { AllowsByRefLike: true }))
{
AddKeyword(SyntaxKind.ScopedKeyword);
AddSpace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public override bool HasValueTypeConstraint
get { return false; }
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
Expand Down
5 changes: 3 additions & 2 deletions src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ public bool SupportsRuntimeCapability(RuntimeCapability capability)
return this.RuntimeSupportsStaticAbstractMembersInInterfaces;
case RuntimeCapability.InlineArrayTypes:
return this.RuntimeSupportsInlineArrayTypes;
case RuntimeCapability.ByRefLikeGenerics:
return this.RuntimeSupportsByRefLikeGenerics;
}

return false;
Expand Down Expand Up @@ -480,9 +482,8 @@ internal bool RuntimeSupportsInlineArrayTypes
/// <summary>
/// Figure out if the target runtime supports inline array types.
/// </summary>
internal bool RuntimeSupportsByRefLikeGenerics // PROTOTYPE(RefStructInterfaces): Implement public API.
internal bool RuntimeSupportsByRefLikeGenerics
{
// PROTOTYPE(RefStructInterfaces): Implement VB side.
// Keep in sync with VB's AssemblySymbol.RuntimeSupportsByRefLikeGenerics
get
{
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public static TypeParameterBounds ResolveBounds(

diagnosticsBuilder.Free();

if (typeParameter.AllowByRefLike)
if (typeParameter.AllowsByRefLike)
{
if (inherited)
{
Expand Down Expand Up @@ -936,7 +936,7 @@ private static bool CheckBasicConstraints(

if (typeArgument.Type.IsRefLikeTypeOrAllowsByRefLike())
{
if (typeParameter.AllowByRefLike)
if (typeParameter.AllowsByRefLike)
{
if (args.CurrentCompilation.SourceModule != typeParameter.ContainingModule)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public override bool HasValueTypeConstraint
}
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ public static bool HaveSameConstraints(TypeParameterSymbol typeParameter1, TypeM
if ((typeParameter1.HasConstructorConstraint != typeParameter2.HasConstructorConstraint) ||
(typeParameter1.HasReferenceTypeConstraint != typeParameter2.HasReferenceTypeConstraint) ||
(typeParameter1.HasValueTypeConstraint != typeParameter2.HasValueTypeConstraint) ||
(typeParameter1.AllowByRefLike != typeParameter2.AllowByRefLike) ||
(typeParameter1.AllowsByRefLike != typeParameter2.AllowsByRefLike) ||
(typeParameter1.HasUnmanagedTypeConstraint != typeParameter2.HasUnmanagedTypeConstraint) ||
(typeParameter1.Variance != typeParameter2.Variance))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ public override bool HasValueTypeConstraint
}
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ ITypeParameterSymbol ITypeParameterSymbol.ReducedFrom

bool ITypeParameterSymbol.HasReferenceTypeConstraint => _underlying.HasReferenceTypeConstraint;

bool ITypeParameterSymbol.HasValueTypeConstraint => _underlying.HasValueTypeConstraint; // PROTOTYPE(RefStructInterfaces): Add AllowByRefLike to public API.
bool ITypeParameterSymbol.HasValueTypeConstraint => _underlying.HasValueTypeConstraint;

bool ITypeParameterSymbol.AllowsByRefLike => _underlying.AllowsByRefLike;

bool ITypeParameterSymbol.HasUnmanagedTypeConstraint => _underlying.HasUnmanagedTypeConstraint;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ ImmutableArray<SymbolDisplayPart> ITypeSymbol.ToMinimalDisplayParts(SemanticMode

SpecialType ITypeSymbol.SpecialType => UnderlyingTypeSymbol.SpecialType;

bool ITypeSymbol.IsRefLikeType => UnderlyingTypeSymbol.IsRefLikeType; // PROTOTYPE(RefStructInterfaces): adjust?
bool ITypeSymbol.IsRefLikeType => UnderlyingTypeSymbol.IsRefLikeType;

bool ITypeSymbol.IsReadOnly => UnderlyingTypeSymbol.IsReadOnly;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public override bool HasValueTypeConstraint
get { return false; }
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get { return false; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public override bool HasValueTypeConstraint
get { return false; }
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get { return false; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ public override bool HasValueTypeConstraint
}
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
Expand Down Expand Up @@ -646,7 +646,7 @@ public override bool HasValueTypeConstraint
}
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
Expand Down Expand Up @@ -909,12 +909,12 @@ public override bool HasValueTypeConstraint
}
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get
{
var typeParameter = this.OverriddenTypeParameter;
return ((object)typeParameter != null) && typeParameter.AllowByRefLike;
return ((object)typeParameter != null) && typeParameter.AllowsByRefLike;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal SynthesizedReadOnlyListTypeParameterSymbol(SynthesizedReadOnlyListTypeS

public override bool HasValueTypeConstraint => false;

public override bool AllowByRefLike => false; // The list is a class type and cannot store ref structs as elements.
public override bool AllowsByRefLike => false; // The list is a class type and cannot store ref structs as elements.

public override bool IsValueTypeFromConstraintTypes => false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ internal InlineArrayTypeParameterSymbol(SynthesizedInlineArrayTypeSymbol contain

public override bool HasValueTypeConstraint => false;

public override bool AllowByRefLike => false; // Span types do not support ref like type parameters for now
public override bool AllowsByRefLike => false; // Span types do not support ref like type parameters for now

public override bool IsValueTypeFromConstraintTypes => false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public override bool HasValueTypeConstraint
get { return false; }
}

public override bool AllowByRefLike
public override bool AllowsByRefLike
{
get { return false; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData

public abstract bool HasValueTypeConstraint { get; }

public abstract bool AllowByRefLike { get; }
public abstract bool AllowsByRefLike { get; }

public abstract bool IsValueTypeFromConstraintTypes { get; }

Expand Down
Loading