Skip to content

Commit f19d363

Browse files
authored
Merge pull request #59654 from bnbarham/cherry-new-diag
[5.7][Sema] Diagnose redundant any on existential type
2 parents 0279459 + 564c9d3 commit f19d363

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4762,6 +4762,9 @@ ERROR(unchecked_not_inheritance_clause,none,
47624762
ERROR(unchecked_not_existential,none,
47634763
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))
47644764

4765+
ERROR(redundant_any_in_existential,none,
4766+
"redundant 'any' has no effect on existential type %0",
4767+
(Type))
47654768
ERROR(any_not_existential,none,
47664769
"'any' has no effect on %select{concrete type|type parameter}0 %1",
47674770
(bool, Type))

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4007,7 +4007,7 @@ TypeResolver::resolveExistentialType(ExistentialTypeRepr *repr,
40074007
if (constraintType->hasError())
40084008
return ErrorType::get(getASTContext());
40094009

4010-
if (!constraintType->isExistentialType()) {
4010+
if (!constraintType->isConstraintType()) {
40114011
// Emit a tailored diagnostic for the incorrect optional
40124012
// syntax 'any P?' with a fix-it to add parenthesis.
40134013
auto wrapped = constraintType->getOptionalObjectType();
@@ -4021,14 +4021,18 @@ TypeResolver::resolveExistentialType(ExistentialTypeRepr *repr,
40214021
.fixItReplace(repr->getSourceRange(), fix);
40224022
return constraintType;
40234023
}
4024+
4025+
// Diagnose redundant `any` on an already existential type e.g. any (any P)
4026+
// with a fix-it to remove first any.
4027+
if (constraintType->is<ExistentialType>()) {
4028+
diagnose(repr->getLoc(), diag::redundant_any_in_existential, constraintType)
4029+
.fixItRemove(repr->getAnyLoc());
4030+
return constraintType;
4031+
}
40244032

4025-
auto anyStart = repr->getAnyLoc();
4026-
auto anyEnd = Lexer::getLocForEndOfToken(getASTContext().SourceMgr,
4027-
anyStart);
40284033
diagnose(repr->getLoc(), diag::any_not_existential,
4029-
constraintType->isTypeParameter(),
4030-
constraintType)
4031-
.fixItRemove({anyStart, anyEnd});
4034+
constraintType->isTypeParameter(), constraintType)
4035+
.fixItRemove(repr->getAnyLoc());
40324036
return constraintType;
40334037
}
40344038

test/type/explicit_existential.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,15 @@ func testEnumAssociatedValue() {
331331
case c3((P) -> Void)
332332
}
333333
}
334+
335+
// https://github.com/apple/swift/issues/58920
336+
typealias Iterator = any IteratorProtocol
337+
var example: any Iterator = 5 // expected-error{{redundant 'any' has no effect on existential type 'Iterator' (aka 'any IteratorProtocol')}} {{14-18=}}
338+
// expected-error@-1{{value of type 'Int' does not conform to specified type 'IteratorProtocol'}}
339+
var example1: any (any IteratorProtocol) = 5 // expected-error{{redundant 'any' has no effect on existential type 'any IteratorProtocol'}} {{15-19=}}
340+
// expected-error@-1{{value of type 'Int' does not conform to specified type 'IteratorProtocol'}}
341+
342+
protocol PP {}
343+
struct A : PP {}
344+
let _: any PP = A() // Ok
345+
let _: any (any PP) = A() // expected-error{{redundant 'any' has no effect on existential type 'any PP'}} {{8-12=}}

0 commit comments

Comments
 (0)