Skip to content

Sema: Skip diagnosing witness availability for unavailable conformances #79537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,14 @@ bool TypeChecker::isAvailabilitySafeForConformance(
assert(dc->getSelfNominalTypeDecl() &&
"Must have a nominal or extension context");

AvailabilityContext contextForConformingDecl =
availabilityForDeclSignature(dc->getAsDecl());

// If the conformance is unavailable then it's irrelevant whether the witness
// is potentially unavailable.
if (contextForConformingDecl.isUnavailable())
return true;

// Make sure that any access of the witness through the protocol
// can only occur when the witness is available. That is, make sure that
// on every version where the conforming declaration is available, if the
Expand All @@ -1703,7 +1711,7 @@ bool TypeChecker::isAvailabilitySafeForConformance(
requirementInfo = AvailabilityInference::availableRange(requirement);

AvailabilityRange infoForConformingDecl =
overApproximateAvailabilityAtLocation(dc->getAsDecl()->getLoc(), dc);
contextForConformingDecl.getPlatformRange();

// Relax the requirements for @_spi witnesses by treating the requirement as
// if it were introduced at the deployment target. This is not strictly sound
Expand Down
6 changes: 6 additions & 0 deletions test/Sema/availability_scopes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,12 @@ extension SomeEnum {
func neverAvailable() {}
}

// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOSAndIntroduced()

@available(macOS, unavailable, introduced: 52)
func unavailableOnMacOSAndIntroduced() {
}

// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=NeverAvailable
// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=unavailableOnMacOS()

Expand Down
65 changes: 65 additions & 0 deletions test/Sema/conformance_availability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,14 @@ extension Bike : Vehicle {
func move() {}
}

@available(macOS, introduced: 100)
struct Wagon {}

@available(macOS, introduced: 100)
extension Wagon : Vehicle {
func move() {}
}

class Car {}
class ClownCar : Car {}

Expand All @@ -478,6 +486,63 @@ extension Car {
extension ClownCar : Vehicle {}
// expected-error@-1 {{protocol 'Vehicle' requires 'move()' to be available in macOS 100 and newer}}

@available(macOS, unavailable)
struct Truck : Vehicle {
func move() {}
}

struct Scooter {}

@available(macOS, unavailable)
extension Scooter : Vehicle {
func move() {}
}

struct Motorcycle {}

@available(macOS, unavailable)
extension Motorcycle : Vehicle {
@available(macOS, introduced: 100)
func move() {}
}

@available(macOS, unavailable)
struct AircraftCarrier {
struct Jet : Vehicle {
@available(macOS, introduced: 100)
func move() {}
}
}

struct Unicycle {
@available(macOS, introduced: 100)
func move() {}
}

@available(macOS, unavailable)
extension Unicycle : Vehicle {}

@available(macOS, unavailable, introduced: 100)
struct Train : Vehicle {
func move() {}
}

struct Blimp {}

@available(macOS, unavailable, introduced: 100)
extension Blimp : Vehicle {
func move() {}
}

@available(macOS, unavailable, introduced: 100)
struct Spaceship {
}

@available(macOS, unavailable, introduced: 100)
extension Spaceship : Vehicle {
func move() {}
}

// rdar://problem/75430966 - Allow using unavailable conformances from unavailable contexts.
@available(*, unavailable)
public enum UnavailableEnum {
Expand Down