Skip to content

Commit 0519dd7

Browse files
[Sema] Adjustments on implementation and diagnostic message for SR-14720
1 parent 51ee1de commit 0519dd7

File tree

4 files changed

+34
-25
lines changed

4 files changed

+34
-25
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3890,10 +3890,9 @@ ERROR(converting_noattrfunc_to_type,none,
38903890
"converting %select{non-escaping|non-concurrent function}0 value to %1 "
38913891
"may %select{allow it to escape|introduce data races}0",
38923892
(unsigned, Type))
3893-
ERROR(converting_noattrfunc_contravariant_parameter_position,none,
3894-
"converting escaping to non-escaping functions of type %2 in parameter position "
3895-
"#%0 of function type %3 %1 is not allowed",
3896-
(unsigned, Identifier, Type, DescriptiveDeclKind))
3893+
NOTE(escape_expected_at_parameter_position,none,
3894+
"parameter #%0 expects escaping value of type %1",
3895+
(unsigned, Type))
38973896
NOTE(add_explicit_escaping,none,
38983897
"add explicit @escaping to function parameter #%0",
38993898
(unsigned))

lib/Sema/CSDiagnostics.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -932,26 +932,27 @@ bool AttributedFuncToTypeConversionFailure::
932932
if (!loc->findLast<LocatorPathElt::FunctionArgument>())
933933
return false;
934934

935-
auto &solution = getSolution();
936-
auto decl = getDestinationVarDecl(AE, solution);
937-
if (!decl)
938-
return false;
935+
auto destType = getType(AE->getDest())->lookThroughAllOptionalTypes();
936+
auto destFnType = destType->castTo<FunctionType>();
937+
auto sourceType = getType(AE->getSrc())->lookThroughAllOptionalTypes();
939938

940939
// The tuple locator element will give us the exact parameter mismatch
941940
// position.
942941
auto tupleElt = loc->getLastElementAs<LocatorPathElt::TupleElement>();
943942
auto mismatchPosition = tupleElt ? tupleElt->getIndex() : 0;
943+
auto param = destFnType->getParams()[mismatchPosition];
944944

945-
auto destInterfaceType =
946-
decl->getInterfaceType()->lookThroughAllOptionalTypes();
947-
auto destInterfaceFnType = destInterfaceType->castTo<FunctionType>();
948-
auto param = destInterfaceFnType->getParams()[mismatchPosition];
949-
emitDiagnostic(diag::converting_noattrfunc_contravariant_parameter_position,
950-
mismatchPosition, decl->getName(), param.getParameterType(),
951-
decl->getDescriptiveKind());
945+
emitDiagnostic(diag::cannot_convert_assign, sourceType, destType);
946+
emitDiagnosticAt(AE->getDest()->getLoc(),
947+
diag::escape_expected_at_parameter_position,
948+
mismatchPosition, param.getParameterType());
952949

953-
auto note = emitDiagnosticAt(decl->getLoc(), diag::add_explicit_escaping,
954-
mismatchPosition);
950+
auto &solution = getSolution();
951+
auto decl = getDestinationVarDecl(AE, solution);
952+
// We couldn't find a declaration to add an extra note with a fix-it but
953+
// the main diagnostic was already covered.
954+
if (!decl)
955+
return true;
955956

956957
auto declRepr = decl->getTypeReprOrParentPatternTypeRepr();
957958
class TopLevelFuncReprFinder : public ASTWalker {
@@ -972,8 +973,10 @@ bool AttributedFuncToTypeConversionFailure::
972973

973974
auto declFnRepr = fnFinder.FnRepr;
974975
if (!declFnRepr)
975-
return false;
976+
return true;
976977

978+
auto note = emitDiagnosticAt(decl->getLoc(), diag::add_explicit_escaping,
979+
mismatchPosition);
977980
auto argsRepr = declFnRepr->getArgsTypeRepr();
978981
auto argRepr = argsRepr->getElement(mismatchPosition).Type;
979982
if (!param.isAutoClosure()) {

test/Constraints/function_conversion.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ takesAny(consumeEscaping)
5959

6060
var noEscapeParam: ((Int) -> Int) -> () = consumeNoEscape // expected-note {{add explicit @escaping to function parameter}}{{21-21=@escaping }}
6161
var escapingParam: (@escaping (Int) -> Int) -> () = consumeEscaping
62-
noEscapeParam = escapingParam // expected-error {{converting escaping to non-escaping functions of type '(Int) -> Int' in parameter position #0 of function type var 'noEscapeParam' is not allowed}}
62+
noEscapeParam = escapingParam // expected-error {{cannot assign value of type '(@escaping (Int) -> Int) -> ()' to type '((Int) -> Int) -> ()'}}
63+
// expected-note@-1{{parameter #0 expects escaping value of type '(Int) -> Int'}}
6364

6465
escapingParam = takesAny
6566
noEscapeParam = takesAny // expected-error {{converting non-escaping value to 'Any' may allow it to escape}}

test/attr/attr_escaping.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ class FooClass {
153153
}
154154
var computedEscaping : (@escaping ()->Int)->Void {
155155
get { return stored! }
156-
set(newValue) { stored = newValue } // expected-error{{converting escaping to non-escaping functions of type '() -> Int' in parameter position #0 of function type property 'stored' is not allowed}}
156+
set(newValue) { stored = newValue } // expected-error{{cannot assign value of type '(@escaping () -> Int) -> Void' to type '(() -> Int) -> Void'}}
157+
// expected-note@-1{{parameter #0 expects escaping value of type '() -> Int'}}
157158
}
158159
}
159160

@@ -241,23 +242,28 @@ class SR14720 {
241242
let callbackOpt: ((() -> Void) -> Void)? // expected-note{{add explicit @escaping to function parameter #0}} {{22-22=@escaping }}
242243

243244
init(f: @escaping (@escaping() -> Void) -> Void) {
244-
self.callback = f // expected-error{{converting escaping to non-escaping functions of type '() -> Void' in parameter position #0 of function type property 'callback' is not allowed}}
245+
self.callback = f // expected-error{{cannot assign value of type '(@escaping () -> Void) -> Void' to type '(() -> Void) -> Void'}}
246+
// expected-note@-1{{parameter #0 expects escaping value of type '() -> Void'}}
245247
self.ok = f // Ok
246248
}
247249

248250
init(af: @escaping (@escaping() -> Void) -> Void) {
249-
self.callbackOpt = af // expected-error{{converting escaping to non-escaping functions of type '() -> Void' in parameter position #0 of function type property 'callbackOpt' is not allowed}}
251+
self.callbackOpt = af // expected-error{{cannot assign value of type '(@escaping () -> Void) -> Void' to type '(() -> Void) -> Void'}}
252+
// expected-note@-1{{parameter #0 expects escaping value of type '() -> Void'}}
250253
}
251254

252255
init(ag: @escaping (@escaping() -> Void) -> Void) {
253-
global = ag // expected-error{{converting escaping to non-escaping functions of type '() -> Void' in parameter position #0 of function type var 'global' is not allowed}}
256+
global = ag // expected-error{{cannot assign value of type '(@escaping () -> Void) -> Void' to type '(() -> Void) -> Void'}}
257+
// expected-note@-1{{parameter #0 expects escaping value of type '() -> Void'}}
254258
}
255259

256260
init(a: @escaping (@escaping () -> Void) -> Void) {
257-
self.callbackAuto = a // expected-error{{converting escaping to non-escaping functions of type '() -> Void' in parameter position #0 of function type property 'callbackAuto' is not allowed}}
261+
self.callbackAuto = a // expected-error{{cannot assign value of type '(@escaping () -> Void) -> Void' to type '(@autoclosure () -> Void) -> Void'}}
262+
// expected-note@-1{{parameter #0 expects escaping value of type '() -> Void'}}
258263
}
259264

260265
init(f: @escaping (() -> Void, @escaping() -> Void) -> Void) {
261-
self.callback1 = f // expected-error{{converting escaping to non-escaping functions of type '() -> Void' in parameter position #1 of function type property 'callback1' is not allowed}}
266+
self.callback1 = f // expected-error{{cannot assign value of type '(() -> Void, @escaping () -> Void) -> Void' to type '(() -> Void, () -> Void) -> Void'}}
267+
// expected-note@-1{{parameter #1 expects escaping value of type '() -> Void'}}
262268
}
263269
}

0 commit comments

Comments
 (0)