Files
swift-mirror/test/Sema/conformance_availability_implied.swift
Slava Pestov 8d30df5327 AST: Tweak ConformanceLookupTable::compareConformances() some more
If two conformances imply a conformance to the same marker
protocol, don't diagnose redundancy if they differ by
unavailability. Instead, allow the more available conformance
to win.

This allows declaring a type that conforms to a protocol
that inherits from SendableMetatype, followed by an
unavailable Sendable conformance on the same type.

Fixes rdar://152509409.
2025-06-23 22:54:18 -04:00

69 lines
1.7 KiB
Swift

// RUN: %target-typecheck-verify-swift -swift-version 6
// REQUIRES: OS=macosx
// Protocols:
protocol Base {
func f() // expected-note {{protocol requirement here}}
}
func takesBase<T: Base>(_: T.Type) {}
protocol Derived1: Base {}
protocol Derived2: Base {}
@_marker protocol MarkerBase {}
func takesMarkerBase<T: MarkerBase>(_: T.Type) {}
protocol MarkerDerived1: MarkerBase {}
protocol MarkerDerived2: MarkerBase {}
// Verify that the implied conformance is macOS 100:
struct Conformer1 {}
@available(macOS 100, *)
extension Conformer1: Derived1 {
func f() {} // okay!
}
@available(macOS 200, *)
extension Conformer1: Derived2 {}
takesBase(Conformer1.self)
// expected-error@-1 {{conformance of 'Conformer1' to 'Base' is only available in macOS 100 or newer}}
// expected-note@-2 {{add 'if #available' version check}}
// No warning about redundant MarkerBase conformance (rdar://142873265):
@available(macOS 100, *)
extension Conformer1: MarkerDerived1 {}
@available(macOS 200, *)
extension Conformer1: MarkerDerived2 {}
takesMarkerBase(Conformer1.self)
// expected-error@-1 {{conformance of 'Conformer1' to 'MarkerBase' is only available in macOS 100 or newer}}
// expected-note@-2 {{add 'if #available' version check}}
// Bad availability on the Base.f() witness:
struct Conformer2 {}
@available(macOS 100, *)
extension Conformer2: Derived1 {
// expected-error@-1 {{protocol 'Base' requires 'f()' to be available in macOS 100 and newer}}
}
@available(macOS 200, *)
extension Conformer2: Derived2 {
func f() {} // expected-note {{'f()' declared here}}
}
protocol P: MarkerBase {}
struct Conformer3: P {}
@available(*, unavailable)
extension Conformer3: MarkerDerived1 {}
takesMarkerBase(Conformer3.self)