Skip to content

Commit f2c2aa5

Browse files
committed
[AST] Mark repr invalid only if @autoclosure parameter doesn't point to function type
Instead on depending on repr to be a function, let's only check whether type resolved for `@autoclosure` points to a function type because it's allowed for `@autoclosure` parameters to be to wrapped into parens or be represented by a typealias. Resolves: rdar://problem/65704049
1 parent b2f8fa8 commit f2c2aa5

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,15 +2345,23 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
23452345
}
23462346
}
23472347

2348-
if (hasFunctionAttr && !fnRepr) {
2349-
if (attrs.has(TAK_autoclosure)) {
2348+
if (attrs.has(TAK_autoclosure)) {
2349+
// If this is a situation where function type is wrapped
2350+
// into a number of parens, let's try to look through them,
2351+
// because parens are insignificant here e.g.:
2352+
//
2353+
// let _: (@autoclosure (() -> Void)) -> Void = { _ in }
2354+
if (!ty->is<FunctionType>()) {
23502355
// @autoclosure is going to be diagnosed when type of
23512356
// the parameter is validated, because that attribute
23522357
// applies to the declaration now.
23532358
repr->setInvalid();
2354-
attrs.clearAttribute(TAK_autoclosure);
23552359
}
23562360

2361+
attrs.clearAttribute(TAK_autoclosure);
2362+
}
2363+
2364+
if (hasFunctionAttr && !fnRepr) {
23572365
const auto diagnoseInvalidAttr = [&](TypeAttrKind kind) {
23582366
if (kind == TAK_escaping) {
23592367
Type optionalObjectType = ty->getOptionalObjectType();

test/attr/attr_autoclosure.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,36 @@ struct SR_11938_S : @autoclosure SR_11938_P {} // expected-error {{'@autoclosure
295295

296296
// SR-9178
297297
func bar<T>(_ x: @autoclosure T) {} // expected-error 1{{@autoclosure attribute only applies to function types}}
298+
299+
func test_autoclosure_type_in_parens() {
300+
let _: (@autoclosure (() -> Void)) -> Void = { _ in } // Ok
301+
302+
struct Test {
303+
func bugSingle<T: RawRepresentable>(defaultValue: @autoclosure (() -> T)) -> T { // Ok
304+
defaultValue()
305+
}
306+
307+
func bugMultiple<T: RawRepresentable>(defaultValue: @autoclosure ((() -> T))) -> T { // Ok
308+
defaultValue()
309+
}
310+
}
311+
312+
enum E : String {
313+
case foo = "foo"
314+
case bar = "bar"
315+
}
316+
317+
_ = Test().bugSingle(defaultValue: E.foo) // Ok
318+
_ = Test().bugMultiple(defaultValue: E.bar) // Ok
319+
}
320+
321+
func test_autoclosure_with_typealias() {
322+
typealias ConcreteFunc = () -> Int
323+
typealias GenericFunc<T> = () -> T
324+
325+
func test(cr: @autoclosure ConcreteFunc) -> Int { cr() } // Ok
326+
func test<Q>(gn: @autoclosure GenericFunc<Q>) -> Q { gn() } // Ok
327+
328+
_ = test(cr: 0) // Ok
329+
_ = test(gn: 1) // Ok
330+
}

0 commit comments

Comments
 (0)