Skip to content

Commit ea107ae

Browse files
authored
Merge pull request #63324 from rjmccall/element-archetype-printing
Fix printing and implement parsing of opened element archetypes in SIL
2 parents 8c7f331 + c491d25 commit ea107ae

19 files changed

+394
-87
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5302,6 +5302,8 @@ NOTE(overridden_required_initializer_here,none,
53025302
// Functions
53035303
ERROR(attribute_requires_function_type,none,
53045304
"@%0 attribute only applies to function types", (StringRef))
5305+
ERROR(generic_function_type,none,
5306+
"function values cannot be generic", ())
53055307
ERROR(unsupported_convention,none,
53065308
"convention '%0' not supported", (StringRef))
53075309
ERROR(unreferenced_generic_parameter,NoUsage,
@@ -5383,6 +5385,9 @@ ERROR(illegal_sil_type,none,
53835385
"type %0 is not a legal SIL value type", (Type))
53845386
ERROR(sil_box_arg_mismatch,none,
53855387
"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?", ())
53865391
// SIL Metatypes
53875392
ERROR(sil_metatype_without_repr,none,
53885393
"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/AST/TypeCheckRequests.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3292,8 +3292,7 @@ class ModuleLibraryLevelRequest
32923292

32933293
class ResolveTypeRequest
32943294
: public SimpleRequest<ResolveTypeRequest,
3295-
Type(const TypeResolution *, TypeRepr *,
3296-
GenericParamList *),
3295+
Type(const TypeResolution *, TypeRepr *),
32973296
RequestFlags::Uncached> {
32983297
public:
32993298
using SimpleRequest::SimpleRequest;
@@ -3302,12 +3301,15 @@ class ResolveTypeRequest
33023301
// Cycle handling.
33033302
void noteCycleStep(DiagnosticEngine &diags) const;
33043303

3304+
static Type evaluate(const TypeResolution &resolution,
3305+
TypeRepr *repr);
3306+
33053307
private:
33063308
friend SimpleRequest;
33073309

33083310
// Evaluation.
33093311
Type evaluate(Evaluator &evaluator, const TypeResolution *resolution,
3310-
TypeRepr *repr, GenericParamList *silParams) const;
3312+
TypeRepr *repr) const;
33113313
};
33123314

33133315
void simple_display(llvm::raw_ostream &out, const TypeResolution *resolution);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===--- SILTypeResolutionContext.h -----------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SEMA_SILTYPERESOLUTIONCONTEXT_H
14+
#define SWIFT_SEMA_SILTYPERESOLUTIONCONTEXT_H
15+
16+
#include "llvm/ADT/DenseMap.h"
17+
#include "swift/Basic/UUID.h"
18+
19+
namespace swift {
20+
class GenericParamList;
21+
class GenericEnvironment;
22+
23+
class SILTypeResolutionContext {
24+
public:
25+
struct OpenedPackElement {
26+
SourceLoc DefinitionPoint;
27+
GenericParamList *Params;
28+
GenericEnvironment *Environment;
29+
};
30+
using OpenedPackElementsMap = llvm::DenseMap<UUID, OpenedPackElement>;
31+
32+
/// Are we requesting a SIL type?
33+
bool IsSILType;
34+
35+
/// Look up types in the given parameter list.
36+
GenericParamList *GenericParams;
37+
38+
/// Look up @pack_element environments in this map.
39+
OpenedPackElementsMap *OpenedPackElements;
40+
41+
SILTypeResolutionContext(bool isSILType,
42+
GenericParamList *genericParams,
43+
OpenedPackElementsMap *openedPackElements)
44+
: IsSILType(isSILType),
45+
GenericParams(genericParams),
46+
OpenedPackElements(openedPackElements) {}
47+
};
48+
49+
}
50+
51+
#endif

include/swift/Subsystems.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace swift {
6464
class SerializationOptions;
6565
class SILOptions;
6666
class SILModule;
67+
class SILTypeResolutionContext;
6768
class SourceFile;
6869
enum class SourceFileKind;
6970
class SourceManager;
@@ -163,10 +164,9 @@ namespace swift {
163164
/// code completion).
164165
///
165166
/// \returns A well-formed type on success, or an \c ErrorType.
166-
Type performTypeResolution(TypeRepr *TyR, ASTContext &Ctx, bool isSILMode,
167-
bool isSILType,
167+
Type performTypeResolution(TypeRepr *TyR, ASTContext &Ctx,
168168
GenericSignature GenericSig,
169-
GenericParamList *GenericParams,
169+
SILTypeResolutionContext *SILContext,
170170
DeclContext *DC, bool ProduceDiagnostics = true);
171171

172172
/// Expose TypeChecker's handling of GenericParamList to SIL parsing.

lib/AST/ASTPrinter.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5460,6 +5460,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
54605460
} else if (auto archetype = dyn_cast<ArchetypeType>(T.getPointer())) {
54615461
if (archetype->isParameterPack() && Options.PrintExplicitEach)
54625462
return false;
5463+
if (Options.PrintForSIL && isa<LocalArchetypeType>(archetype))
5464+
return false;
54635465
}
54645466
return T->hasSimpleTypeRepr();
54655467
}
@@ -6621,12 +6623,58 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
66216623
}
66226624
}
66236625

6626+
static Type findPackForElementArchetype(ElementArchetypeType *T) {
6627+
// The type in @pack_element is looked up in the generic params
6628+
// of the identified open_pack_element instruction. The param list
6629+
// is long gone, but the sugar survives in the type parameters of
6630+
// the generic signature of the contextual substitution map in the
6631+
// opened element environment.
6632+
auto env = T->getGenericEnvironment();
6633+
auto subs = env->getPackElementContextSubstitutions();
6634+
auto sig = subs.getGenericSignature();
6635+
auto params = sig.getGenericParams();
6636+
6637+
auto elementShapeClass =
6638+
env->getOpenedElementShapeClass()->mapTypeOutOfContext();
6639+
6640+
// The element archetypes are at a depth one past the max depth
6641+
// of the base signature.
6642+
unsigned elementDepth = params.back()->getDepth() + 1;
6643+
6644+
// Transform the archetype's interface type to be based on the
6645+
// corresponding non-canonical type parameter.
6646+
auto interfaceType = T->getInterfaceType();
6647+
return interfaceType.subst([&](SubstitutableType *type) -> Type {
6648+
// Don't transform types that aren't element type parameters.
6649+
auto *elementParam = type->getAs<GenericTypeParamType>();
6650+
if (!elementParam || elementParam->getDepth() != elementDepth)
6651+
return Type();
6652+
6653+
// Loop through the type parameters looking for the type parameter
6654+
// pack at the appropriate index. We only expect to actually do
6655+
// this once for each type, so it's fine to do it in the callback.
6656+
unsigned nextIndex = 0;
6657+
for (auto *genericParam : params) {
6658+
if (!genericParam->isParameterPack())
6659+
continue;
6660+
6661+
if (!sig->haveSameShape(genericParam, elementShapeClass))
6662+
continue;
6663+
6664+
if (nextIndex == elementParam->getIndex())
6665+
return genericParam;
6666+
nextIndex++;
6667+
}
6668+
llvm_unreachable("ran out of type parameters");
6669+
return Type();
6670+
}, LookUpConformanceInSignature(sig.getPointer()));
6671+
}
6672+
66246673
void visitElementArchetypeType(ElementArchetypeType *T) {
66256674
if (Options.PrintForSIL) {
6626-
Printer << "@element(\"" << T->getOpenedElementID() << ") ";
6627-
6628-
auto interfaceTy = T->getInterfaceType();
6629-
visit(interfaceTy);
6675+
Printer << "@pack_element(\"" << T->getOpenedElementID() << "\") ";
6676+
auto packTy = findPackForElementArchetype(T);
6677+
visit(packTy);
66306678
} else {
66316679
visit(T->getInterfaceType());
66326680
}

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/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,8 @@ class CodeCompletionCallbacksImpl : public IDEInspectionCallbacks {
200200

201201
const auto ty = swift::performTypeResolution(
202202
ParsedTypeLoc.getTypeRepr(), P.Context,
203-
/*isSILMode=*/false,
204-
/*isSILType=*/false,
205203
CurDeclContext->getGenericSignatureOfContext(),
206-
/*GenericParams=*/nullptr,
204+
/*SILContext=*/nullptr,
207205
CurDeclContext,
208206
/*ProduceDiagnostics=*/false);
209207
if (!ty->hasError()) {

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,7 @@ void swift::ide::collectPossibleReturnTypesFromContext(
254254
} else {
255255
const auto type = swift::performTypeResolution(
256256
CE->getExplicitResultTypeRepr(), DC->getASTContext(),
257-
/*isSILMode=*/false, /*isSILType=*/false,
258-
DC->getGenericSignatureOfContext(), /*GenericParams=*/nullptr,
257+
DC->getGenericSignatureOfContext(), /*SILContext=*/nullptr,
259258
const_cast<DeclContext *>(DC), /*diagnostics=*/false);
260259

261260
if (!type->hasError()) {

lib/Parse/ParseDecl.cpp

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

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

0 commit comments

Comments
 (0)