{
if (returnType.Kind != MemberKind.Void &&
returnType != host.Module.PredefinedTypes.Task.TypeSpec &&
- returnType.MemberDefinition != host.Module.PredefinedTypes.TaskGeneric.TypeSpec.MemberDefinition) {
+ !returnType.IsGenericTask) {
host.Compiler.Report.Error (1983, loc, "The return type of an async method must be void, Task, or Task<T>");
}
InflatedExpressionType = 1 << 19,
InflatedNullableType = 1 << 20,
GenericIterateInterface = 1 << 21,
+ GenericTask = 1 << 22
}
protected Modifiers modifiers;
}
}
+ public override bool IsGenericTask {
+ get {
+ return (open_type.state & StateFlags.GenericTask) != 0;
+ }
+ }
+
public override bool IsNullableType {
get {
return (open_type.state & StateFlags.InflatedNullableType) != 0;
ctx.StartFlowBranching (this, ec.CurrentBranching);
Block.Resolve (ctx);
- ctx.CurrentBranching.CurrentUsageVector.Goto ();
+ //
+ // Explicit return is required for Task<T> state machine
+ //
+ var task_storey = storey as AsyncTaskStorey;
+ if (task_storey == null || !task_storey.ReturnType.IsGenericTask)
+ ctx.CurrentBranching.CurrentUsageVector.Goto ();
+
ctx.EndFlowBranching ();
var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc));
var storey = (AsyncTaskStorey) am.Storey;
var async_type = storey.ReturnType;
- if (async_type.MemberDefinition != ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MemberDefinition) {
+ if (!async_type.IsGenericTask) {
ec.Report.Error (1997, loc,
"`{0}': A return keyword must not be followed by an expression when async method returns Task. Consider using Task<T>",
ec.GetSignatureForError ());
ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
Task.Define ();
- TaskGeneric.Define ();
+ if (TaskGeneric.Define ())
+ TaskGeneric.TypeSpec.IsGenericTask = true;
}
}
}
}
+ //
+ // Returns true for instances of System.Threading.Tasks.Task<T>
+ //
+ public virtual bool IsGenericTask {
+ get {
+ return false;
+ }
+ set {
+ state = value ? state | StateFlags.GenericTask : state & ~StateFlags.GenericTask;
+ }
+ }
+
// TODO: Should probably do
// IsGenericType -- recursive
// HasTypeParameter -- non-recursive
if (t2.Result != 5)
return 4;
- if (t.Status != TaskStatus.RanToCompletion)
+ if (t2.Status != TaskStatus.RanToCompletion)
return 5;
return 0;
</method>
</type>
</test>
+ <test name="test-async-04.cs">
+ <type name="C">
+ <method name="System.Threading.Tasks.Task`1[System.Int32] TestTaskGeneric()">
+ <size>34</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.Int32] CallGeneric()">
+ <size>23</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>84</size>
+ </method>
+ <method name="Int32 <CallGeneric>m__0()">
+ <size>14</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>19</size>
+ </method>
+ </type>
+ <type name="C+<>c__async0">
+ <method name="Void MoveNext()">
+ <size>145</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>36</size>
+ </method>
+ </type>
+ </test>
<test name="test-async-05.cs">
<type name="C">
<method name="System.Threading.Tasks.Task Method()">