Skip to content

Commit c491d25

Browse files
committed
Fix printing and implement parsing of opened element archetypes in SIL
Also, fix a couple places that were checking for opened existentials to check for any local archetype.
1 parent 5dd6c4e commit c491d25

File tree

12 files changed

+215
-14
lines changed

12 files changed

+215
-14
lines changed

include/swift/AST/Attr.def.gyb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ TYPE_ATTR(callee_owned)
8484
TYPE_ATTR(callee_guaranteed)
8585
TYPE_ATTR(objc_metatype)
8686
TYPE_ATTR(opened)
87+
TYPE_ATTR(pack_element)
8788
TYPE_ATTR(pseudogeneric)
8889
TYPE_ATTR(yields)
8990
TYPE_ATTR(yield_once)

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ ERROR(expected_generic_signature,none,
677677
"expected a generic signature", ())
678678
ERROR(sil_expected_uuid,none,
679679
"expected a UUID string literal", ())
680+
NOTE(sil_previous_instruction,none, "previous instruction", ())
680681

681682
// SIL Basic Blocks
682683
ERROR(expected_sil_block_name,none,
@@ -1656,6 +1657,14 @@ ERROR(opened_attribute_id_value,none,
16561657
ERROR(opened_attribute_expected_rparen,none,
16571658
"expected ')' after id value for 'opened' attribute", ())
16581659

1660+
// pack_element
1661+
ERROR(pack_element_attribute_expected_lparen,none,
1662+
"expected '(' after 'pack_element' attribute", ())
1663+
ERROR(pack_element_attribute_expected_rparen,none,
1664+
"expected ')' after id value for 'pack_element' attribute", ())
1665+
ERROR(multiple_open_pack_element,none,
1666+
"multiple 'open_pack_element' instructions with same UUID", ())
1667+
16591668
// unowned
16601669
ERROR(attr_unowned_invalid_specifier,none,
16611670
"expected 'safe' or 'unsafe'", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5385,6 +5385,9 @@ ERROR(illegal_sil_type,none,
53855385
"type %0 is not a legal SIL value type", (Type))
53865386
ERROR(sil_box_arg_mismatch,none,
53875387
"SIL box type has wrong number of generic arguments for layout", ())
5388+
ERROR(sil_pack_element_uuid_not_found,none,
5389+
"open_pack_element instruction not found for @pack_element type UUID; "
5390+
"possible forward reference?", ())
53885391
// SIL Metatypes
53895392
ERROR(sil_metatype_without_repr,none,
53905393
"metatypes in SIL must have @thin, @thick, or @objc_metatype attribute",

include/swift/AST/GenericEnvironment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ class ArchetypeType;
3535
class ASTContext;
3636
class GenericTypeParamType;
3737
class OpaqueTypeDecl;
38+
class ElementArchetypeType;
3839
class OpenedArchetypeType;
40+
class PackArchetypeType;
3941
class SILModule;
4042
class SILType;
4143

include/swift/Sema/SILTypeResolutionContext.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,37 @@
1313
#ifndef SWIFT_SEMA_SILTYPERESOLUTIONCONTEXT_H
1414
#define SWIFT_SEMA_SILTYPERESOLUTIONCONTEXT_H
1515

16+
#include "llvm/ADT/DenseMap.h"
17+
#include "swift/Basic/UUID.h"
18+
1619
namespace swift {
1720
class GenericParamList;
21+
class GenericEnvironment;
1822

1923
class SILTypeResolutionContext {
2024
public:
25+
struct OpenedPackElement {
26+
SourceLoc DefinitionPoint;
27+
GenericParamList *Params;
28+
GenericEnvironment *Environment;
29+
};
30+
using OpenedPackElementsMap = llvm::DenseMap<UUID, OpenedPackElement>;
31+
2132
/// Are we requesting a SIL type?
2233
bool IsSILType;
2334

2435
/// Look up types in the given parameter list.
2536
GenericParamList *GenericParams;
2637

38+
/// Look up @pack_element environments in this map.
39+
OpenedPackElementsMap *OpenedPackElements;
40+
2741
SILTypeResolutionContext(bool isSILType,
28-
GenericParamList *genericParams)
29-
: IsSILType(isSILType), GenericParams(genericParams) {}
42+
GenericParamList *genericParams,
43+
OpenedPackElementsMap *openedPackElements)
44+
: IsSILType(isSILType),
45+
GenericParams(genericParams),
46+
OpenedPackElements(openedPackElements) {}
3047
};
3148

3249
}

lib/AST/ASTPrinter.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5439,6 +5439,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
54395439
} else if (auto archetype = dyn_cast<ArchetypeType>(T.getPointer())) {
54405440
if (archetype->isParameterPack() && Options.PrintExplicitEach)
54415441
return false;
5442+
if (Options.PrintForSIL && isa<LocalArchetypeType>(archetype))
5443+
return false;
54425444
}
54435445
return T->hasSimpleTypeRepr();
54445446
}
@@ -6600,12 +6602,58 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
66006602
}
66016603
}
66026604

6605+
static Type findPackForElementArchetype(ElementArchetypeType *T) {
6606+
// The type in @pack_element is looked up in the generic params
6607+
// of the identified open_pack_element instruction. The param list
6608+
// is long gone, but the sugar survives in the type parameters of
6609+
// the generic signature of the contextual substitution map in the
6610+
// opened element environment.
6611+
auto env = T->getGenericEnvironment();
6612+
auto subs = env->getPackElementContextSubstitutions();
6613+
auto sig = subs.getGenericSignature();
6614+
auto params = sig.getGenericParams();
6615+
6616+
auto elementShapeClass =
6617+
env->getOpenedElementShapeClass()->mapTypeOutOfContext();
6618+
6619+
// The element archetypes are at a depth one past the max depth
6620+
// of the base signature.
6621+
unsigned elementDepth = params.back()->getDepth() + 1;
6622+
6623+
// Transform the archetype's interface type to be based on the
6624+
// corresponding non-canonical type parameter.
6625+
auto interfaceType = T->getInterfaceType();
6626+
return interfaceType.subst([&](SubstitutableType *type) -> Type {
6627+
// Don't transform types that aren't element type parameters.
6628+
auto *elementParam = type->getAs<GenericTypeParamType>();
6629+
if (!elementParam || elementParam->getDepth() != elementDepth)
6630+
return Type();
6631+
6632+
// Loop through the type parameters looking for the type parameter
6633+
// pack at the appropriate index. We only expect to actually do
6634+
// this once for each type, so it's fine to do it in the callback.
6635+
unsigned nextIndex = 0;
6636+
for (auto *genericParam : params) {
6637+
if (!genericParam->isParameterPack())
6638+
continue;
6639+
6640+
if (!sig->haveSameShape(genericParam, elementShapeClass))
6641+
continue;
6642+
6643+
if (nextIndex == elementParam->getIndex())
6644+
return genericParam;
6645+
nextIndex++;
6646+
}
6647+
llvm_unreachable("ran out of type parameters");
6648+
return Type();
6649+
}, LookUpConformanceInSignature(sig.getPointer()));
6650+
}
6651+
66036652
void visitElementArchetypeType(ElementArchetypeType *T) {
66046653
if (Options.PrintForSIL) {
6605-
Printer << "@element(\"" << T->getOpenedElementID() << ") ";
6606-
6607-
auto interfaceTy = T->getInterfaceType();
6608-
visit(interfaceTy);
6654+
Printer << "@pack_element(\"" << T->getOpenedElementID() << "\") ";
6655+
auto packTy = findPackForElementArchetype(T);
6656+
visit(packTy);
66096657
} else {
66106658
visit(T->getInterfaceType());
66116659
}

lib/AST/GenericEnvironment.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
547547
Type GenericEnvironment::mapTypeIntoContext(
548548
Type type,
549549
LookupConformanceFn lookupConformance) const {
550-
assert((!type->hasArchetype() || type->hasOpenedExistential()) &&
550+
assert((!type->hasArchetype() || type->hasLocalArchetype()) &&
551551
"already have a contextual type");
552552

553553
type = maybeApplyOuterContextSubstitutions(type);

lib/AST/Type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4710,7 +4710,7 @@ static Type substType(Type derivedType,
47104710
if (origArchetype->isRoot()) {
47114711
// Root opened archetypes are not required to be substituted. Other root
47124712
// archetypes must already have been substituted above.
4713-
if (isa<OpenedArchetypeType>(origArchetype)) {
4713+
if (isa<LocalArchetypeType>(origArchetype)) {
47144714
return Type(type);
47154715
} else {
47164716
return ErrorType::get(type);

lib/Parse/ParseDecl.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4164,6 +4164,33 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes,
41644164
break;
41654165
}
41664166

4167+
case TAK_pack_element: {
4168+
if (!isInSILMode()) {
4169+
diagnose(AtLoc, diag::only_allowed_in_sil, "pack_element");
4170+
return makeParserSuccess();
4171+
}
4172+
4173+
// Parse the opened ID string in parens
4174+
SourceLoc beginLoc = Tok.getLoc(), idLoc, endLoc;
4175+
if (consumeIfNotAtStartOfLine(tok::l_paren)) {
4176+
idLoc = Tok.getLoc();
4177+
UUID id;
4178+
if (!parseUUIDString(id, diag::opened_attribute_id_value))
4179+
Attributes.OpenedID = id;
4180+
4181+
// TODO: allow more information so that these can be parsed
4182+
// prior to the open instruction.
4183+
4184+
parseMatchingToken(tok::r_paren, endLoc,
4185+
diag::opened_attribute_expected_rparen,
4186+
beginLoc);
4187+
} else {
4188+
diagnose(Tok, diag::pack_element_attribute_expected_lparen);
4189+
}
4190+
4191+
break;
4192+
}
4193+
41674194
case TAK_differentiable: {
41684195
Attributes.differentiabilityKind = DifferentiabilityKind::Normal;
41694196
if (parseDifferentiableTypeAttributeArgument(

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,20 @@ namespace swift {
157157
llvm::DenseMap<SILBasicBlock*,
158158
Located<Identifier>> UndefinedBlocks;
159159

160+
/// The set of opened packs in the function, indexed by UUID.
161+
/// Note that we don't currently support parsing references to
162+
/// opened packs prior to their instruction, although this is
163+
/// theoretically possible if basic blocks are not sorted in
164+
/// dominance order.
165+
SILTypeResolutionContext::OpenedPackElementsMap OpenedPackElements;
166+
160167
/// Data structures used to perform name lookup for local values.
161168
llvm::StringMap<ValueBase*> LocalValues;
162169
llvm::StringMap<SourceLoc> ForwardRefLocalValues;
163170

164171
Type performTypeResolution(TypeRepr *TyR, bool IsSILType,
165172
GenericSignature GenericSig,
166-
GenericParamList *GenericParams) const;
173+
GenericParamList *GenericParams);
167174

168175
void convertRequirements(ArrayRef<RequirementRepr> From,
169176
SmallVectorImpl<Requirement> &To,
@@ -1253,11 +1260,12 @@ static bool parseDeclSILOptional(bool *isTransparent,
12531260

12541261
Type SILParser::performTypeResolution(TypeRepr *TyR, bool IsSILType,
12551262
GenericSignature GenericSig,
1256-
GenericParamList *GenericParams) const {
1263+
GenericParamList *GenericParams) {
12571264
if (!GenericSig)
12581265
GenericSig = ContextGenericSig;
12591266

1260-
SILTypeResolutionContext SILContext(IsSILType, GenericParams);
1267+
SILTypeResolutionContext SILContext(IsSILType, GenericParams,
1268+
&OpenedPackElements);
12611269

12621270
return swift::performTypeResolution(TyR, P.Context, GenericSig,
12631271
&SILContext, &P.SF);
@@ -3408,7 +3416,18 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
34083416
auto openedEnv = GenericEnvironment::forOpenedElement(openedElementSig,
34093417
uuid, shapeClass, openedSubMap);
34103418

3411-
ResultVal = B.createOpenPackElement(InstLoc, Val, openedEnv);
3419+
auto openInst = B.createOpenPackElement(InstLoc, Val, openedEnv);
3420+
ResultVal = openInst;
3421+
3422+
auto &entry = OpenedPackElements[uuid];
3423+
if (entry.DefinitionPoint.isValid()) {
3424+
P.diagnose(OpcodeLoc, diag::multiple_open_pack_element);
3425+
P.diagnose(entry.DefinitionPoint, diag::sil_previous_instruction);
3426+
} else {
3427+
entry.DefinitionPoint = OpcodeLoc;
3428+
entry.Params = openedGenerics;
3429+
entry.Environment = openedEnv;
3430+
}
34123431
break;
34133432
}
34143433

@@ -7593,7 +7612,8 @@ static bool parseSILWitnessTableEntry(
75937612
return true;
75947613

75957614
SILTypeResolutionContext silContext(/*isSILType=*/false,
7596-
witnessParams);
7615+
witnessParams,
7616+
/*openedPacks=*/nullptr);
75977617
auto Ty =
75987618
swift::performTypeResolution(TyR.get(), P.Context,
75997619
witnessSig, &silContext,
@@ -7657,7 +7677,8 @@ static bool parseSILWitnessTableEntry(
76577677
return true;
76587678

76597679
SILTypeResolutionContext silContext(/*isSILType=*/false,
7660-
witnessParams);
7680+
witnessParams,
7681+
/*openedPacks=*/nullptr);
76617682
auto Ty =
76627683
swift::performTypeResolution(TyR.get(), P.Context,
76637684
witnessSig, &silContext,

0 commit comments

Comments
 (0)