PageRenderTime 73ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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>> F1()
  1293. {
  1294. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1295. }
  1296. static void F2()
  1297. {
  1298. var ls = new List<int>() { 1, 2, 3 };
  1299. unsafe
  1300. {
  1301. var xs = from l in ls
  1302. where l > 1
  1303. select (from l2 in ls
  1304. join l3 in await F1() on l2 equals l3
  1305. where l2 > 1
  1306. select l2);
  1307. }
  1308. }
  1309. }";
  1310. CreateCompilationWithMscorlib45(
  1311. source,
  1312. new MetadataReference[] { SystemRef, LinqAssemblyRef },
  1313. TestOptions.UnsafeDll).VerifyDiagnostics(
  1314. // (22,41): error CS4004: Cannot await in an unsafe context
  1315. // join l3 in await F1() on l2 equals l3
  1316. Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await F1()"),
  1317. // (22,41): 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
  1318. // join l3 in await F1() on l2 equals l3
  1319. Diagnostic(ErrorCode.ERR_BadAwaitInQuery, "await F1()"));
  1320. }
  1321. [Fact]
  1322. public void BadAwaitWithoutAsyncInQuery()
  1323. {
  1324. var source = @"
  1325. using System.Linq;
  1326. using System.Collections.Generic;
  1327. using System.Threading.Tasks;
  1328. class Test
  1329. {
  1330. async static Task<List<int>> F1()
  1331. {
  1332. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1333. }
  1334. static void F2()
  1335. {
  1336. var ls = new List<int>() { 1, 2, 3 };
  1337. var xs = from l in ls
  1338. where l > 1
  1339. select (from l2 in ls
  1340. join l3 in await F1() on l2 equals l3
  1341. where l2 > 1
  1342. select l2);
  1343. }
  1344. }";
  1345. CreateCompilationWithMscorlib45(
  1346. source,
  1347. new MetadataReference[] { SystemRef, LinqAssemblyRef },
  1348. TestOptions.UnsafeDll).VerifyDiagnostics(
  1349. // (22,41): 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
  1350. // join l3 in await F1() on l2 equals l3
  1351. Diagnostic(ErrorCode.ERR_BadAwaitInQuery, "await F1()"));
  1352. }
  1353. [Fact]
  1354. public void BadAwaitWithoutAsyncInLegalQueryRegion()
  1355. {
  1356. var source = @"
  1357. using System.Linq;
  1358. using System.Collections.Generic;
  1359. using System.Threading.Tasks;
  1360. class Test
  1361. {
  1362. async static Task<List<int>> F1()
  1363. {
  1364. return await Task.Factory.StartNew(() => new List<int>() { 1, 2, 3 });
  1365. }
  1366. static void F2()
  1367. {
  1368. var ls = new List<int>() { 1, 2, 3 };
  1369. var xs = from l in await F1()
  1370. where l > 1
  1371. select l;
  1372. }
  1373. }";
  1374. CreateCompilationWithMscorlib45(source, new MetadataReference[] { SystemRef, LinqAssemblyRef }).VerifyDiagnostics(
  1375. // (17,28): 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'.
  1376. // var xs = from l in await F1()
  1377. Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await F1()"));
  1378. }
  1379. [Fact]
  1380. public void AsyncLacksAwaits()
  1381. {
  1382. var source = @"
  1383. using System;
  1384. using System.Threading.Tasks;
  1385. class Test
  1386. {
  1387. async static Task M()
  1388. {
  1389. }
  1390. static void Main()
  1391. {
  1392. Action f1 = async () => new Action(() => { })();
  1393. Action f2 = async () => { };
  1394. Func<Task<int>> f3 = async () => { return 1; };
  1395. Action f4 = async delegate () { };
  1396. Func<Task<int>> f5 = async delegate () { return 1; };
  1397. }
  1398. }";
  1399. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1400. // (7,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.
  1401. // async static Task M()
  1402. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M"),
  1403. // (13,21): 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.
  1404. // Action f1 = async () => new Action(() => { })();
  1405. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => new Action(() => { })()"),
  1406. // (14,21): 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.
  1407. // Action f2 = async () => { };
  1408. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => { }"),
  1409. // (15,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.
  1410. // Func<Task<int>> f3 = async () => { return 1; };
  1411. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => { return 1; }"),
  1412. // (16,21): 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.
  1413. // Action f4 = async delegate () { };
  1414. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async delegate () { }"),
  1415. // (17,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.
  1416. // Func<Task<int>> f5 = async delegate () { return 1; };
  1417. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async delegate () { return 1; }"));
  1418. }
  1419. [Fact]
  1420. public void UnobservedAwaitableExpression()
  1421. {
  1422. var source = @"
  1423. using System.Threading.Tasks;
  1424. class Test
  1425. {
  1426. public static async Task F1()
  1427. {
  1428. await Task.Factory.StartNew(() => 1);
  1429. }
  1430. public static async Task<int> F2(bool truth)
  1431. {
  1432. for (F1(); truth; F1()) ;
  1433. for (F1(), F1(); truth; F1(), F1()) ;
  1434. return await Task.Factory.StartNew(() => 1);
  1435. }
  1436. static void Main()
  1437. {
  1438. F2(false);
  1439. }
  1440. }";
  1441. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1442. // (13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1443. // for (F1(); truth; F1()) ;
  1444. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1445. // (13,27): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1446. // for (F1(); truth; F1()) ;
  1447. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1448. // (15,14): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1449. // for (F1(), F1(); truth; F1(), F1()) ;
  1450. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1451. // (15,20): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1452. // for (F1(), F1(); truth; F1(), F1()) ;
  1453. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1454. // (15,33): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1455. // for (F1(), F1(); truth; F1(), F1()) ;
  1456. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1457. // (15,39): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1458. // for (F1(), F1(); truth; F1(), F1()) ;
  1459. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F1()"),
  1460. // (22,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1461. // F2(false);
  1462. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "F2(false)"));
  1463. }
  1464. [Fact]
  1465. public void UnobservedAwaitableExpression_ForgetAwait01()
  1466. {
  1467. // invoke a method that returns an awaitable type in an async method
  1468. var source = @"
  1469. using System.Threading.Tasks;
  1470. class Test
  1471. {
  1472. public async void Meth()
  1473. {
  1474. await Task.Delay(10);
  1475. Foo();
  1476. }
  1477. public async Task<int> Foo()
  1478. {
  1479. await Task.Delay(10);
  1480. return 1;
  1481. }
  1482. static int Main()
  1483. {
  1484. return 0;
  1485. }
  1486. }";
  1487. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1488. // (16,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1489. // Foo();
  1490. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  1491. }
  1492. [Fact]
  1493. public void UnobservedAwaitableExpression_ForgetAwait02()
  1494. {
  1495. // invoke a method that returns an awaitable type in an async method
  1496. var source = @"
  1497. using System.Threading.Tasks;
  1498. class Test
  1499. {
  1500. public async Task Meth()
  1501. {
  1502. Foo();
  1503. foreach (var x in new int[] { 1, 2 })
  1504. {
  1505. Foo();
  1506. }
  1507. while (await Foo())
  1508. {
  1509. Foo();
  1510. }
  1511. }
  1512. public async Task<dynamic> Foo()
  1513. {
  1514. return 1;
  1515. }
  1516. static int Main()
  1517. {
  1518. return 0;
  1519. }
  1520. }";
  1521. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  1522. // (19,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1523. // Foo();
  1524. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1525. // (22,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1526. // Foo();
  1527. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1528. // (27,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1529. // Foo();
  1530. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1531. // (31,32): 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.
  1532. // public async Task<dynamic> Foo()
  1533. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  1534. }
  1535. [Fact]
  1536. public void UnobservedAwaitableExpression_ForgetAwait03()
  1537. {
  1538. // invoke a method that returns an awaitable type in an async method
  1539. var source = @"
  1540. using System.Threading.Tasks;
  1541. public delegate Task<decimal?> Bar();
  1542. class Test
  1543. {
  1544. static async Task<object> Meth()
  1545. {
  1546. Foo();
  1547. Bar bar = Foo;
  1548. bar();
  1549. return (object)"""";
  1550. }
  1551. static async Task<decimal?> Foo()
  1552. {
  1553. return null;
  1554. }
  1555. static Task Meth2()
  1556. {
  1557. Foo();
  1558. Bar bar = Foo;
  1559. bar();
  1560. return Task.Run(async () => { await Task.Delay(10); });
  1561. }
  1562. static int Main()
  1563. {
  1564. return 0;
  1565. }
  1566. }";
  1567. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1568. // (21,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1569. // Foo();
  1570. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1571. // (24,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1572. // bar();
  1573. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "bar()"),
  1574. // (19,31): 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.
  1575. // static async Task<object> Meth()
  1576. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth"),
  1577. // (29,33): 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.
  1578. // static async Task<decimal?> Foo()
  1579. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"),
  1580. // (36,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1581. // Foo();
  1582. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  1583. }
  1584. [Fact]
  1585. public void UnobservedAwaitableExpression_ForgetAwait04()
  1586. {
  1587. // invoke a method that returns an awaitable type in an async method
  1588. var source = @"
  1589. using System.Threading.Tasks;
  1590. class C1{}
  1591. static class Extension
  1592. {
  1593. public static Task<C1> MethExt(this int i)
  1594. {
  1595. return Task.Run(async () => new C1());
  1596. }
  1597. }
  1598. class Test
  1599. {
  1600. static async Task<T> Meth<T>(T t)
  1601. {
  1602. int i = 0;
  1603. i.MethExt();
  1604. Foo(1);
  1605. return t;
  1606. }
  1607. static Task<T> Foo<T>(T t)
  1608. {
  1609. return Task.Run(async () => { return t; });
  1610. }
  1611. static int Main()
  1612. {
  1613. return 0;
  1614. }
  1615. }";
  1616. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1617. // (22,25): 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.
  1618. // return Task.Run(async () => new C1());
  1619. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => new C1()"),
  1620. // (28,26): 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.
  1621. // static async Task<T> Meth<T>(T t)
  1622. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth"),
  1623. // (31,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1624. // i.MethExt();
  1625. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "i.MethExt()"),
  1626. // (32,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1627. // Foo(1);
  1628. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo(1)"),
  1629. // (38,25): 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.
  1630. // return Task.Run(async () => { return t; });
  1631. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => { return t; }"));
  1632. }
  1633. [Fact]
  1634. public void UnobservedAwaitableExpression_ForgetAwait05()
  1635. {
  1636. // invoke a method that returns an awaitable type in an async method
  1637. var source = @"
  1638. using System;
  1639. using System.Threading.Tasks;
  1640. class Test
  1641. {
  1642. static async Task<dynamic> Meth1()
  1643. {
  1644. throw new EntryPointNotFoundException();
  1645. Foo();
  1646. return """";
  1647. }
  1648. static async Task<decimal?> Meth2()
  1649. {
  1650. Foo();
  1651. throw new DuplicateWaitObjectException();
  1652. return null;
  1653. }
  1654. static async Task<decimal?> Foo()
  1655. {
  1656. return null;
  1657. }
  1658. static int Main()
  1659. {
  1660. return 0;
  1661. }
  1662. }";
  1663. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  1664. // (20,32): 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.
  1665. // static async Task<dynamic> Meth1()
  1666. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth1"),
  1667. // (23,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1668. // Foo();
  1669. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1670. // (23,9): warning CS0162: Unreachable code detected
  1671. // Foo();
  1672. Diagnostic(ErrorCode.WRN_UnreachableCode, "Foo"),
  1673. // (27,33): 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.
  1674. // static async Task<decimal?> Meth2()
  1675. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth2"),
  1676. // (29,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1677. // Foo();
  1678. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1679. // (31,9): warning CS0162: Unreachable code detected
  1680. // return null;
  1681. Diagnostic(ErrorCode.WRN_UnreachableCode, "return"),
  1682. // (34,33): 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.
  1683. // static async Task<decimal?> Foo()
  1684. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  1685. }
  1686. [Fact]
  1687. public void UnobservedAwaitableExpression_ForgetAwait05_b()
  1688. {
  1689. // invoke a method that returns an awaitable type in an async method
  1690. var source = @"
  1691. using System.Threading.Tasks;
  1692. class Test
  1693. {
  1694. static async Task<dynamic> Meth1()
  1695. {
  1696. return """";
  1697. Foo();
  1698. }
  1699. static int Meth2()
  1700. {
  1701. return 2;
  1702. Foo();
  1703. }
  1704. static async Task<double?> Foo()
  1705. {
  1706. return null;
  1707. }
  1708. static int Main()
  1709. {
  1710. return 0;
  1711. }
  1712. }";
  1713. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  1714. // (22,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1715. // Foo();
  1716. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1717. // (19,32): 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.
  1718. // static async Task<dynamic> Meth1()
  1719. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth1"),
  1720. // (22,9): warning CS0162: Unreachable code detected
  1721. // Foo();
  1722. Diagnostic(ErrorCode.WRN_UnreachableCode, "Foo"),
  1723. // (28,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1724. // Foo();
  1725. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  1726. // (28,9): warning CS0162: Unreachable code detected
  1727. // Foo();
  1728. Diagnostic(ErrorCode.WRN_UnreachableCode, "Foo"),
  1729. // (31,32): 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.
  1730. // static async Task<double?> Foo()
  1731. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  1732. }
  1733. [Fact]
  1734. public void UnobservedAwaitableExpression_ForgetAwait06()
  1735. {
  1736. // invoke a method that returns an awaitable type in an async method
  1737. var source = @"
  1738. using System;
  1739. using System.Threading.Tasks;
  1740. class Test
  1741. {
  1742. static async Task<T> Meth<T>(T t)
  1743. {
  1744. await Task.Delay(10);
  1745. return t;
  1746. }
  1747. static async Task<T> Foo<T>(T t)
  1748. {
  1749. Func<Task<int>> f = async () =>
  1750. {
  1751. await Task.Delay(10);
  1752. Meth(1);
  1753. return 2;
  1754. };
  1755. f();
  1756. Func<Task<Func<Task<int>>>> ff = async delegate()
  1757. {
  1758. Meth((dynamic)5.1);
  1759. await Task.Delay(10);
  1760. return (Func<Task<int>>)(async () =>
  1761. {
  1762. Meth("""");
  1763. await Task.Delay(10);
  1764. return 3;
  1765. });
  1766. };
  1767. ff();
  1768. (await ff())();
  1769. return t;
  1770. }
  1771. static int Main()
  1772. {
  1773. return 0;
  1774. }
  1775. }";
  1776. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1777. // (30,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1778. // Meth(1);
  1779. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(1)"),
  1780. // (33,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1781. // f();
  1782. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "f()"),
  1783. // (41,25): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1784. // Meth("");
  1785. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""")"),
  1786. // (47,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1787. // ff();
  1788. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "ff()"),
  1789. // (49,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1790. // (await ff())();
  1791. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "(await ff())()"));
  1792. }
  1793. [Fact]
  1794. public void UnobservedAwaitableExpression_ForgetAwait07()
  1795. {
  1796. // invoke a method that returns an awaitable type in an async method
  1797. var source = @"
  1798. using System;
  1799. using System.Threading;
  1800. using System.Threading.Tasks;
  1801. struct MyDisp : IDisposable
  1802. {
  1803. public static int DisposeCalledCount;
  1804. public void Dispose()
  1805. {
  1806. DisposeCalledCount++;
  1807. TestCase.DisposeCalled++;
  1808. }
  1809. public MyDisp(int Count = 0)
  1810. {
  1811. DisposeCalledCount = 0;
  1812. }
  1813. }
  1814. class TestCase
  1815. {
  1816. private int tests;
  1817. public static int DisposeCalled;
  1818. public async Task Meth(MyDisp x)
  1819. {
  1820. await Task.Delay(10);
  1821. }
  1822. public async void Run()
  1823. {
  1824. this.tests = 0;
  1825. TestCase.DisposeCalled = 0;
  1826. //using statement inside async void sub
  1827. tests++;
  1828. using (var x = new MyDisp())
  1829. {
  1830. Meth(x);
  1831. }
  1832. if (MyDisp.DisposeCalledCount == TestCase.DisposeCalled)
  1833. Driver.Count++;
  1834. //using statement inside Task returning lambda
  1835. this.tests++;
  1836. Func<Task> f = async () =>
  1837. {
  1838. await Task.Delay(10);
  1839. using (var x = new MyDisp())
  1840. {
  1841. Meth(x);
  1842. }
  1843. };
  1844. f();
  1845. await f();
  1846. if (MyDisp.DisposeCalledCount == TestCase.DisposeCalled)
  1847. Driver.Count++;
  1848. //using statement inside Task<decimal> returning lambda
  1849. this.tests++;
  1850. Func<Task<decimal>> g = async () =>
  1851. {
  1852. await Task.Delay(10);
  1853. Meth(new MyDisp());
  1854. using (var x = new MyDisp())
  1855. {
  1856. Task.Run(async () =>
  1857. {
  1858. new Action<MyDisp>((y) => { })(x);
  1859. await Task.Delay(10);
  1860. });
  1861. }
  1862. return 1;
  1863. };
  1864. var t = await g();
  1865. if (MyDisp.DisposeCalledCount == TestCase.DisposeCalled && t == 1)
  1866. Driver.Count++;
  1867. Driver.Result = Driver.Count - this.tests;
  1868. //When test complete, set the flag.
  1869. Driver.CompletedSignal.Set();
  1870. }
  1871. }
  1872. class Driver
  1873. {
  1874. public static int Result = -1;
  1875. public static int Count = 0;
  1876. public static AutoResetEvent CompletedSignal = new AutoResetEvent(false);
  1877. static int Main()
  1878. {
  1879. var t = new TestCase();
  1880. t.Run();
  1881. CompletedSignal.WaitOne();
  1882. // 0 - success
  1883. // 1 - failed (test completed)
  1884. // -1 - failed (test incomplete - deadlock, etc)
  1885. return Driver.Result;
  1886. }
  1887. }";
  1888. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1889. // (55,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1890. // Meth(x);
  1891. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(x)"),
  1892. // (67,17): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1893. // Meth(x);
  1894. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(x)"),
  1895. // (70,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1896. // f();
  1897. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "f()"),
  1898. // (80,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1899. // Meth(new MyDisp());
  1900. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(new MyDisp())"),
  1901. // (83,17): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1902. // Task.Run(async () =>
  1903. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Task.Run(async () =>
  1904. {
  1905. new Action<MyDisp>((y) => { })(x);
  1906. await Task.Delay(10);
  1907. })"));
  1908. }
  1909. [Fact]
  1910. public void UnobservedAwaitableExpression_ForgetAwait08()
  1911. {
  1912. // invoke a method that returns an awaitable type in an async method
  1913. var source = @"
  1914. using System;
  1915. using System.Threading.Tasks;
  1916. class Test
  1917. {
  1918. static async Task<T> Meth<T>(T t)
  1919. {
  1920. await Task.Delay(10);
  1921. return t;
  1922. }
  1923. static async Task Foo()
  1924. {
  1925. try
  1926. {
  1927. Meth(1);
  1928. }
  1929. catch (Exception)
  1930. {
  1931. Meth("""");
  1932. }
  1933. finally
  1934. {
  1935. Meth((decimal?)2);
  1936. }
  1937. }
  1938. static int Main()
  1939. {
  1940. return 0;
  1941. }
  1942. }";
  1943. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  1944. // (28,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1945. // Meth(1);
  1946. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(1)"),
  1947. // (32,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1948. // Meth("");
  1949. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""")"),
  1950. // (36,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  1951. // Meth((decimal?)2);
  1952. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth((decimal?)2)"),
  1953. // (24,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.
  1954. // static async Task Foo()
  1955. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  1956. }
  1957. [Fact]
  1958. public void UnobservedAwaitableExpression_ForgetAwait09()
  1959. {
  1960. // invoke a method that returns an awaitable type in an async method
  1961. var source = @"
  1962. using System;
  1963. using System.Threading.Tasks;
  1964. static class Extension
  1965. {
  1966. public static async Task Meth<T>(this int i, T t)
  1967. {
  1968. await Task.Delay(10);
  1969. }
  1970. }
  1971. class Test
  1972. {
  1973. static async Task<T> Foo<T>(T t)
  1974. {
  1975. var i = 0;
  1976. Func<Task> f = async delegate()
  1977. {
  1978. await Task.Delay(10);
  1979. i.Meth(1);
  1980. };
  1981. Func<Task<Func<Task<int>>>> ff = async () =>
  1982. {
  1983. f();
  1984. await Task.Delay(10);
  1985. return (Func<Task<int>>)(async delegate()
  1986. {
  1987. i.Meth("""");
  1988. await Task.Delay(10);
  1989. return 3;
  1990. });
  1991. };
  1992. ff();
  1993. (await ff())();
  1994. return t;
  1995. }
  1996. static int Main()
  1997. {
  1998. return 0;
  1999. }
  2000. }";
  2001. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2002. // (33,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2003. // i.Meth(1);
  2004. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "i.Meth(1)"),
  2005. // (38,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2006. // f();
  2007. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "f()"),
  2008. // (42,17): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2009. // i.Meth("");
  2010. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"i.Meth("""")"),
  2011. // (48,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2012. // ff();
  2013. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "ff()"),
  2014. // (50,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2015. // (await ff())();
  2016. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "(await ff())()"));
  2017. }
  2018. [Fact]
  2019. public void UnobservedAwaitableExpression_ForgetAwait10()
  2020. {
  2021. // invoke a method that returns an awaitable type in an async method
  2022. var source = @"
  2023. using System.Threading.Tasks;
  2024. class Test
  2025. {
  2026. async Task<T> Meth<T>(T t)
  2027. {
  2028. await Task.Delay(10);
  2029. return t;
  2030. }
  2031. private Task field;
  2032. public Task Prop
  2033. {
  2034. get
  2035. {
  2036. Meth(1);
  2037. return field;
  2038. }
  2039. set
  2040. {
  2041. Bar();
  2042. Meth("""");
  2043. field = value;
  2044. }
  2045. }
  2046. public async Task Foo()
  2047. {
  2048. await Bar();
  2049. Bar(); //the callee return type is dynamic, it will not give warning
  2050. Meth((decimal?)null);
  2051. }
  2052. public dynamic Bar()
  2053. {
  2054. return Task.Run<int>(async () => { await Task.Delay(10); return 2; });
  2055. }
  2056. static int Main()
  2057. {
  2058. return 0;
  2059. }
  2060. }";
  2061. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  2062. // (30,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2063. // Meth(1);
  2064. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(1)"),
  2065. // (36,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2066. // Meth("");
  2067. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""")"),
  2068. // (45,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2069. // Meth((decimal?)null);
  2070. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth((decimal?)null)"));
  2071. }
  2072. [Fact]
  2073. public void UnobservedAwaitableExpression_ForgetAwait11()
  2074. {
  2075. // invoke a method that returns an awaitable type in an async method
  2076. var source = @"
  2077. using System.Threading.Tasks;
  2078. partial class Test
  2079. {
  2080. partial void Bar();
  2081. public async Task<T> Meth<T>(params T[] t)
  2082. {
  2083. await Task.Delay(10);
  2084. return t[0];
  2085. }
  2086. }
  2087. partial class Test
  2088. {
  2089. async partial void Bar()
  2090. {
  2091. await Task.Delay(10);
  2092. Meth("""", null);
  2093. }
  2094. async public Task Foo()
  2095. {
  2096. Bar();
  2097. Meth(Task.Run(async () => 1), Meth(1));
  2098. }
  2099. static int Main()
  2100. {
  2101. return 0;
  2102. }
  2103. }";
  2104. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2105. // (30,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2106. // Meth("", null);
  2107. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""", null)"),
  2108. // (36,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.
  2109. // Meth(Task.Run(async () => 1), Meth(1));
  2110. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => 1"),
  2111. // (36,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2112. // Meth(Task.Run(async () => 1), Meth(1));
  2113. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(Task.Run(async () => 1), Meth(1))"),
  2114. // (33,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.
  2115. // async public Task Foo()
  2116. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  2117. }
  2118. [WorkItem(611150, "DevDiv")]
  2119. [Fact]
  2120. public void UnobservedAwaitableExpression_ForgetAwait12()
  2121. {
  2122. var source = @"
  2123. using System.Threading.Tasks;
  2124. class Test
  2125. {
  2126. static async Task<T> Meth<T>(T t)
  2127. {
  2128. await Task.Delay(10);
  2129. return t;
  2130. }
  2131. static async Task Foo()
  2132. {
  2133. checked
  2134. {
  2135. Meth(await Meth(int.MaxValue) + 1);
  2136. }
  2137. unchecked
  2138. {
  2139. Meth(long.MinValue - 1);
  2140. }
  2141. var str = """";
  2142. lock (str)
  2143. {
  2144. Meth((int?)null);
  2145. }
  2146. lock (Meth(""""))
  2147. {
  2148. Task.Run(async () => { await Task.Delay(10); return """"; });
  2149. }
  2150. }
  2151. static int Main()
  2152. {
  2153. return 0;
  2154. }
  2155. }";
  2156. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2157. // (16,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2158. // Meth(await Meth(int.MaxValue) + 1);
  2159. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(await Meth(int.MaxValue) + 1)"),
  2160. // (20,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2161. // Meth(long.MinValue - 1);
  2162. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(long.MinValue - 1)"),
  2163. // (26,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2164. // Meth((int?)null);
  2165. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth((int?)null)"));
  2166. }
  2167. [WorkItem(611150, "DevDiv")]
  2168. [Fact]
  2169. public void UnobservedAwaitableExpression_ForgetAwait12_breaking()
  2170. {
  2171. // The native compiler gives a warning on the un-awaited async invocation. However, awaiting inside the lock
  2172. // would escalate the warning to an error. Roslyn does not give a warning.
  2173. var source = @"
  2174. using System.Threading.Tasks;
  2175. class Test
  2176. {
  2177. static async Task Foo()
  2178. {
  2179. await Task.Factory.StartNew(() => { });
  2180. lock (new object())
  2181. {
  2182. Task.Run(async () => { await Task.Delay(10); return """"; });
  2183. }
  2184. }
  2185. }";
  2186. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  2187. }
  2188. [Fact]
  2189. public void UnobservedAwaitableExpression_ForgetAwait13()
  2190. {
  2191. // invoke a method that returns an awaitable type in an async method
  2192. // 1. the callee is a property/indexer that returns Task/Task<T>
  2193. // 2. invoke the method in the constructor
  2194. var source = @"
  2195. using System.Threading.Tasks;
  2196. class Test
  2197. {
  2198. public Task Prop
  2199. {
  2200. get { return Task.Run(async () => { await Task.Delay(10); }); }
  2201. }
  2202. public Task<int> this[dynamic index]
  2203. {
  2204. get
  2205. {
  2206. return Task.Run<int>(async () => { await Task.Delay(10); return index; });
  2207. }
  2208. }
  2209. public async Task<T> Meth<T>(T t)
  2210. {
  2211. await Task.Delay(10);
  2212. return t;
  2213. }
  2214. public Test()
  2215. {
  2216. Meth(1); //warning CS4014
  2217. }
  2218. public async Task Foo()
  2219. {
  2220. var test = new Test();
  2221. test.Prop; //error CS0201
  2222. test[1]; //error CS0201
  2223. }
  2224. static int Main()
  2225. {
  2226. return 0;
  2227. }
  2228. }";
  2229. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  2230. // (41,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2231. // Meth(1); //warning CS4014
  2232. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(1)"),
  2233. // (47,9): error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
  2234. // test.Prop; //error CS0201
  2235. Diagnostic(ErrorCode.ERR_IllegalStatement, "test.Prop"),
  2236. // (48,9): error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
  2237. // test[1]; //error CS0201
  2238. Diagnostic(ErrorCode.ERR_IllegalStatement, "test[1]"),
  2239. // (44,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.
  2240. // public async Task Foo()
  2241. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  2242. }
  2243. [Fact]
  2244. public void UnobservedAwaitableExpression_ForgetAwait14()
  2245. {
  2246. // invoke a method that returns an awaitable type in async/non-async method
  2247. var source = @"
  2248. using System.Threading.Tasks;
  2249. class Test
  2250. {
  2251. static async Task<T> Meth<T>(T t)
  2252. {
  2253. await Task.Delay(10);
  2254. return t;
  2255. }
  2256. static async Task Foo()
  2257. {
  2258. for (Meth(""""); await Meth(false); Meth((float?)null))
  2259. {
  2260. Meth(1);
  2261. }
  2262. }
  2263. static Task<int> Bar()
  2264. {
  2265. for (Meth(5m); ; Meth(""""))
  2266. {
  2267. Meth((string)null);
  2268. }
  2269. }
  2270. static int Main()
  2271. {
  2272. return 0;
  2273. }
  2274. }";
  2275. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2276. // (27,14): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2277. // for (Meth(""); await Meth(false); Meth((float?)null))
  2278. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""")"),
  2279. // (27,43): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2280. // for (Meth(""); await Meth(false); Meth((float?)null))
  2281. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth((float?)null)"),
  2282. // (29,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2283. // Meth(1);
  2284. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(1)"),
  2285. // (35,14): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2286. // for (Meth(5m); ; Meth(""))
  2287. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth(5m)"),
  2288. // (35,26): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2289. // for (Meth(5m); ; Meth(""))
  2290. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, @"Meth("""")"),
  2291. // (37,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2292. // Meth((string)null);
  2293. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Meth((string)null)"));
  2294. }
  2295. [Fact]
  2296. public void UnobservedAwaitableExpression_ForgetAwait15()
  2297. {
  2298. // invoke a method that returns an awaitable type in async/non-async method
  2299. var source = @"
  2300. using System.Threading.Tasks;
  2301. public class TestB
  2302. {
  2303. public async Task<T> Meth<T>(T t = default(T))
  2304. {
  2305. await Task.Delay(10);
  2306. return t;
  2307. }
  2308. public async Task Meth2()
  2309. {
  2310. await Task.Delay(10);
  2311. }
  2312. }
  2313. public class Test
  2314. {
  2315. public async Task Foo()
  2316. {
  2317. var testB = new TestB();
  2318. for (testB.Meth2(); await testB.Meth(false); testB.Meth((float?)null))
  2319. {
  2320. testB.Meth(1);
  2321. }
  2322. }
  2323. public void Bar()
  2324. {
  2325. //if the awaitable method was compiled into a library, the warning will not give
  2326. var testB = new TestB();
  2327. testB.Meth<decimal>();
  2328. testB.Meth2();
  2329. }
  2330. static int Main()
  2331. {
  2332. return 0;
  2333. }
  2334. }";
  2335. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2336. // (33,14): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2337. // for (testB.Meth2(); await testB.Meth(false); testB.Meth((float?)null))
  2338. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "testB.Meth2()"),
  2339. // (33,54): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2340. // for (testB.Meth2(); await testB.Meth(false); testB.Meth((float?)null))
  2341. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "testB.Meth((float?)null)"),
  2342. // (35,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2343. // testB.Meth(1);
  2344. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "testB.Meth(1)"),
  2345. // (43,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2346. // testB.Meth<decimal>();
  2347. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "testB.Meth<decimal>()"),
  2348. // (44,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2349. // testB.Meth2();
  2350. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "testB.Meth2()"));
  2351. }
  2352. [Fact]
  2353. public void UnobservedAwaitableExpression_ForgetAwait16()
  2354. {
  2355. // invoke a method that returns an awaitable type in an non-async method
  2356. var source = @"
  2357. using System.Threading.Tasks;
  2358. class Test
  2359. {
  2360. public void Meth()
  2361. {
  2362. Foo();
  2363. }
  2364. public async Task<int> Foo()
  2365. {
  2366. await Task.Delay(10);
  2367. return 1;
  2368. }
  2369. static int Main()
  2370. {
  2371. return 0;
  2372. }
  2373. }";
  2374. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2375. // (15,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2376. // Foo();
  2377. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  2378. }
  2379. [Fact]
  2380. public void UnobservedAwaitableExpression_ForgetAwait17()
  2381. {
  2382. // invoke a method that returns an awaitable type in an non-async method
  2383. var source = @"
  2384. using System;
  2385. using System.Threading.Tasks;
  2386. static class Extension
  2387. {
  2388. public static async Task<int> ExMeth(this string str)
  2389. {
  2390. await Task.Delay(10);
  2391. return str.Length;
  2392. }
  2393. }
  2394. class Test:IDisposable
  2395. {
  2396. public void Dispose() { }
  2397. static int Main()
  2398. {
  2399. using (Test test = new Test())
  2400. {
  2401. string s=""abc"";
  2402. s.ExMeth();
  2403. }
  2404. return 0;
  2405. }
  2406. }";
  2407. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2408. // (29,14): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2409. // s.ExMeth();
  2410. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "s.ExMeth()"));
  2411. }
  2412. [Fact]
  2413. public void UnobservedAwaitableExpression_ForgetAwait18()
  2414. {
  2415. // invoke a method that returns an awaitable type in an non-async method
  2416. var source = @"
  2417. using System.Threading.Tasks;
  2418. class Test
  2419. {
  2420. public delegate T Del<T>(T item);
  2421. public T Meth<T>(T t)
  2422. {
  2423. Foo();
  2424. Del<int> del = x =>
  2425. {
  2426. Foo();
  2427. return 1;
  2428. };
  2429. return t;
  2430. }
  2431. static async Task<Task> Foo()
  2432. {
  2433. await Task.Delay(10);
  2434. return new Task(() => { Task.Delay(10); });
  2435. }
  2436. static int Main()
  2437. {
  2438. return 0;
  2439. }
  2440. }";
  2441. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2442. // (18,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2443. // Foo();
  2444. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  2445. // (21,17): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2446. // Foo();
  2447. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  2448. }
  2449. [Fact]
  2450. public void UnobservedAwaitableExpression_ForgetAwait19()
  2451. {
  2452. // invoke a method that returns an awaitable type in an non-async method
  2453. var source = @"
  2454. using System.Threading.Tasks;
  2455. class Test
  2456. {
  2457. public delegate T Del<T>();
  2458. public T Meth<T>(T t)
  2459. {
  2460. Foo();
  2461. Del<Task<string>> del =async delegate()
  2462. {
  2463. await Task.Delay(10);
  2464. Foo();
  2465. Del<int> del2 = () =>
  2466. {
  2467. Foo();
  2468. return 1;
  2469. };
  2470. return """";
  2471. };
  2472. del();
  2473. return t;
  2474. }
  2475. public Task Foo()
  2476. {
  2477. return Task.Run(async() =>
  2478. {
  2479. await Task.Delay(10);
  2480. });
  2481. }
  2482. static int Main()
  2483. {
  2484. return 0;
  2485. }
  2486. }";
  2487. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2488. // (21,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2489. // Foo();
  2490. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  2491. }
  2492. [Fact]
  2493. public void UnobservedAwaitableExpression_ForgetAwait20()
  2494. {
  2495. // invoke a method that returns an awaitable type in an non-async method
  2496. var source = @"
  2497. using System;
  2498. using System.Threading.Tasks;
  2499. class Test { }
  2500. class Testcase
  2501. {
  2502. static Test test = null;
  2503. public void Meth()
  2504. {
  2505. Foo();
  2506. Func<Task<Test>> fun = () =>
  2507. {
  2508. return Foo();
  2509. };
  2510. }
  2511. public Task<Test> Foo()
  2512. {
  2513. return Task.Run<Test>( () =>
  2514. {
  2515. if (test == null)
  2516. test = new Test();
  2517. return test;
  2518. }
  2519. );
  2520. }
  2521. static int Main()
  2522. {
  2523. return 0;
  2524. }
  2525. }";
  2526. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  2527. }
  2528. [Fact]
  2529. public void UnobservedAwaitableExpression_ForgetAwait21()
  2530. {
  2531. var source = @"
  2532. using System;
  2533. using System.Threading.Tasks;
  2534. class Test
  2535. {
  2536. delegate Task<dynamic> Del(dynamic d = null);
  2537. public void Meth()
  2538. {
  2539. Del del = async x =>
  2540. {
  2541. await Task.Delay(10);
  2542. return 1;
  2543. };
  2544. del();
  2545. Func<int,Task<Func<dynamic>>> func =async y =>
  2546. {
  2547. await Task.Delay(10);
  2548. del(y);
  2549. return (delegate() { return 1; });
  2550. };
  2551. func(1);
  2552. }
  2553. static int Main()
  2554. {
  2555. return 0;
  2556. }
  2557. }";
  2558. CreateCompilationWithMscorlib45(source, references: new MetadataReference[] { CSharpRef, SystemCoreRef }).VerifyDiagnostics(
  2559. // (27,17): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2560. // del(y);
  2561. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "del(y)"));
  2562. }
  2563. [Fact]
  2564. public void UnobservedAwaitableExpression_ForgetAwait22()
  2565. {
  2566. var source = @"
  2567. using System;
  2568. using System.Threading.Tasks;
  2569. class Test
  2570. {
  2571. public void Meth()
  2572. {
  2573. Func<Task<string>> Foo = async () =>
  2574. {
  2575. await Task.Delay(10);
  2576. return """";
  2577. };
  2578. Foo();
  2579. Task.Run(() =>
  2580. {
  2581. Foo();
  2582. Func<Task<Task>> fun = async () =>
  2583. {
  2584. await Task.Delay(10);
  2585. return Task.Run(() =>
  2586. {
  2587. Foo();
  2588. });
  2589. };
  2590. });
  2591. }
  2592. static int Main()
  2593. {
  2594. return 0;
  2595. }
  2596. }";
  2597. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  2598. }
  2599. [Fact]
  2600. public void UnobservedAwaitableExpression_ForgetAwait23()
  2601. {
  2602. var source = @"
  2603. using System.Threading.Tasks;
  2604. class Test
  2605. {
  2606. delegate Task<string> Del();
  2607. delegate void Del2();
  2608. public void Meth()
  2609. {
  2610. Del del = async delegate()
  2611. {
  2612. await Task.Delay(10);
  2613. return """";
  2614. };
  2615. del();
  2616. Del2 del2 = delegate()
  2617. {
  2618. del();
  2619. Del del3 = async () =>
  2620. {
  2621. await Task.Delay(10);
  2622. Del2 del4 = delegate()
  2623. {
  2624. del();
  2625. };
  2626. return """";
  2627. };
  2628. del3();
  2629. };
  2630. }
  2631. static int Main()
  2632. {
  2633. return 0;
  2634. }
  2635. }";
  2636. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  2637. }
  2638. [Fact]
  2639. public void UnobservedAwaitableExpression_ForgetAwait24()
  2640. {
  2641. var source = @"
  2642. using System;
  2643. using System.Threading.Tasks;
  2644. static class Extension
  2645. {
  2646. public static Task<int> ExMeth(this int i)
  2647. {
  2648. Func<Task<int>> Foo = async () =>
  2649. {
  2650. await Task.Delay(10);
  2651. return ++i;
  2652. };
  2653. return (Task<int>) Foo();
  2654. }
  2655. }
  2656. class Test
  2657. {
  2658. public static int amount=0;
  2659. static int Main()
  2660. {
  2661. lock (amount.ExMeth())
  2662. {
  2663. amount.ExMeth();
  2664. }
  2665. return 0;
  2666. }
  2667. }";
  2668. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  2669. }
  2670. [Fact]
  2671. public void UnobservedAwaitableExpression_ForgetAwait25()
  2672. {
  2673. var source = @"
  2674. using System.Threading.Tasks;
  2675. class Test
  2676. {
  2677. public async Task<int> Meth()
  2678. {
  2679. await Task.Delay(10);
  2680. return int.MaxValue;
  2681. }
  2682. public Task<int> Foo()
  2683. {
  2684. int i = int.MaxValue;
  2685. return Task.Run(async () => { return i; });
  2686. }
  2687. static int Main()
  2688. {
  2689. Test test = new Test();
  2690. checked
  2691. {
  2692. test.Meth();
  2693. test.Foo();
  2694. }
  2695. unchecked
  2696. {
  2697. test.Meth();
  2698. test.Foo();
  2699. }
  2700. return 0;
  2701. }
  2702. }";
  2703. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2704. // (24,25): 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.
  2705. // return Task.Run(async () => { return i; });
  2706. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => { return i; }"),
  2707. // (31,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2708. // test.Meth();
  2709. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "test.Meth()"),
  2710. // (36,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2711. // test.Meth();
  2712. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "test.Meth()"));
  2713. }
  2714. [Fact]
  2715. public void UnobservedAwaitableExpression_ForgetAwait26()
  2716. {
  2717. var source = @"
  2718. using System;
  2719. using System.Threading.Tasks;
  2720. class Testcase
  2721. {
  2722. ~Testcase()
  2723. {
  2724. Foo();
  2725. Foo2();
  2726. }
  2727. public async Task<string> Foo()
  2728. {
  2729. await Task.Delay(10);
  2730. return ""Foo"";
  2731. }
  2732. public Task Foo2()
  2733. {
  2734. return Task.Run(() => { });
  2735. }
  2736. }
  2737. class Test
  2738. {
  2739. static int Main()
  2740. {
  2741. Object obj = new Testcase();
  2742. obj = null;
  2743. GC.Collect();
  2744. GC.WaitForPendingFinalizers();
  2745. return 0;
  2746. }
  2747. }";
  2748. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2749. // (17,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2750. // Foo();
  2751. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"));
  2752. }
  2753. [Fact]
  2754. public void UnobservedAwaitableExpression_ForgetAwait27()
  2755. {
  2756. var source = @"
  2757. using System;
  2758. using System.Threading.Tasks;
  2759. class Test : IDisposable
  2760. {
  2761. public async Task Foo()
  2762. {
  2763. await Task.Delay(10);
  2764. }
  2765. public void Dispose()
  2766. {
  2767. Foo();
  2768. }
  2769. static int Main()
  2770. {
  2771. using (Test test = new Test())
  2772. {
  2773. test.Foo();
  2774. }
  2775. return 0;
  2776. }
  2777. }
  2778. ";
  2779. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2780. // (22,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2781. // Foo();
  2782. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "Foo()"),
  2783. // (28,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  2784. // test.Foo();
  2785. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "test.Foo()"));
  2786. }
  2787. [Fact]
  2788. public void BadAsyncMethodWithNoStatementBody()
  2789. {
  2790. var source = @"
  2791. using System.Threading.Tasks;
  2792. static class Test
  2793. {
  2794. static async Task M1();
  2795. }";
  2796. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2797. // (6,23): error CS1994: The 'async' modifier can only be used in methods that have a statement body
  2798. // static async Task M1();
  2799. Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M1"));
  2800. }
  2801. [Fact]
  2802. public void BadAsyncMethodWithVarargsAndNoStatementBody()
  2803. {
  2804. var source = @"
  2805. using System.Threading.Tasks;
  2806. static class Test
  2807. {
  2808. static async Task M1(__arglist);
  2809. }";
  2810. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2811. // (6,23): error CS1994: The 'async' modifier can only be used in methods that have a statement body
  2812. // static async Task M1(__arglist);
  2813. Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M1"));
  2814. }
  2815. [Fact]
  2816. public void BadSpecialByRefParameter()
  2817. {
  2818. var source = @"
  2819. using System.Threading.Tasks;
  2820. using System;
  2821. class Test
  2822. {
  2823. async Task M1(TypedReference tr)
  2824. {
  2825. await Task.Factory.StartNew(() => { });
  2826. }
  2827. }";
  2828. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2829. // (7,34): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or lambda expressions
  2830. // async Task M1(TypedReference tr)
  2831. Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "tr").WithArguments("System.TypedReference"));
  2832. }
  2833. [Fact]
  2834. public void BadSpecialByRefLocal()
  2835. {
  2836. var source = @"
  2837. using System.Threading.Tasks;
  2838. using System;
  2839. class Test
  2840. {
  2841. async Task M1()
  2842. {
  2843. TypedReference tr;
  2844. await Task.Factory.StartNew(() => { });
  2845. }
  2846. }";
  2847. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2848. // (9,9): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or lambda expressions
  2849. // TypedReference tr;
  2850. Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "TypedReference").WithArguments("System.TypedReference"),
  2851. // (9,24): warning CS0168: The variable 'tr' is declared but never used
  2852. // TypedReference tr;
  2853. Diagnostic(ErrorCode.WRN_UnreferencedVar, "tr").WithArguments("tr"));
  2854. }
  2855. [Fact]
  2856. public void BadSpecialByRefVarDeclLocal()
  2857. {
  2858. var source = @"
  2859. using System.Threading.Tasks;
  2860. using System;
  2861. class Test
  2862. {
  2863. async Task M1(bool truth)
  2864. {
  2865. var tr = new TypedReference();
  2866. await Task.Factory.StartNew(() => { });
  2867. }
  2868. }";
  2869. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2870. // (9,9): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or lambda expressions
  2871. // var tr = new TypedReference();
  2872. Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.TypedReference"),
  2873. // (9,13): warning CS0219: The variable 'tr' is assigned but its value is never used
  2874. // var tr = new TypedReference();
  2875. Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "tr").WithArguments("tr"));
  2876. }
  2877. [Fact]
  2878. public void BadFixedSpecialByRefLocal()
  2879. {
  2880. var source = @"
  2881. using System;
  2882. public class MyClass
  2883. {
  2884. unsafe async public static void F()
  2885. {
  2886. fixed (TypedReference tr) { }
  2887. }
  2888. }";
  2889. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.UnsafeDll).VerifyDiagnostics(
  2890. // (8,31): error CS0209: The type of a local declared in a fixed statement must be a pointer type
  2891. // fixed (TypedReference tr) { }
  2892. Diagnostic(ErrorCode.ERR_BadFixedInitType, "tr"),
  2893. // (8,16): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or lambda expressions.
  2894. // fixed (TypedReference tr) { }
  2895. Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "TypedReference").WithArguments("System.TypedReference"),
  2896. // (8,31): error CS0210: You must provide an initializer in a fixed or using statement declaration
  2897. // fixed (TypedReference tr) { }
  2898. Diagnostic(ErrorCode.ERR_FixedMustInit, "tr"),
  2899. // (6,37): 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.
  2900. // unsafe async public static void F()
  2901. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "F"));
  2902. }
  2903. [Fact]
  2904. public void AsyncInSecurityCriticalClass()
  2905. {
  2906. var source = @"
  2907. using System.Security;
  2908. using System.Threading.Tasks;
  2909. [SecurityCritical]
  2910. public class C
  2911. {
  2912. public async void M()
  2913. {
  2914. await Task.Factory.StartNew(() => { });
  2915. }
  2916. }";
  2917. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2918. // (8,23): error CS4031: Async methods are not allowed in an Interface, Class, or Structure which has the 'SecurityCritical' or 'SecuritySafeCritical' attribute.
  2919. // public async void M()
  2920. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct, "M"));
  2921. }
  2922. [Fact]
  2923. public void AsyncInSecuritySafeCriticalClass()
  2924. {
  2925. var source = @"
  2926. using System.Security;
  2927. using System.Threading.Tasks;
  2928. [SecuritySafeCritical]
  2929. public class C
  2930. {
  2931. public async void M()
  2932. {
  2933. await Task.Factory.StartNew(() => { });
  2934. }
  2935. }";
  2936. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2937. // (8,23): error CS4031: Async methods are not allowed in an Interface, Class, or Structure which has the 'SecurityCritical' or 'SecuritySafeCritical' attribute.
  2938. // public async void M()
  2939. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct, "M"));
  2940. }
  2941. [Fact]
  2942. public void AsyncInSecuritySafeCriticalAndSecurityCriticalClass()
  2943. {
  2944. var source = @"
  2945. using System.Security;
  2946. using System.Threading.Tasks;
  2947. [SecurityCritical]
  2948. [SecuritySafeCritical]
  2949. public class C
  2950. {
  2951. public async void M()
  2952. {
  2953. await Task.Factory.StartNew(() => { });
  2954. }
  2955. }";
  2956. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2957. // (9,23): error CS4031: Async methods are not allowed in an Interface, Class, or Structure which has the 'SecurityCritical' or 'SecuritySafeCritical' attribute.
  2958. // public async void M()
  2959. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct, "M"));
  2960. }
  2961. [Fact]
  2962. public void AsyncInDoublyNestedSecuritySafeCriticalAndSecurityCriticalClasses()
  2963. {
  2964. var source = @"
  2965. using System.Security;
  2966. using System.Threading.Tasks;
  2967. [SecurityCritical]
  2968. [SecuritySafeCritical]
  2969. public class C
  2970. {
  2971. [SecuritySafeCritical]
  2972. public class D
  2973. {
  2974. public async void M()
  2975. {
  2976. await Task.Factory.StartNew(() => { });
  2977. }
  2978. }
  2979. }";
  2980. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  2981. // (12,27): error CS4031: Async methods are not allowed in an Interface, Class, or Structure which has the 'SecurityCritical' or 'SecuritySafeCritical' attribute.
  2982. // public async void M()
  2983. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct, "M"));
  2984. }
  2985. [Fact]
  2986. public void SecurityCriticalOnAsync()
  2987. {
  2988. var source = @"
  2989. using System.Security;
  2990. using System.Threading.Tasks;
  2991. public class D
  2992. {
  2993. [SecurityCritical]
  2994. public async void M()
  2995. {
  2996. await Task.Factory.StartNew(() => { });
  2997. }
  2998. }";
  2999. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3000. // (7,6): error CS4030: Security attribute 'SecurityCritical' cannot be applied to an Async method.
  3001. // [SecurityCritical]
  3002. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecurityCritical").WithArguments("SecurityCritical"));
  3003. }
  3004. [Fact]
  3005. public void SecuritySafeCriticalOnAsync()
  3006. {
  3007. var source = @"
  3008. using System.Security;
  3009. using System.Threading.Tasks;
  3010. public class D
  3011. {
  3012. [SecuritySafeCritical]
  3013. public async void M()
  3014. {
  3015. await Task.Factory.StartNew(() => { });
  3016. }
  3017. }";
  3018. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3019. // (7,6): error CS4030: Security attribute 'SecuritySafeCritical' cannot be applied to an Async method.
  3020. // [SecuritySafeCritical]
  3021. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecuritySafeCritical").WithArguments("SecuritySafeCritical"));
  3022. }
  3023. [Fact]
  3024. public void SecuritySafeCriticalAndSecurityCriticalOnAsync()
  3025. {
  3026. var source = @"
  3027. using System.Security;
  3028. using System.Threading.Tasks;
  3029. public class D
  3030. {
  3031. [SecurityCritical]
  3032. [SecuritySafeCritical]
  3033. public async void M()
  3034. {
  3035. await Task.Factory.StartNew(() => { });
  3036. }
  3037. }";
  3038. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3039. // (7,6): error CS4030: Security attribute 'SecurityCritical' cannot be applied to an Async method.
  3040. // [SecurityCritical]
  3041. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecurityCritical").WithArguments("SecurityCritical"),
  3042. // (8,6): error CS4030: Security attribute 'SecuritySafeCritical' cannot be applied to an Async method.
  3043. // [SecuritySafeCritical]
  3044. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecuritySafeCritical").WithArguments("SecuritySafeCritical"));
  3045. }
  3046. [Fact, WorkItem(547077, "DevDiv")]
  3047. public void Repro_17880()
  3048. {
  3049. var source = @"
  3050. class Program
  3051. {
  3052. async void Meth()
  3053. {
  3054. }
  3055. }";
  3056. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3057. // (4,16): 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.
  3058. // async void Meth()
  3059. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Meth"));
  3060. }
  3061. [Fact, WorkItem(547079, "DevDiv")]
  3062. public void Repro_17883()
  3063. {
  3064. var source = @"
  3065. abstract class Base
  3066. {
  3067. public async abstract void M1();
  3068. }
  3069. class Test
  3070. {
  3071. public static int Main()
  3072. {
  3073. return 1;
  3074. }
  3075. }";
  3076. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3077. // (4,32): error CS1994: The 'async' modifier can only be used in methods that have a statement body.
  3078. // public async abstract void M1();
  3079. Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M1"));
  3080. }
  3081. [Fact, WorkItem(547081, "DevDiv")]
  3082. public void Repro_17885()
  3083. {
  3084. var source = @"
  3085. class Test
  3086. {
  3087. async public static void Main()
  3088. {
  3089. }
  3090. }";
  3091. CreateCompilationWithMscorlib45(source, compOptions: TestOptions.Exe).VerifyDiagnostics(
  3092. // (4,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.
  3093. // async public static void Main()
  3094. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Main"),
  3095. // (4,30): error CS4009: 'Test.Main()': an entry point cannot be marked with the 'async' modifier
  3096. // async public static void Main()
  3097. Diagnostic(ErrorCode.ERR_MainCantBeAsync, "Main").WithArguments("Test.Main()"));
  3098. }
  3099. [Fact, WorkItem(547088, "DevDiv")]
  3100. public void Repro_17914()
  3101. {
  3102. var source = @"
  3103. class Driver
  3104. {
  3105. static int Main()
  3106. {
  3107. return 1;
  3108. }
  3109. public async void Foo(ref int x)
  3110. { }
  3111. }";
  3112. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3113. // (9,35): error CS1988: Async methods cannot have ref or out parameters
  3114. // public async void Foo(ref int x)
  3115. Diagnostic(ErrorCode.ERR_BadAsyncArgType, "x"),
  3116. // (9,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.
  3117. // public async void Foo(ref int x)
  3118. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Foo"));
  3119. }
  3120. [Fact]
  3121. public void BadAsync_MethodImpl_Synchronized()
  3122. {
  3123. var source = @"
  3124. using System.Runtime.CompilerServices;
  3125. using System.Threading.Tasks;
  3126. public class C
  3127. {
  3128. [MethodImpl(MethodImplOptions.Synchronized)]
  3129. async Task<int> F1()
  3130. {
  3131. return await Task.Factory.StartNew(() => 1);
  3132. }
  3133. }";
  3134. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3135. // (9,21): error CS4015: 'MethodImplOptions.Synchronized' cannot be applied to an Async method.
  3136. // async Task<int> F1()
  3137. Diagnostic(ErrorCode.ERR_SynchronizedAsyncMethod, "F1"));
  3138. }
  3139. [Fact]
  3140. public void Async_MethodImplSynchronized_BadReturn_SecurityCritical()
  3141. {
  3142. var source = @"
  3143. using System.Runtime.CompilerServices;
  3144. using System.Security;
  3145. using System.Threading.Tasks;
  3146. [SecurityCritical]
  3147. public class C
  3148. {
  3149. [MethodImpl(MethodImplOptions.Synchronized)]
  3150. async int F1()
  3151. {
  3152. return await Task.Factory.StartNew(() => 1);
  3153. }
  3154. }";
  3155. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3156. // (10,15): error CS1983: The return type of an async method must be void, Task or Task<T>
  3157. // async int F1()
  3158. Diagnostic(ErrorCode.ERR_BadAsyncReturn, "F1"),
  3159. // (10,15): error CS4031: Async methods are not allowed in an Interface, Class, or Structure which has the 'SecurityCritical' or 'SecuritySafeCritical' attribute.
  3160. // async int F1()
  3161. Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct, "F1"),
  3162. // (10,15): error CS4015: 'MethodImplOptions.Synchronized' cannot be applied to an Async method.
  3163. // async int F1()
  3164. Diagnostic(ErrorCode.ERR_SynchronizedAsyncMethod, "F1"));
  3165. }
  3166. [Fact]
  3167. [WorkItem(552382, "DevDiv")]
  3168. public void GetAwaiterIsExtension()
  3169. {
  3170. var source =
  3171. @"using System;
  3172. using A;
  3173. namespace A
  3174. {
  3175. public class IAS<T>
  3176. {
  3177. }
  3178. public class Awaiter<T> : System.Runtime.CompilerServices.INotifyCompletion
  3179. {
  3180. public bool IsCompleted { get { return true; } }
  3181. public T GetResult() { return default(T); }
  3182. public void OnCompleted(Action continuation) { }
  3183. }
  3184. public static class IAS_Extensions
  3185. {
  3186. public static Awaiter<T> GetAwaiter<T>(this IAS<T> self) { return null; }
  3187. }
  3188. }
  3189. namespace B
  3190. {
  3191. public class Program
  3192. {
  3193. static async void M(IAS<int> i)
  3194. {
  3195. int i1 = await i;
  3196. int i2 = i.GetAwaiter().GetResult();
  3197. }
  3198. public static void Main(string[] args)
  3199. {
  3200. }
  3201. }
  3202. }";
  3203. CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
  3204. }
  3205. [Fact]
  3206. [WorkItem(576311, "DevDiv")]
  3207. public void BadDelegateTypeForAsync()
  3208. {
  3209. var source =
  3210. @"using System;
  3211. class C
  3212. {
  3213. static void Main()
  3214. {
  3215. Func<int> x = async delegate { throw null; };
  3216. }
  3217. }";
  3218. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3219. // (6,23): error CS4010: Cannot convert async anonymous method to delegate type 'System.Func<int>'. An async anonymous method may return void, Task or Task<T>, none of which are convertible to 'System.Func<int>'.
  3220. // Func<int> x = async delegate { throw null; };
  3221. Diagnostic(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, "async delegate { throw null; }").WithArguments("anonymous method", "System.Func<int>").WithLocation(6, 23),
  3222. // (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.
  3223. // Func<int> x = async delegate { throw null; };
  3224. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async delegate { throw null; }").WithLocation(6, 23)
  3225. );
  3226. }
  3227. [WorkItem(588706, "DevDiv")]
  3228. [Fact]
  3229. public void AsyncAsLambdaParameter()
  3230. {
  3231. var source =
  3232. @"using System;
  3233. using System.Threading.Tasks;
  3234. class C
  3235. {
  3236. async void Foo()
  3237. {
  3238. Action<int> x = (await) => { }; // should be a syntax error
  3239. await Task.Delay(1);
  3240. }
  3241. }";
  3242. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3243. // (8,26): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression
  3244. // Action<int> x = (await) => { }; // should be a syntax error
  3245. Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(8, 26)
  3246. );
  3247. }
  3248. [Fact]
  3249. [WorkItem(629368, "DevDiv")]
  3250. public void GetAwaiterFieldUsedLikeMethod()
  3251. {
  3252. string source = @"
  3253. using System;
  3254. using System.Runtime.CompilerServices;
  3255. using System.Threading.Tasks;
  3256. public class C
  3257. {
  3258. public Func<TaskAwaiter<int>> GetAwaiter;
  3259. public async Task<int> F(C x)
  3260. {
  3261. return await x;
  3262. }
  3263. }
  3264. ";
  3265. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3266. // (12,17): error CS0118: 'GetAwaiter' is a field but is used like a method
  3267. Diagnostic(ErrorCode.ERR_BadSKknown, "await x").WithArguments("GetAwaiter", "field", "method"));
  3268. }
  3269. [Fact]
  3270. [WorkItem(629368, "DevDiv")]
  3271. public void GetAwaiterPropertyUsedLikeMethod()
  3272. {
  3273. string source = @"
  3274. using System;
  3275. using System.Runtime.CompilerServices;
  3276. using System.Threading.Tasks;
  3277. public class C
  3278. {
  3279. public Func<TaskAwaiter<int>> GetAwaiter { get; set; }
  3280. public async Task<int> F(C x)
  3281. {
  3282. return await x;
  3283. }
  3284. }
  3285. ";
  3286. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3287. // (12,16): error CS0118: 'GetAwaiter' is a property but is used like a method
  3288. Diagnostic(ErrorCode.ERR_BadSKknown, "await x").WithArguments("GetAwaiter", "property", "method"));
  3289. }
  3290. [Fact]
  3291. [WorkItem(628619, "DevDiv")]
  3292. public void ReturnExpressionNotConvertible()
  3293. {
  3294. string source = @"
  3295. using System.Threading.Tasks;
  3296. class Program
  3297. {
  3298. static async Task<T> Foo<T>()
  3299. {
  3300. await Task.Delay(1);
  3301. return 1;
  3302. }
  3303. }";
  3304. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3305. // (9,16): error CS0029: Cannot implicitly convert type 'int' to 'T'
  3306. // return 1;
  3307. Diagnostic(ErrorCode.ERR_NoImplicitConv, "1").WithArguments("int", "T")
  3308. );
  3309. }
  3310. [Fact]
  3311. [WorkItem(632824, "DevDiv")]
  3312. public void RefParameterOnAsyncLambda()
  3313. {
  3314. string source = @"
  3315. using System;
  3316. using System.Threading.Tasks;
  3317. delegate Task D(ref int x);
  3318. class C
  3319. {
  3320. static void Main()
  3321. {
  3322. D d = async delegate(ref int i)
  3323. {
  3324. await Task.Delay(500);
  3325. Console.WriteLine(i++);
  3326. };
  3327. int x = 5;
  3328. d(ref x).Wait();
  3329. Console.WriteLine(x);
  3330. }
  3331. }";
  3332. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3333. // (11,38): error CS1988: Async methods cannot have ref or out parameters
  3334. // D d = async delegate(ref int i)
  3335. Diagnostic(ErrorCode.ERR_BadAsyncArgType, "i")
  3336. );
  3337. }
  3338. [Fact]
  3339. [WorkItem(858059, "DevDiv")]
  3340. public void UnawaitedVersusLambda()
  3341. {
  3342. string source =
  3343. @"using System;
  3344. using System.Threading.Tasks;
  3345. public class Program
  3346. {
  3347. public static void Main(string[] args)
  3348. {
  3349. }
  3350. void X()
  3351. {
  3352. Action x1 = () => XAsync(); // warn
  3353. Action y1 = () => YAsync(); // ok
  3354. Action x2 = async () => XAsync(); // warn
  3355. Action y2 = async () => YAsync(); // warn
  3356. XAsync(); // warn
  3357. YAsync(); // ok
  3358. }
  3359. async Task XAsync()
  3360. {
  3361. await Task.Delay(1);
  3362. }
  3363. Task YAsync()
  3364. {
  3365. return Task.Delay(1);
  3366. }
  3367. }";
  3368. // The rules for when we give a warning may seem quirky, but we aim to precisely replicate
  3369. // the diagnostics produced by the native compiler.
  3370. CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
  3371. // (12,27): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  3372. // Action x1 = () => XAsync(); // warn
  3373. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "XAsync()").WithLocation(12, 27),
  3374. // (14,33): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  3375. // Action x2 = async () => XAsync(); // warn
  3376. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "XAsync()").WithLocation(14, 33),
  3377. // (15,33): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  3378. // Action y2 = async () => YAsync(); // warn
  3379. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "YAsync()").WithLocation(15, 33),
  3380. // (17,9): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
  3381. // XAsync(); // warn
  3382. Diagnostic(ErrorCode.WRN_UnobservedAwaitableExpression, "XAsync()").WithLocation(17, 9),
  3383. // (14,21): 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.
  3384. // Action x2 = async () => XAsync(); // warn
  3385. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => XAsync()").WithLocation(14, 21),
  3386. // (15,21): 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.
  3387. // Action y2 = async () => YAsync(); // warn
  3388. Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "async () => YAsync()").WithLocation(15, 21)
  3389. );
  3390. }
  3391. }
  3392. }