Skip to content

Commit 2e0c6db

Browse files
authored
Merge pull request #22186 from xedin/rdar-47586626
[TypeChecker] Drop @autoclosure attribute from invalid parameters
2 parents 53ddd8c + 9da67c1 commit 2e0c6db

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

lib/Parse/ParsePattern.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ mapParsedParameters(Parser &parser,
489489
// belongs to both type flags and declaration.
490490
if (auto *ATR = dyn_cast<AttributedTypeRepr>(type)) {
491491
auto &attrs = ATR->getAttrs();
492+
// At this point we actually don't know if that's valid to mark
493+
// this parameter declaration as `autoclosure` because type has
494+
// not been resolved yet - it should either be a function type
495+
// or typealias with underlying function type.
492496
param->setAutoClosure(attrs.has(TypeAttrKind::TAK_autoclosure));
493497
}
494498
} else if (paramContext != Parser::ParameterContextKind::Closure) {

lib/Sema/TypeCheckPattern.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,13 @@ static bool validateParameterType(ParamDecl *decl, TypeResolution resolution,
773773
}
774774
}
775775

776+
// If this parameter declaration is marked as `@autoclosure`
777+
// let's make sure that its parameter type is indeed a function,
778+
// this decision couldn't be made based on type representative
779+
// alone because it may be later resolved into an invalid type.
780+
if (decl->isAutoClosure())
781+
hadError |= !(Ty && Ty->is<FunctionType>());
782+
776783
if (hadError)
777784
TL.setInvalidType(TC.Context);
778785

lib/Sema/TypeCheckType.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,10 +2293,6 @@ bool TypeResolver::resolveASTFunctionTypeParams(
22932293
variadic = true;
22942294
}
22952295

2296-
bool autoclosure = false;
2297-
if (auto *ATR = dyn_cast<AttributedTypeRepr>(eltTypeRepr))
2298-
autoclosure = ATR->getAttrs().has(TAK_autoclosure);
2299-
23002296
Type ty = resolveType(eltTypeRepr, thisElementOptions);
23012297
if (!ty) return true;
23022298

@@ -2310,6 +2306,16 @@ bool TypeResolver::resolveASTFunctionTypeParams(
23102306
ty = ty->mapTypeOutOfContext();
23112307
}
23122308

2309+
bool autoclosure = false;
2310+
if (auto *ATR = dyn_cast<AttributedTypeRepr>(eltTypeRepr)) {
2311+
// Make sure that parameter itself is of a function type, otherwise
2312+
// the problem would already be diagnosed by `resolveAttributedType`
2313+
// but attributes would stay unchanged. So as a recovery let's drop
2314+
// 'autoclosure' attribute from the resolved parameter.
2315+
autoclosure =
2316+
ty->is<FunctionType>() && ATR->getAttrs().has(TAK_autoclosure);
2317+
}
2318+
23132319
ValueOwnership ownership;
23142320

23152321
auto *nestedRepr = eltTypeRepr;

test/attr/attr_autoclosure.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,16 @@ class Bar {
245245
typealias BarClosure = (String) -> String
246246
func barFunction(closure: @autoclosure BarClosure) {} // expected-error {{argument type of @autoclosure parameter must be '()'}}
247247
}
248+
249+
func rdar_47586626() {
250+
struct S {}
251+
typealias F = () -> S
252+
253+
func foo(_: @autoclosure S) {} // expected-error {{@autoclosure attribute only applies to function types}}
254+
func bar(_: @autoclosure F) {} // Ok
255+
256+
let s = S()
257+
258+
foo(s) // ok
259+
bar(s) // ok
260+
}

0 commit comments

Comments
 (0)