Skip to content

Commit 5085226

Browse files
authored
Merge pull request #3636 from swiftwasm/release/5.5
[pull] swiftwasm-release/5.5 from release/5.5
2 parents 490bf1d + 95dc169 commit 5085226

19 files changed

+491
-161
lines changed

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace swift {
106106
class InheritedProtocolConformance;
107107
class SelfProtocolConformance;
108108
class SpecializedProtocolConformance;
109+
class BuiltinProtocolConformance;
109110
enum class ProtocolConformanceState;
110111
class Pattern;
111112
enum PointerTypeKind : unsigned;
@@ -1010,6 +1011,12 @@ class ASTContext final {
10101011
SelfProtocolConformance *
10111012
getSelfConformance(ProtocolDecl *protocol);
10121013

1014+
/// Produce the builtin conformance for some structural type to some protocol.
1015+
BuiltinProtocolConformance *
1016+
getBuiltinConformance(Type type, ProtocolDecl *protocol,
1017+
GenericSignature genericSig,
1018+
ArrayRef<Requirement> conditionalRequirements);
1019+
10131020
/// A callback used to produce a diagnostic for an ill-formed protocol
10141021
/// conformance that was type-checked before we're actually walking the
10151022
/// conformance itself, along with a bit indicating whether this diagnostic

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,12 @@ ERROR(type_cannot_conform, none,
19161916
NOTE(only_concrete_types_conform_to_protocols,none,
19171917
"only concrete types such as structs, enums and classes can conform to protocols",
19181918
())
1919+
NOTE(nonsendable_function_type,none,
1920+
"a function type must be marked '@Sendable' to conform to 'Sendable'", ())
1921+
NOTE(nonsendable_tuple_type,none,
1922+
"a tuple type must be composed of 'Sendable' elements to conform to "
1923+
"'Sendable'", ())
1924+
19191925
NOTE(required_by_opaque_return,none,
19201926
"required by opaque return type of %0 %1", (DescriptiveDeclKind, DeclName))
19211927
NOTE(required_by_decl,none,

include/swift/AST/ProtocolConformance.h

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -66,7 +66,10 @@ enum class ProtocolConformanceKind {
6666
Specialized,
6767
/// Conformance of a generic class type projected through one of its
6868
/// superclass's conformances.
69-
Inherited
69+
Inherited,
70+
/// Builtin conformances are special conformaces that the runtime handles
71+
/// and isn't implemented directly in Swift.
72+
Builtin
7073
};
7174

7275
/// Describes the state of a protocol conformance, which may be complete,
@@ -329,7 +332,9 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
329332
/// - the type is directly declared to conform to the protocol (a
330333
/// normal conformance) or
331334
/// - the protocol's existential type is known to conform to itself (a
332-
/// self-conformance).
335+
/// self-conformance) or
336+
/// - the type's conformance is declared within the runtime (a builtin
337+
/// conformance).
333338
class RootProtocolConformance : public ProtocolConformance {
334339
protected:
335340
RootProtocolConformance(ProtocolConformanceKind kind, Type conformingType)
@@ -380,7 +385,8 @@ class RootProtocolConformance : public ProtocolConformance {
380385

381386
static bool classof(const ProtocolConformance *conformance) {
382387
return conformance->getKind() == ProtocolConformanceKind::Normal ||
383-
conformance->getKind() == ProtocolConformanceKind::Self;
388+
conformance->getKind() == ProtocolConformanceKind::Self ||
389+
conformance->getKind() == ProtocolConformanceKind::Builtin;
384390
}
385391
};
386392

@@ -987,6 +993,103 @@ class InheritedProtocolConformance : public ProtocolConformance,
987993
}
988994
};
989995

996+
/// A builtin conformance appears when a non-nominal type has a
997+
/// conformance that is synthesized by the implementation.
998+
class BuiltinProtocolConformance final : public RootProtocolConformance,
999+
private llvm::TrailingObjects<BuiltinProtocolConformance, Requirement> {
1000+
friend ASTContext;
1001+
friend TrailingObjects;
1002+
1003+
ProtocolDecl *protocol;
1004+
GenericSignature genericSig;
1005+
size_t numConditionalRequirements;
1006+
1007+
size_t numTrailingObjects(OverloadToken<Requirement>) const {
1008+
return numConditionalRequirements;
1009+
}
1010+
1011+
BuiltinProtocolConformance(Type conformingType, ProtocolDecl *protocol,
1012+
GenericSignature genericSig,
1013+
ArrayRef<Requirement> conditionalRequirements);
1014+
1015+
public:
1016+
/// Get the protocol being conformed to.
1017+
ProtocolDecl *getProtocol() const {
1018+
return protocol;
1019+
}
1020+
1021+
/// Retrieve the generic signature that describes the type parameters used
1022+
/// within the conforming type.
1023+
GenericSignature getGenericSignature() const {
1024+
return genericSig;
1025+
}
1026+
1027+
/// Get any requirements that must be satisfied for this conformance to apply.
1028+
Optional<ArrayRef<Requirement>>
1029+
getConditionalRequirementsIfAvailable() const {
1030+
return getConditionalRequirements();
1031+
}
1032+
1033+
/// Get any requirements that must be satisfied for this conformance to apply.
1034+
ArrayRef<Requirement> getConditionalRequirements() const {
1035+
return {getTrailingObjects<Requirement>(), numConditionalRequirements};
1036+
}
1037+
1038+
/// Get the declaration context that contains the nominal type declaration.
1039+
DeclContext *getDeclContext() const {
1040+
return getProtocol();
1041+
}
1042+
1043+
/// Retrieve the state of this conformance.
1044+
ProtocolConformanceState getState() const {
1045+
return ProtocolConformanceState::Complete;
1046+
}
1047+
1048+
/// Get the kind of source from which this conformance comes.
1049+
ConformanceEntryKind getSourceKind() const {
1050+
return ConformanceEntryKind::Synthesized;
1051+
}
1052+
/// Get the protocol conformance which implied this implied conformance.
1053+
NormalProtocolConformance *getImplyingConformance() const {
1054+
return nullptr;
1055+
}
1056+
1057+
bool hasTypeWitness(AssociatedTypeDecl *assocType) const {
1058+
llvm_unreachable("builtin-conformances never have associated types");
1059+
}
1060+
1061+
/// Retrieve the type witness and type decl (if one exists)
1062+
/// for the given associated type.
1063+
TypeWitnessAndDecl
1064+
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
1065+
SubstOptions options=None) const {
1066+
llvm_unreachable("builtin-conformances never have associated types");
1067+
}
1068+
1069+
/// Given that the requirement signature of the protocol directly states
1070+
/// that the given dependent type must conform to the given protocol,
1071+
/// return its associated conformance.
1072+
ProtocolConformanceRef
1073+
getAssociatedConformance(Type assocType, ProtocolDecl *protocol) const {
1074+
llvm_unreachable("builtin-conformances never have associated types");
1075+
}
1076+
1077+
/// Retrieve the witness corresponding to the given value requirement.
1078+
ConcreteDeclRef getWitnessDeclRef(ValueDecl *requirement) const {
1079+
return ConcreteDeclRef(requirement);
1080+
}
1081+
1082+
/// Determine whether the witness for the given requirement
1083+
/// is either the default definition or was otherwise deduced.
1084+
bool usesDefaultDefinition(AssociatedTypeDecl *requirement) const {
1085+
llvm_unreachable("builtin-conformances never have associated types");
1086+
}
1087+
1088+
static bool classof(const ProtocolConformance *conformance) {
1089+
return conformance->getKind() == ProtocolConformanceKind::Builtin;
1090+
}
1091+
};
1092+
9901093
inline bool ProtocolConformance::isInvalid() const {
9911094
return getRootConformance()->isInvalid();
9921095
}

lib/AST/ASTContext.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ struct ASTContext::Implementation {
425425
/// The set of inherited protocol conformances.
426426
llvm::FoldingSet<InheritedProtocolConformance> InheritedConformances;
427427

428+
/// The set of builtin protocol conformances.
429+
llvm::DenseMap<std::pair<Type, ProtocolDecl *>,
430+
BuiltinProtocolConformance *> BuiltinConformances;
431+
428432
/// The set of substitution maps (uniqued by their storage).
429433
llvm::FoldingSet<SubstitutionMap::Storage> SubstitutionMaps;
430434

@@ -2189,6 +2193,28 @@ ASTContext::getSelfConformance(ProtocolDecl *protocol) {
21892193
return entry;
21902194
}
21912195

2196+
/// Produce the builtin conformance for some non-nominal to some protocol.
2197+
BuiltinProtocolConformance *
2198+
ASTContext::getBuiltinConformance(
2199+
Type type, ProtocolDecl *protocol,
2200+
GenericSignature genericSig,
2201+
ArrayRef<Requirement> conditionalRequirements
2202+
) {
2203+
auto key = std::make_pair(type, protocol);
2204+
AllocationArena arena = getArena(type->getRecursiveProperties());
2205+
auto &builtinConformances = getImpl().getArena(arena).BuiltinConformances;
2206+
2207+
auto &entry = builtinConformances[key];
2208+
if (!entry) {
2209+
auto size = BuiltinProtocolConformance::
2210+
totalSizeToAlloc<Requirement>(conditionalRequirements.size());
2211+
auto mem = this->Allocate(size, alignof(BuiltinProtocolConformance), arena);
2212+
entry = new (mem) BuiltinProtocolConformance(
2213+
type, protocol, genericSig, conditionalRequirements);
2214+
}
2215+
return entry;
2216+
}
2217+
21922218
/// If one of the ancestor conformances already has a matching type, use
21932219
/// that instead.
21942220
static ProtocolConformance *collapseSpecializedConformance(
@@ -2205,6 +2231,7 @@ static ProtocolConformance *collapseSpecializedConformance(
22052231
case ProtocolConformanceKind::Normal:
22062232
case ProtocolConformanceKind::Inherited:
22072233
case ProtocolConformanceKind::Self:
2234+
case ProtocolConformanceKind::Builtin:
22082235
// If the conformance matches, return it.
22092236
if (conformance->getType()->isEqual(type)) {
22102237
for (auto subConformance : substitutions.getConformances())
@@ -2442,6 +2469,7 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
24422469
// NormalConformances ?
24432470
// SpecializedConformances ?
24442471
// InheritedConformances ?
2472+
// BuiltinConformances ?
24452473
}
24462474

24472475
void AbstractFunctionDecl::setForeignErrorConvention(

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -3352,6 +3352,10 @@ static void dumpProtocolConformanceRec(
33523352
visited);
33533353
break;
33543354
}
3355+
3356+
case ProtocolConformanceKind::Builtin: {
3357+
printCommon("builtin");
3358+
}
33553359
}
33563360

33573361
PrintWithColorRAII(out, ParenthesisColor) << ')';

lib/AST/ASTMangler.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -209,9 +209,11 @@ std::string ASTMangler::mangleWitnessTable(const RootProtocolConformance *C) {
209209
if (isa<NormalProtocolConformance>(C)) {
210210
appendProtocolConformance(C);
211211
appendOperator("WP");
212-
} else {
212+
} else if (isa<SelfProtocolConformance>(C)) {
213213
appendProtocolName(cast<SelfProtocolConformance>(C)->getProtocol());
214214
appendOperator("WS");
215+
} else {
216+
llvm_unreachable("mangling unknown conformance kind");
215217
}
216218
return finalize();
217219
}
@@ -235,7 +237,11 @@ std::string ASTMangler::mangleWitnessThunk(
235237
}
236238

237239
if (Conformance) {
238-
appendOperator(isa<SelfProtocolConformance>(Conformance) ? "TS" : "TW");
240+
if (isa<SelfProtocolConformance>(Conformance)) {
241+
appendOperator("TS");
242+
} else {
243+
appendOperator("TW");
244+
}
239245
}
240246
return finalize();
241247
}
@@ -1554,7 +1560,8 @@ void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
15541560
static bool conformanceHasIdentity(const RootProtocolConformance *root) {
15551561
auto conformance = dyn_cast<NormalProtocolConformance>(root);
15561562
if (!conformance) {
1557-
assert(isa<SelfProtocolConformance>(root));
1563+
assert(isa<SelfProtocolConformance>(root) ||
1564+
isa<BuiltinProtocolConformance>(root));
15581565
return true;
15591566
}
15601567

@@ -1575,8 +1582,9 @@ static bool conformanceHasIdentity(const RootProtocolConformance *root) {
15751582
static bool isRetroactiveConformance(const RootProtocolConformance *root) {
15761583
auto conformance = dyn_cast<NormalProtocolConformance>(root);
15771584
if (!conformance) {
1578-
assert(isa<SelfProtocolConformance>(root));
1579-
return false; // self-conformances are never retroactive.
1585+
assert(isa<SelfProtocolConformance>(root) ||
1586+
isa<BuiltinProtocolConformance>(root));
1587+
return false; // self-conformances are never retroactive. nor are builtin.
15801588
}
15811589

15821590
return conformance->isRetroactive();
@@ -3058,6 +3066,10 @@ ASTMangler::appendProtocolConformance(const ProtocolConformance *conformance) {
30583066
appendModule(Mod, DC->getAsDecl()->getAlternateModuleName());
30593067
}
30603068

3069+
// If this is a non-nominal type, we're done.
3070+
if (!conformingType->getAnyNominal())
3071+
return;
3072+
30613073
contextSig =
30623074
conformingType->getAnyNominal()->getGenericSignatureOfContext();
30633075

@@ -3082,6 +3094,9 @@ void ASTMangler::appendProtocolConformanceRef(
30823094
assert(DC->getAsDecl());
30833095
appendModule(conformance->getDeclContext()->getParentModule(),
30843096
DC->getAsDecl()->getAlternateModuleName());
3097+
// Builtin conformances are always from the Swift module.
3098+
} else if (isa<BuiltinProtocolConformance>(conformance)) {
3099+
appendOperator("HP");
30853100
} else if (conformance->getDeclContext()->getParentModule() ==
30863101
conformance->getType()->getAnyNominal()->getParentModule()) {
30873102
appendOperator("HP");

lib/AST/ASTPrinter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -5702,6 +5702,12 @@ void ProtocolConformance::printName(llvm::raw_ostream &os,
57025702
os << ")";
57035703
break;
57045704
}
5705+
case ProtocolConformanceKind::Builtin: {
5706+
auto builtin = cast<BuiltinProtocolConformance>(this);
5707+
os << builtin->getProtocol()->getName()
5708+
<< " type " << builtin->getType();
5709+
break;
5710+
}
57055711
}
57065712
}
57075713

0 commit comments

Comments
 (0)