Skip to content
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 @@ -1636,13 +1636,19 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
var arg = new TypedConstant(compilation.GetWellKnownType(WellKnownType.System_Type),
TypedConstantKind.Type, stateMachineType.GetUnboundGenericTypeOrSelf());

if (isAsync)
if (isAsync && isIterator)
{
AddSynthesizedAttribute(ref attributes,
compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor,
ImmutableArray.Create(arg)));
}
else if (isAsync)
{
AddSynthesizedAttribute(ref attributes,
compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor,
ImmutableArray.Create(arg)));
}
if (isIterator)
else if (isIterator)
{
AddSynthesizedAttribute(ref attributes,
compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,35 @@ public static async System.Collections.Generic.IAsyncEnumerable<int> M()
CompileAndVerify(comp, symbolValidator: module =>
{
var method = module.GlobalNamespace.GetMember<MethodSymbol>("C.M");
AssertEx.SetEqual(new[] { "AsyncStateMachineAttribute", "IteratorStateMachineAttribute" },
AssertEx.SetEqual(new[] { "AsyncIteratorStateMachineAttribute" },
GetAttributeNames(method.GetAttributes()));

var attribute = method.GetAttributes().Single();
var argument = attribute.ConstructorArguments.Single();
Assert.Equal("System.Type", argument.Type.ToTestDisplayString());
Assert.Equal("C.<M>d__0", ((ITypeSymbol)argument.Value).ToTestDisplayString());
});
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
public void AttributesSynthesized_Optional()
{
string source = @"
public class C
{
public static async System.Collections.Generic.IAsyncEnumerable<int> M()
{
await System.Threading.Tasks.Task.CompletedTask;
yield return 4;
}
}";
var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugDll);
comp.MakeTypeMissing(WellKnownType.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute);
comp.VerifyDiagnostics();
CompileAndVerify(comp, symbolValidator: module =>
{
var method = module.GlobalNamespace.GetMember<MethodSymbol>("C.M");
Assert.Empty(GetAttributeNames(method.GetAttributes()));
});
}

Expand Down Expand Up @@ -1091,9 +1118,9 @@ async System.Collections.Generic.IAsyncEnumerator<int> M()
// (4,60): error CS8370: Feature 'async streams' is not available in C# 7.3. Please use language version 8.0 or greater.
// async System.Collections.Generic.IAsyncEnumerator<int> M()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M").WithArguments("async streams", "8.0").WithLocation(4, 60),
// (23,2): error CS8370: Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater.
// (34,2): error CS8370: Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater.
// #nullable disable
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "nullable").WithArguments("nullable reference types", "8.0").WithLocation(23, 2)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "nullable").WithArguments("nullable reference types", "8.0").WithLocation(34, 2)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ public void AllWellKnownTypes()
case WellKnownType.System_Runtime_CompilerServices_IsUnmanagedAttribute:
case WellKnownType.System_Index:
case WellKnownType.System_Range:
case WellKnownType.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute:
case WellKnownType.System_IAsyncDisposable:
case WellKnownType.System_Collections_Generic_IAsyncEnumerable_T:
case WellKnownType.System_Collections_Generic_IAsyncEnumerator_T:
Expand Down Expand Up @@ -891,6 +892,7 @@ public void AllWellKnownTypeMembers()
case WellKnownMember.System_Range__Create:
case WellKnownMember.System_Range__FromStart:
case WellKnownMember.System_Range__ToEnd:
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor:
case WellKnownMember.System_IAsyncDisposable__DisposeAsync:
case WellKnownMember.System_Collections_Generic_IAsyncEnumerable_T__GetAsyncEnumerator:
case WellKnownMember.System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync:
Expand Down
4 changes: 4 additions & 0 deletions src/Compilers/Core/Portable/WellKnownMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ internal enum WellKnownMember
System_Range__FromStart,
System_Range__All,

System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor,

System_IAsyncDisposable__DisposeAsync,
System_Collections_Generic_IAsyncEnumerable_T__GetAsyncEnumerator,
System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync,
Expand All @@ -477,5 +479,7 @@ internal enum WellKnownMember
System_Threading_Tasks_ValueTask_T__ctor,

Count

// Remember to update the AllWellKnownTypeMembers tests when making changes here
}
}
11 changes: 11 additions & 0 deletions src/Compilers/Core/Portable/WellKnownMembers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3137,6 +3137,14 @@ static WellKnownMembers()
0, // Method Signature
(byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Range - WellKnownType.ExtSentinel),

// System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor
(byte)MemberFlags.Constructor, // Flags
(byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId
0, // Arity
1, // Method Signature
(byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type
(byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.System_Type,

// System_IAsyncDisposable__DisposeAsync
(byte)(MemberFlags.Method | MemberFlags.Virtual), // Flags
(byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_IAsyncDisposable - WellKnownType.ExtSentinel), // DeclaringTypeId
Expand Down Expand Up @@ -3695,6 +3703,8 @@ static WellKnownMembers()
"FromStart", // System_Range__FromStart
"All", // System_Range__All

".ctor", // System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor

"DisposeAsync", // System_IAsyncDisposable__DisposeAsync
"GetAsyncEnumerator", // System_Collections_Generic_IAsyncEnumerable_T__GetAsyncEnumerator
"MoveNextAsync", // System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync
Expand Down Expand Up @@ -3742,6 +3752,7 @@ internal static bool IsSynthesizedAttributeOptional(WellKnownMember attributeMem
case WellKnownMember.System_STAThreadAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor:
return true;

default:
Expand Down
8 changes: 6 additions & 2 deletions src/Compilers/Core/Portable/WellKnownTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ internal enum WellKnownType
System_Index,
System_Range,

System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute,
System_IAsyncDisposable,
System_Collections_Generic_IAsyncEnumerable_T,
System_Collections_Generic_IAsyncEnumerator_T,
Expand All @@ -292,6 +293,8 @@ internal enum WellKnownType
System_Threading_Tasks_ValueTask,

NextAvailable,

// Remember to update the AllWellKnownTypes tests when making changes here
}

internal static class WellKnownTypes
Expand Down Expand Up @@ -565,6 +568,7 @@ internal static class WellKnownTypes
"System.Index",
"System.Range",

"System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute",
"System.IAsyncDisposable",
"System.Collections.Generic.IAsyncEnumerable`1",
"System.Collections.Generic.IAsyncEnumerator`1",
Expand Down Expand Up @@ -627,11 +631,11 @@ private static void AssertEnumAndTableInSync()
typeIdName = typeIdName.Substring(0, separator);
}

Debug.Assert(name == typeIdName);
Debug.Assert(name == typeIdName, "Enum name and type name must match");
}

Debug.Assert((int)WellKnownType.ExtSentinel == 255);
Debug.Assert((int)WellKnownType.NextAvailable <= 512);
Debug.Assert((int)WellKnownType.NextAvailable <= 512, "Time for a new sentinel");
}

public static bool IsWellKnownType(this WellKnownType typeId)
Expand Down
11 changes: 11 additions & 0 deletions src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ public interface IAsyncDisposable
}
}

namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class AsyncIteratorStateMachineAttribute : StateMachineAttribute
{
public AsyncIteratorStateMachineAttribute(Type stateMachineType) : base(stateMachineType)
{
}
}
}

#nullable disable

namespace System.Runtime.CompilerServices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ End Namespace
WellKnownType.System_ReadOnlySpan_T,
WellKnownType.System_Index,
WellKnownType.System_Range,
WellKnownType.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute,
WellKnownType.System_IAsyncDisposable,
WellKnownType.System_Collections_Generic_IAsyncEnumerable_T,
WellKnownType.System_Collections_Generic_IAsyncEnumerator_T,
Expand Down Expand Up @@ -561,6 +562,7 @@ End Namespace
WellKnownType.System_ReadOnlySpan_T,
WellKnownType.System_Index,
WellKnownType.System_Range,
WellKnownType.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute,
WellKnownType.System_IAsyncDisposable,
WellKnownType.System_Collections_Generic_IAsyncEnumerable_T,
WellKnownType.System_Collections_Generic_IAsyncEnumerator_T,
Expand Down Expand Up @@ -591,7 +593,7 @@ End Namespace
End Sub

<Fact>
<WorkItem(530436, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530436")>
<WorkItem(530436, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530436")>
Public Sub AllWellKnownTypeMembers()
Dim refs As MetadataReference() =
{
Expand Down Expand Up @@ -623,6 +625,7 @@ End Namespace
WellKnownMember.System_ReadOnlySpan_T__ctor,
WellKnownMember.System_ReadOnlySpan_T__get_Item,
WellKnownMember.System_ReadOnlySpan_T__get_Length,
WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor,
WellKnownMember.System_IAsyncDisposable__DisposeAsync,
WellKnownMember.System_Collections_Generic_IAsyncEnumerable_T__GetAsyncEnumerator,
WellKnownMember.System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync,
Expand Down Expand Up @@ -746,6 +749,7 @@ End Namespace
WellKnownMember.System_ReadOnlySpan_T__ctor,
WellKnownMember.System_ReadOnlySpan_T__get_Item,
WellKnownMember.System_ReadOnlySpan_T__get_Length,
WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorStateMachineAttribute__ctor,
WellKnownMember.System_IAsyncDisposable__DisposeAsync,
WellKnownMember.System_Collections_Generic_IAsyncEnumerable_T__GetAsyncEnumerator,
WellKnownMember.System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync,
Expand Down