Skip to content

Commit a038463

Browse files
authored
Merge pull request #22229 from xedin/rdar-47586626-5.0
[5.0][TypeChecker] Drop @autoclosure attribute from invalid parameters
2 parents d81c3d2 + 31a4d4c commit a038463

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
@@ -2275,10 +2275,6 @@ bool TypeResolver::resolveASTFunctionTypeParams(
22752275
variadic = true;
22762276
}
22772277

2278-
bool autoclosure = false;
2279-
if (auto *ATR = dyn_cast<AttributedTypeRepr>(eltTypeRepr))
2280-
autoclosure = ATR->getAttrs().has(TAK_autoclosure);
2281-
22822278
Type ty = resolveType(eltTypeRepr, thisElementOptions);
22832279
if (!ty) return true;
22842280

@@ -2292,6 +2288,16 @@ bool TypeResolver::resolveASTFunctionTypeParams(
22922288
ty = ty->mapTypeOutOfContext();
22932289
}
22942290

2291+
bool autoclosure = false;
2292+
if (auto *ATR = dyn_cast<AttributedTypeRepr>(eltTypeRepr)) {
2293+
// Make sure that parameter itself is of a function type, otherwise
2294+
// the problem would already be diagnosed by `resolveAttributedType`
2295+
// but attributes would stay unchanged. So as a recovery let's drop
2296+
// 'autoclosure' attribute from the resolved parameter.
2297+
autoclosure =
2298+
ty->is<FunctionType>() && ATR->getAttrs().has(TAK_autoclosure);
2299+
}
2300+
22952301
ValueOwnership ownership;
22962302

22972303
auto *nestedRepr = eltTypeRepr;

test/attr/attr_autoclosure.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,16 @@ func rdar_30906031(in arr: [Int], fn: @autoclosure () -> Int) -> Bool {
234234
arr.lazy.filter { $0 >= escapableF() }.isEmpty
235235
}
236236
}
237+
238+
func rdar_47586626() {
239+
struct S {}
240+
typealias F = () -> S
241+
242+
func foo(_: @autoclosure S) {} // expected-error {{@autoclosure attribute only applies to function types}}
243+
func bar(_: @autoclosure F) {} // expected-error {{@autoclosure attribute only applies to function types}}
244+
245+
let s = S()
246+
247+
foo(s) // ok
248+
bar(s) // ok
249+
}

0 commit comments

Comments
 (0)