--- /dev/null
+// CS1986: The `await' operand type `int' must have suitable GetAwaiter method
+// Line: 15
+// Compiler options: -langversion:future
+
+static class S
+{
+ public static void GetAwaiter (this int i)
+ {
+ }
+}
+
+class A
+{
+ static async void Test ()
+ {
+ await 1;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS1986: The `await' operand type `A' must have suitable GetAwaiter method
+// Line: 15
+// Compiler options: -langversion:future
+
+static class S
+{
+ public static void GetAwaiter (this int i)
+ {
+ }
+}
+
+class A
+{
+ bool GetAwaiter;
+
+ static async void Test ()
+ {
+ await new A ();
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS1986: The `await' operand type `int' must have suitable GetAwaiter method
+// Line: 8
+// Compiler options: -langversion:future
+
+class A
+{
+ static async void Test ()
+ {
+ await 1;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS1991: Cannot await `void' expression
+// Line: 10
+// Compiler options: -langversion:future
+
+using System;
+
+class A
+{
+ static async void Test ()
+ {
+ await Console.WriteLine ("await");
+ }
+}
--- /dev/null
+// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+ public static int GetAwaiter (this int i)
+ {
+ return 1;
+ }
+}
+
+class A
+{
+ static async void Test ()
+ {
+ await 9;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+ public static int GetAwaiter (this int i)
+ {
+ return 1;
+ }
+}
+
+class A
+{
+ static async void Test ()
+ {
+ await 9;
+ }
+}
\ No newline at end of file
protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name)
{
- rc.Report.Error (1986, loc,
- "The `await' operand type `{0}' must have suitable GetAwaiter method",
- type.GetSignatureForError ());
+ Error_WrongGetAwaiter (rc, loc, type);
+ }
+
+ protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
+ {
+ rc.Report.Error (1991, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
}
}
MethodSpec on_completed;
public Await (Expression expr, Location loc)
- : base (new AwaitableMemberAccess (expr), loc)
+ : base (expr, loc)
{
}
mg_completed.EmitCall (ec, args);
}
+ static void Error_WrongGetAwaiter (ResolveContext rc, Location loc, TypeSpec type)
+ {
+ rc.Report.Error (1986, loc,
+ "The `await' operand type `{0}' must have suitable GetAwaiter method",
+ type.GetSignatureForError ());
+ }
+
void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
{
rc.Report.Error (1999, loc, "The awaiter type `{0}' must have suitable IsCompleted, OnCompleted, and GetResult members",
if (!base.Resolve (bc))
return false;
- //
- // Check whether the expression is awaitable
- //
- var t = expr.Type;
-
//
// The task t is of type dynamic
//
- if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+ if (expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
throw new NotImplementedException ("dynamic await");
- var mg = expr as MethodGroupExpr;
- if (mg == null)
- throw new NotImplementedException ("wrong expression kind");
+ //
+ // Check whether the expression is awaitable
+ //
+ Expression ama = new AwaitableMemberAccess (expr).Resolve (bc);
+ if (ama == null)
+ return false;
Arguments args = new Arguments (0);
- //expr = mg.OverloadResolve (bc, ref args, null, OverloadResolver.Restrictions.NoBaseMembers);
- expr = new Invocation (expr, args).Resolve (bc);
+ var errors_printer = new SessionReportPrinter ();
+ var old = bc.Report.SetPrinter (errors_printer);
+ ama = new Invocation (ama, args).Resolve (bc);
+
+ if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression (ama.Type)) {
+ bc.Report.SetPrinter (old);
+ Error_WrongGetAwaiter (bc, loc, expr.Type);
+ return false;
+ }
var awaiter_type = expr.Type;
awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (awaiter_type, loc);
if (is_completed != null && is_completed.Type.BuiltinType == BuiltinTypeSpec.Type.Bool && is_completed.IsInstance && is_completed.Getter != null) {
// valid
} else {
+ bc.Report.SetPrinter (old);
Error_WrongAwaiterPattern (bc, awaiter_type);
return false;
}
}
+ if (errors_printer.ErrorsCount > 0) {
+ bc.Report.SetPrinter (old);
+ Error_WrongAwaiterPattern (bc, awaiter_type);
+ return false;
+ }
+
//
// void OnCompleted (Action)
//
get;
}
- // TODO: Not needed
protected abstract TypeSpec DeclaringType {
get;
}
return e;
}
+ protected virtual void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
+ {
+ if (type == InternalType.NullLiteral && rc.IsRuntimeBinder)
+ rc.Report.Error (Report.RuntimeErrorId, loc, "Cannot perform member binding on `null' value");
+ else
+ Unary.Error_OperatorCannotBeApplied (rc, loc, ".", type);
+ }
+
+ public static bool IsValidDotExpression (TypeSpec type)
+ {
+ const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
+ MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
+
+ return (type.Kind & dot_kinds) != 0;
+ }
+
public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
{
var sn = expr as SimpleName;
return new DynamicMemberBinder (Name, args, loc);
}
- const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
- MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
-
- if ((expr_type.Kind & dot_kinds) == 0) {
- if (expr_type == InternalType.NullLiteral && rc.IsRuntimeBinder)
- rc.Report.Error (Report.RuntimeErrorId, loc, "Cannot perform member binding on `null' value");
- else
- Unary.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
+ if (!IsValidDotExpression (expr_type)) {
+ Error_OperatorCannotBeApplied (rc, expr_type);
return null;
}
}
#region Properties
+
protected override TypeSpec DeclaringType {
get {
return best_candidate.DeclaringType;
default_references.Add ("Microsoft.CSharp.dll");
}
+ if (compiler.Settings.Version == LanguageVersion.Future)
+ default_references.Add ("Mono.Async.dll");
+
return default_references.ToArray ();
}