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

Recognize 'allows ref struct' constraint in VB compiler #73429

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -837,7 +837,7 @@ private static bool TypeParameterHasConstraints(ITypeParameterSymbol typeParam)
{
return !typeParam.ConstraintTypes.IsEmpty || typeParam.HasConstructorConstraint ||
typeParam.HasReferenceTypeConstraint || typeParam.HasValueTypeConstraint ||
typeParam.HasNotNullConstraint;
typeParam.HasNotNullConstraint || typeParam.AllowsByRefLike;
}

private void AddTypeParameterConstraints(ImmutableArray<ITypeSymbol> typeArguments)
Expand Down Expand Up @@ -917,7 +917,7 @@ private void AddTypeParameterConstraints(ImmutableArray<ITypeSymbol> typeArgumen
needComma = true;
}

//ctor constraint must be last
//ctor constraint must be last before 'allows ref struct'
if (typeParam.HasConstructorConstraint)
{
if (needComma)
Expand All @@ -929,6 +929,22 @@ private void AddTypeParameterConstraints(ImmutableArray<ITypeSymbol> typeArgumen
AddKeyword(SyntaxKind.NewKeyword);
AddPunctuation(SyntaxKind.OpenParenToken);
AddPunctuation(SyntaxKind.CloseParenToken);
needComma = true;
}

if (typeParam.AllowsByRefLike)
{
if (needComma)
{
AddPunctuation(SyntaxKind.CommaToken);
AddSpace();
}

AddKeyword(SyntaxKind.AllowsKeyword);
AddSpace();
AddKeyword(SyntaxKind.RefKeyword);
AddSpace();
AddKeyword(SyntaxKind.StructKeyword);
}
}
}
Expand Down
66 changes: 66 additions & 0 deletions src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4377,6 +4377,7 @@ void verify(ModuleSymbol m)
Assert.False(t.HasNotNullConstraint);
Assert.True(t.AllowsByRefLike);
Assert.True(t.GetPublicSymbol().AllowsByRefLike);
AssertEx.Equal("C<T> where T : allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints));
}

comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext).VerifyDiagnostics();
Expand Down Expand Up @@ -5085,6 +5086,7 @@ public class C<T>
Assert.False(t.HasNotNullConstraint);
Assert.True(t.HasConstructorConstraint);
Assert.True(t.AllowsByRefLike);
AssertEx.Equal("C<T> where T : new(), allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints));
}

[Fact]
Expand All @@ -5108,6 +5110,7 @@ public class C<T>
Assert.False(t.HasNotNullConstraint);
Assert.True(t.HasConstructorConstraint);
Assert.True(t.AllowsByRefLike);
AssertEx.Equal("C<T> where T : new(), allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints));
}

[Fact]
Expand Down Expand Up @@ -5754,6 +5757,7 @@ void verify(ModuleSymbol m)
Assert.False(t.HasNotNullConstraint);
Assert.False(t.AllowsByRefLike);
Assert.False(t.GetPublicSymbol().AllowsByRefLike);
AssertEx.Equal("C<T>", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints));
}
}

Expand Down Expand Up @@ -23918,5 +23922,67 @@ public class Activator
expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123 246" : null,
verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics();
}

[Fact]
public void NoPiaEmbedding()
{
string pia = @"
using System;
using System.Runtime.InteropServices;

[assembly: ImportedFromTypeLib(""GeneralPIA.dll"")]
[assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")]

[ComImport()]
[Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58278"")]
public interface ITest29
{
void M21<T1>() where T1 : allows ref struct;
}
";

var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, assemblyName: "Pia", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics);

string consumer = @"
class UsePia
{
public static void Main()
{
}
}

interface UsePia5 : ITest29
{
}
";

var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseExe,
references: [piaCompilation.ToMetadataReference(embedInteropTypes: true)],
targetFramework: s_targetFrameworkSupportingByRefLikeGenerics);

var compilation2 = CreateCompilation(consumer, options: TestOptions.ReleaseExe,
references: [piaCompilation.EmitToImageReference(embedInteropTypes: true)],
targetFramework: s_targetFrameworkSupportingByRefLikeGenerics);

System.Action<ModuleSymbol> metadataValidator =
delegate (ModuleSymbol module)
{
((PEModuleSymbol)module).Module.PretendThereArentNoPiaLocalTypes();

var itest29 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest29").Single();
Assert.Equal(TypeKind.Interface, itest29.TypeKind);

var m21 = (PEMethodSymbol)itest29.GetMembers("M21").Single();

var t1 = m21.TypeParameters[0];
Assert.Equal("T1", t1.Name);
Assert.True(t1.AllowsByRefLike);
AssertEx.Equal("void ITest29.M21<T1>() where T1 : allows ref struct", m21.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints));
};

CompileAndVerify(compilation1, symbolValidator: metadataValidator, verify: Verification.Skipped).VerifyDiagnostics();

CompileAndVerify(compilation2, symbolValidator: metadataValidator, verify: Verification.Skipped).VerifyDiagnostics();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
' 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.AllowsByRefLike = other.AllowsByRefLike)
Debug.Assert(type.HasReferenceTypeConstraint = other.HasReferenceTypeConstraint)
Debug.Assert(type.ConstraintTypesNoUseSiteDiagnostics.Length = other.ConstraintTypesNoUseSiteDiagnostics.Length)
Return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit.NoPia

Protected Overrides ReadOnly Property AllowByRefLike As Boolean
Get
Return False ' PROTOTYPE(RefStructInterfaces): Implement for real
Return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.AllowsByRefLike
End Get
End Property

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols

Private ReadOnly Property IGenericParameterAllowByRefLike As Boolean Implements IGenericParameter.AllowByRefLike
Get
Return False ' PROTOTYPE(RefStructInterfaces): Implement for real
Return AdaptedTypeParameterSymbol.AllowsByRefLike
End Get
End Property

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return False
End Get
End Property

Public Overrides ReadOnly Property Variance As VarianceKind
Get
Return VarianceKind.None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return False
End Get
End Property

Public Overrides ReadOnly Property HasReferenceTypeConstraint As Boolean
Get
Return False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return False
End Get
End Property

Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return ImmutableArray(Of Location).Empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return (_flags And MetadataHelpers.GenericParameterAttributesAllowByRefLike) <> 0
End Get
End Property

Public Overrides ReadOnly Property Variance As VarianceKind
Get
Return CType((_flags And GenericParameterAttributes.VarianceMask), VarianceKind)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,7 @@ Done:
If (typeParameter1.HasConstructorConstraint <> typeParameter2.HasConstructorConstraint) OrElse
(typeParameter1.HasReferenceTypeConstraint <> typeParameter2.HasReferenceTypeConstraint) OrElse
(typeParameter1.HasValueTypeConstraint <> typeParameter2.HasValueTypeConstraint) OrElse
(typeParameter1.AllowsByRefLike <> typeParameter2.AllowsByRefLike) OrElse
(typeParameter1.Variance <> typeParameter2.Variance) Then
Return False
End If
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return _curriedFromTypeParameter.AllowsByRefLike
End Get
End Property

Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return _curriedFromTypeParameter.Locations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return _underlyingTypeParameter.AllowsByRefLike
End Get
End Property

Public Overrides ReadOnly Property Variance As VarianceKind
Get
Return _underlyingTypeParameter.Variance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return False
End Get
End Property

Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return ImmutableArray(Of TypeSymbol).Empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return False
End Get
End Property

Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
EnsureAllConstraintsAreResolved()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return _originalDefinition.AllowsByRefLike
End Get
End Property

Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean
Get
Return _originalDefinition.IsImplicitlyDeclared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return _correspondingMethodTypeParameter.AllowsByRefLike
End Get
End Property

Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return _correspondingMethodTypeParameter.Locations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols

Public MustOverride ReadOnly Property HasValueTypeConstraint As Boolean Implements ITypeParameterSymbol.HasValueTypeConstraint

Public ReadOnly Property AllowsByRefLike As Boolean Implements ITypeParameterSymbol.AllowsByRefLike
Get
Return False ' PROTOTYPE(RefStructInterfaces): Implement for real
End Get
End Property
Public MustOverride ReadOnly Property AllowsByRefLike As Boolean Implements ITypeParameterSymbol.AllowsByRefLike

Private ReadOnly Property HasUnmanagedTypeConstraint As Boolean Implements ITypeParameterSymbol.HasUnmanagedTypeConstraint
Get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property

Public Overrides ReadOnly Property AllowsByRefLike As Boolean
Get
Return Me._underlyingTypeParameter.AllowsByRefLike
End Get
End Property

Public Overrides ReadOnly Property Variance As VarianceKind
Get
Return Me._underlyingTypeParameter.Variance
Expand Down
Loading