Skip to content

Commit e5a0c96

Browse files
committed
Fix inout optional overload warning for methods.
Also add a note saying that allowing these overloads is deprecated and will be removed in a future release.
1 parent 6347112 commit e5a0c96

File tree

3 files changed

+64
-35
lines changed

3 files changed

+64
-35
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ NOTE(invalid_redecl_prev,none,
616616
WARNING(deprecated_redecl_by_optionality, none,
617617
"invalid redeclaration of %0 which differs only by the kind of optional passed as an inout argument (%1 vs. %2)",
618618
(DeclName, Type, Type))
619+
NOTE(deprecated_redecl_by_optionality_note, none,
620+
"overloading by kind of optional is deprecated and will be removed in a future release", ())
619621

620622
ERROR(ambiguous_type_base,none,
621623
"%0 is ambiguous for type lookup in this context", (Identifier))

lib/Sema/TypeCheckDecl.cpp

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -978,43 +978,52 @@ static void checkRedeclaration(TypeChecker &tc, ValueDecl *current) {
978978
// warning that these overloads are deprecated and will no
979979
// longer be supported in the future.
980980
if (!current->getInterfaceType()->isEqual(other->getInterfaceType())) {
981-
auto diagnosed = false;
982-
auto currFnTy = current->getInterfaceType()->getAs<AnyFunctionType>();
983-
auto otherFnTy = other->getInterfaceType()->getAs<AnyFunctionType>();
984-
if (currFnTy && otherFnTy) {
985-
ArrayRef<AnyFunctionType::Param> currParams = currFnTy->getParams();
986-
ArrayRef<AnyFunctionType::Param> otherParams = otherFnTy->getParams();
987-
988-
if (currParams.size() == otherParams.size()) {
989-
for (unsigned i : indices(currParams)) {
990-
if (currParams[i].isInOut() && otherParams[i].isInOut()) {
991-
auto currParamTy = currParams[i]
992-
.getType()
993-
->getAs<InOutType>()
994-
->getObjectType();
995-
auto otherParamTy = otherParams[i]
996-
.getType()
997-
->getAs<InOutType>()
998-
->getObjectType();
999-
OptionalTypeKind currOTK;
1000-
OptionalTypeKind otherOTK;
1001-
(void)currParamTy->getAnyOptionalObjectType(currOTK);
1002-
(void)otherParamTy->getAnyOptionalObjectType(otherOTK);
1003-
if (currOTK != OTK_None && otherOTK != OTK_None &&
1004-
currOTK != otherOTK) {
1005-
tc.diagnose(current, diag::deprecated_redecl_by_optionality,
1006-
current->getFullName(), currParamTy,
1007-
otherParamTy);
1008-
tc.diagnose(other, diag::invalid_redecl_prev,
1009-
other->getFullName());
1010-
diagnosed = true;
1011-
break;
981+
if (currentDC->isTypeContext() == other->getDeclContext()->isTypeContext()) {
982+
auto currFnTy = current->getInterfaceType()->getAs<AnyFunctionType>();
983+
auto otherFnTy = other->getInterfaceType()->getAs<AnyFunctionType>();
984+
if (currFnTy && otherFnTy && currentDC->isTypeContext()) {
985+
currFnTy = currFnTy->getResult()->getAs<AnyFunctionType>();
986+
otherFnTy = otherFnTy->getResult()->getAs<AnyFunctionType>();
987+
}
988+
989+
if (currFnTy && otherFnTy) {
990+
ArrayRef<AnyFunctionType::Param> currParams = currFnTy->getParams();
991+
ArrayRef<AnyFunctionType::Param> otherParams = otherFnTy->getParams();
992+
993+
if (currParams.size() == otherParams.size()) {
994+
auto diagnosed = false;
995+
for (unsigned i : indices(currParams)) {
996+
if (currParams[i].isInOut() && otherParams[i].isInOut()) {
997+
auto currParamTy = currParams[i]
998+
.getType()
999+
->getAs<InOutType>()
1000+
->getObjectType();
1001+
auto otherParamTy = otherParams[i]
1002+
.getType()
1003+
->getAs<InOutType>()
1004+
->getObjectType();
1005+
OptionalTypeKind currOTK;
1006+
OptionalTypeKind otherOTK;
1007+
(void)currParamTy->getAnyOptionalObjectType(currOTK);
1008+
(void)otherParamTy->getAnyOptionalObjectType(otherOTK);
1009+
if (currOTK != OTK_None && otherOTK != OTK_None &&
1010+
currOTK != otherOTK) {
1011+
tc.diagnose(current, diag::deprecated_redecl_by_optionality,
1012+
current->getFullName(), currParamTy,
1013+
otherParamTy);
1014+
tc.diagnose(other, diag::invalid_redecl_prev,
1015+
other->getFullName());
1016+
tc.diagnose(current,
1017+
diag::deprecated_redecl_by_optionality_note);
1018+
diagnosed = true;
1019+
break;
1020+
}
10121021
}
10131022
}
1014-
}
10151023

1016-
if (diagnosed)
1017-
break;
1024+
if (diagnosed)
1025+
break;
1026+
}
10181027
}
10191028
}
10201029
}

test/decl/overload.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,25 @@ func optional(x: Int!) { } // expected-error{{invalid redeclaration of 'optional
264264
func optionalInOut(x: inout Int?) { } // expected-note{{previously declared}}
265265
// expected-note@-1 {{previously declared}}
266266
func optionalInOut(x: inout Int!) { } // expected-warning{{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
267-
// expected-warning@-1 {{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
267+
// expected-note@-1 {{overloading by kind of optional is deprecated and will be removed in a future release}}
268+
// expected-warning@-2 {{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
269+
// expected-note@-3 {{overloading by kind of optional is deprecated and will be removed in a future release}}
270+
271+
class optionalOverloads {
272+
class func optionalInOut(x: inout Int?) { } // expected-note{{previously declared}}
273+
// expected-note@-1 {{previously declared}}
274+
class func optionalInOut(x: inout Int!) { } // expected-warning{{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
275+
// expected-note@-1 {{overloading by kind of optional is deprecated and will be removed in a future release}}
276+
// expected-warning@-2 {{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
277+
// expected-note@-3 {{overloading by kind of optional is deprecated and will be removed in a future release}}
278+
279+
func optionalInOut(x: inout Int?) { } // expected-note{{previously declared}}
280+
// expected-note@-1 {{previously declared}}
281+
func optionalInOut(x: inout Int!) { } // expected-warning{{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
282+
// expected-note@-1 {{overloading by kind of optional is deprecated and will be removed in a future release}}
283+
// expected-warning@-2 {{invalid redeclaration of 'optionalInOut(x:)' which differs only by the kind of optional passed as an inout argument ('Int!' vs. 'Int?')}}
284+
// expected-note@-3 {{overloading by kind of optional is deprecated and will be removed in a future release}}
285+
}
268286

269287
func optional_3() -> Int? { } // expected-note{{previously declared}}
270288
func optional_3() -> Int! { } // expected-error{{invalid redeclaration of 'optional_3()'}}

0 commit comments

Comments
 (0)