PageRenderTime 25ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/Src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs

https://github.com/EkardNT/Roslyn
C# | 3780 lines | 3195 code | 137 blank | 448 comment | 1 complexity | 093c3e2421baa2837e93dde09d6dbcc9 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.CodeAnalysis.CSharp.Symbols;
  5. using Microsoft.CodeAnalysis.CSharp.Syntax;
  6. using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
  7. using Microsoft.CodeAnalysis.Text;
  8. using Roslyn.Test.Utilities;
  9. using Xunit;
  10. namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
  11. {
  12. public class BindingAsyncTests : CompilingTestBase
  13. {
  14. [Fact]
  15. public void AsyncMethod()
  16. {
  17. var source = @"
  18. using System.Threading.Tasks;
  19. class C
  20. {
  21. async void M(Task t)
  22. {
  23. await t;
  24. }
  25. }";
  26. var compilation = CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  27. var method = (SourceMethodSymbol)compilation.GlobalNamespace.GetTypeMembers("C").Single().GetMembers("M").Single();
  28. Assert.True(method.IsAsync);
  29. }
  30. [Fact]
  31. public void AsyncLambdas()
  32. {
  33. var source = @"
  34. using System;
  35. using System.Threading.Tasks;
  36. class C
  37. {
  38. public static void Main()
  39. {
  40. Action<Task> f1 = async (Task t) => { await t; };
  41. Action<Task> f2 = async t => { await t; };
  42. Action<Task> f3 = async (t) => { await t; };
  43. }
  44. }";
  45. var tree = SyntaxFactory.ParseSyntaxTree(source);
  46. var compilation = CreateCompilationWithMscorlib45(new SyntaxTree[] {tree}).VerifyDiagnostics();
  47. var model = compilation.GetSemanticModel(tree);
  48. var simple = tree.GetCompilationUnitRoot().DescendantNodes().OfType<SimpleLambdaExpressionSyntax>().Single();
  49. Assert.True(((LambdaSymbol)model.GetSymbolInfo(simple).Symbol).IsAsync);
  50. var parens = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>();
  51. Assert.True(parens.Count() == 2, "Expect exactly two parenthesized lambda expressions in the syntax tree.");
  52. foreach (var paren in parens)
  53. {
  54. Assert.True(((LambdaSymbol)model.GetSymbolInfo(paren).Symbol).IsAsync);
  55. }
  56. }
  57. [Fact]
  58. public void AsyncDelegates()
  59. {
  60. var source = @"
  61. using System;
  62. using System.Threading.Tasks;
  63. class C
  64. {
  65. public static void Main()
  66. {
  67. Action<Task> f4 = async delegate(Task t) { await t; };
  68. }
  69. }";
  70. var tree = SyntaxFactory.ParseSyntaxTree(source);
  71. var compilation = CreateCompilationWithMscorlib45(new SyntaxTree[] { tree }).VerifyDiagnostics();
  72. var model = compilation.GetSemanticModel(tree);
  73. var del = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
  74. Assert.True(((LambdaSymbol)model.GetSymbolInfo(del).Symbol).IsAsync);
  75. }
  76. [Fact]
  77. public void BadAsyncConstructor()
  78. {
  79. var source = @"
  80. class C {
  81. async public C() { }
  82. }";
  83. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  84. Diagnostic(ErrorCode.ERR_BadMemberFlag, "C").WithArguments("async"));
  85. }
  86. [Fact]
  87. public void BadAsyncDestructor()
  88. {
  89. var source = @"
  90. class C
  91. {
  92. async extern ~C();
  93. }";
  94. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  95. Diagnostic(ErrorCode.ERR_BadMemberFlag, "C").WithArguments("async"),
  96. Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "C").WithArguments("C.~C()"));
  97. }
  98. [Fact]
  99. public void BadAsyncEvent()
  100. {
  101. var source = @"
  102. public delegate void MyDelegate();
  103. class C
  104. {
  105. public C() {
  106. MyEvent.Invoke();
  107. }
  108. async event MyDelegate MyEvent;
  109. }";
  110. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  111. Diagnostic(ErrorCode.ERR_BadMemberFlag, "MyEvent").WithArguments("async"));
  112. }
  113. [Fact]
  114. public void BadAsyncField()
  115. {
  116. var source = @"
  117. class C
  118. {
  119. public C(int i)
  120. {
  121. this.i = i;
  122. }
  123. async int i;
  124. }";
  125. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  126. Diagnostic(ErrorCode.ERR_BadMemberFlag, "i").WithArguments("async"));
  127. }
  128. [Fact]
  129. public void BadAsyncClass()
  130. {
  131. var source = @"
  132. public async class C
  133. {
  134. }";
  135. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  136. Diagnostic(ErrorCode.ERR_BadMemberFlag, "C").WithArguments("async"));
  137. }
  138. [Fact]
  139. public void BadAsyncStruct()
  140. {
  141. var source = @"
  142. internal async struct S
  143. {
  144. }";
  145. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  146. Diagnostic(ErrorCode.ERR_BadMemberFlag, "S").WithArguments("async"));
  147. }
  148. [Fact]
  149. public void BadAsyncInterface()
  150. {
  151. var source = @"
  152. internal async interface I
  153. {
  154. }";
  155. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  156. Diagnostic(ErrorCode.ERR_BadMemberFlag, "I").WithArguments("async"));
  157. }
  158. [Fact]
  159. public void BadAsyncDelegate()
  160. {
  161. var source = @"
  162. public async delegate void MyDelegate();
  163. ";
  164. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  165. Diagnostic(ErrorCode.ERR_BadMemberFlag, "MyDelegate").WithArguments("async"));
  166. }
  167. [Fact]
  168. public void BadAsyncProperty()
  169. {
  170. var source = @"
  171. public async delegate void MyDelegate();
  172. ";
  173. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  174. Diagnostic(ErrorCode.ERR_BadMemberFlag, "MyDelegate").WithArguments("async"));
  175. }
  176. [Fact]
  177. public void BadAsyncPropertyAccessor()
  178. {
  179. var source = @"
  180. public async delegate void MyDelegate();
  181. ";
  182. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  183. Diagnostic(ErrorCode.ERR_BadMemberFlag, "MyDelegate").WithArguments("async"));
  184. }
  185. [Fact]
  186. public void TaskRetNoObjectRequired()
  187. {
  188. var source = @"
  189. using System;
  190. using System.Threading.Tasks;
  191. class C
  192. {
  193. static void InferTask(Func<Task> x) { }
  194. static void InferTaskOrTaskT(Func<Task> x) { }
  195. static void InferTaskOrTaskT(Func<Task<int>> x) { }
  196. static async Task F1()
  197. {
  198. return await Task.Factory.StartNew(() => 1);
  199. }
  200. static void Main()
  201. {
  202. Func<Task> F2 = async () => { await Task.Factory.StartNew(() => { }); return 1; };
  203. InferTask(async () => { return await Task.Factory.StartNew(() => 1); });
  204. InferTaskOrTaskT(async () => { return await Task.Factory.StartNew(() => 1); });
  205. }
  206. }";
  207. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  208. // (14,9): error CS1997: Since 'C.F1()' is an async method that returns 'Task', a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?
  209. // return await Task.Factory.StartNew(() => 1);
  210. Diagnostic(ErrorCode.ERR_TaskRetNoObjectRequired, "return").WithArguments("C.F1()").WithLocation(14, 9),
  211. // (19,79): error CS8030: Async lambda expression converted to a 'Task' returning delegate cannot return a value. Did you intend to return 'Task<T>'?
  212. // Func<Task> F2 = async () => { await Task.Factory.StartNew(() => { }); return 1; };
  213. Diagnostic(ErrorCode.ERR_TaskRetNoObjectRequiredLambda, "return").WithLocation(19, 79),
  214. // (20,33): error CS8030: Async lambda expression converted to a 'Task' returning delegate cannot return a value. Did you intend to return 'Task<T>'?
  215. // InferTask(async () => { return await Task.Factory.StartNew(() => 1); });
  216. Diagnostic(ErrorCode.ERR_TaskRetNoObjectRequiredLambda, "return").WithLocation(20, 33)
  217. );
  218. }
  219. [Fact]
  220. public void BadAsyncReturn()
  221. {
  222. var source = @"
  223. using System;
  224. using System.Threading.Tasks;
  225. class MyTask : Task
  226. {
  227. public MyTask(Action a) : base(a) { }
  228. }
  229. class C
  230. {
  231. async int F1()
  232. {
  233. await Task.Factory.StartNew(() => { });
  234. }
  235. async MyTask F2()
  236. {
  237. await Task.Factory.StartNew(() => { });
  238. }
  239. async T F3<T>()
  240. {
  241. await Task.Factory.StartNew(() => { });
  242. }
  243. async T F4<T>() where T : Task
  244. {
  245. await Task.Factory.StartNew(() => { });
  246. }
  247. }";
  248. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  249. // (17,18): error CS1983: The return type of an async method must be void, Task or Task<T>
  250. // async MyTask F2()
  251. Diagnostic(ErrorCode.ERR_BadAsyncReturn, "F2"),
  252. // (22,13): error CS1983: The return type of an async method must be void, Task or Task<T>
  253. // async T F3<T>()
  254. Diagnostic(ErrorCode.ERR_BadAsyncReturn, "F3"),
  255. // (27,13): error CS1983: The return type of an async method must be void, Task or Task<T>
  256. // async T F4<T>() where T : Task
  257. Diagnostic(ErrorCode.ERR_BadAsyncReturn, "F4"),
  258. // (12,15): error CS1983: The return type of an async method must be void, Task or Task<T>
  259. // async int F1()
  260. Diagnostic(ErrorCode.ERR_BadAsyncReturn, "F1"),
  261. // (12,15): error CS0161: 'C.F1()': not all code paths return a value
  262. // async int F1()
  263. Diagnostic(ErrorCode.ERR_ReturnExpected, "F1").WithArguments("C.F1()"),
  264. // (17,18): error CS0161: 'C.F2()': not all code paths return a value
  265. // async MyTask F2()
  266. Diagnostic(ErrorCode.ERR_ReturnExpected, "F2").WithArguments("C.F2()"),
  267. // (22,13): error CS0161: 'C.F3<T>()': not all code paths return a value
  268. // async T F3<T>()
  269. Diagnostic(ErrorCode.ERR_ReturnExpected, "F3").WithArguments("C.F3<T>()"),
  270. // (27,13): error CS0161: 'C.F4<T>()': not all code paths return a value
  271. // async T F4<T>() where T : Task
  272. Diagnostic(ErrorCode.ERR_ReturnExpected, "F4").WithArguments("C.F4<T>()"));
  273. }
  274. [Fact]
  275. public void CantConvAsyncAnonFuncReturns()
  276. {
  277. var source = @"
  278. using System;
  279. using System.Threading.Tasks;
  280. class C
  281. {
  282. static void Main()
  283. {
  284. Func<int> f1 = async () => await Task.Factory.StartNew(() => 1);
  285. Func<int> f2 = async () => { return await Task.Factory.StartNew(() => 1); };
  286. }
  287. }";
  288. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  289. // (9,24): error CS4010: Cannot convert async lambda expression to delegate type 'System.Func<int>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'System.Func<int>'.
  290. // Func<int> f1 = async () => await Task.Factory.StartNew(() => 1);
  291. Diagnostic(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, "async () => await Task.Factory.StartNew(() => 1)").WithArguments("lambda expression", "System.Func<int>").WithLocation(9, 24),
  292. // (10,24): error CS4010: Cannot convert async lambda expression to delegate type 'System.Func<int>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'System.Func<int>'.
  293. // Func<int> f2 = async () => { return await Task.Factory.StartNew(() => 1); };
  294. Diagnostic(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, "async () => { return await Task.Factory.StartNew(() => 1); }").WithArguments("lambda expression", "System.Func<int>").WithLocation(10, 24)
  295. );
  296. }
  297. [Fact]
  298. public void BadAsyncReturnExpression()
  299. {
  300. var source = @"
  301. using System;
  302. using System.Threading.Tasks;
  303. class C
  304. {
  305. static void InferTask_T(Func<Task<int>> x) { }
  306. static void Main()
  307. {
  308. Func<Task<int>> f1 = async () => await Task.Factory.StartNew(() => new Task<int>(null));
  309. Func<Task<int>> f2 = async () => { return await Task.Factory.StartNew(() => new Task<int>(null)); };
  310. InferTask_T(async () => await Task.Factory.StartNew(() => new Task<int>(() => 1)));
  311. InferTask_T(async () => { return await Task.Factory.StartNew(() => new Task<int>(() => 1)); });
  312. }
  313. }";
  314. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  315. // (11,42): error CS4016: Since this is an async method, the return expression must be of type 'int' rather than 'Task<int>'
  316. // Func<Task<int>> f1 = async () => await Task.Factory.StartNew(() => new Task<int>(null));
  317. Diagnostic(ErrorCode.ERR_BadAsyncReturnExpression, "await Task.Factory.StartNew(() => new Task<int>(null))").WithArguments("int"),
  318. // (12,51): error CS4016: Since this is an async method, the return expression must be of type 'int' rather than 'Task<int>'
  319. // Func<Task<int>> f2 = async () => { return await Task.Factory.StartNew(() => new Task<int>(null)); };
  320. Diagnostic(ErrorCode.ERR_BadAsyncReturnExpression, "await Task.Factory.StartNew(() => new Task<int>(null))").WithArguments("int"),
  321. // (14,33): error CS4016: Since this is an async method, the return expression must be of type 'int' rather than 'Task<int>'
  322. // InferTask_T(async () => await Task.Factory.StartNew(() => new Task<int>(() => 1)));
  323. Diagnostic(ErrorCode.ERR_BadAsyncReturnExpression, "await Task.Factory.StartNew(() => new Task<int>(() => 1))").WithArguments("int"),
  324. // (15,42): error CS4016: Since this is an async method, the return expression must be of type 'int' rather than 'Task<int>'
  325. // InferTask_T(async () => { return await Task.Factory.StartNew(() => new Task<int>(() => 1)); });
  326. Diagnostic(ErrorCode.ERR_BadAsyncReturnExpression, "await Task.Factory.StartNew(() => new Task<int>(() => 1))").WithArguments("int"));
  327. }
  328. [Fact]
  329. public void AsyncCantReturnVoid()
  330. {
  331. var source = @"
  332. using System;
  333. using System.Threading.Tasks;
  334. class C
  335. {
  336. static void InferVoid(Action x) { }
  337. static void InferTask_T<T>(Func<Task<T>> x) { }
  338. static void Infer_T<T>(Func<T> x) { }
  339. static void Main()
  340. {
  341. InferVoid(async () => { return await Task.Factory.StartNew(() => { }); });
  342. InferTask_T(async () => { return await Task.Factory.StartNew(() => { }); });
  343. Infer_T(async () => { return await Task.Factory.StartNew(() => { }); });
  344. }
  345. }";
  346. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics(
  347. // (13,33): error CS8029: Anonymous function converted to a void returning delegate cannot return a value
  348. // InferVoid(async () => { return await Task.Factory.StartNew(() => { }); });
  349. Diagnostic(ErrorCode.ERR_RetNoObjectRequiredLambda, "return").WithLocation(13, 33),
  350. // (14,42): error CS4029: Cannot return an expression of type 'void'
  351. // InferTask_T(async () => { return await Task.Factory.StartNew(() => { }); });
  352. Diagnostic(ErrorCode.ERR_CantReturnVoid, "await Task.Factory.StartNew(() => { })").WithLocation(14, 42),
  353. // (15,38): error CS4029: Cannot return an expression of type 'void'
  354. // Infer_T(async () => { return await Task.Factory.StartNew(() => { }); });
  355. Diagnostic(ErrorCode.ERR_CantReturnVoid, "await Task.Factory.StartNew(() => { })").WithLocation(15, 38)
  356. );
  357. }
  358. [Fact]
  359. public void InferAsyncReturn()
  360. {
  361. var source = @"
  362. using System;
  363. using System.Threading.Tasks;
  364. class C
  365. {
  366. static void InferVoid(Action x) { }
  367. static void InferTask(Func<Task> x) { }
  368. static void InferTask_T<T>(Func<Task<T>> x) { }
  369. static void Main()
  370. {
  371. InferVoid(async () => { await Task.Factory.StartNew(() => { }); });
  372. InferTask(async () => { await Task.Factory.StartNew(() => { return; }); });
  373. InferTask_T(async () => { return await Task.Factory.StartNew(() => 1); });
  374. }
  375. }";
  376. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics();
  377. }
  378. [Fact]
  379. public void BadInferAsyncReturn_T()
  380. {
  381. var source = @"
  382. using System;
  383. using System.Threading.Tasks;
  384. class C
  385. {
  386. static void Infer<T>(Func<bool, T> x) { }
  387. static void Main()
  388. {
  389. Infer(async (x) =>
  390. {
  391. await Task.Factory.StartNew(() => { });
  392. if (x)
  393. {
  394. return 1;
  395. }
  396. else
  397. {
  398. return;
  399. }
  400. });
  401. }
  402. }";
  403. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics(
  404. // (19,17): error CS0126: An object of a type convertible to 'int' is required
  405. // return;
  406. Diagnostic(ErrorCode.ERR_RetObjectRequired, "return").WithArguments("int"));
  407. }
  408. [Fact]
  409. public void BadInferAsyncReturnVoid()
  410. {
  411. var source = @"
  412. using System;
  413. using System.Threading.Tasks;
  414. class C
  415. {
  416. static void Infer(Action<bool> x) { }
  417. static void Main()
  418. {
  419. Infer(async (x) =>
  420. {
  421. await Task.Factory.StartNew(() => { });
  422. if (x)
  423. {
  424. return 1;
  425. }
  426. else
  427. {
  428. return;
  429. }
  430. });
  431. }
  432. }";
  433. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics(
  434. // (16,17): error CS8029: Anonymous function converted to a void returning delegate cannot return a value
  435. // return 1;
  436. Diagnostic(ErrorCode.ERR_RetNoObjectRequiredLambda, "return").WithLocation(16, 17)
  437. );
  438. }
  439. [Fact]
  440. public void BadInferAsyncReturnTask()
  441. {
  442. var source = @"
  443. using System;
  444. using System.Threading.Tasks;
  445. class C
  446. {
  447. static void Infer(Func<bool, Task> x) { }
  448. static void Main()
  449. {
  450. Infer(async (x) =>
  451. {
  452. await Task.Factory.StartNew(() => { });
  453. if (x)
  454. {
  455. return 1;
  456. }
  457. else
  458. {
  459. return;
  460. }
  461. });
  462. }
  463. }";
  464. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics(
  465. // (16,17): error CS8030: Async lambda expression converted to a 'Task' returning delegate cannot return a value. Did you intend to return 'Task<T>'?
  466. // return 1;
  467. Diagnostic(ErrorCode.ERR_TaskRetNoObjectRequiredLambda, "return").WithLocation(16, 17)
  468. );
  469. }
  470. [Fact]
  471. public void BadInferAsyncReturnTask_T()
  472. {
  473. var source = @"
  474. using System;
  475. using System.Threading.Tasks;
  476. class C
  477. {
  478. static void Infer<T>(Func<bool, Task<T>> x) { }
  479. static void Main()
  480. {
  481. Infer(async (x) =>
  482. {
  483. await Task.Factory.StartNew(() => { });
  484. if (x)
  485. {
  486. return 1;
  487. }
  488. else
  489. {
  490. return;
  491. }
  492. });
  493. }
  494. }";
  495. CreateCompilationWithMscorlib45(source, new MetadataReference[] { LinqAssemblyRef, SystemRef }).VerifyDiagnostics(
  496. // (19,17): error CS0126: An object of a type convertible to 'int' is required
  497. // return;
  498. Diagnostic(ErrorCode.ERR_RetObjectRequired, "return").WithArguments("int"));
  499. }
  500. [Fact]
  501. public void TaskReturningAsyncWithoutReturn()
  502. {
  503. var source = @"
  504. using System.Threading.Tasks;
  505. class C
  506. {
  507. async static Task F()
  508. {
  509. }
  510. }";
  511. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  512. // (6,23): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
  513. // async static Task F()
  514. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "F"));
  515. }
  516. [Fact]
  517. public void TestAsyncReturnsNullableT()
  518. {
  519. var source = @"
  520. using System;
  521. using System.Threading.Tasks;
  522. class C
  523. {
  524. async static Task<int?> F()
  525. {
  526. await Task.Factory.StartNew(() => { });
  527. return null;
  528. }
  529. static void Main()
  530. {
  531. Func<Task<int?>> f1 = async () => await Task.Factory.StartNew<int?>(() => { return null; });
  532. Func<Task<int?>> f2 = async () => { return await Task.Factory.StartNew<int?>(() => { return null; }); };
  533. }
  534. }";
  535. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  536. }
  537. [Fact]
  538. public void VarargsAsync()
  539. {
  540. var source = @"
  541. using System.Threading.Tasks;
  542. class Test
  543. {
  544. async static Task M1(__arglist)
  545. {
  546. await Task.Factory.StartNew(() => { });
  547. }
  548. }";
  549. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  550. // (6,23): error CS4006: __arglist is not allowed in the parameter list of async methods
  551. // async static Task M1(__arglist)
  552. Diagnostic(ErrorCode.ERR_VarargsAsync, "M1"));
  553. }
  554. [Fact]
  555. public void VarargsAsyncGeneric()
  556. {
  557. var source = @"
  558. using System.Threading.Tasks;
  559. class Test
  560. {
  561. async static Task M1<T>(__arglist)
  562. {
  563. await Task.Factory.StartNew(() => { });
  564. return;
  565. }
  566. }";
  567. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  568. // (6,23): error CS0224: A method with vararg cannot be generic, be in a generic type, or have a params parameter
  569. // async static Task M1<T>(__arglist)
  570. Diagnostic(ErrorCode.ERR_BadVarargs, "M1"));
  571. }
  572. [Fact]
  573. public void VarargsAsyncInGenericClass()
  574. {
  575. var source = @"
  576. using System.Threading.Tasks;
  577. class Test
  578. {
  579. async static Task M1<T>(__arglist)
  580. {
  581. await Task.Factory.StartNew(() => { });
  582. return;
  583. }
  584. }";
  585. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  586. // (6,23): error CS0224: A method with vararg cannot be generic, be in a generic type, or have a params parameter
  587. // async static Task M1<T>(__arglist)
  588. Diagnostic(ErrorCode.ERR_BadVarargs, "M1"));
  589. }
  590. [Fact]
  591. public void UnsafeAsyncArgType()
  592. {
  593. var source = @"
  594. using System.Threading.Tasks;
  595. class Test
  596. {
  597. unsafe async static Task M1(int* i) { }
  598. }";
  599. CreateCompilationWithMscorlib45(source, null, TestOptions.Dll.WithAllowUnsafe(true)).VerifyDiagnostics(
  600. // (6,38): error CS4005: Async methods cannot have unsafe parameters or return types
  601. // unsafe async static Task M1(int* i)
  602. Diagnostic(ErrorCode.ERR_UnsafeAsyncArgType, "i"),
  603. // (6,30): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
  604. // unsafe async static Task M1(ref int* i)
  605. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M1"));
  606. }
  607. [Fact]
  608. public void Ref_and_UnsafeAsyncArgType()
  609. {
  610. var source = @"
  611. using System.Threading.Tasks;
  612. class Test
  613. {
  614. unsafe async static Task M1(ref int* i) { }
  615. }";
  616. CreateCompilationWithMscorlib45(source, null, TestOptions.UnsafeDll).VerifyDiagnostics(
  617. // (6,42): error CS1988: Async methods cannot have ref or out parameters
  618. // unsafe async static Task M1(ref int* i)
  619. Diagnostic(ErrorCode.ERR_BadAsyncArgType, "i"),
  620. // (6,30): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
  621. // unsafe async static Task M1(ref int* i)
  622. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M1"));
  623. }
  624. [Fact]
  625. public void RefAsyncArgType()
  626. {
  627. var source = @"
  628. using System.Threading.Tasks;
  629. class Test
  630. {
  631. async static Task M1(ref int i)
  632. {
  633. await Task.Factory.StartNew(() => { });
  634. }
  635. }";
  636. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  637. // (6,42): error CS1988: Async methods cannot have ref or out parameters
  638. // unsafe async static Task M1(ref int* i) { }
  639. Diagnostic(ErrorCode.ERR_BadAsyncArgType, "i"));
  640. }
  641. [Fact]
  642. public void OutAsyncArgType()
  643. {
  644. var source = @"
  645. using System.Threading.Tasks;
  646. class Test
  647. {
  648. async static Task M1(out int i)
  649. {
  650. await Task.Factory.StartNew(() => { });
  651. }
  652. }";
  653. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  654. // (6,34): error CS1988: Async methods cannot have ref or out parameters
  655. // async static Task M1(out int i) { }
  656. Diagnostic(ErrorCode.ERR_BadAsyncArgType, "i"));
  657. }
  658. [Fact]
  659. public void BadAwaitWithoutAsync()
  660. {
  661. var source = @"
  662. using System;
  663. using System.Threading.Tasks;
  664. class MyAttribute : Attribute {
  665. public MyAttribute(int i) { }
  666. }
  667. [MyAttribute(await C.t)]
  668. class C
  669. {
  670. public static Task<int> t = new Task<int>(() => 1);
  671. int i = await t;
  672. }";
  673. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  674. // (9,14): error CS1992: The 'await' operator can only be used when contained within a method or lambda expression marked with the 'async' modifier
  675. // [MyAttribute(await C.t)]
  676. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsync, "await C.t"),
  677. // (14,13): error CS1992: The 'await' operator can only be used when contained within a method or lambda expression marked with the 'async' modifier
  678. // int i = await t;
  679. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsync, "await t"));
  680. }
  681. [Fact]
  682. public void BadAwaitWithoutAsync_AnonMeth_Lambda()
  683. {
  684. var source = @"
  685. using System;
  686. using System.Threading.Tasks;
  687. class C
  688. {
  689. public static void Main()
  690. {
  691. Action f1 = delegate() { await Task.Factory.StartNew(() => { }); };
  692. Action f2 = () => await Task.Factory.StartNew(() => { });
  693. Action f3 = () => { await Task.Factory.StartNew(() => { }); };
  694. }
  695. }";
  696. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  697. // (9,34): error CS4034: The 'await' operator can only be used within an async anonymous method. Consider marking this anonymous method with the 'async' modifier.
  698. // Action f1 = delegate() { await Task.Factory.StartNew(() => { }); };
  699. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncLambda, "await Task.Factory.StartNew(() => { })").WithArguments("anonymous method"),
  700. // (10,27): error CS4034: The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.
  701. // Action f2 = () => await Task.Factory.StartNew(() => { });
  702. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncLambda, "await Task.Factory.StartNew(() => { })").WithArguments("lambda expression"),
  703. // (11,29): error CS4034: The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.
  704. // Action f3 = () => { await Task.Factory.StartNew(() => { }); };
  705. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncLambda, "await Task.Factory.StartNew(() => { })").WithArguments("lambda expression"));
  706. }
  707. [Fact]
  708. public void IDS_BadAwaitWithoutAsyncMethod_VoidMethod()
  709. {
  710. var source = @"
  711. using System.Threading.Tasks;
  712. class C
  713. {
  714. public static void F()
  715. {
  716. await Task.Factory.StartNew(() => { });
  717. }
  718. public static int G()
  719. {
  720. return await Task.Factory.StartNew(() => 1);
  721. }
  722. }";
  723. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  724. // (8,9): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
  725. // await Task.Factory.StartNew(() => { });
  726. Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Factory.StartNew(() => { })"),
  727. // (13,16): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<int>'.
  728. // return await Task.Factory.StartNew(() => 1);
  729. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Factory.StartNew(() => 1)").WithArguments("int"));
  730. }
  731. [Fact]
  732. public void IDS_BadAwaitAsDefaultParam()
  733. {
  734. var source = @"
  735. using System.Threading.Tasks;
  736. class Test
  737. {
  738. static Task t = new Task(null);
  739. class await { }
  740. static int Foo(int[] arr = await t)
  741. {
  742. return arr.Length;
  743. }
  744. static int Main()
  745. {
  746. return 1;
  747. }
  748. }";
  749. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  750. /// (10,32): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<int>'.
  751. // static int Foo(int[] arr = await t)
  752. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await t").WithArguments("int"),
  753. // (10,26): error CS1750: A value of type '?' cannot be used as a default parameter because there are no standard conversions to type 'int[]'
  754. // static int Foo(int[] arr = await t)
  755. Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "arr").WithArguments("?", "int[]"));
  756. }
  757. [Fact]
  758. public void BadAwaitInFinally()
  759. {
  760. var source = @"
  761. using System.Threading.Tasks;
  762. class Test
  763. {
  764. async static Task M1() {
  765. try
  766. {
  767. }
  768. catch
  769. {
  770. try
  771. {
  772. }
  773. catch
  774. {
  775. }
  776. finally
  777. {
  778. await Task.Factory.StartNew(() => { });
  779. }
  780. }
  781. finally
  782. {
  783. try
  784. {
  785. }
  786. catch
  787. {
  788. await Task.Factory.StartNew(() => { });
  789. }
  790. finally
  791. {
  792. }
  793. }
  794. }
  795. }";
  796. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  797. }
  798. [Fact]
  799. public void BadAwaitInCatch()
  800. {
  801. var source = @"
  802. using System.Threading.Tasks;
  803. class Test
  804. {
  805. async static Task M1() {
  806. try
  807. {
  808. }
  809. catch
  810. {
  811. await Task.Factory.StartNew(() => { });
  812. }
  813. finally
  814. {
  815. }
  816. }
  817. }";
  818. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  819. }
  820. [Fact]
  821. public void BadAwaitInCatchFilter()
  822. {
  823. var source = @"
  824. using System.Threading.Tasks;
  825. class Test
  826. {
  827. async static Task M1()
  828. {
  829. try
  830. {
  831. }
  832. catch if (await Task.Factory.StartNew(() => false))
  833. {
  834. }
  835. finally
  836. {
  837. }
  838. }
  839. }";
  840. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  841. // (11,19): error CS7094: Cannot await in the filter expression of a catch clause
  842. // catch if (await Task.Factory.StartNew(() => false))
  843. Diagnostic(ErrorCode.ERR_BadAwaitInCatchFilter, "await Task.Factory.StartNew(() => false)").WithLocation(11, 19)
  844. );
  845. }
  846. [Fact]
  847. public void BadAwaitInLock()
  848. {
  849. var source = @"
  850. using System.Threading.Tasks;
  851. class Test
  852. {
  853. async static Task M1() {
  854. lock (new object())
  855. {
  856. await Task.Factory.StartNew(() => { });
  857. try
  858. {
  859. }
  860. catch
  861. {
  862. await Task.Factory.StartNew(() => { });
  863. }
  864. finally
  865. {
  866. await Task.Factory.StartNew(() => { });
  867. }
  868. }
  869. try
  870. {
  871. }
  872. catch
  873. {
  874. lock (new object())
  875. {
  876. await Task.Factory.StartNew(() => { });
  877. }
  878. }
  879. finally
  880. {
  881. lock (new object())
  882. {
  883. await Task.Factory.StartNew(() => { });
  884. }
  885. }
  886. }
  887. }";
  888. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  889. // (10,13): error CS1996: Cannot await in the body of a lock statement
  890. // await Task.Factory.StartNew(() => { });
  891. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Factory.StartNew(() => { })"),
  892. // (17,17): error CS1996: Cannot await in the body of a lock statement
  893. // await Task.Factory.StartNew(() => { });
  894. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Factory.StartNew(() => { })"),
  895. // (21,17): error CS1996: Cannot await in the body of a lock statement
  896. // await Task.Factory.StartNew(() => { });
  897. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Factory.StartNew(() => { })"),
  898. // (32,17): error CS1996: Cannot await in the body of a lock statement
  899. // await Task.Factory.StartNew(() => { });
  900. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Factory.StartNew(() => { })"),
  901. // (39,17): error CS1996: Cannot await in the body of a lock statement
  902. // await Task.Factory.StartNew(() => { });
  903. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Factory.StartNew(() => { })"));
  904. }
  905. [Fact]
  906. public void BadAwaitInLock2()
  907. {
  908. var source = @"
  909. using System.Threading.Tasks;
  910. class Program
  911. {
  912. async void Test()
  913. {
  914. lock(await M()) // fine, not in body of lock
  915. lock (await M()) // error, in body of outer lock
  916. {
  917. await M(); // error, in body of inner lock
  918. }
  919. }
  920. async Task<object> M()
  921. {
  922. return await M();
  923. }
  924. }";
  925. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  926. // (9,19): error CS1996: Cannot await in the body of a lock statement
  927. // lock (await M()) // error, in body of outer lock
  928. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await M()"),
  929. // (11,17): error CS1996: Cannot await in the body of a lock statement
  930. // await M(); // error, in body of inner lock
  931. Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await M()"));
  932. }
  933. [Fact]
  934. public void AwaitingInLockExpressionsIsActuallyOK()
  935. {
  936. var source = @"
  937. using System.Threading.Tasks;
  938. class Driver
  939. {
  940. public static async void F()
  941. {
  942. object o = new object();
  943. lock(await Task.Factory.StartNew(() => o))
  944. {
  945. }
  946. }
  947. static void Main() { }
  948. }";
  949. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  950. }
  951. [WorkItem(611150, "DevDiv")]
  952. [Fact]
  953. public void AwaitInLambdaInLock()
  954. {
  955. var source = @"
  956. using System.Threading.Tasks;
  957. class Test
  958. {
  959. static void Main()
  960. {
  961. lock (new object())
  962. {
  963. Task.Run(async () => { await Task.Factory.StartNew(() => { }); });
  964. Task.Run(async () => await Task.Factory.StartNew(() => { }));
  965. Task.Run(async delegate () { await Task.Factory.StartNew(() => { }); });
  966. }
  967. }
  968. }";
  969. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  970. }
  971. [Fact]
  972. public void BadAwaitInUnsafeContext()
  973. {
  974. var source = @"
  975. using System.Threading.Tasks;
  976. class Test
  977. {
  978. unsafe async static Task M1() {
  979. await Task.Factory.StartNew(() => { }); // not OK
  980. }
  981. async static Task M2()
  982. {
  983. await Task.Factory.StartNew(() => { }); // OK
  984. unsafe
  985. {
  986. await Task.Factory.StartNew(() => { }); // not OK
  987. }
  988. }
  989. }";
  990. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.UnsafeDll).VerifyDiagnostics(
  991. // (7,9): error CS4004: Cannot await in an unsafe context
  992. // await Task.Factory.StartNew(() => { }); // not OK
  993. Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Factory.StartNew(() => { })"),
  994. // (16,13): error CS4004: Cannot await in an unsafe context
  995. // await Task.Factory.StartNew(() => { }); // not OK
  996. Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Factory.StartNew(() => { })"));
  997. }
  998. [Fact]
  999. public void BadAwaitWithoutAsyncInBadContext()
  1000. {
  1001. var source = @"
  1002. using System.Threading.Tasks;
  1003. class Test
  1004. {
  1005. static Task M2()
  1006. {
  1007. await Task.Factory.StartNew(() => { });
  1008. unsafe
  1009. {
  1010. await Task.Factory.StartNew(() => { });
  1011. }
  1012. try
  1013. {
  1014. }
  1015. catch
  1016. {
  1017. await Task.Factory.StartNew(() => { });
  1018. }
  1019. finally
  1020. {
  1021. await Task.Factory.StartNew(() => { });
  1022. }
  1023. }
  1024. }";
  1025. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.UnsafeDll).VerifyDiagnostics(
  1026. // (8,9): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<System.Threading.Tasks.Task>'.
  1027. // await Task.Factory.StartNew(() => { });
  1028. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Factory.StartNew(() => { })").WithArguments("System.Threading.Tasks.Task").WithLocation(8, 9),
  1029. // (12,13): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<System.Threading.Tasks.Task>'.
  1030. // await Task.Factory.StartNew(() => { });
  1031. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Factory.StartNew(() => { })").WithArguments("System.Threading.Tasks.Task").WithLocation(12, 13),
  1032. // (12,13): error CS4004: Cannot await in an unsafe context
  1033. // await Task.Factory.StartNew(() => { });
  1034. Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Factory.StartNew(() => { })").WithLocation(12, 13),
  1035. // (20,13): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<System.Threading.Tasks.Task>'.
  1036. // await Task.Factory.StartNew(() => { });
  1037. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Factory.StartNew(() => { })").WithArguments("System.Threading.Tasks.Task").WithLocation(20, 13),
  1038. // (24,13): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<System.Threading.Tasks.Task>'.
  1039. // await Task.Factory.StartNew(() => { });
  1040. Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Factory.StartNew(() => { })").WithArguments("System.Threading.Tasks.Task").WithLocation(24, 13),
  1041. // (6,17): error CS0161: 'Test.M2()': not all code paths return a value
  1042. // static Task M2()
  1043. Diagnostic(ErrorCode.ERR_ReturnExpected, "M2").WithArguments("Test.M2()").WithLocation(6, 17)
  1044. );
  1045. }
  1046. [Fact]
  1047. public void AsyncExplicitInterfaceImplementation()
  1048. {
  1049. var source = @"
  1050. using System.Threading.Tasks;
  1051. interface IInterface
  1052. {
  1053. void F();
  1054. }
  1055. class C : IInterface
  1056. {
  1057. async void IInterface.F()
  1058. {
  1059. await Task.Factory.StartNew(() => { });
  1060. }
  1061. static void Main()
  1062. {
  1063. }
  1064. }";
  1065. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  1066. }
  1067. [Fact]
  1068. public void AsyncInterfaceMember()
  1069. {
  1070. var source = @"
  1071. interface IInterface
  1072. {
  1073. async void F();
  1074. }";
  1075. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1076. // (4,16): error CS0106: The modifier 'async' is not valid for this item
  1077. // async void F();
  1078. Diagnostic(ErrorCode.ERR_BadMemberFlag, "F").WithArguments("async"));
  1079. }
  1080. [Fact]
  1081. public void MainCantBeAsync()
  1082. {
  1083. var source = @"
  1084. using System.Threading.Tasks;
  1085. class A
  1086. {
  1087. async static void Main()
  1088. {
  1089. await Task.Factory.StartNew(() => { });
  1090. }
  1091. }";
  1092. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.Exe).VerifyDiagnostics(
  1093. // (4,23): error CS4009: 'A.Main()': an entry point cannot be marked with the 'async' modifier
  1094. // async static void Main()
  1095. Diagnostic(ErrorCode.ERR_MainCantBeAsync, "Main").WithArguments("A.Main()"));
  1096. }
  1097. [Fact]
  1098. public void MainCantBeAsync_AndGeneric()
  1099. {
  1100. var source = @"
  1101. using System.Threading.Tasks;
  1102. class A
  1103. {
  1104. async static void Main<T>()
  1105. {
  1106. await Task.Factory.StartNew(() => { });
  1107. }
  1108. }";
  1109. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.Exe).VerifyDiagnostics(
  1110. // (4,23): warning CS0402: 'A.Main<T>()': an entry point cannot be generic or in a generic type
  1111. // async static void Main<T>()
  1112. Diagnostic(ErrorCode.WRN_MainCantBeGeneric, "Main").WithArguments("A.Main<T>()"),
  1113. // error CS5001: Program does not contain a static 'Main' method suitable for an entry point
  1114. Diagnostic(ErrorCode.ERR_NoEntryPoint));
  1115. }
  1116. [Fact]
  1117. public void MainCantBeAsync_AndBadSig()
  1118. {
  1119. var source = @"
  1120. using System.Threading.Tasks;
  1121. class A
  1122. {
  1123. async static void Main(bool truth)
  1124. {
  1125. await Task.Factory.StartNew(() => { });
  1126. }
  1127. }";
  1128. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.Exe).VerifyDiagnostics(
  1129. // (4,23): warning CS0028: 'A.Main(bool)' has the wrong signature to be an entry point
  1130. // async static void Main(bool truth)
  1131. Diagnostic(ErrorCode.WRN_InvalidMainSig, "Main").WithArguments("A.Main(bool)"),
  1132. // error CS5001: Program does not contain a static 'Main' method suitable for an entry point
  1133. Diagnostic(ErrorCode.ERR_NoEntryPoint));
  1134. }
  1135. [Fact]
  1136. public void MainCantBeAsync_AndGeneric_AndBadSig()
  1137. {
  1138. var source = @"
  1139. using System.Threading.Tasks;
  1140. class A
  1141. {
  1142. async static void Main<T>(bool truth)
  1143. {
  1144. await Task.Factory.StartNew(() => { });
  1145. }
  1146. }";
  1147. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.Exe).VerifyDiagnostics(
  1148. // (4,23): warning CS0028: 'A.Main<T>(bool)' has the wrong signature to be an entry point
  1149. // async static void Main<T>(bool truth)
  1150. Diagnostic(ErrorCode.WRN_InvalidMainSig, "Main").WithArguments("A.Main<T>(bool)"),
  1151. // error CS5001: Program does not contain a static 'Main' method suitable for an entry point
  1152. Diagnostic(ErrorCode.ERR_NoEntryPoint));
  1153. }
  1154. [Fact]
  1155. public void AwaitInQuery_FirstCollectionExpressionOfInitialFrom()
  1156. {
  1157. var source = @"
  1158. using System.Linq;
  1159. using System.Collections.Generic;
  1160. using System.Threading.Tasks;
  1161. class Test
  1162. {
  1163. async static Task<List<int>> F1()
  1164. {
  1165. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1166. }
  1167. async static void F2()
  1168. {
  1169. await Task.Factory.StartNew(() => { });
  1170. var ls = new List<int>() {1, 2, 3};
  1171. var xs = from l in await F1() where l > 1 select l;
  1172. }
  1173. }";
  1174. CreateCompilationWithMscorlib45(source, new MetadataReference[] { SystemRef, LinqAssemblyRef }).VerifyDiagnostics();
  1175. }
  1176. [Fact]
  1177. public void AwaitInQuery_CollectionExpressionOfJoin()
  1178. {
  1179. var source = @"
  1180. using System.Linq;
  1181. using System.Collections.Generic;
  1182. using System.Threading.Tasks;
  1183. class Test
  1184. {
  1185. async static Task<List<int>> F1()
  1186. {
  1187. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1188. }
  1189. async static void F2()
  1190. {
  1191. await Task.Factory.StartNew(() => { });
  1192. var ls = new List<int>() {1, 2, 3};
  1193. var xs = from l in ls
  1194. join l2 in await F1() on l equals l2
  1195. where l > 1 select l;
  1196. }
  1197. }";
  1198. CreateCompilationWithMscorlib45(source, new MetadataReference[] { SystemRef, LinqAssemblyRef }).VerifyDiagnostics();
  1199. }
  1200. [Fact]
  1201. public void BadAwaitInQuery_QueryBody()
  1202. {
  1203. var source = @"
  1204. using System.Linq;
  1205. using System.Collections.Generic;
  1206. using System.Threading.Tasks;
  1207. class Test
  1208. {
  1209. async static Task<List<int>> F1()
  1210. {
  1211. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1212. }
  1213. async static void F2()
  1214. {
  1215. await Task.Factory.StartNew(() => { });
  1216. var ls = new List<int>() {1, 2, 3};
  1217. var xs = from l in ls
  1218. where l > 1 select await F1();
  1219. }
  1220. }";
  1221. CreateCompilationWithMscorlib45(source, new MetadataReference[]{ SystemRef, LinqAssemblyRef }).VerifyDiagnostics(
  1222. // (20,37): error CS1995: The 'await' operator may only be used in a query expression within the first collection expression of the initial 'from' clause or within the collection expression of a 'join' clause
  1223. // where l > 1 select await F1();
  1224. Diagnostic(ErrorCode.ERR_BadAwaitInQuery, "await F1()"));
  1225. }
  1226. [Fact]
  1227. public void BadAwaitInQuery_FirstCollectionExpressionOfInitialFrom_InsideQueryBody()
  1228. {
  1229. var source = @"
  1230. using System.Linq;
  1231. using System.Collections.Generic;
  1232. using System.Threading.Tasks;
  1233. class Test
  1234. {
  1235. async static Task<List<int>> F1()
  1236. {
  1237. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1238. }
  1239. async static void F2()
  1240. {
  1241. await Task.Factory.StartNew(() => { });
  1242. var ls = new List<int>() { 1, 2, 3 };
  1243. var xs = from l in ls
  1244. where l > 1
  1245. select (from l2 in await F1() where l2 > 1 select l2);
  1246. }
  1247. }";
  1248. CreateCompilationWithMscorlib45(source, new MetadataReference[] { SystemRef, LinqAssemblyRef }).VerifyDiagnostics(
  1249. // (21,37): error CS1995: The 'await' operator may only be used in a query expression within the first collection expression of the initial 'from' clause or within the collection expression of a 'join' clause
  1250. // select (from l2 in await F1() where l2 > 1 select l2);
  1251. Diagnostic(ErrorCode.ERR_BadAwaitInQuery, "await F1()"));
  1252. }
  1253. [Fact]
  1254. public void BadAwaitInQuery_CollectionExpressionOfJoin_InsideQueryBody()
  1255. {
  1256. var source = @"
  1257. using System.Linq;
  1258. using System.Collections.Generic;
  1259. using System.Threading.Tasks;
  1260. class Test
  1261. {
  1262. async static Task<List<int>> F1()
  1263. {
  1264. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1265. }
  1266. async static void F2()
  1267. {
  1268. await Task.Factory.StartNew(() => { });
  1269. var ls = new List<int>() { 1, 2, 3 };
  1270. var xs = from l in ls
  1271. where l > 1
  1272. select (from l2 in ls
  1273. join l3 in await F1() on l2 equals l3
  1274. where l2 > 1
  1275. select l2);
  1276. }
  1277. }";
  1278. CreateCompilationWithMscorlib45(source, new MetadataReference[] { SystemRef, LinqAssemblyRef }).VerifyDiagnostics(
  1279. // (22,37): error CS1995: The 'await' operator may only be used in a query expression within the first collection expression of the initial 'from' clause or within the collection expression of a 'join' clause
  1280. // join l3 in await F1() on l2 equals l3
  1281. Diagnostic(ErrorCode.ERR_BadAwaitInQuery, "await F1()"));
  1282. }
  1283. [Fact]
  1284. public void BadAwaitWithoutAsyncInUnsafeQuery()
  1285. {
  1286. var source = @"
  1287. using System.Linq;
  1288. using System.Collections.Generic;
  1289. using System.Threading.Tasks;
  1290. class Test
  1291. {
  1292. async static Task<List<int>>

Large files files are truncated, but you can click here to view the full file