mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Don't complain about implied Sendable conformance of imported type being retroactive
- Fixes rdar://145184871.
This commit is contained in:
@@ -6816,6 +6816,9 @@ static bool checkSendableInstanceStorage(
|
||||
|
||||
bool swift::checkSendableConformance(
|
||||
ProtocolConformance *conformance, SendableCheck check) {
|
||||
ASSERT(conformance->getProtocol()->isSpecificProtocol(
|
||||
KnownProtocolKind::Sendable));
|
||||
|
||||
auto conformanceDC = conformance->getDeclContext();
|
||||
auto nominal = conformance->getType()->getAnyNominal();
|
||||
if (!nominal)
|
||||
@@ -6905,13 +6908,16 @@ bool swift::checkSendableConformance(
|
||||
return false;
|
||||
}
|
||||
|
||||
// An implied conformance is generated when you state a conformance to
|
||||
// a protocol P that inherits from Sendable.
|
||||
bool wasImplied = (conformance->getSourceKind() ==
|
||||
ConformanceEntryKind::Implied);
|
||||
|
||||
// Sendable can only be used in the same source file.
|
||||
auto conformanceDecl = conformanceDC->getAsDecl();
|
||||
SendableCheckContext checkContext(conformanceDC, check);
|
||||
DiagnosticBehavior behavior = checkContext.defaultDiagnosticBehavior();
|
||||
if (conformance->getSourceKind() == ConformanceEntryKind::Implied &&
|
||||
conformance->getProtocol()->isSpecificProtocol(
|
||||
KnownProtocolKind::Sendable)) {
|
||||
if (wasImplied) {
|
||||
if (auto optBehavior = checkContext.preconcurrencyBehavior(
|
||||
nominal, /*ignoreExplicitConformance=*/true))
|
||||
behavior = *optBehavior;
|
||||
@@ -6920,12 +6926,14 @@ bool swift::checkSendableConformance(
|
||||
if (conformanceDC->getOutermostParentSourceFile() &&
|
||||
conformanceDC->getOutermostParentSourceFile() !=
|
||||
nominal->getOutermostParentSourceFile()) {
|
||||
conformanceDecl->diagnose(diag::concurrent_value_outside_source_file,
|
||||
nominal)
|
||||
.limitBehaviorUntilSwiftVersion(behavior, 6);
|
||||
if (!(nominal->hasClangNode() && wasImplied)) {
|
||||
conformanceDecl->diagnose(diag::concurrent_value_outside_source_file,
|
||||
nominal)
|
||||
.limitBehaviorUntilSwiftVersion(behavior, 6);
|
||||
|
||||
if (behavior == DiagnosticBehavior::Unspecified)
|
||||
return true;
|
||||
if (behavior == DiagnosticBehavior::Unspecified)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (classDecl && classDecl->getParentSourceFile()) {
|
||||
@@ -6963,7 +6971,7 @@ bool swift::checkSendableConformance(
|
||||
// a Sendable conformance. The implied conformance is unconditional, so check
|
||||
// the storage for sendability as if the conformance was declared on the nominal,
|
||||
// and not some (possibly constrained) extension.
|
||||
if (conformance->getSourceKind() == ConformanceEntryKind::Implied)
|
||||
if (wasImplied)
|
||||
conformanceDC = nominal;
|
||||
return checkSendableInstanceStorage(nominal, conformanceDC, check);
|
||||
}
|
||||
|
||||
@@ -1843,6 +1843,18 @@ static void diagnoseRetroactiveConformances(
|
||||
bool inserted = protocols.insert(std::make_pair(
|
||||
proto, conformance->isRetroactive())).second;
|
||||
ASSERT(inserted);
|
||||
|
||||
if (proto->isSpecificProtocol(KnownProtocolKind::SendableMetatype)) {
|
||||
protocolsWithRetroactiveAttr.insert(proto);
|
||||
}
|
||||
|
||||
// Implied conformance to Sendable is a special case that should not be
|
||||
// diagnosed. Pretend it's always @retroactive.
|
||||
if (conformance->getSourceKind() == ConformanceEntryKind::Implied &&
|
||||
proto->isSpecificProtocol(KnownProtocolKind::Sendable) &&
|
||||
extendedNominalDecl->hasClangNode()) {
|
||||
protocolsWithRetroactiveAttr.insert(proto);
|
||||
}
|
||||
}
|
||||
|
||||
for (const InheritedEntry &entry : ext->getInherited().getEntries()) {
|
||||
|
||||
15
test/Concurrency/implied_sendable_conformance_objc.swift
Normal file
15
test/Concurrency/implied_sendable_conformance_objc.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -swift-version 6
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
// REQUIRES: concurrency
|
||||
|
||||
import Foundation
|
||||
|
||||
extension CGRect: Sendable {}
|
||||
// expected-warning@-1 {{extension declares a conformance of imported type 'CGRect' to imported protocol 'Sendable'; this will not behave correctly if the owners of 'CoreGraphics' introduce this conformance in the future}}
|
||||
// expected-note@-2 {{add '@retroactive' to silence this warning}}
|
||||
// expected-error@-3 {{conformance to 'Sendable' must occur in the same source file as struct 'CGRect'; use '@unchecked Sendable' for retroactive conformance}}
|
||||
protocol P: Sendable {}
|
||||
|
||||
extension CGPoint: P {}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
protocol _CFObject: Hashable {}
|
||||
|
||||
#if CGFLOAT_IN_COREFOUNDATION
|
||||
public struct CGFloat {
|
||||
public struct CGFloat: @unchecked Sendable {
|
||||
#if _pointerBitWidth(_32)
|
||||
public typealias UnderlyingType = Float
|
||||
#elseif _pointerBitWidth(_64)
|
||||
|
||||
@@ -6,7 +6,7 @@ public func == (lhs: CGPoint, rhs: CGPoint) -> Bool {
|
||||
}
|
||||
|
||||
#if !CGFLOAT_IN_COREFOUNDATION
|
||||
public struct CGFloat {
|
||||
public struct CGFloat: Sendable {
|
||||
#if _pointerBitWidth(_32)
|
||||
public typealias UnderlyingType = Float
|
||||
#elseif _pointerBitWidth(_64)
|
||||
|
||||
Reference in New Issue
Block a user