Skip to content

Commit 3c0b1ab

Browse files
Merge pull request swiftlang#59015 from LucianoPAlmeida/existential-resolve
[Sema] Check for already existential type while resolving existential
2 parents 262f77f + 20e02a2 commit 3c0b1ab

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
@@ -4709,6 +4709,9 @@ ERROR(unchecked_not_inheritance_clause,none,
47094709
ERROR(unchecked_not_existential,none,
47104710
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))
47114711

4712+
ERROR(redundant_any_in_existential,none,
4713+
"redundant 'any' has no effect on existential type %0",
4714+
(Type))
47124715
ERROR(any_not_existential,none,
47134716
"'any' has no effect on %select{concrete type|type parameter}0 %1",
47144717
(bool, Type))

lib/Sema/TypeCheckType.cpp

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

3990-
if (!constraintType->isExistentialType()) {
3990+
if (!constraintType->isConstraintType()) {
39913991
// Emit a tailored diagnostic for the incorrect optional
39923992
// syntax 'any P?' with a fix-it to add parenthesis.
39933993
auto wrapped = constraintType->getOptionalObjectType();
@@ -4001,14 +4001,18 @@ TypeResolver::resolveExistentialType(ExistentialTypeRepr *repr,
40014001
.fixItReplace(repr->getSourceRange(), fix);
40024002
return constraintType;
40034003
}
4004+
4005+
// Diagnose redundant `any` on an already existential type e.g. any (any P)
4006+
// with a fix-it to remove first any.
4007+
if (constraintType->is<ExistentialType>()) {
4008+
diagnose(repr->getLoc(), diag::redundant_any_in_existential, constraintType)
4009+
.fixItRemove(repr->getAnyLoc());
4010+
return constraintType;
4011+
}
40044012

4005-
auto anyStart = repr->getAnyLoc();
4006-
auto anyEnd = Lexer::getLocForEndOfToken(getASTContext().SourceMgr,
4007-
anyStart);
40084013
diagnose(repr->getLoc(), diag::any_not_existential,
4009-
constraintType->isTypeParameter(),
4010-
constraintType)
4011-
.fixItRemove({anyStart, anyEnd});
4014+
constraintType->isTypeParameter(), constraintType)
4015+
.fixItRemove(repr->getAnyLoc());
40124016
return constraintType;
40134017
}
40144018

test/type/explicit_existential.swift

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

0 commit comments

Comments
 (0)