diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 69380de83f722..ae25d9467e509 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1972,10 +1972,12 @@ NOTE(objc_generic_extension_using_type_parameter_here,none, "generic parameter used here", ()) NOTE(objc_generic_extension_using_type_parameter_try_objc,none, "add '@objc' to allow uses of 'self' within the function body", ()) +ERROR(unsupported_existential_extension,none, + "extension of existential type %0 is not supported", (Type)) ERROR(invalid_nominal_extension,none, "extension of type %0 must be declared as an extension of %1", (Type, Type)) -NOTE(invalid_nominal_extension_rewrite,none, +NOTE(invalid_extension_rewrite,none, "did you mean to extend %0 instead?", (Type)) ERROR(synthesized_nominal_extension,none, "cannot extend synthesized type %0", (Type)) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index d476b7bec76e5..189b358be6bc6 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -3084,21 +3084,31 @@ class DeclChecker : public DeclVisitor { const bool wasAlreadyInvalid = ED->isInvalid(); ED->setInvalid(); if (!extType->hasError() && extType->getAnyNominal()) { + auto canExtType = extType->getCanonicalType(); + if (auto existential = canExtType->getAs()) { + ED->diagnose(diag::unsupported_existential_extension, extType) + .highlight(ED->getExtendedTypeRepr()->getSourceRange()); + ED->diagnose(diag::invalid_extension_rewrite, + existential->getConstraintType()) + .fixItReplace(ED->getExtendedTypeRepr()->getSourceRange(), + existential->getConstraintType()->getString()); + return; + } + // If we've got here, then we have some kind of extension of a prima - // fascie non-nominal type. This can come up when we're projecting + // facie non-nominal type. This can come up when we're projecting // typealiases out of bound generic types. // // struct Array { typealias Indices = Range } // extension Array.Indices.Bound {} // // Offer to rewrite it to the underlying nominal type. - auto canExtType = extType->getCanonicalType(); if (canExtType.getPointer() != extType.getPointer()) { ED->diagnose(diag::invalid_nominal_extension, extType, canExtType) - .highlight(ED->getExtendedTypeRepr()->getSourceRange()); - ED->diagnose(diag::invalid_nominal_extension_rewrite, canExtType) - .fixItReplace(ED->getExtendedTypeRepr()->getSourceRange(), - canExtType->getString()); + .highlight(ED->getExtendedTypeRepr()->getSourceRange()); + ED->diagnose(diag::invalid_extension_rewrite, canExtType) + .fixItReplace(ED->getExtendedTypeRepr()->getSourceRange(), + canExtType->getString()); return; } } diff --git a/test/decl/ext/extensions.swift b/test/decl/ext/extensions.swift index c6ef3c72b488e..1ae4a4bc7e5da 100644 --- a/test/decl/ext/extensions.swift +++ b/test/decl/ext/extensions.swift @@ -349,7 +349,7 @@ extension Tree.LimbContent.Contents { extension Tree.BoughPayload.Contents { // expected-error@-1 {{extension of type 'Tree.BoughPayload.Contents' (aka 'Nest') must be declared as an extension of 'Nest'}} - // expected-note@-2 {{did you mean to extend 'Nest' instead?}} + // expected-note@-2 {{did you mean to extend 'Nest' instead?}} {{11-37=Nest}} } // https://github.com/apple/swift/issues/52866 @@ -367,3 +367,25 @@ protocol Rdar66943328 { } extension Rdar66943328 where Assoc == Int // expected-error {{expected '{' in extension}} #endif + +// Reject extension of existential type + +protocol P4 {} + +extension any P4 { +// expected-error@-1 {{extension of existential type 'any P4' is not supported}} +// expected-note@-2 {{did you mean to extend 'P4' instead?}} {{11-17=P4}} +} + +typealias A4 = P4 + +extension any A4 { +// expected-error@-1 {{extension of existential type 'any A4' (aka 'any P4') is not supported}} +// expected-note@-2 {{did you mean to extend 'P4' instead?}} {{11-17=P4}} +} + +typealias B4 = any P4 +extension B4 { +// expected-error@-1 {{extension of existential type 'B4' (aka 'any P4') is not supported}} +// expected-note@-2 {{did you mean to extend 'P4' instead?}} {{11-13=P4}} +}