Skip to content

Add fix-it to error and add note - SR-4637 #8947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2035,6 +2035,14 @@ Type TypeResolver::resolveAttributedType(AttributedTypeRepr *repr,
Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
TypeRepr *repr,
TypeResolutionOptions options) {
// Convenience to grab the source range of a type attribute.
auto getTypeAttrRangeWithAt = [](TypeChecker &TC, SourceLoc attrLoc) {
return SourceRange(attrLoc.getAdvancedLoc(-1),
Lexer::getLocForEndOfToken(TC.Context.SourceMgr,
attrLoc));

};

// Remember whether this is a function parameter.
bool isFunctionParam =
options.contains(TR_FunctionInput) ||
Expand Down Expand Up @@ -2230,12 +2238,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,

// @noreturn has been replaced with a 'Never' return type.
if (fnRepr && attrs.has(TAK_noreturn)) {
auto &SM = TC.Context.SourceMgr;
auto loc = attrs.getLoc(TAK_noreturn);
auto attrRange = SourceRange(
loc.getAdvancedLoc(-1),
Lexer::getLocForEndOfToken(SM, loc));

auto attrRange = getTypeAttrRangeWithAt(TC, loc);
auto resultRange = fnRepr->getResultTypeRepr()->getSourceRange();

TC.diagnose(loc, diag::noreturn_not_supported)
Expand Down Expand Up @@ -2276,11 +2280,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
// The attribute is meaningless except on parameter types.
bool shouldDiagnose = !isFunctionParam && !skipDiagnostic;
if (shouldDiagnose) {
auto &SM = TC.Context.SourceMgr;
auto loc = attrs.getLoc(TAK_escaping);
auto attrRange = SourceRange(
loc.getAdvancedLoc(-1),
Lexer::getLocForEndOfToken(SM, loc));
auto attrRange = getTypeAttrRangeWithAt(TC, loc);

TC.diagnose(loc, diag::escaping_non_function_parameter)
.fixItRemove(attrRange);
Expand All @@ -2305,11 +2306,25 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
attrs.clearAttribute(TAK_noescape);

for (auto i : FunctionAttrs) {
if (attrs.has(i)) {
TC.diagnose(attrs.getLoc(i), diag::attribute_requires_function_type,
TypeAttributes::getAttrName(i));
attrs.clearAttribute(i);
if (!attrs.has(i))
continue;

auto diag = TC.diagnose(attrs.getLoc(i),
diag::attribute_requires_function_type,
TypeAttributes::getAttrName(i));

// If we see @escaping among the attributes on this type, because it isn't
// a function type, we'll remove it.
if (i == TAK_escaping) {
diag.fixItRemove(getTypeAttrRangeWithAt(TC,
attrs.getLoc(TAK_escaping)));
// Specialize the diagnostic for Optionals.
if (ty->getOptionalObjectType()) {
diag.flush();
TC.diagnose(repr->getLoc(), diag::escaping_optional_type_argument);
}
}
attrs.clearAttribute(i);
}
} else if (hasFunctionAttr && fnRepr) {
// Remove the function attributes from the set so that we don't diagnose.
Expand Down
6 changes: 4 additions & 2 deletions test/attr/attr_escaping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ let foo: @escaping (Int) -> Int // expected-error{{@escaping attribute may only

struct GenericStruct<T> {}

func misuseEscaping(_ a: @escaping Int) {} // expected-error{{@escaping attribute only applies to function types}}
func misuseEscaping(_ a: (@escaping Int)?) {} // expected-error{{@escaping attribute only applies to function types}}
func misuseEscaping(_ a: @escaping Int) {} // expected-error{{@escaping attribute only applies to function types}} {{26-38=}}
func misuseEscaping(_ a: (@escaping Int)?) {} // expected-error{{@escaping attribute only applies to function types}} {{27-39=}}
func misuseEscaping(opt a: @escaping ((Int) -> Int)?) {} // expected-error{{@escaping attribute only applies to function types}} {{28-38=}}
// expected-note@-1{{closure is already escaping in optional type argument}}

func misuseEscaping(_ a: (@escaping (Int) -> Int)?) {} // expected-error{{@escaping attribute may only be used in function parameter position}} {{27-37=}}
// expected-note@-1{{closure is already escaping in optional type argument}}
Expand Down