Skip to content

Commit 9aeddd0

Browse files
authored
Merge pull request #62955 from rjmccall/open_pack_element
Add the open_pack_element instruction
2 parents bc267f9 + 37baf9b commit 9aeddd0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+714
-115
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,10 @@ ERROR(sil_moveonlytocopyable_invalid_attribute,none,
673673
"Attribute '[%0]' can not be applied to moveonlywrapper_to_copyable", (StringRef))
674674
ERROR(sil_moveonlytocopyable_requires_attribute,none,
675675
"moveonlywrapper_to_copyable requires either a [guaranteed] or [owned] attribute", ())
676+
ERROR(expected_generic_signature,none,
677+
"expected a generic signature", ())
678+
ERROR(sil_expected_uuid,none,
679+
"expected a UUID string literal", ())
676680

677681
// SIL Basic Blocks
678682
ERROR(expected_sil_block_name,none,
@@ -890,6 +894,10 @@ ERROR(deprecated_protocol_composition_single,none,
890894
ERROR(deprecated_any_composition,none,
891895
"'protocol<>' syntax has been removed; use 'Any' instead", ())
892896

897+
// Pack Types
898+
ERROR(expected_rbrace_pack_type_list,none,
899+
"expected '}' at end of pack type list", ())
900+
893901
// SIL box Types
894902
ERROR(sil_box_expected_var_or_let,none,
895903
"expected 'var' or 'let' to introduce SIL box field type", ())

include/swift/AST/GenericEnvironment.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,19 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
195195
/// Retrieve the UUID for an opened element environment.
196196
UUID getOpenedElementUUID() const;
197197

198-
using PackElementBinding =
199-
std::pair<ElementArchetypeType *, PackArchetypeType *>;
200-
201-
/// Retrieve the bindings for the opened pack element archetypes in this
202-
/// generic environment to the pack archetypes that contain them.
203-
///
204-
/// \param bindings The vector to populate with the pack element bindings.
205-
void getPackElementBindings(
206-
SmallVectorImpl<PackElementBinding> &bindings) const;
198+
void forEachPackElementArchetype(
199+
llvm::function_ref<void(ElementArchetypeType*)> function) const;
200+
201+
using PackElementBindingCallback =
202+
llvm::function_ref<void(ElementArchetypeType *elementType,
203+
PackType *packSubstitution)>;
204+
205+
/// Given that this is an opened element environment, iterate the
206+
/// opened pack element bindings: the pack archetype that's been opened
207+
/// (which may not be meaningful in the surrounding context), the element
208+
/// archetype that it has been opened as, and the pack type whose elements
209+
/// are opened.
210+
void forEachPackElementBinding(PackElementBindingCallback function) const;
207211

208212
/// Create a new, primary generic environment.
209213
static GenericEnvironment *forPrimary(GenericSignature signature);

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ struct PrintOptions {
285285

286286
bool PrintImplicitAttrs = true;
287287

288+
/// Whether to print the \c each keyword for pack archetypes.
289+
bool PrintExplicitEach = false;
290+
288291
/// Whether to print the \c any keyword for existential
289292
/// types.
290293
bool PrintExplicitAny = false;

include/swift/AST/TypeRepr.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
100100
NumFields : 32
101101
);
102102

103+
SWIFT_INLINE_BITFIELD_FULL(PackTypeRepr, TypeRepr, 32,
104+
/// The number of elements contained.
105+
NumElements : 32
106+
);
107+
103108
} Bits;
104109

105110
TypeRepr(TypeReprKind K) {
@@ -758,6 +763,54 @@ class PackExpansionTypeRepr final : public TypeRepr {
758763
friend class TypeRepr;
759764
};
760765

766+
/// An explicit pack grouping, `Pack{...}`.
767+
///
768+
/// This allows packs to be explicitly grouped. It is currently only
769+
/// allowed in SIL files.
770+
class PackTypeRepr final
771+
: public TypeRepr,
772+
private llvm::TrailingObjects<PackTypeRepr, TypeRepr *> {
773+
friend TrailingObjects;
774+
SourceLoc KeywordLoc;
775+
SourceRange BraceLocs;
776+
777+
size_t numTrailingObjects(OverloadToken<TypeRepr*>) const {
778+
return Bits.PackTypeRepr.NumElements;
779+
}
780+
781+
PackTypeRepr(SourceLoc keywordLoc, SourceRange braceLocs,
782+
ArrayRef<TypeRepr*> elements);
783+
public:
784+
static PackTypeRepr *create(const ASTContext &ctx,
785+
SourceLoc keywordLoc,
786+
SourceRange braceLocs,
787+
ArrayRef<TypeRepr*> elements);
788+
789+
SourceLoc getKeywordLoc() const { return KeywordLoc; }
790+
SourceRange getBracesRange() const { return BraceLocs; }
791+
792+
MutableArrayRef<TypeRepr*> getMutableElements() {
793+
return llvm::makeMutableArrayRef(getTrailingObjects<TypeRepr*>(),
794+
Bits.PackTypeRepr.NumElements);
795+
}
796+
ArrayRef<TypeRepr*> getElements() const {
797+
return llvm::makeArrayRef(getTrailingObjects<TypeRepr*>(),
798+
Bits.PackTypeRepr.NumElements);
799+
}
800+
801+
static bool classof(const TypeRepr *T) {
802+
return T->getKind() == TypeReprKind::Pack;
803+
}
804+
static bool classof(const PackTypeRepr *T) { return true; }
805+
806+
private:
807+
SourceLoc getStartLocImpl() const { return KeywordLoc; }
808+
SourceLoc getEndLocImpl() const { return BraceLocs.End; }
809+
SourceLoc getLocImpl() const { return KeywordLoc; }
810+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
811+
friend class TypeRepr;
812+
};
813+
761814
/// A pack reference spelled with the \c each keyword.
762815
///
763816
/// Pack references can only appear inside pack expansions and in
@@ -1398,6 +1451,7 @@ inline bool TypeRepr::isSimple() const {
13981451
case TypeReprKind::ImplicitlyUnwrappedOptional:
13991452
case TypeReprKind::Vararg:
14001453
case TypeReprKind::PackExpansion:
1454+
case TypeReprKind::Pack:
14011455
case TypeReprKind::Tuple:
14021456
case TypeReprKind::Fixed:
14031457
case TypeReprKind::Array:

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ TYPEREPR(Protocol, TypeRepr)
6565
TYPEREPR(OpaqueReturn, TypeRepr)
6666
TYPEREPR(NamedOpaqueReturn, TypeRepr)
6767
TYPEREPR(Existential, TypeRepr)
68+
TYPEREPR(Pack, TypeRepr)
6869
TYPEREPR(PackReference, TypeRepr)
6970
TYPEREPR(Placeholder, TypeRepr)
7071
ABSTRACT_TYPEREPR(Specifier, TypeRepr)

include/swift/Parse/Parser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace swift {
5252
class SourceManager;
5353
class TupleType;
5454
class TypeLoc;
55+
class UUID;
5556

5657
struct EnumElementInfo;
5758

@@ -1018,6 +1019,11 @@ class Parser {
10181019
parseExtendedAvailabilitySpecList(SourceLoc AtLoc, SourceLoc AttrLoc,
10191020
StringRef AttrName);
10201021

1022+
/// Parse a string literal whose contents can be interpreted as a UUID.
1023+
///
1024+
/// \returns false on success, true on error.
1025+
bool parseUUIDString(UUID &uuid, Diag<> diag);
1026+
10211027
/// Parse the Objective-C selector inside @objc
10221028
void parseObjCSelector(SmallVector<Identifier, 4> &Names,
10231029
SmallVector<SourceLoc, 4> &NameLocs,

include/swift/SIL/SILBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,14 @@ class SILBuilder {
19361936
getSILDebugLocation(Loc), Existential));
19371937
}
19381938

1939+
OpenPackElementInst *
1940+
createOpenPackElement(SILLocation loc, SILValue packIndex,
1941+
GenericEnvironment *openedElementEnvironment) {
1942+
return insert(OpenPackElementInst::create(getFunction(),
1943+
getSILDebugLocation(loc),
1944+
packIndex, openedElementEnvironment));
1945+
}
1946+
19391947
ProjectBlockStorageInst *createProjectBlockStorage(SILLocation Loc,
19401948
SILValue Storage) {
19411949
auto CaptureTy = Storage->getType()

include/swift/SIL/SILCloner.h

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
4949

5050
SILBuilder Builder;
5151
DominanceInfo *DomTree = nullptr;
52-
TypeSubstitutionMap OpenedExistentialSubs;
52+
TypeSubstitutionMap LocalArchetypeSubs;
5353

5454
// The old-to-new value map.
5555
llvm::DenseMap<SILValue, SILValue> ValueMap;
@@ -164,10 +164,10 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
164164
asImpl().mapValue(origValue, mappedValue);
165165
}
166166

167-
/// Register a re-mapping for opened existentials.
168-
void registerOpenedExistentialRemapping(ArchetypeType *From,
169-
ArchetypeType *To) {
170-
auto result = OpenedExistentialSubs.insert(
167+
/// Register a re-mapping for local archetypes such as opened existentials.
168+
void registerLocalArchetypeRemapping(ArchetypeType *From,
169+
ArchetypeType *To) {
170+
auto result = LocalArchetypeSubs.insert(
171171
std::make_pair(CanArchetypeType(From), CanType(To)));
172172
assert(result.second);
173173
(void)result;
@@ -189,15 +189,15 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
189189
}
190190

191191
SubstitutionMap getOpSubstitutionMap(SubstitutionMap Subs) {
192-
// If we have open existentials to substitute, check whether that's
192+
// If we have local archetypes to substitute, check whether that's
193193
// relevant to this particular substitution.
194-
if (!OpenedExistentialSubs.empty()) {
194+
if (!LocalArchetypeSubs.empty()) {
195195
for (auto ty : Subs.getReplacementTypes()) {
196-
// If we found a type containing an opened existential, substitute
196+
// If we found a type containing a local archetype, substitute
197197
// open existentials throughout the substitution map.
198-
if (ty->hasOpenedExistential()) {
198+
if (ty->hasLocalArchetype()) {
199199
Subs = Subs.subst(QueryTypeSubstitutionMapOrIdentity{
200-
OpenedExistentialSubs},
200+
LocalArchetypeSubs},
201201
MakeAbstractConformanceForGenericType());
202202
break;
203203
}
@@ -209,19 +209,19 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
209209

210210
SILType getTypeInClonedContext(SILType Ty) {
211211
auto objectTy = Ty.getASTType();
212-
// Do not substitute opened existential types, if we do not have any.
213-
if (!objectTy->hasOpenedExistential())
212+
// Do not substitute local archetypes, if we do not have any.
213+
if (!objectTy->hasLocalArchetype())
214214
return Ty;
215-
// Do not substitute opened existential types, if it is not required.
215+
// Do not substitute local archetypes, if it is not required.
216216
// This is often the case when cloning basic blocks inside the same
217217
// function.
218-
if (OpenedExistentialSubs.empty())
218+
if (LocalArchetypeSubs.empty())
219219
return Ty;
220220

221-
// Substitute opened existential types, if we have any.
221+
// Substitute local archetypes, if we have any.
222222
return Ty.subst(
223223
Builder.getModule(),
224-
QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs},
224+
QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
225225
MakeAbstractConformanceForGenericType());
226226
}
227227
SILType getOpType(SILType Ty) {
@@ -230,17 +230,17 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
230230
}
231231

232232
CanType getASTTypeInClonedContext(Type ty) {
233-
// Do not substitute opened existential types, if we do not have any.
234-
if (!ty->hasOpenedExistential())
233+
// Do not substitute local archetypes, if we do not have any.
234+
if (!ty->hasLocalArchetype())
235235
return ty->getCanonicalType();
236-
// Do not substitute opened existential types, if it is not required.
236+
// Do not substitute local archetypes, if it is not required.
237237
// This is often the case when cloning basic blocks inside the same
238238
// function.
239-
if (OpenedExistentialSubs.empty())
239+
if (LocalArchetypeSubs.empty())
240240
return ty->getCanonicalType();
241241

242242
return ty.subst(
243-
QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs},
243+
QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
244244
MakeAbstractConformanceForGenericType()
245245
)->getCanonicalType();
246246
}
@@ -258,7 +258,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
258258
->getCanonicalType();
259259
auto substExistentialTy = getOpASTType(origExistentialTy);
260260
auto replacementTy = OpenedArchetypeType::get(substExistentialTy, sig);
261-
registerOpenedExistentialRemapping(archetypeTy, replacementTy);
261+
registerLocalArchetypeRemapping(archetypeTy, replacementTy);
262262
}
263263

264264
// SILCloner will take care of debug scope on the instruction
@@ -273,12 +273,12 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
273273

274274
ProtocolConformanceRef getOpConformance(Type ty,
275275
ProtocolConformanceRef conformance) {
276-
// If we have open existentials to substitute, do so now.
277-
if (ty->hasOpenedExistential() && !OpenedExistentialSubs.empty()) {
276+
// If we have local archetypes to substitute, do so now.
277+
if (ty->hasLocalArchetype() && !LocalArchetypeSubs.empty()) {
278278
conformance =
279279
conformance.subst(ty,
280280
QueryTypeSubstitutionMapOrIdentity{
281-
OpenedExistentialSubs},
281+
LocalArchetypeSubs},
282282
MakeAbstractConformanceForGenericType());
283283
}
284284

@@ -2392,6 +2392,52 @@ void SILCloner<ImplClass>::visitDeinitExistentialValueInst(
23922392
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
23932393
}
23942394

2395+
template <typename ImplClass>
2396+
void SILCloner<ImplClass>::visitOpenPackElementInst(
2397+
OpenPackElementInst *Inst) {
2398+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2399+
2400+
auto newIndexValue = getOpValue(Inst->getIndexOperand());
2401+
auto loc = getOpLocation(Inst->getLoc());
2402+
2403+
// We need to make a new opened-element environment. This is *not*
2404+
// a refinement of the contextual environment of the new insertion
2405+
// site; we just substitute the contextual substitutions in the
2406+
// opened environment and build a new one.
2407+
auto origEnv = Inst->getOpenedGenericEnvironment();
2408+
2409+
// Substitute the contextual substitutions.
2410+
auto newContextSubs =
2411+
getOpSubstitutionMap(origEnv->getPackElementContextSubstitutions());
2412+
2413+
// Substitute the shape class.
2414+
auto newShapeClass = getOpASTType(origEnv->getOpenedElementShapeClass());
2415+
2416+
// Build the new environment.
2417+
auto newEnv =
2418+
GenericEnvironment::forOpenedElement(origEnv->getGenericSignature(),
2419+
UUID::fromTime(), newShapeClass,
2420+
newContextSubs);
2421+
2422+
// Associate the old opened archetypes with the new ones.
2423+
SmallVector<ArchetypeType*, 4> oldOpenedArchetypes;
2424+
origEnv->forEachPackElementArchetype([&](ElementArchetypeType *oldType) {
2425+
oldOpenedArchetypes.push_back(oldType);
2426+
});
2427+
{
2428+
size_t nextOldIndex = 0;
2429+
newEnv->forEachPackElementArchetype([&](ElementArchetypeType *newType) {
2430+
ArchetypeType *oldType = oldOpenedArchetypes[nextOldIndex++];
2431+
registerLocalArchetypeRemapping(oldType, newType);
2432+
});
2433+
assert(nextOldIndex == oldOpenedArchetypes.size() &&
2434+
"different opened archetype count");
2435+
}
2436+
2437+
recordClonedInstruction(
2438+
Inst, getBuilder().createOpenPackElement(loc, newIndexValue, newEnv));
2439+
}
2440+
23952441
template<typename ImplClass>
23962442
void
23972443
SILCloner<ImplClass>::visitCopyBlockInst(CopyBlockInst *Inst) {

0 commit comments

Comments
 (0)