Skip to content

Commit aff95bf

Browse files
authored
Merge pull request #38691 from DougGregor/missing-sendable-conformances
2 parents ba0536f + f9c3475 commit aff95bf

25 files changed

+234
-72
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace swift {
106106
class InheritedProtocolConformance;
107107
class SelfProtocolConformance;
108108
class SpecializedProtocolConformance;
109+
enum class BuiltinConformanceKind;
109110
class BuiltinProtocolConformance;
110111
enum class ProtocolConformanceState;
111112
class Pattern;
@@ -1046,7 +1047,8 @@ class ASTContext final {
10461047
BuiltinProtocolConformance *
10471048
getBuiltinConformance(Type type, ProtocolDecl *protocol,
10481049
GenericSignature genericSig,
1049-
ArrayRef<Requirement> conditionalRequirements);
1050+
ArrayRef<Requirement> conditionalRequirements,
1051+
BuiltinConformanceKind kind);
10501052

10511053
/// A callback used to produce a diagnostic for an ill-formed protocol
10521054
/// conformance that was type-checked before we're actually walking the

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3251,7 +3251,8 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
32513251
///
32523252
/// This is used by deserialization of module files to report
32533253
/// conformances.
3254-
void registerProtocolConformance(ProtocolConformance *conformance);
3254+
void registerProtocolConformance(ProtocolConformance *conformance,
3255+
bool synthesized = false);
32553256

32563257
void setConformanceLoader(LazyMemberLoader *resolver, uint64_t contextData);
32573258

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4518,6 +4518,11 @@ ERROR(concurrent_value_inherit,none,
45184518
"`Sendable` class %1 cannot inherit from another class"
45194519
"%select{| other than 'NSObject'}0",
45204520
(bool, DeclName))
4521+
ERROR(non_sendable_type,none,
4522+
"type %0 does not conform to the 'Sendable' protocol", (Type))
4523+
ERROR(non_sendable_function_type,none,
4524+
"function type %0 must be marked '@Sendable' to conform to 'Sendable'",
4525+
(Type))
45214526

45224527
WARNING(unchecked_conformance_not_special,none,
45234528
"@unchecked conformance to %0 has no meaning", (Type))

include/swift/AST/GenericSignature.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
373373
/// T: Foo or T == U (etc.) with the information it knows. This includes
374374
/// checking against global state, if any/all of the types in the requirement
375375
/// are concrete, not type parameters.
376-
bool isRequirementSatisfied(Requirement requirement) const;
376+
bool isRequirementSatisfied(
377+
Requirement requirement, bool allowMissing = false) const;
377378

378379
/// Return the requirements of this generic signature that are not also
379380
/// satisfied by \c otherSig.

include/swift/AST/Module.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,10 +578,15 @@ class ModuleDecl : public DeclContext, public TypeDecl {
578578
///
579579
/// \param protocol The protocol to which we are computing conformance.
580580
///
581+
/// \param allowMissing When \c true, the resulting conformance reference
582+
/// might include "missing" conformances, which are synthesized for some
583+
/// protocols as an error recovery mechanism.
584+
///
581585
/// \returns The result of the conformance search, which will be
582586
/// None if the type does not conform to the protocol or contain a
583587
/// ProtocolConformanceRef if it does conform.
584-
ProtocolConformanceRef lookupConformance(Type type, ProtocolDecl *protocol);
588+
ProtocolConformanceRef lookupConformance(Type type, ProtocolDecl *protocol,
589+
bool allowMissing = false);
585590

586591
/// Look for the conformance of the given existential type to the given
587592
/// protocol.

include/swift/AST/ProtocolConformance.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,15 @@ class InheritedProtocolConformance : public ProtocolConformance,
993993
}
994994
};
995995

996+
/// Describes the kind of a builtin conformance.
997+
enum class BuiltinConformanceKind {
998+
// A builtin conformance that has been synthesized by the implementation.
999+
Synthesized = 0,
1000+
// A missing conformance that we have nonetheless synthesized so that
1001+
// we can diagnose it later.
1002+
Missing,
1003+
};
1004+
9961005
/// A builtin conformance appears when a non-nominal type has a
9971006
/// conformance that is synthesized by the implementation.
9981007
class BuiltinProtocolConformance final : public RootProtocolConformance,
@@ -1002,15 +1011,17 @@ class BuiltinProtocolConformance final : public RootProtocolConformance,
10021011

10031012
ProtocolDecl *protocol;
10041013
GenericSignature genericSig;
1005-
size_t numConditionalRequirements;
1014+
size_t numConditionalRequirements : 31;
1015+
unsigned builtinConformanceKind : 1;
10061016

10071017
size_t numTrailingObjects(OverloadToken<Requirement>) const {
10081018
return numConditionalRequirements;
10091019
}
10101020

10111021
BuiltinProtocolConformance(Type conformingType, ProtocolDecl *protocol,
10121022
GenericSignature genericSig,
1013-
ArrayRef<Requirement> conditionalRequirements);
1023+
ArrayRef<Requirement> conditionalRequirements,
1024+
BuiltinConformanceKind kind);
10141025

10151026
public:
10161027
/// Get the protocol being conformed to.
@@ -1024,6 +1035,16 @@ class BuiltinProtocolConformance final : public RootProtocolConformance,
10241035
return genericSig;
10251036
}
10261037

1038+
BuiltinConformanceKind getBuiltinConformanceKind() const {
1039+
return static_cast<BuiltinConformanceKind>(builtinConformanceKind);
1040+
}
1041+
1042+
/// Whether this represents a "missing" conformance that should be diagnosed
1043+
/// later.
1044+
bool isMissing() const {
1045+
return getBuiltinConformanceKind() == BuiltinConformanceKind::Missing;
1046+
}
1047+
10271048
/// Get any requirements that must be satisfied for this conformance to apply.
10281049
Optional<ArrayRef<Requirement>>
10291050
getConditionalRequirementsIfAvailable() const {

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ class ProtocolConformanceRef {
9898
return Union.get<ProtocolDecl*>();
9999
}
100100

101+
/// Determine whether this conformance (or a conformance it depends on)
102+
/// involves a "missing" conformance anywhere. Such conformances
103+
/// cannot be depended on to always exist.
104+
bool hasMissingConformance(ModuleDecl *module) const;
105+
101106
using OpaqueValue = void*;
102107
OpaqueValue getOpaqueValue() const { return Union.getOpaqueValue(); }
103108
static ProtocolConformanceRef getFromOpaqueValue(OpaqueValue value) {

include/swift/AST/Requirement.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ class Requirement
8181
/// \param conditionalRequirements An out parameter initialized to an
8282
/// array of requirements that the caller must check to ensure this
8383
/// requirement is completely satisfied.
84-
bool isSatisfied(ArrayRef<Requirement> &conditionalRequirements) const;
84+
bool isSatisfied(ArrayRef<Requirement> &conditionalRequirements,
85+
bool allowMissing = false) const;
8586

8687
/// Determines if this substituted requirement can ever be satisfied,
8788
/// possibly with additional substitutions.

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,7 +2331,8 @@ BuiltinProtocolConformance *
23312331
ASTContext::getBuiltinConformance(
23322332
Type type, ProtocolDecl *protocol,
23332333
GenericSignature genericSig,
2334-
ArrayRef<Requirement> conditionalRequirements
2334+
ArrayRef<Requirement> conditionalRequirements,
2335+
BuiltinConformanceKind kind
23352336
) {
23362337
auto key = std::make_pair(type, protocol);
23372338
AllocationArena arena = getArena(type->getRecursiveProperties());
@@ -2343,7 +2344,7 @@ ASTContext::getBuiltinConformance(
23432344
totalSizeToAlloc<Requirement>(conditionalRequirements.size());
23442345
auto mem = this->Allocate(size, alignof(BuiltinProtocolConformance), arena);
23452346
entry = new (mem) BuiltinProtocolConformance(
2346-
type, protocol, genericSig, conditionalRequirements);
2347+
type, protocol, genericSig, conditionalRequirements, kind);
23472348
}
23482349
return entry;
23492350
}

lib/AST/GenericSignature.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ bool GenericSignatureImpl::areSameTypeParameterInContext(Type type1,
937937
}
938938

939939
bool GenericSignatureImpl::isRequirementSatisfied(
940-
Requirement requirement) const {
940+
Requirement requirement, bool allowMissing) const {
941941
if (requirement.getFirstType()->hasTypeParameter()) {
942942
auto *genericEnv = getGenericEnvironment();
943943

@@ -959,7 +959,7 @@ bool GenericSignatureImpl::isRequirementSatisfied(
959959
// FIXME: Need to check conditional requirements here.
960960
ArrayRef<Requirement> conditionalRequirements;
961961

962-
return requirement.isSatisfied(conditionalRequirements);
962+
return requirement.isSatisfied(conditionalRequirements, allowMissing);
963963
}
964964

965965
SmallVector<Requirement, 4> GenericSignatureImpl::requirementsNotSatisfiedBy(
@@ -1391,12 +1391,14 @@ ProtocolDecl *Requirement::getProtocolDecl() const {
13911391
}
13921392

13931393
bool
1394-
Requirement::isSatisfied(ArrayRef<Requirement> &conditionalRequirements) const {
1394+
Requirement::isSatisfied(ArrayRef<Requirement> &conditionalRequirements,
1395+
bool allowMissing) const {
13951396
switch (getKind()) {
13961397
case RequirementKind::Conformance: {
13971398
auto *proto = getProtocolDecl();
13981399
auto *module = proto->getParentModule();
1399-
auto conformance = module->lookupConformance(getFirstType(), proto);
1400+
auto conformance = module->lookupConformance(
1401+
getFirstType(), proto, allowMissing);
14001402
if (!conformance)
14011403
return false;
14021404

0 commit comments

Comments
 (0)