diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 8d7ed568906dd..accc6aaa429c0 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2002,8 +2002,16 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, // Handle @escaping if (hasFunctionAttr && ty->is()) { if (attrs.has(TAK_escaping)) { + // For compatibility with 3.0, we don't emit an error if it appears on a + // variadic argument list. + // + // FIXME: Version-gate on Swift language version 3, as we don't want its + // presence to confuse users. + bool skipDiagnostic = isVariadicFunctionParam; + // The attribute is meaningless except on parameter types. - if (!isFunctionParam) { + bool shouldDiagnose = !isFunctionParam && !skipDiagnostic; + if (shouldDiagnose) { auto &SM = TC.Context.SourceMgr; auto loc = attrs.getLoc(TAK_escaping); auto attrRange = SourceRange( diff --git a/test/attr/attr_escaping.swift b/test/attr/attr_escaping.swift index d57791bb1656b..03937668f9e6a 100644 --- a/test/attr/attr_escaping.swift +++ b/test/attr/attr_escaping.swift @@ -139,6 +139,11 @@ func takesVarargsOfFunctions(fns: () -> ()...) { } } +// This is allowed, in order to keep source compat with Swift version 3.0. +// +// FIXME: version-gate on Swift version 3 +func takesVarargsOfFunctionsExplicitEscaping(fns: @escaping () -> ()...) {} + func takesNoEscapeFunction(fn: () -> ()) { // expected-note {{parameter 'fn' is implicitly non-escaping}} takesVarargsOfFunctions(fns: fn) // expected-error {{passing non-escaping parameter 'fn' to function expecting an @escaping closure}} }