@@ -2035,6 +2035,14 @@ Type TypeResolver::resolveAttributedType(AttributedTypeRepr *repr,
2035
2035
Type TypeResolver::resolveAttributedType (TypeAttributes &attrs,
2036
2036
TypeRepr *repr,
2037
2037
TypeResolutionOptions options) {
2038
+ // Convenience to grab the source range of a type attribute.
2039
+ auto getTypeAttrRangeWithAt = [](TypeChecker &TC, SourceLoc attrLoc) {
2040
+ return SourceRange (attrLoc.getAdvancedLoc (-1 ),
2041
+ Lexer::getLocForEndOfToken (TC.Context .SourceMgr ,
2042
+ attrLoc));
2043
+
2044
+ };
2045
+
2038
2046
// Remember whether this is a function parameter.
2039
2047
bool isFunctionParam =
2040
2048
options.contains (TR_FunctionInput) ||
@@ -2230,12 +2238,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
2230
2238
2231
2239
// @noreturn has been replaced with a 'Never' return type.
2232
2240
if (fnRepr && attrs.has (TAK_noreturn)) {
2233
- auto &SM = TC.Context .SourceMgr ;
2234
2241
auto loc = attrs.getLoc (TAK_noreturn);
2235
- auto attrRange = SourceRange (
2236
- loc.getAdvancedLoc (-1 ),
2237
- Lexer::getLocForEndOfToken (SM, loc));
2238
-
2242
+ auto attrRange = getTypeAttrRangeWithAt (TC, loc);
2239
2243
auto resultRange = fnRepr->getResultTypeRepr ()->getSourceRange ();
2240
2244
2241
2245
TC.diagnose (loc, diag::noreturn_not_supported)
@@ -2276,11 +2280,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
2276
2280
// The attribute is meaningless except on parameter types.
2277
2281
bool shouldDiagnose = !isFunctionParam && !skipDiagnostic;
2278
2282
if (shouldDiagnose) {
2279
- auto &SM = TC.Context .SourceMgr ;
2280
2283
auto loc = attrs.getLoc (TAK_escaping);
2281
- auto attrRange = SourceRange (
2282
- loc.getAdvancedLoc (-1 ),
2283
- Lexer::getLocForEndOfToken (SM, loc));
2284
+ auto attrRange = getTypeAttrRangeWithAt (TC, loc);
2284
2285
2285
2286
TC.diagnose (loc, diag::escaping_non_function_parameter)
2286
2287
.fixItRemove (attrRange);
@@ -2305,11 +2306,25 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
2305
2306
attrs.clearAttribute (TAK_noescape);
2306
2307
2307
2308
for (auto i : FunctionAttrs) {
2308
- if (attrs.has (i)) {
2309
- TC.diagnose (attrs.getLoc (i), diag::attribute_requires_function_type,
2310
- TypeAttributes::getAttrName (i));
2311
- attrs.clearAttribute (i);
2309
+ if (!attrs.has (i))
2310
+ continue ;
2311
+
2312
+ auto diag = TC.diagnose (attrs.getLoc (i),
2313
+ diag::attribute_requires_function_type,
2314
+ TypeAttributes::getAttrName (i));
2315
+
2316
+ // If we see @escaping among the attributes on this type, because it isn't
2317
+ // a function type, we'll remove it.
2318
+ if (i == TAK_escaping) {
2319
+ diag.fixItRemove (getTypeAttrRangeWithAt (TC,
2320
+ attrs.getLoc (TAK_escaping)));
2321
+ // Specialize the diagnostic for Optionals.
2322
+ if (ty->getOptionalObjectType ()) {
2323
+ diag.flush ();
2324
+ TC.diagnose (repr->getLoc (), diag::escaping_optional_type_argument);
2325
+ }
2312
2326
}
2327
+ attrs.clearAttribute (i);
2313
2328
}
2314
2329
} else if (hasFunctionAttr && fnRepr) {
2315
2330
// Remove the function attributes from the set so that we don't diagnose.
0 commit comments