diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index c13bd31ac8f73..ac8c593babe12 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -1230,7 +1230,11 @@ Pattern *TypeChecker::coercePatternToType( // If the whole pattern is implicit, the user didn't write it. // Assume the compiler knows what it's doing. } else if (diagTy->isEqual(Context.TheEmptyTupleType)) { - shouldRequireType = true; + // Async-let bindings are commonly used to run a Void-returning + // synchronous function in an async context. As a policy choice, don't + // diagnose an inferred Void type (or optional thereof) on such bindings + // as potentially unexpected. + shouldRequireType = var->isAsyncLet() ? false : true; } else if (auto MTT = diagTy->getAs()) { if (MTT->getInstanceType()->isAnyObject()) shouldRequireType = true; diff --git a/test/decl/var/async_let.swift b/test/decl/var/async_let.swift index 5461e510484f4..dc31ff6aa3bd9 100644 --- a/test/decl/var/async_let.swift +++ b/test/decl/var/async_let.swift @@ -42,3 +42,39 @@ func testInterpolation() async { async let y = "\(12345)" _ = await y } + +// https://forums.swift.org/t/disable-constant-inferred-to-have-type-warning-when-using-async-let/83025 + +func testVoidResultTypeDiagnostics() async { + async let void = print("hello") + await void + async let void2 = () + await void2 + async let void3 = Void() + await void3 + async let void4 = { _ = 42 }() + await void4 + + @Sendable func syncVoid() {} + async let void5 = syncVoid() + await void5 + + @Sendable func asyncVoid() async {} + async let void6 = asyncVoid() + await void6 + + async let maybeVoid = { Bool.random() ? () : nil }() + await maybeVoid + + do { + final class C: Sendable { func doit() {} } + let c: C? = nil + async let maybeVoid2 = c?.doit() + let _: ()? = await maybeVoid2 + } + + // expected-warning @+2 {{constant 'boxOVoid' inferred to have type '[()]', which may be unexpected}} + // expected-note @+1 {{add an explicit type annotation to silence this warning}} + async let boxOVoid = { [(), (), ()] }() + await boxOVoid // expected-warning {{expression of type '[()]' is unused}} +}