Skip to content

Commit 95b6de2

Browse files
committed
[escaping] Correct diagnostic for parameter position
In situations where @escaping is used in non-function-parameter positions, we give an incorrect diagnostic message pertaining to function types. Instead, we should just state that this is not allowed in non-function-parameter positions. This includes the general message fix. Unfortunately, this does not include more friendly messages for special cases, e.g. closure members of aggregate and optional closures. That may be possible with more nested type context information in TypeCheckType.
1 parent b3c7894 commit 95b6de2

File tree

4 files changed

+10
-2
lines changed

4 files changed

+10
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,8 @@ ERROR(noescape_conflicts_escaping_autoclosure,none,
18791879

18801880
ERROR(escaping_function_type,none,
18811881
"@escaping may only be applied to parameters of function type", ())
1882+
ERROR(escaping_non_function_parameter,none,
1883+
"@escaping attribute may only be used in function parameter position", ())
18821884

18831885
// NSManaged attribute
18841886
ERROR(attr_NSManaged_not_instance_member,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
20102010
loc.getAdvancedLoc(-1),
20112011
Lexer::getLocForEndOfToken(SM, loc));
20122012

2013-
TC.diagnose(loc, diag::escaping_function_type)
2013+
TC.diagnose(loc, diag::escaping_non_function_parameter)
20142014
.fixItRemove(attrRange);
20152015
}
20162016

test/attr/attr_escaping.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ func callEscapingAutoclosureWithNoEscape_3(_ fn: @autoclosure () -> Int) {
7070
takesEscapingAutoclosure(fn()) // expected-error{{closure use of non-escaping parameter 'fn' may allow it to escape}}
7171
}
7272

73+
let foo: @escaping (Int) -> Int // expected-error{{@escaping attribute may only be used in function parameter position}} {{10-20=}}
74+
75+
func misuseEscaping(_ a: @escaping Int) {} // expected-error{{@escaping attribute only applies to function types}}
76+
func misuseEscaping(_ a: (@escaping Int)?) {} // expected-error{{@escaping attribute only applies to function types}}
77+
func misuseEscaping(_ a: (@escaping (Int) -> Int)?) {} // expected-error{{@escaping attribute may only be used in function parameter position}} {{27-37=}}
78+
func misuseEscaping(_ a: (@escaping (Int) -> Int, Int)) {} // expected-error{{@escaping attribute may only be used in function parameter position}} {{27-37=}}
7379

7480
func takesEscapingGeneric<T>(_ fn: @escaping () -> T) {}
7581
func callEscapingGeneric<T>(_ fn: () -> T) { // expected-note {{parameter 'fn' is implicitly non-escaping}} {{35-35=@escaping }}

test/attr/attr_noescape.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ func escapeNoEscapeResult(_ x: [Int]) -> (@noescape (Int) -> Int) -> Int { // ex
271271
typealias CompletionHandlerNE = @noescape (_ success: Bool) -> () // expected-warning{{@noescape is the default and is deprecated}} {{33-43=}}
272272

273273
// Explicit @escaping is not allowed here
274-
typealias CompletionHandlerE = @escaping (_ success: Bool) -> () // expected-error{{@escaping may only be applied to parameters of function type}}
274+
typealias CompletionHandlerE = @escaping (_ success: Bool) -> () // expected-error{{@escaping attribute may only be used in function parameter position}} {{32-42=}}
275275

276276
// No @escaping -- it's implicit from context
277277
typealias CompletionHandler = (_ success: Bool) -> ()

0 commit comments

Comments
 (0)