Skip to content

Commit 0416ec7

Browse files
committed
Augment GenericTypeParamDecl with bits indicating they came from opaque types
1 parent 7dc36c3 commit 0416ec7

File tree

12 files changed

+122
-38
lines changed

12 files changed

+122
-38
lines changed

include/swift/AST/Decl.h

+61-7
Original file line numberDiff line numberDiff line change
@@ -492,12 +492,15 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
492492
SWIFT_INLINE_BITFIELD_EMPTY(TypeDecl, ValueDecl);
493493
SWIFT_INLINE_BITFIELD_EMPTY(AbstractTypeParamDecl, TypeDecl);
494494

495-
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, AbstractTypeParamDecl, 16+16+1,
495+
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, AbstractTypeParamDecl, 16+16+1+1,
496496
: NumPadBits,
497497

498498
Depth : 16,
499499
Index : 16,
500-
TypeSequence : 1
500+
TypeSequence : 1,
501+
502+
/// Whether this generic parameter represents an opaque type.
503+
IsOpaqueType : 1
501504
);
502505

503506
SWIFT_INLINE_BITFIELD_EMPTY(GenericTypeDecl, TypeDecl);
@@ -2993,9 +2996,14 @@ class AbstractTypeParamDecl : public TypeDecl {
29932996
/// \code
29942997
/// func min<T : Comparable>(x : T, y : T) -> T { ... }
29952998
/// \endcode
2996-
class GenericTypeParamDecl : public AbstractTypeParamDecl {
2997-
public:
2998-
static const unsigned InvalidDepth = 0xFFFF;
2999+
class GenericTypeParamDecl final :
3000+
public AbstractTypeParamDecl,
3001+
private llvm::TrailingObjects<GenericTypeParamDecl, OpaqueReturnTypeRepr *>{
3002+
friend TrailingObjects;
3003+
3004+
size_t numTrailingObjects(OverloadToken<OpaqueReturnTypeRepr *>) const {
3005+
return isOpaqueType() ? 1 : 0;
3006+
}
29993007

30003008
/// Construct a new generic type parameter.
30013009
///
@@ -3006,7 +3014,29 @@ class GenericTypeParamDecl : public AbstractTypeParamDecl {
30063014
/// \param name The name of the generic parameter.
30073015
/// \param nameLoc The location of the name.
30083016
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
3009-
bool isTypeSequence, unsigned depth, unsigned index);
3017+
bool isTypeSequence, unsigned depth, unsigned index,
3018+
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr);
3019+
3020+
public:
3021+
/// Construct a new generic type parameter.
3022+
///
3023+
/// \param dc The DeclContext in which the generic type parameter's owner
3024+
/// occurs. This should later be overwritten with the actual declaration
3025+
/// context that owns the type parameter.
3026+
///
3027+
/// \param name The name of the generic parameter.
3028+
/// \param nameLoc The location of the name.
3029+
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
3030+
bool isTypeSequence, unsigned depth, unsigned index)
3031+
: GenericTypeParamDecl(dc, name, nameLoc, isTypeSequence, depth, index,
3032+
false, nullptr) { }
3033+
3034+
static const unsigned InvalidDepth = 0xFFFF;
3035+
3036+
static GenericTypeParamDecl *
3037+
create(DeclContext *dc, Identifier name, SourceLoc nameLoc,
3038+
bool isTypeSequence, unsigned depth, unsigned index,
3039+
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr);
30103040

30113041
/// The depth of this generic type parameter, i.e., the number of outer
30123042
/// levels of generic parameter lists that enclose this type parameter.
@@ -3034,9 +3064,33 @@ class GenericTypeParamDecl : public AbstractTypeParamDecl {
30343064
/// \code
30353065
/// func foo<@_typeSequence T>(_ : T...) { }
30363066
/// struct Foo<@_typeSequence T> { }
3037-
/// \encode
3067+
/// \endcode
30383068
bool isTypeSequence() const { return Bits.GenericTypeParamDecl.TypeSequence; }
30393069

3070+
/// Determine whether this generic parameter represents an opaque type.
3071+
///
3072+
/// \code
3073+
/// // "some P" is representated by a generic type parameter.
3074+
/// func f() -> [some P] { ... }
3075+
/// \endcode
3076+
bool isOpaqueType() const {
3077+
return Bits.GenericTypeParamDecl.IsOpaqueType;
3078+
}
3079+
3080+
/// Retrieve the opaque return type representation described by this
3081+
/// generic parameter, or NULL if any of the following are true:
3082+
/// - the generic parameter does not describe an opaque type
3083+
/// - the opaque type was introduced via the "named opaque parameters"
3084+
/// extension, meaning that it was specified explicitly
3085+
/// - the enclosing declaration was deserialized, in which case it lost
3086+
/// the source location information and has no type representation.
3087+
OpaqueReturnTypeRepr *getOpaqueTypeRepr() const {
3088+
if (!isOpaqueType())
3089+
return nullptr;
3090+
3091+
return *getTrailingObjects<OpaqueReturnTypeRepr *>();
3092+
}
3093+
30403094
/// The index of this generic type parameter within its generic parameter
30413095
/// list.
30423096
///

lib/AST/Builtins.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,9 @@ static GenericTypeParamDecl*
234234
createGenericParam(ASTContext &ctx, const char *name, unsigned index) {
235235
ModuleDecl *M = ctx.TheBuiltinModule;
236236
Identifier ident = ctx.getIdentifier(name);
237-
auto genericParam = new (ctx) GenericTypeParamDecl(
237+
auto genericParam = GenericTypeParamDecl::create(
238238
&M->getMainFile(FileUnitKind::Builtin), ident, SourceLoc(),
239-
/*type sequence*/ false, 0, index);
239+
/*type sequence*/ false, 0, index, /*opaque type=*/false, nullptr);
240240
return genericParam;
241241
}
242242

lib/AST/Decl.cpp

+25-5
Original file line numberDiff line numberDiff line change
@@ -4102,16 +4102,21 @@ AbstractTypeParamDecl::getConformingProtocols() const {
41024102
return { };
41034103
}
41044104

4105-
GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
4106-
SourceLoc nameLoc,
4107-
bool isTypeSequence, unsigned depth,
4108-
unsigned index)
4109-
: AbstractTypeParamDecl(DeclKind::GenericTypeParam, dc, name, nameLoc) {
4105+
GenericTypeParamDecl::GenericTypeParamDecl(
4106+
DeclContext *dc, Identifier name, SourceLoc nameLoc,
4107+
bool isTypeSequence, unsigned depth, unsigned index,
4108+
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr
4109+
) : AbstractTypeParamDecl(DeclKind::GenericTypeParam, dc, name, nameLoc) {
41104110
Bits.GenericTypeParamDecl.Depth = depth;
41114111
assert(Bits.GenericTypeParamDecl.Depth == depth && "Truncation");
41124112
Bits.GenericTypeParamDecl.Index = index;
41134113
assert(Bits.GenericTypeParamDecl.Index == index && "Truncation");
41144114
Bits.GenericTypeParamDecl.TypeSequence = isTypeSequence;
4115+
Bits.GenericTypeParamDecl.IsOpaqueType = isOpaqueType;
4116+
assert(!isOpaqueType || !opaqueTypeRepr);
4117+
if (isOpaqueType)
4118+
*getTrailingObjects<OpaqueReturnTypeRepr *>() = opaqueTypeRepr;
4119+
41154120
auto &ctx = dc->getASTContext();
41164121
RecursiveTypeProperties props = RecursiveTypeProperties::HasTypeParameter;
41174122
if (this->isTypeSequence())
@@ -4120,6 +4125,21 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
41204125
setInterfaceType(MetatypeType::get(type, ctx));
41214126
}
41224127

4128+
GenericTypeParamDecl *
4129+
GenericTypeParamDecl::create(
4130+
DeclContext *dc, Identifier name, SourceLoc nameLoc,
4131+
bool isTypeSequence, unsigned depth, unsigned index,
4132+
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr) {
4133+
ASTContext &ctx = dc->getASTContext();
4134+
auto mem = ctx.Allocate(
4135+
totalSizeToAlloc<OpaqueReturnTypeRepr *>(isOpaqueType ? 1 : 0),
4136+
alignof(GenericTypeParamDecl));
4137+
return new (mem) GenericTypeParamDecl(
4138+
dc, name, nameLoc, isTypeSequence, depth, index, isOpaqueType,
4139+
opaqueTypeRepr);
4140+
}
4141+
4142+
41234143
SourceRange GenericTypeParamDecl::getSourceRange() const {
41244144
SourceLoc endLoc = getNameLoc();
41254145

lib/AST/GenericParamList.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ GenericParamList::clone(DeclContext *dc) const {
7373
auto &ctx = dc->getASTContext();
7474
SmallVector<GenericTypeParamDecl *, 2> params;
7575
for (auto param : getParams()) {
76-
auto *newParam = new (ctx) GenericTypeParamDecl(
76+
auto *newParam = GenericTypeParamDecl::create(
7777
dc, param->getName(), SourceLoc(), param->isTypeSequence(),
78-
GenericTypeParamDecl::InvalidDepth, param->getIndex());
78+
GenericTypeParamDecl::InvalidDepth, param->getIndex(),
79+
param->isOpaqueType(), param->getOpaqueTypeRepr());
7980
newParam->setImplicit(true);
8081
params.push_back(newParam);
8182
}

lib/AST/NameLookup.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -2603,9 +2603,10 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
26032603
// The generic parameter 'Self'.
26042604
auto &ctx = value->getASTContext();
26052605
auto selfId = ctx.Id_Self;
2606-
auto selfDecl = new (ctx)
2607-
GenericTypeParamDecl(proto, selfId, SourceLoc(),
2608-
/*type sequence=*/false, /*depth=*/0, /*index=*/0);
2606+
auto selfDecl = GenericTypeParamDecl::create(
2607+
proto, selfId, SourceLoc(), /*type sequence=*/false,
2608+
/*depth=*/0, /*index=*/0, /*opaque type=*/false,
2609+
/*opaque type repr=*/nullptr);
26092610
auto protoType = proto->getDeclaredInterfaceType();
26102611
InheritedEntry selfInherited[1] = {
26112612
InheritedEntry(TypeLoc::withoutLoc(protoType)) };

lib/Parse/ParseGeneric.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,10 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc,
105105
// parameter list.
106106
const bool isTypeSequence =
107107
attributes.getAttribute<TypeSequenceAttr>() != nullptr;
108-
auto Param = new (Context) GenericTypeParamDecl(
108+
auto Param = GenericTypeParamDecl::create(
109109
CurDeclContext, Name, NameLoc, isTypeSequence,
110-
GenericTypeParamDecl::InvalidDepth, GenericParams.size());
110+
GenericTypeParamDecl::InvalidDepth, GenericParams.size(),
111+
/*isOpaqueType=*/false, /*opaqueTypeRepr=*/nullptr);
111112
if (!Inherited.empty())
112113
Param->setInherited(Context.AllocateCopy(Inherited));
113114
GenericParams.push_back(Param);

lib/SILOptimizer/Differentiation/LinearMapInfo.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ static GenericParamList *cloneGenericParameters(ASTContext &ctx,
3838
CanGenericSignature sig) {
3939
SmallVector<GenericTypeParamDecl *, 2> clonedParams;
4040
for (auto paramType : sig.getGenericParams()) {
41-
auto clonedParam = new (ctx) GenericTypeParamDecl(
41+
auto clonedParam = GenericTypeParamDecl::create(
4242
dc, paramType->getName(), SourceLoc(), paramType->isTypeSequence(),
43-
paramType->getDepth(), paramType->getIndex());
43+
paramType->getDepth(), paramType->getIndex(),
44+
/*isOpaqueType=*/false, /*opaqueTypeRepr=*/nullptr);
4445
clonedParam->setDeclContext(dc);
4546
clonedParam->setImplicit(true);
4647
clonedParams.push_back(clonedParam);

lib/Sema/CodeSynthesis.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,10 @@ computeDesignatedInitOverrideSignature(ASTContext &ctx,
468468
depth = genericSig.getGenericParams().back()->getDepth() + 1;
469469

470470
for (auto *param : genericParams->getParams()) {
471-
auto *newParam = new (ctx) GenericTypeParamDecl(
471+
auto *newParam = GenericTypeParamDecl::create(
472472
classDecl, param->getName(), SourceLoc(), param->isTypeSequence(),
473-
depth, param->getIndex());
473+
depth, param->getIndex(), param->isOpaqueType(),
474+
/*opaqueTypeRepr=*/nullptr);
474475
newParams.push_back(newParam);
475476
}
476477

lib/Serialization/Deserialization.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -1047,9 +1047,9 @@ ModuleFile::getGenericSignatureChecked(serialization::GenericSignatureID ID) {
10471047
auto paramTy = getType(rawParamIDs[i+1])->castTo<GenericTypeParamType>();
10481048

10491049
if (!name.empty()) {
1050-
auto paramDecl = createDecl<GenericTypeParamDecl>(
1050+
auto paramDecl = GenericTypeParamDecl::create(
10511051
getAssociatedModule(), name, SourceLoc(), paramTy->isTypeSequence(),
1052-
paramTy->getDepth(), paramTy->getIndex());
1052+
paramTy->getDepth(), paramTy->getIndex(), false, nullptr);
10531053
paramTy = paramDecl->getDeclaredInterfaceType()
10541054
->castTo<GenericTypeParamType>();
10551055
}
@@ -2680,16 +2680,18 @@ class DeclDeserializer {
26802680
bool isTypeSequence;
26812681
unsigned depth;
26822682
unsigned index;
2683+
bool isOpaqueType;
26832684

26842685
decls_block::GenericTypeParamDeclLayout::readRecord(
2685-
scratch, nameID, isImplicit, isTypeSequence, depth, index);
2686+
scratch, nameID, isImplicit, isTypeSequence, depth, index,
2687+
isOpaqueType);
26862688

26872689
// Always create GenericTypeParamDecls in the associated file; the real
26882690
// context will reparent them.
26892691
auto *DC = MF.getFile();
2690-
auto genericParam = MF.createDecl<GenericTypeParamDecl>(
2692+
auto genericParam = GenericTypeParamDecl::create(
26912693
DC, MF.getIdentifier(nameID), SourceLoc(), isTypeSequence, depth,
2692-
index);
2694+
index, isOpaqueType, /*opaqueTypeRepr=*/nullptr);
26932695
declOrOffset = genericParam;
26942696

26952697
if (isImplicit)

lib/Serialization/ModuleFormat.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 664; // parametrized protocols
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 665; // opaque type param bits
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1223,7 +1223,8 @@ namespace decls_block {
12231223
BCFixed<1>, // implicit flag
12241224
BCFixed<1>, // type sequence?
12251225
BCVBR<4>, // depth
1226-
BCVBR<4> // index
1226+
BCVBR<4>, // index
1227+
BCFixed<1> // opaque type?
12271228
>;
12281229

12291230
using AssociatedTypeDeclLayout = BCRecordLayout<

lib/Serialization/Serialization.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3424,7 +3424,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
34243424
S.Out, S.ScratchRecord, abbrCode,
34253425
S.addDeclBaseNameRef(genericParam->getName()),
34263426
genericParam->isImplicit(), genericParam->isTypeSequence(),
3427-
genericParam->getDepth(), genericParam->getIndex());
3427+
genericParam->getDepth(), genericParam->getIndex(),
3428+
genericParam->isOpaqueType());
34283429
}
34293430

34303431
void visitAssociatedTypeDecl(const AssociatedTypeDecl *assocType) {

unittests/AST/TestContext.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ using namespace swift::unittest;
2222

2323
static Decl *createOptionalType(ASTContext &ctx, SourceFile *fileForLookups,
2424
Identifier name) {
25-
auto wrapped = new (ctx) GenericTypeParamDecl(fileForLookups,
26-
ctx.getIdentifier("Wrapped"),
27-
SourceLoc(),
28-
/*type sequence*/ false,
29-
/*depth*/0, /*index*/0);
25+
auto wrapped = GenericTypeParamDecl::create(fileForLookups,
26+
ctx.getIdentifier("Wrapped"),
27+
SourceLoc(),
28+
/*type sequence*/ false,
29+
/*depth*/0, /*index*/0,
30+
/*opaque type*/false, nullptr);
3031
auto params = GenericParamList::create(ctx, SourceLoc(), wrapped,
3132
SourceLoc());
3233
auto decl = new (ctx) EnumDecl(SourceLoc(), name, SourceLoc(),

0 commit comments

Comments
 (0)