diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index ae21d7a9ad319..6feed045acaf1 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2455,16 +2455,10 @@ NOTE(suggest_removing_override, none, ERROR(override_less_available,none, "overriding %0 must be as available as declaration it overrides", (DeclBaseName)) -WARNING(override_less_available_warn,none, - "overriding %0 must be as available as declaration it overrides", - (DeclBaseName)) ERROR(override_accessor_less_available,none, "overriding %0 for %1 must be as available as declaration it overrides", (DescriptiveDeclKind, DeclBaseName)) -WARNING(override_accessor_less_available_warn,none, - "overriding %0 for %1 must be as available as declaration it overrides", - (DescriptiveDeclKind, DeclBaseName)) ERROR(override_let_property,none, "cannot override immutable 'let' property %0 with the getter of a 'var'", diff --git a/include/swift/AST/TypeRefinementContext.h b/include/swift/AST/TypeRefinementContext.h index c0851969fd712..2dca10739444e 100644 --- a/include/swift/AST/TypeRefinementContext.h +++ b/include/swift/AST/TypeRefinementContext.h @@ -154,23 +154,16 @@ class TypeRefinementContext { SourceRange SrcRange; - /// Runtime availability information for the code in this context. AvailabilityContext AvailabilityInfo; - /// Runtime availability information as explicitly declared by attributes - /// for the inlinable code in this context. Compared to AvailabilityInfo, - /// this is not bounded to the minimum deployment OS version. - AvailabilityContext AvailabilityInfoExplicit; - std::vector Children; TypeRefinementContext(ASTContext &Ctx, IntroNode Node, TypeRefinementContext *Parent, SourceRange SrcRange, - const AvailabilityContext &Info, - const AvailabilityContext &InfoExplicit); + const AvailabilityContext &Info); public: - + /// Create the root refinement context for the given SourceFile. static TypeRefinementContext *createRoot(SourceFile *SF, const AvailabilityContext &Info); @@ -179,9 +172,8 @@ class TypeRefinementContext { static TypeRefinementContext *createForDecl(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent, const AvailabilityContext &Info, - const AvailabilityContext &InfoExplicit, SourceRange SrcRange); - + /// Create a refinement context for the Then branch of the given IfStmt. static TypeRefinementContext * createForIfStmtThen(ASTContext &Ctx, IfStmt *S, TypeRefinementContext *Parent, @@ -248,19 +240,11 @@ class TypeRefinementContext { SourceRange getSourceRange() const { return SrcRange; } /// Returns the information on what can be assumed present at run time when - /// running code contained in this context, taking into account the minimum - /// deployment target. + /// running code contained in this context. const AvailabilityContext &getAvailabilityInfo() const { return AvailabilityInfo; } - /// Returns the information on what can be assumed present at run time when - /// running code contained in this context if it were to be inlined, - /// without considering the minimum deployment target. - const AvailabilityContext &getAvailabilityInfoExplicit() const { - return AvailabilityInfoExplicit; - } - /// Adds a child refinement context. void addChild(TypeRefinementContext *Child) { assert(Child->getSourceRange().isValid()); diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 20e9fb6132ec1..e042a3dda668f 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -144,13 +144,8 @@ static bool isBetterThan(const AvailableAttr *newAttr, return true; // If they belong to the same platform, the one that introduces later wins. - if (prevAttr->Platform == newAttr->Platform) { - if (newAttr->isUnconditionallyUnavailable()) - return true; - if (prevAttr->isUnconditionallyUnavailable()) - return false; + if (prevAttr->Platform == newAttr->Platform) return prevAttr->Introduced.getValue() < newAttr->Introduced.getValue(); - } // If the new attribute's platform inherits from the old one, it wins. return inheritsAvailabilityFromPlatform(newAttr->Platform, @@ -163,12 +158,10 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) { for (auto Attr : D->getAttrs()) { auto *AvailAttr = dyn_cast(Attr); - if (AvailAttr == nullptr || + if (AvailAttr == nullptr || !AvailAttr->Introduced.hasValue() || !AvailAttr->isActivePlatform(Ctx) || AvailAttr->isLanguageVersionSpecific() || - AvailAttr->isPackageDescriptionVersionSpecific() || - (!AvailAttr->Introduced.hasValue() && - !AvailAttr->isUnconditionallyUnavailable())) { + AvailAttr->isPackageDescriptionVersionSpecific()) { continue; } @@ -179,9 +172,6 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) { if (!bestAvailAttr) return None; - if (bestAvailAttr->isUnconditionallyUnavailable()) - return AvailabilityContext(VersionRange::empty()); - return AvailabilityContext{ VersionRange::allGTE(bestAvailAttr->Introduced.getValue())}; } diff --git a/lib/AST/TypeRefinementContext.cpp b/lib/AST/TypeRefinementContext.cpp index 3fe283bebd896..c5bcaeb4e0d54 100644 --- a/lib/AST/TypeRefinementContext.cpp +++ b/lib/AST/TypeRefinementContext.cpp @@ -28,14 +28,12 @@ using namespace swift; TypeRefinementContext::TypeRefinementContext(ASTContext &Ctx, IntroNode Node, TypeRefinementContext *Parent, SourceRange SrcRange, - const AvailabilityContext &Info, - const AvailabilityContext &InfoExplicit) - : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info), - AvailabilityInfoExplicit(InfoExplicit) { + const AvailabilityContext &Info) + : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info) { if (Parent) { assert(SrcRange.isValid()); Parent->addChild(this); - assert(InfoExplicit.isContainedIn(Parent->getAvailabilityInfoExplicit())); + assert(Info.isContainedIn(Parent->getAvailabilityInfo())); } Ctx.addDestructorCleanup(Children); } @@ -48,20 +46,18 @@ TypeRefinementContext::createRoot(SourceFile *SF, ASTContext &Ctx = SF->getASTContext(); return new (Ctx) TypeRefinementContext(Ctx, SF, - /*Parent=*/nullptr, SourceRange(), Info, - AvailabilityContext::alwaysAvailable()); + /*Parent=*/nullptr, SourceRange(), Info); } TypeRefinementContext * TypeRefinementContext::createForDecl(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent, const AvailabilityContext &Info, - const AvailabilityContext &InfoExplicit, SourceRange SrcRange) { assert(D); assert(Parent); return new (Ctx) - TypeRefinementContext(Ctx, D, Parent, SrcRange, Info, InfoExplicit); + TypeRefinementContext(Ctx, D, Parent, SrcRange, Info); } TypeRefinementContext * @@ -72,7 +68,7 @@ TypeRefinementContext::createForIfStmtThen(ASTContext &Ctx, IfStmt *S, assert(Parent); return new (Ctx) TypeRefinementContext(Ctx, IntroNode(S, /*IsThen=*/true), Parent, - S->getThenStmt()->getSourceRange(), Info, Info); + S->getThenStmt()->getSourceRange(), Info); } TypeRefinementContext * @@ -83,7 +79,7 @@ TypeRefinementContext::createForIfStmtElse(ASTContext &Ctx, IfStmt *S, assert(Parent); return new (Ctx) TypeRefinementContext(Ctx, IntroNode(S, /*IsThen=*/false), Parent, - S->getElseStmt()->getSourceRange(), Info, Info); + S->getElseStmt()->getSourceRange(), Info); } TypeRefinementContext * @@ -96,7 +92,7 @@ TypeRefinementContext::createForConditionFollowingQuery(ASTContext &Ctx, assert(Parent); SourceRange Range(PAI->getEndLoc(), LastElement.getEndLoc()); return new (Ctx) TypeRefinementContext(Ctx, PAI, Parent, Range, - Info, Info); + Info); } TypeRefinementContext * @@ -111,7 +107,7 @@ TypeRefinementContext::createForGuardStmtFallthrough(ASTContext &Ctx, SourceRange Range(RS->getEndLoc(), ContainingBraceStmt->getEndLoc()); return new (Ctx) TypeRefinementContext(Ctx, IntroNode(RS, /*IsFallthrough=*/true), - Parent, Range, Info, Info); + Parent, Range, Info); } TypeRefinementContext * @@ -122,7 +118,7 @@ TypeRefinementContext::createForGuardStmtElse(ASTContext &Ctx, GuardStmt *RS, assert(Parent); return new (Ctx) TypeRefinementContext(Ctx, IntroNode(RS, /*IsFallthrough=*/false), Parent, - RS->getBody()->getSourceRange(), Info, Info); + RS->getBody()->getSourceRange(), Info); } TypeRefinementContext * @@ -132,7 +128,7 @@ TypeRefinementContext::createForWhileStmtBody(ASTContext &Ctx, WhileStmt *S, assert(S); assert(Parent); return new (Ctx) TypeRefinementContext( - Ctx, S, Parent, S->getBody()->getSourceRange(), Info, Info); + Ctx, S, Parent, S->getBody()->getSourceRange(), Info); } // Only allow allocation of TypeRefinementContext using the allocator in @@ -300,7 +296,6 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr, OS << "(" << getReasonName(getReason()); OS << " versions=" << AvailabilityInfo.getOSVersion().getAsString(); - OS << " explicit=" << AvailabilityInfoExplicit.getOSVersion().getAsString(); if (getReason() == Reason::Decl) { Decl *D = Node.getAsDecl(); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 81cb3ee453050..079ded2e02094 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -1817,27 +1817,18 @@ static void applyAvailableAttribute(Decl *decl, AvailabilityContext &info, if (info.isAlwaysAvailable()) return; - PlatformAgnosticAvailabilityKind platformAgnosticAvailability; - llvm::VersionTuple introducedVersion; - if (info.isKnownUnreachable()) { - platformAgnosticAvailability = PlatformAgnosticAvailabilityKind::Unavailable; - } else { - platformAgnosticAvailability = PlatformAgnosticAvailabilityKind::None; - introducedVersion = info.getOSVersion().getLowerEndpoint(); - } - llvm::VersionTuple noVersion; auto AvAttr = new (C) AvailableAttr(SourceLoc(), SourceRange(), targetPlatform(C.LangOpts), /*Message=*/StringRef(), /*Rename=*/StringRef(), - introducedVersion, + info.getOSVersion().getLowerEndpoint(), /*IntroducedRange*/SourceRange(), /*Deprecated=*/noVersion, /*DeprecatedRange*/SourceRange(), /*Obsoleted=*/noVersion, /*ObsoletedRange*/SourceRange(), - platformAgnosticAvailability, + PlatformAgnosticAvailabilityKind::None, /*Implicit=*/false); decl->getAttrs().add(AvAttr); diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 65a32b8de3b4a..3b057395d2156 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -2638,8 +2638,7 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { if (isAlwaysWeakImported()) OS << "[weak_imported] "; auto availability = getAvailabilityForLinkage(); - if (!availability.isAlwaysAvailable() && - !availability.isKnownUnreachable()) { + if (!availability.isAlwaysAvailable()) { auto version = availability.getOSVersion().getLowerEndpoint(); OS << "[available " << version.getAsString() << "] "; } diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index d0661b189ba3e..29597227c705b 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -1543,16 +1543,9 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) { VersionRange::allGTE(attr->Introduced.getValue())}; if (!AttrRange.isContainedIn(EnclosingAnnotatedRange.getValue())) { - // Don't show this error in swiftinterfaces if it is about a context that - // is unavailable, this was in the stdlib at Swift 5.3. - SourceFile *Parent = D->getDeclContext()->getParentSourceFile(); - if (!Parent || Parent->Kind != SourceFileKind::Interface || - !EnclosingAnnotatedRange.getValue().isKnownUnreachable()) { - diagnose(attr->getLocation(), - diag::availability_decl_more_than_enclosing); - diagnose(EnclosingDecl->getLoc(), - diag::availability_decl_more_than_enclosing_enclosing_here); - } + diagnose(attr->getLocation(), diag::availability_decl_more_than_enclosing); + diagnose(EnclosingDecl->getLoc(), + diag::availability_decl_more_than_enclosing_enclosing_here); } } diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 4acbe673bb823..3cb6978441c93 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -170,30 +170,13 @@ class TypeRefinementContextBuilder : private ASTWalker { // The potential versions in the declaration are constrained by both // the declared availability of the declaration and the potential versions // of its lexical context. - AvailabilityContext ExplicitDeclInfo = + AvailabilityContext DeclInfo = swift::AvailabilityInference::availableRange(D, Context); - ExplicitDeclInfo.intersectWith( - getCurrentTRC()->getAvailabilityInfoExplicit()); - AvailabilityContext DeclInfo = ExplicitDeclInfo; - - // When the body is inlinable consider only the explicitly declared range - // for checking availability. Otherwise, use the parent range which may - // begin at the minimum deployment target. - // - // Also use the parent range when reading swiftinterfaces for - // retrocompatibility. - bool isInlinable = D->getAttrs().hasAttribute() || - D->getAttrs().hasAttribute(); - SourceFile *SF = D->getDeclContext()->getParentSourceFile(); - if (!isInlinable || (SF && SF->Kind == SourceFileKind::Interface)) { - DeclInfo.intersectWith( - getCurrentTRC()->getAvailabilityInfo()); - } + DeclInfo.intersectWith(getCurrentTRC()->getAvailabilityInfo()); TypeRefinementContext *NewTRC = TypeRefinementContext::createForDecl(Context, D, getCurrentTRC(), DeclInfo, - ExplicitDeclInfo, refinementSourceRangeForDecl(D)); // Record the TRC for this storage declaration so that @@ -207,27 +190,19 @@ class TypeRefinementContextBuilder : private ASTWalker { return NewTRC; } - + /// Returns true if the declaration should introduce a new refinement context. bool declarationIntroducesNewContext(Decl *D) { if (!isa(D) && !isa(D)) { return false; } - - // Explicit inlinability may to the decl being used on an earlier OS - // version when inlined on the client side. This check assumes that - // implicit decls are handled elsewhere. - bool isExplicitlyInlinable = !D->isImplicit() && - (D->getAttrs().hasAttribute() || - D->getAttrs().hasAttribute()); - + // No need to introduce a context if the declaration does not have an - // availability or non-implicit inlinable attribute. - if (!hasActiveAvailableAttribute(D, Context) && - !isExplicitlyInlinable) { + // availability attribute. + if (!hasActiveAvailableAttribute(D, Context)) { return false; } - + // Only introduce for an AbstractStorageDecl if it is not local. // We introduce for the non-local case because these may // have getters and setters (and these may be synthesized, so they might @@ -238,7 +213,7 @@ class TypeRefinementContextBuilder : private ASTWalker { return false; } } - + return true; } @@ -699,7 +674,9 @@ TypeChecker::overApproximateAvailabilityAtLocation(SourceLoc loc, // refined. For now, this is fine -- but if we ever synthesize #available(), // this will be a real problem. - auto OverApproximateContext = AvailabilityContext::alwaysAvailable(); + // We can assume we are running on at least the minimum deployment target. + auto OverApproximateContext = + AvailabilityContext::forDeploymentTarget(Context); auto isInvalidLoc = [SF](SourceLoc loc) { return SF ? loc.isInvalid() : true; }; @@ -730,14 +707,6 @@ TypeChecker::overApproximateAvailabilityAtLocation(SourceLoc loc, } } - // If we still don't have an introduction version, use the current deployment - // target. This covers cases where an inlinable function and its parent - // contexts don't have explicit availability attributes. - if (!OverApproximateContext.getOSVersion().hasLowerEndpoint()) { - auto currentOS = AvailabilityContext::forDeploymentTarget(Context); - OverApproximateContext.constrainWith(currentOS); - } - return OverApproximateContext; } diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index f0bc0550a8085..11c7985877a54 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1689,37 +1689,16 @@ static bool diagnoseOverrideForAvailability(ValueDecl *override, if (isRedundantAccessorOverrideAvailabilityDiagnostic(override, base)) return false; - auto &ctx = override->getASTContext(); - auto &diags = ctx.Diags; + auto &diags = override->getASTContext().Diags; if (auto *accessor = dyn_cast(override)) { - bool downgradeToWarning = override->getAttrs().isUnavailable(ctx); - diags.diagnose(override, - downgradeToWarning? - diag::override_accessor_less_available_warn : - diag::override_accessor_less_available, + diags.diagnose(override, diag::override_accessor_less_available, accessor->getDescriptiveKind(), accessor->getStorage()->getBaseName()); diags.diagnose(base, diag::overridden_here); return true; } - bool downgradeToWarning = false; - if (override->getAttrs().isUnavailable(ctx)) { - // Don't report constructors that are marked unavailable as being less - // available than their introduction. This was previously allowed and - // can be used to forbid the direct use of a constructor in a subclass. - // Note that even when marked unavailable the constructor could be called - // by other inherited constructors. - if (isa(override)) - return false; - - // Report as a warning other unavailable overrides. - downgradeToWarning = true; - } - - diags.diagnose(override, - downgradeToWarning? diag::override_less_available_warn : - diag::override_less_available, + diags.diagnose(override, diag::override_less_available, override->getBaseName()); diags.diagnose(base, diag::overridden_here); diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 6016d82df68dc..01cf489a25a6b 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -1455,11 +1455,6 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement, return CheckKind::UsableFromInline; } - if (match.Witness->getAttrs().isUnavailable(getASTContext()) && - !requirement->getAttrs().isUnavailable(getASTContext())) { - return CheckKind::WitnessUnavailable; - } - auto requiredAvailability = AvailabilityContext::alwaysAvailable(); if (checkWitnessAvailability(requirement, match.Witness, &requiredAvailability)) { @@ -1489,6 +1484,11 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement, } } + if (match.Witness->getAttrs().isUnavailable(getASTContext()) && + !requirement->getAttrs().isUnavailable(getASTContext())) { + return CheckKind::WitnessUnavailable; + } + return CheckKind::Success; } diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 767455fa5f004..70fa8597c5470 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -430,8 +430,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { Optional available; auto availability = F.getAvailabilityForLinkage(); - if (!availability.isAlwaysAvailable() && - !availability.isKnownUnreachable()) { + if (!availability.isAlwaysAvailable()) { available = availability.getOSVersion().getLowerEndpoint(); } ENCODE_VER_TUPLE(available, available) diff --git a/test/SILGen/vtables.swift b/test/SILGen/vtables.swift index 9c0f2fafc7369..387fd0df1e69d 100644 --- a/test/SILGen/vtables.swift +++ b/test/SILGen/vtables.swift @@ -21,6 +21,7 @@ class C : B { // CHECK: #A.bar: {{.*}} : @$s7vtables1CC3bar{{[_0-9a-zA-Z]*}}F // CHECK: #A.bas: {{.*}} : @$s7vtables1AC3bas{{[_0-9a-zA-Z]*}}F // CHECK: #A.qux: {{.*}} : @$s7vtables1CC3qux{{[_0-9a-zA-Z]*}}F +// CHECK: #A.flux: {{.*}} : @$s7vtables1BC4flux{{[_0-9a-zA-Z]*}}F // CHECK: #B.init!allocator: {{.*}} : @$s7vtables1CC{{[_0-9a-zA-Z]*}}fC // CHECK: #B.zim: {{.*}} : @$s7vtables1BC3zim{{[_0-9a-zA-Z]*}}F // CHECK: #B.zang: {{.*}} : @$s7vtables1CC4zang{{[_0-9a-zA-Z]*}}F @@ -34,7 +35,7 @@ class A { func bar() {} func bas() {} func qux() {} - @available(*, unavailable) func flux() {} + func flux() {} } // CHECK: sil_vtable A { @@ -53,6 +54,7 @@ class B : A { // bar inherited from A // bas inherited from A override func qux() {} + @available(*, unavailable) override func flux() {} func zim() {} func zang() {} @@ -63,6 +65,7 @@ class B : A { // CHECK: #A.bar: {{.*}} : @$s7vtables1AC3bar{{[_0-9a-zA-Z]*}}F // CHECK: #A.bas: {{.*}} : @$s7vtables1AC3bas{{[_0-9a-zA-Z]*}}F // CHECK: #A.qux: {{.*}} : @$s7vtables1BC3qux{{[_0-9a-zA-Z]*}}F +// CHECK: #A.flux: {{.*}} : @$s7vtables1BC4flux{{[_0-9a-zA-Z]*}}F // CHECK: #B.init!allocator: {{.*}} : @$s7vtables1BC{{[_0-9a-zA-Z]*}}fC // CHECK: #B.zim: {{.*}} : @$s7vtables1BC3zim{{[_0-9a-zA-Z]*}}F // CHECK: #B.zang: {{.*}} : @$s7vtables1BC4zang{{[_0-9a-zA-Z]*}}F diff --git a/test/Sema/availability_inlinable.swift b/test/Sema/availability_inlinable.swift deleted file mode 100644 index 34750bce1134e..0000000000000 --- a/test/Sema/availability_inlinable.swift +++ /dev/null @@ -1,48 +0,0 @@ -/// Inlinable functions should check availability by ignoring the current -/// deployment target as clients could inline the function in a lower target. - -// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx11.0 -// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.10 - -// REQUIRES: OS=macosx - -@available(macOS 10.10, *) -@inlinable -public func availMacOS10() { - availMacOS11() // expected-error {{'availMacOS11()' is only available in macOS 11.0 or newer}} - // expected-note @-1 {{add 'if #available' version check}} - - if #available(macOS 11.0, *) { - availMacOS11() - } else { - availMacOS11() // expected-error {{'availMacOS11()' is only available in macOS 11.0 or newer}} - // expected-note @-1 {{add 'if #available' version check}} - } - - if #available(macOS 10.15, *) { - availMacOS11() // expected-error {{'availMacOS11()' is only available in macOS 11.0 or newer}} - // expected-note @-1 {{add 'if #available' version check}} - } - - func nestedFunc() { - availMacOS11() // expected-error {{'availMacOS11()' is only available in macOS 11.0 or newer}} - // expected-note @-1 {{add 'if #available' version check}} - } -} - -@available(macOS 11.0, *) -public func availMacOS11() { } - -@available(macOS 10.10, *) -public struct StructAvailMacOS10 { - @inlinable - public func availabilityFromTheContextInlinable() { - // expected-note @-1 {{add @available attribute to enclosing instance method}} - availMacOS11() // expected-error {{'availMacOS11()' is only available in macOS 11.0 or newer}} - // expected-note @-1 {{add 'if #available' version check}} - - availabilityFromContext() - } - - public func availabilityFromContext() {} -} diff --git a/test/Sema/availability_refinement_contexts.swift b/test/Sema/availability_refinement_contexts.swift index 44f6b8fd05f6e..088a644384ff6 100644 --- a/test/Sema/availability_refinement_contexts.swift +++ b/test/Sema/availability_refinement_contexts.swift @@ -1,18 +1,18 @@ -// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts -target %target-cpu-apple-macosx10.50 %s > %t.dump 2>&1 +// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s > %t.dump 2>&1 // RUN: %FileCheck --strict-whitespace %s < %t.dump // REQUIRES: OS=macosx -// CHECK: {{^}}(root versions=[10.50.0,+Inf) explicit=all +// CHECK: {{^}}(root versions=[10.{{[0-9]+}}.0,+Inf) -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=SomeClass -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=someMethod() -// CHECK-NEXT: {{^}} (decl versions=[10.53,+Inf) explicit=[10.53,+Inf) decl=someInnerFunc() -// CHECK-NEXT: {{^}} (decl versions=[10.53,+Inf) explicit=[10.53,+Inf) decl=InnerClass -// CHECK-NEXT: {{^}} (decl versions=[10.54,+Inf) explicit=[10.54,+Inf) decl=innerClassMethod -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=someStaticProperty -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=someComputedProperty -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=someOtherMethod() +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=SomeClass +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=someMethod() +// CHECK-NEXT: {{^}} (decl versions=[10.53,+Inf) decl=someInnerFunc() +// CHECK-NEXT: {{^}} (decl versions=[10.53,+Inf) decl=InnerClass +// CHECK-NEXT: {{^}} (decl versions=[10.54,+Inf) decl=innerClassMethod +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=someStaticProperty +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=someComputedProperty +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=someOtherMethod() @available(OSX 10.51, *) class SomeClass { @available(OSX 10.52, *) @@ -43,13 +43,13 @@ class SomeClass { func someOtherMethod() { } } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=someFunction() +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=someFunction() @available(OSX 10.51, *) func someFunction() { } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=SomeProtocol -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=protoMethod() -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=protoProperty +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=SomeProtocol +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=protoMethod() +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=protoProperty @available(OSX 10.51, *) protocol SomeProtocol { @available(OSX 10.52, *) @@ -59,26 +59,26 @@ protocol SomeProtocol { var protoProperty: Int { get } } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=extension.SomeClass -// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) explicit=[10.52,+Inf) decl=someExtensionFunction() +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=extension.SomeClass +// CHECK-NEXT: {{^}} (decl versions=[10.52,+Inf) decl=someExtensionFunction() @available(OSX 10.51, *) extension SomeClass { @available(OSX 10.52, *) func someExtensionFunction() { } } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=functionWithStmtCondition -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.52,+Inf) explicit=[10.52,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.53,+Inf) explicit=[10.53,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.53,+Inf) explicit=[10.53,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.54,+Inf) explicit=[10.54,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.54,+Inf) explicit=[10.54,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.55,+Inf) explicit=[10.55,+Inf) -// CHECK-NEXT: {{^}} (decl versions=[10.55,+Inf) explicit=[10.55,+Inf) decl=funcInGuardElse() -// CHECK-NEXT: {{^}} (guard_fallthrough versions=[10.55,+Inf) explicit=[10.55,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.56,+Inf) explicit=[10.56,+Inf) -// CHECK-NEXT: {{^}} (guard_fallthrough versions=[10.56,+Inf) explicit=[10.56,+Inf) -// CHECK-NEXT: {{^}} (decl versions=[10.57,+Inf) explicit=[10.57,+Inf) decl=funcInInnerIfElse() +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=functionWithStmtCondition +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.52,+Inf) +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.53,+Inf) +// CHECK-NEXT: {{^}} (if_then versions=[10.53,+Inf) +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.54,+Inf) +// CHECK-NEXT: {{^}} (if_then versions=[10.54,+Inf) +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.55,+Inf) +// CHECK-NEXT: {{^}} (decl versions=[10.55,+Inf) decl=funcInGuardElse() +// CHECK-NEXT: {{^}} (guard_fallthrough versions=[10.55,+Inf) +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.56,+Inf) +// CHECK-NEXT: {{^}} (guard_fallthrough versions=[10.56,+Inf) +// CHECK-NEXT: {{^}} (decl versions=[10.57,+Inf) decl=funcInInnerIfElse() @available(OSX 10.51, *) func functionWithStmtCondition() { if #available(OSX 10.52, *), @@ -97,11 +97,11 @@ func functionWithStmtCondition() { } } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=functionWithUnnecessaryStmtCondition -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.53,+Inf) explicit=[10.53,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.53,+Inf) explicit=[10.53,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.54,+Inf) explicit=[10.54,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.54,+Inf) explicit=[10.54,+Inf) +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=functionWithUnnecessaryStmtCondition +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.53,+Inf) +// CHECK-NEXT: {{^}} (if_then versions=[10.53,+Inf) +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.54,+Inf) +// CHECK-NEXT: {{^}} (if_then versions=[10.54,+Inf) @available(OSX 10.51, *) func functionWithUnnecessaryStmtCondition() { @@ -127,13 +127,13 @@ func functionWithUnnecessaryStmtCondition() { } } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=functionWithUnnecessaryStmtConditionsHavingElseBranch -// CHECK-NEXT: {{^}} (if_else versions=empty explicit=empty -// CHECK-NEXT: {{^}} (decl versions=empty explicit=empty decl=funcInInnerIfElse() -// CHECK-NEXT: {{^}} (if_else versions=empty explicit=empty -// CHECK-NEXT: {{^}} (guard_else versions=empty explicit=empty -// CHECK-NEXT: {{^}} (guard_else versions=empty explicit=empty -// CHECK-NEXT: {{^}} (if_else versions=empty explicit=empty +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=functionWithUnnecessaryStmtConditionsHavingElseBranch +// CHECK-NEXT: {{^}} (if_else versions=empty +// CHECK-NEXT: {{^}} (decl versions=empty decl=funcInInnerIfElse() +// CHECK-NEXT: {{^}} (if_else versions=empty +// CHECK-NEXT: {{^}} (guard_else versions=empty +// CHECK-NEXT: {{^}} (guard_else versions=empty +// CHECK-NEXT: {{^}} (if_else versions=empty @available(OSX 10.51, *) func functionWithUnnecessaryStmtConditionsHavingElseBranch(p: Int?) { @@ -180,10 +180,10 @@ func functionWithUnnecessaryStmtConditionsHavingElseBranch(p: Int?) { } -// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) explicit=[10.51,+Inf) decl=functionWithWhile() -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.52,+Inf) explicit=[10.52,+Inf) -// CHECK-NEXT: {{^}} (while_body versions=[10.52,+Inf) explicit=[10.52,+Inf) -// CHECK-NEXT: {{^}} (decl versions=[10.54,+Inf) explicit=[10.54,+Inf) decl=funcInWhileBody() +// CHECK-NEXT: {{^}} (decl versions=[10.51,+Inf) decl=functionWithWhile() +// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.52,+Inf) +// CHECK-NEXT: {{^}} (while_body versions=[10.52,+Inf) +// CHECK-NEXT: {{^}} (decl versions=[10.54,+Inf) decl=funcInWhileBody() @available(OSX 10.51, *) func functionWithWhile() { while #available(OSX 10.52, *), @@ -192,49 +192,3 @@ func functionWithWhile() { func funcInWhileBody() { } } } - -// CHECK-NEXT: {{^}} (decl versions=[10.50.0,+Inf) explicit=[10.10,+Inf) decl=olderFunction() -@available(macOS 10.10, *) -public func olderFunction() { -} - -// CHECK-NEXT: {{^}} (decl versions=empty explicit=empty decl=unavailableFunction() -@available(macOS, unavailable) -public func unavailableFunction() { -} - -// CHECK-NEXT: {{^}} (decl versions=[10.10,+Inf) explicit=[10.10,+Inf) decl=inlinableFunction() -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.55,+Inf) explicit=[10.55,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.55,+Inf) explicit=[10.55,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.15,+Inf) -// CHECK-NEXT: {{^}} (if_then versions=[10.15,+Inf) explicit=[10.15,+Inf) -// CHECK-NEXT: {{^}} (condition_following_availability versions=[10.15,+Inf) explicit=[10.15,+Inf) -// CHECK-NEXT: {{^}} (guard_fallthrough versions=[10.15,+Inf) explicit=[10.15,+Inf) -@available(macOS 10.10, *) -@inlinable -public func inlinableFunction() { - if #available(macOS 10.55, *) { } else { } - - if #available(macOS 10.15, *) { } - - guard #available(macOS 10.15, *) else { } - - func nestedFunc() { } -} - -// CHECK-NEXT: {{^}} (decl versions=[10.50.0,+Inf) explicit=[10.10,+Inf) decl=SomeOlderClass -// CHECK-NEXT: {{^}} (decl versions=[10.10,+Inf) explicit=[10.10,+Inf) decl=someInlinableMethod() -// CHECK-NEXT: {{^}} (decl versions=[10.15,+Inf) explicit=[10.15,+Inf) decl=someOtherInlinableMethod() -// CHECK-NEXT: {{^}} (decl versions=[10.50.0,+Inf) explicit=[10.15,+Inf) decl=someMethod() -@available(OSX 10.10, *) -class SomeOlderClass { - @inlinable - func someInlinableMethod() { } - - @available(OSX 10.15, *) - @inlinable - func someOtherInlinableMethod() { } - - @available(OSX 10.15, *) - func someMethod() { } -} diff --git a/test/Sema/availability_versions.swift b/test/Sema/availability_versions.swift index 97ec079f50d06..ad4159215becf 100644 --- a/test/Sema/availability_versions.swift +++ b/test/Sema/availability_versions.swift @@ -788,33 +788,26 @@ class UnavailableClassExtendingUnavailableClass : ClassAvailableOn10_51 { // Method availability is contravariant class SuperWithAlwaysAvailableMembers { - - required init() {} // expected-note {{overridden declaration is here}} - - func shouldAlwaysBeAvailableMethod() { // expected-note 2 {{overridden declaration is here}} + func shouldAlwaysBeAvailableMethod() { // expected-note {{overridden declaration is here}} } - var shouldAlwaysBeAvailableProperty: Int { // expected-note 2 {{overridden declaration is here}} + var shouldAlwaysBeAvailableProperty: Int { // expected-note {{overridden declaration is here}} get { return 9 } set(newVal) {} } var setterShouldAlwaysBeAvailableProperty: Int { get { return 9 } - set(newVal) {} // expected-note 2 {{overridden declaration is here}} + set(newVal) {} // expected-note {{overridden declaration is here}} } var getterShouldAlwaysBeAvailableProperty: Int { - get { return 9 } // expected-note 2 {{overridden declaration is here}} + get { return 9 } // expected-note {{overridden declaration is here}} set(newVal) {} } } class SubWithLimitedMemberAvailability : SuperWithAlwaysAvailableMembers { - - @available(OSX, introduced: 10.51) - required init() {} // expected-error {{overriding 'init' must be as available as declaration it overrides}} - @available(OSX, introduced: 10.51) override func shouldAlwaysBeAvailableMethod() { // expected-error {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}} } @@ -839,35 +832,6 @@ class SubWithLimitedMemberAvailability : SuperWithAlwaysAvailableMembers { } } -class SubWithUnavailableMembers : SuperWithAlwaysAvailableMembers { - - @available(OSX, unavailable) - required init() {} - - @available(OSX, unavailable) - override func shouldAlwaysBeAvailableMethod() { // expected-warning {{overriding 'shouldAlwaysBeAvailableMethod' must be as available as declaration it overrides}} - } - - @available(OSX, unavailable) - override var shouldAlwaysBeAvailableProperty: Int { // expected-warning {{overriding 'shouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}} - get { return 10 } - set(newVal) {} - } - - override var setterShouldAlwaysBeAvailableProperty: Int { - get { return 9 } - @available(OSX, unavailable) - set(newVal) {} // expected-warning {{overriding setter for 'setterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}} - // This is a terrible diagnostic. rdar://problem/20427938 - } - - override var getterShouldAlwaysBeAvailableProperty: Int { - @available(OSX, unavailable) - get { return 9 } // expected-warning {{overriding getter for 'getterShouldAlwaysBeAvailableProperty' must be as available as declaration it overrides}} - set(newVal) {} - } -} - class SuperWithLimitedMemberAvailability { @available(OSX, introduced: 10.51) func someMethod() { diff --git a/test/attr/attr_availability_maccatalyst.swift b/test/attr/attr_availability_maccatalyst.swift index 2346cb9ec0dfc..f69cc8aea1b3d 100644 --- a/test/attr/attr_availability_maccatalyst.swift +++ b/test/attr/attr_availability_maccatalyst.swift @@ -1,6 +1,6 @@ // RUN: %swift -typecheck -verify -parse-stdlib -target x86_64-apple-ios51.0-macabi %s -// REQUIRES: VENDOR=apple +// REQUIRES: OS=maccatalyst @available(macCatalyst, introduced: 1.0, deprecated: 2.0, obsoleted: 9.0, message: "you don't want to do that anyway") @@ -52,16 +52,6 @@ func introducedLaterOnMacCatalyst() { func introducedLaterOnIOS() { } -@available(iOS, introduced: 1.0) -@available(macCatalyst, unavailable) -func unavailableOnMacCatalyst() { // expected-note 3 {{'unavailableOnMacCatalyst()' has been explicitly marked unavailable here}} -} - -@available(iOS, unavailable) -@available(macCatalyst, introduced: 1.0) -func unavailableOnIOS() { -} - // expected-note@+1 *{{add @available attribute to enclosing global function}} func testPoundAvailable() { @@ -70,9 +60,6 @@ func testPoundAvailable() { // expected-note@-1 {{add 'if #available' version check}} introducedLaterOnIOS() // expected-error {{'introducedLaterOnIOS()' is only available in Mac Catalyst 56.0 or newer}} // expected-note@-1 {{add 'if #available' version check}} - - unavailableOnMacCatalyst() // expected-error {{'unavailableOnMacCatalyst()' is unavailable in Mac Catalyst}} - unavailableOnIOS() } // macCatalyst should win over iOS when present @@ -82,9 +69,6 @@ func testPoundAvailable() { // expected-note@-1 {{add 'if #available' version check}} introducedLaterOnIOS() // expected-error {{'introducedLaterOnIOS()' is only available in Mac Catalyst 56.0 or newer}} // expected-note@-1 {{add 'if #available' version check}} - - unavailableOnMacCatalyst() // expected-error {{'unavailableOnMacCatalyst()' is unavailable in Mac Catalyst}} - unavailableOnIOS() } if #available(iOS 55.0, macCatalyst 56.0, *) { @@ -104,9 +88,6 @@ func testPoundAvailable() { // expected-note@-1 {{add 'if #available' version check}} introducedLaterOnIOS() // expected-error {{'introducedLaterOnIOS()' is only available in Mac Catalyst 56.0 or newer}} // expected-note@-1 {{add 'if #available' version check}} - - unavailableOnMacCatalyst() // expected-error {{'unavailableOnMacCatalyst()' is unavailable in Mac Catalyst}} - unavailableOnIOS() } if #available(iOS 56.0, *) {