Skip to content

Commit 2357d00

Browse files
committed
Support allows ref struct constraint
1 parent 4c08359 commit 2357d00

File tree

12 files changed

+29
-4
lines changed

12 files changed

+29
-4
lines changed

ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOp
792792
configureDecompiler?.Invoke(settings);
793793
var decompiled = await Tester.DecompileCSharp(exeFile, settings).ConfigureAwait(false);
794794

795-
// 3. Compile
795+
// 3. Compare
796796
CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).Append("EXPECTED_OUTPUT").ToArray());
797797
Tester.RepeatOnIOError(() => File.Delete(decompiled));
798798
}

ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ public unsafe static int UnmanagedConstraint<T>() where T : unmanaged
293293
}
294294
#endif
295295

296+
#if NET90
297+
public static void AllowsRefStruct<T>() where T : allows ref struct
298+
{
299+
}
300+
#endif
301+
296302
public static void Issue1959(int a, int b, int? c)
297303
{
298304
// This line requires parentheses around `a < b` to avoid a grammar ambiguity.

ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2465,7 +2465,7 @@ internal TypeParameterDeclaration ConvertTypeParameter(ITypeParameter tp)
24652465

24662466
internal Constraint ConvertTypeParameterConstraint(ITypeParameter tp)
24672467
{
2468-
if (!tp.HasDefaultConstructorConstraint && !tp.HasReferenceTypeConstraint && !tp.HasValueTypeConstraint && tp.NullabilityConstraint != Nullability.NotNullable && tp.DirectBaseTypes.All(IsObjectOrValueType))
2468+
if (!tp.HasDefaultConstructorConstraint && !tp.HasReferenceTypeConstraint && !tp.HasValueTypeConstraint && !tp.AllowsRefLikeType && tp.NullabilityConstraint != Nullability.NotNullable && tp.DirectBaseTypes.All(IsObjectOrValueType))
24692469
{
24702470
return null;
24712471
}
@@ -2518,6 +2518,10 @@ internal Constraint ConvertTypeParameterConstraint(ITypeParameter tp)
25182518
{
25192519
c.BaseTypes.Add(new PrimitiveType("new"));
25202520
}
2521+
if (tp.AllowsRefLikeType)
2522+
{
2523+
c.BaseTypes.Add(new PrimitiveType("allows ref struct"));
2524+
}
25212525
return c;
25222526
}
25232527

ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
using ICSharpCode.Decompiler.DebugInfo;
2929
using ICSharpCode.Decompiler.IL;
3030
using ICSharpCode.Decompiler.Metadata;
31+
using ICSharpCode.Decompiler.TypeSystem;
3132

3233
namespace ICSharpCode.Decompiler.Disassembler
3334
{
@@ -1733,8 +1734,7 @@ void WriteTypeParameters(ITextOutput output, MetadataFile module, MetadataGeneri
17331734
{
17341735
output.Write("valuetype ");
17351736
}
1736-
const GenericParameterAttributes allowByRefLike = (GenericParameterAttributes)0x0020;
1737-
if ((gp.Attributes & allowByRefLike) == allowByRefLike)
1737+
if ((gp.Attributes & TypeUtils.AllowByRefLike) == TypeUtils.AllowByRefLike)
17381738
{
17391739
output.Write("byreflike ");
17401740
}

ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public interface ITypeParameter : IType, ISymbol
9797
/// </summary>
9898
bool HasUnmanagedConstraint { get; }
9999

100+
/// <summary>
101+
/// <see langword="true"/> if the <c>allows ref struct</c> constraint is specified for the type parameter.
102+
/// </summary>
103+
bool AllowsRefLikeType { get; }
104+
100105
/// <summary>
101106
/// Nullability of the reference type constraint. (e.g. "where T : class?").
102107
///

ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ IReadOnlyCollection<IType> CalculateEffectiveInterfaceSet()
175175
public abstract bool HasReferenceTypeConstraint { get; }
176176
public abstract bool HasValueTypeConstraint { get; }
177177
public abstract bool HasUnmanagedConstraint { get; }
178+
public abstract bool AllowsRefLikeType { get; }
178179
public abstract Nullability NullabilityConstraint { get; }
179180

180181
public TypeKind Kind {

ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public DefaultTypeParameter(
7171
public override bool HasReferenceTypeConstraint => hasReferenceTypeConstraint;
7272
public override bool HasDefaultConstructorConstraint => hasDefaultConstructorConstraint;
7373
public override bool HasUnmanagedConstraint => false;
74+
public override bool AllowsRefLikeType => false;
7475
public override Nullability NullabilityConstraint => nullabilityConstraint;
7576

7677
public override IReadOnlyList<TypeConstraint> TypeConstraints { get; }

ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ IReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet {
179179
bool ITypeParameter.HasReferenceTypeConstraint => false;
180180
bool ITypeParameter.HasValueTypeConstraint => false;
181181
bool ITypeParameter.HasUnmanagedConstraint => false;
182+
bool ITypeParameter.AllowsRefLikeType => false;
182183
Nullability ITypeParameter.NullabilityConstraint => Nullability.Oblivious;
183184

184185
IReadOnlyList<TypeConstraint> ITypeParameter.TypeConstraints => EmptyList<TypeConstraint>.Instance;

ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public override IEnumerable<IAttribute> GetAttributes()
119119
public override bool HasDefaultConstructorConstraint => (attr & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
120120
public override bool HasReferenceTypeConstraint => (attr & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
121121
public override bool HasValueTypeConstraint => (attr & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
122+
public override bool AllowsRefLikeType => (attr & TypeUtils.AllowByRefLike) != 0;
122123

123124
public override bool HasUnmanagedConstraint {
124125
get {

ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ internal NullabilityAnnotatedTypeParameter(ITypeParameter type, Nullability null
115115
bool ITypeParameter.HasReferenceTypeConstraint => baseType.HasReferenceTypeConstraint;
116116
bool ITypeParameter.HasValueTypeConstraint => baseType.HasValueTypeConstraint;
117117
bool ITypeParameter.HasUnmanagedConstraint => baseType.HasUnmanagedConstraint;
118+
bool ITypeParameter.AllowsRefLikeType => baseType.AllowsRefLikeType;
118119
Nullability ITypeParameter.NullabilityConstraint => baseType.NullabilityConstraint;
119120
IReadOnlyList<TypeConstraint> ITypeParameter.TypeConstraints => baseType.TypeConstraints;
120121
SymbolKind ISymbol.SymbolKind => SymbolKind.TypeParameter;

0 commit comments

Comments
 (0)